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

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

2# 

3# SPDX-License-Identifier: Apache-2.0 

4  

5from libc.string cimport memset 

6  

7from typing import Any 

8  

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 

17  

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) 

28  

29__all__ = ['LaunchConfig'] 

30  

31  

32cdef class LaunchConfig: 

33 """Customizable launch options. 

34  

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. 

42  

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 """ 

83  

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 } 

89  

90 # TODO: expand LaunchConfig to include other attributes 

91 # Note: attributes are declared in _launch_config.pxd 

92  

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. 

105  

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

138  

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 ) 

144  

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

158  

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

164  

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

167  

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

187  

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

190  

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

193  

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

198  

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

203  

204 def __hash__(self) -> int: 

205 return hash(self._identity()) 2odpdqdrdkdld

206  

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 ) 

222  

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 ] 

227  

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

233  

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] 

240  

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

247  

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

250  

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

255  

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

260  

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) 

267  

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) 

272  

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

275  

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

277  

278  

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. 

282  

283 Parameters 

284 ---------- 

285 config : LaunchConfig 

286 High-level launch configuration 

287  

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 

298  

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

308  

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

318  

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

321  

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

327  

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

333  

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

339  

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

345  

346 drv_cfg.numAttrs = len(attrs) 2a c d 1be 2bb 3b

347 drv_cfg.attrs = attrs 2a c d 1be 2bb 3b

348  

349 return drv_cfg 2a c d 1be 2bb 3b