|
6 | 6 |
|
7 | 7 | from dpctl import get_device_cached_queue
|
8 | 8 | from llvmlite import ir as llvmir
|
9 |
| -from llvmlite.ir import Constant |
| 9 | +from llvmlite.ir import Constant, IRBuilder |
10 | 10 | from llvmlite.ir.types import DoubleType, FloatType
|
11 | 11 | from numba import types
|
12 | 12 | from numba.core import cgutils
|
13 | 13 | from numba.core import config as numba_config
|
| 14 | +from numba.core import errors, imputils |
14 | 15 | from numba.core.typing import signature
|
15 | 16 | from numba.extending import intrinsic, overload_classmethod
|
16 | 17 | from numba.np.arrayobj import (
|
@@ -1076,3 +1077,61 @@ def codegen(context, builder, sig, args):
|
1076 | 1077 | return ary._getvalue()
|
1077 | 1078 |
|
1078 | 1079 | return signature, codegen
|
| 1080 | + |
| 1081 | + |
| 1082 | +@intrinsic |
| 1083 | +def ol_dpnp_nd_array_sycl_queue( |
| 1084 | + ty_context, |
| 1085 | + ty_dpnp_nd_array: DpnpNdArray, |
| 1086 | +): |
| 1087 | + if not isinstance(ty_dpnp_nd_array, DpnpNdArray): |
| 1088 | + raise errors.TypingError("Argument must be DpnpNdArray") |
| 1089 | + |
| 1090 | + ty_queue: DpctlSyclQueue = ty_dpnp_nd_array.queue |
| 1091 | + |
| 1092 | + sig = ty_queue(ty_dpnp_nd_array) |
| 1093 | + |
| 1094 | + def codegen(context, builder: IRBuilder, sig, args: list): |
| 1095 | + array_proxy = cgutils.create_struct_proxy(ty_dpnp_nd_array)( |
| 1096 | + context, |
| 1097 | + builder, |
| 1098 | + value=args[0], |
| 1099 | + ) |
| 1100 | + |
| 1101 | + queue_ref = array_proxy.sycl_queue |
| 1102 | + |
| 1103 | + queue_struct_proxy = cgutils.create_struct_proxy(ty_queue)( |
| 1104 | + context, builder |
| 1105 | + ) |
| 1106 | + |
| 1107 | + queue_struct_proxy.queue_ref = queue_ref |
| 1108 | + queue_struct_proxy.meminfo = array_proxy.meminfo |
| 1109 | + |
| 1110 | + # Warning: current implementation prevents whole object from being |
| 1111 | + # destroyed as long as sycl_queue attribute is being used. It should be |
| 1112 | + # okay since anywere we use it as an argument callee creates a copy |
| 1113 | + # so it does not steel reference. |
| 1114 | + # |
| 1115 | + # We can avoid it by: |
| 1116 | + # queue_ref_copy = sycl.dpctl_queue_copy(builder, queue_ref) #noqa E800 |
| 1117 | + # queue_struct_proxy.queue_ref = queue_ref_copy #noqa E800 |
| 1118 | + # queue_struct->meminfo = |
| 1119 | + # nrt->manage_memory(queue_ref_copy, DPCTLEvent_Delete); |
| 1120 | + # but it will allocate new meminfo object which can negatively affect |
| 1121 | + # performance. |
| 1122 | + # Speaking philosophically attribute is a part of the object and as long |
| 1123 | + # as nobody can still the reference it is a part of the owner object |
| 1124 | + # and lifetime is tied to it. |
| 1125 | + # TODO: we want to have queue: queuestruct_t instead of |
| 1126 | + # queue_ref: QueueRef as an attribute for DPNPNdArray. |
| 1127 | + |
| 1128 | + queue_value = queue_struct_proxy._getvalue() |
| 1129 | + |
| 1130 | + # We need to incref meminfo so that queue model is preventing parent |
| 1131 | + # ndarray from being destroyed, that can destroy queue that we are |
| 1132 | + # using. |
| 1133 | + return imputils.impl_ret_borrowed( |
| 1134 | + context, builder, ty_queue, queue_value |
| 1135 | + ) |
| 1136 | + |
| 1137 | + return sig, codegen |
0 commit comments