-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
python: add wrapper code for ITT-NERSC implementation to ensure compa…
…tibility (#153) * Added the wrapper code for ITT-NERSC implementation of ITTAPI * Added unit testcases for ittapi.compat adapter code * Added ittapi.compat section to README.md * Added pt_region support to main ittapi module * Updated ittapi version to 1.2.0 from 1.1.0
- Loading branch information
1 parent
4febd9a
commit fc432d1
Showing
19 changed files
with
654 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,269 @@ | ||
#include "pt_region.hpp" | ||
|
||
#include <structmember.h> | ||
|
||
#include "string_handle.hpp" | ||
#include "extensions/string.hpp" | ||
|
||
namespace ittapi | ||
{ | ||
|
||
template<typename T> | ||
T* pt_region_cast(PT_Region* self); | ||
|
||
template <> | ||
PyObject* pt_region_cast(PT_Region* self) | ||
{ | ||
return reinterpret_cast<PyObject*>(self); | ||
} | ||
|
||
static PyObject* pt_region_new(PyTypeObject* type, PyObject* args, PyObject* kwargs); | ||
static void pt_region_dealloc(PyObject* self); | ||
|
||
static PyObject* pt_region_repr(PyObject* self); | ||
static PyObject* pt_region_str(PyObject* self); | ||
|
||
static PyMemberDef pt_region_attrs[] = | ||
{ | ||
{"name", T_OBJECT, offsetof(PT_Region, name), READONLY, "a pt_region name"}, | ||
{nullptr}, | ||
}; | ||
|
||
PyTypeObject PT_RegionType = | ||
{ | ||
.ob_base = PyVarObject_HEAD_INIT(nullptr, 0) | ||
.tp_name = "ittapi.native.PT_Region", | ||
.tp_basicsize = sizeof(PT_Region), | ||
.tp_itemsize = 0, | ||
|
||
/* Methods to implement standard operations */ | ||
.tp_dealloc = pt_region_dealloc, | ||
.tp_vectorcall_offset = 0, | ||
.tp_getattr = nullptr, | ||
.tp_setattr = nullptr, | ||
.tp_as_async = nullptr, | ||
.tp_repr = pt_region_repr, | ||
|
||
/* Method suites for standard classes */ | ||
.tp_as_number = nullptr, | ||
.tp_as_sequence = nullptr, | ||
.tp_as_mapping = nullptr, | ||
|
||
/* More standard operations (here for binary compatibility) */ | ||
.tp_hash = nullptr, | ||
.tp_call = nullptr, | ||
.tp_str = pt_region_str, | ||
.tp_getattro = nullptr, | ||
.tp_setattro = nullptr, | ||
|
||
/* Functions to access object as input/output buffer */ | ||
.tp_as_buffer = nullptr, | ||
|
||
/* Flags to define presence of optional/expanded features */ | ||
.tp_flags = Py_TPFLAGS_DEFAULT, | ||
|
||
/* Documentation string */ | ||
.tp_doc = "A class that represents a __itt_pt_region(__itt_pt_region -> unsigned char)", | ||
|
||
/* Assigned meaning in release 2.0 call function for all accessible objects */ | ||
.tp_traverse = nullptr, | ||
|
||
/* Delete references to contained objects */ | ||
.tp_clear = nullptr, | ||
|
||
/* Assigned meaning in release 2.1 rich comparisons */ | ||
.tp_richcompare = nullptr, | ||
|
||
/* weak reference enabler */ | ||
.tp_weaklistoffset = 0, | ||
|
||
/* Iterators */ | ||
.tp_iter = nullptr, | ||
.tp_iternext = nullptr, | ||
|
||
/* Attribute descriptor and subclassing stuff */ | ||
.tp_methods = nullptr, | ||
.tp_members = pt_region_attrs, | ||
.tp_getset = nullptr, | ||
|
||
/* Strong reference on a heap type, borrowed reference on a static type */ | ||
.tp_base = nullptr, | ||
.tp_dict = nullptr, | ||
.tp_descr_get = nullptr, | ||
.tp_descr_set = nullptr, | ||
.tp_dictoffset = 0, | ||
.tp_init = nullptr, | ||
.tp_alloc = nullptr, | ||
.tp_new = pt_region_new, | ||
|
||
/* Low-level free-memory routine */ | ||
.tp_free = nullptr, | ||
|
||
/* For PyObject_IS_GC */ | ||
.tp_is_gc = nullptr, | ||
.tp_bases = nullptr, | ||
|
||
/* method resolution order */ | ||
.tp_mro = nullptr, | ||
.tp_cache = nullptr, | ||
.tp_subclasses = nullptr, | ||
.tp_weaklist = nullptr, | ||
.tp_del = nullptr, | ||
|
||
/* Type attribute cache version tag. Added in version 2.6 */ | ||
.tp_version_tag = 0, | ||
|
||
.tp_finalize = nullptr, | ||
.tp_vectorcall = nullptr, | ||
}; | ||
|
||
static PyObject* pt_region_new(PyTypeObject* type, PyObject* args, PyObject* kwargs) | ||
{ | ||
PT_Region* self = pt_region_obj(type->tp_alloc(type,0)); | ||
if (self == nullptr) | ||
{ | ||
return nullptr; | ||
} | ||
|
||
char name_key[] = { "name" }; | ||
char* kwlist[] = { name_key, nullptr }; | ||
|
||
PyObject* name = nullptr; | ||
|
||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O", kwlist, &name)) | ||
{ | ||
return nullptr; | ||
} | ||
|
||
if (name && PyUnicode_Check(name)) | ||
{ | ||
self->name = pyext::new_ref(name); | ||
} | ||
else if (name && Py_TYPE(name) == &StringHandleType) | ||
{ | ||
self->name = pyext::new_ref(string_handle_obj(name)->str); | ||
} | ||
else | ||
{ | ||
Py_DecRef(pt_region_cast<PyObject>(self)); | ||
|
||
PyErr_SetString(PyExc_TypeError, "The passed string to create pt_region is not a valid instance of neither str nor StringHandle"); | ||
return nullptr; | ||
} | ||
|
||
pyext::string name_str = pyext::string::from_unicode(self->name); | ||
if (name_str.c_str() == nullptr) | ||
{ | ||
Py_DecRef(pt_region_cast<PyObject>(self)); | ||
return nullptr; | ||
} | ||
|
||
#if defined(_WIN32) | ||
self->handle=__itt_pt_region_createW(name_str.c_str()); | ||
#else | ||
self->handle=__itt_pt_region_create(name_str.c_str()); | ||
#endif | ||
|
||
return pt_region_cast<PyObject>(self); | ||
} | ||
|
||
static void pt_region_dealloc(PyObject* self) | ||
{ | ||
if (self == nullptr) | ||
{ | ||
return; | ||
} | ||
|
||
PT_Region* obj = pt_region_obj(self); | ||
Py_XDECREF(obj->name); | ||
} | ||
|
||
static PyObject* pt_region_repr(PyObject* self) | ||
{ | ||
PT_Region* obj = pt_region_check(self); | ||
if (obj == nullptr) | ||
{ | ||
return nullptr; | ||
} | ||
|
||
if (obj->name == nullptr) | ||
{ | ||
PyErr_SetString(PyExc_AttributeError, "The name attribute has not been initialized."); | ||
return nullptr; | ||
} | ||
|
||
return PyUnicode_FromFormat("%s('%U')", PT_RegionType.tp_name, obj->name); | ||
} | ||
|
||
static PyObject* pt_region_str(PyObject* self) | ||
{ | ||
PT_Region* obj = pt_region_check(self); | ||
if (obj == nullptr) | ||
{ | ||
return nullptr; | ||
} | ||
|
||
if (obj->name == nullptr) | ||
{ | ||
PyErr_SetString(PyExc_AttributeError, "The name attribute has not been initialized."); | ||
return nullptr; | ||
} | ||
|
||
return pyext::new_ref(obj->name); | ||
} | ||
|
||
PT_Region* pt_region_check(PyObject* self) | ||
{ | ||
if (self == nullptr || Py_TYPE(self) != &PT_RegionType) | ||
{ | ||
PyErr_SetString(PyExc_TypeError, "The passed pt_region is not a valid instance of PT_Region type."); | ||
return nullptr; | ||
} | ||
|
||
return pt_region_obj(self); | ||
} | ||
|
||
int exec_pt_region(PyObject* module) | ||
{ | ||
return pyext::add_type(module, &PT_RegionType); | ||
} | ||
|
||
PyObject* pt_region_begin(PyObject* self, PyObject* args) | ||
{ | ||
PyObject* pt_region = nullptr; | ||
if (!PyArg_ParseTuple(args, "O", &pt_region)) | ||
{ | ||
return nullptr; | ||
} | ||
|
||
PT_Region *pt_region_obj = pt_region_check(pt_region); | ||
if (pt_region_obj == nullptr) | ||
{ | ||
return nullptr; | ||
} | ||
|
||
__itt_mark_pt_region_begin(pt_region_obj->handle); | ||
|
||
Py_RETURN_NONE; | ||
} | ||
|
||
PyObject* pt_region_end(PyObject* self, PyObject* args) | ||
{ | ||
PyObject* pt_region = nullptr; | ||
if (!PyArg_ParseTuple(args, "O", &pt_region)) | ||
{ | ||
return nullptr; | ||
} | ||
|
||
PT_Region *pt_region_obj = pt_region_check(pt_region); | ||
if (pt_region_obj == nullptr) | ||
{ | ||
return nullptr; | ||
} | ||
|
||
__itt_mark_pt_region_end(pt_region_obj->handle); | ||
|
||
Py_RETURN_NONE; | ||
} | ||
|
||
} // namespace ittapi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
#pragma once | ||
|
||
#define PY_SSIZE_T_CLEAN | ||
#include <Python.h> | ||
|
||
#include <ittnotify.h> | ||
|
||
#include "extensions/python.hpp" | ||
|
||
namespace ittapi | ||
{ | ||
|
||
struct PT_Region | ||
{ | ||
PyObject_HEAD | ||
PyObject* name; | ||
__itt_pt_region handle; | ||
}; | ||
|
||
extern PyTypeObject PT_RegionType; | ||
|
||
inline PT_Region* pt_region_obj(PyObject* self); | ||
PT_Region* pt_region_check(PyObject* self); | ||
int exec_pt_region(PyObject* module); | ||
|
||
/* Implementation of inline functions */ | ||
PT_Region* pt_region_obj(PyObject* self) | ||
{ | ||
return pyext::pyobject_cast<PT_Region>(self); | ||
} | ||
|
||
PyObject* pt_region_begin(PyObject* self, PyObject* args); | ||
PyObject* pt_region_end(PyObject* self, PyObject* args); | ||
|
||
} // namespace ittapi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.