Coverage for cuda / core / _kernel_arg_handler.pyx: 85.52%

221 statements  

« prev     ^ index     » next       coverage.py v7.14.0, created at 2026-05-22 01:37 +0000

1# SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 

2# 

3# SPDX-License-Identifier: Apache-2.0 

4  

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 

13  

14import ctypes 

15  

16import numpy 

17  

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.graph._graph_definition cimport GraphCondition 

22from cuda.core._utils.cuda_utils import driver 

23from cuda.bindings cimport cydriver 

24  

25  

26ctypedef cpp_complex.complex[float] cpp_single_complex 

27ctypedef cpp_complex.complex[double] cpp_double_complex 

28  

29  

30# We need an identifier for fp16 for copying scalars on the host. This is a minimal 

31# implementation borrowed from cuda_fp16.h. 

32cdef extern from *: 

33 """ 

34 #if __cplusplus >= 201103L 

35 #define __CUDA_ALIGN__(n) alignas(n) /* C++11 kindly gives us a keyword for this */ 

36 #else 

37 #if defined(__GNUC__) 

38 #define __CUDA_ALIGN__(n) __attribute__ ((aligned(n))) 

39 #elif defined(_MSC_VER) 

40 #define __CUDA_ALIGN__(n) __declspec(align(n)) 

41 #else 

42 #define __CUDA_ALIGN__(n) 

43 #endif /* defined(__GNUC__) */ 

44 #endif /* __cplusplus >= 201103L */ 

45  

46 typedef struct __CUDA_ALIGN__(2) { 

47 /** 

48 * Storage field contains bits representation of the \p half floating-point number. 

49 */ 

50 unsigned short x; 

51 } __half_raw; 

52 """ 

53 ctypedef struct __half_raw: 

54 unsigned short x 

55  

56  

57ctypedef fused supported_type: 

58 cpp_bool 

59 int8_t 

60 int16_t 

61 int32_t 

62 int64_t 

63 uint8_t 

64 uint16_t 

65 uint32_t 

66 uint64_t 

67 __half_raw 

68 float 

69 double 

70 intptr_t 

71 cpp_single_complex 

72 cpp_double_complex 

73  

74  

75# cache ctypes/numpy type objects to avoid attribute access 

76cdef object ctypes_bool = ctypes.c_bool 

77cdef object ctypes_int8 = ctypes.c_int8 

78cdef object ctypes_int16 = ctypes.c_int16 

79cdef object ctypes_int32 = ctypes.c_int32 

80cdef object ctypes_int64 = ctypes.c_int64 

81cdef object ctypes_uint8 = ctypes.c_uint8 

82cdef object ctypes_uint16 = ctypes.c_uint16 

83cdef object ctypes_uint32 = ctypes.c_uint32 

84cdef object ctypes_uint64 = ctypes.c_uint64 

85cdef object ctypes_float = ctypes.c_float 

86cdef object ctypes_double = ctypes.c_double 

87cdef object numpy_bool = numpy.bool_ 

88cdef object numpy_int8 = numpy.int8 

89cdef object numpy_int16 = numpy.int16 

90cdef object numpy_int32 = numpy.int32 

91cdef object numpy_int64 = numpy.int64 

92cdef object numpy_uint8 = numpy.uint8 

93cdef object numpy_uint16 = numpy.uint16 

94cdef object numpy_uint32 = numpy.uint32 

95cdef object numpy_uint64 = numpy.uint64 

96cdef object numpy_float16 = numpy.float16 

97cdef object numpy_float32 = numpy.float32 

98cdef object numpy_float64 = numpy.float64 

99cdef object numpy_complex64 = numpy.complex64 

100cdef object numpy_complex128 = numpy.complex128 

101  

102  

103cdef object tensor_map_descriptor_type = _TensorMapDescriptor_py 

104  

105  

106# limitation due to cython/cython#534 

107ctypedef void* voidptr 

108  

109  

110# Cython can't infer the overload without at least one input argument with fused type 

111cdef inline int prepare_arg( 

112 vector.vector[void*]& data, 

113 vector.vector[void*]& data_addresses, 

114 arg, # important: keep it a Python object and don't cast 

115 const size_t idx, 

116 const supported_type* __unused=NULL) except -1: 

117 cdef void* ptr = PyMem_Malloc(sizeof(supported_type)) 2/ : s t b c k l m n u v d e o p q r w x y z f g h i bbcb; = ? @ [ ] 9 ! # $ % ' ( ) * + , ^ _ ` j { | } ~ 0 1 2 abB Q a . 7 N M D E K J L I G F H S R 8 U V T - 6 5 4 3 Z Y X W C P db

118 # note: this should also work once ctypes has complex support: 

119 # python/cpython#121248 

120 if supported_type is cpp_single_complex: 

121 (<supported_type*>ptr)[0] = cpp_complex.complex[float](arg.real, arg.imag) 1S

122 elif supported_type is cpp_double_complex: 

123 (<supported_type*>ptr)[0] = cpp_complex.complex[double](arg.real, arg.imag) 1aR8

124 elif supported_type is __half_raw: 

125 (<supported_type*>ptr).x = <int16_t>(arg.view(numpy_int16)) 1U

126 else: 

127 (<supported_type*>ptr)[0] = <supported_type>(arg) 2/ : s t b c k l m n u v d e o p q r w x y z f g h i bbcb; = ? @ [ ] 9 ! # $ % ' ( ) * + , ^ _ ` j { | } ~ 0 1 2 abB Q a . 7 N M D E K J L I G F H S R 8 U V T - 6 5 4 3 Z Y X W C P db

128 data_addresses[idx] = ptr # take the address to the scalar 2/ : s t b c k l m n u v d e o p q r w x y z f g h i bbcb; = ? @ [ ] 9 ! # $ % ' ( ) * + , ^ _ ` j { | } ~ 0 1 2 abB Q a . 7 N M D E K J L I G F H S R 8 U V T - 6 5 4 3 Z Y X W C P db

129 data[idx] = ptr # for later dealloc 2/ : s t b c k l m n u v d e o p q r w x y z f g h i bbcb; = ? @ [ ] 9 ! # $ % ' ( ) * + , ^ _ ` j { | } ~ 0 1 2 abB Q a . 7 N M D E K J L I G F H S R 8 U V T - 6 5 4 3 Z Y X W C P db

130 return 0 2/ : s t b c k l m n u v d e o p q r w x y z f g h i bbcb; = ? @ [ ] 9 ! # $ % ' ( ) * + , ^ _ ` j { | } ~ 0 1 2 abB Q a . 7 N M D E K J L I G F H S R 8 U V T - 6 5 4 3 Z Y X W C P db

131  

132  

133cdef inline int prepare_tensor_map_arg( 

134 vector.vector[void*]& data, 

135 vector.vector[void*]& data_addresses, 

136 TensorMapDescriptor arg, 

137 const size_t idx) except -1: 

138 # cuLaunchKernel copies argument bytes during launch, so a TensorMap 

139 # descriptor can point directly at its internal CUtensorMap storage. 

140 data_addresses[idx] = arg._get_data_ptr() 

141 return 0 

142  

143  

144cdef inline int prepare_ctypes_arg( 

145 vector.vector[void*]& data, 

146 vector.vector[void*]& data_addresses, 

147 arg, 

148 const size_t idx) except -1: 

149 cdef object arg_type = type(arg) 1OstbcklmnuvdeopqrwxyzfghijBaANMDEKJLIGFHC

150 if arg_type is ctypes_bool: 1stbcklmnuvdeopqrwxyzfghijBaANMDEKJLIGFHC

151 return prepare_arg[cpp_bool](data, data_addresses, arg.value, idx) 1klopN

152 elif arg_type is ctypes_int8: 1stbcklmnuvdeopqrwxyzfghijBaAMDEKJLIGFHC

153 return prepare_arg[int8_t](data, data_addresses, arg.value, idx) 1M

154 elif arg_type is ctypes_int16: 1OstbcklmnuvdeopqrwxyzfghijBaADEKJLIGFHC

155 return prepare_arg[int16_t](data, data_addresses, arg.value, idx) 1L

156 elif arg_type is ctypes_int32: 1stbcklmnuvdeopqrwxyzfghijBaADEKJIGFHC

157 return prepare_arg[int32_t](data, data_addresses, arg.value, idx) 1K

158 elif arg_type is ctypes_int64: 1stbcklmnuvdeopqrwxyzfghijBaADEJIGFHC

159 return prepare_arg[int64_t](data, data_addresses, arg.value, idx) 1OJ

160 elif arg_type is ctypes_uint8: 1stbcklmnuvdeopqrwxyzfghijBaADEIGFHC

161 return prepare_arg[uint8_t](data, data_addresses, arg.value, idx) 1I

162 elif arg_type is ctypes_uint16: 1stbcklmnuvdeopqrwxyzfghijBaADEGFHC

163 return prepare_arg[uint16_t](data, data_addresses, arg.value, idx) 1H

164 elif arg_type is ctypes_uint32: 1OstbcklmnuvdeopqrwxyzfghijBaADEGFC

165 return prepare_arg[uint32_t](data, data_addresses, arg.value, idx) 1G

166 elif arg_type is ctypes_uint64: 1stbcklmnuvdeopqrwxyzfghijBaADEFC

167 return prepare_arg[uint64_t](data, data_addresses, arg.value, idx) 1F

168 elif arg_type is ctypes_float: 1stbcklmnuvdeopqrwxyzfghijBaADEC

169 return prepare_arg[float](data, data_addresses, arg.value, idx) 1E

170 elif arg_type is ctypes_double: 1stbcklmnuvdeopqrwxyzfghijBaADC

171 return prepare_arg[double](data, data_addresses, arg.value, idx) 1D

172 else: 

173 # If no exact types are found, fallback to slower `isinstance` check 

174 if isinstance(arg, ctypes_bool): 1stbcklmnuvdeopqrwxyzfghijBaAC

175 return prepare_arg[cpp_bool](data, data_addresses, arg.value, idx) 1B

176 elif isinstance(arg, ctypes_int8): 1stbcklmnuvdeopqrwxyzfghijBaAC

177 return prepare_arg[int8_t](data, data_addresses, arg.value, idx) 

178 elif isinstance(arg, ctypes_int16): 1stbcklmnuvdeopqrwxyzfghijBaAC

179 return prepare_arg[int16_t](data, data_addresses, arg.value, idx) 

180 elif isinstance(arg, ctypes_int32): 1stbcklmnuvdeopqrwxyzfghijBaAC

181 return prepare_arg[int32_t](data, data_addresses, arg.value, idx) 1BC

182 elif isinstance(arg, ctypes_int64): 1stbcklmnuvdeopqrwxyzfghijBaA

183 return prepare_arg[int64_t](data, data_addresses, arg.value, idx) 

184 elif isinstance(arg, ctypes_uint8): 1stbcklmnuvdeopqrwxyzfghijBaA

185 return prepare_arg[uint8_t](data, data_addresses, arg.value, idx) 

186 elif isinstance(arg, ctypes_uint16): 1stbcklmnuvdeopqrwxyzfghijBaA

187 return prepare_arg[uint16_t](data, data_addresses, arg.value, idx) 

188 elif isinstance(arg, ctypes_uint32): 1stbcklmnuvdeopqrwxyzfghijBaA

189 return prepare_arg[uint32_t](data, data_addresses, arg.value, idx) 

190 elif isinstance(arg, ctypes_uint64): 1stbcklmnuvdeopqrwxyzfghijBaA

191 return prepare_arg[uint64_t](data, data_addresses, arg.value, idx) 

192 elif isinstance(arg, ctypes_float): 1stbcklmnuvdeopqrwxyzfghijBaA

193 return prepare_arg[float](data, data_addresses, arg.value, idx) 1B

194 elif isinstance(arg, ctypes_double): 1OstbcklmnuvdeopqrwxyzfghijaA

195 return prepare_arg[double](data, data_addresses, arg.value, idx) 

196 else: 

197 return 1 1stbcklmnuvdeopqrwxyzfghijaA

198  

199  

200cdef inline int prepare_numpy_arg( 

201 vector.vector[void*]& data, 

202 vector.vector[void*]& data_addresses, 

203 arg, 

204 const size_t idx) except -1: 

205 cdef object arg_type = type(arg) 1stbcklmnuvdeopqrwxyzfghij012BQaA7NMDEKJLIGFHSRUVT6543ZYXWCP

206 if arg_type is numpy_bool: 1stbcklmnuvdeopqrwxyzfghij012BQaA7NMDEKJLIGFHSRUVT6543ZYXWCP

207 return prepare_arg[cpp_bool](data, data_addresses, arg, idx) 1mnqr7

208 elif arg_type is numpy_int8: 1stbcklmnuvdeopqrwxyzfghij012BQaANMDEKJLIGFHSRUVT6543ZYXWCP

209 return prepare_arg[int8_t](data, data_addresses, arg, idx) 16

210 elif arg_type is numpy_int16: 1stbcklmnuvdeopqrwxyzfghij012BQaANMDEKJLIGFHSRUVT543ZYXWCP

211 return prepare_arg[int16_t](data, data_addresses, arg, idx) 15

212 elif arg_type is numpy_int32: 1stbcklmnuvdeopqrwxyzfghij012BQaANMDEKJLIGFHSRUVT43ZYXWCP

213 return prepare_arg[int32_t](data, data_addresses, arg, idx) 1O0124

214 elif arg_type is numpy_int64: 1stbcklmnuvdeopqrwxyzfghijBQaANMDEKJLIGFHSRUVT3ZYXWCP

215 return prepare_arg[int64_t](data, data_addresses, arg, idx) 13

216 elif arg_type is numpy_uint8: 1stbcklmnuvdeopqrwxyzfghijBQaANMDEKJLIGFHSRUVTZYXWCP

217 return prepare_arg[uint8_t](data, data_addresses, arg, idx) 1Z

218 elif arg_type is numpy_uint16: 1stbcklmnuvdeopqrwxyzfghijBQaANMDEKJLIGFHSRUVTYXWCP

219 return prepare_arg[uint16_t](data, data_addresses, arg, idx) 1OY

220 elif arg_type is numpy_uint32: 1stbcklmnuvdeopqrwxyzfghijBQaANMDEKJLIGFHSRUVTXWCP

221 return prepare_arg[uint32_t](data, data_addresses, arg, idx) 1X

222 elif arg_type is numpy_uint64: 1stbcklmnuvdeopqrwxyzfghijBQaANMDEKJLIGFHSRUVTWCP

223 return prepare_arg[uint64_t](data, data_addresses, arg, idx) 1OW

224 elif arg_type is numpy_float16: 1stbcklmnuvdeopqrwxyzfghijBQaANMDEKJLIGFHSRUVTCP

225 return prepare_arg[__half_raw](data, data_addresses, arg, idx) 1U

226 elif arg_type is numpy_float32: 1stbcklmnuvdeopqrwxyzfghijBQaANMDEKJLIGFHSRVTCP

227 return prepare_arg[float](data, data_addresses, arg, idx) 1V

228 elif arg_type is numpy_float64: 1stbcklmnuvdeopqrwxyzfghijBQaANMDEKJLIGFHSRTCP

229 return prepare_arg[double](data, data_addresses, arg, idx) 1T

230 elif arg_type is numpy_complex64: 1stbcklmnuvdeopqrwxyzfghijBQaANMDEKJLIGFHSRCP

231 return prepare_arg[cpp_single_complex](data, data_addresses, arg, idx) 1S

232 elif arg_type is numpy_complex128: 1OstbcklmnuvdeopqrwxyzfghijBQaANMDEKJLIGFHRCP

233 return prepare_arg[cpp_double_complex](data, data_addresses, arg, idx) 1R

234 else: 

235 # If no exact types are found, fallback to slower `isinstance` check 

236 if isinstance(arg, numpy_bool): 1stbcklmnuvdeopqrwxyzfghijBQaANMDEKJLIGFHCP

237 return prepare_arg[cpp_bool](data, data_addresses, arg, idx) 

238 elif isinstance(arg, numpy_int8): 1stbcklmnuvdeopqrwxyzfghijBQaANMDEKJLIGFHCP

239 return prepare_arg[int8_t](data, data_addresses, arg, idx) 

240 elif isinstance(arg, numpy_int16): 1stbcklmnuvdeopqrwxyzfghijBQaANMDEKJLIGFHCP

241 return prepare_arg[int16_t](data, data_addresses, arg, idx) 

242 elif isinstance(arg, numpy_int32): 1stbcklmnuvdeopqrwxyzfghijBQaANMDEKJLIGFHCP

243 return prepare_arg[int32_t](data, data_addresses, arg, idx) 1Q

244 elif isinstance(arg, numpy_int64): 1stbcklmnuvdeopqrwxyzfghijBQaANMDEKJLIGFHCP

245 return prepare_arg[int64_t](data, data_addresses, arg, idx) 

246 elif isinstance(arg, numpy_uint8): 1OstbcklmnuvdeopqrwxyzfghijBQaANMDEKJLIGFHCP

247 return prepare_arg[uint8_t](data, data_addresses, arg, idx) 

248 elif isinstance(arg, numpy_uint16): 1stbcklmnuvdeopqrwxyzfghijBQaANMDEKJLIGFHCP

249 return prepare_arg[uint16_t](data, data_addresses, arg, idx) 

250 elif isinstance(arg, numpy_uint32): 1stbcklmnuvdeopqrwxyzfghijBQaANMDEKJLIGFHCP

251 return prepare_arg[uint32_t](data, data_addresses, arg, idx) 

252 elif isinstance(arg, numpy_uint64): 1stbcklmnuvdeopqrwxyzfghijBQaANMDEKJLIGFHCP

253 return prepare_arg[uint64_t](data, data_addresses, arg, idx) 

254 elif isinstance(arg, numpy_float16): 1stbcklmnuvdeopqrwxyzfghijBQaANMDEKJLIGFHCP

255 return prepare_arg[__half_raw](data, data_addresses, arg, idx) 

256 elif isinstance(arg, numpy_float32): 1stbcklmnuvdeopqrwxyzfghijBQaANMDEKJLIGFHCP

257 return prepare_arg[float](data, data_addresses, arg, idx) 1QP

258 elif isinstance(arg, numpy_float64): 1OstbcklmnuvdeopqrwxyzfghijBaANMDEKJLIGFHC

259 return prepare_arg[double](data, data_addresses, arg, idx) 

260 elif isinstance(arg, numpy_complex64): 1stbcklmnuvdeopqrwxyzfghijBaANMDEKJLIGFHC

261 return prepare_arg[cpp_single_complex](data, data_addresses, arg, idx) 

262 elif isinstance(arg, numpy_complex128): 1stbcklmnuvdeopqrwxyzfghijBaANMDEKJLIGFHC

263 return prepare_arg[cpp_double_complex](data, data_addresses, arg, idx) 

264 else: 

265 return 1 1stbcklmnuvdeopqrwxyzfghijBaANMDEKJLIGFHC

266  

267  

268cdef class ParamHolder: 

269  

270 def __init__(self, kernel_args): 

271 if len(kernel_args) == 0: 2/ ebfb: gbhbs t b c k l m n u v d e o p q r w x y z f g h i ibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbbbcbIbJbKbLbMb; = ? @ [ ] 9 ! # $ % ' ( ) * + , ^ _ ` NbObPbQbRbj { | } ~ Sb0 1 2 abTbB Q a A Ub. 7 N M D E K J L I G F H S R 8 U V T - 6 5 4 3 Z Y X W C P dbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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*c+c,c-c.c

272 self.ptr = 0 2ebfbgbhbf g h i ibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbj SbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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*c+c,c-c.c

273 return 2ebfbgbhbf g h i ibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbj SbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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*c+c,c-c.c

274  

275 cdef size_t n_args = len(kernel_args) 2/ : s t b c k l m n u v d e o p q r w x y z f g h i bbcb; = ? @ [ ] 9 ! # $ % ' ( ) * + , ^ _ ` j { | } ~ 0 1 2 abB Q a A . 7 N M D E K J L I G F H S R 8 U V T - 6 5 4 3 Z Y X W C P db

276 cdef size_t i 

277 cdef int not_prepared 

278 cdef object arg_type 

279 self.data = vector.vector[voidptr](n_args, nullptr) 2/ : s t b c k l m n u v d e o p q r w x y z f g h i bbcb; = ? @ [ ] 9 ! # $ % ' ( ) * + , ^ _ ` j { | } ~ 0 1 2 abB Q a A . 7 N M D E K J L I G F H S R 8 U V T - 6 5 4 3 Z Y X W C P db

280 self.data_addresses = vector.vector[voidptr](n_args) 2/ : s t b c k l m n u v d e o p q r w x y z f g h i bbcb; = ? @ [ ] 9 ! # $ % ' ( ) * + , ^ _ ` j { | } ~ 0 1 2 abB Q a A . 7 N M D E K J L I G F H S R 8 U V T - 6 5 4 3 Z Y X W C P db

281 for i, arg in enumerate(kernel_args): 2/ : s t b c k l m n u v d e o p q r w x y z f g h i bbcb; = ? @ [ ] 9 ! # $ % ' ( ) * + , ^ _ ` j { | } ~ 0 1 2 abB Q a A . 7 N M D E K J L I G F H S R 8 U V T - 6 5 4 3 Z Y X W C P db

282 arg_type = type(arg) 2/ : s t b c k l m n u v d e o p q r w x y z f g h i bbcb; = ? @ [ ] 9 ! # $ % ' ( ) * + , ^ _ ` j { | } ~ 0 1 2 abB Q a A . 7 N M D E K J L I G F H S R 8 U V T - 6 5 4 3 Z Y X W C P db

283 if arg_type is Buffer: 2/ : s t b c k l m n u v d e o p q r w x y z f g h i bbcb; = ? @ [ ] 9 ! # $ % ' ( ) * + , ^ _ ` j { | } ~ 0 1 2 abB Q a A . 7 N M D E K J L I G F H S R 8 U V T - 6 5 4 3 Z Y X W C P db

284 # we need the address of where the actual buffer address is stored 

285 if type(arg.handle) is int: 2bbcb9 ! # $ % ' ( ) * + , 0 1 2 db

286 # see note below on handling int arguments 

287 prepare_arg[intptr_t](self.data, self.data_addresses, arg.handle, i) 2bbcb9 ! # $ % ' ( ) * + , 0 1 2 db

288 continue 2bbcb9 ! # $ % ' ( ) * + , 0 1 2 db

289 else: 

290 # it's a CUdeviceptr: 

291 self.data_addresses[i] = <void*><intptr_t>(arg.handle.getPtr()) 

292 continue 

293 elif arg_type is bool: 2/ : s t b c k l m n u v d e o p q r w x y z f g h i ; = ? @ [ ] 9 ! # $ % ' ( ) * + , ^ _ ` j { | } ~ 0 1 2 abB Q a A . 7 N M D E K J L I G F H S R 8 U V T - 6 5 4 3 Z Y X W C P

294 prepare_arg[cpp_bool](self.data, self.data_addresses, arg, i) 1bcdej.

295 continue 1bcdej.

296 elif arg_type is int: 2/ : s t b c k l m n u v d e o p q r w x y z f g h i ; = ? @ [ ] 9 ! # $ % ' ( ) * + , ^ _ ` j { | } ~ 0 1 2 abB Q a A . 7 N M D E K J L I G F H S R 8 U V T - 6 5 4 3 Z Y X W C P

297 # Here's the dilemma: We want to have a fast path to pass in Python 

298 # integers as pointer addresses, but one could also (mistakenly) pass 

299 # it with the intention of passing a scalar integer. It's a mistake 

300 # bacause a Python int is ambiguous (arbitrary width). Our judgement 

301 # call here is to treat it as a pointer address, without any warning! 

302 prepare_arg[intptr_t](self.data, self.data_addresses, arg, i) 2/ : s t b c k l m n u v d e o p q r w x y z f g h i ; = ? @ [ ] 9 ! # $ % ' ( ) * + , ^ _ ` { | } ~ ab. 7 N M D E K J L I G F H S R 8 U V T - 6 5 4 3 Z Y X W C P

303 continue 2/ : s t b c k l m n u v d e o p q r w x y z f g h i ; = ? @ [ ] 9 ! # $ % ' ( ) * + , ^ _ ` { | } ~ ab. 7 N M D E K J L I G F H S R 8 U V T - 6 5 4 3 Z Y X W C P

304 elif arg_type is float: 1stbcklmnuvdeopqrwxyzfghij012BQaA7NMDEKJLIGFHSR8UVT-6543ZYXWCP

305 prepare_arg[double](self.data, self.data_addresses, arg, i) 1-

306 continue 1-

307 elif arg_type is complex: 1stbcklmnuvdeopqrwxyzfghij012BQaA7NMDEKJLIGFHSR8UVT6543ZYXWCP

308 prepare_arg[cpp_double_complex](self.data, self.data_addresses, arg, i) 18

309 continue 18

310 elif arg_type is tensor_map_descriptor_type: 1stbcklmnuvdeopqrwxyzfghij012BQaA7NMDEKJLIGFHSRUVT6543ZYXWCP

311 prepare_tensor_map_arg(self.data, self.data_addresses, <TensorMapDescriptor>arg, i) 

312 continue 

313  

314 not_prepared = prepare_numpy_arg(self.data, self.data_addresses, arg, i) 1stbcklmnuvdeopqrwxyzfghij012BQaA7NMDEKJLIGFHSRUVT6543ZYXWCP

315 if not_prepared: 1stbcklmnuvdeopqrwxyzfghij012BQaA7NMDEKJLIGFHSRUVT6543ZYXWCP

316 not_prepared = prepare_ctypes_arg(self.data, self.data_addresses, arg, i) 1stbcklmnuvdeopqrwxyzfghijBaANMDEKJLIGFHC

317 if not_prepared: 1stbcklmnuvdeopqrwxyzfghij012BQaA7NMDEKJLIGFHSRUVT6543ZYXWCP

318 # TODO: revisit this treatment if we decide to cythonize cuda.core 

319 if arg_type is driver.CUgraphConditionalHandle: 1stbcklmnuvdeopqrwxyzfghijaA

320 prepare_arg[cydriver.CUgraphConditionalHandle](self.data, self.data_addresses, <intptr_t>int(arg), i) 

321 continue 

322 elif arg_type is GraphCondition: 1stbcklmnuvdeopqrwxyzfghijaA

323 prepare_arg[cydriver.CUgraphConditionalHandle]( 1stbcklmnuvdeopqrwxyzfghij

324 self.data, self.data_addresses, 

325 <intptr_t><unsigned long long>(<GraphCondition>arg)._c_handle, i) 1stbcklmnuvdeopqrwxyzfghij

326 continue 1stbcklmnuvdeopqrwxyzfghij

327 # If no exact types are found, fallback to slower `isinstance` check 

328 elif isinstance(arg, Buffer): 1aA

329 if isinstance(arg.handle, int): 

330 prepare_arg[intptr_t](self.data, self.data_addresses, arg.handle, i) 

331 continue 

332 else: 

333 self.data_addresses[i] = <void*><intptr_t>(arg.handle.getPtr()) 

334 continue 

335 elif isinstance(arg, bool): 1aA

336 prepare_arg[cpp_bool](self.data, self.data_addresses, arg, i) 

337 continue 

338 elif isinstance(arg, int): 1OaA

339 prepare_arg[intptr_t](self.data, self.data_addresses, arg, i) 1a

340 continue 1a

341 elif isinstance(arg, float): 1aA

342 prepare_arg[double](self.data, self.data_addresses, arg, i) 1a

343 continue 1a

344 elif isinstance(arg, complex): 1aA

345 prepare_arg[cpp_double_complex](self.data, self.data_addresses, arg, i) 1a

346 continue 1a

347 elif isinstance(arg, driver.CUgraphConditionalHandle): 1A

348 prepare_arg[cydriver.CUgraphConditionalHandle](self.data, self.data_addresses, arg, i) 

349 continue 

350 elif isinstance(arg, GraphCondition): 1A

351 prepare_arg[cydriver.CUgraphConditionalHandle]( 

352 self.data, self.data_addresses, 

353 <intptr_t><unsigned long long>(<GraphCondition>arg)._c_handle, i) 

354 continue 

355 # TODO: support ctypes/numpy struct 

356 raise TypeError("the argument is of unsupported type: " + str(type(arg))) 1A

357  

358 self.kernel_args = kernel_args 2O / : s t b c k l m n u v d e o p q r w x y z f g h i bbcb; = ? @ [ ] 9 ! # $ % ' ( ) * + , ^ _ ` j { | } ~ 0 1 2 abB Q a . 7 N M D E K J L I G F H S R 8 U V T - 6 5 4 3 Z Y X W C P db

359 self.ptr = <intptr_t>self.data_addresses.data() 2/ : s t b c k l m n u v d e o p q r w x y z f g h i bbcb; = ? @ [ ] 9 ! # $ % ' ( ) * + , ^ _ ` j { | } ~ 0 1 2 abB Q a . 7 N M D E K J L I G F H S R 8 U V T - 6 5 4 3 Z Y X W C P db

360  

361 def __dealloc__(self): 

362 for data in self.data: 2/ ebfb: gbhbs t b c k l m n u v d e o p q r w x y z f g h i ibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbbbcbIbJbKbLbMb; = ? @ [ ] 9 ! # $ % ' ( ) * + , ^ _ ` NbObPbQbRbj { | } ~ Sb0 1 2 abTbB Q a A Ub. 7 N M D E K J L I G F H S R 8 U V T - 6 5 4 3 Z Y X W C P dbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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*c+c,c-c.c

363 if data: 2/ : s t b c k l m n u v d e o p q r w x y z f g h i bbcb; = ? @ [ ] 9 ! # $ % ' ( ) * + , ^ _ ` j { | } ~ 0 1 2 abB Q a A . 7 N M D E K J L I G F H S R 8 U V T - 6 5 4 3 Z Y X W C P db

364 PyMem_Free(data) 2/ : s t b c k l m n u v d e o p q r w x y z f g h i bbcb; = ? @ [ ] 9 ! # $ % ' ( ) * + , ^ _ ` j { | } ~ 0 1 2 abB Q a . 7 N M D E K J L I G F H S R 8 U V T - 6 5 4 3 Z Y X W C P db