Coverage for cuda/core/_module.pyx: 71.83%
284 statements
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-16 01:23 +0000
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-16 01:23 +0000
1# SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2#
3# SPDX-License-Identifier: Apache-2.0
5from __future__ import annotations
7cimport cython
8from libc.stddef cimport size_t
9from libcpp.mutex cimport py_safe_call_once
11from collections import namedtuple
12from os import fsencode, fspath, PathLike
14from cuda.core._device import Device
15from cuda.core._launch_config cimport LaunchConfig
16from cuda.core._launch_config import LaunchConfig
17from cuda.core._stream cimport Stream, Stream_accept
18from cuda.core._program import ObjectCodeFormatType
19from cuda.core._rt cimport (
20 LibraryHandle,
21 KernelHandle,
22 create_library_handle_from_file,
23 create_library_handle_from_data,
24 create_kernel_handle,
25 create_kernel_handle_ref,
26 get_kernel_library,
27 get_last_error,
28 as_cu,
29 as_py,
30 as_intptr,
31)
32from cuda.core._stream import Stream
33from cuda.core._utils.clear_error_support import (
34 assert_type_str_or_bytes_like,
35 raise_code_path_meant_to_be_unreachable,
36)
37from cuda.core._utils.cuda_utils cimport HANDLE_RETURN
38from cuda.core._utils.version cimport cy_driver_version
39from cuda.core._utils.cuda_utils import driver
40from cuda.bindings cimport cydriver
42__all__ = ["Kernel", "ObjectCode"]
45cdef class KernelAttributes:
46 """Read-only view of a kernel's per-device attributes.
48 The default view returned by :attr:`Kernel.attributes` is bound to
49 the current device, resolved at attribute-access time. Use
50 ``kernel.attributes[device]`` to obtain a view bound to a specific
51 device (an :class:`int` device ordinal or :class:`Device`). Per-device
52 views share the underlying cache so a value queried through one view
53 is visible through the others.
54 """
56 def __init__(self, *args, **kwargs) -> None:
57 raise RuntimeError("KernelAttributes cannot be instantiated directly. Please use Kernel APIs.") 2?h
59 @staticmethod
60 cdef KernelAttributes _init(KernelHandle h_kernel):
61 cdef KernelAttributes self = KernelAttributes.__new__(KernelAttributes) 2b c d Pfdbo a z s A B C D E F G H I J K L M N O P Q R )d%d*d'd+d,d-d.d(d/d:d;d=d?d@d[d
62 self._h_kernel = h_kernel 2b c d Pfdbo a z s A B C D E F G H I J K L M N O P Q R )d%d*d'd+d,d-d.d(d/d:d;d=d?d@d[d
63 self._device_id = -1 2b c d Pfdbo a z s A B C D E F G H I J K L M N O P Q R )d%d*d'd+d,d-d.d(d/d:d;d=d?d@d[d
64 self._cache = {} 2b c d Pfdbo a z s A B C D E F G H I J K L M N O P Q R )d%d*d'd+d,d-d.d(d/d:d;d=d?d@d[d
65 return self 2b c d Pfdbo a z s A B C D E F G H I J K L M N O P Q R )d%d*d'd+d,d-d.d(d/d:d;d=d?d@d[d
67 cdef KernelAttributes _view_for_device(self, int device_id):
68 cdef KernelAttributes view = KernelAttributes.__new__(KernelAttributes) 2db)d%d*d'd+d,d-d.d(d/d:d;d=d?d@d[d
69 view._h_kernel = self._h_kernel 2db)d%d*d'd+d,d-d.d(d/d:d;d=d?d@d[d
70 view._device_id = device_id 2db)d%d*d'd+d,d-d.d(d/d:d;d=d?d@d[d
71 view._cache = self._cache 2db)d%d*d'd+d,d-d.d(d/d:d;d=d?d@d[d
72 return view 2db)d%d*d'd+d,d-d.d(d/d:d;d=d?d@d[d
74 cdef inline int _effective_device_id(self) except? -1:
75 if self._device_id >= 0: 2b c d dbo a z s A B C D E F G H I J K L M N O P Q R )d%d*d'd+d,d-d.d(d/d:d;d=d?d@d[d
76 return self._device_id 2db)d%d*d'd+d,d-d.d(d/d:d;d=d?d@d[d
77 return Device().device_id 2b c d dbo a z s A B C D E F G H I J K L M N O P Q R )d%d*d'd+d,d-d.d(d/d:d;d=d?d@d[d
79 cdef int _get_cached_attribute(self, int device_id, cydriver.CUfunction_attribute attribute) except? -1:
80 """Helper function to get a cached attribute or fetch and cache it if not present."""
81 cdef tuple cache_key = (device_id, <int>attribute) 2b c d dbo a z s A B C D E F G H I J K L M N O P Q R )d%d*d'd+d,d-d.d(d/d:d;d=d?d@d[d
82 cached = self._cache.get(cache_key, cache_key) 2b c d dbo a z s A B C D E F G H I J K L M N O P Q R )d%d*d'd+d,d-d.d(d/d:d;d=d?d@d[d
83 if cached is not cache_key: 2b c d dbo a z s A B C D E F G H I J K L M N O P Q R )d%d*d'd+d,d-d.d(d/d:d;d=d?d@d[d
84 return cached 2db)d%d*d'd+d,d-d.d(d/d:d;d=d?d@d[d
85 cdef int result
86 with nogil: 2b c d dbo a z s A B C D E F G H I J K L M N O P Q R )d%d*d'd+d,d-d.d(d/d:d;d=d?d@d[d
87 HANDLE_RETURN(cydriver.cuKernelGetAttribute(&result, attribute, as_cu(self._h_kernel), device_id)) 2b c d dbo a z s A B C D E F G H I J K L M N O P Q R )d%d*d'd+d,d-d.d(d/d:d;d=d?d@d[d
88 self._cache[cache_key] = result # setdefault not needed for ints 2b c d dbo a z s A B C D E F G H I J K L M N O P Q R )d%d*d'd+d,d-d.d(d/d:d;d=d?d@d[d
89 return result 2b c d dbo a z s A B C D E F G H I J K L M N O P Q R )d%d*d'd+d,d-d.d(d/d:d;d=d?d@d[d
91 def __getitem__(self, device: Device | int) -> KernelAttributes:
92 """Return a view of these attributes bound to a specific device.
94 Parameters
95 ----------
96 device : Device or int
97 The device whose attributes to query. Accepts a :class:`Device`
98 or a device ordinal (:class:`int`).
100 Returns
101 -------
102 KernelAttributes
103 A view bound to ``device`` that shares the underlying cache
104 with this view.
105 """
106 return self._view_for_device(Device(device).device_id) 2Pfdb)d%d*d'd+d,d-d.d(d/d:d;d=d?d@d[d
108 @property
109 def max_threads_per_block(self) -> int:
110 """int : The maximum number of threads per block.
111 This attribute is read-only."""
112 return self._get_cached_attribute( 2b c d dbo a z s .d
113 self._effective_device_id(), cydriver.CU_FUNC_ATTRIBUTE_MAX_THREADS_PER_BLOCK 2b c d dbo a z s .d
114 )
116 @property
117 def shared_size_bytes(self) -> int:
118 """int : The size in bytes of statically-allocated shared memory required by this function.
119 This attribute is read-only."""
120 return self._get_cached_attribute( 2[d
121 self._effective_device_id(), cydriver.CU_FUNC_ATTRIBUTE_SHARED_SIZE_BYTES 2[d
122 )
124 @property
125 def const_size_bytes(self) -> int:
126 """int : The size in bytes of user-allocated constant memory required by this function.
127 This attribute is read-only."""
128 return self._get_cached_attribute( 2+d
129 self._effective_device_id(), cydriver.CU_FUNC_ATTRIBUTE_CONST_SIZE_BYTES 2+d
130 )
132 @property
133 def local_size_bytes(self) -> int:
134 """int : The size in bytes of local memory used by each thread of this function.
135 This attribute is read-only."""
136 return self._get_cached_attribute( 2,d
137 self._effective_device_id(), cydriver.CU_FUNC_ATTRIBUTE_LOCAL_SIZE_BYTES 2,d
138 )
140 @property
141 def num_regs(self) -> int:
142 """int : The number of registers used by each thread of this function.
143 This attribute is read-only."""
144 return self._get_cached_attribute( 2dbA B C D E F G H I J K L M N O P Q R /d
145 self._effective_device_id(), cydriver.CU_FUNC_ATTRIBUTE_NUM_REGS 2dbA B C D E F G H I J K L M N O P Q R /d
146 )
148 @property
149 def ptx_version(self) -> int:
150 """int : The PTX virtual architecture version for which the function was compiled.
151 This attribute is read-only."""
152 return self._get_cached_attribute( 2;d
153 self._effective_device_id(), cydriver.CU_FUNC_ATTRIBUTE_PTX_VERSION 2;d
154 )
156 @property
157 def binary_version(self) -> int:
158 """int : The binary architecture version for which the function was compiled.
159 This attribute is read-only."""
160 return self._get_cached_attribute( 2)d
161 self._effective_device_id(), cydriver.CU_FUNC_ATTRIBUTE_BINARY_VERSION 2)d
162 )
164 @property
165 def cache_mode_ca(self) -> bool:
166 """bool : Whether the function has been compiled with user specified option "-Xptxas --dlcm=ca" set.
167 This attribute is read-only."""
168 return bool( 2%d
169 self._get_cached_attribute( 2%d
170 self._effective_device_id(), cydriver.CU_FUNC_ATTRIBUTE_CACHE_MODE_CA 2%d
171 )
172 )
174 @property
175 def max_dynamic_shared_size_bytes(self) -> int:
176 """int : The maximum size in bytes of dynamically-allocated shared memory that can be used
177 by this function."""
178 return self._get_cached_attribute( 2-d
179 self._effective_device_id(), cydriver.CU_FUNC_ATTRIBUTE_MAX_DYNAMIC_SHARED_SIZE_BYTES 2-d
180 )
182 @property
183 def preferred_shared_memory_carveout(self) -> int:
184 """int : The shared memory carveout preference, in percent of the total shared memory."""
185 return self._get_cached_attribute( 2:d
186 self._effective_device_id(), cydriver.CU_FUNC_ATTRIBUTE_PREFERRED_SHARED_MEMORY_CARVEOUT 2:d
187 )
189 @property
190 def cluster_size_must_be_set(self) -> bool:
191 """bool : The kernel must launch with a valid cluster size specified.
192 This attribute is read-only."""
193 return bool( 2'd
194 self._get_cached_attribute( 2'd
195 self._effective_device_id(), cydriver.CU_FUNC_ATTRIBUTE_CLUSTER_SIZE_MUST_BE_SET 2'd
196 )
197 )
199 @property
200 def required_cluster_width(self) -> int:
201 """int : The required cluster width in blocks."""
202 return self._get_cached_attribute( 2@d
203 self._effective_device_id(), cydriver.CU_FUNC_ATTRIBUTE_REQUIRED_CLUSTER_WIDTH 2@d
204 )
206 @property
207 def required_cluster_height(self) -> int:
208 """int : The required cluster height in blocks."""
209 return self._get_cached_attribute( 2?d
210 self._effective_device_id(), cydriver.CU_FUNC_ATTRIBUTE_REQUIRED_CLUSTER_HEIGHT 2?d
211 )
213 @property
214 def required_cluster_depth(self) -> int:
215 """int : The required cluster depth in blocks."""
216 return self._get_cached_attribute( 2=d
217 self._effective_device_id(), cydriver.CU_FUNC_ATTRIBUTE_REQUIRED_CLUSTER_DEPTH 2=d
218 )
220 @property
221 def non_portable_cluster_size_allowed(self) -> bool:
222 """bool : Whether the function can be launched with non-portable cluster size."""
223 return bool( 2(d
224 self._get_cached_attribute( 2(d
225 self._effective_device_id(), 2(d
226 cydriver.CU_FUNC_ATTRIBUTE_NON_PORTABLE_CLUSTER_SIZE_ALLOWED,
227 )
228 )
230 @property
231 def cluster_scheduling_policy_preference(self) -> int:
232 """int : The block scheduling policy of a function."""
233 return self._get_cached_attribute( 2*d
234 self._effective_device_id(), 2*d
235 cydriver.CU_FUNC_ATTRIBUTE_CLUSTER_SCHEDULING_POLICY_PREFERENCE,
236 )
239MaxPotentialBlockSizeOccupancyResult = namedtuple(
240 "MaxPotentialBlockSizeOccupancyResult", ("min_grid_size", "max_block_size")
241)
244cdef class KernelOccupancy:
245 """This class offers methods to query occupancy metrics that help determine optimal
246 launch parameters such as block size, grid size, and shared memory usage.
247 """
249 def __init__(self, *args, **kwargs) -> None:
250 raise RuntimeError("KernelOccupancy cannot be instantiated directly. Please use Kernel APIs.") 2@h
252 @staticmethod
253 cdef KernelOccupancy _init(KernelHandle h_kernel):
254 cdef KernelOccupancy self = KernelOccupancy.__new__(KernelOccupancy) 2n )e*e+e,e-e.eA B C D E F G H I J K L M N O P Q R }d~daebecedeeefegeheiejekelemeneoepeqerese
255 self._h_kernel = h_kernel 2n )e*e+e,e-e.eA B C D E F G H I J K L M N O P Q R }d~daebecedeeefegeheiejekelemeneoepeqerese
256 return self 2n )e*e+e,e-e.eA B C D E F G H I J K L M N O P Q R }d~daebecedeeefegeheiejekelemeneoepeqerese
258 def max_active_blocks_per_multiprocessor(self, block_size: int, dynamic_shared_memory_size: int) -> int:
259 """Occupancy of the kernel.
261 Returns the maximum number of active blocks per multiprocessor for this kernel.
263 Parameters
264 ----------
265 block_size: int
266 Block size parameter used to launch this kernel.
267 dynamic_shared_memory_size: int
268 The amount of dynamic shared memory in bytes needed by block.
269 Use `0` if block does not need shared memory.
271 Returns
272 -------
273 int
274 The maximum number of active blocks per multiprocessor.
276 Note
277 ----
278 The fraction of the product of maximum number of active blocks per multiprocessor
279 and the block size to the maximum number of threads per multiprocessor is known as
280 theoretical multiprocessor utilization (occupancy).
282 """
283 cdef int num_blocks
284 cdef int c_block_size = block_size 1nABCDEFGHIJKLMNOPQR
285 cdef size_t c_shmem_size = dynamic_shared_memory_size 1nABCDEFGHIJKLMNOPQR
286 cdef cydriver.CUfunction func = <cydriver.CUfunction>as_cu(self._h_kernel) 1nABCDEFGHIJKLMNOPQR
287 with nogil: 1nABCDEFGHIJKLMNOPQR
288 HANDLE_RETURN(cydriver.cuOccupancyMaxActiveBlocksPerMultiprocessor( 1nABCDEFGHIJKLMNOPQR
289 &num_blocks, func, c_block_size, c_shmem_size
290 ))
291 return num_blocks 1nABCDEFGHIJKLMNOPQR
293 def max_potential_block_size(
294 self, dynamic_shared_memory_needed: int | driver.CUoccupancyB2DSize, block_size_limit: int
295 ) -> MaxPotentialBlockSizeOccupancyResult:
296 """MaxPotentialBlockSizeOccupancyResult: Suggested launch configuration for reasonable occupancy.
298 Returns the minimum grid size needed to achieve the maximum occupancy and
299 the maximum block size that can achieve the maximum occupancy.
301 Parameters
302 ----------
303 dynamic_shared_memory_needed: int | driver.CUoccupancyB2DSize
304 The amount of dynamic shared memory in bytes needed by block.
305 Use `0` if block does not need shared memory. Use C-callable
306 represented by :obj:`~driver.CUoccupancyB2DSize` to encode
307 amount of needed dynamic shared memory which varies depending
308 on tne block size.
309 block_size_limit: int
310 Known upper limit on the kernel block size. Use `0` to indicate
311 the maximum block size permitted by the device / kernel instead
313 Returns
314 -------
315 :obj:`~MaxPotentialBlockSizeOccupancyResult`
316 An object with `min_grid_size` and `max_block_size` attributes encoding
317 the suggested launch configuration.
319 Note
320 ----
321 Please be advised that use of C-callable that requires Python Global
322 Interpreter Lock may lead to deadlocks.
324 """
325 cdef int min_grid_size, max_block_size
326 cdef cydriver.CUfunction func = <cydriver.CUfunction>as_cu(self._h_kernel) 2}d~daebecedeeefegeheiejekelemeneoepeqerese
327 cdef cydriver.CUoccupancyB2DSize callback
328 cdef size_t c_shmem_size
329 cdef int c_block_size_limit = block_size_limit 2}d~daebecedeeefegeheiejekelemeneoepeqerese
330 if isinstance(dynamic_shared_memory_needed, int): 2}d~daebecedeeefegeheiejekelemeneoepeqerese
331 c_shmem_size = dynamic_shared_memory_needed 2}d~daebecedeeefegeheiejekelemeneoepeqerese
332 with nogil: 2}d~daebecedeeefegeheiejekelemeneoepeqerese
333 HANDLE_RETURN(cydriver.cuOccupancyMaxPotentialBlockSize( 2}d~daebecedeeefegeheiejekelemeneoepeqerese
334 &min_grid_size, &max_block_size, func, NULL, c_shmem_size, c_block_size_limit
335 ))
336 elif isinstance(dynamic_shared_memory_needed, driver.CUoccupancyB2DSize): 2}d~daebecedeeefegeheiejekelemeneoepeqerese
337 # Callback may require GIL, so don't use nogil here
338 callback = <cydriver.CUoccupancyB2DSize><size_t>dynamic_shared_memory_needed.getPtr()
339 HANDLE_RETURN(cydriver.cuOccupancyMaxPotentialBlockSize(
340 &min_grid_size, &max_block_size, func, callback, 0, c_block_size_limit
341 ))
342 else:
343 raise TypeError( 2}d~daebecedeeefegeheiejekelemeneoepeqerese
344 "dynamic_shared_memory_needed expected to have type int, or CUoccupancyB2DSize, " 2}d~daebecedeeefegeheiejekelemeneoepeqerese
345 f"got {type(dynamic_shared_memory_needed)}" 2}d~daebecedeeefegeheiejekelemeneoepeqerese
346 )
347 return MaxPotentialBlockSizeOccupancyResult(min_grid_size=min_grid_size, max_block_size=max_block_size) 2}d~daebecedeeefegeheiejekelemeneoepeqerese
349 def available_dynamic_shared_memory_per_block(self, num_blocks_per_multiprocessor: int, block_size: int) -> int:
350 """Dynamic shared memory available per block for given launch configuration.
352 The amount of dynamic shared memory per block, in bytes, for given kernel launch configuration.
354 Parameters
355 ----------
356 num_blocks_per_multiprocessor: int
357 Number of blocks to be concurrently executing on a multiprocessor.
358 block_size: int
359 Block size parameter used to launch this kernel.
361 Returns
362 -------
363 int
364 Dynamic shared memory available per block for given launch configuration.
365 """
366 cdef size_t dynamic_smem_size
367 cdef int c_num_blocks = num_blocks_per_multiprocessor 2)e*e+e,e-e.e
368 cdef int c_block_size = block_size 2)e*e+e,e-e.e
369 cdef cydriver.CUfunction func = <cydriver.CUfunction>as_cu(self._h_kernel) 2)e*e+e,e-e.e
370 with nogil: 2)e*e+e,e-e.e
371 HANDLE_RETURN(cydriver.cuOccupancyAvailableDynamicSMemPerBlock( 2)e*e+e,e-e.e
372 &dynamic_smem_size, func, c_num_blocks, c_block_size
373 ))
374 return dynamic_smem_size 2)e*e+e,e-e.e
376 def max_potential_cluster_size(self, LaunchConfig config not None: LaunchConfig, *, Stream stream not None: Stream) -> int:
377 """Maximum potential cluster size.
379 The maximum potential cluster size for this kernel and given launch configuration.
381 Parameters
382 ----------
383 config: :obj:`~_launch_config.LaunchConfig`
384 Kernel launch configuration. Cluster dimensions in the configuration are ignored.
385 stream: :obj:`~Stream`
386 Keyword-only. The stream on which this kernel is to be launched.
387 Must be passed explicitly; pass ``device.default_stream`` to
388 use the default stream.
390 Returns
391 -------
392 int
393 The maximum cluster size that can be launched for this kernel and launch configuration.
394 """
395 cdef cydriver.CUlaunchConfig drv_cfg = config._to_native_launch_config()
396 cdef Stream s = Stream_accept(stream)
397 drv_cfg.hStream = as_cu(s._h_stream)
398 cdef int cluster_size
399 cdef cydriver.CUfunction func = <cydriver.CUfunction>as_cu(self._h_kernel)
400 with nogil:
401 HANDLE_RETURN(cydriver.cuOccupancyMaxPotentialClusterSize(&cluster_size, func, &drv_cfg))
402 return cluster_size
404 def max_active_clusters(self, LaunchConfig config not None: LaunchConfig, *, Stream stream not None: Stream) -> int:
405 """Maximum number of active clusters on the target device.
407 The maximum number of clusters that could concurrently execute on the target device.
409 Parameters
410 ----------
411 config: :obj:`~_launch_config.LaunchConfig`
412 Kernel launch configuration.
413 stream: :obj:`~Stream`
414 Keyword-only. The stream on which this kernel is to be launched.
415 Must be passed explicitly; pass ``device.default_stream`` to
416 use the default stream.
418 Returns
419 -------
420 int
421 The maximum number of clusters that could co-exist on the target device.
422 """
423 cdef cydriver.CUlaunchConfig drv_cfg = config._to_native_launch_config()
424 cdef Stream s = Stream_accept(stream)
425 drv_cfg.hStream = as_cu(s._h_stream)
426 cdef int num_clusters
427 cdef cydriver.CUfunction func = <cydriver.CUfunction>as_cu(self._h_kernel)
428 with nogil:
429 HANDLE_RETURN(cydriver.cuOccupancyMaxActiveClusters(&num_clusters, func, &drv_cfg))
430 return num_clusters
433ParamInfo = namedtuple("ParamInfo", ["offset", "size"])
436cdef class Kernel:
437 """Represent a compiled kernel that had been loaded onto the device.
439 Kernel instances can execution when passed directly into the
440 :func:`~launch` function.
442 Directly creating a :obj:`~_module.Kernel` is not supported, and they
443 should instead be created through a :obj:`~_module.ObjectCode` object.
445 """
447 def __init__(self, *args, **kwargs) -> None:
448 raise RuntimeError("Kernel objects cannot be instantiated directly. Please use ObjectCode APIs.") 2[h
450 @staticmethod
451 cdef Kernel _from_handle(KernelHandle h_kernel):
452 cdef Kernel ker = Kernel.__new__(Kernel) 2ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b4h7b8b5h9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]bb c d ^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmc^ _ ` V ncocpcqcrcsctcucvcwcxcyczc{ | } Ac~ abbbcbBcCcDcEcFcGcHcIcJcKcLcMcNcW X Y Z 0 1 2 3 4 5 n OcPc6 xeyezeAeBeCeDeEeFeGeHeIeJe7 8 KeLeMeNe`dOePeQeRe{dSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e7e8e9e!e#e$e%eQcRcScTcUcVcWcXcYcZc0c1cv w x y 9 ! # 2c3c] 4co 5ca te6cz 7cs 8ce 9cr p f g h i q j k l m !cS #c$ $c% %cT ' ( t u 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQd) Rdue* Sd+ TdUd, Vd- Wd. XdYd/ Zd0d: 1d2d; 3d4d= 5d6d? 7d8d@ 9d!d[ #dU
453 ker._h_kernel = h_kernel 2ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b4h7b8b5h9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]bb c d ^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmc^ _ ` V ncocpcqcrcsctcucvcwcxcyczc{ | } Ac~ abbbcbBcCcDcEcFcGcHcIcJcKcLcMcNcW X Y Z 0 1 2 3 4 5 n OcPc6 xeyezeAeBeCeDeEeFeGeHeIeJe7 8 KeLeMeNe`dOePeQeRe{dSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e7e8e9e!e#e$e%eQcRcScTcUcVcWcXcYcZc0c1cv w x y 9 ! # 2c3c] 4co 5ca te6cz 7cs 8ce 9cr p f g h i q j k l m !cS #c$ $c% %cT ' ( t u 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQd) Rdue* Sd+ TdUd, Vd- Wd. XdYd/ Zd0d: 1d2d; 3d4d= 5d6d? 7d8d@ 9d!d[ #dU
454 ker._attributes = None 2ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b4h7b8b5h9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]bb c d ^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmc^ _ ` V ncocpcqcrcsctcucvcwcxcyczc{ | } Ac~ abbbcbBcCcDcEcFcGcHcIcJcKcLcMcNcW X Y Z 0 1 2 3 4 5 n OcPc6 xeyezeAeBeCeDeEeFeGeHeIeJe7 8 KeLeMeNe`dOePeQeRe{dSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e7e8e9e!e#e$e%eQcRcScTcUcVcWcXcYcZc0c1cv w x y 9 ! # 2c3c] 4co 5ca te6cz 7cs 8ce 9cr p f g h i q j k l m !cS #c$ $c% %cT ' ( t u 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQd) Rdue* Sd+ TdUd, Vd- Wd. XdYd/ Zd0d: 1d2d; 3d4d= 5d6d? 7d8d@ 9d!d[ #dU
455 ker._occupancy = None 2ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b4h7b8b5h9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]bb c d ^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmc^ _ ` V ncocpcqcrcsctcucvcwcxcyczc{ | } Ac~ abbbcbBcCcDcEcFcGcHcIcJcKcLcMcNcW X Y Z 0 1 2 3 4 5 n OcPc6 xeyezeAeBeCeDeEeFeGeHeIeJe7 8 KeLeMeNe`dOePeQeRe{dSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e7e8e9e!e#e$e%eQcRcScTcUcVcWcXcYcZc0c1cv w x y 9 ! # 2c3c] 4co 5ca te6cz 7cs 8ce 9cr p f g h i q j k l m !cS #c$ $c% %cT ' ( t u 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQd) Rdue* Sd+ TdUd, Vd- Wd. XdYd/ Zd0d: 1d2d; 3d4d= 5d6d? 7d8d@ 9d!d[ #dU
456 return ker 2ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b4h7b8b5h9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]bb c d ^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmc^ _ ` V ncocpcqcrcsctcucvcwcxcyczc{ | } Ac~ abbbcbBcCcDcEcFcGcHcIcJcKcLcMcNcW X Y Z 0 1 2 3 4 5 n OcPc6 xeyezeAeBeCeDeEeFeGeHeIeJe7 8 KeLeMeNe`dOePeQeRe{dSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e7e8e9e!e#e$e%eQcRcScTcUcVcWcXcYcZc0c1cv w x y 9 ! # 2c3c] 4co 5ca te6cz 7cs 8ce 9cr p f g h i q j k l m !cS #c$ $c% %cT ' ( t u 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQd) Rdue* Sd+ TdUd, Vd- Wd. XdYd/ Zd0d: 1d2d; 3d4d= 5d6d? 7d8d@ 9d!d[ #dU
458 @property
459 @cython.critical_section
460 def attributes(self) -> KernelAttributes:
461 """Get the read-only attributes of this kernel."""
462 cdef KernelAttributes attributes
463 if self._attributes is None: 2b c d Pfdbo a z s A B C D E F G H I J K L M N O P Q R )d%d*d'd+d,d-d.d(d/d:d;d=d?d@d[d
464 attributes = KernelAttributes._init(self._h_kernel) 2b c d Pfdbo a z s A B C D E F G H I J K L M N O P Q R )d%d*d'd+d,d-d.d(d/d:d;d=d?d@d[d
465 if self._attributes is None: 2b c d Pfdbo a z s A B C D E F G H I J K L M N O P Q R )d%d*d'd+d,d-d.d(d/d:d;d=d?d@d[d
466 self._attributes = attributes 2b c d Pfdbo a z s A B C D E F G H I J K L M N O P Q R )d%d*d'd+d,d-d.d(d/d:d;d=d?d@d[d
467 return self._attributes 2b c d Pfdbo a z s A B C D E F G H I J K L M N O P Q R )d%d*d'd+d,d-d.d(d/d:d;d=d?d@d[d
469 cdef tuple _get_arguments_info(self, bint param_info=False):
470 if cy_driver_version() < (12, 4, 0): 2e r p f g h i q j k l m ve
471 raise NotImplementedError(
472 "Driver version 12.4 or newer is required for this function. "
473 f"Using driver version {'.'.join(map(str, cy_driver_version()))}"
474 )
475 cdef size_t arg_pos = 0 2e r p f g h i q j k l m ve
476 cdef list param_info_data = [] 2e r p f g h i q j k l m ve
477 cdef cydriver.CUkernel cu_kernel = as_cu(self._h_kernel) 2e r p f g h i q j k l m ve
478 cdef size_t param_offset, param_size
479 cdef cydriver.CUresult err
480 while True: 2e r p f g h i q j k l m ve
481 with nogil: 2e r p f g h i q j k l m ve
482 err = cydriver.cuKernelGetParamInfo(cu_kernel, arg_pos, ¶m_offset, ¶m_size) 2e r p f g h i q j k l m ve
483 if err != cydriver.CUDA_SUCCESS: 2e r p f g h i q j k l m ve
484 break 2e r p f g h i q j k l m ve
485 if param_info: 2e f g h i j k l m ve
486 param_info_data.append(ParamInfo(offset=param_offset, size=param_size)) 2f g h i j k l m ve
487 arg_pos = arg_pos + 1 2e f g h i j k l m ve
488 if err != cydriver.CUDA_ERROR_INVALID_VALUE: 2e r p f g h i q j k l m ve
489 HANDLE_RETURN(err) 1r
490 return arg_pos, param_info_data 2e p f g h i q j k l m ve
492 @property
493 def num_arguments(self) -> int:
494 """int : The number of arguments of this function"""
495 num_args, _ = self._get_arguments_info() 2e r p f g h i q j k l m ve
496 return num_args 2e p f g h i q j k l m ve
498 @property
499 def arguments_info(self) -> list[ParamInfo]:
500 """list[ParamInfo]: (offset, size) for each argument of this function"""
501 _, param_info = self._get_arguments_info(param_info=True) 2p f g h i q j k l m ve
502 return param_info 2p f g h i q j k l m ve
504 @property
505 @cython.critical_section
506 def occupancy(self) -> KernelOccupancy:
507 """Get the occupancy information for launching this kernel."""
508 cdef KernelOccupancy occupancy
509 if self._occupancy is None: 2n )e*e+e,e-e.eA B C D E F G H I J K L M N O P Q R }d~daebecedeeefegeheiejekelemeneoepeqerese
510 occupancy = KernelOccupancy._init(self._h_kernel) 2n )e*e+e,e-e.eA B C D E F G H I J K L M N O P Q R }d~daebecedeeefegeheiejekelemeneoepeqerese
511 if self._occupancy is None: 2n )e*e+e,e-e.eA B C D E F G H I J K L M N O P Q R }d~daebecedeeefegeheiejekelemeneoepeqerese
512 self._occupancy = occupancy 2n )e*e+e,e-e.eA B C D E F G H I J K L M N O P Q R }d~daebecedeeefegeheiejekelemeneoepeqerese
513 return self._occupancy 2n )e*e+e,e-e.eA B C D E F G H I J K L M N O P Q R }d~daebecedeeefegeheiejekelemeneoepeqerese
515 @property
516 def handle(self) -> object:
517 """Return the underlying kernel handle object.
519 .. caution::
521 This handle is a Python object. To get the memory address of the underlying C
522 handle, call ``int(Kernel.handle)``.
523 """
524 return as_py(self._h_kernel) 2b _ ` V { | } ~ abbb] ]ha tez s e 6hue
526 @property
527 def _handle(self) -> object:
528 return self.handle
530 @staticmethod
531 def from_handle(handle, ObjectCode mod: ObjectCode | None = None) -> Kernel:
532 """Creates a new :obj:`Kernel` object from a kernel handle.
534 Parameters
535 ----------
536 handle : int
537 Kernel handle representing the address of a foreign
538 kernel object (CUkernel).
539 mod : :obj:`ObjectCode`, optional
540 The ObjectCode object associated with this kernel. Provides
541 library lifetime for foreign kernels not created by
542 cuda.core.
543 """
545 if not isinstance(handle, int): 2b ] o a tez (h)h*h+h,h-h.h/h:h;hs ue
546 raise TypeError(f"handle must be an integer, got {type(handle).__name__}") 2(h)h*h+h,h-h.h/h:h;h
548 cdef cydriver.CUkernel cu_kernel = <cydriver.CUkernel><void*><size_t>handle 2b ] o a tez s ue
549 cdef KernelHandle h_kernel = create_kernel_handle_ref(cu_kernel) 2b ] o a tez s ue
550 if not h_kernel: 2b ] o a tez s ue
551 HANDLE_RETURN(get_last_error())
553 cdef LibraryHandle h_existing_lib = get_kernel_library(h_kernel) 2b ] o a tez s ue
554 cdef LibraryHandle h_caller_lib
556 if mod is not None: 2b ] o a tez s ue
557 h_caller_lib = mod._h_library 2] a tes
558 if h_existing_lib and h_caller_lib: 2] a tes
559 if as_cu(h_existing_lib) != as_cu(h_caller_lib): 2] a tes
560 import warnings 1a
561 warnings.warn( 1a
562 "The library from the provided ObjectCode does not match "
563 "the library associated with this kernel.",
564 stacklevel=2,
565 )
567 cdef Kernel k = Kernel._from_handle(h_kernel) 2b ] o a tez s ue
568 if mod is not None and not h_existing_lib: 2b ] o a tez s ue
569 k._keepalive = mod
570 return k 2b ] o a tez s ue
572 def __eq__(self, other: object) -> bool:
573 if not isinstance(other, Kernel): 24h5hV ] 6hue7h=h9h!h
574 return NotImplemented 2] 6h7h
575 return as_intptr(self._h_kernel) == as_intptr((<Kernel>other)._h_kernel) 24h5hV ] 6hue=h9h!h
577 def __hash__(self) -> int:
578 return hash(as_intptr(self._h_kernel)) 2] ue^h_h`h{h9h!h
580 def __repr__(self) -> str:
581 return f"<Kernel handle={as_intptr(self._h_kernel):#x}>" 2^ cb] |h
584CodeTypeT = bytes | bytearray | str
586cdef tuple _supported_code_type = tuple(ObjectCodeFormatType.__members__.values())
589cdef void _lazy_load_module_once(void *self_v) except *:
590 # Call-once helper for the lazy module loading, we want to avoid unloading
591 # a module in case of threads racing, so use `call_once`.
592 cdef ObjectCode self = <ObjectCode>self_v 2ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]bb c d ^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmc^ _ ` V ncocpcqcrcsctcucvcwcxcyczc{ | } Ac~ abbbcbBcCcDcEcFcGcHcIcJcKcLcMcNcW X Y Z 0 1 2 3 4 5 n OcPc6 7 8 `d{dQcRcScTcUcVcWcXcYcZc0c1cv w x y 9 ! # 2c3c4c5ca 6c7c8ce 9cr p f g h i q j k l m |d!cS #c$ $c% %cT ' ( ]d^d_dt u 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQd) Rdwe* Sd+ TdQfUd, VdRf- Wd. XdSfTfYd/ Zd=e0d: 1dUf2d; 3dVf4d= 5d'e6d? 7d(e8d@ 9d!d[ #d$dU
593 cdef LibraryHandle h_library
594 cdef bytes path_bytes
595 module = self._module 2ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]bb c d ^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmc^ _ ` V ncocpcqcrcsctcucvcwcxcyczc{ | } Ac~ abbbcbBcCcDcEcFcGcHcIcJcKcLcMcNcW X Y Z 0 1 2 3 4 5 n OcPc6 7 8 `d{dQcRcScTcUcVcWcXcYcZc0c1cv w x y 9 ! # 2c3c4c5ca 6c7c8ce 9cr p f g h i q j k l m |d!cS #c$ $c% %cT ' ( ]d^d_dt u 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQd) Rdwe* Sd+ TdQfUd, VdRf- Wd. XdSfTfYd/ Zd=e0d: 1dUf2d; 3dVf4d= 5d'e6d? 7d(e8d@ 9d!d[ #d$dU
596 if isinstance(module, str): 2ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]bb c d ^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmc^ _ ` V ncocpcqcrcsctcucvcwcxcyczc{ | } Ac~ abbbcbBcCcDcEcFcGcHcIcJcKcLcMcNcW X Y Z 0 1 2 3 4 5 n OcPc6 7 8 `d{dQcRcScTcUcVcWcXcYcZc0c1cv w x y 9 ! # 2c3c4c5ca 6c7c8ce 9cr p f g h i q j k l m |d!cS #c$ $c% %cT ' ( ]d^d_dt u 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQd) Rdwe* Sd+ TdQfUd, VdRf- Wd. XdSfTfYd/ Zd=e0d: 1dUf2d; 3dVf4d= 5d'e6d? 7d(e8d@ 9d!d[ #d$dU
597 path_bytes = module.encode() 1S$T'
598 h_library = create_library_handle_from_file(<const char*>path_bytes) 1S$T'
599 elif isinstance(module, (bytes, bytearray)): 2ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]bb c d ^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmc^ _ ` V ncocpcqcrcsctcucvcwcxcyczc{ | } Ac~ abbbcbBcCcDcEcFcGcHcIcJcKcLcMcNcW X Y Z 0 1 2 3 4 5 n OcPc6 7 8 `d{dQcRcScTcUcVcWcXcYcZc0c1cv w x y 9 ! # 2c3c4c5ca 6c7c8ce 9cr p f g h i q j k l m |d!c#c$c% %c( ]d^d_dt u 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQd) Rdwe* Sd+ TdQfUd, VdRf- Wd. XdSfTfYd/ Zd=e0d: 1dUf2d; 3dVf4d= 5d'e6d? 7d(e8d@ 9d!d[ #d$dU
600 h_library = create_library_handle_from_data(<const void*><char*>module) 2ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]bb c d ^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmc^ _ ` V ncocpcqcrcsctcucvcwcxcyczc{ | } Ac~ abbbcbBcCcDcEcFcGcHcIcJcKcLcMcNcW X Y Z 0 1 2 3 4 5 n OcPc6 7 8 `d{dQcRcScTcUcVcWcXcYcZc0c1cv w x y 9 ! # 2c3c4c5ca 6c7c8ce 9cr p f g h i q j k l m |d!c#c$c% %c( ]d^d_dt u 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQd) Rdwe* Sd+ TdQfUd, VdRf- Wd. XdSfTfYd/ Zd=e0d: 1dUf2d; 3dVf4d= 5d'e6d? 7d(e8d@ 9d!d[ #d$dU
601 elif isinstance(module, PathLike):
602 path_bytes = fsencode(module)
603 h_library = create_library_handle_from_file(<const char*>path_bytes)
604 else:
605 assert_type_str_or_bytes_like(module)
606 raise_code_path_meant_to_be_unreachable()
607 return
608 if not h_library: 2ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]bb c d ^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmc^ _ ` V ncocpcqcrcsctcucvcwcxcyczc{ | } Ac~ abbbcbBcCcDcEcFcGcHcIcJcKcLcMcNcW X Y Z 0 1 2 3 4 5 n OcPc6 7 8 `d{dQcRcScTcUcVcWcXcYcZc0c1cv w x y 9 ! # 2c3c4c5ca 6c7c8ce 9cr p f g h i q j k l m |d!cS #c$ $c% %cT ' ( ]d^d_dt u 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQd) Rdwe* Sd+ TdQfUd, VdRf- Wd. XdSfTfYd/ Zd=e0d: 1dUf2d; 3dVf4d= 5d'e6d? 7d(e8d@ 9d!d[ #d$dU
609 HANDLE_RETURN(get_last_error())
610 self._h_library = h_library 2ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]bb c d ^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmc^ _ ` V ncocpcqcrcsctcucvcwcxcyczc{ | } Ac~ abbbcbBcCcDcEcFcGcHcIcJcKcLcMcNcW X Y Z 0 1 2 3 4 5 n OcPc6 7 8 `d{dQcRcScTcUcVcWcXcYcZc0c1cv w x y 9 ! # 2c3c4c5ca 6c7c8ce 9cr p f g h i q j k l m |d!cS #c$ $c% %cT ' ( ]d^d_dt u 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQd) Rdwe* Sd+ TdQfUd, VdRf- Wd. XdSfTfYd/ Zd=e0d: 1dUf2d; 3dVf4d= 5d'e6d? 7d(e8d@ 9d!d[ #d$dU
613cdef class ObjectCode:
614 """Represent a compiled program to be loaded onto the device.
616 This object provides a unified interface for different types of
617 compiled programs that will be loaded onto the device.
619 Note
620 ----
621 This class has no default constructor. If you already have a cubin that you would
622 like to load, use the :meth:`from_cubin` alternative constructor. Constructing directly
623 from all other possible code types should be avoided in favor of compilation through
624 :class:`~cuda.core.Program`
625 """
627 def __init__(self, *args, **kwargs) -> None:
628 raise RuntimeError( 2}h
629 "ObjectCode objects cannot be instantiated directly. "
630 "Please use ObjectCode APIs (from_cubin, from_ptx) or Program APIs (compile)."
631 )
633 @classmethod
634 def _init(cls, module, code_type, *, name: str = "", symbol_mapping: dict[str, str] | None = None) -> ObjectCode:
635 assert code_type in _supported_code_type, f"{code_type=} is not supported" 2ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]bb c d ^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmc^ _ ` V ncocpcqcrcsctcucvcwcxcyczc{ | } Ac~ abbbcbBcCcDcEcFcGcHcIcJcKcLcMcNcW X Y Z 0 1 2 3 4 5 n OcPc6 7 8 NgOgQcRcScTcUcVcWcXcYcZc0c1c]ePgv w QgRgx y ^eSg_eTgUg`eVg{eWg|eXg}eYg~eZgaf0gbf1gcf2gdf3gef4gff5ggf6ghf7gif8gjf9gkf!glf#gmf$gnf%gof'gpf(gqf)grf*gsf+g,gtf-g.g?e/guf:gvf;gwfxf=g9 ! # ?g2c3c4co 5ca 6c7c8ce /e9cr p f g h i q j k l m |d!cS #c$ $c% %cT Wf' Xf( Yf:e@g@e[g]d]g;e:f[e;fyf=f^d_dzfAft u 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQd) Rd^g* Sd+ Td_gUd, Vd`g- Zf{g0f|gWd. Xd}g~gYd/ Zdah0d: 1dbh2d; 3dch4d= 5ddh6d? 7deh8d@ 9dfh!d[ #dgh1f2fhhihjhkhlhmhnhohphqhrhshthuhvhwhxhyhzhAhBhChDhEhFhGhHhIhJhKhLhMhNhOhPhQhRhShThUhVhWh?f@f[fXhYh]f^f_f`f$d{f3f4f5f6f7f8f9f!f#f$f%f'f(f)f|f}f~fBfCfZhDfEfFfGfHfIf0hJfKfLfMfNf1hU *fagbgcgdgegfggghg+fig,fjgkglgmgngogpgqgrgsgtgugvgwgxgygzgAgBgCgDgEg-fFgGgHgIgJgKg2hOf.fLgMg/f3h
636 cdef ObjectCode self = ObjectCode.__new__(ObjectCode) 2ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]bb c d ^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmc^ _ ` V ncocpcqcrcsctcucvcwcxcyczc{ | } Ac~ abbbcbBcCcDcEcFcGcHcIcJcKcLcMcNcW X Y Z 0 1 2 3 4 5 n OcPc6 7 8 NgOgQcRcScTcUcVcWcXcYcZc0c1c]ePgv w QgRgx y ^eSg_eTgUg`eVg{eWg|eXg}eYg~eZgaf0gbf1gcf2gdf3gef4gff5ggf6ghf7gif8gjf9gkf!glf#gmf$gnf%gof'gpf(gqf)grf*gsf+g,gtf-g.g?e/guf:gvf;gwfxf=g9 ! # ?g2c3c4co 5ca 6c7c8ce /e9cr p f g h i q j k l m |d!cS #c$ $c% %cT Wf' Xf( Yf:e@g@e[g]d]g;e:f[e;fyf=f^d_dzfAft u 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQd) Rd^g* Sd+ Td_gUd, Vd`g- Zf{g0f|gWd. Xd}g~gYd/ Zdah0d: 1dbh2d; 3dch4d= 5ddh6d? 7deh8d@ 9dfh!d[ #dgh1f2fhhihjhkhlhmhnhohphqhrhshthuhvhwhxhyhzhAhBhChDhEhFhGhHhIhJhKhLhMhNhOhPhQhRhShThUhVhWh?f@f[fXhYh]f^f_f`f$d{f3f4f5f6f7f8f9f!f#f$f%f'f(f)f|f}f~fBfCfZhDfEfFfGfHfIf0hJfKfLfMfNf1hU *fagbgcgdgegfggghg+fig,fjgkglgmgngogpgqgrgsgtgugvgwgxgygzgAgBgCgDgEg-fFgGgHgIgJgKg2hOf.fLgMg/f3h
638 # _h_library is assigned during _lazy_load_module
639 self._h_library = LibraryHandle() # Empty handle 2ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]bb c d ^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmc^ _ ` V ncocpcqcrcsctcucvcwcxcyczc{ | } Ac~ abbbcbBcCcDcEcFcGcHcIcJcKcLcMcNcW X Y Z 0 1 2 3 4 5 n OcPc6 7 8 NgOgQcRcScTcUcVcWcXcYcZc0c1c]ePgv w QgRgx y ^eSg_eTgUg`eVg{eWg|eXg}eYg~eZgaf0gbf1gcf2gdf3gef4gff5ggf6ghf7gif8gjf9gkf!glf#gmf$gnf%gof'gpf(gqf)grf*gsf+g,gtf-g.g?e/guf:gvf;gwfxf=g9 ! # ?g2c3c4co 5ca 6c7c8ce /e9cr p f g h i q j k l m |d!cS #c$ $c% %cT Wf' Xf( Yf:e@g@e[g]d]g;e:f[e;fyf=f^d_dzfAft u 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQd) Rd^g* Sd+ Td_gUd, Vd`g- Zf{g0f|gWd. Xd}g~gYd/ Zdah0d: 1dbh2d; 3dch4d= 5ddh6d? 7deh8d@ 9dfh!d[ #dgh1f2fhhihjhkhlhmhnhohphqhrhshthuhvhwhxhyhzhAhBhChDhEhFhGhHhIhJhKhLhMhNhOhPhQhRhShThUhVhWh?f@f[fXhYh]f^f_f`f$d{f3f4f5f6f7f8f9f!f#f$f%f'f(f)f|f}f~fBfCfZhDfEfFfGfHfIf0hJfKfLfMfNf1hU *fagbgcgdgegfggghg+fig,fjgkglgmgngogpgqgrgsgtgugvgwgxgygzgAgBgCgDgEg-fFgGgHgIgJgKg2hOf.fLgMg/f3h
641 self._code_type = str(code_type) 2ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]bb c d ^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmc^ _ ` V ncocpcqcrcsctcucvcwcxcyczc{ | } Ac~ abbbcbBcCcDcEcFcGcHcIcJcKcLcMcNcW X Y Z 0 1 2 3 4 5 n OcPc6 7 8 NgOgQcRcScTcUcVcWcXcYcZc0c1c]ePgv w QgRgx y ^eSg_eTgUg`eVg{eWg|eXg}eYg~eZgaf0gbf1gcf2gdf3gef4gff5ggf6ghf7gif8gjf9gkf!glf#gmf$gnf%gof'gpf(gqf)grf*gsf+g,gtf-g.g?e/guf:gvf;gwfxf=g9 ! # ?g2c3c4co 5ca 6c7c8ce /e9cr p f g h i q j k l m |d!cS #c$ $c% %cT Wf' Xf( Yf:e@g@e[g]d]g;e:f[e;fyf=f^d_dzfAft u 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQd) Rd^g* Sd+ Td_gUd, Vd`g- Zf{g0f|gWd. Xd}g~gYd/ Zdah0d: 1dbh2d; 3dch4d= 5ddh6d? 7deh8d@ 9dfh!d[ #dgh1f2fhhihjhkhlhmhnhohphqhrhshthuhvhwhxhyhzhAhBhChDhEhFhGhHhIhJhKhLhMhNhOhPhQhRhShThUhVhWh?f@f[fXhYh]f^f_f`f$d{f3f4f5f6f7f8f9f!f#f$f%f'f(f)f|f}f~fBfCfZhDfEfFfGfHfIf0hJfKfLfMfNf1hU *fagbgcgdgegfggghg+fig,fjgkglgmgngogpgqgrgsgtgugvgwgxgygzgAgBgCgDgEg-fFgGgHgIgJgKg2hOf.fLgMg/f3h
643 if isinstance(module, (str, bytes, bytearray)): 2ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]bb c d ^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmc^ _ ` V ncocpcqcrcsctcucvcwcxcyczc{ | } Ac~ abbbcbBcCcDcEcFcGcHcIcJcKcLcMcNcW X Y Z 0 1 2 3 4 5 n OcPc6 7 8 NgOgQcRcScTcUcVcWcXcYcZc0c1c]ePgv w QgRgx y ^eSg_eTgUg`eVg{eWg|eXg}eYg~eZgaf0gbf1gcf2gdf3gef4gff5ggf6ghf7gif8gjf9gkf!glf#gmf$gnf%gof'gpf(gqf)grf*gsf+g,gtf-g.g?e/guf:gvf;gwfxf=g9 ! # ?g2c3c4co 5ca 6c7c8ce /e9cr p f g h i q j k l m |d!cS #c$ $c% %cT Wf' Xf( Yf:e@g@e[g]d]g;e:f[e;fyf=f^d_dzfAft u 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQd) Rd^g* Sd+ Td_gUd, Vd`g- Zf{g0f|gWd. Xd}g~gYd/ Zdah0d: 1dbh2d; 3dch4d= 5ddh6d? 7deh8d@ 9dfh!d[ #dgh1f2fhhihjhkhlhmhnhohphqhrhshthuhvhwhxhyhzhAhBhChDhEhFhGhHhIhJhKhLhMhNhOhPhQhRhShThUhVhWh?f@f[fXhYh]f^f_f`f$d{f3f4f5f6f7f8f9f!f#f$f%f'f(f)f|f}f~fBfCfZhDfEfFfGfHfIf0hJfKfLfMfNf1hU *fagbgcgdgegfggghg+fig,fjgkglgmgngogpgqgrgsgtgugvgwgxgygzgAgBgCgDgEg-fFgGgHgIgJgKg2hOf.fLgMg/f3h
644 self._module = module 2ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]bb c d ^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmc^ _ ` V ncocpcqcrcsctcucvcwcxcyczc{ | } Ac~ abbbcbBcCcDcEcFcGcHcIcJcKcLcMcNcW X Y Z 0 1 2 3 4 5 n OcPc6 7 8 NgOgQcRcScTcUcVcWcXcYcZc0c1c]ePgv w QgRgx y ^eSg_eTgUg`eVg{eWg|eXg}eYg~eZgaf0gbf1gcf2gdf3gef4gff5ggf6ghf7gif8gjf9gkf!glf#gmf$gnf%gof'gpf(gqf)grf*gsf+g,gtf-g.g?e/guf:gvf;gwfxf=g9 ! # ?g2c3c4co 5ca 6c7c8ce /e9cr p f g h i q j k l m |d!c#c$ $c% %cWf' Xf( Yf@g@e[g]d]g:f[e;fyf=f^d_dzfAft u 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQd) Rd^g* Sd+ Td_gUd, Vd`g- Zf{g0f|gWd. Xd}g~gYd/ Zdah0d: 1dbh2d; 3dch4d= 5ddh6d? 7deh8d@ 9dfh!d[ #dgh1f2fhhihjhkhlhmhnhohphqhrhshthuhvhwhxhyhzhAhBhChDhEhFhGhHhIhJhKhLhMhNhOhPhQhRhShThUhVhWh?f@f[fXhYh]f^f_f`f$d{f3f4f5f6f7f8f9f!f#f$f%f'f(f)f|f}f~fBfCfZhDfEfFfGfHfIf0hJfKfLfMfNf1hU *fagbgcgdgegfggghg+fig,fjgkglgmgngogpgqgrgsgtgugvgwgxgygzgAgBgCgDgEg-fFgGgHgIgJgKg2hOf.fLgMg/f3h
645 elif isinstance(module, PathLike): 2S T :e;e
646 self._module = fspath(module) 2S T :e;e
647 else:
648 self._module = module
649 self._sym_map = {} if symbol_mapping is None else symbol_mapping 2ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]bb c d ^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmc^ _ ` V ncocpcqcrcsctcucvcwcxcyczc{ | } Ac~ abbbcbBcCcDcEcFcGcHcIcJcKcLcMcNcW X Y Z 0 1 2 3 4 5 n OcPc6 7 8 NgOgQcRcScTcUcVcWcXcYcZc0c1c]ePgv w QgRgx y ^eSg_eTgUg`eVg{eWg|eXg}eYg~eZgaf0gbf1gcf2gdf3gef4gff5ggf6ghf7gif8gjf9gkf!glf#gmf$gnf%gof'gpf(gqf)grf*gsf+g,gtf-g.g?e/guf:gvf;gwfxf=g9 ! # ?g2c3c4co 5ca 6c7c8ce /e9cr p f g h i q j k l m |d!cS #c$ $c% %cT Wf' Xf( Yf:e@g@e[g]d]g;e:f[e;fyf=f^d_dzfAft u 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQd) Rd^g* Sd+ Td_gUd, Vd`g- Zf{g0f|gWd. Xd}g~gYd/ Zdah0d: 1dbh2d; 3dch4d= 5ddh6d? 7deh8d@ 9dfh!d[ #dgh1f2fhhihjhkhlhmhnhohphqhrhshthuhvhwhxhyhzhAhBhChDhEhFhGhHhIhJhKhLhMhNhOhPhQhRhShThUhVhWh?f@f[fXhYh]f^f_f`f$d{f3f4f5f6f7f8f9f!f#f$f%f'f(f)f|f}f~fBfCfZhDfEfFfGfHfIf0hJfKfLfMfNf1hU *fagbgcgdgegfggghg+fig,fjgkglgmgngogpgqgrgsgtgugvgwgxgygzgAgBgCgDgEg-fFgGgHgIgJgKg2hOf.fLgMg/f3h
650 self._name = name if name else "" 2ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]bb c d ^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmc^ _ ` V ncocpcqcrcsctcucvcwcxcyczc{ | } Ac~ abbbcbBcCcDcEcFcGcHcIcJcKcLcMcNcW X Y Z 0 1 2 3 4 5 n OcPc6 7 8 NgOgQcRcScTcUcVcWcXcYcZc0c1c]ePgv w QgRgx y ^eSg_eTgUg`eVg{eWg|eXg}eYg~eZgaf0gbf1gcf2gdf3gef4gff5ggf6ghf7gif8gjf9gkf!glf#gmf$gnf%gof'gpf(gqf)grf*gsf+g,gtf-g.g?e/guf:gvf;gwfxf=g9 ! # ?g2c3c4co 5ca 6c7c8ce /e9cr p f g h i q j k l m |d!cS #c$ $c% %cT Wf' Xf( Yf:e@g@e[g]d]g;e:f[e;fyf=f^d_dzfAft u 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQd) Rd^g* Sd+ Td_gUd, Vd`g- Zf{g0f|gWd. Xd}g~gYd/ Zdah0d: 1dbh2d; 3dch4d= 5ddh6d? 7deh8d@ 9dfh!d[ #dgh1f2fhhihjhkhlhmhnhohphqhrhshthuhvhwhxhyhzhAhBhChDhEhFhGhHhIhJhKhLhMhNhOhPhQhRhShThUhVhWh?f@f[fXhYh]f^f_f`f$d{f3f4f5f6f7f8f9f!f#f$f%f'f(f)f|f}f~fBfCfZhDfEfFfGfHfIf0hJfKfLfMfNf1hU *fagbgcgdgegfggghg+fig,fjgkglgmgngogpgqgrgsgtgugvgwgxgygzgAgBgCgDgEg-fFgGgHgIgJgKg2hOf.fLgMg/f3h
652 return self 2ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]bb c d ^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmc^ _ ` V ncocpcqcrcsctcucvcwcxcyczc{ | } Ac~ abbbcbBcCcDcEcFcGcHcIcJcKcLcMcNcW X Y Z 0 1 2 3 4 5 n OcPc6 7 8 NgOgQcRcScTcUcVcWcXcYcZc0c1c]ePgv w QgRgx y ^eSg_eTgUg`eVg{eWg|eXg}eYg~eZgaf0gbf1gcf2gdf3gef4gff5ggf6ghf7gif8gjf9gkf!glf#gmf$gnf%gof'gpf(gqf)grf*gsf+g,gtf-g.g?e/guf:gvf;gwfxf=g9 ! # ?g2c3c4co 5ca 6c7c8ce /e9cr p f g h i q j k l m |d!cS #c$ $c% %cT Wf' Xf( Yf:e@g@e[g]d]g;e:f[e;fyf=f^d_dzfAft u 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQd) Rd^g* Sd+ Td_gUd, Vd`g- Zf{g0f|gWd. Xd}g~gYd/ Zdah0d: 1dbh2d; 3dch4d= 5ddh6d? 7deh8d@ 9dfh!d[ #dgh1f2fhhihjhkhlhmhnhohphqhrhshthuhvhwhxhyhzhAhBhChDhEhFhGhHhIhJhKhLhMhNhOhPhQhRhShThUhVhWh?f@f[fXhYh]f^f_f`f$d{f3f4f5f6f7f8f9f!f#f$f%f'f(f)f|f}f~fBfCfZhDfEfFfGfHfIf0hJfKfLfMfNf1hU *fagbgcgdgegfggghg+fig,fjgkglgmgngogpgqgrgsgtgugvgwgxgygzgAgBgCgDgEg-fFgGgHgIgJgKg2hOf.fLgMg/f3h
654 @staticmethod
655 def _reduce_helper(module, code_type, name, symbol_mapping):
656 return ObjectCode._init(module, code_type, name=name if name else "", symbol_mapping=symbol_mapping) 2/eZf0f
658 def __reduce__(self) -> tuple[object, ...]:
659 return ObjectCode._reduce_helper, (self._module, self._code_type, self._name, self._sym_map) 2/eZf0f
661 @staticmethod
662 def from_cubin(module: bytes | str | PathLike[str], *, name: str = "", symbol_mapping: dict[str, str] | None = None) -> ObjectCode:
663 """Create an :class:`ObjectCode` instance from an existing cubin.
665 Parameters
666 ----------
667 module : bytes | str | os.PathLike
668 Either a bytes object containing the in-memory cubin to load, or
669 a file path object (or its string representation) pointing to the
670 on-disk cubin to load.
671 name : str | None
672 A human-readable identifier representing this code object.
673 symbol_mapping : dict | None
674 A dictionary specifying how the unmangled symbol names (as keys)
675 should be mapped to the mangled names before trying to retrieve
676 them (default to no mappings).
677 """
678 return ObjectCode._init(module, ObjectCodeFormatType.CUBIN, name=name, symbol_mapping=symbol_mapping) 2S $ % *f+f,f-f
680 @staticmethod
681 def from_ptx(module: bytes | str | PathLike[str], *, name: str = "", symbol_mapping: dict[str, str] | None = None) -> ObjectCode:
682 """Create an :class:`ObjectCode` instance from an existing PTX.
684 Parameters
685 ----------
686 module : bytes | str | os.PathLike
687 Either a bytes object containing the in-memory ptx code to load, or
688 a file path object (or its string representation) pointing to the
689 on-disk ptx file to load.
690 name : str | None
691 A human-readable identifier representing this code object.
692 symbol_mapping : dict | None
693 A dictionary specifying how the unmangled symbol names (as keys)
694 should be mapped to the mangled names before trying to retrieve
695 them (default to no mappings).
696 """
697 return ObjectCode._init(module, ObjectCodeFormatType.PTX, name=name, symbol_mapping=symbol_mapping) 2?e;e[eyf
699 @staticmethod
700 def from_ltoir(module: bytes | str | PathLike[str], *, name: str = "", symbol_mapping: dict[str, str] | None = None) -> ObjectCode:
701 """Create an :class:`ObjectCode` instance from an existing LTOIR.
703 Parameters
704 ----------
705 module : bytes | str | os.PathLike
706 Either a bytes object containing the in-memory ltoir code to load,
707 or a file path object (or its string representation) pointing to the
708 on-disk ltoir file to load.
709 name : str | None
710 A human-readable identifier representing this code object.
711 symbol_mapping : dict | None
712 A dictionary specifying how the unmangled symbol names (as keys)
713 should be mapped to the mangled names before trying to retrieve
714 them (default to no mappings).
715 """
716 return ObjectCode._init(module, ObjectCodeFormatType.LTOIR, name=name, symbol_mapping=symbol_mapping) 2:e@e]d
718 @staticmethod
719 def from_fatbin(module: bytes | str | PathLike[str], *, name: str = "", symbol_mapping: dict[str, str] | None = None) -> ObjectCode:
720 """Create an :class:`ObjectCode` instance from an existing fatbin.
722 Parameters
723 ----------
724 module : bytes | str | os.PathLike
725 Either a bytes object containing the in-memory fatbin to load, or
726 or a file path object (or its string representation) pointing to the
727 on-disk fatbin to load.
728 name : str | None
729 A human-readable identifier representing this code object.
730 symbol_mapping : dict | None
731 A dictionary specifying how the unmangled symbol names (as keys)
732 should be mapped to the mangled names before trying to retrieve
733 them (default to no mappings).
734 """
735 return ObjectCode._init(module, ObjectCodeFormatType.FATBIN, name=name, symbol_mapping=symbol_mapping) 1T'(
737 @staticmethod
738 def from_object(module: bytes | str, *, name: str = "", symbol_mapping: dict[str, str] | None = None) -> ObjectCode:
739 """Create an :class:`ObjectCode` instance from a host object containing device code.
741 Parameters
742 ----------
743 module : bytes | str
744 Either a bytes object containing the in-memory host object to load, or
745 a file path string pointing to the on-disk host object to load.
746 name : str | None
747 A human-readable identifier representing this code object.
748 symbol_mapping : dict | None
749 A dictionary specifying how the unmangled symbol names (as keys)
750 should be mapped to the mangled names before trying to retrieve
751 them (default to no mappings).
752 """
753 return ObjectCode._init(module, ObjectCodeFormatType.OBJECT, name=name, symbol_mapping=symbol_mapping) 2_dAfu
755 @staticmethod
756 def from_library(module: bytes | str, *, name: str = "", symbol_mapping: dict[str, str] | None = None) -> ObjectCode:
757 """Create an :class:`ObjectCode` instance from an existing library.
759 Parameters
760 ----------
761 module : bytes | str
762 Either a bytes object containing the in-memory library to load, or
763 a file path string pointing to the on-disk library to load.
764 name : str | None
765 A human-readable identifier representing this code object.
766 symbol_mapping : dict | None
767 A dictionary specifying how the unmangled symbol names (as keys)
768 should be mapped to the mangled names before trying to retrieve
769 them (default to no mappings).
770 """
771 return ObjectCode._init(module, ObjectCodeFormatType.LIBRARY, name=name, symbol_mapping=symbol_mapping) 2^dzft
773 # TODO: do we want to unload in a finalizer? Probably not..
775 cdef int _lazy_load_module(self) except -1:
776 py_safe_call_once(self._load_once, _lazy_load_module_once, <void *>self) 2ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]bb c d ^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmc^ _ ` V ncocpcqcrcsctcucvcwcxcyczc{ | } Ac~ abbbcbBcCcDcEcFcGcHcIcJcKcLcMcNcW X Y Z 0 1 2 3 4 5 n OcPc6 xeyezeAeBeCeDeEeFeGeHeIeJe7 8 KeLeMeNe`dOePeQeRe{dSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e7e8e9e!e#e$e%eQcRcScTcUcVcWcXcYcZc0c1cv w x y 9 ! # 2c3c] 4c5ca 6c7c8ce 9cr p f g h i q j k l m |d8h!cS #c$ $c% %cT ' ( ]d^d_dt u 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQd) Rdwe* Sd+ TdQfUd, VdRf- Wd. XdSfTfYd/ Zd=e0d: 1dUf2d; 3dVf4d= 5d'e6d? 7d(e8d@ 9d!d[ #d$dU
777 return 0 2ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]bb c d ^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmc^ _ ` V ncocpcqcrcsctcucvcwcxcyczc{ | } Ac~ abbbcbBcCcDcEcFcGcHcIcJcKcLcMcNcW X Y Z 0 1 2 3 4 5 n OcPc6 xeyezeAeBeCeDeEeFeGeHeIeJe7 8 KeLeMeNe`dOePeQeRe{dSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e7e8e9e!e#e$e%eQcRcScTcUcVcWcXcYcZc0c1cv w x y 9 ! # 2c3c] 4c5ca 6c7c8ce 9cr p f g h i q j k l m |d8h!cS #c$ $c% %cT ' ( ]d^d_dt u 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQd) Rdwe* Sd+ TdQfUd, VdRf- Wd. XdSfTfYd/ Zd=e0d: 1dUf2d; 3dVf4d= 5d'e6d? 7d(e8d@ 9d!d[ #d$dU
779 def get_kernel(self, name: str | bytes) -> Kernel:
780 """Return the :obj:`~_module.Kernel` of a specified name from this object code.
782 Parameters
783 ----------
784 name : str | bytes
785 Name of the kernel to retrieve.
787 Returns
788 -------
789 :obj:`~_module.Kernel`
790 Newly created kernel object.
792 """
793 self._lazy_load_module() 2ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]bb c d ^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmc^ _ ` V ncocpcqcrcsctcucvcwcxcyczc{ | } Ac~ abbbcbBcCcDcEcFcGcHcIcJcKcLcMcNcW X Y Z 0 1 2 3 4 5 n OcPc6 xeyezeAeBeCeDeEeFeGeHeIeJe7 8 KeLeMeNe`dOePeQeRe{dSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e7e8e9e!e#e$e%eQcRcScTcUcVcWcXcYcZc0c1cv w x y 9 ! # 2c3c] 4c5ca 6c7c8ce 9cr p f g h i q j k l m !cS #c$ $c% %cT ' ( ]d^d_dt u 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQd) Rd* Sd+ TdUd, Vd- Wd. XdYd/ Zd0d: 1d2d; 3d4d= 5d6d? 7d8d@ 9d!d[ #d$dU
794 supported_code_types = (ObjectCodeFormatType.CUBIN, ObjectCodeFormatType.PTX, ObjectCodeFormatType.FATBIN) 2ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]bb c d ^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmc^ _ ` V ncocpcqcrcsctcucvcwcxcyczc{ | } Ac~ abbbcbBcCcDcEcFcGcHcIcJcKcLcMcNcW X Y Z 0 1 2 3 4 5 n OcPc6 xeyezeAeBeCeDeEeFeGeHeIeJe7 8 KeLeMeNe`dOePeQeRe{dSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e7e8e9e!e#e$e%eQcRcScTcUcVcWcXcYcZc0c1cv w x y 9 ! # 2c3c] 4c5ca 6c7c8ce 9cr p f g h i q j k l m !cS #c$ $c% %cT ' ( ]d^d_dt u 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQd) Rd* Sd+ TdUd, Vd- Wd. XdYd/ Zd0d: 1d2d; 3d4d= 5d6d? 7d8d@ 9d!d[ #d$dU
795 if self._code_type not in supported_code_types: 2ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]bb c d ^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmc^ _ ` V ncocpcqcrcsctcucvcwcxcyczc{ | } Ac~ abbbcbBcCcDcEcFcGcHcIcJcKcLcMcNcW X Y Z 0 1 2 3 4 5 n OcPc6 xeyezeAeBeCeDeEeFeGeHeIeJe7 8 KeLeMeNe`dOePeQeRe{dSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e7e8e9e!e#e$e%eQcRcScTcUcVcWcXcYcZc0c1cv w x y 9 ! # 2c3c] 4c5ca 6c7c8ce 9cr p f g h i q j k l m !cS #c$ $c% %cT ' ( ]d^d_dt u 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQd) Rd* Sd+ TdUd, Vd- Wd. XdYd/ Zd0d: 1d2d; 3d4d= 5d6d? 7d8d@ 9d!d[ #d$dU
796 raise RuntimeError(f'Unsupported code type "{self._code_type}" ({supported_code_types=})') 2]d^d_d
797 try: 2ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]bb c d ^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmc^ _ ` V ncocpcqcrcsctcucvcwcxcyczc{ | } Ac~ abbbcbBcCcDcEcFcGcHcIcJcKcLcMcNcW X Y Z 0 1 2 3 4 5 n OcPc6 xeyezeAeBeCeDeEeFeGeHeIeJe7 8 KeLeMeNe`dOePeQeRe{dSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e7e8e9e!e#e$e%eQcRcScTcUcVcWcXcYcZc0c1cv w x y 9 ! # 2c3c] 4c5ca 6c7c8ce 9cr p f g h i q j k l m !cS #c$ $c% %cT ' ( t u 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQd) Rd* Sd+ TdUd, Vd- Wd. XdYd/ Zd0d: 1d2d; 3d4d= 5d6d? 7d8d@ 9d!d[ #d$dU
798 name = self._sym_map[name] 2ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]bb c d ^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmc^ _ ` V ncocpcqcrcsctcucvcwcxcyczc{ | } Ac~ abbbcbBcCcDcEcFcGcHcIcJcKcLcMcNcW X Y Z 0 1 2 3 4 5 n OcPc6 xeyezeAeBeCeDeEeFeGeHeIeJe7 8 KeLeMeNe`dOePeQeRe{dSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e7e8e9e!e#e$e%eQcRcScTcUcVcWcXcYcZc0c1cv w x y 9 ! # 2c3c] 4c5ca 6c7c8ce 9cr p f g h i q j k l m !cS #c$ $c% %cT ' ( t u 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQd) Rd* Sd+ TdUd, Vd- Wd. XdYd/ Zd0d: 1d2d; 3d4d= 5d6d? 7d8d@ 9d!d[ #d$dU
799 except KeyError: 2W X Y Z 0 1 2 3 4 5 n 6 7 8 v w x y 9 ! # e t u ) * + , - . / : ; = ? @ [ $dU
800 if isinstance(name, str): 2W X Y Z 0 1 2 3 4 5 n 6 7 8 v w x y 9 ! # e t u ) * + , - . / : ; = ? @ [ $dU
801 name = name.encode() 2W X Y Z 0 1 2 3 4 5 n 6 7 8 v w x y 9 ! # e t u ) * + , - . / : ; = ? @ [ $dU
803 cdef KernelHandle h_kernel = create_kernel_handle(self._h_library, <const char*>name) 2ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]bb c d ^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmc^ _ ` V ncocpcqcrcsctcucvcwcxcyczc{ | } Ac~ abbbcbBcCcDcEcFcGcHcIcJcKcLcMcNcW X Y Z 0 1 2 3 4 5 n OcPc6 xeyezeAeBeCeDeEeFeGeHeIeJe7 8 KeLeMeNe`dOePeQeRe{dSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e7e8e9e!e#e$e%eQcRcScTcUcVcWcXcYcZc0c1cv w x y 9 ! # 2c3c] 4c5ca 6c7c8ce 9cr p f g h i q j k l m !cS #c$ $c% %cT ' ( t u 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQd) Rd* Sd+ TdUd, Vd- Wd. XdYd/ Zd0d: 1d2d; 3d4d= 5d6d? 7d8d@ 9d!d[ #d$dU
804 if not h_kernel: 2ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]bb c d ^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmc^ _ ` V ncocpcqcrcsctcucvcwcxcyczc{ | } Ac~ abbbcbBcCcDcEcFcGcHcIcJcKcLcMcNcW X Y Z 0 1 2 3 4 5 n OcPc6 xeyezeAeBeCeDeEeFeGeHeIeJe7 8 KeLeMeNe`dOePeQeRe{dSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e7e8e9e!e#e$e%eQcRcScTcUcVcWcXcYcZc0c1cv w x y 9 ! # 2c3c] 4c5ca 6c7c8ce 9cr p f g h i q j k l m !cS #c$ $c% %cT ' ( t u 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQd) Rd* Sd+ TdUd, Vd- Wd. XdYd/ Zd0d: 1d2d; 3d4d= 5d6d? 7d8d@ 9d!d[ #d$dU
805 HANDLE_RETURN(get_last_error()) 2$d
806 return Kernel._from_handle(h_kernel) 2ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]bb c d ^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmc^ _ ` V ncocpcqcrcsctcucvcwcxcyczc{ | } Ac~ abbbcbBcCcDcEcFcGcHcIcJcKcLcMcNcW X Y Z 0 1 2 3 4 5 n OcPc6 xeyezeAeBeCeDeEeFeGeHeIeJe7 8 KeLeMeNe`dOePeQeRe{dSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e7e8e9e!e#e$e%eQcRcScTcUcVcWcXcYcZc0c1cv w x y 9 ! # 2c3c] 4c5ca 6c7c8ce 9cr p f g h i q j k l m !cS #c$ $c% %cT ' ( t u 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQd) Rd* Sd+ TdUd, Vd- Wd. XdYd/ Zd0d: 1d2d; 3d4d= 5d6d? 7d8d@ 9d!d[ #dU
808 def get_module(self) -> driver.CUmodule:
809 """Return a context-dependent :obj:`~driver.CUmodule` for legacy interop.
811 Bridges the native :obj:`~driver.CUlibrary` (see :attr:`handle`) to a
812 ``CUmodule`` via ``cuLibraryGetModule``, for use with legacy driver APIs
813 that only accept ``CUmodule``.
815 Returns
816 -------
817 :obj:`~driver.CUmodule`
818 Module handle for the current CUDA context, suitable for legacy
819 driver APIs that accept ``CUmodule``.
820 """
821 self._lazy_load_module() 2|d
822 cdef cydriver.CUmodule mod
823 with nogil: 2|d
824 HANDLE_RETURN(cydriver.cuLibraryGetModule(&mod, as_cu(self._h_library))) 2|d
825 return as_py(mod) 2|d
827 @property
828 def code(self) -> CodeTypeT:
829 """Return the underlying code object."""
830 return self._module 2]ev w #hx y ^e_e$h`e{e|e}e~eafbfcfdfefffgfhfifjfkflfmfnfofpfqfrfsftf%h?eufvfwfxf'ho /eS $ % T Wf' Xf( Yf:e@e]d;e:f[e;fyf=f^d_dzfAft u 1f2f_f`f{f3f4f5f6f7f8f9f!f#f$f%f'f(f)f~hBfCfDfEfFfGfHfIfJfKfLfMfNfU *fagbgcgdgegfggghg+fig,fjgkglgmgngogpgqgrgsgtgugvgwgxgygzgAgBgCgDgEg-fFgGgHgIgJgKgOf.fLgMg/f
832 @property
833 def name(self) -> str:
834 """Return a human-readable name of this code object."""
835 return self._name 2]ev w #hx y ^e_e$h`e{e|e}e~eafbfcfdfefffgfhfifjfkflfmfnfofpfqfrfsftf%h?eufvfwfxf'ht u 1f2f?f@f[f]f^f3f4f5f6f7f8f9f!f#f$f%f'f(f)f|f}f~fBfCfDfEfFfGfHfIfJfKfLfMfNfOf.f
837 @property
838 def code_type(self) -> str:
839 """Return the type of the underlying code object."""
840 return self._code_type 2]ev w #hx y ^e_e$h`e{e|e}e~eafbfcfdfefffgfhfifjfkflfmfnfofpfqfrfsftf%h?eufvfwfxf'h/eT ' ( :e@e]d;e[e^d_dzfAft u BfCfDfEfFfGfHfIfJfKfLfMfNfOf/f
842 @property
843 def symbol_mapping(self) -> dict[str, str]:
844 """Return a copy of the symbol mapping dictionary."""
845 return dict(self._sym_map) 2o /eS $ % WfXfYf:e@e]d;e[eyf
847 @property
848 def handle(self) -> object:
849 """Return the native, context-independent :obj:`~driver.CUlibrary` handle.
851 Used by ``cuda.core`` and newer driver library APIs. For legacy APIs
852 that only accept a ``CUmodule``, use :meth:`get_module` instead.
854 .. caution::
856 This handle is a Python object. To get the memory address of the underlying C
857 handle, call ``int(ObjectCode.handle)``.
858 """
859 self._lazy_load_module() 28hwe
860 return as_py(self._h_library) 28hwe
862 def __eq__(self, other: object) -> bool:
863 if not isinstance(other, ObjectCode): 2we7h=e'e(e
864 return NotImplemented 2we7h
865 # Trigger lazy load for both objects to compare handles
866 self._lazy_load_module() 2we=e'e(e
867 (<ObjectCode>other)._lazy_load_module() 2we=e'e(e
868 return as_intptr(self._h_library) == as_intptr((<ObjectCode>other)._h_library) 2we=e'e(e
870 def __hash__(self) -> int:
871 # Trigger lazy load to get the handle
872 self._lazy_load_module() 2QfRfUfVf'e(e
873 return hash(as_intptr(self._h_library)) 2QfRfUfVf'e(e
875 def __repr__(self) -> str:
876 # Trigger lazy load to get the handle
877 self._lazy_load_module() 2SfTf$d
878 return f"<ObjectCode handle={as_intptr(self._h_library):#x} code_type='{self._code_type}'>" 2SfTf$d