|
1 | | -# GoPJRT ([Installing](#installing)) |
| 1 | +# go-xla: OpenXLA APIs bindings for Go |
2 | 2 |
|
3 | 3 | [](https://pkg.go.dev/github.com/gomlx/go-xla?tab=doc) |
4 | | -[](https://github.com/Kwynto/gosession/blob/master/LICENSE) |
| 4 | +[](https://github.com/gomlx/go-xla/blob/master/LICENSE) |
5 | 5 | [](https://goreportcard.com/report/github.com/gomlx/go-xla) |
6 | 6 | [](https://github.com/gomlx/go-xla/actions/workflows/linux_tests.yaml) |
7 | 7 | [](https://github.com/gomlx/go-xla/actions/workflows/darwin_tests.yaml) |
8 | | - |
9 | 8 | [](https://app.slack.com/client/T029RQSE6/C08TX33BX6U) |
10 | 9 |
|
11 | | -## Why use GoPJRT ? |
12 | 10 |
|
13 | | -GoPJRT leverages [OpenXLA](https://openxla.org/) to compile, optimize, and **accelerate numeric computations** (with large data) |
14 | | -from Go using various [backends supported by OpenXLA](https://opensource.googleblog.com/2024/03/pjrt-plugin-to-accelerate-machine-learning.html): CPU, GPUs (Nvidia, AMD ROCm*, Intel*, Apple Metal*) and TPU. |
| 11 | + |
| 12 | +## Why use go-xla ? |
| 13 | + |
| 14 | +The **go-xla** project leverages [OpenXLA's](https://openxla.org/) to (JIT-) compile, optimize, and **accelerate numeric computations** |
| 15 | +(with large data) from Go using various [backends supported by OpenXLA](https://opensource.googleblog.com/2024/03/pjrt-plugin-to-accelerate-machine-learning.html): CPU, GPUs (Nvidia, AMD ROCm*, Intel*, Apple Metal*) and TPUs. |
15 | 16 | It can be used to power Machine Learning frameworks (e.g. [GoMLX](https://github.com/gomlx/gomlx)), image processing, scientific |
16 | 17 | computation, game AIs, etc. |
17 | 18 |
|
18 | 19 | And because [Jax](https://docs.jax.dev/en/latest/), [TensorFlow](https://www.tensorflow.org/) and |
19 | 20 | [optionally PyTorch](https://pytorch.org/xla/release/2.3/index.html) run on XLA, it is possible to run Jax functions in Go with GoPJRT, |
20 | 21 | and probably TensorFlow and PyTorch as well. |
21 | | -See [example 2 in xlabuilder/README.md](https://github.com/gomlx/go-xla/blob/main/xlabuilder/README.md#example-2). |
22 | 22 |
|
23 | | -GoPJRT aims to be minimalist and robust: it provides well-maintained, extensible Go wrappers for |
24 | | -[OpenXLA PJRT](https://openxla.org/#pjrt). |
| 23 | +The **go-xla** porject aims to be minimalist and robust: it provides well-maintained, extensible Go wrappers for |
| 24 | +[OpenXLA's StableHLO](https://openxla.org/#stablehlo) and [OpenXLA's PJRT](https://openxla.org/#pjrt). |
25 | 25 |
|
26 | | -GoPJRT is not very ergonomic (error handling everywhere), but it's expected to be a stable building block for |
27 | | -other projects to create a friendlier API on top. The same way [Jax](https://jax.readthedocs.io/en/latest/) is a Python friendlier API |
28 | | -on top of XLA/PJRT. |
| 26 | +The APIs are not very "ergonomic" (error handling everywhere), but it's expected to be a stable building block for |
| 27 | +other projects to create a friendlier API on top. |
| 28 | +The same way [Jax](https://jax.readthedocs.io/en/latest/) is a Python friendlier API on top of XLA/PJRT. |
29 | 29 |
|
30 | | -One such friendlier API co-developed with GoPJRT is [GoMLX, a Go machine learning framework](https://github.com/gomlx/gomlx). |
31 | | -But GoPJRT may be used as a standalone, for lower level access to XLA and other accelerator use cases—like running |
| 30 | +One such friendlier API co-developed with **go-xla** is [GoMLX, a Go machine learning framework](https://github.com/gomlx/gomlx). |
| 31 | +But **go-xla** may be used as a standalone, for lower level access to XLA and other accelerator use cases—like running |
32 | 32 | Jax functions in Go, maybe an "accelerated" image processing or scientific simulation pipeline. |
33 | 33 |
|
34 | 34 | ## What is what? |
35 | 35 |
|
36 | | -"**PJRT**" stands for "Pretty much Just another RunTime." |
| 36 | +### **PJRT** - "Pretty much Just another RunTime." |
37 | 37 |
|
38 | | -It is the heart of the OpenXLA project: it takes an IR (intermediate representation) of the "computation graph," JIT (Just-In-Time) compiles it |
39 | | -(once) and executes it fast (many times). |
| 38 | +It is the heart of the OpenXLA project: it takes an IR (intermediate representation, typically _StableHLO_) of the "computation graph," |
| 39 | +JIT (Just-In-Time) compiles it (once) and executes it fast (many times). |
40 | 40 | See the [Google's "PJRT: Simplifying ML Hardware and Framework Integration"](https://opensource.googleblog.com/2023/05/pjrt-simplifying-ml-hardware-and-framework-integration.html) blog post. |
41 | 41 |
|
42 | 42 | A "computation graph" is the part of your program (usually vectorial math/machine learning related) that one |
43 | 43 | wants to "accelerate." |
44 | | -It must be provided in an IR (intermediate representation) that is understood by the PJRT plugin. |
45 | | -A few ways to create the computation graph IR: |
46 | 44 |
|
47 | | -1. [github.com/gomlx/go-xla/pkg/stablehlo](https://github.com/gomlx/go-xla/pkg/stablehlo?tab=readme-ov-file): [StableHLO](https://openxla.org/stablehlo) |
| 45 | +The PJRT comes in the form of a _plugin_, a dynamically linked library (`.so` file in Linux, or optionally |
| 46 | +`.dylib` in Darwin, or `.dll` in Windows). Typically, there is one plugin per hardware you are supporting. |
| 47 | +E.g.: there are PJRT plugins for CPU (Linux/amd64 and macOS for now, but likely it could be compiled for |
| 48 | +other CPUs -- SIMD/AVX are well-supported), for TPUs (Google's accelerator), |
| 49 | +GPUs (Nvidia is well-supported; there are AMD and Intel's PJRT plugins, but they were not tested), |
| 50 | +and others are in development. Some PJRT plugins are not open-source, but are available for download. |
| 51 | + |
| 52 | +The **go-xla** project provides the package `github.com/gomlx/go-xla/pkg/pjrt`, |
| 53 | +a Go API for dynamically loading and calling the **PJRT** runtime. |
| 54 | +It also provides a installer or library (`github.com/gomlx/go-xla/pkg/installer`) to |
| 55 | +auto-install (download pre-compiled binaries) **PJRT** plugins for CPU (from GitHub), |
| 56 | +CUDA (from pypi.org Jax pacakges) and TPU (also from pypi.org). |
| 57 | + |
| 58 | +### **StableHLO** - "Stable High Level Optimization" (?) |
| 59 | + |
| 60 | +The currently better supported IR (intermediary representation) supported by PJRT, see specs |
| 61 | +in [StableHLO docs](https://openxla.org/stablehlo). It's a text representation of the computation |
| 62 | +that can easily be parsed by computers, but not easily written or read by humans. |
| 63 | + |
| 64 | +The package [`github.com/gomlx/go-xla/pkg/stablehlo`](https://github.com/gomlx/go-xla/pkg/stablehlo?tab=readme-ov-file) |
| 65 | +provides a Go API for writing StableHLO programs, including _shape inference_, needed to correctly |
| 66 | +infer the output shape of operations as the program is being built. |
| 67 | + |
48 | 68 | is the current preferred IR language for XLA PJRT. This library (co-developed with **GoPJRT**) is a Go API for building |
49 | 69 | computation graphs in StableHLO that can be directly fed to *GoPJRT*. See examples below. |
50 | | -2. [github.com/gomlx/gopjtr/xlabuilder](https://github.com/gomlx/go-xla/tree/main/xlabuilder): |
51 | 70 | This is a wrapper Go library to an XLA C++ library that generates the previous IR (called MHLO). |
52 | 71 | It is still supported by XLA and by **GoPJRT**, but it is being deprecated. |
53 | 72 | 3. Using Jax, Tensorflow, PyTorchXLA: Jax/Tensorflow/PyTorchXLA can output the StableHLO of JIT compiled functions |
54 | 73 | that can be fed directly to PJRT (as text). We don't detail this here, but the authors did this a lot during |
55 | 74 | development of **GoPJRT**, [github.com/gomlx/go-xla/pkg/stablehlo](https://github.com/gomlx/go-xla/pkg/stablehlo?tab=readme-ov-file) and |
56 | 75 | [github.com/gomlx/gopjtr/xlabuilder](https://github.com/gomlx/go-xla/tree/main/xlabuilder) for testing. |
57 | 76 |
|
58 | | -> [!NOTE] |
59 | | -> The IR (intermediary representation) that PJRT plugins accept are text, but not human-friendly to read/write. |
60 | | -> Small ones are debuggable, or can be used to probe which operations are being used behind the scenes, |
61 | | -> but definitely not friendly. |
62 | | -
|
63 | | -A "PJRT Plugin" is a dynamically linked library (`.so` file in Linux, or optionally `.dylib` in Darwin, or `.dll` in Windows). |
64 | | -Typically, there is one plugin per hardware you are supporting. E.g.: there are PJRT plugins |
65 | | -for CPU (Linux/amd64 and macOS for now, but likely it could be compiled for other CPUs -- SIMD/AVX are well-supported), |
66 | | -for TPUs (Google's accelerator), |
67 | | -GPUs (Nvidia is well-supported; there are AMD and Intel's PJRT plugins, but they were not tested), |
68 | | -and others are in development. |
69 | | - |
70 | 77 | ## Example |
71 | 78 |
|
72 | 79 | 1. Minimalistic example, that assumes you have your StableHLO code in a variable (`[]byte`) called `stablehloCode`: |
@@ -109,61 +116,24 @@ The `pjrt` package includes the following main concepts: |
109 | 116 | * `Buffer`: Represents a buffer with the input/output data for the computations in the accelerators. There are |
110 | 117 | methods to transfer it to/from the host memory. They are the inputs and outputs of `LoadedExecutable.Execute`. |
111 | 118 |
|
112 | | -PJRT plugins by default are loaded after the program is started (using `dlopen`). |
113 | | -But there is also the option to pre-link the CPU PJRT plugin in your program -- option only works for Linux/amd64 for now. |
114 | | -For that, import (as `_`) one of the following packages: |
115 | | - |
116 | | -- `github.com/gomlx/go-xla/pkg/pjrt/cpu/dynamic`: pre-link the CPU PJRT dynamically (as opposed to load it after the |
117 | | - Go program starts). It is fast to build, but it still requires deploying the PJRT plugin along with your |
118 | | - program. Not commonly used, but a possibility. |
119 | | -- `github.com/gomlx/go-xla/pkg/pjrt/cpu/static`: (**experimental**) pre-link the CPU PJRT statically, so you don't need to |
120 | | - distribute a CPU PJRT with your program. But it's slower to build, potentially taking a few extra (annoying) seconds |
121 | | - (static libraries are much slower to link). |
122 | | - As of version v0.9.1 this is no longer built by default – you can still install the Linux CPU PJRT from release |
123 | | - v0.9.0 if you need this. This is a limitation of XLA/Bazel combination – for which a previous hack worked. |
124 | | - Hopefully, with time XLA will migrate to using the new Bazel where static libraries are supported, and we can |
125 | | - include it again. |
| 119 | +## Installation of PJRT plugin |
126 | 120 |
|
127 | | -While it uses CGO to dynamically load the plugin and call its C API, `pjrt` doesn't require anything other than the plugin |
128 | | -to be installed. |
| 121 | +Most programs may simply add a call `installer.AutoInstall()` and it will automatically download the PJRT plugin |
| 122 | +to the user's local home (`${HOME}/.local/lib/go-xla/` in Linux), if not installed already. |
| 123 | +So there is nothing to do. |
129 | 124 |
|
130 | | -The project release includes pre-built CPU released for Linux/amd64 only now. |
131 | | -It's been compiled for Macs before—I don't have easy access to an Apple Mac to maintain it. |
132 | | - |
133 | | - |
134 | | -## Installing |
135 | | - |
136 | | -GoPJRT requires one or more "PJRT plugin" modules to JIT-compile and execute your computation graphs. |
137 | | -To facilitate installing them, it provides an interactive and self-explanatory installer: |
138 | | - |
139 | | -```bash |
140 | | -go run github.com/gomlx/go-xla/cmd/gopjrt_installer@latest |
141 | | -``` |
142 | | - |
143 | | -> [!NOTE] |
144 | | -> For now it works for (1) CPU PJRT on linux/amd64 (or Windows+WSL); (2) Nvidia CUDA PJRT on Linux/amd64; |
145 | | -> (3) CPU PJRT on Darwin (macOS); (4) TPU PJRT in GCP (Linux/amd64 host). |
146 | | -> I would love to support for AMD ROCm, Apple Metal (GPU), Intel, and others, but I don't have easy access to |
147 | | -> hardwre to test/maintain them. |
148 | | -> If you feel like contributing or donating hardware/cloud credits, please contact me. |
149 | | - |
150 | | -There are also some older bash install scripts under [`github.com/gomlx/go-xla/cmd`](https://github.com/gomlx/go-xla/tree/main/cmd), |
151 | | -but they are deprecated and eventually will be removed in a few versions. Let me know if you need them. |
152 | | - |
153 | | -## PJRT Plugins for other devices or platforms. |
154 | | - |
155 | | -See [docs/devel.md](https://github.com/gomlx/go-xla/blob/main/docs/devel.md#pjrt-plugins) on hints on how to compile a plugin |
156 | | -from OpenXLA/XLA sources. |
157 | | - |
158 | | -Also, see [this blog post](https://opensource.googleblog.com/2024/03/pjrt-plugin-to-accelerate-machine-learning.html) with the link and references to the Intel and Apple hardware plugins. |
| 125 | +To manually install it, consider using the command line installer with |
| 126 | +`go run github.com/gomlx/go-xla/cmd/pjrt_installer@latest` and follow the |
| 127 | +self-explanatory menu (or provide the flags for a quiet installation) |
159 | 128 |
|
160 | 129 | ## FAQ |
161 | 130 |
|
162 | 131 | * **When is feature X from PJRT going to be supported ?** |
163 | 132 | GoPJRT doesn't wrap everything—although it does cover the most common operations. |
164 | 133 | The simple ops and structs are auto-generated. But many require hand-writing. |
165 | | - Please, if it is useful to your project, create an issue; I'm happy to add it. I focused on the needs of GoMLX, |
166 | | - but the idea is that it can serve other purposes, and I'm happy to support it. |
| 134 | + Please, if it is useful to your project, create an issue; I'm happy to add it. |
| 135 | + I focus on the needs of GoMLX, but the idea is that it can serve other purposes, and I'm happy to support it. |
| 136 | + |
167 | 137 | * **Why does PJRT spit out so many logs? Can we disable it?** |
168 | 138 | This is a great question ... imagine if every library we use decided they also want to clutter our stderr? |
169 | 139 | I have [an open question in Abseil about it](https://github.com/abseil/abseil-cpp/discussions/1700). |
@@ -193,41 +163,19 @@ Environment variables that help control or debug how GoPJRT works: |
193 | 163 | is passed during the JIT-compilation (`Client.Compile()`) of a computation graph. |
194 | 164 | It is not documented how it works in PJRT (e.g., I observed a great slow down when this is set, |
195 | 165 | even if set to the default values), but [the proto has some documentation](https://github.com/gomlx/go-xla/blob/main/protos/xla.proto#L40). |
196 | | -* `GOPJRT_INSTALL_DIR` and `GOPJRT_NOSUDO`: used by the installation scripts, see "Installing" section above. |
197 | | - |
198 | | -## Links to documentation |
199 | | - |
200 | | -* [Google Drive Directory with Design Docs](https://drive.google.com/drive/folders/18M944-QQPk1E34qRyIjkqDRDnpMa3miN): Some links are outdated or redirected, but invaluable information. |
201 | | -* [How to use the PJRT C API? #openxla/xla/issues/7038](https://github.com/openxla/xla/issues/7038): discussion of folks trying to use PJRT in their projects. Some examples leveraging some of the XLA C++ library. |
202 | | -* [How to use PJRT C API v.2 #openxla/xla/issues/7038](https://github.com/openxla/xla/issues/13733). |
203 | | -* [PJRT C API README.md](https://github.com/openxla/xla/blob/main/xla/pjrt/c/README.md): a collection of links to other documents. |
204 | | -* [Public Design Document](https://docs.google.com/document/d/1Qdptisz1tUPGn1qFAVgCV2omnfjN01zoQPwKLdlizas/edit). |
205 | | -* [Gemini](https://gemini.google.com) helped quite a bit in parsing and understanding things—despite the hallucinations—other AIs may help as well. |
206 | | - |
207 | | -## Running Tests |
208 | | - |
209 | | -All tests support (in linux) the following build tags to pre-link the CPU plugin (as opposed to `dlopen` the plugin) -- select at most one of them: |
210 | | - |
211 | | -* `--tags pjrt_cpu_dynamic`: link (preload) the CPU PJRT plugin from the dynamic library (`.so`) version. |
212 | | - Faster to build, but deployments require deploying the `libpjrt_c_api_cpu_dynamic.so` file along. |
213 | | -* `--tags pjrt_cpu_static`: (**experimental**) link (preload) the CPU PJRT plugin from the static library (`.a`) version. |
214 | | - Slowest to build (but executes the same speed). |
215 | 166 |
|
216 | 167 | ## Acknowledgements |
217 | | -This project uses the following components from the [OpenXLA project](https://openxla.org/): |
218 | 168 |
|
219 | | -* This project includes a (slightly modified) copy of the OpenXLA's [`pjrt_c_api.h`](https://github.com/openxla/xla/blob/main/xla/pjrt/c/pjrt_c_api.h) file. |
220 | | -* OpenXLA PJRT CPU Plugin: This plugin enables execution of XLA computations on the CPU. |
221 | | -* OpenXLA PJRT CUDA Plugin: This plugin enables execution of XLA computations on NVIDIA GPUs. |
| 169 | +This project includes a (slightly modified) copy of the OpenXLA's [`pjrt_c_api.h`](https://github.com/openxla/xla/blob/main/xla/pjrt/c/pjrt_c_api.h) file as well as some of the `.proto` files used by `pjrt_c_api.h`. |
222 | 170 |
|
223 | | -* We gratefully acknowledge the OpenXLA team for their valuable work in developing and maintaining these plugins. |
| 171 | +More importantly, we **gratefully acknowledge the OpenXLA project and team** for their valuable work in developing and maintaining these plugins. |
224 | 172 |
|
225 | | -## Licensing: |
| 173 | +For more information about OpenXLA, please visit their website at [openxla.org](https://openxla.org/), or the GitHub page at [github.com/openxla/xla](https://github.com/openxla/xla) |
226 | 174 |
|
227 | | -GoPJRT is [licensed under the Apache 2.0 license](https://github.com/gomlx/go-xla/blob/main/LICENSE). |
| 175 | +## Licensing |
228 | 176 |
|
229 | | -The [OpenXLA project](https://openxla.org/), including `pjrt_c_api.h` file, the CPU and CUDA plugins, is [licensed under the Apache 2.0 license](https://github.com/openxla/xla/blob/main/LICENSE). |
| 177 | +The **go-xla** project is [licensed under the Apache 2.0 license](https://github.com/gomlx/go-xla/blob/main/LICENSE). |
230 | 178 |
|
231 | | -The CUDA plugin also uses the Nvidia CUDA Toolkit, which is subject to Nvidia's licensing terms and must be installed by the user. |
| 179 | +The [OpenXLA project](https://openxla.org/), including `pjrt_c_api.h` file, the CPU and CUDA plugins, is [licensed under the Apache 2.0 license](https://github.com/openxla/xla/blob/main/LICENSE). |
232 | 180 |
|
233 | | -For more information about OpenXLA, please visit their website at [openxla.org](https://openxla.org/), or the GitHub page at [github.com/openxla/xla](https://github.com/openxla/xla) |
| 181 | +The CUDA plugin also uses the Nvidia CUDA Toolkit, which is subject to Nvidia's licensing terms and must be installed by the user or at the user's request. |
0 commit comments