Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes for GPU Interface #18

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ and copies it to the proper destination.
$ git clone https://github.com/RRZE-HPC/pylikwid.git
$ cd pylikwid
# Build C interface
# NVIDIA functions enabled by -DLIKWID_NVMON
$ python setup.py build_ext -I <include path for likwid> -L <library path for likwid> -R <library path for likwid>
# Install module to the proper location
$ python setup.py install (--prefix=<where to install>)
Expand Down
87 changes: 45 additions & 42 deletions pylikwid.c
Original file line number Diff line number Diff line change
Expand Up @@ -2049,7 +2049,7 @@ likwid_gpumarkergetregion(PyObject *self, PyObject *args)
}
pyLen = (Py_ssize_t)nr_events;
pyList = PyList_New(pyLen);
likwid_gpuMarkerGetRegion(regiontag, &nr_gpus, &nr_events, events, &time, &count);
likwid_gpuMarkerGetRegion(regiontag, &nr_gpus, &nr_events, &events, &time, &count);
for (i=0; i< nr_events; i++)
{
PyList_SET_ITEM(pyList, (Py_ssize_t)i, Py_BuildValue("d", events[i]));
Expand Down Expand Up @@ -2101,7 +2101,7 @@ likwid_nvmon_init(PyObject *self, PyObject *args)

if (gpuTopology_initialized == 0)
{
gputopology_init();
topology_gpu_init();
gpuTopology_initialized = 1;
gputopo = get_gpuTopology();
}
Expand Down Expand Up @@ -2144,7 +2144,7 @@ likwid_nvmon_init(PyObject *self, PyObject *args)
ret = nvmon_init(nrGpus, &(gpulist[0]));
if (ret != 0)
{
free(cpulist);
free(gpulist);
printf("Initialization of PerfMon module failed.\n");
return PYINT(1);
}
Expand Down Expand Up @@ -2438,6 +2438,9 @@ likwid_nvmon_getGroups(PyObject *self, PyObject *args)
{
int i, ret;
char** tmp, **infos, **longs;
int gpuId;
PyArg_ParseTuple(args, "i", &gpuId);

PyObject *l;
if (gpuTopology_initialized == 0)
{
Expand All @@ -2448,7 +2451,7 @@ likwid_nvmon_getGroups(PyObject *self, PyObject *args)
{
gputopo = get_gpuTopology();
}
ret = nvmon_getGroups(&tmp, &infos, &longs);
ret = nvmon_getGroups(gpuId, &tmp, &infos, &longs);
if (ret > 0)
{
l = PyList_New(ret);
Expand Down Expand Up @@ -2483,43 +2486,43 @@ likwid_nvmon_setverbosity(PyObject *self, PyObject *args)
return Py_BuildValue("i", -1);
}

static PyObject *
likwid_nvmon_getEventsOfGpu(PyObject *self, PyObject *args)
{
int g;
if (!PyArg_ParseTuple(args, "i", &g))
Py_RETURN_NONE;
if (gpuTopology_initialized == 0)
{
topology_gpu_init();
gpuTopology_initialized = 1;
}
if (gpuTopology_initialized && gputopo == NULL)
{
gputopo = get_gpuTopology();
}
if (g < 0 || g >= gputopo->numDevices)
Py_RETURN_NONE;
NvmonEventList_t l = NULL;

int num_events = nvmon_getEventsOfGpu(g, &l);
if (num_events > 0)
{
PyObject *o = PyList_New(l->numEvents);

for (int i = 0; i < l->numEvents; i++)
{
PyObject *d = PyDict_New();
PyDict_SetItem(d, PYSTR("name"), PYSTR(l->events[i].name));
PyDict_SetItem(d, PYSTR("desc"), PYSTR(l->events[i].desc));
PyDict_SetItem(d, PYSTR("limit"), PYSTR(l->events[i].limit));
PyList_SET_ITEM(o, (Py_ssize_t)i, d);
}
nvmon_returnEventsOfGpu(l);
return o;
}
Py_RETURN_NONE;
}
// static PyObject *
// likwid_nvmon_getEventsOfGpu(PyObject *self, PyObject *args)
// {
// int g;
// if (!PyArg_ParseTuple(args, "i", &g))
// Py_RETURN_NONE;
// if (gpuTopology_initialized == 0)
// {
// topology_gpu_init();
// gpuTopology_initialized = 1;
// }
// if (gpuTopology_initialized && gputopo == NULL)
// {
// gputopo = get_gpuTopology();
// }
// if (g < 0 || g >= gputopo->numDevices)
// Py_RETURN_NONE;
// NvmonEventList_t l = NULL;

// int num_events = nvmon_getEventsOfGpu(g, &l);
// if (num_events > 0)
// {
// PyObject *o = PyList_New(l->numEvents);

// for (int i = 0; i < l->numEvents; i++)
// {
// PyObject *d = PyDict_New();
// PyDict_SetItem(d, PYSTR("name"), PYSTR(l->events[i].name));
// PyDict_SetItem(d, PYSTR("desc"), PYSTR(l->events[i].desc));
// PyDict_SetItem(d, PYSTR("limit"), PYSTR(l->events[i].limit));
// PyList_SET_ITEM(o, (Py_ssize_t)i, d);
// }
// nvmon_returnEventsOfGpu(l);
// return o;
// }
// Py_RETURN_NONE;
// }

#endif

Expand Down Expand Up @@ -2683,7 +2686,7 @@ static PyMethodDef LikwidMethods[] = {
{"nvgetnameofgroup", likwid_nvmon_getNameOfGroup, METH_VARARGS, "Return the name of a Nvmon group."},
{"nvgetshortinfoofgroup", likwid_nvmon_getShortInfoOfGroup, METH_VARARGS, "Return the short description of a Nvmon group."},
{"nvgetlonginfoofgroup", likwid_nvmon_getLongInfoOfGroup, METH_VARARGS, "Return the long description of a Nvmon group."},
{"nvgeteventsofgpu", likwid_nvmon_getEventsOfGpu, METH_VARARGS, "Get the events of a gpu."}
// {"nvgeteventsofgpu", likwid_nvmon_getEventsOfGpu, METH_VARARGS, "Get the events of a gpu."},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this function not exported anymore and completely commented out? Are there any undefined symbols?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, calls to nvmon_returnEvents* etc. are undefined

/* Misc function */
{"nvsetverbosity", likwid_nvmon_setverbosity, METH_VARARGS, "Set the verbosity for the LIKWID Nvmon library."},
#endif
Expand Down
3 changes: 3 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ def get_hierarchy():

try:
LIKWID_PREFIX, LIKWID_LIBPATH, LIKWID_LIB, LIKWID_INCPATH = get_hierarchy()
# TODO
major, minor, release = (5, 3, 2)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoded version is not future-proof. The major and minor number is present in likwid.h after installation, so maybe we read it from there.
Remark: There is no version 5.3.2

print(LIKWID_PREFIX, LIKWID_LIBPATH, LIKWID_LIB, LIKWID_INCPATH)
except Exception as e:
print(e)
Expand All @@ -105,6 +107,7 @@ def get_hierarchy():
include_dirs=[LIKWID_INCPATH],
libraries=[LIKWID_LIB],
library_dirs=[LIKWID_LIBPATH],
define_macros=[("LIKWID_MAJOR", major), ("LIKWID_MINOR", minor), (("LIKWID_RELEASE", release))],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this work? The variables major, minor and release are defined in a try block, so they are probably not in scope anymore.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There exists a function likwidversion that returns the version at runtime.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but the MACROS are not defined. It seems like there's a differently named MACRO in likwid.h, which comprises a string of the full version, .e.g., "5.3.2". So it seems like the function is broken when not defining the macros here

sources=["pylikwid.c"])

setup(
Expand Down