Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 328
feat(cuda.core): add cluster scheduling policy to LaunchConfig#2703
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base:main
Are you sure you want to change the base?
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
3374af4b6b0fbb18c95f2c6c283b39c9fc01a78ad53a90298db871e5541e95dc15bf56d185a86e85fafeFile filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -12,6 +12,7 @@ from cuda.core._utils.cuda_utils import ( | ||
| cast_to_3_tuple, | ||
| driver, | ||
| ) | ||
| from cuda.core._utils.validators import format_or_list | ||
| _LAUNCH_CONFIG_ATTRS = ( | ||
| 'grid', | ||
| @@ -20,8 +21,15 @@ _LAUNCH_CONFIG_ATTRS = ( | ||
| 'shmem_size', | ||
| 'is_cooperative', | ||
| 'programmatic_stream_serialization', | ||
| 'cluster_scheduling_policy_preference', | ||
| ) | ||
| _CLUSTER_SCHED_POLICY_TO_DRIVER = { | ||
| "DEFAULT": driver.CUclusterSchedulingPolicy.CU_CLUSTER_SCHEDULING_POLICY_DEFAULT, | ||
| "SPREAD": driver.CUclusterSchedulingPolicy.CU_CLUSTER_SCHEDULING_POLICY_SPREAD, | ||
| "LOAD_BALANCING": driver.CUclusterSchedulingPolicy.CU_CLUSTER_SCHEDULING_POLICY_LOAD_BALANCING, | ||
| } | ||
| __all__ = ['LaunchConfig'] | ||
| @@ -59,6 +67,10 @@ cdef class LaunchConfig: | ||
| Whether to allow programmatic stream serialization (PDL). When True, | ||
| the kernel may overlap with a previous kernel in the same stream that | ||
| signals completion via programmatic means. | ||
| cluster_scheduling_policy_preference : str, optional | ||
| Cluster scheduling policy for the launch. One of ``"DEFAULT"``, | ||
| ``"SPREAD"``, or ``"LOAD_BALANCING"``. When omitted, the driver uses | ||
| the kernel function's default policy. | ||
| """ | ||
| # TODO: expand LaunchConfig to include other attributes | ||
| @@ -72,6 +84,7 @@ cdef class LaunchConfig: | ||
| shmem_size: int | None = None, | ||
| is_cooperative: bool = False, | ||
| programmatic_stream_serialization: bool = False, | ||
| cluster_scheduling_policy_preference: str | None = None, | ||
| ) -> None: | ||
| """Initialize LaunchConfig with validation. | ||
| @@ -89,21 +102,31 @@ cdef class LaunchConfig: | ||
| Whether to launch as cooperative kernel (default: False) | ||
| programmatic_stream_serialization : bool, optional | ||
| Whether to allow programmatic stream serialization / PDL (default: False) | ||
| cluster_scheduling_policy_preference : str, optional | ||
| Cluster scheduling policy for the launch: ``"DEFAULT"``, | ||
| ``"SPREAD"``, or ``"LOAD_BALANCING"`` (default: None) | ||
| """ | ||
| # Convert and validate grid and block dimensions | ||
| self.grid = cast_to_3_tuple("LaunchConfig.grid", grid) | ||
| self.block = cast_to_3_tuple("LaunchConfig.block", block) | ||
| validated_policy = self._validate_cluster_scheduling_policy_preference( | ||
| cluster_scheduling_policy_preference | ||
| ) | ||
| # FIXME: Calling Device() strictly speaking is not quite right; we should instead | ||
| # look up the device from stream. We probably need to defer the checks related to | ||
| # device compute capability or attributes. | ||
| # thread block clusters are supported starting H100 | ||
| if cluster is not None: | ||
| cc = None | ||
| if cluster is not None or validated_policy is not None: | ||
| cc = Device().compute_capability | ||
| if cc < (9, 0): | ||
| raise CUDAError( | ||
| f"thread block clusters are not supported on devices with compute capability < 9.0 (got {cc})" | ||
| "cluster launch attributes are not supported on devices with " | ||
| f"compute capability < 9.0 (got {cc})" | ||
| ) | ||
| if cluster is not None: | ||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. let's keep lines 142-150 unchanged and add compute capability checking to the unified function. ContributorAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in e85fafe — lines 142–150 unchanged; CC check for policy is also in the member validator. | ||
| self.cluster = cast_to_3_tuple("LaunchConfig.cluster", cluster) | ||
| else: | ||
| self.cluster = None | ||
| @@ -116,6 +139,7 @@ cdef class LaunchConfig: | ||
| self.is_cooperative = is_cooperative | ||
| self.programmatic_stream_serialization = programmatic_stream_serialization | ||
| self.cluster_scheduling_policy_preference = validated_policy | ||
| if self.is_cooperative and not Device().properties.cooperative_launch: | ||
| raise CUDAError("cooperative kernels are not supported on this device") | ||
| @@ -136,6 +160,25 @@ cdef class LaunchConfig: | ||
| def __hash__(self) -> int: | ||
| return hash(self._identity()) | ||
| def _validate_cluster_scheduling_policy_preference(self, value): | ||
| if value is None: | ||
| return None | ||
| if isinstance(value, str) and value in _CLUSTER_SCHED_POLICY_TO_DRIVER: | ||
| cc = Device().compute_capability | ||
| if cc < (9, 0): | ||
| raise CUDAError( | ||
| "cluster launch attributes are not supported on devices with " | ||
| f"compute capability < 9.0 (got {cc})" | ||
| ) | ||
| return value | ||
| valid = format_or_list(_CLUSTER_SCHED_POLICY_TO_DRIVER.keys()) | ||
| raise ValueError( | ||
| f"{value!r} is not a valid cluster_scheduling_policy_preference. Must be {valid}" | ||
| ) | ||
| def _cluster_sched_policy_driver_value(self): | ||
| return _CLUSTER_SCHED_POLICY_TO_DRIVER[self.cluster_scheduling_policy_preference] | ||
| cdef cydriver.CUlaunchConfig _to_native_launch_config(self): | ||
| cdef cydriver.CUlaunchConfig drv_cfg | ||
| cdef cydriver.CUlaunchAttribute attr | ||
| @@ -169,6 +212,13 @@ cdef class LaunchConfig: | ||
| attr.value.programmaticStreamSerializationAllowed = 1 | ||
| self._attrs.push_back(attr) | ||
| if self.cluster_scheduling_policy_preference is not None: | ||
| attr.id = cydriver.CUlaunchAttributeID.CU_LAUNCH_ATTRIBUTE_CLUSTER_SCHEDULING_POLICY_PREFERENCE | ||
| attr.value.clusterSchedulingPolicyPreference = int( | ||
| self._cluster_sched_policy_driver_value() | ||
| ) | ||
| self._attrs.push_back(attr) | ||
| drv_cfg.numAttrs = self._attrs.size() | ||
| drv_cfg.attrs = self._attrs.data() | ||
| @@ -230,6 +280,13 @@ cpdef object _to_native_launch_config(LaunchConfig config): | ||
| attr.value.programmaticStreamSerializationAllowed = 1 | ||
| attrs.append(attr) | ||
| if config.cluster_scheduling_policy_preference is not None: | ||
| attr = driver.CUlaunchAttribute() | ||
| attr.id = driver.CUlaunchAttributeID.CU_LAUNCH_ATTRIBUTE_CLUSTER_SCHEDULING_POLICY_PREFERENCE | ||
| # 13.0.2 setter reads .value; pass FastEnum, not a raw int. | ||
| attr.value.clusterSchedulingPolicyPreference = config._cluster_sched_policy_driver_value() | ||
| attrs.append(attr) | ||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we set twice? one at line 217-223, and the other at line 285-292? ContributorAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The attribute is appended in two conversion paths until all modules are cythonized: the cdef | ||
| drv_cfg.numAttrs = len(attrs) | ||
| drv_cfg.attrs = attrs | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's combine _CLUSTER_SCHED_POLICY_TO_DRIVER, and _validate_cluster_scheduling_policy_preference into a unified function (maybe _validate_cluster_scheduling_policy_preference or better name)?
Also, please put the unified function under LaunchConfig as a member function not global.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in e85fafe — merged validation into
LaunchConfig._validate_cluster_scheduling_policy_preference(member method).