1 # Heterogeneous Accelerator Toolkit (HAT)
2
3 [](https://github.com/openjdk/babylon/tree/code-reflection/hat)
4
5 HAT is a toolkit that allows developers to express data-parallel applications in Java, optimize, offload and execute them on hardware accelerators.
6 - **Heterogeneous**: a variety of devices and their corresponding programming languages.
7 - **Accelerator**: GPUs, FPGA, CPUs, etc.
8 - **Toolkit**: a set of libraries for Java developers.
9
10 HAT uses the code reflection API from the [Project Babylon](https://github.com/openjdk/babylon).
11
12 The toolkit offers:
13 - An API for SIMT (Single Instruction Multiple Thread) Kernel Programming on Accelerators from Java.
14 - An API for Tile Kernel Programming on Accelerators from Java. Currently only available to target NVIDIA GPUs (Ampere or later).
15 - An API for Combining multiple kernels into a compute-graph.
16 - An API for Java object mapping to hardware accelerators using Panama FFM.
17 - An extensible backend system for multiple accelerators:
18 - OpenCL C
19 - CUDA C/C++
20 - Java
21
22 ## Prerequisites
23
24 - HAT currently requires Babylon JDK, which contains the code reflection APIs.
25 - A base JDK >= 26. We currently use OpenJDK 26 for development.
26 - A GPU SDK (one or more of the SDKs below) to be able to run on GPUs:
27 - An OpenCL implementation (e.g., Intel, Apple Silicon, CUDA SDK)
28 - OpenCL >= 1.2
29 - CUDA SDK >= 13.0
30 - `cmake` >= `3.22.1`
31 - `gcc` >= 12.0, or `clang` >= 17.0
32
33 ## Compatible systems
34
35 We actively develop and run benchmarks on the following systems:
36
37 - Apple Silicon M1-M5
38 - Linux Fedora >= 43
39 - Oracle Linux >= 10.0
40 - Ubuntu >= 22.04
41
42 ## Quick Start
43
44 ### 1. Build Babylon JDK
45
46 ```bash
47 git clone https://github.com/openjdk/babylon
48 cd babylon
49 bash configure --with-boot-jdk=${JAVA_HOME}
50 make clean
51 make images
52 ```
53
54 ### 2. Update JAVA_HOME and PATH
55
56 ```bash
57 cd hat/
58 source env.bash
59 ```
60
61 The env.bash script will setup the `JAVA_HOME` and the `PATH` to use the Babylon JDK.
62
63 Alternatively, you can run it manually:
64
65 ```bash
66 export JAVA_HOME=<BABYLON-DIR>/build/macosx-aarch64-server-release/images/jdk
67 export PATH=$JAVA_HOME/bin:$PATH
68 ```
69
70 ### 3. Install HAT specific tools (cmake and maven)
71
72 Either:
73
74 ```bash
75 brew install maven
76 brew install cmake
77 ```
78
79 Or
80
81 ```bash
82 ## Debian-based distros
83 sudo apt-get install maven cmake
84
85 ## For RHEL-based distros
86 sudo dnf install maven cmake
87 ```
88
89 ### 4. Build HAT
90
91 ```bash
92 cd <path-to>/babylon/hat
93 mvn clean package
94 ```
95
96 Done!
97
98 ## Run Examples
99
100 For instance, matrix-multiply:
101
102 ```bash
103 java @.ffi-opencl-example matmul.Main --size=1024
104 ```
105
106 Some examples have a GUI implementation:
107
108 ```java
109 java @.ffi-opencl-example mandel.Main
110 ```
111
112 Full list of examples:
113 - [link](https://github.com/openjdk/babylon/tree/code-reflection/hat/examples)
114
115
116 ## Run Unit-Tests
117
118 OpenCL backend:
119
120 ```bash
121 java @.ffi-opencl-test-suite
122 ```
123
124 CUDA backed:
125
126 ```bash
127 java @.ffi-cuda-test-suite
128 ```
129
130 ## Full Example Explained (SMIT Model)
131
132 The following example compute the square value of an input vector.
133 The example is self-contained and it can be directly run with the `java` command.
134
135 Place the following code in the `hat` directory.
136
137 ```java
138 import hat.*;
139 import hat.Accelerator.Compute;
140 import hat.backend.*;
141 import hat.buffer.*;
142 import optkl.ifacemapper.MappableIface.*;
143 import jdk.incubator.code.Reflect;
144 import java.lang.invoke.MethodHandles;
145
146 import static hat.KernelContext.*;
147
148 public class ExampleHAT {
149
150 // Kernel Code: This is the function to be offloaded to the accelerator (e.g.,
151 // a GPU). The kernel will be executed by many GPU threads, in this case,
152 // as many threads as elements in `array`.
153 // HAT kernels follow the SIMT programming model (Single Instruction Multiple Thread)
154 // mode.
155 // Kernel code is reflectable. Thus, the HAT runtime and HAT compiler can build
156 // and optimize the code model. Once the code model is optimized, HAT generates
157 // OpenCL/CUDA C99 code.
158 @Reflect
159 public static void squareKernel(S32Array array) {
160 // HAT kernels support a reduced set of Java.
161 // Kernels express the work to be done per thread (GPU/accelerator thread).
162 // Use GIX() to obtain the thread global id for the first dimension
163 if (GIX() < array.length()) {
164 int value = array.array(GIX());
165 array.array(GIX(), (value * value));
166 }
167 }
168
169 // The following method represents the compute layer, in which we specify
170 // the number of threads to be deployed on the accelerator. The number of threads
171 // is specified in an ND-Range. An ND-Range could be 1D, 2D and 3D.
172 // In this example, we launch 1D-range with the number of threads equal to
173 // the input array size.
174 @Reflect
175 public static void square(ComputeContext cc, S32Array array) {
176 var ndRange = NDRange.of1D(array.length());
177
178 // Dispatch the kernel. The HAT runtime will offload the kernels
179 // reached from this point and run the generated GPU kernels on the
180 // target accelerator.
181 // Furthermore, HAT automatically transfers data to the accelerator.
182 // This is a blocking call, and when it returns control to the main
183 // Java thread, results (outputs) are available to be consumed.
184 cc.dispatchKernel(ndRange, () -> squareKernel(array));
185 }
186
187 static void main() {
188 final int size = 4096;
189 // Create a new accelerator object
190 var accelerator = new Accelerator(MethodHandles.lookup(), Backend.FIRST);
191
192 // Instantiate an array on the target accelerator.
193 // Data is stored off-heap using the Panama FFM API.
194 var array = S32Array.create(accelerator, size);
195
196 // Data initialization
197 for (int i = 0; i < array.length(); i++) {
198 array.array(i, i);
199 }
200
201 // Dispatch the set of kernels defined in the compute-layer on the target accelerator.
202 // This is a blocking call. Once this call finalizes, the results (outputs)
203 // will be available to consume by the current Java thread.
204 accelerator.compute((@Reflect Compute) cc -> ExampleHAT.square(cc, array));
205
206 // Test result
207 boolean isCorrect = true;
208 for (int i = 0; i < size; i++) {
209 if (array.array(i) != i * i) {
210 isCorrect = false;
211 }
212 }
213 if (isCorrect) {
214 IO.println("Result is correct");
215 } else {
216 IO.println("Result is NOT correct");
217 }
218 }
219 }
220 ```
221
222 Run this example in the `babylon/hat` directory.
223 If you run from another directory, update the `--class-path` parameter accordingly.
224 Use the `java` version built with the Babylon JDK.
225
226 ```bash
227 java --enable-preview \
228 --add-modules=jdk.incubator.code \
229 --enable-native-access=ALL-UNNAMED \
230 --class-path build/hat-optkl-1.0.jar:build/hat-core-1.0.jar:build/hat-backend-ffi-shared-1.0.jar:build/hat-backend-ffi-opencl-1.0.jar \
231 -Djava.library.path=build \
232 ExampleHAT.java
233 ```
234
235 If you run with `HAT=INFO` you can see which accelerator was used:
236
237 ```bash
238 $ HAT=INFO java --enable-preview \
239 --add-modules=jdk.incubator.code \
240 --enable-native-access=ALL-UNNAMED \
241 --class-path build/hat-optkl-1.0.jar:build/hat-core-1.0.jar:build/hat-backend-ffi-shared-1.0.jar:build/hat-backend-ffi-opencl-1.0.jar \
242 -Djava.library.path=build \
243 ExampleHAT.java
244
245 [INFO] Config Bits = 8000
246 [INFO] Platform :"Apple"
247 [INFO] Version :"OpenCL 1.2 (Jan 16 2026 07:22:26)"
248 [INFO] Name :"Apple"
249 [INFO] Device Type : GPU 4
250 [INFO] OpenCLBackend::OpenCLQueue::dispatch
251 [INFO] numDimensions: 1
252 [INFO] GLOBAL [4096,1,1]
253 [INFO] LOCAL [ nullptr ] // The driver will setup a default value
254 ```
255
256 ## Documentation
257
258 Visit the [docs](docs/) folder.
259
260 ## Contributing
261
262 Contributions are welcome. Please see the [OpenJDK Developers' Guide](https://openjdk.org/guide/).
263
264 ## Development Workflow
265
266 1. Fork the repository
267 2. Create a feature branch: `git checkout -b <branch>`
268 3. Commit with clear messages
269 4. Run formatting and tests:
270 1. For OpenCL: `java @.ffi-opencl-test-suite`
271 1. For CUDA: `java @.ffi-cuda-test-suite`
272 5. Submit a pull request
273
274
275 ## Contacts/Questions
276
277 You can interact, provide feedback and ask questions using the [babylon-dev](https://mail.openjdk.org/archives/list/babylon-dev@openjdk.org/) mailing list.
278