modal 1.5.6.dev1__tar.gz → 1.5.6.dev3__tar.gz
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-1.5.6.dev1 → modal-1.5.6.dev3}/PKG-INFO +1 -1
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_runtime/gpu_memory_snapshot.py +3 -34
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_runtime/task_lifecycle_manager.py +28 -16
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_runtime/task_lifecycle_manager.pyi +5 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/client.pyi +2 -2
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/config.py +2 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal.egg-info/PKG-INFO +1 -1
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal_version/__init__.py +1 -1
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/pyproject.toml +4 -8
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/LICENSE +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/README.md +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/__init__.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/__main__.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_billing.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_clustered_functions.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_clustered_functions.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_container_entrypoint.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_environments.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_function_variants.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_functions.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_grpc_client.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_image.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_ipython.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_load_context.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_location.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_logs.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_logs_manager.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_logs_manager.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_object.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_output/__init__.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_output/manager.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_output/pty.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_output/rich.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_output/status.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_partial_function.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_resolver.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_resources.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_runtime/__init__.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_runtime/asgi.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_runtime/container_io_manager.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_runtime/container_io_manager.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_runtime/execution_context.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_runtime/execution_context.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_runtime/telemetry.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_runtime/user_code_event_loop.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_runtime/user_code_imports.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_serialization.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_server.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_supports_logs.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_traceback.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_tunnel.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_tunnel.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_type_manager.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_utils/__init__.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_utils/app_utils.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_utils/async_utils.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_utils/auth_token_manager.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_utils/blob_utils.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_utils/browser_utils.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_utils/bytes_io_segment_payload.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_utils/curl_utils.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_utils/deprecation.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_utils/display_utils.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_utils/docker_utils.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_utils/function_utils.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_utils/git_utils.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_utils/grpc_testing.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_utils/grpc_utils.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_utils/hash_utils.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_utils/http_utils.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_utils/jwt_utils.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_utils/logger.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_utils/mount_utils.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_utils/name_utils.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_utils/package_utils.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_utils/pattern_utils.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_utils/proxy_support.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_utils/rand_pb_testing.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_utils/sandbox_fs_utils.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_utils/shell_utils.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_utils/task_command_router_client.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_utils/time_utils.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_vendor/__init__.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_vendor/a2wsgi_wsgi.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_vendor/cloudpickle.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_vendor/tblib.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_vendor/version.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_watcher.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/_workspace.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/app.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/app.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/billing.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/billing.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/builder/2023.12.312.txt +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/builder/2023.12.txt +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/builder/2024.04.txt +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/builder/2024.10.txt +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/builder/2025.06.txt +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/builder/PREVIEW.txt +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/builder/README.md +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/builder/base-images.json +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/call_graph.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/__init__.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/_download.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/_help.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/_traceback.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/app.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/billing.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/bootstrap.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/changelog.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/cluster.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/config.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/container.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/curl.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/dashboard.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/dict.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/endpoint.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/entry_point.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/environment.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/image.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/import_refs.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/launch.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/logo.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/network_file_system.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/profile.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/programs/__init__.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/programs/run_jupyter.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/programs/vscode.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/queues.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/run.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/secret.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/selector.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/shell.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/skills.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/token.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/utils.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/volume.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cli/workspace.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/client.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cloud_bucket_mount.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cloud_bucket_mount.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cls.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/cls.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/container_process.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/container_process.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/dict.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/dict.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/environments.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/environments.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/exception.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/experimental/__init__.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/experimental/flash.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/experimental/flash.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/experimental/ipython.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/file_io.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/file_io.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/file_pattern_matcher.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/functions.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/functions.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/image.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/image.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/io_streams.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/io_streams.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/mount.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/mount.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/network_file_system.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/network_file_system.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/object.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/object.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/output.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/parallel_map.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/parallel_map.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/partial_function.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/partial_function.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/proxy.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/proxy.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/py.typed +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/queue.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/queue.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/retries.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/runner.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/runner.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/running_app.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/sandbox.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/sandbox.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/sandbox_fs.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/sandbox_fs.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/schedule.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/scheduler_placement.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/secret.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/secret.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/server.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/server.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/serving.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/serving.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/skills/modal/SKILL.md +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/snapshot.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/snapshot.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/stream_type.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/token_flow.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/token_flow.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/types.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/volume.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/volume.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/workspace.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal/workspace.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal.egg-info/SOURCES.txt +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal.egg-info/dependency_links.txt +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal.egg-info/entry_points.txt +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal.egg-info/requires.txt +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal.egg-info/top_level.txt +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal_docs/__init__.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal_docs/gen_cli_docs.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal_docs/gen_cli_docs_main.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal_docs/gen_reference_docs.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal_docs/gen_reference_docs_main.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal_docs/mdmd/__init__.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal_docs/mdmd/mdmd.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal_docs/mdmd/signatures.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal_docs/mdmd/types.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal_docs/reference_intro.md +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal_proto/__init__.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal_proto/api_grpc.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal_proto/api_pb2.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal_proto/api_pb2.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal_proto/api_pb2_grpc.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal_proto/api_pb2_grpc.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal_proto/modal_api_grpc.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal_proto/py.typed +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal_proto/task_command_router_grpc.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal_proto/task_command_router_pb2.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal_proto/task_command_router_pb2.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal_proto/task_command_router_pb2_grpc.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/modal_version/__main__.py +0 -0
- {modal-1.5.6.dev1 → modal-1.5.6.dev3}/setup.cfg +0 -0
|
@@ -22,15 +22,9 @@ CUDA_CHECKPOINT_PATH: str = config.get("cuda_checkpoint_path")
|
|
|
22
22
|
# stay in sync with `GPU_SNAPSHOT_RESTORE_FAILED_EXIT_CODE` in runner.rs.
|
|
23
23
|
SNAPSHOT_RESTORE_FAILED_EXIT_CODE: int = 222
|
|
24
24
|
|
|
25
|
-
# Maximum total duration for each individual `cuda-checkpoint` invocation.
|
|
26
|
-
CUDA_CHECKPOINT_TIMEOUT: float = 3 * 60.0
|
|
27
|
-
|
|
28
25
|
# Number of retries for each individual `cuda-checkpoint --toggle` invocation.
|
|
29
26
|
CUDA_CHECKPOINT_TOGGLE_NUM_RETRIES: int = 3
|
|
30
27
|
|
|
31
|
-
# Maximum total duration for an entire toggle operation.
|
|
32
|
-
CUDA_CHECKPOINT_TOGGLE_TIMEOUT: float = CUDA_CHECKPOINT_TOGGLE_NUM_RETRIES * CUDA_CHECKPOINT_TIMEOUT
|
|
33
|
-
|
|
34
28
|
|
|
35
29
|
class CudaCheckpointState(Enum):
|
|
36
30
|
"""State representation from the CUDA API [1].
|
|
@@ -63,14 +57,11 @@ class CudaCheckpointProcess:
|
|
|
63
57
|
"""
|
|
64
58
|
logger.debug(f"PID: {self.pid} Toggling CUDA checkpoint state to {target_state.value}")
|
|
65
59
|
|
|
66
|
-
start_time = time.monotonic()
|
|
67
60
|
retry_count = 0
|
|
68
61
|
max_retries = CUDA_CHECKPOINT_TOGGLE_NUM_RETRIES
|
|
69
62
|
|
|
70
63
|
attempts = 0
|
|
71
|
-
while self._should_continue_toggle(
|
|
72
|
-
target_state, start_time, refresh=not (skip_first_refresh and attempts == 0)
|
|
73
|
-
):
|
|
64
|
+
while self._should_continue_toggle(target_state, refresh=not (skip_first_refresh and attempts == 0)):
|
|
74
65
|
attempts += 1
|
|
75
66
|
try:
|
|
76
67
|
self._execute_toggle_command()
|
|
@@ -89,10 +80,8 @@ class CudaCheckpointProcess:
|
|
|
89
80
|
|
|
90
81
|
logger.debug(f"PID: {self.pid} Target state {target_state.value} reached")
|
|
91
82
|
|
|
92
|
-
def _should_continue_toggle(
|
|
93
|
-
|
|
94
|
-
) -> bool:
|
|
95
|
-
"""Check if toggle operation should continue based on current state and timeout."""
|
|
83
|
+
def _should_continue_toggle(self, target_state: CudaCheckpointState, refresh: bool = True) -> bool:
|
|
84
|
+
"""Check if toggle operation should continue based on current state."""
|
|
96
85
|
if refresh:
|
|
97
86
|
self.refresh_state()
|
|
98
87
|
|
|
@@ -102,13 +91,6 @@ class CudaCheckpointProcess:
|
|
|
102
91
|
if self.state == CudaCheckpointState.FAILED:
|
|
103
92
|
raise CudaCheckpointException(f"PID: {self.pid} CUDA process state is {self.state}")
|
|
104
93
|
|
|
105
|
-
elapsed = time.monotonic() - start_time
|
|
106
|
-
if elapsed >= CUDA_CHECKPOINT_TOGGLE_TIMEOUT:
|
|
107
|
-
raise CudaCheckpointException(
|
|
108
|
-
f"PID: {self.pid} Timeout after {elapsed:.2f}s waiting for state {target_state.value}. "
|
|
109
|
-
f"Current state: {self.state}"
|
|
110
|
-
)
|
|
111
|
-
|
|
112
94
|
return True
|
|
113
95
|
|
|
114
96
|
def _execute_toggle_command(self) -> None:
|
|
@@ -119,17 +101,12 @@ class CudaCheckpointProcess:
|
|
|
119
101
|
check=True,
|
|
120
102
|
capture_output=True,
|
|
121
103
|
text=True,
|
|
122
|
-
timeout=CUDA_CHECKPOINT_TIMEOUT,
|
|
123
104
|
)
|
|
124
105
|
logger.debug(f"PID: {self.pid} Successfully toggled CUDA checkpoint state")
|
|
125
106
|
except subprocess.CalledProcessError as e:
|
|
126
107
|
error_msg = f"PID: {self.pid} Failed to toggle CUDA checkpoint state: {e.stderr}"
|
|
127
108
|
logger.debug(error_msg)
|
|
128
109
|
raise CudaCheckpointException(error_msg)
|
|
129
|
-
except subprocess.TimeoutExpired:
|
|
130
|
-
error_msg = f"PID: {self.pid} Toggle command timed out"
|
|
131
|
-
logger.debug(error_msg)
|
|
132
|
-
raise CudaCheckpointException(error_msg)
|
|
133
110
|
|
|
134
111
|
def refresh_state(self) -> None:
|
|
135
112
|
"""Refreshes the current CUDA checkpoint state for this process."""
|
|
@@ -139,7 +116,6 @@ class CudaCheckpointProcess:
|
|
|
139
116
|
check=True,
|
|
140
117
|
capture_output=True,
|
|
141
118
|
text=True,
|
|
142
|
-
timeout=CUDA_CHECKPOINT_TIMEOUT,
|
|
143
119
|
)
|
|
144
120
|
|
|
145
121
|
state_str = result.stdout.strip().lower()
|
|
@@ -149,10 +125,6 @@ class CudaCheckpointProcess:
|
|
|
149
125
|
error_msg = f"PID: {self.pid} Failed to get CUDA checkpoint state: {e.stderr}"
|
|
150
126
|
logger.debug(error_msg)
|
|
151
127
|
raise CudaCheckpointException(error_msg)
|
|
152
|
-
except subprocess.TimeoutExpired:
|
|
153
|
-
error_msg = f"PID: {self.pid} Get state command timed out"
|
|
154
|
-
logger.debug(error_msg)
|
|
155
|
-
raise CudaCheckpointException(error_msg)
|
|
156
128
|
|
|
157
129
|
|
|
158
130
|
class CudaCheckpointSession:
|
|
@@ -208,7 +180,6 @@ class CudaCheckpointSession:
|
|
|
208
180
|
[CUDA_CHECKPOINT_PATH, "--get-state", "--pid", str(pid)],
|
|
209
181
|
capture_output=True,
|
|
210
182
|
text=True,
|
|
211
|
-
timeout=CUDA_CHECKPOINT_TIMEOUT,
|
|
212
183
|
)
|
|
213
184
|
|
|
214
185
|
# If the command succeeds (return code 0), this PID has a CUDA session
|
|
@@ -220,8 +191,6 @@ class CudaCheckpointSession:
|
|
|
220
191
|
except subprocess.CalledProcessError:
|
|
221
192
|
# Command failed, which is expected for PIDs without CUDA sessions
|
|
222
193
|
pass
|
|
223
|
-
except subprocess.TimeoutExpired:
|
|
224
|
-
logger.debug(f"Timeout checking CUDA state for PID {pid}")
|
|
225
194
|
except Exception as e:
|
|
226
195
|
logger.debug(f"Error checking PID {pid}: {e}")
|
|
227
196
|
|
|
@@ -143,6 +143,12 @@ class _TaskLifecycleManager:
|
|
|
143
143
|
else:
|
|
144
144
|
logger.debug(f"modal.Volume background commit success for {volume_id}.")
|
|
145
145
|
|
|
146
|
+
@property
|
|
147
|
+
def _gpu_snapshot_enabled(self) -> bool:
|
|
148
|
+
return bool(
|
|
149
|
+
self.function_def._experimental_enable_gpu_snapshot and self.function_def.resources.gpu_config.gpu_type
|
|
150
|
+
)
|
|
151
|
+
|
|
146
152
|
async def memory_restore(self) -> None:
|
|
147
153
|
# Busy-wait for restore. `/__modal/restore-state.json` is created
|
|
148
154
|
# by the worker process with updates to the container config.
|
|
@@ -177,18 +183,21 @@ class _TaskLifecycleManager:
|
|
|
177
183
|
config.override_locally(key, value)
|
|
178
184
|
|
|
179
185
|
# Restore GPU memory.
|
|
180
|
-
if self.
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
186
|
+
if self._gpu_snapshot_enabled:
|
|
187
|
+
if config.get("runtime_managed_cuda_checkpoint"):
|
|
188
|
+
logger.debug("GPU memory restore is managed by the container runtime.")
|
|
189
|
+
else:
|
|
190
|
+
logger.debug("GPU memory snapshot enabled. Attempting to restore GPU memory.")
|
|
191
|
+
|
|
192
|
+
try:
|
|
193
|
+
if self._cuda_checkpoint_session is None:
|
|
194
|
+
raise gpu_memory_snapshot.CudaCheckpointException("CudaCheckpointSession not found")
|
|
195
|
+
self._cuda_checkpoint_session.restore()
|
|
196
|
+
except gpu_memory_snapshot.CudaCheckpointException as exc:
|
|
197
|
+
logger.warning(f"GPU memory snapshot restore failed; retrying task without snapshot. Error: {exc}")
|
|
198
|
+
sys.stderr.flush()
|
|
199
|
+
# Exit with a sentinel code that the runtime will use to retry the task without a snapshot.
|
|
200
|
+
os._exit(gpu_memory_snapshot.SNAPSHOT_RESTORE_FAILED_EXIT_CODE)
|
|
192
201
|
|
|
193
202
|
self._client = await _Client.from_env()
|
|
194
203
|
|
|
@@ -199,11 +208,14 @@ class _TaskLifecycleManager:
|
|
|
199
208
|
else:
|
|
200
209
|
raise ValueError("No checkpoint ID provided for memory snapshot")
|
|
201
210
|
|
|
202
|
-
if self.
|
|
203
|
-
|
|
211
|
+
if self._gpu_snapshot_enabled:
|
|
212
|
+
if config.get("runtime_managed_cuda_checkpoint"):
|
|
213
|
+
logger.debug("GPU memory snapshot is managed by the container runtime.")
|
|
214
|
+
else:
|
|
215
|
+
logger.debug("GPU memory snapshot enabled. Attempting to snapshot GPU memory.")
|
|
204
216
|
|
|
205
|
-
|
|
206
|
-
|
|
217
|
+
self._cuda_checkpoint_session = gpu_memory_snapshot.CudaCheckpointSession()
|
|
218
|
+
self._cuda_checkpoint_session.checkpoint()
|
|
207
219
|
|
|
208
220
|
await self._client.stub.ContainerCheckpoint(
|
|
209
221
|
api_pb2.ContainerCheckpointRequest(checkpoint_id=self.checkpoint_id)
|
|
@@ -54,6 +54,8 @@ class _TaskLifecycleManager:
|
|
|
54
54
|
"""
|
|
55
55
|
...
|
|
56
56
|
|
|
57
|
+
@property
|
|
58
|
+
def _gpu_snapshot_enabled(self) -> bool: ...
|
|
57
59
|
async def memory_restore(self) -> None: ...
|
|
58
60
|
async def memory_snapshot(self) -> None:
|
|
59
61
|
"""Message server indicating that function is ready to be checkpointed."""
|
|
@@ -111,6 +113,9 @@ class TaskLifecycleManager:
|
|
|
111
113
|
|
|
112
114
|
volume_commit: __volume_commit_spec
|
|
113
115
|
|
|
116
|
+
@property
|
|
117
|
+
def _gpu_snapshot_enabled(self) -> bool: ...
|
|
118
|
+
|
|
114
119
|
class __memory_restore_spec(typing_extensions.Protocol):
|
|
115
120
|
def __call__(self, /) -> None: ...
|
|
116
121
|
async def aio(self, /) -> None: ...
|
|
@@ -77,7 +77,7 @@ class _Client:
|
|
|
77
77
|
server_url: str,
|
|
78
78
|
client_type: int,
|
|
79
79
|
credentials: typing.Optional[tuple[str, str]],
|
|
80
|
-
version: str = "1.5.6.
|
|
80
|
+
version: str = "1.5.6.dev3",
|
|
81
81
|
*,
|
|
82
82
|
oauth_credentials: typing.Optional[_OAuthCredentials] = None,
|
|
83
83
|
):
|
|
@@ -277,7 +277,7 @@ class Client:
|
|
|
277
277
|
server_url: str,
|
|
278
278
|
client_type: int,
|
|
279
279
|
credentials: typing.Optional[tuple[str, str]],
|
|
280
|
-
version: str = "1.5.6.
|
|
280
|
+
version: str = "1.5.6.dev3",
|
|
281
281
|
*,
|
|
282
282
|
oauth_credentials: typing.Optional[_OAuthCredentials] = None,
|
|
283
283
|
):
|
|
@@ -339,6 +339,8 @@ _SETTINGS = {
|
|
|
339
339
|
"sandbox_v2": _Setting(None, transform=_to_boolean),
|
|
340
340
|
"snapshot_debug": _Setting(False, transform=_to_boolean),
|
|
341
341
|
"cuda_checkpoint_path": _Setting("/__modal/.bin/cuda-checkpoint"), # Used for snapshotting GPU memory.
|
|
342
|
+
# Used to indicate gVisor cuda-checkpoint automation.
|
|
343
|
+
"runtime_managed_cuda_checkpoint": _Setting(False, transform=_to_boolean),
|
|
342
344
|
"build_validation": _Setting("error", transform=_check_value(["error", "warn", "ignore"])),
|
|
343
345
|
# Payload format for function inputs/outputs: 'pickle' (default) or 'cbor'
|
|
344
346
|
"payload_format": _Setting(
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
[build-system]
|
|
2
|
-
requires = ["setuptools
|
|
2
|
+
requires = ["setuptools>=83,<84", "wheel"]
|
|
3
3
|
build-backend = "setuptools.build_meta"
|
|
4
4
|
|
|
5
5
|
[project]
|
|
@@ -53,10 +53,10 @@ dev = [
|
|
|
53
53
|
"pytest-env~=1.1.5",
|
|
54
54
|
"pytest-markdown-docs==0.9.2",
|
|
55
55
|
"pytest-timeout~=2.4.0",
|
|
56
|
-
"python-dotenv~=1.
|
|
57
|
-
"requests
|
|
56
|
+
"python-dotenv~=1.2.2",
|
|
57
|
+
"requests==2.33.0",
|
|
58
58
|
"ruff~=0.9.6",
|
|
59
|
-
"setuptools
|
|
59
|
+
"setuptools>=83,<84",
|
|
60
60
|
"types-croniter~=1.0.8",
|
|
61
61
|
"types-python-dateutil~=2.8.10",
|
|
62
62
|
"types-requests~=2.31.0",
|
|
@@ -98,10 +98,6 @@ dev = [
|
|
|
98
98
|
"aiohttp-socks>=0.8",
|
|
99
99
|
]
|
|
100
100
|
|
|
101
|
-
[tool.uv.extra-build-dependencies]
|
|
102
|
-
grpcio-tools = ["setuptools<82"]
|
|
103
|
-
|
|
104
|
-
|
|
105
101
|
[project.urls]
|
|
106
102
|
Homepage = "https://modal.com"
|
|
107
103
|
Source = "https://github.com/modal-labs/modal-client"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|