Coverage for cuda / core / _kernel_arg_handler.pyx: 85.45%
213 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-29 01:27 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-29 01:27 +0000
1# SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2#
3# SPDX-License-Identifier: Apache-2.0
5from cpython.mem cimport PyMem_Malloc, PyMem_Free
6from libc.stdint cimport (intptr_t,
7 int8_t, int16_t, int32_t, int64_t,
8 uint8_t, uint16_t, uint32_t, uint64_t,)
9from libcpp cimport bool as cpp_bool
10from libcpp.complex cimport complex as cpp_complex
11from libcpp cimport nullptr
12from libcpp cimport vector
14import ctypes
16import numpy
18from cuda.core._memory import Buffer
19from cuda.core._tensor_map import TensorMapDescriptor as _TensorMapDescriptor_py
20from cuda.core._tensor_map cimport TensorMapDescriptor
21from cuda.core._utils.cuda_utils import driver
22from cuda.bindings cimport cydriver
25ctypedef cpp_complex.complex[float] cpp_single_complex
26ctypedef cpp_complex.complex[double] cpp_double_complex
29# We need an identifier for fp16 for copying scalars on the host. This is a minimal
30# implementation borrowed from cuda_fp16.h.
31cdef extern from *:
32 """
33 #if __cplusplus >= 201103L
34 #define __CUDA_ALIGN__(n) alignas(n) /* C++11 kindly gives us a keyword for this */
35 #else
36 #if defined(__GNUC__)
37 #define __CUDA_ALIGN__(n) __attribute__ ((aligned(n)))
38 #elif defined(_MSC_VER)
39 #define __CUDA_ALIGN__(n) __declspec(align(n))
40 #else
41 #define __CUDA_ALIGN__(n)
42 #endif /* defined(__GNUC__) */
43 #endif /* __cplusplus >= 201103L */
45 typedef struct __CUDA_ALIGN__(2) {
46 /**
47 * Storage field contains bits representation of the \p half floating-point number.
48 */
49 unsigned short x;
50 } __half_raw;
51 """
52 ctypedef struct __half_raw:
53 unsigned short x
56ctypedef fused supported_type:
57 cpp_bool
58 int8_t
59 int16_t
60 int32_t
61 int64_t
62 uint8_t
63 uint16_t
64 uint32_t
65 uint64_t
66 __half_raw
67 float
68 double
69 intptr_t
70 cpp_single_complex
71 cpp_double_complex
74# cache ctypes/numpy type objects to avoid attribute access
75cdef object ctypes_bool = ctypes.c_bool
76cdef object ctypes_int8 = ctypes.c_int8
77cdef object ctypes_int16 = ctypes.c_int16
78cdef object ctypes_int32 = ctypes.c_int32
79cdef object ctypes_int64 = ctypes.c_int64
80cdef object ctypes_uint8 = ctypes.c_uint8
81cdef object ctypes_uint16 = ctypes.c_uint16
82cdef object ctypes_uint32 = ctypes.c_uint32
83cdef object ctypes_uint64 = ctypes.c_uint64
84cdef object ctypes_float = ctypes.c_float
85cdef object ctypes_double = ctypes.c_double
86cdef object numpy_bool = numpy.bool_
87cdef object numpy_int8 = numpy.int8
88cdef object numpy_int16 = numpy.int16
89cdef object numpy_int32 = numpy.int32
90cdef object numpy_int64 = numpy.int64
91cdef object numpy_uint8 = numpy.uint8
92cdef object numpy_uint16 = numpy.uint16
93cdef object numpy_uint32 = numpy.uint32
94cdef object numpy_uint64 = numpy.uint64
95cdef object numpy_float16 = numpy.float16
96cdef object numpy_float32 = numpy.float32
97cdef object numpy_float64 = numpy.float64
98cdef object numpy_complex64 = numpy.complex64
99cdef object numpy_complex128 = numpy.complex128
102cdef object tensor_map_descriptor_type = _TensorMapDescriptor_py
105# limitation due to cython/cython#534
106ctypedef void* voidptr
109# Cython can't infer the overload without at least one input argument with fused type
110cdef inline int prepare_arg(
111 vector.vector[void*]& data,
112 vector.vector[void*]& data_addresses,
113 arg, # important: keep it a Python object and don't cast
114 const size_t idx,
115 const supported_type* __unused=NULL) except -1:
116 cdef void* ptr = PyMem_Malloc(sizeof(supported_type)) 1,-stbcklmnuvdeopqrwxyzfghi./:;=?6789!#$%'()@[]j^_`{|AQa+4NMDEKJLIGFHSR5UVT*3210ZYXWCP}
117 # note: this should also work once ctypes has complex support:
118 # python/cpython#121248
119 if supported_type is cpp_single_complex:
120 (<supported_type*>ptr)[0] = cpp_complex.complex[float](arg.real, arg.imag) 1S
121 elif supported_type is cpp_double_complex:
122 (<supported_type*>ptr)[0] = cpp_complex.complex[double](arg.real, arg.imag) 1aR5
123 elif supported_type is __half_raw:
124 (<supported_type*>ptr).x = <int16_t>(arg.view(numpy_int16)) 1U
125 else:
126 (<supported_type*>ptr)[0] = <supported_type>(arg) 1O,-stbcklmnuvdeopqrwxyzfghi./:;=?6789!#$%'()@[]j^_`{|AQa+4NMDEKJLIGFHSR5UVT*3210ZYXWCP}
127 data_addresses[idx] = ptr # take the address to the scalar 1,-stbcklmnuvdeopqrwxyzfghi./:;=?6789!#$%'()@[]j^_`{|AQa+4NMDEKJLIGFHSR5UVT*3210ZYXWCP}
128 data[idx] = ptr # for later dealloc 1,-stbcklmnuvdeopqrwxyzfghi./:;=?6789!#$%'()@[]j^_`{|AQa+4NMDEKJLIGFHSR5UVT*3210ZYXWCP}
129 return 0 1,-stbcklmnuvdeopqrwxyzfghi./:;=?6789!#$%'()@[]j^_`{|AQa+4NMDEKJLIGFHSR5UVT*3210ZYXWCP}
132cdef inline int prepare_tensor_map_arg(
133 vector.vector[void*]& data,
134 vector.vector[void*]& data_addresses,
135 TensorMapDescriptor arg,
136 const size_t idx) except -1:
137 # cuLaunchKernel copies argument bytes during launch, so a TensorMap
138 # descriptor can point directly at its internal CUtensorMap storage.
139 data_addresses[idx] = arg._get_data_ptr()
140 return 0
143cdef inline int prepare_ctypes_arg(
144 vector.vector[void*]& data,
145 vector.vector[void*]& data_addresses,
146 arg,
147 const size_t idx) except -1:
148 cdef object arg_type = type(arg) 1stbcklmnuvdeopqrwxyzfghijAaBNMDEKJLIGFHC
149 if arg_type is ctypes_bool: 1OstbcklmnuvdeopqrwxyzfghijAaBNMDEKJLIGFHC
150 return prepare_arg[cpp_bool](data, data_addresses, arg.value, idx) 1klopN
151 elif arg_type is ctypes_int8: 1stbcklmnuvdeopqrwxyzfghijAaBMDEKJLIGFHC
152 return prepare_arg[int8_t](data, data_addresses, arg.value, idx) 1M
153 elif arg_type is ctypes_int16: 1stbcklmnuvdeopqrwxyzfghijAaBDEKJLIGFHC
154 return prepare_arg[int16_t](data, data_addresses, arg.value, idx) 1OL
155 elif arg_type is ctypes_int32: 1stbcklmnuvdeopqrwxyzfghijAaBDEKJIGFHC
156 return prepare_arg[int32_t](data, data_addresses, arg.value, idx) 1K
157 elif arg_type is ctypes_int64: 1stbcklmnuvdeopqrwxyzfghijAaBDEJIGFHC
158 return prepare_arg[int64_t](data, data_addresses, arg.value, idx) 1J
159 elif arg_type is ctypes_uint8: 1OstbcklmnuvdeopqrwxyzfghijAaBDEIGFHC
160 return prepare_arg[uint8_t](data, data_addresses, arg.value, idx) 1I
161 elif arg_type is ctypes_uint16: 1stbcklmnuvdeopqrwxyzfghijAaBDEGFHC
162 return prepare_arg[uint16_t](data, data_addresses, arg.value, idx) 1H
163 elif arg_type is ctypes_uint32: 1stbcklmnuvdeopqrwxyzfghijAaBDEGFC
164 return prepare_arg[uint32_t](data, data_addresses, arg.value, idx) 1OG
165 elif arg_type is ctypes_uint64: 1stbcklmnuvdeopqrwxyzfghijAaBDEFC
166 return prepare_arg[uint64_t](data, data_addresses, arg.value, idx) 1F
167 elif arg_type is ctypes_float: 1stbcklmnuvdeopqrwxyzfghijAaBDEC
168 return prepare_arg[float](data, data_addresses, arg.value, idx) 1E
169 elif arg_type is ctypes_double: 1stbcklmnuvdeopqrwxyzfghijAaBDC
170 return prepare_arg[double](data, data_addresses, arg.value, idx) 1D
171 else:
172 # If no exact types are found, fallback to slower `isinstance` check
173 if isinstance(arg, ctypes_bool): 1stbcklmnuvdeopqrwxyzfghijAaBC
174 return prepare_arg[cpp_bool](data, data_addresses, arg.value, idx) 1A
175 elif isinstance(arg, ctypes_int8): 1stbcklmnuvdeopqrwxyzfghijAaBC
176 return prepare_arg[int8_t](data, data_addresses, arg.value, idx)
177 elif isinstance(arg, ctypes_int16): 1stbcklmnuvdeopqrwxyzfghijAaBC
178 return prepare_arg[int16_t](data, data_addresses, arg.value, idx)
179 elif isinstance(arg, ctypes_int32): 1OstbcklmnuvdeopqrwxyzfghijAaBC
180 return prepare_arg[int32_t](data, data_addresses, arg.value, idx) 1AC
181 elif isinstance(arg, ctypes_int64): 1stbcklmnuvdeopqrwxyzfghijAaB
182 return prepare_arg[int64_t](data, data_addresses, arg.value, idx)
183 elif isinstance(arg, ctypes_uint8): 1stbcklmnuvdeopqrwxyzfghijAaB
184 return prepare_arg[uint8_t](data, data_addresses, arg.value, idx)
185 elif isinstance(arg, ctypes_uint16): 1OstbcklmnuvdeopqrwxyzfghijAaB
186 return prepare_arg[uint16_t](data, data_addresses, arg.value, idx)
187 elif isinstance(arg, ctypes_uint32): 1stbcklmnuvdeopqrwxyzfghijAaB
188 return prepare_arg[uint32_t](data, data_addresses, arg.value, idx)
189 elif isinstance(arg, ctypes_uint64): 1stbcklmnuvdeopqrwxyzfghijAaB
190 return prepare_arg[uint64_t](data, data_addresses, arg.value, idx)
191 elif isinstance(arg, ctypes_float): 1stbcklmnuvdeopqrwxyzfghijAaB
192 return prepare_arg[float](data, data_addresses, arg.value, idx) 1A
193 elif isinstance(arg, ctypes_double): 1stbcklmnuvdeopqrwxyzfghijaB
194 return prepare_arg[double](data, data_addresses, arg.value, idx)
195 else:
196 return 1 1stbcklmnuvdeopqrwxyzfghijaB
199cdef inline int prepare_numpy_arg(
200 vector.vector[void*]& data,
201 vector.vector[void*]& data_addresses,
202 arg,
203 const size_t idx) except -1:
204 cdef object arg_type = type(arg) 1stbcklmnuvdeopqrwxyzfghijAQaB4NMDEKJLIGFHSRUVT3210ZYXWCP
205 if arg_type is numpy_bool: 1stbcklmnuvdeopqrwxyzfghijAQaB4NMDEKJLIGFHSRUVT3210ZYXWCP
206 return prepare_arg[cpp_bool](data, data_addresses, arg, idx) 1mnqr4
207 elif arg_type is numpy_int8: 1stbcklmnuvdeopqrwxyzfghijAQaBNMDEKJLIGFHSRUVT3210ZYXWCP
208 return prepare_arg[int8_t](data, data_addresses, arg, idx) 13
209 elif arg_type is numpy_int16: 1stbcklmnuvdeopqrwxyzfghijAQaBNMDEKJLIGFHSRUVT210ZYXWCP
210 return prepare_arg[int16_t](data, data_addresses, arg, idx) 12
211 elif arg_type is numpy_int32: 1stbcklmnuvdeopqrwxyzfghijAQaBNMDEKJLIGFHSRUVT10ZYXWCP
212 return prepare_arg[int32_t](data, data_addresses, arg, idx) 11
213 elif arg_type is numpy_int64: 1OstbcklmnuvdeopqrwxyzfghijAQaBNMDEKJLIGFHSRUVT0ZYXWCP
214 return prepare_arg[int64_t](data, data_addresses, arg, idx) 10
215 elif arg_type is numpy_uint8: 1stbcklmnuvdeopqrwxyzfghijAQaBNMDEKJLIGFHSRUVTZYXWCP
216 return prepare_arg[uint8_t](data, data_addresses, arg, idx) 1Z
217 elif arg_type is numpy_uint16: 1stbcklmnuvdeopqrwxyzfghijAQaBNMDEKJLIGFHSRUVTYXWCP
218 return prepare_arg[uint16_t](data, data_addresses, arg, idx) 1Y
219 elif arg_type is numpy_uint32: 1OstbcklmnuvdeopqrwxyzfghijAQaBNMDEKJLIGFHSRUVTXWCP
220 return prepare_arg[uint32_t](data, data_addresses, arg, idx) 1X
221 elif arg_type is numpy_uint64: 1stbcklmnuvdeopqrwxyzfghijAQaBNMDEKJLIGFHSRUVTWCP
222 return prepare_arg[uint64_t](data, data_addresses, arg, idx) 1W
223 elif arg_type is numpy_float16: 1OstbcklmnuvdeopqrwxyzfghijAQaBNMDEKJLIGFHSRUVTCP
224 return prepare_arg[__half_raw](data, data_addresses, arg, idx) 1U
225 elif arg_type is numpy_float32: 1stbcklmnuvdeopqrwxyzfghijAQaBNMDEKJLIGFHSRVTCP
226 return prepare_arg[float](data, data_addresses, arg, idx) 1V
227 elif arg_type is numpy_float64: 1stbcklmnuvdeopqrwxyzfghijAQaBNMDEKJLIGFHSRTCP
228 return prepare_arg[double](data, data_addresses, arg, idx) 1T
229 elif arg_type is numpy_complex64: 1stbcklmnuvdeopqrwxyzfghijAQaBNMDEKJLIGFHSRCP
230 return prepare_arg[cpp_single_complex](data, data_addresses, arg, idx) 1S
231 elif arg_type is numpy_complex128: 1stbcklmnuvdeopqrwxyzfghijAQaBNMDEKJLIGFHRCP
232 return prepare_arg[cpp_double_complex](data, data_addresses, arg, idx) 1OR
233 else:
234 # If no exact types are found, fallback to slower `isinstance` check
235 if isinstance(arg, numpy_bool): 1stbcklmnuvdeopqrwxyzfghijAQaBNMDEKJLIGFHCP
236 return prepare_arg[cpp_bool](data, data_addresses, arg, idx)
237 elif isinstance(arg, numpy_int8): 1stbcklmnuvdeopqrwxyzfghijAQaBNMDEKJLIGFHCP
238 return prepare_arg[int8_t](data, data_addresses, arg, idx)
239 elif isinstance(arg, numpy_int16): 1stbcklmnuvdeopqrwxyzfghijAQaBNMDEKJLIGFHCP
240 return prepare_arg[int16_t](data, data_addresses, arg, idx)
241 elif isinstance(arg, numpy_int32): 1OstbcklmnuvdeopqrwxyzfghijAQaBNMDEKJLIGFHCP
242 return prepare_arg[int32_t](data, data_addresses, arg, idx) 1Q
243 elif isinstance(arg, numpy_int64): 1stbcklmnuvdeopqrwxyzfghijAQaBNMDEKJLIGFHCP
244 return prepare_arg[int64_t](data, data_addresses, arg, idx)
245 elif isinstance(arg, numpy_uint8): 1stbcklmnuvdeopqrwxyzfghijAQaBNMDEKJLIGFHCP
246 return prepare_arg[uint8_t](data, data_addresses, arg, idx)
247 elif isinstance(arg, numpy_uint16): 1stbcklmnuvdeopqrwxyzfghijAQaBNMDEKJLIGFHCP
248 return prepare_arg[uint16_t](data, data_addresses, arg, idx)
249 elif isinstance(arg, numpy_uint32): 1stbcklmnuvdeopqrwxyzfghijAQaBNMDEKJLIGFHCP
250 return prepare_arg[uint32_t](data, data_addresses, arg, idx)
251 elif isinstance(arg, numpy_uint64): 1OstbcklmnuvdeopqrwxyzfghijAQaBNMDEKJLIGFHCP
252 return prepare_arg[uint64_t](data, data_addresses, arg, idx)
253 elif isinstance(arg, numpy_float16): 1stbcklmnuvdeopqrwxyzfghijAQaBNMDEKJLIGFHCP
254 return prepare_arg[__half_raw](data, data_addresses, arg, idx)
255 elif isinstance(arg, numpy_float32): 1stbcklmnuvdeopqrwxyzfghijAQaBNMDEKJLIGFHCP
256 return prepare_arg[float](data, data_addresses, arg, idx) 1QP
257 elif isinstance(arg, numpy_float64): 1stbcklmnuvdeopqrwxyzfghijAaBNMDEKJLIGFHC
258 return prepare_arg[double](data, data_addresses, arg, idx)
259 elif isinstance(arg, numpy_complex64): 1stbcklmnuvdeopqrwxyzfghijAaBNMDEKJLIGFHC
260 return prepare_arg[cpp_single_complex](data, data_addresses, arg, idx)
261 elif isinstance(arg, numpy_complex128): 1stbcklmnuvdeopqrwxyzfghijAaBNMDEKJLIGFHC
262 return prepare_arg[cpp_double_complex](data, data_addresses, arg, idx)
263 else:
264 return 1 1stbcklmnuvdeopqrwxyzfghijAaBNMDEKJLIGFHC
267cdef class ParamHolder:
269 def __init__(self, kernel_args):
270 if len(kernel_args) == 0: 2, ~ ab- bbcbs t b c k l m n u v d e o p q r w x y z f g h i dbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHb. / : ; = ? 6 7 8 9 ! # $ % ' ( ) @ [ ] IbJbKbLbMbj ^ _ ` { Nb| ObA Q a B Pb+ 4 N M D E K J L I G F H S R 5 U V T * 3 2 1 0 Z Y X W C P } QbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$c%c'c(c)c
271 self.ptr = 0 2~ abbbcbf g h i dbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbj NbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$c%c'c(c)c
272 return 2~ abbbcbf g h i dbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbj NbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$c%c'c(c)c
274 cdef size_t n_args = len(kernel_args) 1,-stbcklmnuvdeopqrwxyzfghi./:;=?6789!#$%'()@[]j^_`{|AQaB+4NMDEKJLIGFHSR5UVT*3210ZYXWCP}
275 cdef size_t i
276 cdef int not_prepared
277 cdef object arg_type
278 self.data = vector.vector[voidptr](n_args, nullptr) 1,-stbcklmnuvdeopqrwxyzfghi./:;=?6789!#$%'()@[]j^_`{|AQaB+4NMDEKJLIGFHSR5UVT*3210ZYXWCP}
279 self.data_addresses = vector.vector[voidptr](n_args) 1,-stbcklmnuvdeopqrwxyzfghi./:;=?6789!#$%'()@[]j^_`{|AQaB+4NMDEKJLIGFHSR5UVT*3210ZYXWCP}
280 for i, arg in enumerate(kernel_args): 1,-stbcklmnuvdeopqrwxyzfghi./:;=?6789!#$%'()@[]j^_`{|AQaB+4NMDEKJLIGFHSR5UVT*3210ZYXWCP}
281 arg_type = type(arg) 1,-stbcklmnuvdeopqrwxyzfghi./:;=?6789!#$%'()@[]j^_`{|AQaB+4NMDEKJLIGFHSR5UVT*3210ZYXWCP}
282 if arg_type is Buffer: 1,-stbcklmnuvdeopqrwxyzfghi./:;=?6789!#$%'()@[]j^_`{|AQaB+4NMDEKJLIGFHSR5UVT*3210ZYXWCP}
283 # we need the address of where the actual buffer address is stored
284 if type(arg.handle) is int: 16789!#$%'()}
285 # see note below on handling int arguments
286 prepare_arg[intptr_t](self.data, self.data_addresses, arg.handle, i) 16789!#$%'()}
287 continue 16789!#$%'()}
288 else:
289 # it's a CUdeviceptr:
290 self.data_addresses[i] = <void*><intptr_t>(arg.handle.getPtr())
291 continue
292 elif arg_type is bool: 1O,-stbcklmnuvdeopqrwxyzfghi./:;=?6789!#$%'()@[]j^_`{|AQaB+4NMDEKJLIGFHSR5UVT*3210ZYXWCP
293 prepare_arg[cpp_bool](self.data, self.data_addresses, arg, i) 1bcdej+
294 continue 1bcdej+
295 elif arg_type is int: 1,-stbcklmnuvdeopqrwxyzfghi./:;=?6789!#$%'()@[]j^_`{|AQaB+4NMDEKJLIGFHSR5UVT*3210ZYXWCP
296 # Here's the dilemma: We want to have a fast path to pass in Python
297 # integers as pointer addresses, but one could also (mistakenly) pass
298 # it with the intention of passing a scalar integer. It's a mistake
299 # bacause a Python int is ambiguous (arbitrary width). Our judgement
300 # call here is to treat it as a pointer address, without any warning!
301 prepare_arg[intptr_t](self.data, self.data_addresses, arg, i) 1,-stbcklmnuvdeopqrwxyzfghi./:;=?6789!#$%'()@[]^_`{|+4NMDEKJLIGFHSR5UVT*3210ZYXWCP
302 continue 1,-stbcklmnuvdeopqrwxyzfghi./:;=?6789!#$%'()@[]^_`{|+4NMDEKJLIGFHSR5UVT*3210ZYXWCP
303 elif arg_type is float: 1stbcklmnuvdeopqrwxyzfghijAQaB4NMDEKJLIGFHSR5UVT*3210ZYXWCP
304 prepare_arg[double](self.data, self.data_addresses, arg, i) 1*
305 continue 1*
306 elif arg_type is complex: 1stbcklmnuvdeopqrwxyzfghijAQaB4NMDEKJLIGFHSR5UVT3210ZYXWCP
307 prepare_arg[cpp_double_complex](self.data, self.data_addresses, arg, i) 15
308 continue 15
309 elif arg_type is tensor_map_descriptor_type: 1stbcklmnuvdeopqrwxyzfghijAQaB4NMDEKJLIGFHSRUVT3210ZYXWCP
310 prepare_tensor_map_arg(self.data, self.data_addresses, <TensorMapDescriptor>arg, i)
311 continue
313 not_prepared = prepare_numpy_arg(self.data, self.data_addresses, arg, i) 1stbcklmnuvdeopqrwxyzfghijAQaB4NMDEKJLIGFHSRUVT3210ZYXWCP
314 if not_prepared: 1stbcklmnuvdeopqrwxyzfghijAQaB4NMDEKJLIGFHSRUVT3210ZYXWCP
315 not_prepared = prepare_ctypes_arg(self.data, self.data_addresses, arg, i) 1stbcklmnuvdeopqrwxyzfghijAaBNMDEKJLIGFHC
316 if not_prepared: 1stbcklmnuvdeopqrwxyzfghijAQaB4NMDEKJLIGFHSRUVT3210ZYXWCP
317 # TODO: revisit this treatment if we decide to cythonize cuda.core
318 if arg_type is driver.CUgraphConditionalHandle: 1stbcklmnuvdeopqrwxyzfghijaB
319 prepare_arg[cydriver.CUgraphConditionalHandle](self.data, self.data_addresses, <intptr_t>int(arg), i) 1stbcklmnuvdeopqrwxyzfghij
320 continue 1stbcklmnuvdeopqrwxyzfghij
321 # If no exact types are found, fallback to slower `isinstance` check
322 elif isinstance(arg, Buffer): 1aB
323 if isinstance(arg.handle, int):
324 prepare_arg[intptr_t](self.data, self.data_addresses, arg.handle, i)
325 continue
326 else:
327 self.data_addresses[i] = <void*><intptr_t>(arg.handle.getPtr())
328 continue
329 elif isinstance(arg, bool): 1aB
330 prepare_arg[cpp_bool](self.data, self.data_addresses, arg, i)
331 continue
332 elif isinstance(arg, int): 1aB
333 prepare_arg[intptr_t](self.data, self.data_addresses, arg, i) 1a
334 continue 1a
335 elif isinstance(arg, float): 1aB
336 prepare_arg[double](self.data, self.data_addresses, arg, i) 1a
337 continue 1a
338 elif isinstance(arg, complex): 1OaB
339 prepare_arg[cpp_double_complex](self.data, self.data_addresses, arg, i) 1a
340 continue 1a
341 elif isinstance(arg, driver.CUgraphConditionalHandle): 1B
342 prepare_arg[cydriver.CUgraphConditionalHandle](self.data, self.data_addresses, arg, i)
343 continue
344 # TODO: support ctypes/numpy struct
345 raise TypeError("the argument is of unsupported type: " + str(type(arg))) 1B
347 self.kernel_args = kernel_args 1,-stbcklmnuvdeopqrwxyzfghi./:;=?6789!#$%'()@[]j^_`{|AQa+4NMDEKJLIGFHSR5UVT*3210ZYXWCP}
348 self.ptr = <intptr_t>self.data_addresses.data() 1,-stbcklmnuvdeopqrwxyzfghi./:;=?6789!#$%'()@[]j^_`{|AQa+4NMDEKJLIGFHSR5UVT*3210ZYXWCP}
350 def __dealloc__(self):
351 for data in self.data: 2O , ~ ab- bbcbs t b c k l m n u v d e o p q r w x y z f g h i dbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHb. / : ; = ? 6 7 8 9 ! # $ % ' ( ) @ [ ] IbJbKbLbMbj ^ _ ` { Nb| ObA Q a B Pb+ 4 N M D E K J L I G F H S R 5 U V T * 3 2 1 0 Z Y X W C P } QbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$c%c'c(c)c
352 if data: 1,-stbcklmnuvdeopqrwxyzfghi./:;=?6789!#$%'()@[]j^_`{|AQaB+4NMDEKJLIGFHSR5UVT*3210ZYXWCP}
353 PyMem_Free(data) 1,-stbcklmnuvdeopqrwxyzfghi./:;=?6789!#$%'()@[]j^_`{|AQa+4NMDEKJLIGFHSR5UVT*3210ZYXWCP}