Coverage for cuda/core/_launch_config.pyx: 76.47%
136 statements
« prev ^ index » next coverage.py v7.17.2, created at 2026-11-05 01:11 +0000
« prev ^ index » next coverage.py v7.17.2, created at 2026-11-05 01:11 +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 ~bacbcccdcecfcgchc_bicjc`bkclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQc0 1 2 3 4 5 6 7 8 9 ! Rc# /b:b;bScTcUcVcWcXcYcZc0c1c2c3c4c$ =b?b@b5c% [b]b^b6c7c8c9c' ( !c) * + , - . / : ; = ? @ [ ] ^ _ ` g { | {bodpdnda |b#cvdqd$c%c.b}b} ~ abbbcbdbebfbgbhbibjbkblbmbnb'c(cobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5bc d 6be 7bb 8b9b!b#b$b%b'b(b)b*b+b)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmd,b-b
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 ~bacbcccdcecfcgchc_bicjc`bkclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQc0 1 2 3 4 5 6 7 8 9 ! Rc# /b:b;bScTcUcVcWcXcYcZc0c1c2c3c4c$ =b?b@b5c% [b]b^b6c7c8c9c' ( !c) * + , - . / : ; = ? @ [ ] ^ _ ` g { | {bodpdnda |b#cvdqd$c%c.b}b} ~ abbbcbdbebfbgbhbibjbkblbmbnb'c(cobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5bc d 6be 7bb 8b9b!b#b$b%b'b(b)b*b+b)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmd,b-b
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 ~bacbcccdcecfcgchc_bicjc`bkclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQc0 1 2 3 4 5 6 7 8 9 ! Rc# /b:b;bScTcUcVcWcXcYcZc0c1c2c3c4c$ =b?b@b5c% [b]b^b6c7c8c9c' ( !c) * + , - . / : ; = ? @ [ ] ^ _ ` g { | {bodpda |b#cqd$c%c.b}b} ~ abbbcbdbebfbgbhbibjbkblbmbnb'c(cobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5bc d 6be 7bb 8b9b!b#b$b%b'b(b)b*b+b)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmd,b-b
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 ~bacbcccdcecfcgchc_bicjc`bkclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQc0 1 2 3 4 5 6 7 8 9 ! Rc# /b:b;bScTcUcVcWcXcYcZc0c1c2c3c4c$ =b?b@b5c% [b]b^b6c7c8c9c' ( !c) * + , - . / : ; = ? @ [ ] ^ _ ` g { | {bodpdnda |b#cqd$c%c.b}b} ~ abbbcbdbebfbgbhbibjbkblbmbnb'c(cobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5bc d 6be 7bb 8b9b!b#b$b%b'b(b)b*b+b)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmd,b-b
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 ~bacbcccdcecfcgchc_bicjc`bkclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQc0 1 2 3 4 5 6 7 8 9 ! Rc# /b:b;bScTcUcVcWcXcYcZc0c1c2c3c4c$ =b?b@b5c% [b]b^b6c7c8c9c' ( !c) * + , - . / : ; = ? @ [ ] ^ _ ` g { | {bodpdnda |b#cqd$c%c.b}b} ~ abbbcbdbebfbgbhbibjbkblbmbnb'c(cobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5bc d 6be 7bb 8b9b!b#b$b%b'b(b)b*b+b)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmd,b-b
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 ~bacbcccdcecfcgchc_bicjc`bkclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQc0 1 2 3 4 5 6 7 8 9 ! Rc# /b:b;bScTcUcVcWcXcYcZc0c1c2c3c4c$ =b?b@b5c% [b]b^b6c7c8c9c' ( !c) * + , - . / : ; = ? @ [ ] ^ _ ` g { | {bodpda |b#cqd$c%c.b}b} ~ abbbcbdbebfbgbhbibjbkblbmbnb'c(cobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5bc d 6be 7bb 8b9b!b#b$b%b'b(b)b*b+b)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmd,b-b
150 cc = Device().compute_capability 2{bodpda qd
151 if cc < (9, 0): 2{bodpda qd
152 raise CUDAError( 2odpdqd
153 f"thread block clusters are not supported on devices with compute capability < 9.0 (got {cc})" 2odpdqd
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 ~bacbcccdcecfcgchc_bicjc`bkclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQc0 1 2 3 4 5 6 7 8 9 ! Rc# /b:b;bScTcUcVcWcXcYcZc0c1c2c3c4c$ =b?b@b5c% [b]b^b6c7c8c9c' ( !c) * + , - . / : ; = ? @ [ ] ^ _ ` g { | a |b#c$c%c.b}b} ~ abbbcbdbebfbgbhbibjbkblbmbnb'c(cobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5bc d 6be 7bb 8b9b!b#b$b%b'b(b)b*b+b)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmd,b-b
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 ~bacbcccdcecfcgchc_bicjc`bkclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQc0 1 2 3 4 5 6 7 8 9 ! Rc# /b:b;bScTcUcVcWcXcYcZc0c1c2c3c4c$ =b?b@b5c% [b]b^b6c7c8c9c' ( !c) * + , - . / : ; = ? @ [ ] ^ _ ` g { | {ba |b#c$c%c.b}b} ~ abbbcbdbebfbgbhbibjbkblbmbnb'c(cobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5bc d 6be 7bb 8b9b!b#b$b%b'b(b)b*b+b)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmd,b-b
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 ~bacbcccdcecfcgchcjclcncpcrctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQc0 1 2 3 4 5 6 7 8 9 ! Rc# /b:b;bScTcUcVcWcXcYcZc0c1c2c3c4c$ =b?b@b5c% [b]b^b6c7c8c9c' ( !c) * + , - . / : ; = ? @ [ ] ^ _ ` g { | {ba |b$c%c.b}b} ~ bbcbdbebfbgbhbibjbkblbmbnb'c(cobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5bc d e 7bb 8b9b!b#b$b%b'b(b)b*b+b)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmd,b-b
162 else:
163 self.shmem_size = shmem_size 2_bic`bkcmcocqcsc/b:b;b=b?b@b[b]b^b#c}bab6b
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 ~bacbcccdcecfcgchc_bicjc`bkclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQc0 1 2 3 4 5 6 7 8 9 ! Rc# /b:b;bScTcUcVcWcXcYcZc0c1c2c3c4c$ =b?b@b5c% [b]b^b6c7c8c9c' ( !c) * + , - . / : ; = ? @ [ ] ^ _ ` g { | {ba |b#c$c%c.b}b} ~ abbbcbdbebfbgbhbibjbkblbmbnb'c(cobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5bc d 6be 7bb 8b9b!b#b$b%b'b(b)b*b+b)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmd,b-b
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 ~bacbcccdcecfcgchc_bicjc`bkclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQc0 1 2 3 4 5 6 7 8 9 ! Rc# /b:b;bScTcUcVcWcXcYcZc0c1c2c3c4c$ =b?b@b5c% [b]b^b6c7c8c9c' ( !c) * + , - . / : ; = ? @ [ ] ^ _ ` g { | {ba |b#c$c%c.b}b} ~ abbbcbdbebfbgbhbibjbkblbmbnb'c(cobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5bc d 6be 7bb 8b9b!b#b$b%b'b(b)b*b+b)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmd,b-b
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 ~bacbcccdcecfcgchc_bicjc`bkclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQc0 1 2 3 4 5 6 7 8 9 ! Rc# /b:b;bScTcUcVcWcXcYcZc0c1c2c3c4c$ =b?b@b5c% [b]b^b6c7c8c9c' ( !c) * + , - . / : ; = ? @ [ ] ^ _ ` g { | {ba |b#c$c%c.b}b} ~ abbbcbdbebfbgbhbibjbkblbmbnb'c(cobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5bc d 6be 7bb 8b9b!b#b$b%b'b(b)b*b+b)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmd,b-b
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 ~bacbcccdcecfcgchc_bicjc`bkclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQc0 1 2 3 4 5 6 7 8 9 ! Rc# /b:b;bScTcUcVcWcXcYcZc0c1c2c3c4c$ =b?b@b5c% [b]b^b6c7c8c9c' ( !c) * + , - . / : ; = ? @ [ ] ^ _ ` g { | {ba |b#c$c%c.b}b} ~ abbbcbdbebfbgbhbibjbkblbmbnb'c(cobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5bc d 6be 7bb 8b9b!b#b$b%b'b(b)b*b+b)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmd,b-b
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^brdwdxdudydzdsdtd
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) 2Ad
197 return f"LaunchConfig({parts})" 2Ad
199 def __eq__(self, other: object) -> bool:
200 if not isinstance(other, LaunchConfig): 2_b`b/b:b;b=b?b@b[b]b^brdBdudsdtd
201 return NotImplemented 2rdBd
202 return self._identity() == (<LaunchConfig>other)._identity() 2_b`b/b:b;b=b?b@b[b]b^brdudsdtd
204 def __hash__(self) -> int:
205 return hash(self._identity()) 2wdxdydzdsdtd
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 ~bacbcccdcecfcgchc_bicjc`bkclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQc0 1 2 3 4 5 6 7 8 9 ! Rc# /b:b;bScTcUcVcWcXcYcZc0c1c2c3c4c$ =b?b@b5c% [b]b^b6c7c8c9c' ( !c) * + , - . / : ; = ? @ [ ] ^ _ ` g { | {bodpdnda |b#cqd$c%c.b}b} ~ abbbcbdbebfbgbhbibjbkblbmbnb'c(cobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5bc d 6be 7bb 8b9b!b#b$b%b'b(b)b*b+b)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmd,b-b
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 ~bacbcccdcecfcgchc_bicjc`bkclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQc0 1 2 3 4 5 6 7 8 9 ! Rc# /b:b;bScTcUcVcWcXcYcZc0c1c2c3c4c$ =b?b@b5c% [b]b^b6c7c8c9c' ( !c) * + , - . / : ; = ? @ [ ] ^ _ ` g { | {bodpda |b#cqd$c%c.b}b} ~ abbbcbdbebfbgbhbibjbkblbmbnb'c(cobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5bc d 6be 7bb 8b9b!b#b$b%b'b(b)b*b+b)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmd,b-b
210 if isinstance(value, str) and value in LaunchConfig._CLUSTER_SCHED_POLICY_TO_DRIVER: 2nda
211 cc = Device().compute_capability 2nda
212 if cc < (9, 0): 2nda
213 raise CUDAError( 2nd
214 "cluster launch attributes are not supported on devices with " 2nd
215 f"compute capability < 9.0 (got {cc})" 2nd
216 )
217 return value 1a
218 valid = format_or_list(LaunchConfig._CLUSTER_SCHED_POLICY_TO_DRIVER.keys()) 2nd
219 raise ValueError( 2nd
220 f"{value!r} is not a valid cluster_scheduling_policy_preference. Must be {valid}" 2nd
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 { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b9b!b#b$b%b'b(b)b*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 { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b9b!b#b$b%b'b(b)b*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 { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b9b!b#b$b%b'b(b)b*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 { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b9b!b#b$b%b'b(b)b*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 { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b9b!b#b$b%b'b(b)b*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 { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b9b!b#b$b%b'b(b)b*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 { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b9b!b#b$b%b'b(b)b*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 { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b9b!b#b$b%b'b(b)b*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 { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b9b!b#b$b%b'b(b)b*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 { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b9b!b#b$b%b'b(b)b*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 { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b9b!b#b$b%b'b(b)b*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 { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b9b!b#b$b%b'b(b)b*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 { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b9b!b#b$b%b'b(b)b*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 6be 7bb 8b
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 6be 7bb 8b
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 6be 7bb 8b
317 attrs = [] 2a d 6be 7bb 8b
319 drv_cfg.blockDimX, drv_cfg.blockDimY, drv_cfg.blockDimZ = config.block 2a c d 6be 7bb 8b
320 drv_cfg.sharedMemBytes = config.shmem_size 2a c d 6be 7bb 8b
322 if config.is_cooperative: 2a c d 6be 7bb 8b
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 6be 7bb 8b
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 6be 7bb 8b
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 6be 7bb 8b
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 6be 7bb 8b
347 drv_cfg.attrs = attrs 2a c d 6be 7bb 8b
349 return drv_cfg 2a c d 6be 7bb 8b