{"id":24905885,"url":"https://github.com/microsoft/scala_torch","last_synced_at":"2025-10-16T16:32:06.654Z","repository":{"id":62848080,"uuid":"555081440","full_name":"microsoft/scala_torch","owner":"microsoft","description":"Scala bindings for LibTorch","archived":false,"fork":false,"pushed_at":"2022-11-10T19:03:34.000Z","size":192,"stargazers_count":125,"open_issues_count":3,"forks_count":7,"subscribers_count":10,"default_branch":"main","last_synced_at":"2025-01-31T16:24:35.489Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/microsoft.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null}},"created_at":"2022-10-20T23:17:12.000Z","updated_at":"2025-01-11T15:38:43.000Z","dependencies_parsed_at":"2022-11-07T21:30:42.832Z","dependency_job_id":null,"html_url":"https://github.com/microsoft/scala_torch","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microsoft%2Fscala_torch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microsoft%2Fscala_torch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microsoft%2Fscala_torch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microsoft%2Fscala_torch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/microsoft","download_url":"https://codeload.github.com/microsoft/scala_torch/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":236737110,"owners_count":19196745,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-02-02T00:25:47.565Z","updated_at":"2025-10-16T16:32:06.252Z","avatar_url":"https://github.com/microsoft.png","language":"Scala","funding_links":[],"categories":["人工智能"],"sub_categories":["机器学习"],"readme":"# scala-torch\nJVM/Scala wrappers for LibTorch.\n\n## State of this project\n\nThis project is mature enough to be used regularly in production code. The API exposed is fairly clean\nand tries to follow PyTorch syntax as much as possible. The API is a mix of hand-written wrappings and a wrapper\naround most of `Declarations.yaml`. \n\nThat said, some internal documentation is not quite ready for public consumption yet, though there is enough\ndocumentation that people who are already familiar with Scala and LibTorch can probably figure out what's going on. \nCode generation is accomplished through a combination of [Swig](https://www.swig.org) and a quick-and-dirty \n[Python script](swig/src/main/swig/bindgen.py) that reads in `Declarations.yaml`, which provides a language-independent \nAPI for a large part of LibTorch. This file is [deprecated](https://github.com/pytorch/pytorch/issues/69471) and in the \nfuture, we can hopefully replace `bindgen.py` using the forthcoming [torchgen](https://github.com/pytorch/pytorch/issues/69471#issuecomment-1273642655)\ntool provided by PyTorch. \n\nOne major annoyance with Scala in particular is that you cannot define multiple overloads of a method that take default\narguments. Currently, `bindgen.py` uses any defaults present in only the first overload found in `Declarations.yaml`.\nIn some cases, clever use of Scala's implicit conversions can hide these headaches, but currently, you occasionaly have to write\nout the defaults where you would not have to in Python. One potential future option is to give overloads\ndifferent names, but we elected not to do that (yet).\n\nWe have not yet published JARs for this project. These are coming soon. \n\n## Short tour\n\nScala-torch exposes an API that tries to mirror PyTorch as much as Scala syntax\nallows. For example, taking some snippets from\n[this tutorial](https://pytorch.org/tutorials/beginner/basics/tensorqs_tutorial.html):\n\nPyTorch:\n```python\nimport torch\n\ndata = [[1, 2],[3, 4]]\nx_data = torch.tensor(data)\n```\n\nScala-Torch:\n```scala\nimport com.microsoft.scalatorch.torch\nimport com.microsoft.scalatorch.torch.syntax._\n\ntorch.ReferenceManager.forBlock { implicit rm =\u003e\n val data = $($(1, 2), $(3, 4))\n val x_data = torch.tensor(data)\n}\n```\n\n\nPyTorch:\n```python\ntensor = torch.ones(4, 4)\nprint(f\"First row: {tensor[0]}\")\nprint(f\"First column: {tensor[:, 0]}\")\nprint(f\"Last column: {tensor[..., -1]}\")\ntensor[:,1] = 0\nprint(tensor)\n```\n\nScala-Torch:\n```scala\nval tensor = torch.ones($(4, 4))\nprintln(s\"First row: ${tensor(0)}\")\nprintln(s\"First column: ${tensor(::, 0)}\")\nprintln(s\"Last column: ${tensor(---, -1)}\")\ntensor(::, 1) = 0\nprintln(tensor)\n```\n\nSee [this file](scala-torch/src/test/scala/com/microsoft/scalatorch/torch/tutorial/PyTorchOrgTensorTutorialTest.scala) for \na complete translation of the PyTorch tutorial into Scala-Torch.\n\n### Memory management\n\nOne big difference between Scala-Torch and PyTorch is in memory management. Because Python and LibTorch both use \nreference counting, memory management is fairly transparent to users. However, since the JVM uses garbage collection\nand [finalizers are not guaranteed to run](https://docs.oracle.com/javase/9/docs/api/java/lang/Object.html#finalize--),\nit is not easy to make memory management transparent to the user. Scala-Torch elects to make memory management something\nthe user must control by providing [ReferenceManager](scala-torch/src/main/scala/com/microsoft/scalatorch/torch/ReferenceManager.scala)s \nthat define the lifetime of any LibTorch-allocated object\nthat is added to it. All Scala-Torch methods that allocate objects from LibTorch take an `implicit` `ReferenceManager`,\nso it is the responsibility of the caller to make sure there is a `ReferenceManager` in `implicit` scope (or passed\nexplicitly) and that that `ReferenceManager` will be `close()`ed when appropriate. See documentation and uses\nof `ReferenceManager` for more examples.\n\n## Handling of native dependencies\n\nPyTorch provides pre-built binaries for the native code backing it [here](https://pytorch.org/get-started/locally/). \nWe make use of the pre-built dynamic libraries by packaging them up in a jar, much like [TensorFlow Scala](http://platanios.org/tensorflow_scala/installation.html).\nDownstream\nprojects have two options for handling the native dependencies: they can either \n1. Declare a dependency on the packaged native dependencies wrapped up with a jar using\n```scala\nval osClassifier = System.getProperty(\"os.name\").toLowerCase match {\n  case os if os.contains(\"mac\") || os.contains(\"darwin\") =\u003e \"darwin\"\n  case os if os.contains(\"linux\")                        =\u003e \"linux\"\n  case os if os.contains(\"windows\")                      =\u003e \"windows\"\n  case os                                                =\u003e throw new sbt.MessageOnlyException(s\"The OS $os is not a supported platform.\")\n}\nlibraryDependencies += (\"com.microsoft.scalatorch\" % \"libtorch-jar\" % \"1.10.0\").classifier(osClassifier + \"_cpu\")\n```\n2. Ensure that the libtorch dependencies are installed in the OS-dependent way, for example, in `/usr/lib` or in `LD_LIBRARY_PATH` on Linux,\nor in `PATH` on windows. Note that on recent version of MacOS, [System Integrity Protected](https://developer.apple.com/library/archive/documentation/Security/Conceptual/System_Integrity_Protection_Guide/RuntimeProtections/RuntimeProtections.html)\nresets `LD_LIBRARY_PATH` and `DYLD_LIBRARY_PATH` when working processes, so it is very hard to use that approach on MacOS. \n\nThe native binaries for the JNI bindings for all three supported OSes are published in `scala-torch-swig.jar`, so there\nis no need for OS-specific treatment of those libraries.\n\nApproach 1 is convenient because sbt will handle the libtorch native dependency for you and users won't need install\nlibtorch or set any environment variables. This is the ideal approach for local development. \n\nThere are several downsides of approach 1:\n* it may unnecessarily duplicate installation of libtorch if, for example, pytorch is already installed\n* jars for GPU builds of libtorch are not provided, so approach 2 is the only option if GPU support is required\n* care must be taken when publishing any library that depends on Scala-Torch to not publish the dependency\n on the `libtorch-jar`, since that would force the consumer of that library to depend on whatever OS-specific\n version of the jar was used at building time. See the use of `pomPostProcess` in [build.sbt](build.sbt) for\n how we handle that. Note that another option is for downstream libraries to exclude the `libtorch-jar`\n using something like \n```scala\nlibraryDependencies += (\"com.microsoft\" % \"scala-torch\" % \"0.1.0\").exclude(\"com.microsoft.scalatorch\", \"libtorch-jar\")\n```\n\nApproach 2 is the better option for CI, remote jobs, production, etc. \n\n### Local Development (MacOS)\n\nYou will need to have SWIG installed, which you can\ninstall using `brew install swig`.\n\n```\ngit submodule update --init --recursive\ncd pytorch\npython3 -m tools.codegen.gen -s aten/src/ATen -d torch/share/ATen\ncd ..\ncurl https://download.pytorch.org/libtorch/cpu/libtorch-macos-$(pytorchVersion).zip -o libtorch.zip\nunzip libtorch.zip\nrm -f libtorch.zip\nconda env create --name scala-torch --file environment.yml\nconda activate scala-torch\nexport TORCH_DIR=$PWD/libtorch\n# This links to the JNI shared library to the absolute paths in the libtorch dir instead of \n# using an rpath.\nexport LINK_TO_BUILD_LIB=true\nsbt test\n```\n\nA similar setup should work for Linux and Windows. \n\n#### Troubleshooting\n\nIf you are using Clang 11.0.3 you may run into an error \nwhen compiling the `SobolEngineOps` file. This is most \nlikely due to an issue with the compiler and it has already \nbeen reported [here](https://github.com/pytorch/pytorch/issues/35478).\nA temporary workaround is to install another version of \nClang (e.g., by executing `brew install llvm`). Another option\nis to downgrade XCode to a version \u003c 11.4.\n\n### Upgrading the LibTorch version\n\nTo upgrade the underlying version of LibTorch:\n* `cd pytorch; git checkout \u003ccommit\u003e` with the `\u003ccommit\u003e` of the desired release version, \n  best found [here](https://github.com/pytorch/pytorch/releases).\n* Rerun the steps under **Local Development**.\n* Change `TORCH_VERSION` in [run_tests.yml](.github/workflows/run_tests.yml).\n* Address compilation errors when running `sbt compile`. Changes to [bindgen.py](swig/src/main/swig/bindgen.py) may\n  be necessary.\n\n# Contributors\n\nThanks to the following contributors to this project:\n\n* [Adam Pauls](https://github.com/adampauls)\n* [David Hall](https://github.com/dlwh)\n* [Theo Lanman](https://github.com/theo-lanman)\n* [Alex Kyte](https://github.com/alexanderkyte)\n* [Hao Fang](https://github.com/hao-fang)\n* [Anthony Platanios](https://github.com/eaplatanios)\n* [Dmitrij Peters](https://github.com/Dpetters)\n\n# Trademarks\n\nThis project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft\ntrademarks or logos is subject to and must follow\n[Microsoft's Trademark \u0026 Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general).\nUse of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship.\nAny use of third-party trademarks or logos are subject to those third-party's policies.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmicrosoft%2Fscala_torch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmicrosoft%2Fscala_torch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmicrosoft%2Fscala_torch/lists"}