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