|
19 | 19 | #include "_nrt_helper.h"
|
20 | 20 | #include "_nrt_python_helper.h"
|
21 | 21 |
|
| 22 | +#include "_dbg_printer.h" |
| 23 | +#include "_queuestruct.h" |
22 | 24 | #include "numba/_arraystruct.h"
|
23 | 25 |
|
24 |
| -/* Debugging facilities - enabled at compile-time */ |
25 |
| -/* #undef NDEBUG */ |
26 |
| -#if 0 |
27 |
| -#include <stdio.h> |
28 |
| -#define DPEXRT_DEBUG(X) \ |
29 |
| - { \ |
30 |
| - X; \ |
31 |
| - fflush(stdout); \ |
32 |
| - } |
33 |
| -#else |
34 |
| -#define DPEXRT_DEBUG(X) \ |
35 |
| - if (0) { \ |
36 |
| - X; \ |
37 |
| - } |
38 |
| -#endif |
39 |
| - |
40 | 26 | // forward declarations
|
41 | 27 | static struct PyUSMArrayObject *PyUSMNdArray_ARRAYOBJ(PyObject *obj);
|
42 | 28 | static npy_intp product_of_shape(npy_intp *shape, npy_intp ndim);
|
@@ -66,6 +52,9 @@ DPEXRT_sycl_usm_ndarray_to_python_acqref(arystruct_t *arystruct,
|
66 | 52 | int ndim,
|
67 | 53 | int writeable,
|
68 | 54 | PyArray_Descr *descr);
|
| 55 | +static int DPEXRT_sycl_queue_from_python(PyObject *obj, |
| 56 | + queuestruct_t *queue_struct); |
| 57 | +static PyObject *DPEXRT_sycl_queue_to_python(queuestruct_t *queuestruct); |
69 | 58 |
|
70 | 59 | /*
|
71 | 60 | * Debugging printf function used internally
|
@@ -663,7 +652,9 @@ static npy_intp product_of_shape(npy_intp *shape, npy_intp ndim)
|
663 | 652 | return nelems;
|
664 | 653 | }
|
665 | 654 |
|
| 655 | +/*----------------------------------------------------------------------------*/ |
666 | 656 | /*----- Boxing and Unboxing implementations for a dpnp.ndarray PyObject ------*/
|
| 657 | +/*----------------------------------------------------------------------------*/ |
667 | 658 |
|
668 | 659 | /*!
|
669 | 660 | * @brief Unboxes a PyObject that may represent a dpnp.ndarray into a Numba
|
@@ -1049,6 +1040,107 @@ DPEXRT_sycl_usm_ndarray_to_python_acqref(arystruct_t *arystruct,
|
1049 | 1040 | return (PyObject *)dpnp_ary;
|
1050 | 1041 | }
|
1051 | 1042 |
|
| 1043 | +/*----------------------------------------------------------------------------*/ |
| 1044 | +/*--------------------- Box-unbox helpers for dpctl.SyclQueue ----------*/ |
| 1045 | +/*----------------------------------------------------------------------------*/ |
| 1046 | + |
| 1047 | +/*! |
| 1048 | + * @brief Helper to unbox a Python dpctl.SyclQueue object to a Numba-native |
| 1049 | + * queuestruct_t instance. |
| 1050 | + * |
| 1051 | + * @param obj A dpctl.SyclQueue Python object |
| 1052 | + * @param queue_struct An instance of the struct numba-dpex uses to |
| 1053 | + * represent a dpctl.SyclQueue inside Numba. |
| 1054 | + * @return {return} Return code indicating success (0) or failure (-1). |
| 1055 | + */ |
| 1056 | +static int DPEXRT_sycl_queue_from_python(PyObject *obj, |
| 1057 | + queuestruct_t *queue_struct) |
| 1058 | +{ |
| 1059 | + |
| 1060 | + struct PySyclQueueObject *queue_obj = NULL; |
| 1061 | + DPCTLSyclQueueRef queue_ref = NULL; |
| 1062 | + PyGILState_STATE gstate; |
| 1063 | + |
| 1064 | + // Increment the ref count on obj to prevent CPython from garbage |
| 1065 | + // collecting the array. |
| 1066 | + Py_IncRef(obj); |
| 1067 | + |
| 1068 | + // We are unconditionally casting obj to a struct PySyclQueueObject*. If |
| 1069 | + // the obj is not a struct PySyclQueueObject* then the SyclQueue_GetQueueRef |
| 1070 | + // will error out. |
| 1071 | + queue_obj = (struct PySyclQueueObject *)obj; |
| 1072 | + |
| 1073 | + DPEXRT_DEBUG( |
| 1074 | + nrt_debug_print("DPEXRT-DEBUG: In DPEXRT_sycl_queue_from_python.\n")); |
| 1075 | + |
| 1076 | + if (!(queue_ref = SyclQueue_GetQueueRef(queue_obj))) { |
| 1077 | + DPEXRT_DEBUG(nrt_debug_print( |
| 1078 | + "DPEXRT-ERROR: SyclQueue_GetQueueRef returned NULL at " |
| 1079 | + "%s, line %d.\n", |
| 1080 | + __FILE__, __LINE__)); |
| 1081 | + goto error; |
| 1082 | + } |
| 1083 | + |
| 1084 | + queue_struct->parent = obj; |
| 1085 | + queue_struct->queue_ref = queue_ref; |
| 1086 | + |
| 1087 | + return 0; |
| 1088 | + |
| 1089 | +error: |
| 1090 | + // If the check failed then decrement the refcount and return an error |
| 1091 | + // code of -1. |
| 1092 | + // Decref the Pyobject of the array |
| 1093 | + // ensure the GIL |
| 1094 | + DPEXRT_DEBUG(nrt_debug_print( |
| 1095 | + "DPEXRT-ERROR: Failed to unbox dpctl SyclQueue into a Numba " |
| 1096 | + "queuestruct at %s, line %d\n", |
| 1097 | + __FILE__, __LINE__)); |
| 1098 | + gstate = PyGILState_Ensure(); |
| 1099 | + // decref the python object |
| 1100 | + Py_DECREF(obj); |
| 1101 | + // release the GIL |
| 1102 | + PyGILState_Release(gstate); |
| 1103 | + |
| 1104 | + return -1; |
| 1105 | +} |
| 1106 | + |
| 1107 | +/*! |
| 1108 | + * @brief A helper function that boxes a Numba-dpex queuestruct_t object into a |
| 1109 | + * dctl.SyclQueue PyObject using the queuestruct_t's parent attribute. |
| 1110 | + * |
| 1111 | + * If there is no parent pointer stored in the queuestruct, then an error will |
| 1112 | + * be raised. |
| 1113 | + * |
| 1114 | + * @param queuestruct A Numba-dpex queuestruct object. |
| 1115 | + * @return {return} A PyObject created from the queuestruct->parent, if |
| 1116 | + * the PyObject could not be created return NULL. |
| 1117 | + */ |
| 1118 | +static PyObject *DPEXRT_sycl_queue_to_python(queuestruct_t *queuestruct) |
| 1119 | +{ |
| 1120 | + PyObject *orig_queue = NULL; |
| 1121 | + PyGILState_STATE gstate; |
| 1122 | + |
| 1123 | + orig_queue = queuestruct->parent; |
| 1124 | + // FIXME: Better error checking is needed to enforce the boxing of the queue |
| 1125 | + // object. For now, only the minimal is done as the returning of SyclQueue |
| 1126 | + // from a dpjit function should not be a used often and the dpctl C API for |
| 1127 | + // type checking etc. is not ready. |
| 1128 | + if (orig_queue == NULL) { |
| 1129 | + PyErr_Format(PyExc_ValueError, |
| 1130 | + "In 'box_from_queuestruct_parent', " |
| 1131 | + "failed to create a new dpctl.SyclQueue object."); |
| 1132 | + return NULL; |
| 1133 | + } |
| 1134 | + |
| 1135 | + gstate = PyGILState_Ensure(); |
| 1136 | + // decref the parent python object as we did an incref when unboxing it |
| 1137 | + Py_DECREF(orig_queue); |
| 1138 | + // release the GIL |
| 1139 | + PyGILState_Release(gstate); |
| 1140 | + |
| 1141 | + return orig_queue; |
| 1142 | +} |
| 1143 | + |
1052 | 1144 | /*----------------------------------------------------------------------------*/
|
1053 | 1145 | /*--------------------- The _dpexrt_python Python extension module -- -------*/
|
1054 | 1146 | /*----------------------------------------------------------------------------*/
|
@@ -1082,6 +1174,9 @@ static PyObject *build_c_helpers_dict(void)
|
1082 | 1174 | _declpointer("DPEXRT_MemInfo_fill", &DPEXRT_MemInfo_fill);
|
1083 | 1175 | _declpointer("NRT_ExternalAllocator_new_for_usm",
|
1084 | 1176 | &NRT_ExternalAllocator_new_for_usm);
|
| 1177 | + _declpointer("DPEXRT_sycl_queue_from_python", |
| 1178 | + &DPEXRT_sycl_queue_from_python); |
| 1179 | + _declpointer("DPEXRT_sycl_queue_to_python", &DPEXRT_sycl_queue_to_python); |
1085 | 1180 |
|
1086 | 1181 | #undef _declpointer
|
1087 | 1182 | return dct;
|
@@ -1129,6 +1224,11 @@ MOD_INIT(_dpexrt_python)
|
1129 | 1224 | m, "DPEXRT_sycl_usm_ndarray_to_python_acqref",
|
1130 | 1225 | PyLong_FromVoidPtr(&DPEXRT_sycl_usm_ndarray_to_python_acqref));
|
1131 | 1226 |
|
| 1227 | + PyModule_AddObject(m, "DPEXRT_sycl_queue_from_python", |
| 1228 | + PyLong_FromVoidPtr(&DPEXRT_sycl_queue_from_python)); |
| 1229 | + PyModule_AddObject(m, "DPEXRT_sycl_queue_to_python", |
| 1230 | + PyLong_FromVoidPtr(&DPEXRT_sycl_queue_to_python)); |
| 1231 | + |
1132 | 1232 | PyModule_AddObject(m, "DPEXRTQueue_CreateFromFilterString",
|
1133 | 1233 | PyLong_FromVoidPtr(&DPEXRTQueue_CreateFromFilterString));
|
1134 | 1234 | PyModule_AddObject(m, "DpexrtQueue_SubmitRange",
|
|
0 commit comments