diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c1726931..45a3b483 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -86,4 +86,4 @@ jobs: cache: false environments: default activate-environment: default - - run: pytest tests/test_CI.py + - run: pytest tests/test_ci.py diff --git a/.gitignore b/.gitignore index 240c67cf..af2731dd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,7 @@ +torchrunx_logs/ .pixi/ -logs/ -test_logs/ -_build/ -out/ -output/ +.ruff_cache/ +.vscode/ # Byte-compiled / optimized / DLL files __pycache__/ diff --git a/docs/source/advanced.rst b/docs/source/advanced.rst index 542d5698..dd8a7179 100644 --- a/docs/source/advanced.rst +++ b/docs/source/advanced.rst @@ -16,13 +16,21 @@ In addition to ``torchrunx.launch``, we provide the ``torchrunx.Launcher`` datac launcher.run(distributed_function, {}) .. autoclass:: torchrunx.Launcher - -.. autofunction:: torchrunx.Launcher.run + :members: +.. .. autofunction:: torchrunx.Launcher.run Logging ------- -All logs are generated in the folder provided as the ``logs`` argument to :mod:`torchrunx.launch`. Each worker agent generates a log, named based on the current date and time, followed by the agent hostname. Each worker also has a log, named identically to their agent's log file except for the addition of the worker's local rank at the end of the name. Each agent includes the output from local worker 0 in its log. The launcher renders agent 0's log to ``stdout`` in real time. +Logs are generated at the worker and agent level, and are specified to :mod:`torchrunx.launch` via the ``log_spec`` argument. By default, a :mod:`torchrunx.DefaultLogSpec` is instantiated, causing logs at the worker and agent levels to be logged to files under ``'./logs'``, and the rank 0 worker's output streams are streamed to the launcher ``stdout``. Logs are prefixed with a timestamp by default. Agent logs have the format ``{timestamp}-{agent hostname}.log`` and workers have the format ``{timestamp}-{agent hostname}[{worker local rank}].log``. + +Custom logging classes can be subclassed from the :mod:`torchrunx.LogSpec` class. Any subclass must have a ``get_map`` method returning a dictionary mapping logger names to lists of :mod:`logging.Handler` objects, in order to be passed to :mod:`torchrunx.launch`. The logger names are of the format ``{agent hostname}`` for agents and ``{agent hostname}[{worker local rank}]`` for workers. The :mod:`torchrunx.DefaultLogSpec` maps all the loggers to :mod:`logging.Filehandler` object pointing to the files mentioned in the previous paragraph. It additionally maps the global rank 0 worker to a :mod:`logging.StreamHandler`, which writes logs the launcher's ``stdout`` stream. + +.. autoclass:: torchrunx.LogSpec + :members: + +.. autoclass:: torchrunx.DefaultLogSpec + :members: .. TODO: example log structure @@ -30,7 +38,7 @@ All logs are generated in the folder provided as the ``logs`` argument to :mod:` Worker environment ------------------ -The :mod:`torchrunx.launch` ``env_vars`` argument allows the user to specify which evnironmental variables should be copied to the agents from the launcher environment. By default, it attempts to copy variables related to Python and important packages/technologies that **torchrunx** uses such as PyTorch, NCCL, CUDA, and more. Strings provided are matched with the names of environmental variables using ``fnmatch`` - standard UNIX filename pattern matching. The variables are inserted into the agent environments, and then copied to workers' environments when they are spawned. +The :mod:`torchrunx.launch` ``env_vars`` argument allows the user to specify which environmental variables should be copied to the agents from the launcher environment. By default, it attempts to copy variables related to Python and important packages/technologies that **torchrunx** uses such as PyTorch, NCCL, CUDA, and more. Strings provided are matched with the names of environmental variables using ``fnmatch`` - standard UNIX filename pattern matching. The variables are inserted into the agent environments, and then copied to workers' environments when they are spawned. :mod:`torchrunx.launch` also accepts the ``env_file`` argument, which is designed to expose more advanced environmental configuration to the user. When a file is provided as this argument, the launcher will source the file on each node before executing the agent. This allows for custom bash scripts to be provided in the environmental variables, and allows for node-specific environmental variables to be set. diff --git a/pixi.lock b/pixi.lock index 6e5e6800..e67beb9f 100644 --- a/pixi.lock +++ b/pixi.lock @@ -10,7 +10,7 @@ environments: linux-64: - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.7.4-hbcca054_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.8.30-hbcca054_0.conda - conda: https://conda.anaconda.org/nvidia/label/cuda-11.7.0/linux-64/cuda-11.7.0-0.tar.bz2 - conda: https://conda.anaconda.org/nvidia/label/cuda-11.7.0/linux-64/cuda-cccl-11.7.58-hc415cf5_0.tar.bz2 - conda: https://conda.anaconda.org/nvidia/label/cuda-11.7.0/linux-64/cuda-command-line-tools-11.7.0-0.tar.bz2 @@ -58,16 +58,18 @@ environments: - conda: https://conda.anaconda.org/nvidia/label/cuda-11.7.0/linux-64/libcusparse-11.7.3.50-h6aaafad_0.tar.bz2 - conda: https://conda.anaconda.org/nvidia/label/cuda-11.7.0/linux-64/libcusparse-dev-11.7.3.50-hc644b96_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.2.1-he1b5a44_1007.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-14.1.0-h77fa898_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-14.1.0-h77fa898_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-14.1.0-h77fa898_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-14.1.0-h69a702a_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-14.1.0-h77fa898_1.conda - conda: https://conda.anaconda.org/nvidia/label/cuda-11.7.0/linux-64/libnpp-11.7.3.21-h3effbd9_0.tar.bz2 - conda: https://conda.anaconda.org/nvidia/label/cuda-11.7.0/linux-64/libnpp-dev-11.7.3.21-hb6476a9_0.tar.bz2 - conda: https://conda.anaconda.org/nvidia/label/cuda-11.7.0/linux-64/libnvjpeg-11.7.2.34-hfe236c7_0.tar.bz2 - conda: https://conda.anaconda.org/nvidia/label/cuda-11.7.0/linux-64/libnvjpeg-dev-11.7.2.34-h2e48410_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.46.0-hde9e2c9_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-14.1.0-hc0a3c3a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-14.1.0-hc0a3c3a_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-14.1.0-h4852527_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.2.13-h4ab18f5_6.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h59595ed_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-he02047a_1.conda - conda: https://conda.anaconda.org/nvidia/label/cuda-11.7.0/linux-64/nsight-compute-2022.2.0.13-0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-1.1.1w-hd590300_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.8.1-h357f687_2.tar.bz2 @@ -77,78 +79,78 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/xz-5.2.6-h166bdaf_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/zlib-1.2.13-h4ab18f5_6.conda - pypi: https://files.pythonhosted.org/packages/b9/fa/123043af240e49752f1c4bd24da5053b6bd00cad78c2be53c0d1e8b975bc/backports.tarfile-1.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4c/6a/ce950d4350c734bc5d9b7196a58fedbdc94f564c00b495a1222984431e03/bcrypt-4.1.3-cp37-abi3-manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/ac/be/da233c5f11fce3f8adec05e8e532b299b64833cc962f49331cdd0e614fa9/bcrypt-4.2.0-cp37-abi3-manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/e2/03/f3c8ba0a6b6e30d7d18c40faab90807c9bb5e9a1e3b2fe2008af624a9c97/build-1.2.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1c/d5/c84e1a17bf61d4df64ca866a1c9a913874b4e9bdc131ec689a0ad013fb36/certifi-2024.7.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f1/c9/326611aa83e16b13b6db4dbb73b5455c668159a003c4c2f0c3bcb2ddabaf/cffi-1.16.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/12/90/3c9ff0512038035f59d279fddeb79f5f1eccd8859f06d6163c58798b9487/certifi-2024.8.30-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/60/9f/0b88c6ebc1b3a32917b396140a3505efdb115b4a64e7c1e80b12ee319c10/cffi-1.17.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/3d/09/d82fe4a34c5f0585f9ea1df090e2a71eb9bb1e469723053e1ee9f57c16f3/charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/96/43/dae06432d0c4b1dc9e9149ad37b4ca8384cf6eb7700cd9215b177b914f0a/cloudpickle-3.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/07/40/d6f6819c62e808ea74639c3c640f7edd636b86cce62cb14943996a15df92/cryptography-42.0.8-cp37-abi3-manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/83/25/439a8ddd8058e7f898b7d27c36f94b66c8c8a2d60e1855d725845f4be0bc/cryptography-43.0.0-cp37-abi3-manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/d5/50/83c593b07763e1161326b3b8c6686f0f4b0f24d5526546bee538c89837d6/decorator-5.1.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/20/8d/778b7d51b981a96554f29136cd59ca7880bf58094338085bcf2a979a0e6a/Deprecated-1.2.14-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/26/87/f238c0670b94533ac0353a4e2a1a771a0cc73277b88bff23d3ae35a256c1/docutils-0.20.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/01/90/79fe92dd413a9cab314ef5c591b5aa9b9ba787ae4cadab75055b0ae00b33/exceptiongroup-1.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d6/1f/e99e23ee01847147fa194e8d41cfcf2535a2dbfcb51414c541cadb15c5d7/fabric-3.2.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ae/f0/48285f0262fe47103a4a45972ed2f9b93e4c80b8fd609fa98da78b2a5706/filelock-3.15.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/5e/44/73bea497ac69bafde2ee4269292fa3b41f1198f4bb7bbaaabde30ad29d4a/fsspec-2024.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e5/3e/741d8c82801c347547f8a2a06aa57dbb1992be9e948df2ea0eda2c8b79e8/idna-3.7-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/dc/ef/38766b2edb096260d9b1b6ad35adaa0bce3b0567abb452b21eb074af88c4/importlib_metadata-8.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/75/06/4df55e1b7b112d183f65db9503bff189e97179b256e1ea450a3c365241e0/importlib_resources-6.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/22/7e/d71db821f177828df9dea8c42ac46473366f191be53080e552e628aad991/idna-3.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c0/14/362d31bf1076b21e1bcdcb0dc61944822ff263937b804a79231df2774d28/importlib_metadata-8.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/2a/728c8ae66011600fac5731a7db030d23c42f1321fd9547654f0c3b2b32d7/importlib_resources-6.4.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0a/66/7f8c48009c72d73bc6bbe6eb87ac838d6a526146f7dab14af671121eb379/invoke-2.2.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/7f/66/b15ce62552d84bbfcec9a4873ab79d993a1dd4edb922cbfccae192bd5b5f/jaraco.classes-3.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d2/40/11b7bc1898cf1dcb87ccbe09b39f5088634ac78bb25f3383ff541c2b40aa/jaraco.context-5.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c3/ac/d0bf0d37a9f95f69a5efc5685d9166ee34a664d3cd29a9c139989512fe14/jaraco.functools-4.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ff/db/0c52c4cf5e4bd9f5d7135ec7669a3a767af21b3a308e1ed3674881e52b62/jaraco.context-6.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b1/54/7623e24ffc63730c3a619101361b08860c6b7c7cfc1aef6edb66d80ed708/jaraco.functools-4.0.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ae/72/2a1e2290f1ab1e06f71f3d0f1646c9e4634e70e1d37491535e19266e8dc9/jeepney-0.8.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/31/80/3a54838c3fb461f6fec263ebf3a3a41771bd05190238de3486aae8540c36/jinja2-3.1.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/92/91/901f5cfeaaea04cf15f5ddf41ee053a5c9e389166477a3427fcfd055e1d9/keyring-25.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/63/42/ea8c9726e5ee5ff0731978aaf7cd5fa16674cf549c46279b279d7167c2b4/keyring-25.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c7/bd/50319665ce81bb10e90d1cf76f9e1aa269ea6f7fa30ab4521f14d122a3df/MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bb/23/2d1cdb0427aecb2b150dc2ac2d15400990c4f05585b3fbc1b5177d74d7fb/more_itertools-10.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d8/0b/6a51175e1395774449fca317fb8861379b7a2d59be411b8cce3d19d6ce78/more_itertools-10.4.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a8/05/9d4f9b78ead6b2661d6e8ea772e111fc4a9fbd866ad0c81906c11206b55e/networkx-3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/da/19/d52d9a0247007835df949f17abd904615248dc1b94d67cb8c99100330f08/nh3-0.2.17-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/1b/63/6ab90d0e5225ab9780f6c9fb52254fa36b52bb7c188df9201d05b647e5e1/nh3-0.2.18-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/98/5d/5738903efe0ecb73e51eb44feafba32bdba2081263d40c5043568ff60faf/numpy-1.24.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/37/6d/121efd7382d5b0284239f4ab1fc1590d86d34ed4a4a2fdb13b30ca8e5740/nvidia_cublas_cu12-12.1.3.1-py3-none-manylinux1_x86_64.whl - pypi: https://files.pythonhosted.org/packages/7e/00/6b218edd739ecfc60524e585ba8e6b00554dd908de2c9c66c1af3e44e18d/nvidia_cuda_cupti_cu12-12.1.105-py3-none-manylinux1_x86_64.whl - pypi: https://files.pythonhosted.org/packages/b6/9f/c64c03f49d6fbc56196664d05dba14e3a561038a81a638eeb47f4d4cfd48/nvidia_cuda_nvrtc_cu12-12.1.105-py3-none-manylinux1_x86_64.whl - pypi: https://files.pythonhosted.org/packages/eb/d5/c68b1d2cdfcc59e72e8a5949a37ddb22ae6cade80cd4a57a84d4c8b55472/nvidia_cuda_runtime_cu12-12.1.105-py3-none-manylinux1_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/ff/74/a2e2be7fb83aaedec84f391f082cf765dfb635e7caa9b49065f73e4835d8/nvidia_cudnn_cu12-8.9.2.26-py3-none-manylinux1_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/9f/fd/713452cd72343f682b1c7b9321e23829f00b842ceaedcda96e742ea0b0b3/nvidia_cudnn_cu12-9.1.0.70-py3-none-manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/86/94/eb540db023ce1d162e7bea9f8f5aa781d57c65aed513c33ee9a5123ead4d/nvidia_cufft_cu12-11.0.2.54-py3-none-manylinux1_x86_64.whl - pypi: https://files.pythonhosted.org/packages/44/31/4890b1c9abc496303412947fc7dcea3d14861720642b49e8ceed89636705/nvidia_curand_cu12-10.3.2.106-py3-none-manylinux1_x86_64.whl - pypi: https://files.pythonhosted.org/packages/bc/1d/8de1e5c67099015c834315e333911273a8c6aaba78923dd1d1e25fc5f217/nvidia_cusolver_cu12-11.4.5.107-py3-none-manylinux1_x86_64.whl - pypi: https://files.pythonhosted.org/packages/65/5b/cfaeebf25cd9fdec14338ccb16f6b2c4c7fa9163aefcf057d86b9cc248bb/nvidia_cusparse_cu12-12.1.0.106-py3-none-manylinux1_x86_64.whl - pypi: https://files.pythonhosted.org/packages/4b/2a/0a131f572aa09f741c30ccd45a8e56316e8be8dfc7bc19bf0ab7cfef7b19/nvidia_nccl_cu12-2.20.5-py3-none-manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/75/bc/e0d0dbb85246a086ab14839979039647bce501d8c661a159b8b019d987b7/nvidia_nvjitlink_cu12-12.5.82-py3-none-manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/a8/48/a9775d377cb95585fb188b469387f58ba6738e268de22eae2ad4cedb2c41/nvidia_nvjitlink_cu12-12.6.68-py3-none-manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/da/d3/8057f0587683ed2fcd4dbfbdfdfa807b9160b809976099d36b8f60d08f03/nvidia_nvtx_cu12-12.1.105-py3-none-manylinux1_x86_64.whl - pypi: https://files.pythonhosted.org/packages/08/aa/cc0199a5f0ad350994d660967a8efb233fe0416e4639146c089643407ce6/packaging-24.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ad/50/8792484502c8141c20c996b802fefa8435a9c018a2bb440a06b172782118/paramiko-3.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/96/6e/4a52a8923d840107024b844d83502dfa6a1e5399ad31cf9d1a4ddbaaa7e5/paramiko-3.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/56/09/054aea9b7534a15ad38a363a2bd974c20646ab1582a387a95b8df1bfea1c/pkginfo-1.10.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f7/3f/01c8b82017c199075f8f788d0d906b9ffbbc5a47dc9918a945e13d5a2bda/pygments-2.18.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ee/87/f1bb6a595f14a327e8285b9eb54d41fef76c585a0edef0a45f6fc95de125/PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl - pypi: https://files.pythonhosted.org/packages/ae/f3/431b9d5fe7d14af7a32340792ef43b8a714e7726f1d7b69cc4e8e7a3f1d7/pyproject_hooks-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0c/2b/3d70ea49041da4dfb64b71039d94f3b31843575edf1f29fe0370919c35aa/pyright-1.1.370-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4e/e7/81ebdd666d3bff6670d27349b5053605d83d55548e6bd5711f3b0ae7dd23/pytest-8.2.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/c6/f0d4bc20c13b20cecfbf13c699477c825e45767f1dc5068137323f86e495/pyright-1.1.378-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0f/f9/cf155cf32ca7d6fa3601bc4c5dd19086af4b320b706919d48a4c79081cf9/pytest-8.3.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/45/be/3ea20dc38b9db08387cf97997a85a7d51527ea2057d71118feb0aa8afa55/readme_renderer-43.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ff/9a/9afaade874b2fa6c752c36f1548f718b5b83af81ed9b76628329dab81c1b/rfc3986-2.0.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/87/67/a37f6214d0e9fe57f6ae54b2956d550ca8365857f42a1ce0392bb21d9410/rich-13.7.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8a/d5/8271d42dd239b7c2d163615b3b01b1acfb187f5114bfca6d5a85e1d6a1eb/ruff-0.5.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/c7/d9/c2a126eeae791e90ea099d05cb0515feea3688474b978343f3cdcfe04523/rich-13.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/5d/b33284c108e3f315ddd09b70296fd76bd28ecf8965a520bc93f3bbd8ac40/ruff-0.6.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/54/24/b4293291fa1dd830f353d2cb163295742fa87f179fcc8a20a306a81978b7/SecretStorage-3.3.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/61/53/e18c8c97d0b2724d85c9830477e3ebea3acf1dcdc6deb344d5d9c93a9946/sympy-1.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c1/f9/6845bf8fca0eaf847da21c5d5bc6cd92797364662824a11d3f836423a1a5/sympy-1.13.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c0/7e/309d63c6330a0b821a6f55e06dcef6704a7ab8b707534a4923837570624e/torch-2.3.1-cp38-cp38-manylinux1_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/d3/55/45b3882019a8d69ad73b5b2bd1714cb2d6653b39e7376b7ac5accf745760/triton-2.3.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/fc/58/f93bdce23c9ff568c3dfb5129db0c14e60f7c72ab4d1a6de8fedca6e3792/torch-2.4.0-cp38-cp38-manylinux1_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/4d/b4/c37e2776a1390bab7e78a6d52bd525441cb3cad7260a6a00b11b0b702e7c/triton-3.0.0-1-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - pypi: https://files.pythonhosted.org/packages/5d/ec/00f9d5fd040ae29867355e559a94e9a8429225a0284a3f5f091a3878bfc0/twine-5.1.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ca/1c/89ffc63a9605b583d5df2be791a27bc1a42b7c32bab68d3c8f2f73a98cd4/urllib3-2.2.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ef/c6/56e718e2c58a4078518c14d97e531ef1e9e8a5c1ddafdc0d264a92be1a1a/wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/20/38/f5c473fe9b90c8debdd29ea68d5add0289f1936d6f923b6b9cc0b931194c/zipp-3.19.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/9e/c96f7a4cd0bf5625bb409b7e61e99b1130dc63a98cb8b24aeabae62d43e8/zipp-3.20.1-py3-none-any.whl - pypi: . dev: channels: @@ -160,15 +162,17 @@ environments: linux-64: - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.7.4-hbcca054_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.8.30-hbcca054_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-hf3520f5_7.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.2.1-he1b5a44_1007.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-14.1.0-h77fa898_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-14.1.0-h77fa898_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-14.1.0-h77fa898_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-14.1.0-h69a702a_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-14.1.0-h77fa898_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.46.0-hde9e2c9_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-14.1.0-hc0a3c3a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-14.1.0-hc0a3c3a_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-14.1.0-h4852527_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.2.13-h4ab18f5_6.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h59595ed_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-he02047a_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-1.1.1w-hd590300_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.8.1-h357f687_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8228510_1.conda @@ -178,25 +182,25 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/zlib-1.2.13-h4ab18f5_6.conda - pypi: https://files.pythonhosted.org/packages/b9/fa/123043af240e49752f1c4bd24da5053b6bd00cad78c2be53c0d1e8b975bc/backports.tarfile-1.2.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/e2/03/f3c8ba0a6b6e30d7d18c40faab90807c9bb5e9a1e3b2fe2008af624a9c97/build-1.2.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1c/d5/c84e1a17bf61d4df64ca866a1c9a913874b4e9bdc131ec689a0ad013fb36/certifi-2024.7.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f1/c9/326611aa83e16b13b6db4dbb73b5455c668159a003c4c2f0c3bcb2ddabaf/cffi-1.16.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/12/90/3c9ff0512038035f59d279fddeb79f5f1eccd8859f06d6163c58798b9487/certifi-2024.8.30-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/60/9f/0b88c6ebc1b3a32917b396140a3505efdb115b4a64e7c1e80b12ee319c10/cffi-1.17.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/3d/09/d82fe4a34c5f0585f9ea1df090e2a71eb9bb1e469723053e1ee9f57c16f3/charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/07/40/d6f6819c62e808ea74639c3c640f7edd636b86cce62cb14943996a15df92/cryptography-42.0.8-cp37-abi3-manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/83/25/439a8ddd8058e7f898b7d27c36f94b66c8c8a2d60e1855d725845f4be0bc/cryptography-43.0.0-cp37-abi3-manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/26/87/f238c0670b94533ac0353a4e2a1a771a0cc73277b88bff23d3ae35a256c1/docutils-0.20.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/01/90/79fe92dd413a9cab314ef5c591b5aa9b9ba787ae4cadab75055b0ae00b33/exceptiongroup-1.2.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e5/3e/741d8c82801c347547f8a2a06aa57dbb1992be9e948df2ea0eda2c8b79e8/idna-3.7-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/dc/ef/38766b2edb096260d9b1b6ad35adaa0bce3b0567abb452b21eb074af88c4/importlib_metadata-8.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/75/06/4df55e1b7b112d183f65db9503bff189e97179b256e1ea450a3c365241e0/importlib_resources-6.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/22/7e/d71db821f177828df9dea8c42ac46473366f191be53080e552e628aad991/idna-3.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c0/14/362d31bf1076b21e1bcdcb0dc61944822ff263937b804a79231df2774d28/importlib_metadata-8.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/2a/728c8ae66011600fac5731a7db030d23c42f1321fd9547654f0c3b2b32d7/importlib_resources-6.4.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/7f/66/b15ce62552d84bbfcec9a4873ab79d993a1dd4edb922cbfccae192bd5b5f/jaraco.classes-3.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d2/40/11b7bc1898cf1dcb87ccbe09b39f5088634ac78bb25f3383ff541c2b40aa/jaraco.context-5.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c3/ac/d0bf0d37a9f95f69a5efc5685d9166ee34a664d3cd29a9c139989512fe14/jaraco.functools-4.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ff/db/0c52c4cf5e4bd9f5d7135ec7669a3a767af21b3a308e1ed3674881e52b62/jaraco.context-6.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b1/54/7623e24ffc63730c3a619101361b08860c6b7c7cfc1aef6edb66d80ed708/jaraco.functools-4.0.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ae/72/2a1e2290f1ab1e06f71f3d0f1646c9e4634e70e1d37491535e19266e8dc9/jeepney-0.8.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/92/91/901f5cfeaaea04cf15f5ddf41ee053a5c9e389166477a3427fcfd055e1d9/keyring-25.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/63/42/ea8c9726e5ee5ff0731978aaf7cd5fa16674cf549c46279b279d7167c2b4/keyring-25.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bb/23/2d1cdb0427aecb2b150dc2ac2d15400990c4f05585b3fbc1b5177d74d7fb/more_itertools-10.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/da/19/d52d9a0247007835df949f17abd904615248dc1b94d67cb8c99100330f08/nh3-0.2.17-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/d8/0b/6a51175e1395774449fca317fb8861379b7a2d59be411b8cce3d19d6ce78/more_itertools-10.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/1b/63/6ab90d0e5225ab9780f6c9fb52254fa36b52bb7c188df9201d05b647e5e1/nh3-0.2.18-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/08/aa/cc0199a5f0ad350994d660967a8efb233fe0416e4639146c089643407ce6/packaging-24.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/56/09/054aea9b7534a15ad38a363a2bd974c20646ab1582a387a95b8df1bfea1c/pkginfo-1.10.0-py3-none-any.whl @@ -204,20 +208,20 @@ environments: - pypi: https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f7/3f/01c8b82017c199075f8f788d0d906b9ffbbc5a47dc9918a945e13d5a2bda/pygments-2.18.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ae/f3/431b9d5fe7d14af7a32340792ef43b8a714e7726f1d7b69cc4e8e7a3f1d7/pyproject_hooks-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0c/2b/3d70ea49041da4dfb64b71039d94f3b31843575edf1f29fe0370919c35aa/pyright-1.1.370-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4e/e7/81ebdd666d3bff6670d27349b5053605d83d55548e6bd5711f3b0ae7dd23/pytest-8.2.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/c6/f0d4bc20c13b20cecfbf13c699477c825e45767f1dc5068137323f86e495/pyright-1.1.378-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0f/f9/cf155cf32ca7d6fa3601bc4c5dd19086af4b320b706919d48a4c79081cf9/pytest-8.3.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/45/be/3ea20dc38b9db08387cf97997a85a7d51527ea2057d71118feb0aa8afa55/readme_renderer-43.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ff/9a/9afaade874b2fa6c752c36f1548f718b5b83af81ed9b76628329dab81c1b/rfc3986-2.0.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/87/67/a37f6214d0e9fe57f6ae54b2956d550ca8365857f42a1ce0392bb21d9410/rich-13.7.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8a/d5/8271d42dd239b7c2d163615b3b01b1acfb187f5114bfca6d5a85e1d6a1eb/ruff-0.5.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/c7/d9/c2a126eeae791e90ea099d05cb0515feea3688474b978343f3cdcfe04523/rich-13.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/5d/b33284c108e3f315ddd09b70296fd76bd28ecf8965a520bc93f3bbd8ac40/ruff-0.6.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/54/24/b4293291fa1dd830f353d2cb163295742fa87f179fcc8a20a306a81978b7/SecretStorage-3.3.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/5d/ec/00f9d5fd040ae29867355e559a94e9a8429225a0284a3f5f091a3878bfc0/twine-5.1.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ca/1c/89ffc63a9605b583d5df2be791a27bc1a42b7c32bab68d3c8f2f73a98cd4/urllib3-2.2.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/20/38/f5c473fe9b90c8debdd29ea68d5add0289f1936d6f923b6b9cc0b931194c/zipp-3.19.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/9e/c96f7a4cd0bf5625bb409b7e61e99b1130dc63a98cb8b24aeabae62d43e8/zipp-3.20.1-py3-none-any.whl extra: channels: - url: https://conda.anaconda.org/nvidia/label/cuda-11.7.0/ @@ -228,7 +232,7 @@ environments: linux-64: - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.7.4-hbcca054_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.8.30-hbcca054_0.conda - conda: https://conda.anaconda.org/nvidia/label/cuda-11.7.0/linux-64/cuda-11.7.0-0.tar.bz2 - conda: https://conda.anaconda.org/nvidia/label/cuda-11.7.0/linux-64/cuda-cccl-11.7.58-hc415cf5_0.tar.bz2 - conda: https://conda.anaconda.org/nvidia/label/cuda-11.7.0/linux-64/cuda-command-line-tools-11.7.0-0.tar.bz2 @@ -276,16 +280,18 @@ environments: - conda: https://conda.anaconda.org/nvidia/label/cuda-11.7.0/linux-64/libcusparse-11.7.3.50-h6aaafad_0.tar.bz2 - conda: https://conda.anaconda.org/nvidia/label/cuda-11.7.0/linux-64/libcusparse-dev-11.7.3.50-hc644b96_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.2.1-he1b5a44_1007.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-14.1.0-h77fa898_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-14.1.0-h77fa898_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-14.1.0-h77fa898_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-14.1.0-h69a702a_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-14.1.0-h77fa898_1.conda - conda: https://conda.anaconda.org/nvidia/label/cuda-11.7.0/linux-64/libnpp-11.7.3.21-h3effbd9_0.tar.bz2 - conda: https://conda.anaconda.org/nvidia/label/cuda-11.7.0/linux-64/libnpp-dev-11.7.3.21-hb6476a9_0.tar.bz2 - conda: https://conda.anaconda.org/nvidia/label/cuda-11.7.0/linux-64/libnvjpeg-11.7.2.34-hfe236c7_0.tar.bz2 - conda: https://conda.anaconda.org/nvidia/label/cuda-11.7.0/linux-64/libnvjpeg-dev-11.7.2.34-h2e48410_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.46.0-hde9e2c9_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-14.1.0-hc0a3c3a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-14.1.0-hc0a3c3a_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-14.1.0-h4852527_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.2.13-h4ab18f5_6.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h59595ed_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-he02047a_1.conda - conda: https://conda.anaconda.org/nvidia/label/cuda-11.7.0/linux-64/nsight-compute-2022.2.0.13-0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-1.1.1w-hd590300_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.8.1-h357f687_2.tar.bz2 @@ -294,57 +300,57 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/xz-5.2.6-h166bdaf_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/zlib-1.2.13-h4ab18f5_6.conda - - pypi: https://files.pythonhosted.org/packages/15/33/b6b4ad5efa8b9f4275d4ed17ff8a44c97276171341ba565fdffb0e3dc5e8/accelerate-0.33.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/02/0e/626f2dd4325f4545fbaaf9c590390d2d4ab8e7551579346fe1e319bd93af/accelerate-0.34.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b9/fa/123043af240e49752f1c4bd24da5053b6bd00cad78c2be53c0d1e8b975bc/backports.tarfile-1.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4c/6a/ce950d4350c734bc5d9b7196a58fedbdc94f564c00b495a1222984431e03/bcrypt-4.1.3-cp37-abi3-manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/ac/be/da233c5f11fce3f8adec05e8e532b299b64833cc962f49331cdd0e614fa9/bcrypt-4.2.0-cp37-abi3-manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/e2/03/f3c8ba0a6b6e30d7d18c40faab90807c9bb5e9a1e3b2fe2008af624a9c97/build-1.2.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/1c/d5/c84e1a17bf61d4df64ca866a1c9a913874b4e9bdc131ec689a0ad013fb36/certifi-2024.7.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/f1/c9/326611aa83e16b13b6db4dbb73b5455c668159a003c4c2f0c3bcb2ddabaf/cffi-1.16.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/12/90/3c9ff0512038035f59d279fddeb79f5f1eccd8859f06d6163c58798b9487/certifi-2024.8.30-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/60/9f/0b88c6ebc1b3a32917b396140a3505efdb115b4a64e7c1e80b12ee319c10/cffi-1.17.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/3d/09/d82fe4a34c5f0585f9ea1df090e2a71eb9bb1e469723053e1ee9f57c16f3/charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/96/43/dae06432d0c4b1dc9e9149ad37b4ca8384cf6eb7700cd9215b177b914f0a/cloudpickle-3.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/07/40/d6f6819c62e808ea74639c3c640f7edd636b86cce62cb14943996a15df92/cryptography-42.0.8-cp37-abi3-manylinux_2_28_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/83/25/439a8ddd8058e7f898b7d27c36f94b66c8c8a2d60e1855d725845f4be0bc/cryptography-43.0.0-cp37-abi3-manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/d5/50/83c593b07763e1161326b3b8c6686f0f4b0f24d5526546bee538c89837d6/decorator-5.1.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/20/8d/778b7d51b981a96554f29136cd59ca7880bf58094338085bcf2a979a0e6a/Deprecated-1.2.14-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/26/87/f238c0670b94533ac0353a4e2a1a771a0cc73277b88bff23d3ae35a256c1/docutils-0.20.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/01/90/79fe92dd413a9cab314ef5c591b5aa9b9ba787ae4cadab75055b0ae00b33/exceptiongroup-1.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d6/1f/e99e23ee01847147fa194e8d41cfcf2535a2dbfcb51414c541cadb15c5d7/fabric-3.2.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ae/f0/48285f0262fe47103a4a45972ed2f9b93e4c80b8fd609fa98da78b2a5706/filelock-3.15.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/5e/44/73bea497ac69bafde2ee4269292fa3b41f1198f4bb7bbaaabde30ad29d4a/fsspec-2024.6.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0b/05/31b21998f68c31e7ffcc27ff08531fb9af5506d765ce8d661fb0036e6918/huggingface_hub-0.24.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e5/3e/741d8c82801c347547f8a2a06aa57dbb1992be9e948df2ea0eda2c8b79e8/idna-3.7-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/dc/ef/38766b2edb096260d9b1b6ad35adaa0bce3b0567abb452b21eb074af88c4/importlib_metadata-8.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/75/06/4df55e1b7b112d183f65db9503bff189e97179b256e1ea450a3c365241e0/importlib_resources-6.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b9/8f/d6718641c14d98a5848c6a24d2376028d292074ffade0702940a4b1dde76/huggingface_hub-0.24.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/22/7e/d71db821f177828df9dea8c42ac46473366f191be53080e552e628aad991/idna-3.8-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c0/14/362d31bf1076b21e1bcdcb0dc61944822ff263937b804a79231df2774d28/importlib_metadata-8.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/db/2a/728c8ae66011600fac5731a7db030d23c42f1321fd9547654f0c3b2b32d7/importlib_resources-6.4.4-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/0a/66/7f8c48009c72d73bc6bbe6eb87ac838d6a526146f7dab14af671121eb379/invoke-2.2.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/7f/66/b15ce62552d84bbfcec9a4873ab79d993a1dd4edb922cbfccae192bd5b5f/jaraco.classes-3.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d2/40/11b7bc1898cf1dcb87ccbe09b39f5088634ac78bb25f3383ff541c2b40aa/jaraco.context-5.3.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c3/ac/d0bf0d37a9f95f69a5efc5685d9166ee34a664d3cd29a9c139989512fe14/jaraco.functools-4.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/ff/db/0c52c4cf5e4bd9f5d7135ec7669a3a767af21b3a308e1ed3674881e52b62/jaraco.context-6.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b1/54/7623e24ffc63730c3a619101361b08860c6b7c7cfc1aef6edb66d80ed708/jaraco.functools-4.0.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ae/72/2a1e2290f1ab1e06f71f3d0f1646c9e4634e70e1d37491535e19266e8dc9/jeepney-0.8.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/31/80/3a54838c3fb461f6fec263ebf3a3a41771bd05190238de3486aae8540c36/jinja2-3.1.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/92/91/901f5cfeaaea04cf15f5ddf41ee053a5c9e389166477a3427fcfd055e1d9/keyring-25.2.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/63/42/ea8c9726e5ee5ff0731978aaf7cd5fa16674cf549c46279b279d7167c2b4/keyring-25.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c7/bd/50319665ce81bb10e90d1cf76f9e1aa269ea6f7fa30ab4521f14d122a3df/MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bb/23/2d1cdb0427aecb2b150dc2ac2d15400990c4f05585b3fbc1b5177d74d7fb/more_itertools-10.3.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/d8/0b/6a51175e1395774449fca317fb8861379b7a2d59be411b8cce3d19d6ce78/more_itertools-10.4.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/a8/05/9d4f9b78ead6b2661d6e8ea772e111fc4a9fbd866ad0c81906c11206b55e/networkx-3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/da/19/d52d9a0247007835df949f17abd904615248dc1b94d67cb8c99100330f08/nh3-0.2.17-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/1b/63/6ab90d0e5225ab9780f6c9fb52254fa36b52bb7c188df9201d05b647e5e1/nh3-0.2.18-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/98/5d/5738903efe0ecb73e51eb44feafba32bdba2081263d40c5043568ff60faf/numpy-1.24.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/37/6d/121efd7382d5b0284239f4ab1fc1590d86d34ed4a4a2fdb13b30ca8e5740/nvidia_cublas_cu12-12.1.3.1-py3-none-manylinux1_x86_64.whl - pypi: https://files.pythonhosted.org/packages/7e/00/6b218edd739ecfc60524e585ba8e6b00554dd908de2c9c66c1af3e44e18d/nvidia_cuda_cupti_cu12-12.1.105-py3-none-manylinux1_x86_64.whl - pypi: https://files.pythonhosted.org/packages/b6/9f/c64c03f49d6fbc56196664d05dba14e3a561038a81a638eeb47f4d4cfd48/nvidia_cuda_nvrtc_cu12-12.1.105-py3-none-manylinux1_x86_64.whl - pypi: https://files.pythonhosted.org/packages/eb/d5/c68b1d2cdfcc59e72e8a5949a37ddb22ae6cade80cd4a57a84d4c8b55472/nvidia_cuda_runtime_cu12-12.1.105-py3-none-manylinux1_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/ff/74/a2e2be7fb83aaedec84f391f082cf765dfb635e7caa9b49065f73e4835d8/nvidia_cudnn_cu12-8.9.2.26-py3-none-manylinux1_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/9f/fd/713452cd72343f682b1c7b9321e23829f00b842ceaedcda96e742ea0b0b3/nvidia_cudnn_cu12-9.1.0.70-py3-none-manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/86/94/eb540db023ce1d162e7bea9f8f5aa781d57c65aed513c33ee9a5123ead4d/nvidia_cufft_cu12-11.0.2.54-py3-none-manylinux1_x86_64.whl - pypi: https://files.pythonhosted.org/packages/44/31/4890b1c9abc496303412947fc7dcea3d14861720642b49e8ceed89636705/nvidia_curand_cu12-10.3.2.106-py3-none-manylinux1_x86_64.whl - pypi: https://files.pythonhosted.org/packages/bc/1d/8de1e5c67099015c834315e333911273a8c6aaba78923dd1d1e25fc5f217/nvidia_cusolver_cu12-11.4.5.107-py3-none-manylinux1_x86_64.whl - pypi: https://files.pythonhosted.org/packages/65/5b/cfaeebf25cd9fdec14338ccb16f6b2c4c7fa9163aefcf057d86b9cc248bb/nvidia_cusparse_cu12-12.1.0.106-py3-none-manylinux1_x86_64.whl - pypi: https://files.pythonhosted.org/packages/4b/2a/0a131f572aa09f741c30ccd45a8e56316e8be8dfc7bc19bf0ab7cfef7b19/nvidia_nccl_cu12-2.20.5-py3-none-manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/75/bc/e0d0dbb85246a086ab14839979039647bce501d8c661a159b8b019d987b7/nvidia_nvjitlink_cu12-12.5.82-py3-none-manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/a8/48/a9775d377cb95585fb188b469387f58ba6738e268de22eae2ad4cedb2c41/nvidia_nvjitlink_cu12-12.6.68-py3-none-manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/da/d3/8057f0587683ed2fcd4dbfbdfdfa807b9160b809976099d36b8f60d08f03/nvidia_nvtx_cu12-12.1.105-py3-none-manylinux1_x86_64.whl - pypi: https://files.pythonhosted.org/packages/08/aa/cc0199a5f0ad350994d660967a8efb233fe0416e4639146c089643407ce6/packaging-24.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ad/50/8792484502c8141c20c996b802fefa8435a9c018a2bb440a06b172782118/paramiko-3.4.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/96/6e/4a52a8923d840107024b844d83502dfa6a1e5399ad31cf9d1a4ddbaaa7e5/paramiko-3.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/56/09/054aea9b7534a15ad38a363a2bd974c20646ab1582a387a95b8df1bfea1c/pkginfo-1.10.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/19/74/f59e7e0d392bc1070e9a70e2f9190d652487ac115bb16e2eff6b22ad1d24/psutil-6.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl @@ -352,32 +358,32 @@ environments: - pypi: https://files.pythonhosted.org/packages/f7/3f/01c8b82017c199075f8f788d0d906b9ffbbc5a47dc9918a945e13d5a2bda/pygments-2.18.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ee/87/f1bb6a595f14a327e8285b9eb54d41fef76c585a0edef0a45f6fc95de125/PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl - pypi: https://files.pythonhosted.org/packages/ae/f3/431b9d5fe7d14af7a32340792ef43b8a714e7726f1d7b69cc4e8e7a3f1d7/pyproject_hooks-1.1.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0c/2b/3d70ea49041da4dfb64b71039d94f3b31843575edf1f29fe0370919c35aa/pyright-1.1.370-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/4e/e7/81ebdd666d3bff6670d27349b5053605d83d55548e6bd5711f3b0ae7dd23/pytest-8.2.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/c6/f0d4bc20c13b20cecfbf13c699477c825e45767f1dc5068137323f86e495/pyright-1.1.378-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0f/f9/cf155cf32ca7d6fa3601bc4c5dd19086af4b320b706919d48a4c79081cf9/pytest-8.3.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/fd/7f/2c3697bba5d4aa5cc2afe81826d73dfae5f049458e44732c7a0938baa673/PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/45/be/3ea20dc38b9db08387cf97997a85a7d51527ea2057d71118feb0aa8afa55/readme_renderer-43.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/c2/c6/023e5b634e5b72034f9e0c36396648e1481f3482c739d1b456b3e5061243/regex-2024.7.24-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ff/9a/9afaade874b2fa6c752c36f1548f718b5b83af81ed9b76628329dab81c1b/rfc3986-2.0.0-py2.py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/87/67/a37f6214d0e9fe57f6ae54b2956d550ca8365857f42a1ce0392bb21d9410/rich-13.7.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8a/d5/8271d42dd239b7c2d163615b3b01b1acfb187f5114bfca6d5a85e1d6a1eb/ruff-0.5.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/c7/d9/c2a126eeae791e90ea099d05cb0515feea3688474b978343f3cdcfe04523/rich-13.8.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/38/5d/b33284c108e3f315ddd09b70296fd76bd28ecf8965a520bc93f3bbd8ac40/ruff-0.6.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/da/cf/036697a93a8b1e771101f3cf49e3edac946294d9d44383601ff6c4ad2f88/safetensors-0.4.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/54/24/b4293291fa1dd830f353d2cb163295742fa87f179fcc8a20a306a81978b7/SecretStorage-3.3.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/6e/ec/06715d912351edc453e37f93f3fc80dcffd5ca0e70386c87529aca296f05/setuptools-72.2.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/48/f3/e30ee63caefa90716afdffd7d9ae959cd8d0dbd2d0a0eb9fe1d73ddf806b/setuptools-74.1.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/eb/db/64ade58ecdd41b2fae6174ab9d3dd62112c0cc0b3f71d5672cd29877f197/submitit-1.5.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/61/53/e18c8c97d0b2724d85c9830477e3ebea3acf1dcdc6deb344d5d9c93a9946/sympy-1.12.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c1/f9/6845bf8fca0eaf847da21c5d5bc6cd92797364662824a11d3f836423a1a5/sympy-1.13.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/18/0d/ee99f50407788149bc9eddae6af0b4016865d67fb687730d151683b13b80/tokenizers-0.19.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/c0/7e/309d63c6330a0b821a6f55e06dcef6704a7ab8b707534a4923837570624e/torch-2.3.1-cp38-cp38-manylinux1_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/fc/58/f93bdce23c9ff568c3dfb5129db0c14e60f7c72ab4d1a6de8fedca6e3792/torch-2.4.0-cp38-cp38-manylinux1_x86_64.whl - pypi: https://files.pythonhosted.org/packages/48/5d/acf5905c36149bbaec41ccf7f2b68814647347b72075ac0b1fe3022fdc73/tqdm-4.66.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/62/c0/810e741a6244c0f004be40ccb96486d072f042eabbd4d7e8aa02b81ca1eb/transformers-4.44.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d3/55/45b3882019a8d69ad73b5b2bd1714cb2d6653b39e7376b7ac5accf745760/triton-2.3.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/75/35/07c9879163b603f0e464b0f6e6e628a2340cfc7cdc5ca8e7d52d776710d4/transformers-4.44.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/4d/b4/c37e2776a1390bab7e78a6d52bd525441cb3cad7260a6a00b11b0b702e7c/triton-3.0.0-1-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.whl - pypi: https://files.pythonhosted.org/packages/5d/ec/00f9d5fd040ae29867355e559a94e9a8429225a0284a3f5f091a3878bfc0/twine-5.1.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ca/1c/89ffc63a9605b583d5df2be791a27bc1a42b7c32bab68d3c8f2f73a98cd4/urllib3-2.2.2-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ef/c6/56e718e2c58a4078518c14d97e531ef1e9e8a5c1ddafdc0d264a92be1a1a/wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl - - pypi: https://files.pythonhosted.org/packages/20/38/f5c473fe9b90c8debdd29ea68d5add0289f1936d6f923b6b9cc0b931194c/zipp-3.19.2-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/07/9e/c96f7a4cd0bf5625bb409b7e61e99b1130dc63a98cb8b24aeabae62d43e8/zipp-3.20.1-py3-none-any.whl - pypi: . packages: - kind: conda @@ -413,18 +419,18 @@ packages: timestamp: 1650670423406 - kind: pypi name: accelerate - version: 0.33.0 - url: https://files.pythonhosted.org/packages/15/33/b6b4ad5efa8b9f4275d4ed17ff8a44c97276171341ba565fdffb0e3dc5e8/accelerate-0.33.0-py3-none-any.whl - sha256: 0a7f33d60ba09afabd028d4f0856dd19c5a734b7a596d637d9dd6e3d0eadbaf3 + version: 0.34.0 + url: https://files.pythonhosted.org/packages/02/0e/626f2dd4325f4545fbaaf9c590390d2d4ab8e7551579346fe1e319bd93af/accelerate-0.34.0-py3-none-any.whl + sha256: 0161fd3f975dd99b5cdb967bb6942bc986d9da466397742008a73290dcb73408 requires_dist: - - numpy<2.0.0,>=1.17 + - numpy<3.0.0,>=1.17 - packaging>=20.0 - psutil - pyyaml - torch>=1.10.0 - huggingface-hub>=0.21.0 - - safetensors>=0.3.1 - - deepspeed<=0.14.0 ; extra == 'deepspeed' + - safetensors>=0.4.3 + - deepspeed ; extra == 'deepspeed' - black~=23.1 ; extra == 'dev' - hf-doc-builder>=0.3.0 ; extra == 'dev' - ruff~=0.2.1 ; extra == 'dev' @@ -435,6 +441,7 @@ packages: - datasets ; extra == 'dev' - diffusers ; extra == 'dev' - evaluate ; extra == 'dev' + - torchdata>=0.8.0 ; extra == 'dev' - torchpippy>=0.2.0 ; extra == 'dev' - transformers ; extra == 'dev' - scipy ; extra == 'dev' @@ -451,6 +458,7 @@ packages: - datasets ; extra == 'test-dev' - diffusers ; extra == 'test-dev' - evaluate ; extra == 'test-dev' + - torchdata>=0.8.0 ; extra == 'test-dev' - torchpippy>=0.2.0 ; extra == 'test-dev' - transformers ; extra == 'test-dev' - scipy ; extra == 'test-dev' @@ -473,6 +481,7 @@ packages: - datasets ; extra == 'testing' - diffusers ; extra == 'testing' - evaluate ; extra == 'testing' + - torchdata>=0.8.0 ; extra == 'testing' - torchpippy>=0.2.0 ; extra == 'testing' - transformers ; extra == 'testing' - scipy ; extra == 'testing' @@ -501,9 +510,9 @@ packages: requires_python: '>=3.8' - kind: pypi name: bcrypt - version: 4.1.3 - url: https://files.pythonhosted.org/packages/4c/6a/ce950d4350c734bc5d9b7196a58fedbdc94f564c00b495a1222984431e03/bcrypt-4.1.3-cp37-abi3-manylinux_2_28_x86_64.whl - sha256: 4fb253d65da30d9269e0a6f4b0de32bd657a0208a6f4e43d3e645774fb5457f3 + version: 4.2.0 + url: https://files.pythonhosted.org/packages/ac/be/da233c5f11fce3f8adec05e8e532b299b64833cc962f49331cdd0e614fa9/bcrypt-4.2.0-cp37-abi3-manylinux_2_28_x86_64.whl + sha256: 655ea221910bcac76ea08aaa76df427ef8625f92e55a8ee44fbf7753dbabb328 requires_dist: - pytest!=3.3.0,>=3.2.1 ; extra == 'tests' - mypy ; extra == 'typecheck' @@ -546,27 +555,27 @@ packages: requires_python: '>=3.8' - kind: conda name: ca-certificates - version: 2024.7.4 + version: 2024.8.30 build: hbcca054_0 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.7.4-hbcca054_0.conda - sha256: c1548a3235376f464f9931850b64b02492f379b2f2bb98bc786055329b080446 - md5: 23ab7665c5f63cfb9f1f6195256daac6 + url: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.8.30-hbcca054_0.conda + sha256: afee721baa6d988e27fef1832f68d6f32ac8cc99cdf6015732224c2841a09cea + md5: c27d1c142233b5bc9ca570c6e2e0c244 license: ISC purls: [] - size: 154853 - timestamp: 1720077432978 + size: 159003 + timestamp: 1725018903918 - kind: pypi name: certifi - version: 2024.7.4 - url: https://files.pythonhosted.org/packages/1c/d5/c84e1a17bf61d4df64ca866a1c9a913874b4e9bdc131ec689a0ad013fb36/certifi-2024.7.4-py3-none-any.whl - sha256: c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90 + version: 2024.8.30 + url: https://files.pythonhosted.org/packages/12/90/3c9ff0512038035f59d279fddeb79f5f1eccd8859f06d6163c58798b9487/certifi-2024.8.30-py3-none-any.whl + sha256: 922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8 requires_python: '>=3.6' - kind: pypi name: cffi - version: 1.16.0 - url: https://files.pythonhosted.org/packages/f1/c9/326611aa83e16b13b6db4dbb73b5455c668159a003c4c2f0c3bcb2ddabaf/cffi-1.16.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - sha256: 6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324 + version: 1.17.0 + url: https://files.pythonhosted.org/packages/60/9f/0b88c6ebc1b3a32917b396140a3505efdb115b4a64e7c1e80b12ee319c10/cffi-1.17.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + sha256: 3aa9d43b02a0c681f0bfbc12d476d47b2b2b6a3f9287f11ee42989a268a1833c requires_dist: - pycparser requires_python: '>=3.8' @@ -584,30 +593,31 @@ packages: requires_python: '>=3.8' - kind: pypi name: cryptography - version: 42.0.8 - url: https://files.pythonhosted.org/packages/07/40/d6f6819c62e808ea74639c3c640f7edd636b86cce62cb14943996a15df92/cryptography-42.0.8-cp37-abi3-manylinux_2_28_x86_64.whl - sha256: 6b7c4f03ce01afd3b76cf69a5455caa9cfa3de8c8f493e0d3ab7d20611c8dae9 + version: 43.0.0 + url: https://files.pythonhosted.org/packages/83/25/439a8ddd8058e7f898b7d27c36f94b66c8c8a2d60e1855d725845f4be0bc/cryptography-43.0.0-cp37-abi3-manylinux_2_28_x86_64.whl + sha256: 9a8d6802e0825767476f62aafed40532bd435e8a5f7d23bd8b4f5fd04cc80ecf requires_dist: - cffi>=1.12 ; platform_python_implementation != 'PyPy' + - bcrypt>=3.1.5 ; extra == 'ssh' + - nox ; extra == 'nox' + - cryptography-vectors==43.0.0 ; extra == 'test' + - pytest>=6.2.0 ; extra == 'test' + - pytest-benchmark ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-xdist ; extra == 'test' + - pretend ; extra == 'test' + - certifi ; extra == 'test' + - pytest-randomly ; extra == 'test-randomorder' - sphinx>=5.3.0 ; extra == 'docs' - sphinx-rtd-theme>=1.1.1 ; extra == 'docs' - pyenchant>=1.6.11 ; extra == 'docstest' - readme-renderer ; extra == 'docstest' - sphinxcontrib-spelling>=4.0.1 ; extra == 'docstest' - - nox ; extra == 'nox' + - build ; extra == 'sdist' - ruff ; extra == 'pep8test' - mypy ; extra == 'pep8test' - check-sdist ; extra == 'pep8test' - click ; extra == 'pep8test' - - build ; extra == 'sdist' - - bcrypt>=3.1.5 ; extra == 'ssh' - - pytest>=6.2.0 ; extra == 'test' - - pytest-benchmark ; extra == 'test' - - pytest-cov ; extra == 'test' - - pytest-xdist ; extra == 'test' - - pretend ; extra == 'test' - - certifi ; extra == 'test' - - pytest-randomly ; extra == 'test-randomorder' requires_python: '>=3.7' - kind: conda name: cuda @@ -1090,9 +1100,9 @@ packages: requires_python: '>=3.7' - kind: pypi name: exceptiongroup - version: 1.2.1 - url: https://files.pythonhosted.org/packages/01/90/79fe92dd413a9cab314ef5c591b5aa9b9ba787ae4cadab75055b0ae00b33/exceptiongroup-1.2.1-py3-none-any.whl - sha256: 5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad + version: 1.2.2 + url: https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl + sha256: 3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b requires_dist: - pytest>=6 ; extra == 'test' requires_python: '>=3.7' @@ -1252,9 +1262,9 @@ packages: timestamp: 1656528515966 - kind: pypi name: huggingface-hub - version: 0.24.5 - url: https://files.pythonhosted.org/packages/0b/05/31b21998f68c31e7ffcc27ff08531fb9af5506d765ce8d661fb0036e6918/huggingface_hub-0.24.5-py3-none-any.whl - sha256: d93fb63b1f1a919a22ce91a14518974e81fc4610bf344dfe7572343ce8d3aced + version: 0.24.6 + url: https://files.pythonhosted.org/packages/b9/8f/d6718641c14d98a5848c6a24d2376028d292074ffade0702940a4b1dde76/huggingface_hub-0.24.6-py3-none-any.whl + sha256: a990f3232aa985fe749bc9474060cbad75e8b2f115f6665a9fda5b9c97818970 requires_dist: - filelock - fsspec>=2023.5.0 @@ -1364,15 +1374,15 @@ packages: requires_python: '>=3.8.0' - kind: pypi name: idna - version: '3.7' - url: https://files.pythonhosted.org/packages/e5/3e/741d8c82801c347547f8a2a06aa57dbb1992be9e948df2ea0eda2c8b79e8/idna-3.7-py3-none-any.whl - sha256: 82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0 - requires_python: '>=3.5' + version: '3.8' + url: https://files.pythonhosted.org/packages/22/7e/d71db821f177828df9dea8c42ac46473366f191be53080e552e628aad991/idna-3.8-py3-none-any.whl + sha256: 050b4e5baadcd44d760cedbd2b8e639f2ff89bbc7a5730fcc662954303377aac + requires_python: '>=3.6' - kind: pypi name: importlib-metadata - version: 8.0.0 - url: https://files.pythonhosted.org/packages/dc/ef/38766b2edb096260d9b1b6ad35adaa0bce3b0567abb452b21eb074af88c4/importlib_metadata-8.0.0-py3-none-any.whl - sha256: 15584cf2b1bf449d98ff8a6ff1abef57bf20f3ac6454f431736cd3e660921b2f + version: 8.4.0 + url: https://files.pythonhosted.org/packages/c0/14/362d31bf1076b21e1bcdcb0dc61944822ff263937b804a79231df2774d28/importlib_metadata-8.4.0-py3-none-any.whl + sha256: 66f342cc6ac9818fc6ff340576acd24d65ba0b3efabb2b4ac08b598965a4a2f1 requires_dist: - zipp>=0.5 - typing-extensions>=3.6.4 ; python_version < '3.8' @@ -1388,36 +1398,35 @@ packages: - pytest-cov ; extra == 'test' - pytest-mypy ; extra == 'test' - pytest-enabler>=2.2 ; extra == 'test' - - pytest-ruff>=0.2.1 ; extra == 'test' - packaging ; extra == 'test' - pyfakefs ; extra == 'test' - flufl-flake8 ; extra == 'test' - pytest-perf>=0.9.2 ; extra == 'test' - jaraco-test>=5.4 ; extra == 'test' - importlib-resources>=1.3 ; python_version < '3.9' and extra == 'test' + - pytest-ruff>=0.2.1 ; sys_platform != 'cygwin' and extra == 'test' requires_python: '>=3.8' - kind: pypi name: importlib-resources - version: 6.4.0 - url: https://files.pythonhosted.org/packages/75/06/4df55e1b7b112d183f65db9503bff189e97179b256e1ea450a3c365241e0/importlib_resources-6.4.0-py3-none-any.whl - sha256: 50d10f043df931902d4194ea07ec57960f66a80449ff867bfe782b4c486ba78c + version: 6.4.4 + url: https://files.pythonhosted.org/packages/db/2a/728c8ae66011600fac5731a7db030d23c42f1321fd9547654f0c3b2b32d7/importlib_resources-6.4.4-py3-none-any.whl + sha256: dda242603d1c9cd836c3368b1174ed74cb4049ecd209e7a1a0104620c18c5c11 requires_dist: - zipp>=3.1.0 ; python_version < '3.10' - - sphinx>=3.5 ; extra == 'docs' - - sphinx<7.2.5 ; extra == 'docs' - - jaraco-packaging>=9.3 ; extra == 'docs' - - rst-linker>=1.9 ; extra == 'docs' - - furo ; extra == 'docs' - - sphinx-lint ; extra == 'docs' - - jaraco-tidelift>=1.4 ; extra == 'docs' - - pytest>=6 ; extra == 'testing' - - pytest-checkdocs>=2.4 ; extra == 'testing' - - pytest-cov ; extra == 'testing' - - pytest-enabler>=2.2 ; extra == 'testing' - - pytest-ruff>=0.2.1 ; extra == 'testing' - - zipp>=3.17 ; extra == 'testing' - - jaraco-test>=5.4 ; extra == 'testing' - - pytest-mypy ; platform_python_implementation != 'PyPy' and extra == 'testing' + - pytest-checkdocs>=2.4 ; extra == 'check' + - pytest-ruff>=0.2.1 ; sys_platform != 'cygwin' and extra == 'check' + - pytest-cov ; extra == 'cover' + - sphinx>=3.5 ; extra == 'doc' + - jaraco-packaging>=9.3 ; extra == 'doc' + - rst-linker>=1.9 ; extra == 'doc' + - furo ; extra == 'doc' + - sphinx-lint ; extra == 'doc' + - jaraco-tidelift>=1.4 ; extra == 'doc' + - pytest-enabler>=2.2 ; extra == 'enabler' + - pytest!=8.1.*,>=6 ; extra == 'test' + - zipp>=3.17 ; extra == 'test' + - jaraco-test>=5.4 ; extra == 'test' + - pytest-mypy ; extra == 'type' requires_python: '>=3.8' - kind: pypi name: iniconfig @@ -1453,46 +1462,45 @@ packages: requires_python: '>=3.8' - kind: pypi name: jaraco-context - version: 5.3.0 - url: https://files.pythonhosted.org/packages/d2/40/11b7bc1898cf1dcb87ccbe09b39f5088634ac78bb25f3383ff541c2b40aa/jaraco.context-5.3.0-py3-none-any.whl - sha256: 3e16388f7da43d384a1a7cd3452e72e14732ac9fe459678773a3608a812bf266 + version: 6.0.1 + url: https://files.pythonhosted.org/packages/ff/db/0c52c4cf5e4bd9f5d7135ec7669a3a767af21b3a308e1ed3674881e52b62/jaraco.context-6.0.1-py3-none-any.whl + sha256: f797fc481b490edb305122c9181830a3a5b76d84ef6d1aef2fb9b47ab956f9e4 requires_dist: - backports-tarfile ; python_version < '3.12' - - sphinx>=3.5 ; extra == 'docs' - - jaraco-packaging>=9.3 ; extra == 'docs' - - rst-linker>=1.9 ; extra == 'docs' - - furo ; extra == 'docs' - - sphinx-lint ; extra == 'docs' - - jaraco-tidelift>=1.4 ; extra == 'docs' - - pytest!=8.1.1,>=6 ; extra == 'testing' - - pytest-checkdocs>=2.4 ; extra == 'testing' - - pytest-cov ; extra == 'testing' - - pytest-mypy ; extra == 'testing' - - pytest-enabler>=2.2 ; extra == 'testing' - - pytest-ruff>=0.2.1 ; extra == 'testing' - - portend ; extra == 'testing' + - sphinx>=3.5 ; extra == 'doc' + - jaraco-packaging>=9.3 ; extra == 'doc' + - rst-linker>=1.9 ; extra == 'doc' + - furo ; extra == 'doc' + - sphinx-lint ; extra == 'doc' + - jaraco-tidelift>=1.4 ; extra == 'doc' + - pytest!=8.1.*,>=6 ; extra == 'test' + - pytest-checkdocs>=2.4 ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-mypy ; extra == 'test' + - pytest-enabler>=2.2 ; extra == 'test' + - portend ; extra == 'test' + - pytest-ruff>=0.2.1 ; sys_platform != 'cygwin' and extra == 'test' requires_python: '>=3.8' - kind: pypi name: jaraco-functools - version: 4.0.1 - url: https://files.pythonhosted.org/packages/c3/ac/d0bf0d37a9f95f69a5efc5685d9166ee34a664d3cd29a9c139989512fe14/jaraco.functools-4.0.1-py3-none-any.whl - sha256: 3b24ccb921d6b593bdceb56ce14799204f473976e2a9d4b15b04d0f2c2326664 + version: 4.0.2 + url: https://files.pythonhosted.org/packages/b1/54/7623e24ffc63730c3a619101361b08860c6b7c7cfc1aef6edb66d80ed708/jaraco.functools-4.0.2-py3-none-any.whl + sha256: c9d16a3ed4ccb5a889ad8e0b7a343401ee5b2a71cee6ed192d3f68bc351e94e3 requires_dist: - more-itertools - - sphinx>=3.5 ; extra == 'docs' - - sphinx<7.2.5 ; extra == 'docs' - - jaraco-packaging>=9.3 ; extra == 'docs' - - rst-linker>=1.9 ; extra == 'docs' - - furo ; extra == 'docs' - - sphinx-lint ; extra == 'docs' - - jaraco-tidelift>=1.4 ; extra == 'docs' - - pytest>=6 ; extra == 'testing' - - pytest-checkdocs>=2.4 ; extra == 'testing' - - pytest-cov ; extra == 'testing' - - pytest-enabler>=2.2 ; extra == 'testing' - - pytest-ruff>=0.2.1 ; extra == 'testing' - - jaraco-classes ; extra == 'testing' - - pytest-mypy ; platform_python_implementation != 'PyPy' and extra == 'testing' + - sphinx>=3.5 ; extra == 'doc' + - jaraco-packaging>=9.3 ; extra == 'doc' + - rst-linker>=1.9 ; extra == 'doc' + - furo ; extra == 'doc' + - sphinx-lint ; extra == 'doc' + - jaraco-tidelift>=1.4 ; extra == 'doc' + - pytest!=8.1.*,>=6 ; extra == 'test' + - pytest-checkdocs>=2.4 ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-mypy ; extra == 'test' + - pytest-enabler>=2.2 ; extra == 'test' + - jaraco-classes ; extra == 'test' + - pytest-ruff>=0.2.1 ; sys_platform != 'cygwin' and extra == 'test' requires_python: '>=3.8' - kind: pypi name: jeepney @@ -1520,9 +1528,9 @@ packages: requires_python: '>=3.7' - kind: pypi name: keyring - version: 25.2.1 - url: https://files.pythonhosted.org/packages/92/91/901f5cfeaaea04cf15f5ddf41ee053a5c9e389166477a3427fcfd055e1d9/keyring-25.2.1-py3-none-any.whl - sha256: 2458681cdefc0dbc0b7eb6cf75d0b98e59f9ad9b2d4edd319d18f68bdca95e50 + version: 25.3.0 + url: https://files.pythonhosted.org/packages/63/42/ea8c9726e5ee5ff0731978aaf7cd5fa16674cf549c46279b279d7167c2b4/keyring-25.3.0-py3-none-any.whl + sha256: 8d963da00ccdf06e356acd9bf3b743208878751032d8599c6cc89eb51310ffae requires_dist: - jaraco-classes - jaraco-functools @@ -1533,18 +1541,19 @@ packages: - jeepney>=0.4.2 ; sys_platform == 'linux' - pywin32-ctypes>=0.2.0 ; sys_platform == 'win32' - shtab>=1.1.0 ; extra == 'completion' - - sphinx>=3.5 ; extra == 'docs' - - jaraco-packaging>=9.3 ; extra == 'docs' - - rst-linker>=1.9 ; extra == 'docs' - - furo ; extra == 'docs' - - sphinx-lint ; extra == 'docs' - - jaraco-tidelift>=1.4 ; extra == 'docs' - - pytest!=8.1.*,>=6 ; extra == 'testing' - - pytest-checkdocs>=2.4 ; extra == 'testing' - - pytest-cov ; extra == 'testing' - - pytest-mypy ; extra == 'testing' - - pytest-enabler>=2.2 ; extra == 'testing' - - pytest-ruff>=0.2.1 ; extra == 'testing' + - sphinx>=3.5 ; extra == 'doc' + - jaraco-packaging>=9.3 ; extra == 'doc' + - rst-linker>=1.9 ; extra == 'doc' + - furo ; extra == 'doc' + - sphinx-lint ; extra == 'doc' + - jaraco-tidelift>=1.4 ; extra == 'doc' + - pytest!=8.1.*,>=6 ; extra == 'test' + - pytest-checkdocs>=2.4 ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-mypy ; extra == 'test' + - pytest-enabler>=2.2 ; extra == 'test' + - pyfakefs ; extra == 'test' + - pytest-ruff>=0.2.1 ; sys_platform != 'cygwin' and extra == 'test' requires_python: '>=3.8' - kind: conda name: ld_impl_linux-64 @@ -1735,38 +1744,57 @@ packages: size: 48003 timestamp: 1584559351227 - kind: conda - name: libgcc-ng + name: libgcc version: 14.1.0 - build: h77fa898_0 + build: h77fa898_1 + build_number: 1 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-14.1.0-h77fa898_0.conda - sha256: b8e869ac96591cda2704bf7e77a301025e405227791a0bddf14a3dac65125538 - md5: ca0fad6a41ddaef54a153b78eccb5037 + url: https://conda.anaconda.org/conda-forge/linux-64/libgcc-14.1.0-h77fa898_1.conda + sha256: 10fa74b69266a2be7b96db881e18fa62cfa03082b65231e8d652e897c4b335a3 + md5: 002ef4463dd1e2b44a94a4ace468f5d2 depends: - _libgcc_mutex 0.1 conda_forge - _openmp_mutex >=4.5 constrains: - - libgomp 14.1.0 h77fa898_0 + - libgomp 14.1.0 h77fa898_1 + - libgcc-ng ==14.1.0=*_1 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL purls: [] - size: 842109 - timestamp: 1719538896937 + size: 846380 + timestamp: 1724801836552 +- kind: conda + name: libgcc-ng + version: 14.1.0 + build: h69a702a_1 + build_number: 1 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-14.1.0-h69a702a_1.conda + sha256: b91f7021e14c3d5c840fbf0dc75370d6e1f7c7ff4482220940eaafb9c64613b7 + md5: 1efc0ad219877a73ef977af7dbb51f17 + depends: + - libgcc 14.1.0 h77fa898_1 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 52170 + timestamp: 1724801842101 - kind: conda name: libgomp version: 14.1.0 - build: h77fa898_0 + build: h77fa898_1 + build_number: 1 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libgomp-14.1.0-h77fa898_0.conda - sha256: 7699df61a1f6c644b3576a40f54791561f2845983120477a16116b951c9cdb05 - md5: ae061a5ed5f05818acdf9adab72c146d + url: https://conda.anaconda.org/conda-forge/linux-64/libgomp-14.1.0-h77fa898_1.conda + sha256: c96724c8ae4ee61af7674c5d9e5a3fbcf6cd887a40ad5a52c99aa36f1d4f9680 + md5: 23c255b008c4f2ae008f81edcabaca89 depends: - _libgcc_mutex 0.1 conda_forge license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL purls: [] - size: 456925 - timestamp: 1719538796073 + size: 460218 + timestamp: 1724801743478 - kind: conda name: libnpp version: 11.7.3.21 @@ -1834,21 +1862,38 @@ packages: purls: [] size: 865346 timestamp: 1718050628718 +- kind: conda + name: libstdcxx + version: 14.1.0 + build: hc0a3c3a_1 + build_number: 1 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-14.1.0-hc0a3c3a_1.conda + sha256: 44decb3d23abacf1c6dd59f3c152a7101b7ca565b4ef8872804ceaedcc53a9cd + md5: 9dbb9699ea467983ba8a4ba89b08b066 + depends: + - libgcc 14.1.0 h77fa898_1 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 3892781 + timestamp: 1724801863728 - kind: conda name: libstdcxx-ng version: 14.1.0 - build: hc0a3c3a_0 + build: h4852527_1 + build_number: 1 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-14.1.0-hc0a3c3a_0.conda - sha256: 88c42b388202ffe16adaa337e36cf5022c63cf09b0405cf06fc6aeacccbe6146 - md5: 1cb187a157136398ddbaae90713e2498 + url: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-14.1.0-h4852527_1.conda + sha256: a2dc44f97290740cc187bfe94ce543e6eb3c2ea8964d99f189a1d8c97b419b8c + md5: bd2598399a70bb86d8218e95548d735e depends: - - libgcc-ng 14.1.0 h77fa898_0 + - libstdcxx 14.1.0 hc0a3c3a_1 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL purls: [] - size: 3881307 - timestamp: 1719538923443 + size: 52219 + timestamp: 1724801897766 - kind: conda name: libzlib version: 1.2.13 @@ -1913,9 +1958,9 @@ packages: requires_python: '>=3.7' - kind: pypi name: more-itertools - version: 10.3.0 - url: https://files.pythonhosted.org/packages/bb/23/2d1cdb0427aecb2b150dc2ac2d15400990c4f05585b3fbc1b5177d74d7fb/more_itertools-10.3.0-py3-none-any.whl - sha256: ea6a02e24a9161e51faad17a8782b92a0df82c12c1c8886fec7f0c3fa1a1b320 + version: 10.4.0 + url: https://files.pythonhosted.org/packages/d8/0b/6a51175e1395774449fca317fb8861379b7a2d59be411b8cce3d19d6ce78/more_itertools-10.4.0-py3-none-any.whl + sha256: 0f7d9f83a0a8dcfa8a2694a770590d98a67ea943e3d9f5298309a484758c4e27 requires_python: '>=3.8' - kind: pypi name: mpmath @@ -1934,17 +1979,19 @@ packages: - kind: conda name: ncurses version: '6.5' - build: h59595ed_0 + build: he02047a_1 + build_number: 1 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h59595ed_0.conda - sha256: 4fc3b384f4072b68853a0013ea83bdfd3d66b0126e2238e1d6e1560747aa7586 - md5: fcea371545eda051b6deafb24889fc69 + url: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-he02047a_1.conda + sha256: 6a1d5d8634c1a07913f1c525db6455918cbc589d745fac46d9d6e30340c8731a + md5: 70caf8bb6cf39a0b6b7efc885f51c0fe depends: + - __glibc >=2.17,<3.0.a0 - libgcc-ng >=12 license: X11 AND BSD-3-Clause purls: [] - size: 887465 - timestamp: 1715194722503 + size: 889086 + timestamp: 1724658547447 - kind: pypi name: networkx version: '3.1' @@ -1974,9 +2021,9 @@ packages: requires_python: '>=3.8' - kind: pypi name: nh3 - version: 0.2.17 - url: https://files.pythonhosted.org/packages/da/19/d52d9a0247007835df949f17abd904615248dc1b94d67cb8c99100330f08/nh3-0.2.17-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - sha256: c21bac1a7245cbd88c0b0e4a420221b7bfa838a2814ee5bb924e9c2f10a1120b + version: 0.2.18 + url: https://files.pythonhosted.org/packages/1b/63/6ab90d0e5225ab9780f6c9fb52254fa36b52bb7c188df9201d05b647e5e1/nh3-0.2.18-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + sha256: de3ceed6e661954871d6cd78b410213bdcb136f79aafe22aa7182e028b8c7307 - kind: pypi name: nodeenv version: 1.9.1 @@ -2027,9 +2074,9 @@ packages: requires_python: '>=3' - kind: pypi name: nvidia-cudnn-cu12 - version: 8.9.2.26 - url: https://files.pythonhosted.org/packages/ff/74/a2e2be7fb83aaedec84f391f082cf765dfb635e7caa9b49065f73e4835d8/nvidia_cudnn_cu12-8.9.2.26-py3-none-manylinux1_x86_64.whl - sha256: 5ccb288774fdfb07a7e7025ffec286971c06d8d7b4fb162525334616d7629ff9 + version: 9.1.0.70 + url: https://files.pythonhosted.org/packages/9f/fd/713452cd72343f682b1c7b9321e23829f00b842ceaedcda96e742ea0b0b3/nvidia_cudnn_cu12-9.1.0.70-py3-none-manylinux2014_x86_64.whl + sha256: 165764f44ef8c61fcdfdfdbe769d687e06374059fbb388b6c89ecb0e28793a6f requires_dist: - nvidia-cublas-cu12 requires_python: '>=3' @@ -2071,9 +2118,9 @@ packages: requires_python: '>=3' - kind: pypi name: nvidia-nvjitlink-cu12 - version: 12.5.82 - url: https://files.pythonhosted.org/packages/75/bc/e0d0dbb85246a086ab14839979039647bce501d8c661a159b8b019d987b7/nvidia_nvjitlink_cu12-12.5.82-py3-none-manylinux2014_x86_64.whl - sha256: f9b37bc5c8cf7509665cb6ada5aaa0ce65618f2332b7d3e78e9790511f111212 + version: 12.6.68 + url: https://files.pythonhosted.org/packages/a8/48/a9775d377cb95585fb188b469387f58ba6738e268de22eae2ad4cedb2c41/nvidia_nvjitlink_cu12-12.6.68-py3-none-manylinux2014_x86_64.whl + sha256: 125a6c2a44e96386dda634e13d944e60b07a0402d391a070e8fb4104b34ea1ab requires_python: '>=3' - kind: pypi name: nvidia-nvtx-cu12 @@ -2105,9 +2152,9 @@ packages: requires_python: '>=3.8' - kind: pypi name: paramiko - version: 3.4.0 - url: https://files.pythonhosted.org/packages/ad/50/8792484502c8141c20c996b802fefa8435a9c018a2bb440a06b172782118/paramiko-3.4.0-py3-none-any.whl - sha256: 43f0b51115a896f9c00f59618023484cb3a14b98bbceab43394a39c6739b7ee7 + version: 3.4.1 + url: https://files.pythonhosted.org/packages/96/6e/4a52a8923d840107024b844d83502dfa6a1e5399ad31cf9d1a4ddbaaa7e5/paramiko-3.4.1-py3-none-any.whl + sha256: 8e49fd2f82f84acf7ffd57c64311aa2b30e575370dc23bdb375b10262f7eac32 requires_dist: - bcrypt>=3.2 - cryptography>=3.3 @@ -2188,9 +2235,9 @@ packages: requires_python: '>=3.7' - kind: pypi name: pyright - version: 1.1.370 - url: https://files.pythonhosted.org/packages/0c/2b/3d70ea49041da4dfb64b71039d94f3b31843575edf1f29fe0370919c35aa/pyright-1.1.370-py3-none-any.whl - sha256: fc721601e480a69989775bfc210534a6ca0110ebd0c065244a8d3a151294fc61 + version: 1.1.378 + url: https://files.pythonhosted.org/packages/38/c6/f0d4bc20c13b20cecfbf13c699477c825e45767f1dc5068137323f86e495/pyright-1.1.378-py3-none-any.whl + sha256: 8853776138b01bc284da07ac481235be7cc89d3176b073d2dba73636cb95be79 requires_dist: - nodeenv>=1.6.0 - typing-extensions>=3.7 ; python_version < '3.8' @@ -2199,13 +2246,13 @@ packages: requires_python: '>=3.7' - kind: pypi name: pytest - version: 8.2.2 - url: https://files.pythonhosted.org/packages/4e/e7/81ebdd666d3bff6670d27349b5053605d83d55548e6bd5711f3b0ae7dd23/pytest-8.2.2-py3-none-any.whl - sha256: c434598117762e2bd304e526244f67bf66bbd7b5d6cf22138be51ff661980343 + version: 8.3.2 + url: https://files.pythonhosted.org/packages/0f/f9/cf155cf32ca7d6fa3601bc4c5dd19086af4b320b706919d48a4c79081cf9/pytest-8.3.2-py3-none-any.whl + sha256: 4ba08f9ae7dcf84ded419494d229b48d0903ea6407b030eaec46df5e6a73bba5 requires_dist: - iniconfig - packaging - - pluggy<2.0,>=1.5 + - pluggy<2,>=1.5 - exceptiongroup>=1.0.0rc8 ; python_version < '3.11' - tomli>=1 ; python_version < '3.11' - colorama ; sys_platform == 'win32' @@ -2315,9 +2362,9 @@ packages: requires_python: '>=3.7' - kind: pypi name: rich - version: 13.7.1 - url: https://files.pythonhosted.org/packages/87/67/a37f6214d0e9fe57f6ae54b2956d550ca8365857f42a1ce0392bb21d9410/rich-13.7.1-py3-none-any.whl - sha256: 4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222 + version: 13.8.0 + url: https://files.pythonhosted.org/packages/c7/d9/c2a126eeae791e90ea099d05cb0515feea3688474b978343f3cdcfe04523/rich-13.8.0-py3-none-any.whl + sha256: 2e85306a063b9492dffc86278197a60cbece75bcb766022f3436f567cae11bdc requires_dist: - ipywidgets>=7.5.1,<9 ; extra == 'jupyter' - markdown-it-py>=2.2.0 @@ -2326,9 +2373,9 @@ packages: requires_python: '>=3.7.0' - kind: pypi name: ruff - version: 0.5.1 - url: https://files.pythonhosted.org/packages/8a/d5/8271d42dd239b7c2d163615b3b01b1acfb187f5114bfca6d5a85e1d6a1eb/ruff-0.5.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - sha256: e216fc75a80ea1fbd96af94a6233d90190d5b65cc3d5dfacf2bd48c3e067d3e1 + version: 0.6.3 + url: https://files.pythonhosted.org/packages/38/5d/b33284c108e3f315ddd09b70296fd76bd28ecf8965a520bc93f3bbd8ac40/ruff-0.6.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + sha256: 70452a10eb2d66549de8e75f89ae82462159855e983ddff91bc0bce6511d0470 requires_python: '>=3.7' - kind: pypi name: safetensors @@ -2381,12 +2428,14 @@ packages: requires_python: '>=3.6' - kind: pypi name: setuptools - version: 72.2.0 - url: https://files.pythonhosted.org/packages/6e/ec/06715d912351edc453e37f93f3fc80dcffd5ca0e70386c87529aca296f05/setuptools-72.2.0-py3-none-any.whl - sha256: f11dd94b7bae3a156a95ec151f24e4637fb4fa19c878e4d191bfb8b2d82728c4 + version: 74.1.1 + url: https://files.pythonhosted.org/packages/48/f3/e30ee63caefa90716afdffd7d9ae959cd8d0dbd2d0a0eb9fe1d73ddf806b/setuptools-74.1.1-py3-none-any.whl + sha256: fc91b5f89e392ef5b77fe143b17e32f65d3024744fba66dc3afe07201684d766 requires_dist: + - pytest-checkdocs>=2.4 ; extra == 'check' + - pytest-ruff>=0.2.1 ; sys_platform != 'cygwin' and extra == 'check' + - ruff>=0.5.2 ; sys_platform != 'cygwin' and extra == 'check' - packaging>=24 ; extra == 'core' - - ordered-set>=3.1.1 ; extra == 'core' - more-itertools>=8.8 ; extra == 'core' - jaraco-text>=3.7 ; extra == 'core' - wheel>=0.43.0 ; extra == 'core' @@ -2394,6 +2443,7 @@ packages: - importlib-metadata>=6 ; python_version < '3.10' and extra == 'core' - tomli>=2.0.1 ; python_version < '3.11' and extra == 'core' - importlib-resources>=5.10.2 ; python_version < '3.9' and extra == 'core' + - pytest-cov ; extra == 'cover' - sphinx>=3.5 ; extra == 'doc' - jaraco-packaging>=9.3 ; extra == 'doc' - rst-linker>=1.9 ; extra == 'doc' @@ -2408,13 +2458,10 @@ packages: - sphinx-notfound-page<2,>=1 ; extra == 'doc' - pyproject-hooks!=1.1 ; extra == 'doc' - towncrier<24.7 ; extra == 'doc' + - pytest-enabler>=2.2 ; extra == 'enabler' - pytest!=8.1.*,>=6 ; extra == 'test' - - pytest-checkdocs>=2.4 ; extra == 'test' - - pytest-cov ; extra == 'test' - - pytest-mypy ; extra == 'test' - - pytest-enabler>=2.2 ; extra == 'test' - virtualenv>=13.0.0 ; extra == 'test' - - wheel ; extra == 'test' + - wheel>=0.44.0 ; extra == 'test' - pip>=19.1 ; extra == 'test' - packaging>=23.2 ; extra == 'test' - jaraco-envs>=2.2 ; extra == 'test' @@ -2426,17 +2473,15 @@ packages: - tomli-w>=1.0.0 ; extra == 'test' - pytest-timeout ; extra == 'test' - pytest-home>=0.5 ; extra == 'test' - - mypy==1.11.* ; extra == 'test' - - tomli ; extra == 'test' - - importlib-metadata ; extra == 'test' - pytest-subprocess ; extra == 'test' - pyproject-hooks!=1.1 ; extra == 'test' - jaraco-test ; extra == 'test' - - pytest-ruff<0.4 ; platform_system == 'Windows' and extra == 'test' - jaraco-develop>=7.21 ; (python_version >= '3.9' and sys_platform != 'cygwin') and extra == 'test' - - pytest-ruff>=0.2.1 ; sys_platform != 'cygwin' and extra == 'test' - pytest-perf ; sys_platform != 'cygwin' and extra == 'test' - - pytest-ruff>=0.3.2 ; sys_platform != 'cygwin' and extra == 'test' + - pytest-mypy ; extra == 'type' + - mypy==1.11.* ; extra == 'type' + - importlib-metadata>=7.0.2 ; python_version < '3.10' and extra == 'type' + - jaraco-develop>=7.21 ; sys_platform != 'cygwin' and extra == 'type' requires_python: '>=3.8' - kind: conda name: sqlite @@ -2478,11 +2523,13 @@ packages: requires_python: '>=3.8' - kind: pypi name: sympy - version: 1.12.1 - url: https://files.pythonhosted.org/packages/61/53/e18c8c97d0b2724d85c9830477e3ebea3acf1dcdc6deb344d5d9c93a9946/sympy-1.12.1-py3-none-any.whl - sha256: 9b2cbc7f1a640289430e13d2a56f02f867a1da0190f2f99d8968c2f74da0e515 + version: 1.13.2 + url: https://files.pythonhosted.org/packages/c1/f9/6845bf8fca0eaf847da21c5d5bc6cd92797364662824a11d3f836423a1a5/sympy-1.13.2-py3-none-any.whl + sha256: c51d75517712f1aed280d4ce58506a4a88d635d6b5dd48b39102a7ae1f3fcfe9 requires_dist: - - mpmath<1.4.0,>=1.1.0 + - mpmath<1.4,>=1.1.0 + - pytest>=7.1.0 ; extra == 'dev' + - hypothesis>=6.70.0 ; extra == 'dev' requires_python: '>=3.8' - kind: conda name: tk @@ -2527,9 +2574,9 @@ packages: requires_python: '>=3.7' - kind: pypi name: torch - version: 2.3.1 - url: https://files.pythonhosted.org/packages/c0/7e/309d63c6330a0b821a6f55e06dcef6704a7ab8b707534a4923837570624e/torch-2.3.1-cp38-cp38-manylinux1_x86_64.whl - sha256: 07e9ba746832b8d069cacb45f312cadd8ad02b81ea527ec9766c0e7404bb3feb + version: 2.4.0 + url: https://files.pythonhosted.org/packages/fc/58/f93bdce23c9ff568c3dfb5129db0c14e60f7c72ab4d1a6de8fedca6e3792/torch-2.4.0-cp38-cp38-manylinux1_x86_64.whl + sha256: cc30457ea5489c62747d3306438af00c606b509d78822a88f804202ba63111ed requires_dist: - filelock - typing-extensions>=4.8.0 @@ -2540,7 +2587,7 @@ packages: - nvidia-cuda-nvrtc-cu12==12.1.105 ; platform_system == 'Linux' and platform_machine == 'x86_64' - nvidia-cuda-runtime-cu12==12.1.105 ; platform_system == 'Linux' and platform_machine == 'x86_64' - nvidia-cuda-cupti-cu12==12.1.105 ; platform_system == 'Linux' and platform_machine == 'x86_64' - - nvidia-cudnn-cu12==8.9.2.26 ; platform_system == 'Linux' and platform_machine == 'x86_64' + - nvidia-cudnn-cu12==9.1.0.70 ; platform_system == 'Linux' and platform_machine == 'x86_64' - nvidia-cublas-cu12==12.1.3.1 ; platform_system == 'Linux' and platform_machine == 'x86_64' - nvidia-cufft-cu12==11.0.2.54 ; platform_system == 'Linux' and platform_machine == 'x86_64' - nvidia-curand-cu12==10.3.2.106 ; platform_system == 'Linux' and platform_machine == 'x86_64' @@ -2548,16 +2595,15 @@ packages: - nvidia-cusparse-cu12==12.1.0.106 ; platform_system == 'Linux' and platform_machine == 'x86_64' - nvidia-nccl-cu12==2.20.5 ; platform_system == 'Linux' and platform_machine == 'x86_64' - nvidia-nvtx-cu12==12.1.105 ; platform_system == 'Linux' and platform_machine == 'x86_64' - - triton==2.3.1 ; platform_system == 'Linux' and platform_machine == 'x86_64' and python_version < '3.12' - - mkl<=2021.4.0,>=2021.1.1 ; platform_system == 'Windows' + - triton==3.0.0 ; platform_system == 'Linux' and platform_machine == 'x86_64' and python_version < '3.13' - opt-einsum>=3.3 ; extra == 'opt-einsum' - - optree>=0.9.1 ; extra == 'optree' + - optree>=0.11.0 ; extra == 'optree' requires_python: '>=3.8.0' - kind: pypi name: torchrunx - version: 0.1.3 + version: 0.1.4 path: . - sha256: 96b863ca488233d5c87090d1d717de301fb336809ab5565473ce4d6019bf2df5 + sha256: de986bf47e1c379e4de6b10ca352715d708bb5f9b4cfc8736e9ee592db5fe1ae requires_dist: - cloudpickle>=3.0.0 - fabric>=3.0.0 @@ -2583,9 +2629,9 @@ packages: requires_python: '>=3.7' - kind: pypi name: transformers - version: 4.44.0 - url: https://files.pythonhosted.org/packages/62/c0/810e741a6244c0f004be40ccb96486d072f042eabbd4d7e8aa02b81ca1eb/transformers-4.44.0-py3-none-any.whl - sha256: ea0ff72def71e9f4812d9414d4803b22681b1617aa6f511bd51cfff2b44a6fca + version: 4.44.2 + url: https://files.pythonhosted.org/packages/75/35/07c9879163b603f0e464b0f6e6e628a2340cfc7cdc5ca8e7d52d776710d4/transformers-4.44.2-py3-none-any.whl + sha256: 1c02c65e7bfa5e52a634aff3da52138b583fc6f263c1f28d547dc144ba3d412d requires_dist: - filelock - huggingface-hub<1.0,>=0.23.2 @@ -2941,9 +2987,9 @@ packages: requires_python: '>=3.8.0' - kind: pypi name: triton - version: 2.3.1 - url: https://files.pythonhosted.org/packages/d3/55/45b3882019a8d69ad73b5b2bd1714cb2d6653b39e7376b7ac5accf745760/triton-2.3.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - sha256: 63381e35ded3304704ea867ffde3b7cfc42c16a55b3062d41e017ef510433d66 + version: 3.0.0 + url: https://files.pythonhosted.org/packages/4d/b4/c37e2776a1390bab7e78a6d52bd525441cb3cad7260a6a00b11b0b702e7c/triton-3.0.0-1-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.whl + sha256: bcbf3b1c48af6a28011a5c40a5b3b9b5330530c3827716b5fbf6d7adcc1e53e9 requires_dist: - filelock - cmake>=3.20 ; extra == 'build' @@ -2954,11 +3000,10 @@ packages: - numpy ; extra == 'tests' - pytest ; extra == 'tests' - scipy>=1.7.1 ; extra == 'tests' - - torch ; extra == 'tests' + - llnl-hatchet ; extra == 'tests' - matplotlib ; extra == 'tutorials' - pandas ; extra == 'tutorials' - tabulate ; extra == 'tutorials' - - torch ; extra == 'tutorials' - kind: pypi name: twine version: 5.1.1 @@ -3016,22 +3061,21 @@ packages: timestamp: 1660346797927 - kind: pypi name: zipp - version: 3.19.2 - url: https://files.pythonhosted.org/packages/20/38/f5c473fe9b90c8debdd29ea68d5add0289f1936d6f923b6b9cc0b931194c/zipp-3.19.2-py3-none-any.whl - sha256: f091755f667055f2d02b32c53771a7a6c8b47e1fdbc4b72a8b9072b3eef8015c + version: 3.20.1 + url: https://files.pythonhosted.org/packages/07/9e/c96f7a4cd0bf5625bb409b7e61e99b1130dc63a98cb8b24aeabae62d43e8/zipp-3.20.1-py3-none-any.whl + sha256: 9960cd8967c8f85a56f920d5d507274e74f9ff813a0ab8889a5b5be2daf44064 requires_dist: + - pytest-checkdocs>=2.4 ; extra == 'check' + - pytest-ruff>=0.2.1 ; sys_platform != 'cygwin' and extra == 'check' + - pytest-cov ; extra == 'cover' - sphinx>=3.5 ; extra == 'doc' - jaraco-packaging>=9.3 ; extra == 'doc' - rst-linker>=1.9 ; extra == 'doc' - furo ; extra == 'doc' - sphinx-lint ; extra == 'doc' - jaraco-tidelift>=1.4 ; extra == 'doc' + - pytest-enabler>=2.2 ; extra == 'enabler' - pytest!=8.1.*,>=6 ; extra == 'test' - - pytest-checkdocs>=2.4 ; extra == 'test' - - pytest-cov ; extra == 'test' - - pytest-mypy ; extra == 'test' - - pytest-enabler>=2.2 ; extra == 'test' - - pytest-ruff>=0.2.1 ; extra == 'test' - jaraco-itertools ; extra == 'test' - jaraco-functools ; extra == 'test' - more-itertools ; extra == 'test' @@ -3039,6 +3083,7 @@ packages: - pytest-ignore-flaky ; extra == 'test' - jaraco-test ; extra == 'test' - importlib-resources ; python_version < '3.9' and extra == 'test' + - pytest-mypy ; extra == 'type' requires_python: '>=3.8' - kind: conda name: zlib diff --git a/pyproject.toml b/pyproject.toml index fa46f920..b5f3866e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "torchrunx" -version = "0.1.3" +version = "0.1.4" authors = [ {name = "Apoorv Khandelwal", email = "mail@apoorvkh.com"}, {name = "Peter Curtin", email = "peter_curtin@brown.edu"}, @@ -41,7 +41,24 @@ include = ["pyproject.toml", "src/**/*.py", "tests/**/*.py"] line-length = 100 src = ["src", "tests"] [tool.ruff.lint] -select = ["E", "F", "I"] +select = ["ALL"] +ignore = [ + "D", # documentation + "ANN101", "ANN102", "ANN401", # self / cls / Any annotations + "BLE001", # blind exceptions + "TD", # todo syntax + "FIX002", # existing todos + "PLR0913", # too many arguments + "DTZ005", # datetime timezone + "S301", # bandit: pickle + "S603", "S607", # bandit: subprocess + "COM812", "ISC001", # conflict with formatter +] +[tool.ruff.lint.per-file-ignores] +"tests/**/*.py" = [ + "S101", # allow asserts + "T201" # allow prints +] [tool.pyright] include = ["src", "tests"] diff --git a/src/torchrunx/__init__.py b/src/torchrunx/__init__.py index 4709fd24..74214cb8 100644 --- a/src/torchrunx/__init__.py +++ b/src/torchrunx/__init__.py @@ -1,4 +1,10 @@ -from .environment import auto_hosts, auto_workers, slurm_hosts, slurm_workers from .launcher import Launcher, launch +from .logging_utils import add_filter_to_handler, file_handler, stream_handler -__all__ = ["Launcher", "launch", "slurm_hosts", "slurm_workers", "auto_hosts", "auto_workers"] +__all__ = [ + "Launcher", + "launch", + "add_filter_to_handler", + "file_handler", + "stream_handler", +] diff --git a/src/torchrunx/__main__.py b/src/torchrunx/__main__.py index f458d37d..c3b3099e 100644 --- a/src/torchrunx/__main__.py +++ b/src/torchrunx/__main__.py @@ -7,6 +7,7 @@ parser = ArgumentParser() parser.add_argument("--launcher-hostname", type=str) parser.add_argument("--launcher-port", type=int) + parser.add_argument("--logger-port", type=int) parser.add_argument("--world-size", type=int) parser.add_argument("--rank", type=int) args = parser.parse_args() @@ -18,4 +19,8 @@ rank=args.rank, ) - main(launcher_agent_group) + main( + launcher_agent_group, + logger_hostname=args.launcher_hostname, + logger_port=args.logger_port, + ) diff --git a/src/torchrunx/agent.py b/src/torchrunx/agent.py index 550a49b3..04d1ec92 100644 --- a/src/torchrunx/agent.py +++ b/src/torchrunx/agent.py @@ -1,24 +1,26 @@ from __future__ import annotations import datetime +import logging import os import socket import sys import tempfile +import traceback from dataclasses import dataclass -from typing import Callable, Literal +from typing import Any, Callable, Literal import cloudpickle import torch import torch.distributed as dist -from torch.distributed.elastic.multiprocessing import start_processes -from typing_extensions import Self +import torch.distributed.elastic.multiprocessing as dist_mp +from .logging_utils import log_records_to_socket, redirect_stdio_to_logger from .utils import ( AgentPayload, AgentStatus, LauncherAgentGroup, - LauncherPayload, + WorkerException, get_open_port, ) @@ -26,81 +28,80 @@ @dataclass class WorkerArgs: function: Callable - master_hostname: str - master_port: int + logger_hostname: str + logger_port: int + main_agent_hostname: str + main_agent_port: int backend: Literal["mpi", "gloo", "nccl", "ucc", None] rank: int local_rank: int local_world_size: int world_size: int - log_file: os.PathLike + hostname: str timeout: int - def to_bytes(self) -> bytes: - return cloudpickle.dumps(self) + def serialize(self) -> SerializedWorkerArgs: + return SerializedWorkerArgs(worker_args=self) - @classmethod - def from_bytes(cls, serialized: bytes) -> Self: - return cloudpickle.loads(serialized) +class SerializedWorkerArgs: + def __init__(self, worker_args: WorkerArgs) -> None: + self.bytes = cloudpickle.dumps(worker_args) -class WorkerTee(object): - def __init__(self, name: os.PathLike | str, mode: str): - self.file = open(name, mode) - self.stdout = sys.stdout - sys.stdout = self + def deserialize(self) -> WorkerArgs: + return cloudpickle.loads(self.bytes) - def __enter__(self): - return self - def __exit__(self, exception_type, exception_value, exception_traceback): - self.__del__() +def entrypoint(serialized_worker_args: SerializedWorkerArgs) -> Any | WorkerException: + worker_args: WorkerArgs = serialized_worker_args.deserialize() - def __del__(self): - sys.stdout = self.stdout - self.file.close() + logger = logging.getLogger() - def write(self, data): - self.file.write(data) - self.stdout.write(data) - - def flush(self): - self.file.flush() + log_records_to_socket( + logger=logger, + hostname=worker_args.hostname, + worker_rank=worker_args.local_rank, + logger_hostname=worker_args.logger_hostname, + logger_port=worker_args.logger_port, + ) + redirect_stdio_to_logger(logger) -def entrypoint(serialized_worker_args: bytes): - worker_args = WorkerArgs.from_bytes(serialized_worker_args) + store = dist.TCPStore( # pyright: ignore [reportPrivateImportUsage] + host_name=worker_args.main_agent_hostname, + port=worker_args.main_agent_port, + world_size=worker_args.world_size, + is_master=(worker_args.rank == 0), + ) - with WorkerTee(worker_args.log_file, "w"): - store = dist.TCPStore( # pyright: ignore[reportPrivateImportUsage] - host_name=worker_args.master_hostname, - port=worker_args.master_port, - world_size=worker_args.world_size, - is_master=(worker_args.rank == 0), - ) + backend = worker_args.backend or ("nccl" if torch.cuda.is_available() else "gloo") - backend = worker_args.backend - if backend is None: - backend = "nccl" if torch.cuda.is_available() else "gloo" - dist.init_process_group( - backend=backend, - world_size=worker_args.world_size, - rank=worker_args.rank, - store=store, - timeout=datetime.timedelta(seconds=worker_args.timeout), - ) + dist.init_process_group( + backend=backend, + world_size=worker_args.world_size, + rank=worker_args.rank, + store=store, + timeout=datetime.timedelta(seconds=worker_args.timeout), + ) - os.environ["RANK"] = str(worker_args.rank) - os.environ["LOCAL_RANK"] = str(worker_args.local_rank) - os.environ["LOCAL_WORLD_SIZE"] = str(worker_args.local_world_size) - os.environ["WORLD_SIZE"] = str(worker_args.world_size) - os.environ["MASTER_ADDR"] = worker_args.master_hostname - os.environ["MASTER_PORT"] = str(worker_args.master_port) + os.environ["RANK"] = str(worker_args.rank) + os.environ["LOCAL_RANK"] = str(worker_args.local_rank) + os.environ["LOCAL_WORLD_SIZE"] = str(worker_args.local_world_size) + os.environ["WORLD_SIZE"] = str(worker_args.world_size) + os.environ["MASTER_ADDR"] = worker_args.main_agent_hostname + os.environ["MASTER_PORT"] = str(worker_args.main_agent_port) + try: return worker_args.function() + except Exception as e: + traceback.print_exc() + return WorkerException(exception=e) + finally: + sys.stdout.flush() + sys.stderr.flush() -def main(launcher_agent_group: LauncherAgentGroup): +def main(launcher_agent_group: LauncherAgentGroup, logger_hostname: str, logger_port: int) -> None: agent_rank = launcher_agent_group.rank - 1 payload = AgentPayload( @@ -108,67 +109,72 @@ def main(launcher_agent_group: LauncherAgentGroup): port=get_open_port(), process_id=os.getpid(), ) - # DefaultLogsSpecs(log_dir=None, tee=Std.ALL, local_ranks_filter={0}), - all_payloads = launcher_agent_group.sync_payloads(payload=payload) - launcher_payload: LauncherPayload = all_payloads[0] # pyright: ignore[reportAssignmentType] - main_agent_payload: AgentPayload = all_payloads[1] # pyright: ignore[reportAssignmentType] + + launcher_payload, agent_payloads = launcher_agent_group.sync_payloads(payload=payload) + main_agent_payload = agent_payloads[0] hostname = launcher_payload.hostnames[agent_rank] worker_world_size = launcher_payload.worker_world_size worker_global_ranks = launcher_payload.worker_global_ranks[agent_rank] - worker_log_files = launcher_payload.worker_log_files[agent_rank] num_workers = len(worker_global_ranks) - if torch.__version__ >= "2.3": - # DefaultLogsSpecs only exists in torch >= 2.3 - from torch.distributed.elastic.multiprocessing import DefaultLogsSpecs + logger = logging.getLogger() - log_arg = DefaultLogsSpecs(log_dir=tempfile.mkdtemp()) - else: - log_arg = tempfile.mkdtemp() + log_records_to_socket( + logger=logger, + hostname=hostname, + worker_rank=None, + logger_hostname=logger_hostname, + logger_port=logger_port, + ) + + redirect_stdio_to_logger(logger) # spawn workers - ctx = start_processes( - f"{hostname}_", - entrypoint, - { + ctx = dist_mp.start_processes( + name=f"{hostname}_", + entrypoint=entrypoint, + args={ i: ( WorkerArgs( function=launcher_payload.fn, - master_hostname=main_agent_payload.hostname, - master_port=main_agent_payload.port, + logger_hostname=logger_hostname, + logger_port=logger_port, + main_agent_hostname=main_agent_payload.hostname, + main_agent_port=main_agent_payload.port, backend=launcher_payload.backend, rank=worker_global_ranks[i], local_rank=i, local_world_size=num_workers, world_size=worker_world_size, - log_file=worker_log_files[i], + hostname=launcher_payload.hostnames[agent_rank], timeout=launcher_payload.timeout, - ).to_bytes(), + ).serialize(), ) for i in range(num_workers) }, - {i: {} for i in range(num_workers)}, - log_arg, # type: ignore + envs={i: {} for i in range(num_workers)}, + **( + {"logs_specs": dist_mp.DefaultLogsSpecs(log_dir=tempfile.mkdtemp())} + if torch.__version__ >= "2.3" + else {"log_dir": tempfile.mkdtemp()} + ), # pyright: ignore [reportArgumentType] ) try: - status = AgentStatus() + status = None while True: - if status.is_running(): - status = AgentStatus.from_result( - result=ctx.wait(5), worker_global_ranks=worker_global_ranks - ) + if status is None or status.state == "running": + status = AgentStatus.from_result(ctx.wait(5)) agent_statuses = launcher_agent_group.sync_agent_statuses(status=status) - if all(s.is_done() for s in agent_statuses): + all_done = all(s.state == "done" for s in agent_statuses) + any_failed = any(s.state == "failed" for s in agent_statuses) + if all_done or any_failed: break - - if any(s.is_failed() for s in agent_statuses): - raise RuntimeError() - except: - raise finally: ctx.close() + sys.stdout.flush() + sys.stderr.flush() diff --git a/src/torchrunx/environment.py b/src/torchrunx/environment.py index 560d62cc..179cfb8d 100644 --- a/src/torchrunx/environment.py +++ b/src/torchrunx/environment.py @@ -17,7 +17,9 @@ def slurm_hosts() -> list[str]: :rtype: list[str] """ # TODO: sanity check SLURM variables, commands - assert in_slurm_job() + if not in_slurm_job(): + msg = "Not in a SLURM job" + raise RuntimeError(msg) return ( subprocess.check_output(["scontrol", "show", "hostnames", os.environ["SLURM_JOB_NODELIST"]]) .decode() @@ -35,13 +37,18 @@ def slurm_workers() -> int: :rtype: int """ # TODO: sanity check SLURM variables, commands - assert in_slurm_job() + if not in_slurm_job(): + msg = "Not in a SLURM job" + raise RuntimeError(msg) + if "SLURM_JOB_GPUS" in os.environ: # TODO: is it possible to allocate uneven GPUs across nodes? return len(os.environ["SLURM_JOB_GPUS"].split(",")) - else: - # TODO: should we assume that we plan to do one worker per CPU? - return int(os.environ["SLURM_CPUS_ON_NODE"]) + if "SLURM_GPUS_PER_NODE" in os.environ: + return int(os.environ["SLURM_GPUS_PER_NODE"]) + + # TODO: should we assume that we plan to do one worker per CPU? + return int(os.environ["SLURM_CPUS_ON_NODE"]) def auto_hosts() -> list[str]: @@ -52,7 +59,7 @@ def auto_hosts() -> list[str]: :rtype: list[str] """ if in_slurm_job(): - slurm_hosts() + return slurm_hosts() return ["localhost"] diff --git a/src/torchrunx/launcher.py b/src/torchrunx/launcher.py index 62182ca4..fa73ae04 100644 --- a/src/torchrunx/launcher.py +++ b/src/torchrunx/launcher.py @@ -1,35 +1,127 @@ from __future__ import annotations -import datetime import fnmatch -import io import ipaddress import itertools +import logging import os +import shlex import socket import subprocess import sys -import time -from collections import ChainMap -from dataclasses import dataclass, field +from dataclasses import dataclass from functools import partial +from logging import Handler from multiprocessing import Process from pathlib import Path -from typing import Any, Callable, Literal +from typing import Any, Callable, Literal, Sequence import fabric import torch.distributed as dist -from .environment import auto_hosts, auto_workers +from .environment import auto_hosts, auto_workers, slurm_hosts, slurm_workers +from .logging_utils import LogRecordSocketReceiver, default_handlers from .utils import ( - AgentPayload, - AgentStatus, LauncherAgentGroup, LauncherPayload, + WorkerException, get_open_port, ) +def resolve_hostnames(hostnames: list[str] | Literal["auto", "slurm"]) -> list[str]: + if hostnames == "auto": + return auto_hosts() + if hostnames == "slurm": + return slurm_hosts() + return hostnames + + +def resolve_workers_per_host( + workers_per_host: int | list[int] | Literal["auto", "slurm"], + num_hosts: int, +) -> list[int]: + if workers_per_host == "auto": + workers_per_host = auto_workers() + elif workers_per_host == "slurm": + workers_per_host = slurm_workers() + + if isinstance(workers_per_host, int): + workers_per_host = [workers_per_host] * num_hosts + elif len(workers_per_host) != num_hosts: + msg = "len(workers_per_host) != len(hostnames)" + raise ValueError(msg) + + return workers_per_host + + +def build_logging_server( + log_handlers: list[Handler] | Literal["auto"] | None, + launcher_hostname: str, + hostnames: list[str], + workers_per_host: list[int], + log_dir: str | os.PathLike, + log_level: int, +) -> LogRecordSocketReceiver: + if log_handlers is None: + log_handlers = [] + elif log_handlers == "auto": + log_handlers = default_handlers( + hostnames=hostnames, + workers_per_host=workers_per_host, + log_dir=log_dir, + log_level=log_level, + ) + + return LogRecordSocketReceiver( + host=launcher_hostname, + port=get_open_port(), + handlers=log_handlers, + ) + + +def build_command( + launcher_hostname: str, + launcher_port: int, + logger_port: int, + world_size: int, + rank: int, + env_vars: Sequence[str], + env_file: str | os.PathLike | None, +) -> str: + # shlex.quote prevents shell injection here (resolves S602 in execute_command) + + commands = [] + + current_dir = shlex.quote(str(Path.cwd())) + commands.append("cd " + current_dir) + + env_exports = [] + for k, v in os.environ.items(): + if any(fnmatch.fnmatch(k, e) for e in env_vars): + env_exports.append(shlex.quote(f"{k}={v}")) + + if len(env_exports) > 0: + commands.append("export " + " ".join(env_exports)) + + if env_file is not None: + commands.append("source " + shlex.quote(str(env_file))) + + python = shlex.quote(sys.executable) + launcher_hostname = shlex.quote(launcher_hostname) + + commands.append( + f"{python} -u -m torchrunx " + f"--launcher-hostname {launcher_hostname} " + f"--launcher-port {launcher_port} " + f"--logger-port {logger_port} " + f"--world-size {world_size} " + f"--rank {rank}", + ) + + return " && ".join(commands) + + def is_localhost(hostname_or_ip: str) -> bool: # check if host is "loopback" address (i.e. designated to send to self) try: @@ -48,64 +140,45 @@ def execute_command( command: str, hostname: str, ssh_config_file: str | os.PathLike | None = None, - outfile: str | os.PathLike | None = None, ) -> None: - # TODO: permit different stderr / stdout if is_localhost(hostname): - _outfile = subprocess.DEVNULL - if outfile is not None: - _outfile = open(outfile, "w") - subprocess.Popen(command, shell=True, stdout=_outfile, stderr=_outfile) + # S602: subprocess.Popen is called with shell=True (https://docs.python.org/3.8/library/subprocess.html#security-considerations) + # Made sure to shlex.quote arguments in build_command to prevent shell injection + subprocess.Popen(command, shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) # noqa: S602 else: with fabric.Connection( - host=hostname, config=fabric.Config(runtime_ssh_path=ssh_config_file) + host=hostname, + config=fabric.Config(runtime_ssh_path=ssh_config_file), ) as conn: - if outfile is None: - outfile = "/dev/null" - conn.run(f"{command} >> {outfile} 2>&1 &", asynchronous=True) - - -def monitor_log(log_file: Path): - log_file.touch() - f = open(log_file, "r") - print(f.read()) - f.seek(0, io.SEEK_END) - while True: - new = f.read() - if len(new) != 0: - print(new) - time.sleep(0.1) + conn.run(f"{command} >> /dev/null 2>&1 &", asynchronous=True) @dataclass class Launcher: - auto: bool = False - hostnames: list[str] | None = field(default_factory=lambda: ["localhost"]) - workers_per_host: int | list[int] | None = 1 + hostnames: list[str] | Literal["auto", "slurm"] = "auto" + workers_per_host: int | list[int] | Literal["auto", "slurm"] = "auto" ssh_config_file: str | os.PathLike | None = None backend: Literal["mpi", "gloo", "nccl", "ucc", None] = None - log_dir: os.PathLike | str = "./logs" - env_vars: list[str] = field( - default_factory=lambda: [ - "PATH", - "LD_LIBRARY", - "LIBRARY_PATH", - "PYTHON*", - "CUDA*", - "TORCH*", - "PYTORCH*", - "NCCL*", - ] + log_handlers: list[Handler] | Literal["auto"] | None = "auto" + env_vars: Sequence[str] = ( + "PATH", + "LD_LIBRARY", + "LIBRARY_PATH", + "PYTHON*", + "CUDA*", + "TORCH*", + "PYTORCH*", + "NCCL*", ) env_file: str | os.PathLike | None = None timeout: int = 600 - def run( + def run( # noqa: C901, PLR0912 self, func: Callable, - func_args: tuple[Any] = tuple(), - func_kwargs: dict[str, Any] = {}, - ) -> dict[int, Any]: + func_args: tuple[Any] | None = None, + func_kwargs: dict[str, Any] | None = None, + ) -> dict[str, dict[int, Any]]: """ Launch a distributed PyTorch function on the specified nodes. See :mod:`torchrunx.launch` @@ -119,166 +192,137 @@ def run( :return: A dictionary mapping worker ranks to their output :rtype: dict[int, Any] """ - - if self.auto: - if self.hostnames is None: - self.hostnames = auto_hosts() - if self.workers_per_host is None: - self.workers_per_host = auto_workers() - - assert self.hostnames is not None and self.workers_per_host is not None - if not dist.is_available(): - raise RuntimeError("The torch.distributed package is not available.") - - num_hosts = len(self.hostnames) + msg = "The torch.distributed package is not available." + raise RuntimeError(msg) - workers_per_host = self.workers_per_host - if isinstance(self.workers_per_host, int): - workers_per_host = [workers_per_host] * num_hosts + hostnames = resolve_hostnames(self.hostnames) + workers_per_host = resolve_workers_per_host(self.workers_per_host, len(hostnames)) - assert workers_per_host is not None - assert len(workers_per_host) == num_hosts # type: ignore + launcher_hostname = socket.getfqdn() + launcher_port = get_open_port() + world_size = len(hostnames) + 1 - # launch command + log_receiver = None + log_process = None + launcher_agent_group = None + agent_payloads = None - env_exports = [] - for k, v in os.environ.items(): - if any(fnmatch.fnmatch(k, e) for e in self.env_vars): - env_exports.append(f"{k}={v}") + try: + # start logging server + + log_receiver = build_logging_server( + log_handlers=self.log_handlers, + launcher_hostname=launcher_hostname, + hostnames=hostnames, + workers_per_host=workers_per_host, + log_dir=Path(os.environ.get("TORCHRUNX_LOG_DIR", "torchrunx_logs")), + log_level=logging._nameToLevel[os.environ.get("TORCHRUNX_LOG_LEVEL", "INFO")], # noqa: SLF001 + ) - env_export_string = "" - if len(env_exports) > 0: - env_export_string = f"export {' '.join(env_exports)} && " + log_process = Process( + target=log_receiver.serve_forever, + daemon=True, + ) - env_file_string = "" - if self.env_file is not None: - env_file_string = f"source {self.env_file} && " + log_process.start() - launcher_hostname = socket.getfqdn() - launcher_port = get_open_port() - world_size = num_hosts + 1 # launcher + agents - - command = ( - f"cd {os.getcwd()} && " - f"{env_export_string}" - f"{env_file_string}" - f"{sys.executable} -u -m torchrunx " - f"--launcher-hostname {launcher_hostname} " - f"--launcher-port {launcher_port} " - f"--world-size {world_size} " - # rank set in the loop below - ) + # start agents on each node - log_dir = Path(self.log_dir) - log_dir.mkdir(parents=True, exist_ok=True) - timestamp = datetime.datetime.now().isoformat(timespec="seconds") - agent_log_files = [log_dir / f"{timestamp}_{hostname}.log" for hostname in self.hostnames] - - # start process to read from agent 0 log - print_process = Process(target=monitor_log, args=(agent_log_files[0],), daemon=True) - print_process.start() - - # start agents on each node - for i, hostname in enumerate(self.hostnames): - execute_command( - command=f"{command} --rank {i+1}", - hostname=hostname, - ssh_config_file=self.ssh_config_file, - outfile=agent_log_files[i], - ) + for i, hostname in enumerate(hostnames): + execute_command( + command=build_command( + launcher_hostname=launcher_hostname, + launcher_port=launcher_port, + logger_port=log_receiver.port, + world_size=world_size, + rank=i + 1, + env_vars=self.env_vars, + env_file=self.env_file, + ), + hostname=hostname, + ssh_config_file=self.ssh_config_file, + ) - # initialize launcher–agent process group - # ranks = (launcher, agent_0, ..., agent_{num_hosts-1}) + # initialize launcher-agent process group + # ranks = (launcher, agent_{hostnames[0]}, ..., agent[-1]) - launcher_agent_group = LauncherAgentGroup( - launcher_hostname=launcher_hostname, - launcher_port=launcher_port, - world_size=world_size, - rank=0, - ) + launcher_agent_group = LauncherAgentGroup( + launcher_hostname=launcher_hostname, + launcher_port=launcher_port, + world_size=world_size, + rank=0, + ) - # build and sync payloads between launcher and agents + # build and sync payloads between launcher and agents - _cumulative_workers = [0] + list(itertools.accumulate(workers_per_host)) # type: ignore + _cumulative_workers = [0, *itertools.accumulate(workers_per_host)] - worker_world_size = _cumulative_workers[-1] + worker_global_ranks = [ + list(range(_cumulative_workers[n], _cumulative_workers[n + 1])) + for n in range(len(hostnames)) + ] - worker_global_ranks = [] # list of worker ranks per host - for n in range(num_hosts): - host_ranks = range(_cumulative_workers[n], _cumulative_workers[n + 1]) - worker_global_ranks.append(list(host_ranks)) + payload = LauncherPayload( + fn=partial(func, *(func_args or ()), **(func_kwargs or {})), + hostnames=hostnames, + worker_global_ranks=worker_global_ranks, + worker_world_size=sum(workers_per_host), + backend=self.backend, + timeout=self.timeout, + ) - worker_log_files = [ - [ - log_dir / f"{timestamp}_{hostname}_{local_rank}.log" - for local_rank in range(workers_per_host[i]) # type: ignore - ] - for i, hostname in enumerate(self.hostnames) - ] - - payload = LauncherPayload( - fn=partial(func, *func_args, **func_kwargs), - hostnames=self.hostnames, - worker_world_size=worker_world_size, - worker_global_ranks=worker_global_ranks, - worker_log_files=worker_log_files, - backend=self.backend, - timeout=self.timeout, - ) + launcher_payload, agent_payloads = launcher_agent_group.sync_payloads(payload=payload) - agent_payloads: list[AgentPayload] = launcher_agent_group.sync_payloads(payload=payload)[1:] # pyright: ignore[reportAssignmentType] - agent_pids = [p.process_id for p in agent_payloads] + # loop to monitor agent statuses (until failed or done) - # loop to monitor agent statuses (until failed or done) - try: while True: - agent_statuses = launcher_agent_group.sync_agent_statuses(status=AgentStatus()) + # raises RuntimeError if communication timeout due to death of any agent + agent_statuses = launcher_agent_group.sync_agent_statuses(status=None) - if all(s.is_done() for s in agent_statuses): + # raises specific exception if any agent fails + for s in agent_statuses: + for value in s.return_values.values(): + if isinstance(value, WorkerException): + raise value.exception + + if all(s.state == "done" for s in agent_statuses): break + finally: + if log_receiver is not None: + log_receiver.shutdown() + if log_process is not None: + log_receiver.server_close() + log_process.kill() + + if launcher_agent_group is not None: + launcher_agent_group.shutdown() - if any(s.is_failed() for s in agent_statuses): - # TODO: cleaner way to print these? - e = "" - for i, s in enumerate(agent_statuses): - if s is not None and s.is_failed(): - for k, v in s.failures.items(): - e += f"Node {i}, local worker {k} exited with error: " - if isinstance(v.message, str): - e += f"{v.message}\n" - else: - e += f"{v.message['message']}\n" - e += f"{v.message['extraInfo']['py_callstack']}\n\n" - raise RuntimeError(e) - except: # cleanup: SIGTERM all agents - for agent_pid, agent_hostname in zip(agent_pids, self.hostnames): - execute_command( - command=f"kill {agent_pid}", - hostname=agent_hostname, - ssh_config_file=self.ssh_config_file, - ) - raise - finally: - print_process.kill() - dist.destroy_process_group() + if agent_payloads is not None: + for agent_payload, agent_hostname in zip(agent_payloads, hostnames): + execute_command( + command=f"kill {agent_payload.process_id}", + hostname=agent_hostname, + ssh_config_file=self.ssh_config_file, + ) - return_values: dict[int, Any] = dict(ChainMap(*[s.return_values for s in agent_statuses])) - return return_values + return { + hostname: agent_status.return_values + for hostname, agent_status in zip(hostnames, agent_statuses) + } def launch( func: Callable, - func_args: tuple[Any] = tuple(), - func_kwargs: dict[str, Any] = {}, - auto: bool = False, - hostnames: list[str] | None = ["localhost"], - workers_per_host: int | list[int] | None = 1, + func_args: tuple[Any] | None = None, + func_kwargs: dict[str, Any] | None = None, + hostnames: list[str] | Literal["auto", "slurm"] = "auto", + workers_per_host: int | list[int] | Literal["auto", "slurm"] = "auto", ssh_config_file: str | os.PathLike | None = None, backend: Literal["mpi", "gloo", "nccl", "ucc", None] = None, - log_dir: os.PathLike | str = "./logs", - env_vars: list[str] = [ + log_handlers: list[Handler] | Literal["auto"] = "auto", + env_vars: Sequence[str] = ( "PATH", "LD_LIBRARY", "LIBRARY_PATH", @@ -287,10 +331,10 @@ def launch( "TORCH*", "PYTORCH*", "NCCL*", - ], + ), env_file: str | os.PathLike | None = None, timeout: int = 600, -) -> dict[int, Any]: +) -> dict[str, dict[int, Any]]: """ Launch a distributed PyTorch function on the specified nodes. @@ -303,15 +347,15 @@ def launch( :param auto: Automatically determine allocation sizes, supports Slurm allocation. ``hostnames`` and ``workers_per_host`` are automatically assigned if they're set to ``None``, defaults to None :type auto: bool, optional :param hostnames: A list of node hostnames to start workers on, defaults to ["localhost"] - :type hostnames: list[str] | None, optional + :type hostnames: list[str] | Literal["auto", "slurm"] | None, optional :param workers_per_host: The number of workers per node. Providing an ``int`` implies all nodes should have ``workers_per_host`` workers, meanwhile providing a list causes node ``i`` to have ``worker_per_host[i]`` workers, defaults to 1 - :type workers_per_host: int | list[int] | None, optional + :type workers_per_host: int | list[int] | Literal["auto", "slurm"] | None, optional :param ssh_config_file: An SSH configuration file to use when connecting to nodes, defaults to None :type ssh_config_file: str | os.PathLike | None, optional :param backend: A ``torch.distributed`` `backend string `_, defaults to None :type backend: Literal['mpi', 'gloo', 'nccl', 'ucc', None], optional - :param log_dir: A directory in which logs should be written, defaults to "./logs" - :type log_dir: os.PathLike | str, optional + :param log_handlers: A list of handlers to manage agent and worker logs, defaults to [] + :type log_handlers: list[Handler] | Literal["auto"], optional :param env_vars: A list of environmental variables to be copied from the launcher environment to workers. Allows for bash pattern matching syntax, defaults to ["PATH", "LD_LIBRARY", "LIBRARY_PATH", "PYTHON*", "CUDA*", "TORCH*", "PYTORCH*", "NCCL*"] :type env_vars: list[str], optional :param env_file: An additional environment file that will be sourced prior to executing ``func``, defaults to None @@ -323,12 +367,11 @@ def launch( :rtype: dict[int, Any] """ # noqa: E501 return Launcher( - auto=auto, hostnames=hostnames, workers_per_host=workers_per_host, ssh_config_file=ssh_config_file, backend=backend, - log_dir=log_dir, + log_handlers=log_handlers, env_vars=env_vars, env_file=env_file, timeout=timeout, diff --git a/src/torchrunx/logging_utils.py b/src/torchrunx/logging_utils.py new file mode 100644 index 00000000..d12b27f7 --- /dev/null +++ b/src/torchrunx/logging_utils.py @@ -0,0 +1,193 @@ +from __future__ import annotations + +import datetime +import logging +import pickle +import struct +from contextlib import redirect_stderr, redirect_stdout +from dataclasses import dataclass +from io import StringIO +from logging import Handler, Logger +from logging.handlers import SocketHandler +from pathlib import Path +from socketserver import StreamRequestHandler, ThreadingTCPServer +from typing import TYPE_CHECKING + +from typing_extensions import Self + +if TYPE_CHECKING: + import os + +## Launcher utilities + + +class LogRecordSocketReceiver(ThreadingTCPServer): + def __init__(self, host: str, port: int, handlers: list[Handler]) -> None: + self.host = host + self.port = port + + class _LogRecordStreamHandler(StreamRequestHandler): + def handle(self) -> None: + while True: + chunk_size = 4 + chunk = self.connection.recv(chunk_size) + if len(chunk) < chunk_size: + break + slen = struct.unpack(">L", chunk)[0] + chunk = self.connection.recv(slen) + while len(chunk) < slen: + chunk = chunk + self.connection.recv(slen - len(chunk)) + obj = pickle.loads(chunk) + record = logging.makeLogRecord(obj) + + for handler in handlers: + handler.handle(record) + + super().__init__( + server_address=(host, port), + RequestHandlerClass=_LogRecordStreamHandler, + bind_and_activate=True, + ) + self.daemon_threads = True + + def shutdown(self) -> None: + """override BaseServer.shutdown() with added timeout""" + self._BaseServer__shutdown_request = True + self._BaseServer__is_shut_down.wait(timeout=3) # pyright: ignore[reportAttributeAccessIssue] + + +## Agent/worker utilities + + +@dataclass +class WorkerLogRecord(logging.LogRecord): + hostname: str + worker_rank: int | None + + @classmethod + def from_record(cls, record: logging.LogRecord, hostname: str, worker_rank: int | None) -> Self: + record.hostname = hostname + record.worker_rank = worker_rank + record.__class__ = cls + return record # pyright: ignore [reportReturnType] + + +def log_records_to_socket( + logger: Logger, + hostname: str, + worker_rank: int | None, + logger_hostname: str, + logger_port: int, +) -> None: + logger.setLevel(logging.NOTSET) + + old_factory = logging.getLogRecordFactory() + + def record_factory(*args, **kwargs) -> WorkerLogRecord: # noqa: ANN002, ANN003 + record = old_factory(*args, **kwargs) + return WorkerLogRecord.from_record(record, hostname, worker_rank) + + logging.setLogRecordFactory(record_factory) + + logger.addHandler(SocketHandler(host=logger_hostname, port=logger_port)) + + +def redirect_stdio_to_logger(logger: Logger) -> None: + class _LoggingStream(StringIO): + def __init__(self, logger: Logger, level: int = logging.NOTSET) -> None: + super().__init__() + self.logger = logger + self.level = level + + def flush(self) -> None: + super().flush() + value = self.getvalue() + if value != "": + self.logger.log(self.level, value) + self.truncate(0) + self.seek(0) + + logging.captureWarnings(capture=True) + redirect_stderr(_LoggingStream(logger, level=logging.ERROR)).__enter__() + redirect_stdout(_LoggingStream(logger, level=logging.INFO)).__enter__() + + +## Handler utilities + + +def add_filter_to_handler( + handler: Handler, + hostname: str, + worker_rank: int | None, + log_level: int = logging.NOTSET, +) -> None: + def _filter(record: WorkerLogRecord) -> bool: + return ( + record.hostname == hostname + and record.worker_rank == worker_rank + and record.levelno >= log_level + ) + + handler.addFilter(_filter) # pyright: ignore [reportArgumentType] + + +def stream_handler(hostname: str, rank: int | None, log_level: int = logging.NOTSET) -> Handler: + handler = logging.StreamHandler() + add_filter_to_handler(handler, hostname, rank, log_level=log_level) + handler.setFormatter( + logging.Formatter( + "%(asctime)s:%(levelname)s:%(hostname)s[%(worker_rank)s]: %(message)s" + if rank is not None + else "%(asctime)s:%(levelname)s:%(hostname)s: %(message)s", + ), + ) + return handler + + +def file_handler( + hostname: str, + worker_rank: int | None, + file_path: str | os.PathLike, + log_level: int = logging.NOTSET, +) -> Handler: + handler = logging.FileHandler(file_path) + add_filter_to_handler(handler, hostname, worker_rank, log_level=log_level) + formatter = logging.Formatter("%(asctime)s:%(levelname)s: %(message)s") + handler.setFormatter(formatter) + return handler + + +def file_handlers( + hostnames: list[str], + workers_per_host: list[int], + log_dir: str | os.PathLike = Path("torchrunx_logs"), + log_level: int = logging.NOTSET, +) -> list[Handler]: + handlers = [] + + Path(log_dir).mkdir(parents=True, exist_ok=True) + timestamp = datetime.datetime.now().isoformat(timespec="seconds") + + for hostname, num_workers in zip(hostnames, workers_per_host): + for rank in [None, *range(num_workers)]: + file_path = ( + f"{log_dir}/{timestamp}-{hostname}" + + (f"[{rank}]" if rank is not None else "") + + ".log" + ) + handlers.append(file_handler(hostname, rank, file_path, log_level=log_level)) + + return handlers + + +def default_handlers( + hostnames: list[str], + workers_per_host: list[int], + log_dir: str | os.PathLike = Path("torchrunx_logs"), + log_level: int = logging.INFO, +) -> list[Handler]: + return [ + stream_handler(hostname=hostnames[0], rank=None, log_level=log_level), + stream_handler(hostname=hostnames[0], rank=0, log_level=log_level), + *file_handlers(hostnames, workers_per_host, log_dir=log_dir, log_level=log_level), + ] diff --git a/src/torchrunx/utils.py b/src/torchrunx/utils.py index 09bd2466..0fafec9d 100644 --- a/src/torchrunx/utils.py +++ b/src/torchrunx/utils.py @@ -4,30 +4,33 @@ import socket from contextlib import closing from dataclasses import dataclass, field -from pathlib import Path -from typing import Any, Callable, Literal +from typing import TYPE_CHECKING, Any, Callable, Literal import cloudpickle import torch.distributed as dist -from torch.distributed.elastic.multiprocessing.api import RunProcsResult -from torch.distributed.elastic.multiprocessing.errors import ProcessFailure from typing_extensions import Self +if TYPE_CHECKING: + from torch.distributed.elastic.multiprocessing.api import RunProcsResult + def get_open_port() -> int: with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s: s.bind(("", 0)) - port = s.getsockname()[1] - return port + return s.getsockname()[1] + + +@dataclass +class WorkerException: + exception: Exception @dataclass class LauncherPayload: fn: Callable hostnames: list[str] - worker_world_size: int worker_global_ranks: list[list[int]] - worker_log_files: list[list[Path]] + worker_world_size: int backend: Literal["mpi", "gloo", "nccl", "ucc", None] timeout: int @@ -41,33 +44,25 @@ class AgentPayload: @dataclass class AgentStatus: - running: bool = True - failed: bool = False - return_values: dict[int, Any] = field(default_factory=dict) - failures: dict[int, ProcessFailure] = field(default_factory=dict) - stdouts: dict[int, str] = field(default_factory=dict) - stderrs: dict[int, str] = field(default_factory=dict) + state: Literal["running", "failed", "done"] + return_values: dict[int, Any | WorkerException] = field(default_factory=dict) @classmethod - def from_result(cls, result: RunProcsResult | None, worker_global_ranks: list[int]) -> Self: + def from_result(cls, result: RunProcsResult | None) -> Self: if result is None: - return cls() + return cls(state="running") - return cls( - running=False, - failed=result.is_failed(), - return_values={worker_global_ranks[k]: v for k, v in result.return_values.items()}, - failures={worker_global_ranks[k]: v for k, v in result.failures.items()}, - ) - - def is_running(self) -> bool: - return self.running + return_values = result.return_values - def is_failed(self) -> bool: - return self.failed + if any(isinstance(v, WorkerException) for v in return_values.values()): + state = "failed" + else: + state = "done" - def is_done(self) -> bool: - return not self.running and not self.failed + return cls( + state=state, + return_values=return_values, + ) @dataclass @@ -78,11 +73,12 @@ class LauncherAgentGroup: rank: int def __post_init__(self) -> None: + # timeout will raise torch.distributed.DistStoreError self.group = dist.init_process_group( backend="gloo", world_size=self.world_size, rank=self.rank, - store=dist.TCPStore( # pyright: ignore[reportPrivateImportUsage] + store=dist.TCPStore( # pyright: ignore [reportPrivateImportUsage] host_name=self.launcher_hostname, port=self.launcher_port, world_size=self.world_size, @@ -91,24 +87,31 @@ def __post_init__(self) -> None: timeout=datetime.timedelta(seconds=30), ) - def _serialize(self, object: Any) -> bytes: - return cloudpickle.dumps(object) + def _serialize(self, obj: Any) -> bytes: + return cloudpickle.dumps(obj) def _deserialize(self, serialized: bytes) -> Any: return cloudpickle.loads(serialized) - def _all_gather(self, object: Any) -> list: + def _all_gather(self, obj: Any) -> list: """gather object from every rank to list on every rank""" - object_bytes = self._serialize(object) - object_list = [bytes()] * self.world_size + object_bytes = self._serialize(obj) + object_list = [b""] * self.world_size + # raises RuntimeError if timeout dist.all_gather_object(object_list=object_list, obj=object_bytes, group=self.group) - object_list = [self._deserialize(o) for o in object_list] - return object_list + return [self._deserialize(o) for o in object_list] def sync_payloads( - self, payload: LauncherPayload | AgentPayload - ) -> list[LauncherPayload | AgentPayload]: - return self._all_gather(object=payload) - - def sync_agent_statuses(self, status: AgentStatus) -> list[AgentStatus]: - return self._all_gather(object=status)[1:] + self, + payload: LauncherPayload | AgentPayload, + ) -> tuple[LauncherPayload, list[AgentPayload]]: + payloads = self._all_gather(payload) + launcher_payload = payloads[0] + agent_payloads = payloads[1:] + return launcher_payload, agent_payloads + + def sync_agent_statuses(self, status: AgentStatus | None) -> list[AgentStatus]: + return self._all_gather(status)[1:] # [0] is launcher (status=None) + + def shutdown(self) -> None: + dist.destroy_process_group(group=self.group) diff --git a/tests/pytest.ini b/tests/pytest.ini deleted file mode 100644 index 85f8d824..00000000 --- a/tests/pytest.ini +++ /dev/null @@ -1,2 +0,0 @@ -[pytest] -#python_paths = /users/pcurtin1/torchrunx/src diff --git a/tests/test_CI.py b/tests/test_CI.py deleted file mode 100644 index 6ccb6a0b..00000000 --- a/tests/test_CI.py +++ /dev/null @@ -1,75 +0,0 @@ -import os -import tempfile - -import pytest -import torch -import torch.distributed as dist - -import torchrunx as trx - - -def test_simple_localhost(): - def dist_func(): - rank = int(os.environ["RANK"]) - - if rank == 0: - w = torch.rand((100, 100)) # in_dim, out_dim - else: - w = torch.zeros((100, 100)) - - dist.broadcast(w, 0) - - i = torch.rand((500, 100)) # batch, dim - o = torch.matmul(i, w) - - dist.all_reduce(o, op=dist.ReduceOp.SUM) - - print(i) - - return o.detach() - - r = trx.launch( - func=dist_func, func_kwargs={}, workers_per_host=2, backend="gloo", log_dir="./test_logs" - ) - - assert torch.all(r[0] == r[1]) - - -def test_logging(): - def dist_func(): - rank = int(os.environ["RANK"]) - print(f"worker rank: {rank}") - - tmp = tempfile.mkdtemp() - trx.launch(func=dist_func, func_kwargs={}, workers_per_host=2, backend="gloo", log_dir=tmp) - - log_files = next(os.walk(tmp), (None, None, []))[2] - - assert len(log_files) == 3 - - for file in log_files: - with open(f"{tmp}/{file}", "r") as f: - if file.endswith("0.log"): - assert f.read() == "worker rank: 0\n" - elif file.endswith("1.log"): - assert f.read() == "worker rank: 1\n" - else: - contents = f.read() - assert "worker rank: 0" in contents - assert "worker rank: 1" in contents - - -def test_error(): - def error_func(): - raise ValueError("abcdefg") - - with pytest.raises(RuntimeError) as excinfo: - trx.launch( - func=error_func, - func_kwargs={}, - workers_per_host=1, - backend="gloo", - log_dir=tempfile.mkdtemp(), - ) - - assert "abcdefg" in str(excinfo.value) diff --git a/tests/test_ci.py b/tests/test_ci.py new file mode 100644 index 00000000..f72f3ef4 --- /dev/null +++ b/tests/test_ci.py @@ -0,0 +1,95 @@ +import os +import tempfile +from pathlib import Path +from typing import NoReturn + +import pytest +import torch +import torch.distributed as dist + +import torchrunx as trx + + +def test_simple_localhost() -> None: + def dist_func() -> torch.Tensor: + rank = int(os.environ["RANK"]) + + w = torch.rand((100, 100)) if rank == 0 else torch.zeros((100, 100)) + + dist.broadcast(w, 0) + + i = torch.rand((500, 100)) # batch, dim + o = torch.matmul(i, w) + + dist.all_reduce(o, op=dist.ReduceOp.SUM) + + print(i) + + return o.detach() + + tmp = tempfile.mkdtemp() + os.environ["TORCHRUNX_DIR"] = tmp + + r = trx.launch( + func=dist_func, + func_kwargs={}, + workers_per_host=2, + backend="gloo", # log_dir="./test_logs" + ) + + results = next(iter(r.values())) + assert torch.all(results[0] == results[1]) + + +def test_logging() -> None: + def dist_func() -> None: + rank = int(os.environ["RANK"]) + print(f"worker rank: {rank}") + + tmp = tempfile.mkdtemp() + os.environ["TORCHRUNX_LOG_DIR"] = tmp + + num_workers = 2 + + trx.launch( + func=dist_func, + func_kwargs={}, + workers_per_host=num_workers, + backend="gloo", + ) + + log_files = next(os.walk(tmp), (None, None, []))[2] + + assert len(log_files) == num_workers + 1 + + for file in log_files: + with Path(f"{tmp}/{file}").open() as f: + contents = f.read() + print(contents) + if file.endswith("[0].log"): + assert "worker rank: 0\n" in contents + elif file.endswith("[1].log"): + assert "worker rank: 1\n" in contents + + +def test_error() -> None: + def error_func() -> NoReturn: + msg = "abcdefg" + raise ValueError(msg) + + tmp = tempfile.mkdtemp() + os.environ["TORCHRUNX_DIR"] = tmp + + with pytest.raises(ValueError) as excinfo: # noqa: PT011 + trx.launch( + func=error_func, + func_kwargs={}, + workers_per_host=1, + backend="gloo", + ) + + assert "abcdefg" in str(excinfo.value) + + +if __name__ == "__main__": + test_simple_localhost() diff --git a/tests/test_func.py b/tests/test_func.py index 890987b6..8fb264bf 100644 --- a/tests/test_func.py +++ b/tests/test_func.py @@ -6,21 +6,23 @@ import torchrunx as trx -def test_launch(): +def test_launch() -> None: result = trx.launch( func=simple_matmul, - hostnames=trx.slurm_hosts(), - workers_per_host=trx.slurm_workers(), + hostnames="slurm", + workers_per_host="slurm", ) + result_values = [v for host_results in result.values() for v in host_results.values()] + t = True - for i in range(len(result)): - t = t and torch.all(result[i] == result[0]) + for i in range(len(result_values)): + t = t and torch.all(result_values[i] == result_values[0]) assert t, "Not all tensors equal" -def simple_matmul(): +def simple_matmul() -> torch.Tensor: rank = int(os.environ["RANK"]) local_rank = int(os.environ["LOCAL_RANK"]) device = torch.device(local_rank) if torch.cuda.is_available() else torch.device("cpu") diff --git a/tests/test_submitit.py b/tests/test_submitit.py index 53aaf5cc..433e3382 100644 --- a/tests/test_submitit.py +++ b/tests/test_submitit.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import copy import submitit @@ -9,22 +11,22 @@ class DummyDataset(Dataset): - def __init__(self, max_text_length=16, num_samples=20000) -> None: + def __init__(self, max_text_length: int = 16, num_samples: int = 20000) -> None: super().__init__() self.input_ids = torch.randint(0, 30522, (num_samples, max_text_length)) self.labels = copy.deepcopy(self.input_ids) - def __len__(self): + def __len__(self) -> int: return len(self.input_ids) - def __getitem__(self, index): + def __getitem__(self, index: int) -> dict[str, torch.Tensor]: return { "input_ids": self.input_ids[index], "labels": self.labels[index], } -def main(): +def main() -> None: model = BertForMaskedLM.from_pretrained("bert-base-uncased") train_dataset = DummyDataset() @@ -38,7 +40,7 @@ def main(): ) trainer = Trainer( - model=model, # type: ignore + model=model, args=training_arguments, train_dataset=train_dataset, ) @@ -46,13 +48,11 @@ def main(): trainer.train() -def launch(): - trx.launch( - func=main, func_kwargs={}, hostnames=trx.slurm_hosts(), workers_per_host=trx.slurm_workers() - ) +def launch() -> None: + trx.launch(func=main, func_kwargs={}, hostnames="slurm", workers_per_host="slurm") -def test_submitit(): +def test_submitit() -> None: executor = submitit.SlurmExecutor(folder="logs") executor.update_parameters( diff --git a/tests/test_train.py b/tests/test_train.py index 8a0b2a55..b654a8b7 100644 --- a/tests/test_train.py +++ b/tests/test_train.py @@ -3,23 +3,21 @@ import torchrunx as trx -def worker(): +def worker() -> None: import torch - class TwoLinLayerNet(torch.nn.Module): - def __init__(self): + class MLP(torch.nn.Module): + def __init__(self) -> None: super().__init__() self.a = torch.nn.Linear(10, 10, bias=False) self.b = torch.nn.Linear(10, 1, bias=False) - def forward(self, x): - a = self.a(x) - b = self.b(x) - return (a, b) + def forward(self, x: torch.Tensor) -> torch.Tensor: + return self.b(self.a(x)) local_rank = int(os.environ["LOCAL_RANK"]) print("init model") - model = TwoLinLayerNet().to(local_rank) + model = MLP().to(local_rank) print("init ddp") ddp_model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[local_rank]) @@ -28,15 +26,15 @@ def forward(self, x): for _ in range(20): output = ddp_model(inp) - loss = output[0] + output[1] - loss.sum().backward() + loss = output.sum() + loss.backward() -def test_distributed_train(): +def test_distributed_train() -> None: trx.launch( worker, - hostnames=trx.slurm_hosts(), - workers_per_host=trx.slurm_workers(), + hostnames="slurm", + workers_per_host="slurm", backend="nccl", )