22#
33# SPDX-License-Identifier: Apache-2.0
44
5+ import ctypes as _ctypes
56from collections .abc import Mapping as _Mapping
67from typing import Any as _Any
7- from typing import Literal as _Literal
88
99from cuda .core ._utils .cuda_utils import handle_return as _handle_cuda_return
1010from cuda .core ._utils .version import binding_version as _binding_version
1111from cuda .core ._utils .version import driver_version as _driver_version
12+ from cuda .core .typing import ProcessStateT as _ProcessStateT
1213
1314try :
1415 from cuda .bindings import driver as _driver
1516except ImportError :
1617 from cuda import cuda as _driver
1718
1819
19- ProcessStateT = _Literal ["running" , "locked" , "checkpointed" , "failed" ]
20-
21- _PROCESS_STATE_NAMES : dict [int , ProcessStateT ] = {
22- 0 : "running" ,
23- 1 : "locked" ,
24- 2 : "checkpointed" ,
25- 3 : "failed" ,
26- }
20+ _PROCESS_STATE_NAME_ATTRS : tuple [tuple [str , _ProcessStateT ], ...] = (
21+ ("CU_PROCESS_STATE_RUNNING" , "running" ),
22+ ("CU_PROCESS_STATE_LOCKED" , "locked" ),
23+ ("CU_PROCESS_STATE_CHECKPOINTED" , "checkpointed" ),
24+ ("CU_PROCESS_STATE_FAILED" , "failed" ),
25+ )
2726
2827_REQUIRED_BINDING_ATTRS = (
2928 "cuCheckpointProcessCheckpoint" ,
3433 "cuCheckpointProcessUnlock" ,
3534 "CUcheckpointGpuPair" ,
3635 "CUcheckpointLockArgs" ,
36+ "CUprocessState" ,
3737 "CUcheckpointRestoreArgs" ,
3838)
3939_REQUIRED_DRIVER_VERSION = (12 , 8 , 0 )
@@ -56,16 +56,17 @@ def __init__(self, pid: int):
5656 self .pid = _check_pid (pid )
5757
5858 @property
59- def state (self ) -> ProcessStateT :
59+ def state (self ) -> _ProcessStateT :
6060 """
6161 CUDA checkpoint state for this process.
6262 """
6363 driver = _get_driver ()
6464 state = _call_driver (driver , driver .cuCheckpointProcessGetState , self .pid )
65- state_value = int ( state )
65+ state_names = _get_process_state_names ( driver )
6666 try :
67- return _PROCESS_STATE_NAMES [ state_value ]
67+ return state_names [ state ]
6868 except KeyError as e :
69+ state_value = int (state )
6970 raise RuntimeError (f"Unknown CUDA checkpoint process state: { state_value } " ) from e
7071
7172 @property
@@ -105,8 +106,8 @@ def restore(self, gpu_mapping: _Mapping[_Any, _Any] | None = None) -> None:
105106 ----------
106107 gpu_mapping : mapping, optional
107108 GPU UUID remapping from each checkpointed GPU UUID to the GPU UUID
108- to restore onto. If provided, the mapping must contain every
109- checkpointed GPU UUID .
109+ to restore onto. For migration workflows, provide mappings for
110+ every CUDA-visible GPU .
110111 """
111112 driver = _get_driver ()
112113 args = _make_restore_args (driver , gpu_mapping )
@@ -154,6 +155,10 @@ def _binding_version_supports_checkpoint(version) -> bool:
154155 return (major == 12 and (minor , patch ) >= (8 , 0 )) or (major == 13 and (minor , patch ) >= (0 , 2 )) or major > 13
155156
156157
158+ def _get_process_state_names (driver ) -> dict [_Any , _ProcessStateT ]:
159+ return {getattr (driver .CUprocessState , attr ): state_name for attr , state_name in _PROCESS_STATE_NAME_ATTRS }
160+
161+
157162def _call_driver (driver , func , * args ):
158163 try :
159164 result = func (* args )
@@ -207,8 +212,9 @@ def _make_restore_args(driver, gpu_mapping: _Mapping[_Any, _Any] | None):
207212 pairs = []
208213 for old_uuid , new_uuid in gpu_mapping .items ():
209214 pair = driver .CUcheckpointGpuPair ()
210- pair .oldUuid = _as_cuuuid (driver , old_uuid )
211- pair .newUuid = _as_cuuuid (driver , new_uuid )
215+ buffers = []
216+ pair .oldUuid = _as_cuuuid (driver , old_uuid , buffers )
217+ pair .newUuid = _as_cuuuid (driver , new_uuid , buffers )
212218 pairs .append (pair )
213219
214220 if not pairs :
@@ -220,21 +226,20 @@ def _make_restore_args(driver, gpu_mapping: _Mapping[_Any, _Any] | None):
220226 return args
221227
222228
223- def _as_cuuuid (driver , value ):
229+ def _as_cuuuid (driver , value , buffers ):
224230 """Convert *value* to a ``CUuuid``.
225231
226232 Accepts a ``CUuuid`` instance (returned as-is) or a UUID string in
227233 the ``"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"`` format returned by
228234 :attr:`Device.uuid`.
229235 """
230236 if isinstance (value , str ):
231- import ctypes
232-
233237 raw = bytes .fromhex (value .replace ("-" , "" ))
234238 if len (raw ) != 16 :
235239 raise ValueError (f"GPU UUID string must be 32 hex characters (with optional hyphens), got { value !r} " )
236- buf = ctypes .create_string_buffer (raw , 16 )
237- return driver .CUuuid (ctypes .addressof (buf ))
240+ buf = _ctypes .create_string_buffer (raw , 16 )
241+ buffers .append (buf )
242+ return driver .CUuuid (_ctypes .addressof (buf ))
238243 return value
239244
240245
0 commit comments