modal 0.73.7__py3-none-any.whl → 0.73.9__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
modal/_functions.py CHANGED
@@ -476,6 +476,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
476
476
  _experimental_buffer_containers: Optional[int] = None,
477
477
  _experimental_proxy_ip: Optional[str] = None,
478
478
  _experimental_custom_scaling_factor: Optional[float] = None,
479
+ _experimental_enable_gpu_snapshot: bool = False,
479
480
  ) -> "_Function":
480
481
  """mdmd:hidden"""
481
482
  # Needed to avoid circular imports
@@ -824,6 +825,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
824
825
  _experimental_buffer_containers=_experimental_buffer_containers or 0,
825
826
  _experimental_proxy_ip=_experimental_proxy_ip,
826
827
  _experimental_custom_scaling=_experimental_custom_scaling_factor is not None,
828
+ _experimental_enable_gpu_snapshot=_experimental_enable_gpu_snapshot,
827
829
  )
828
830
 
829
831
  if isinstance(gpu, list):
@@ -851,6 +853,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
851
853
  _experimental_group_size=function_definition._experimental_group_size,
852
854
  _experimental_buffer_containers=function_definition._experimental_buffer_containers,
853
855
  _experimental_custom_scaling=function_definition._experimental_custom_scaling,
856
+ _experimental_enable_gpu_snapshot=_experimental_enable_gpu_snapshot,
854
857
  _experimental_proxy_ip=function_definition._experimental_proxy_ip,
855
858
  snapshot_debug=function_definition.snapshot_debug,
856
859
  runtime_perf_record=function_definition.runtime_perf_record,
@@ -25,6 +25,7 @@ from grpclib import Status
25
25
  from synchronicity.async_wrap import asynccontextmanager
26
26
 
27
27
  import modal_proto.api_pb2
28
+ from modal._runtime import gpu_memory_snapshot
28
29
  from modal._serialization import deserialize, serialize, serialize_data_format
29
30
  from modal._traceback import extract_traceback, print_exception
30
31
  from modal._utils.async_utils import TaskContext, asyncify, synchronize_api, synchronizer
@@ -877,6 +878,17 @@ class _ContainerIOManager:
877
878
  if value != "":
878
879
  config.override_locally(key, value)
879
880
 
881
+ # Restore GPU memory.
882
+ if self.function_def._experimental_enable_gpu_snapshot and self.function_def.resources.gpu_config.gpu_type:
883
+ logger.debug("GPU memory snapshot enabled. Attempting to restore GPU memory.")
884
+ gpu_process_state = gpu_memory_snapshot.get_state()
885
+ if gpu_process_state != gpu_memory_snapshot.CudaCheckpointState.CHECKPOINTED:
886
+ raise ValueError(
887
+ "Cannot restore GPU state if GPU isn't in a 'checkpointed' state. "
888
+ f"Current GPU state: {gpu_process_state}"
889
+ )
890
+ gpu_memory_snapshot.toggle()
891
+
880
892
  # Restore input to default state.
881
893
  self.current_input_id = None
882
894
  self.current_inputs = {}
@@ -892,6 +904,18 @@ class _ContainerIOManager:
892
904
 
893
905
  # Pause heartbeats since they keep the client connection open which causes the snapshotter to crash
894
906
  async with self.heartbeat_condition:
907
+ # Snapshot GPU memory.
908
+ if self.function_def._experimental_enable_gpu_snapshot and self.function_def.resources.gpu_config.gpu_type:
909
+ logger.debug("GPU memory snapshot enabled. Attempting to snapshot GPU memory.")
910
+ gpu_process_state = gpu_memory_snapshot.get_state()
911
+ if gpu_process_state != gpu_memory_snapshot.CudaCheckpointState.RUNNING:
912
+ raise ValueError(
913
+ "Cannot snapshot GPU state if it isn't running. " f"Current GPU state: {gpu_process_state}"
914
+ )
915
+
916
+ gpu_memory_snapshot.toggle()
917
+ gpu_memory_snapshot.wait_for_state(gpu_memory_snapshot.CudaCheckpointState.CHECKPOINTED)
918
+
895
919
  # Notify the heartbeat loop that the snapshot phase has begun in order to
896
920
  # prevent it from sending heartbeat RPCs
897
921
  self._waiting_for_memory_snapshot = True
@@ -0,0 +1,104 @@
1
+ # Copyright Modal Labs 2022
2
+ #
3
+ # This module provides a simple interface for creating GPU memory snapshots,
4
+ # provising a convenient interface to `cuda-checkpoint` [1]. This is intended
5
+ # to be used in conjunction with memory snapshots.
6
+ #
7
+ # [1] https://github.com/NVIDIA/cuda-checkpoint
8
+
9
+ import os
10
+ import subprocess
11
+ import time
12
+ from enum import Enum
13
+
14
+ from modal.config import config, logger
15
+
16
+ CUDA_CHECKPOINT_PATH: str = config.get("cuda_checkpoint_path")
17
+
18
+
19
+ class CudaCheckpointState(Enum):
20
+ """State representation from the CUDA API: https://docs.nvidia.com/cuda/cuda-driver-api/group__CUDA__TYPES.html#group__CUDA__TYPES_1gc96cdda177a2b8c296144567cbea4f23"""
21
+
22
+ RUNNING = "running"
23
+ LOCKED = "locked"
24
+ CHECKPOINTED = "checkpointed"
25
+ FAILED = "failed"
26
+
27
+
28
+ class CudaCheckpointException(Exception):
29
+ pass
30
+
31
+
32
+ def toggle():
33
+ """Toggle CUDA checkpoint state for current process, moving GPU memory to the
34
+ CPU and back depending on the current process state when called."""
35
+ pid = get_own_pid()
36
+ logger.debug(f"Toggling CUDA checkpoint state for PID {pid}")
37
+
38
+ try:
39
+ cuda_checkpoint_lock_timeout_ms = 5 * 1000
40
+ subprocess.run(
41
+ [
42
+ CUDA_CHECKPOINT_PATH,
43
+ "--toggle",
44
+ "--pid",
45
+ str(pid),
46
+ "--timeout",
47
+ str(cuda_checkpoint_lock_timeout_ms),
48
+ ],
49
+ check=True,
50
+ capture_output=True,
51
+ text=True,
52
+ )
53
+ logger.debug("Successfully toggled CUDA checkpoint state")
54
+
55
+ except subprocess.CalledProcessError as e:
56
+ logger.debug(f"Failed to toggle CUDA checkpoint state: {e.stderr}")
57
+ raise CudaCheckpointException(e.stderr)
58
+
59
+
60
+ def get_state() -> CudaCheckpointState:
61
+ """Get current CUDA checkpoint state for this process."""
62
+ pid = get_own_pid()
63
+
64
+ try:
65
+ result = subprocess.run(
66
+ [CUDA_CHECKPOINT_PATH, "--get-state", "--pid", str(pid)], check=True, capture_output=True, text=True
67
+ )
68
+
69
+ # Parse output to get state
70
+ state_str = result.stdout.strip().lower()
71
+ logger.debug(f"Raw state output: {state_str}")
72
+ return CudaCheckpointState(state_str)
73
+
74
+ except subprocess.CalledProcessError as e:
75
+ logger.debug(f"Failed to get CUDA checkpoint state: {e.stderr}")
76
+ raise CudaCheckpointException(e.stderr)
77
+
78
+
79
+ def wait_for_state(target_state: CudaCheckpointState, timeout_secs: float = 5.0):
80
+ """Wait for CUDA checkpoint to reach a specific state."""
81
+ logger.debug(f"Waiting for CUDA checkpoint state {target_state.value}")
82
+ start_time = time.monotonic()
83
+
84
+ while True:
85
+ current_state = get_state()
86
+
87
+ if current_state == target_state:
88
+ logger.debug(f"Target state {target_state.value} reached")
89
+
90
+ if current_state == CudaCheckpointState.FAILED:
91
+ raise CudaCheckpointException(f"CUDA process state is {current_state}")
92
+
93
+ elapsed = time.monotonic() - start_time
94
+ if elapsed >= timeout_secs:
95
+ raise CudaCheckpointException(f"Timeout after {elapsed:.2f}s waiting for state {target_state.value}")
96
+
97
+ time.sleep(0.1)
98
+
99
+
100
+ def get_own_pid():
101
+ """Returns the Process ID (PID) of the current Python process
102
+ using only the standard library.
103
+ """
104
+ return os.getpid()
modal/app.py CHANGED
@@ -617,6 +617,7 @@ class _App:
617
617
  _experimental_buffer_containers: Optional[int] = None, # Number of additional, idle containers to keep around.
618
618
  _experimental_proxy_ip: Optional[str] = None, # IP address of proxy
619
619
  _experimental_custom_scaling_factor: Optional[float] = None, # Custom scaling factor
620
+ _experimental_enable_gpu_snapshot: bool = False, # Experimentally enable GPU memory snapshots.
620
621
  ) -> _FunctionDecoratorType:
621
622
  """Decorator to register a new Modal [Function](/docs/reference/modal.Function) with this App."""
622
623
  if isinstance(_warn_parentheses_missing, _Image):
@@ -759,6 +760,7 @@ class _App:
759
760
  i6pn_enabled=i6pn_enabled,
760
761
  cluster_size=cluster_size, # Experimental: Clustered functions
761
762
  include_source=include_source if include_source is not None else self._include_source_default,
763
+ _experimental_enable_gpu_snapshot=_experimental_enable_gpu_snapshot,
762
764
  )
763
765
 
764
766
  self._add_function(function, webhook_config is not None)
@@ -816,6 +818,7 @@ class _App:
816
818
  _experimental_buffer_containers: Optional[int] = None, # Number of additional, idle containers to keep around.
817
819
  _experimental_proxy_ip: Optional[str] = None, # IP address of proxy
818
820
  _experimental_custom_scaling_factor: Optional[float] = None, # Custom scaling factor
821
+ _experimental_enable_gpu_snapshot: bool = False, # Experimentally enable GPU memory snapshots.
819
822
  ) -> Callable[[CLS_T], CLS_T]:
820
823
  """
821
824
  Decorator to register a new Modal [Cls](/docs/reference/modal.Cls) with this App.
@@ -890,6 +893,7 @@ class _App:
890
893
  _experimental_buffer_containers=_experimental_buffer_containers,
891
894
  _experimental_proxy_ip=_experimental_proxy_ip,
892
895
  _experimental_custom_scaling_factor=_experimental_custom_scaling_factor,
896
+ _experimental_enable_gpu_snapshot=_experimental_enable_gpu_snapshot,
893
897
  )
894
898
 
895
899
  self._add_function(cls_func, is_web_endpoint=False)
modal/app.pyi CHANGED
@@ -197,6 +197,7 @@ class _App:
197
197
  _experimental_buffer_containers: typing.Optional[int] = None,
198
198
  _experimental_proxy_ip: typing.Optional[str] = None,
199
199
  _experimental_custom_scaling_factor: typing.Optional[float] = None,
200
+ _experimental_enable_gpu_snapshot: bool = False,
200
201
  ) -> _FunctionDecoratorType: ...
201
202
  @typing_extensions.dataclass_transform(
202
203
  field_specifiers=(modal.cls.parameter,),
@@ -241,6 +242,7 @@ class _App:
241
242
  _experimental_buffer_containers: typing.Optional[int] = None,
242
243
  _experimental_proxy_ip: typing.Optional[str] = None,
243
244
  _experimental_custom_scaling_factor: typing.Optional[float] = None,
245
+ _experimental_enable_gpu_snapshot: bool = False,
244
246
  ) -> collections.abc.Callable[[CLS_T], CLS_T]: ...
245
247
  async def spawn_sandbox(
246
248
  self,
@@ -431,6 +433,7 @@ class App:
431
433
  _experimental_buffer_containers: typing.Optional[int] = None,
432
434
  _experimental_proxy_ip: typing.Optional[str] = None,
433
435
  _experimental_custom_scaling_factor: typing.Optional[float] = None,
436
+ _experimental_enable_gpu_snapshot: bool = False,
434
437
  ) -> _FunctionDecoratorType: ...
435
438
  @typing_extensions.dataclass_transform(
436
439
  field_specifiers=(modal.cls.parameter,),
@@ -475,6 +478,7 @@ class App:
475
478
  _experimental_buffer_containers: typing.Optional[int] = None,
476
479
  _experimental_proxy_ip: typing.Optional[str] = None,
477
480
  _experimental_custom_scaling_factor: typing.Optional[float] = None,
481
+ _experimental_enable_gpu_snapshot: bool = False,
478
482
  ) -> collections.abc.Callable[[CLS_T], CLS_T]: ...
479
483
 
480
484
  class __spawn_sandbox_spec(typing_extensions.Protocol[SUPERSELF]):
modal/client.pyi CHANGED
@@ -27,7 +27,7 @@ class _Client:
27
27
  _snapshotted: bool
28
28
 
29
29
  def __init__(
30
- self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.73.7"
30
+ self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.73.9"
31
31
  ): ...
32
32
  def is_closed(self) -> bool: ...
33
33
  @property
@@ -85,7 +85,7 @@ class Client:
85
85
  _snapshotted: bool
86
86
 
87
87
  def __init__(
88
- self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.73.7"
88
+ self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.73.9"
89
89
  ): ...
90
90
  def is_closed(self) -> bool: ...
91
91
  @property
modal/config.py CHANGED
@@ -223,6 +223,7 @@ _SETTINGS = {
223
223
  "strict_parameters": _Setting(False, transform=_to_boolean), # For internal/experimental use
224
224
  "snapshot_debug": _Setting(False, transform=_to_boolean),
225
225
  "client_retries": _Setting(False, transform=_to_boolean), # For internal testing.
226
+ "cuda_checkpoint_path": _Setting("/__modal/.bin/cuda-checkpoint"), # Used for snapshotting GPU memory.
226
227
  }
227
228
 
228
229
 
modal/functions.pyi CHANGED
@@ -102,6 +102,7 @@ class Function(
102
102
  _experimental_buffer_containers: typing.Optional[int] = None,
103
103
  _experimental_proxy_ip: typing.Optional[str] = None,
104
104
  _experimental_custom_scaling_factor: typing.Optional[float] = None,
105
+ _experimental_enable_gpu_snapshot: bool = False,
105
106
  ) -> Function: ...
106
107
  def _bind_parameters(
107
108
  self,
@@ -199,11 +200,11 @@ class Function(
199
200
 
200
201
  _call_generator_nowait: ___call_generator_nowait_spec[typing_extensions.Self]
201
202
 
202
- class __remote_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
203
+ class __remote_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
203
204
  def __call__(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER: ...
204
205
  async def aio(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER: ...
205
206
 
206
- remote: __remote_spec[modal._functions.ReturnType, modal._functions.P, typing_extensions.Self]
207
+ remote: __remote_spec[modal._functions.P, modal._functions.ReturnType, typing_extensions.Self]
207
208
 
208
209
  class __remote_gen_spec(typing_extensions.Protocol[SUPERSELF]):
209
210
  def __call__(self, *args, **kwargs) -> typing.Generator[typing.Any, None, None]: ...
@@ -218,19 +219,19 @@ class Function(
218
219
  self, *args: modal._functions.P.args, **kwargs: modal._functions.P.kwargs
219
220
  ) -> modal._functions.OriginalReturnType: ...
220
221
 
221
- class ___experimental_spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
222
+ class ___experimental_spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
222
223
  def __call__(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
223
224
  async def aio(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
224
225
 
225
226
  _experimental_spawn: ___experimental_spawn_spec[
226
- modal._functions.ReturnType, modal._functions.P, typing_extensions.Self
227
+ modal._functions.P, modal._functions.ReturnType, typing_extensions.Self
227
228
  ]
228
229
 
229
- class __spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
230
+ class __spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
230
231
  def __call__(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
231
232
  async def aio(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
232
233
 
233
- spawn: __spawn_spec[modal._functions.ReturnType, modal._functions.P, typing_extensions.Self]
234
+ spawn: __spawn_spec[modal._functions.P, modal._functions.ReturnType, typing_extensions.Self]
234
235
 
235
236
  def get_raw_f(self) -> collections.abc.Callable[..., typing.Any]: ...
236
237
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: modal
3
- Version: 0.73.7
3
+ Version: 0.73.9
4
4
  Summary: Python client library for Modal
5
5
  Author: Modal Labs
6
6
  Author-email: support@modal.com
@@ -3,7 +3,7 @@ modal/__main__.py,sha256=scYhGFqh8OJcVDo-VOxIT6CCwxOgzgflYWMnIZiMRqE,2871
3
3
  modal/_clustered_functions.py,sha256=kTf-9YBXY88NutC1akI-gCbvf01RhMPCw-zoOI_YIUE,2700
4
4
  modal/_clustered_functions.pyi,sha256=vllkegc99A0jrUOWa8mdlSbdp6uz36TsHhGxysAOpaQ,771
5
5
  modal/_container_entrypoint.py,sha256=qahIuJvaMmWG85N5vNS1yuAQ9XZoo1ftzfatkos_q7I,29553
6
- modal/_functions.py,sha256=4-CRh1Hgi508tEZRFaSRYdS1Oki0MPgAhnUYcEckMe4,70113
6
+ modal/_functions.py,sha256=XTcpMIlGqa3MPSTbnCwvbagTCeIHlnV4g8WlkGF5SOs,70352
7
7
  modal/_ipython.py,sha256=TW1fkVOmZL3YYqdS2YlM1hqpf654Yf8ZyybHdBnlhSw,301
8
8
  modal/_location.py,sha256=S3lSxIU3h9HkWpkJ3Pwo0pqjIOSB1fjeSgUsY3x7eec,1202
9
9
  modal/_object.py,sha256=ItQcsMNkz9Y3kdTsvfNarbW-paJ2qabDyQ7njaqY0XI,11359
@@ -17,16 +17,16 @@ modal/_traceback.py,sha256=IZQzB3fVlUfMHOSyKUgw0H6qv4yHnpyq-XVCNZKfUdA,5023
17
17
  modal/_tunnel.py,sha256=zTBxBiuH1O22tS1OliAJdIsSmaZS8PlnifS_6S5z-mk,6320
18
18
  modal/_tunnel.pyi,sha256=JmmDYAy9F1FpgJ_hWx0xkom2nTOFQjn4mTPYlU3PFo4,1245
19
19
  modal/_watcher.py,sha256=K6LYnlmSGQB4tWWI9JADv-tvSvQ1j522FwT71B51CX8,3584
20
- modal/app.py,sha256=4tHmc1hFAL9uGj9wp-u7AOPp2mWfu4wJ-633ghFePIY,44248
21
- modal/app.pyi,sha256=ppb3UmJU4oX-Ptd5v_SOQJBP1309qovKaJnH5844pFI,25885
20
+ modal/app.py,sha256=wRygVSrWH8iIqhDAAl2Ww_RAkz8MCJZ0Jt9qYZCF6SA,44626
21
+ modal/app.pyi,sha256=lxiuWzE_OLb3WHg-H7Pek9DGBuCUzZ55P594VhJL5LA,26113
22
22
  modal/call_graph.py,sha256=1g2DGcMIJvRy-xKicuf63IVE98gJSnQsr8R_NVMptNc,2581
23
23
  modal/client.py,sha256=8SQawr7P1PNUCq1UmJMUQXG2jIo4Nmdcs311XqrNLRE,15276
24
- modal/client.pyi,sha256=IdooVP7M-V4EO74JFSFG91VhsFwQVm7-5IQvvu4idL0,7591
24
+ modal/client.pyi,sha256=UOfACeLizRMYzf2NDFzalr9sLhXAy447M3jSwPxPCbc,7591
25
25
  modal/cloud_bucket_mount.py,sha256=YOe9nnvSr4ZbeCn587d7_VhE9IioZYRvF9VYQTQux08,5914
26
26
  modal/cloud_bucket_mount.pyi,sha256=30T3K1a89l6wzmEJ_J9iWv9SknoGqaZDx59Xs-ZQcmk,1607
27
27
  modal/cls.py,sha256=kNnZrBYVXOhgEXU0rDWk2Hr-bQRrsZkMKDgC-TD_6Bs,31063
28
28
  modal/cls.pyi,sha256=gb6QNwfX3HSJfcZXPY36N9ywF7aBJTwwtoARnf3G1HQ,8877
29
- modal/config.py,sha256=BzhZYUUwOmvVwf6x5kf0ywMC257s648dmuhsnB6g3gk,11041
29
+ modal/config.py,sha256=XT1W4Y9PVkbYMAXjJRshvQEPDhZmnfW_ZRMwl8XKoqA,11149
30
30
  modal/container_process.py,sha256=WTqLn01dJPVkPpwR_0w_JH96ceN5mV4TGtiu1ZR2RRA,6108
31
31
  modal/container_process.pyi,sha256=Hf0J5JyDdCCXBJSKx6gvkPOo0XrztCm78xzxamtzUjQ,2828
32
32
  modal/dict.py,sha256=vc5lQVqzeDUCb4fRjnOlqYK2GmBb0fIhZmvB0xIBG0U,12921
@@ -40,7 +40,7 @@ modal/file_io.py,sha256=lcMs_E9Xfm0YX1t9U2wNIBPnqHRxmImqjLW1GHqVmyg,20945
40
40
  modal/file_io.pyi,sha256=NTRft1tbPSWf9TlWVeZmTlgB5AZ_Zhu2srWIrWr7brk,9445
41
41
  modal/file_pattern_matcher.py,sha256=1cZ4V2wSLiaXqAqStETSwp3bzDD6QZOt6pmmjk3Okz4,6505
42
42
  modal/functions.py,sha256=kcNHvqeGBxPI7Cgd57NIBBghkfbeFJzXO44WW0jSmao,325
43
- modal/functions.pyi,sha256=pStDYd9PnJVvWs57qhKIVnmYYAhvKdYzVNoNU1A-s_Q,14231
43
+ modal/functions.pyi,sha256=QYZy3BCjA2y3UC217e3YG-omyG0E1Jx-Uc-sonsyQsE,14288
44
44
  modal/gpu.py,sha256=2qZMNnoMrjU-5Bu7fx68pANUAKTtZq0EWEEeBA9OUVQ,7426
45
45
  modal/image.py,sha256=Vjsi7wS9dEcoj-7m7_LmvbK5iqEuFz-SHKl2K-qWcew,90952
46
46
  modal/image.pyi,sha256=A5mW2dBguEhmRo815Ax1rBIMXTCriu7PqLMHoUPsez8,26372
@@ -83,8 +83,9 @@ modal/volume.py,sha256=JAWeDvoAG95tMBv-fYIERyHsJPS_X_xGpxRRmYtb6j0,30096
83
83
  modal/volume.pyi,sha256=kTsXarphjZILXci84LQy7EyC84eXUs5-7D62IM5q3eE,12491
84
84
  modal/_runtime/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0VESpjWR0fc,28
85
85
  modal/_runtime/asgi.py,sha256=c4hmaMW1pLo-cm7ouriJjieuFm4ZF6D2LMy0638sfOs,22139
86
- modal/_runtime/container_io_manager.py,sha256=QVWMCvJatd2696wsauzXl20psxCYsR0d_CHeS5ceTsU,43201
86
+ modal/_runtime/container_io_manager.py,sha256=L6qv-Mo3mN3ttR5GX-G36cUhH_oz8wdP5WG0HT5FFzg,44619
87
87
  modal/_runtime/execution_context.py,sha256=E6ofm6j1POXGPxS841X3V7JU6NheVb8OkQc7JpLq4Kg,2712
88
+ modal/_runtime/gpu_memory_snapshot.py,sha256=vV6igsqN9CxOoH91kUkuaZQ32QfX5wdoXIS-6MIYX2Y,3315
88
89
  modal/_runtime/telemetry.py,sha256=T1RoAGyjBDr1swiM6pPsGRSITm7LI5FDK18oNXxY08U,5163
89
90
  modal/_runtime/user_code_imports.py,sha256=zl_Mq9dsrVF62x3w-iNK1YAhZKYAXeFaGpd4G7AySTc,14746
90
91
  modal/_utils/__init__.py,sha256=waLjl5c6IPDhSsdWAm9Bji4e2PVxamYABKAze6CHVXY,28
@@ -153,10 +154,10 @@ modal_global_objects/mounts/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0
153
154
  modal_global_objects/mounts/modal_client_package.py,sha256=W0E_yShsRojPzWm6LtIQqNVolapdnrZkm2hVEQuZK_4,767
154
155
  modal_global_objects/mounts/python_standalone.py,sha256=EsC-hdPtiAPOwgW9emHN6muNUkrJwR8dYxroVArxHxM,1841
155
156
  modal_proto/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0VESpjWR0fc,28
156
- modal_proto/api.proto,sha256=Ked8dBpkIRf90TAAF1MQkAsu44l3wjVNq7YVX9plzAs,85124
157
+ modal_proto/api.proto,sha256=_RV_hQIWR_CmanZcjieKll-P9P5qVsRDDS7TtGWL4AU,85264
157
158
  modal_proto/api_grpc.py,sha256=FYGqDegM_w_qxdtlxum8k31mDibKoMvmNxv_p9cKdKs,109056
158
- modal_proto/api_pb2.py,sha256=K2y9GzCtyUb7jg6JdX_wL3oAhK_DwWIQytBbm7lu13s,310989
159
- modal_proto/api_pb2.pyi,sha256=_A_5wXULI7OS24VVbKLGigc_Z6ityG1Xp4Z0weZPzK4,414818
159
+ modal_proto/api_pb2.py,sha256=7hj3Dqmv3Xb6nEzLVMt-zai1EGqUT5uAU5nbGjnk85A,311104
160
+ modal_proto/api_pb2.pyi,sha256=ScYf3xdzV3TQZZR-uPusjrEHoHIxKCRPseS7e8Ee_EI,415384
160
161
  modal_proto/api_pb2_grpc.py,sha256=DNp0Et5i_Ey4dKx_1o1LRtYhyWYyT0NzTcAY4EcHn-c,235765
161
162
  modal_proto/api_pb2_grpc.pyi,sha256=RI6tWC3L8EIN4-izFSEGPPJl5Ta0lXPNuHUJaWAr35s,54892
162
163
  modal_proto/modal_api_grpc.py,sha256=UG8WJU81afrWPwItWB4Ag64E9EpyREMpBbAVGVEYJiM,14550
@@ -170,10 +171,10 @@ modal_proto/options_pb2_grpc.pyi,sha256=CImmhxHsYnF09iENPoe8S4J-n93jtgUYD2JPAc0y
170
171
  modal_proto/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
171
172
  modal_version/__init__.py,sha256=wiJQ53c-OMs0Xf1UeXOxQ7FwlV1VzIjnX6o-pRYZ_Pk,470
172
173
  modal_version/__main__.py,sha256=2FO0yYQQwDTh6udt1h-cBnGd1c4ZyHnHSI4BksxzVac,105
173
- modal_version/_version_generated.py,sha256=o0syRK3ZmTNxvzqCB10qZ2o4WuVW_Wn0HqidHCkVvJk,148
174
- modal-0.73.7.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
175
- modal-0.73.7.dist-info/METADATA,sha256=L5RUur3zp_azxXlfZQ-mqgOpuwt5LsYZOoFxhYHr6UY,2329
176
- modal-0.73.7.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
177
- modal-0.73.7.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
178
- modal-0.73.7.dist-info/top_level.txt,sha256=1nvYbOSIKcmU50fNrpnQnrrOpj269ei3LzgB6j9xGqg,64
179
- modal-0.73.7.dist-info/RECORD,,
174
+ modal_version/_version_generated.py,sha256=RgDn253uA_DeV6d6P40AOPpDJqMMVupp6gXgLMcak24,148
175
+ modal-0.73.9.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
176
+ modal-0.73.9.dist-info/METADATA,sha256=BYeidDOAvKaxgE_yMfAun3xjsRB6Q0jGKR8fcs9a0jU,2329
177
+ modal-0.73.9.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
178
+ modal-0.73.9.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
179
+ modal-0.73.9.dist-info/top_level.txt,sha256=1nvYbOSIKcmU50fNrpnQnrrOpj269ei3LzgB6j9xGqg,64
180
+ modal-0.73.9.dist-info/RECORD,,
modal_proto/api.proto CHANGED
@@ -1263,6 +1263,8 @@ message Function {
1263
1263
  bool _experimental_custom_scaling = 76;
1264
1264
 
1265
1265
  string cloud_provider_str = 77; // Supersedes cloud_provider
1266
+
1267
+ bool _experimental_enable_gpu_snapshot = 78; // Experimental support for GPU snapshotting
1266
1268
  }
1267
1269
 
1268
1270
  message FunctionAsyncInvokeRequest {
@@ -1376,6 +1378,7 @@ message FunctionData {
1376
1378
  uint32 _experimental_group_size = 19;
1377
1379
  uint32 _experimental_buffer_containers = 22;
1378
1380
  bool _experimental_custom_scaling = 23;
1381
+ bool _experimental_enable_gpu_snapshot = 30;
1379
1382
  string worker_id = 7; // for internal debugging use only
1380
1383
 
1381
1384
  uint32 timeout_secs = 8;