Coverage for cuda/core/_launch_config.pyx: 76.47%
136 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) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2#
3# SPDX-License-Identifier: Apache-2.0
5from libc.string cimport memset
7from typing import Any
9from cuda.core._device import Device
10from cuda.core._utils.cuda_utils cimport HANDLE_RETURN
11from cuda.core._utils.cuda_utils import (
12 CUDAError,
13 cast_to_3_tuple,
14 driver,
15)
16from cuda.core._utils.validators import format_or_list
18_LAUNCH_CONFIG_ATTRS = (
19 'grid',
20 'cluster',
21 'block',
22 'shmem_size',
23 'is_cooperative',
24 'programmatic_stream_serialization',
25 'cluster_scheduling_policy_preference',
26 'priority',
27)
29__all__ = ['LaunchConfig']
32cdef class LaunchConfig:
33 """Customizable launch options.
35 Note
36 ----
37 When cluster is specified, the grid parameter represents the number of
38 clusters (not blocks). The hierarchy is: grid (clusters) -> cluster (blocks) ->
39 block (threads). Each dimension in grid specifies clusters in the grid, each dimension in
40 cluster specifies blocks per cluster, and each dimension in block specifies
41 threads per block.
43 Attributes
44 ----------
45 grid : tuple | int
46 Collection of threads that will execute a kernel function. When cluster
47 is not specified, this represents the number of blocks, otherwise
48 this represents the number of clusters.
49 cluster : tuple | int
50 Group of blocks (Thread Block Cluster) that will execute on the same
51 GPU Processing Cluster (GPC). Blocks within a cluster have access to
52 distributed shared memory and can be explicitly synchronized.
53 block : tuple | int
54 Group of threads (Thread Block) that will execute on the same
55 streaming multiprocessor (SM). Threads within a thread blocks have
56 access to shared memory and can be explicitly synchronized.
57 shmem_size : int, optional
58 Dynamic shared-memory size per thread block in bytes.
59 (Default to size 0)
60 is_cooperative : bool, optional
61 Whether this config can be used to launch a cooperative kernel.
62 programmatic_stream_serialization : bool, optional
63 Whether to allow programmatic stream serialization (PDL). When True,
64 the kernel may overlap with a previous kernel in the same stream that
65 signals completion via programmatic means.
66 cluster_scheduling_policy_preference : str, optional
67 Cluster scheduling policy for the launch. One of ``"DEFAULT"``,
68 ``"SPREAD"``, or ``"LOAD_BALANCING"``.
69 When ``None`` (default), the launch attribute is omitted and the
70 driver applies the kernel function's default policy.
71 Passing ``"DEFAULT"`` explicitly sets the driver default via the
72 launch attribute.
73 priority : int, optional
74 Execution priority of the kernel. Lower numbers represent higher
75 priorities. The meaningful range of values is device-specific,
76 given by ``[greatestPriority, leastPriority]`` as returned by
77 ``cuCtxGetStreamPriorityRange`` (the same range used by
78 :attr:`~cuda.core.StreamOptions.priority`); both bounds are 0 on
79 a device that does not support multiple stream priorities. A
80 nonzero value outside this range raises :class:`ValueError`.
81 When omitted (or 0), the launch uses the stream's priority.
82 """
84 _CLUSTER_SCHED_POLICY_TO_DRIVER = {
85 "DEFAULT": driver.CUclusterSchedulingPolicy.CU_CLUSTER_SCHEDULING_POLICY_DEFAULT,
86 "SPREAD": driver.CUclusterSchedulingPolicy.CU_CLUSTER_SCHEDULING_POLICY_SPREAD,
87 "LOAD_BALANCING": driver.CUclusterSchedulingPolicy.CU_CLUSTER_SCHEDULING_POLICY_LOAD_BALANCING,
88 }
90 # TODO: expand LaunchConfig to include other attributes
91 # Note: attributes are declared in _launch_config.pxd
93 def __init__(
94 self,
95 grid: int | tuple[int, ...] | None = None,
96 cluster: int | tuple[int, ...] | None = None,
97 block: int | tuple[int, ...] | None = None,
98 shmem_size: int | None = None,
99 is_cooperative: bool = False,
100 programmatic_stream_serialization: bool = False,
101 cluster_scheduling_policy_preference: str | None = None,
102 priority: int | None = None,
103 ) -> None:
104 """Initialize LaunchConfig with validation.
106 Parameters
107 ----------
108 grid : tuple | int, optional
109 Grid dimensions (number of blocks or clusters if cluster is specified)
110 cluster : tuple | int, optional
111 Cluster dimensions (Thread Block Cluster)
112 block : tuple | int, optional
113 Block dimensions (threads per block)
114 shmem_size : int, optional
115 Dynamic shared memory size in bytes (default: 0)
116 is_cooperative : bool, optional
117 Whether to launch as cooperative kernel (default: False)
118 programmatic_stream_serialization : bool, optional
119 Whether to allow programmatic stream serialization / PDL (default: False)
120 cluster_scheduling_policy_preference : str, optional
121 Cluster scheduling policy for the launch: ``"DEFAULT"``,
122 ``"SPREAD"``, or ``"LOAD_BALANCING"``.
123 ``None`` (default) omits the launch attribute; ``"DEFAULT"``
124 sets the driver default explicitly.
125 priority : int, optional
126 Execution priority of the kernel. Lower numbers represent higher
127 priorities. The meaningful range of values is device-specific,
128 given by ``[greatestPriority, leastPriority]`` as returned by
129 ``cuCtxGetStreamPriorityRange`` (the same range used by
130 :attr:`~cuda.core.StreamOptions.priority`); both bounds are 0 on
131 a device that does not support multiple stream priorities. A
132 nonzero value outside this range raises :class:`ValueError`.
133 When omitted (or 0), the launch uses the stream's priority.
134 """
135 # Convert and validate grid and block dimensions
136 self.grid = cast_to_3_tuple("LaunchConfig.grid", grid) 2h i j k l m n o p q r s t u v w x y z f A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _b`b{b|b}b~bacbccc;bdcec=bfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKc0 1 2 3 4 5 6 7 8 9 ! ?b(b)b*bLcMcNcOcPcQcRcScTcUcVcWcXc+b,b-bYc.b/b:b@bZc0c1c# $ 2c% ' ( ) * + , - . / : ; = ? @ [ ] g [bgdhdfda ]b3cndid4c5c'b^b^ _ ` { | } ~ abbbcbdbebfbgbhbib6c7cjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0bc d 1be 2bb 3b4b5b6b7b8b9b!b#b$b%b8c9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcddded
137 self.block = cast_to_3_tuple("LaunchConfig.block", block) 2h i j k l m n o p q r s t u v w x y z f A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _b`b{b|b}b~bacbccc;bdcec=bfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKc0 1 2 3 4 5 6 7 8 9 ! ?b(b)b*bLcMcNcOcPcQcRcScTcUcVcWcXc+b,b-bYc.b/b:b@bZc0c1c# $ 2c% ' ( ) * + , - . / : ; = ? @ [ ] g [bgdhdfda ]b3cndid4c5c'b^b^ _ ` { | } ~ abbbcbdbebfbgbhbib6c7cjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0bc d 1be 2bb 3b4b5b6b7b8b9b!b#b$b%b8c9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcddded
139 self.cluster_scheduling_policy_preference = ( 2h i j k l m n o p q r s t u v w x y z f A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _b`b{b|b}b~bacbccc;bdcec=bfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKc0 1 2 3 4 5 6 7 8 9 ! ?b(b)b*bLcMcNcOcPcQcRcScTcUcVcWcXc+b,b-bYc.b/b:b@bZc0c1c# $ 2c% ' ( ) * + , - . / : ; = ? @ [ ] g [bgdhda ]b3cid4c5c'b^b^ _ ` { | } ~ abbbcbdbebfbgbhbib6c7cjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0bc d 1be 2bb 3b4b5b6b7b8b9b!b#b$b%b8c9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcddded
140 self._validate_cluster_scheduling_policy_preference( 2h i j k l m n o p q r s t u v w x y z f A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _b`b{b|b}b~bacbccc;bdcec=bfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKc0 1 2 3 4 5 6 7 8 9 ! ?b(b)b*bLcMcNcOcPcQcRcScTcUcVcWcXc+b,b-bYc.b/b:b@bZc0c1c# $ 2c% ' ( ) * + , - . / : ; = ? @ [ ] g [bgdhdfda ]b3cid4c5c'b^b^ _ ` { | } ~ abbbcbdbebfbgbhbib6c7cjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0bc d 1be 2bb 3b4b5b6b7b8b9b!b#b$b%b8c9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcddded
141 cluster_scheduling_policy_preference 2h i j k l m n o p q r s t u v w x y z f A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _b`b{b|b}b~bacbccc;bdcec=bfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKc0 1 2 3 4 5 6 7 8 9 ! ?b(b)b*bLcMcNcOcPcQcRcScTcUcVcWcXc+b,b-bYc.b/b:b@bZc0c1c# $ 2c% ' ( ) * + , - . / : ; = ? @ [ ] g [bgdhdfda ]b3cid4c5c'b^b^ _ ` { | } ~ abbbcbdbebfbgbhbib6c7cjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0bc d 1be 2bb 3b4b5b6b7b8b9b!b#b$b%b8c9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcddded
142 )
143 )
145 # FIXME: Calling Device() strictly speaking is not quite right; we should instead
146 # look up the device from stream. We probably need to defer the checks related to
147 # device compute capability or attributes.
148 # thread block clusters are supported starting H100
149 if cluster is not None: 2h i j k l m n o p q r s t u v w x y z f A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _b`b{b|b}b~bacbccc;bdcec=bfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKc0 1 2 3 4 5 6 7 8 9 ! ?b(b)b*bLcMcNcOcPcQcRcScTcUcVcWcXc+b,b-bYc.b/b:b@bZc0c1c# $ 2c% ' ( ) * + , - . / : ; = ? @ [ ] g [bgdhda ]b3cid4c5c'b^b^ _ ` { | } ~ abbbcbdbebfbgbhbib6c7cjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0bc d 1be 2bb 3b4b5b6b7b8b9b!b#b$b%b8c9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcddded
150 cc = Device().compute_capability 2[bgdhda id
151 if cc < (9, 0): 2[bgdhda id
152 raise CUDAError( 2gdhdid
153 f"thread block clusters are not supported on devices with compute capability < 9.0 (got {cc})" 2gdhdid
154 )
155 self.cluster = cast_to_3_tuple("LaunchConfig.cluster", cluster) 2[ba
156 else:
157 self.cluster = None 2h i j k l m n o p q r s t u v w x y z f A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _b`b{b|b}b~bacbccc;bdcec=bfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKc0 1 2 3 4 5 6 7 8 9 ! ?b(b)b*bLcMcNcOcPcQcRcScTcUcVcWcXc+b,b-bYc.b/b:b@bZc0c1c# $ 2c% ' ( ) * + , - . / : ; = ? @ [ ] g a ]b3c4c5c'b^b^ _ ` { | } ~ abbbcbdbebfbgbhbib6c7cjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0bc d 1be 2bb 3b4b5b6b7b8b9b!b#b$b%b8c9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcddded
159 # Handle shmem_size default
160 if shmem_size is None: 2h i j k l m n o p q r s t u v w x y z f A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _b`b{b|b}b~bacbccc;bdcec=bfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKc0 1 2 3 4 5 6 7 8 9 ! ?b(b)b*bLcMcNcOcPcQcRcScTcUcVcWcXc+b,b-bYc.b/b:b@bZc0c1c# $ 2c% ' ( ) * + , - . / : ; = ? @ [ ] g [ba ]b3c4c5c'b^b^ _ ` { | } ~ abbbcbdbebfbgbhbib6c7cjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0bc d 1be 2bb 3b4b5b6b7b8b9b!b#b$b%b8c9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcddded
161 self.shmem_size = 0 2h i j k l m n o p q r s t u v w x y z f A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _b`b{b|b}b~bacbcccecgcickcmcocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKc0 1 2 3 4 5 6 7 8 9 ! ?b(b)b*bLcMcNcOcPcQcRcScTcUcVcWcXc+b,b-bYc.b/b:b@bZc0c1c# $ 2c% ' ( ) * + , - . / : ; = ? @ [ ] g [ba ]b4c5c'b^b^ _ { | } ~ abbbcbdbebfbgbhbib6c7cjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0bc d e 2bb 3b4b5b6b7b8b9b!b#b$b%b8c9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcddded
162 else:
163 self.shmem_size = shmem_size 2;bdc=bfchcjclcnc(b)b*b+b,b-b.b/b:b3c^b` 1b
165 self.is_cooperative = is_cooperative 2h i j k l m n o p q r s t u v w x y z f A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _b`b{b|b}b~bacbccc;bdcec=bfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKc0 1 2 3 4 5 6 7 8 9 ! ?b(b)b*bLcMcNcOcPcQcRcScTcUcVcWcXc+b,b-bYc.b/b:b@bZc0c1c# $ 2c% ' ( ) * + , - . / : ; = ? @ [ ] g [ba ]b3c4c5c'b^b^ _ ` { | } ~ abbbcbdbebfbgbhbib6c7cjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0bc d 1be 2bb 3b4b5b6b7b8b9b!b#b$b%b8c9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcddded
166 self.programmatic_stream_serialization = programmatic_stream_serialization 2h i j k l m n o p q r s t u v w x y z f A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _b`b{b|b}b~bacbccc;bdcec=bfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKc0 1 2 3 4 5 6 7 8 9 ! ?b(b)b*bLcMcNcOcPcQcRcScTcUcVcWcXc+b,b-bYc.b/b:b@bZc0c1c# $ 2c% ' ( ) * + , - . / : ; = ? @ [ ] g [ba ]b3c4c5c'b^b^ _ ` { | } ~ abbbcbdbebfbgbhbib6c7cjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0bc d 1be 2bb 3b4b5b6b7b8b9b!b#b$b%b8c9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcddded
168 # priority=0 is treated the same as an unset priority (see
169 # _to_native_launch_config), so only nonzero values need validating
170 # against the device's stream priority range.
171 cdef int high, low
172 cdef cydriver.CUresult res_code
173 cdef int prio
174 if priority: 2h i j k l m n o p q r s t u v w x y z f A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _b`b{b|b}b~bacbccc;bdcec=bfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKc0 1 2 3 4 5 6 7 8 9 ! ?b(b)b*bLcMcNcOcPcQcRcScTcUcVcWcXc+b,b-bYc.b/b:b@bZc0c1c# $ 2c% ' ( ) * + , - . / : ; = ? @ [ ] g [ba ]b3c4c5c'b^b^ _ ` { | } ~ abbbcbdbebfbgbhbib6c7cjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0bc d 1be 2bb 3b4b5b6b7b8b9b!b#b$b%b8c9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcddded
175 with nogil: 2'bb
176 res_code = cydriver.cuCtxGetStreamPriorityRange(&high, &low) 2'bb
177 if res_code != cydriver.CUresult.CUDA_SUCCESS: 2'bb
178 if res_code == cydriver.CUresult.CUDA_ERROR_INVALID_CONTEXT:
179 raise RuntimeError(
180 "No current CUDA context. Call dev.set_current() before creating a LaunchConfig with a priority."
181 )
182 HANDLE_RETURN(res_code)
183 prio = priority 2'bb
184 if not (low <= prio <= high): 2'bb
185 raise ValueError(f"{priority=} is out of range {[low, high]}")
186 self.priority = prio 2'bb
188 if self.is_cooperative and not Device().properties.cooperative_launch: 2h i j k l m n o p q r s t u v w x y z f A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _b`b{b|b}b~bacbccc;bdcec=bfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKc0 1 2 3 4 5 6 7 8 9 ! ?b(b)b*bLcMcNcOcPcQcRcScTcUcVcWcXc+b,b-bYc.b/b:b@bZc0c1c# $ 2c% ' ( ) * + , - . / : ; = ? @ [ ] g [ba ]b3c4c5c'b^b^ _ ` { | } ~ abbbcbdbebfbgbhbib6c7cjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0bc d 1be 2bb 3b4b5b6b7b8b9b!b#b$b%b8c9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcddded
189 raise CUDAError("cooperative kernels are not supported on this device") 2]b
191 def _identity(self) -> tuple[Any, ...]:
192 return tuple(getattr(self, attr) for attr in _LAUNCH_CONFIG_ATTRS) 2;b=b(b)b*b+b,b-b.b/b:bjdodpdmdqdrdkdld
194 def __repr__(self) -> str:
195 """Return string representation of LaunchConfig."""
196 parts = ', '.join(f'{attr}={getattr(self, attr)!r}' for attr in _LAUNCH_CONFIG_ATTRS) 2?b@bsd
197 return f"LaunchConfig({parts})" 2?b@bsd
199 def __eq__(self, other: object) -> bool:
200 if not isinstance(other, LaunchConfig): 2;b=b(b)b*b+b,b-b.b/b:bjdtdmdkdld
201 return NotImplemented 2jdtd
202 return self._identity() == (<LaunchConfig>other)._identity() 2;b=b(b)b*b+b,b-b.b/b:bjdmdkdld
204 def __hash__(self) -> int:
205 return hash(self._identity()) 2odpdqdrdkdld
207 def _validate_cluster_scheduling_policy_preference(self, value):
208 if value is None: 2h i j k l m n o p q r s t u v w x y z f A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _b`b{b|b}b~bacbccc;bdcec=bfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKc0 1 2 3 4 5 6 7 8 9 ! ?b(b)b*bLcMcNcOcPcQcRcScTcUcVcWcXc+b,b-bYc.b/b:b@bZc0c1c# $ 2c% ' ( ) * + , - . / : ; = ? @ [ ] g [bgdhdfda ]b3cid4c5c'b^b^ _ ` { | } ~ abbbcbdbebfbgbhbib6c7cjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0bc d 1be 2bb 3b4b5b6b7b8b9b!b#b$b%b8c9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcddded
209 return None 2h i j k l m n o p q r s t u v w x y z f A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _b`b{b|b}b~bacbccc;bdcec=bfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKc0 1 2 3 4 5 6 7 8 9 ! ?b(b)b*bLcMcNcOcPcQcRcScTcUcVcWcXc+b,b-bYc.b/b:b@bZc0c1c# $ 2c% ' ( ) * + , - . / : ; = ? @ [ ] g [bgdhda ]b3cid4c5c'b^b^ _ ` { | } ~ abbbcbdbebfbgbhbib6c7cjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0bc d 1be 2bb 3b4b5b6b7b8b9b!b#b$b%b8c9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcddded
210 if isinstance(value, str) and value in LaunchConfig._CLUSTER_SCHED_POLICY_TO_DRIVER: 2fda
211 cc = Device().compute_capability 2fda
212 if cc < (9, 0): 2fda
213 raise CUDAError( 2fd
214 "cluster launch attributes are not supported on devices with " 2fd
215 f"compute capability < 9.0 (got {cc})" 2fd
216 )
217 return value 1a
218 valid = format_or_list(LaunchConfig._CLUSTER_SCHED_POLICY_TO_DRIVER.keys()) 2fd
219 raise ValueError( 2fd
220 f"{value!r} is not a valid cluster_scheduling_policy_preference. Must be {valid}" 2fd
221 )
223 def _cluster_sched_policy_driver_value(self):
224 return LaunchConfig._CLUSTER_SCHED_POLICY_TO_DRIVER[ 1a
225 self.cluster_scheduling_policy_preference 1a
226 ]
228 cdef cydriver.CUlaunchConfig _to_native_launch_config(self):
229 cdef cydriver.CUlaunchConfig drv_cfg
230 cdef cydriver.CUlaunchAttribute attr
231 memset(&drv_cfg, 0, sizeof(drv_cfg)) 2h i j k l m n o p q r s t u v w x y z f A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] g ^ _ ` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b4b5b6b7b8b9b!b#b$b%b
232 self._attrs.resize(0) 2h i j k l m n o p q r s t u v w x y z f A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] g ^ _ ` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b4b5b6b7b8b9b!b#b$b%b
234 # Handle grid dimensions and cluster configuration
235 if self.cluster is not None: 2h i j k l m n o p q r s t u v w x y z f A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] g ^ _ ` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b4b5b6b7b8b9b!b#b$b%b
236 # Convert grid from cluster units to block units
237 drv_cfg.gridDimX = self.grid[0] * self.cluster[0]
238 drv_cfg.gridDimY = self.grid[1] * self.cluster[1]
239 drv_cfg.gridDimZ = self.grid[2] * self.cluster[2]
241 # Set up cluster attribute
242 attr.id = cydriver.CUlaunchAttributeID.CU_LAUNCH_ATTRIBUTE_CLUSTER_DIMENSION
243 attr.value.clusterDim.x, attr.value.clusterDim.y, attr.value.clusterDim.z = self.cluster
244 self._attrs.push_back(attr)
245 else:
246 drv_cfg.gridDimX, drv_cfg.gridDimY, drv_cfg.gridDimZ = self.grid 2h i j k l m n o p q r s t u v w x y z f A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] g ^ _ ` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b4b5b6b7b8b9b!b#b$b%b
248 drv_cfg.blockDimX, drv_cfg.blockDimY, drv_cfg.blockDimZ = self.block 2h i j k l m n o p q r s t u v w x y z f A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] g ^ _ ` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b4b5b6b7b8b9b!b#b$b%b
249 drv_cfg.sharedMemBytes = self.shmem_size 2h i j k l m n o p q r s t u v w x y z f A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] g ^ _ ` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b4b5b6b7b8b9b!b#b$b%b
251 if self.is_cooperative: 2h i j k l m n o p q r s t u v w x y z f A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] g ^ _ ` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b4b5b6b7b8b9b!b#b$b%b
252 attr.id = cydriver.CUlaunchAttributeID.CU_LAUNCH_ATTRIBUTE_COOPERATIVE 1g
253 attr.value.cooperative = 1 1g
254 self._attrs.push_back(attr) 1g
256 if self.programmatic_stream_serialization: 2h i j k l m n o p q r s t u v w x y z f A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] g ^ _ ` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b4b5b6b7b8b9b!b#b$b%b
257 attr.id = cydriver.CUlaunchAttributeID.CU_LAUNCH_ATTRIBUTE_PROGRAMMATIC_STREAM_SERIALIZATION 1f
258 attr.value.programmaticStreamSerializationAllowed = 1 1f
259 self._attrs.push_back(attr) 1f
261 if self.cluster_scheduling_policy_preference is not None: 2h i j k l m n o p q r s t u v w x y z f A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] g ^ _ ` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b4b5b6b7b8b9b!b#b$b%b
262 attr.id = cydriver.CUlaunchAttributeID.CU_LAUNCH_ATTRIBUTE_CLUSTER_SCHEDULING_POLICY_PREFERENCE
263 attr.value.clusterSchedulingPolicyPreference = int(
264 self._cluster_sched_policy_driver_value()
265 )
266 self._attrs.push_back(attr)
268 if self.priority: 2h i j k l m n o p q r s t u v w x y z f A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] g ^ _ ` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b4b5b6b7b8b9b!b#b$b%b
269 attr.id = cydriver.CUlaunchAttributeID.CU_LAUNCH_ATTRIBUTE_PRIORITY
270 attr.value.priority = self.priority
271 self._attrs.push_back(attr)
273 drv_cfg.numAttrs = <unsigned int>self._attrs.size() 2h i j k l m n o p q r s t u v w x y z f A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] g ^ _ ` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b4b5b6b7b8b9b!b#b$b%b
274 drv_cfg.attrs = self._attrs.data() 2h i j k l m n o p q r s t u v w x y z f A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] g ^ _ ` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b4b5b6b7b8b9b!b#b$b%b
276 return drv_cfg 2h i j k l m n o p q r s t u v w x y z f A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] g ^ _ ` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b4b5b6b7b8b9b!b#b$b%b
279# TODO: once all modules are cythonized, this function can be dropped in favor of the cdef method above
280cpdef object _to_native_launch_config(LaunchConfig config):
281 """Convert LaunchConfig to native driver CUlaunchConfig.
283 Parameters
284 ----------
285 config : LaunchConfig
286 High-level launch configuration
288 Returns
289 -------
290 driver.CUlaunchConfig
291 Native CUDA driver launch configuration
292 """
293 cdef object drv_cfg = driver.CUlaunchConfig() 2a c d 1be 2bb 3b
294 cdef list attrs
295 cdef object attr
296 cdef object dim
297 cdef tuple grid_blocks
299 # Handle grid dimensions and cluster configuration
300 if config.cluster is not None: 2a c d 1be 2bb 3b
301 # Convert grid from cluster units to block units
302 grid_blocks = (
303 config.grid[0] * config.cluster[0], 1ac
304 config.grid[1] * config.cluster[1], 1ac
305 config.grid[2] * config.cluster[2], 1ac
306 )
307 drv_cfg.gridDimX, drv_cfg.gridDimY, drv_cfg.gridDimZ = grid_blocks 1ac
309 # Set up cluster attribute
310 attr = driver.CUlaunchAttribute() 1ac
311 attr.id = driver.CUlaunchAttributeID.CU_LAUNCH_ATTRIBUTE_CLUSTER_DIMENSION 1ac
312 dim = attr.value.clusterDim 1ac
313 dim.x, dim.y, dim.z = config.cluster 1ac
314 attrs = [attr] 1ac
315 else:
316 drv_cfg.gridDimX, drv_cfg.gridDimY, drv_cfg.gridDimZ = config.grid 2a d 1be 2bb 3b
317 attrs = [] 2a d 1be 2bb 3b
319 drv_cfg.blockDimX, drv_cfg.blockDimY, drv_cfg.blockDimZ = config.block 2a c d 1be 2bb 3b
320 drv_cfg.sharedMemBytes = config.shmem_size 2a c d 1be 2bb 3b
322 if config.is_cooperative: 2a c d 1be 2bb 3b
323 attr = driver.CUlaunchAttribute() 1d
324 attr.id = driver.CUlaunchAttributeID.CU_LAUNCH_ATTRIBUTE_COOPERATIVE 1d
325 attr.value.cooperative = 1 1d
326 attrs.append(attr) 1d
328 if config.programmatic_stream_serialization: 2a c d 1be 2bb 3b
329 attr = driver.CUlaunchAttribute() 1e
330 attr.id = driver.CUlaunchAttributeID.CU_LAUNCH_ATTRIBUTE_PROGRAMMATIC_STREAM_SERIALIZATION 1e
331 attr.value.programmaticStreamSerializationAllowed = 1 1e
332 attrs.append(attr) 1e
334 if config.cluster_scheduling_policy_preference is not None: 2a c d 1be 2bb 3b
335 attr = driver.CUlaunchAttribute() 1a
336 attr.id = driver.CUlaunchAttributeID.CU_LAUNCH_ATTRIBUTE_CLUSTER_SCHEDULING_POLICY_PREFERENCE 1a
337 attr.value.clusterSchedulingPolicyPreference = config._cluster_sched_policy_driver_value() 1a
338 attrs.append(attr) 1a
340 if config.priority: 2a c d 1be 2bb 3b
341 attr = driver.CUlaunchAttribute() 1b
342 attr.id = driver.CUlaunchAttributeID.CU_LAUNCH_ATTRIBUTE_PRIORITY 1b
343 attr.value.priority = config.priority 1b
344 attrs.append(attr) 1b
346 drv_cfg.numAttrs = len(attrs) 2a c d 1be 2bb 3b
347 drv_cfg.attrs = attrs 2a c d 1be 2bb 3b
349 return drv_cfg 2a c d 1be 2bb 3b