1 # Building HAT
2 [Back to Index ../](../index.md)
3
4 We use `maven` and `cmake` to build HAT.
5
6 Maven controls the build but delegates to cmake for native artifacts (such as ffi-backends), we also use cmake to provide jextract
7 with location information needed to reference various include/lib paths. (See extractions/pom.xml)
8
9 Use `sudo apt` on Linux or `brew install`.
10
11 ```bash
12 sudo apt install cmake maven
13 ```
14
15 ```bash
16 brew install cmake
17 brew install maven
18 ```
19
20 ## Setting environment variables JAVA_HOME and PATH
21 To build HAT we need to ensure that `JAVA_HOME` points to our babylon jdk (the one we built [here](babylon.md))
22
23 We also need to ensure that `${JAVA_HOME}/bin` is in our PATH (before any other JAVA location).
24
25 We also need jextract for some maven targets.
26
27 We can download and install jextract from [here](https://jdk.java.net/jextract/)
28
29 The `env.bash` shell script can be sourced (dot included) in your shell to set JAVA_HOME and PATH
30 ```bash
31 cd hat
32 . ./env.bash
33 ```
34 This should detect the arch type (AARCH64 or X86_46) and select the correct relative parent dir and inject that dir in your PATH if you are working with
35 HAT in the original subdir of the babylon project.
36
37 It will also check if jextract is in your PATH. If it is not, you will need to add it (if you decide to use any of the jextract artifacts).
38 ```bash
39 cd hat
40 . ./env.bash
41 export PATH=${PATH}:/path/to/my/jextract/bin
42 echo ${JAVA_HOME}
43 /Users/ME/github/babylon/hat/../build/macosx-aarch64-server-release/jdk
44 echo ${PATH}
45 /Users/ME/github/babylon/hat/../build/macosx-aarch64-server-release/jdk/bin:/usr/local/bin:......
46 ```
47 ## Building
48 Now we should be able to use maven to build, if successful maven will place all jars and libs in a newly created `build` dir in your top level hat dir.
49 ```bash
50 cd hat
51 . ./env.bash
52 mvn clean package
53 ls build
54 hat-core-1.0.jar hat-example-heal-1.0.jar
55 hat-backend-ffi-cuda-1.0.jar hat-example-mandel-1.0.jar
56 hat-backend-ffi-mock-1.0.jar hat-example-squares-1.0.jar
57 hat-backend-ffi-opencl-1.0.jar hat-example-view-1.0.jar
58 hat-example-violajones-1.0.jar hat-example-experiments-1.0.jar
59 libopencl_backend.dylib
60 ```
61
62 ## Running an example
63 To run we use some common java `opt` files.
64
65 When executing with java we canplace common java params in files (say opts) then use `java @opts` to avoid typing all the opts each time.
66
67 To declutter the hat dir, we prefix some useful `opt` files with `.`
68
69 For example in the .ffi-opencl-example opt file we have
70 ```bash
71 cat .ffi-opencl-example
72 --enable-preview --add-modules=jdk.incubator.code --enable-native-access=ALL-UNNAMED -Djava.library.path=build --class-path build/hat-ffi-opencl-examples-1.0.jar
73 ```
74
75 So you can run an example (say nbody) using the opencl backend using
76 ```bash
77 java @.ffi-opencl-example nbody.Main
78 ```
79
80 Similarly we can run HAT's test suite.
81
82 ```bash
83 java @.ffi-opencl-test-suite
84 ....
85 ```
86
87 To list available `@.` files
88 ```bash
89 ls .*
90 ```
91
92 ----
93 ### HAT runtime environment variable.
94
95 During ffi-backend development we added some useful flags to pass to native code to allow us to trace calls, inject logging, control options.
96
97 These should be considered just development flags.
98
99 At runtime the ffi-backends all communicate from the java side to the native side via a 32 bit 'config' int.
100
101 The Java side class [hat.backend.ffi.Config](https://github.com/openjdk/babylon/blob/code-reflection/hat/backends/ffi/shared/src/main/java/hat/backend/ffi/Config.java)
102
103 Is initialized from an environment variable `HAT` at runtime
104
105 So for example when we launch
106 ```bash
107 java @hat/run ffi-opencl heal
108 ```
109
110 We can pass config info to `HAT` via either `-DHAT=xxx` or via the `HAT` ENV variable.
111
112 So for example to get HAT to dump the text form of the kernel code models.
113
114 ```
115 HAT=INFO,SHOW_KERNEL_MODEL java @hat/run ffi-opencl heal
116 ```
117
118 Or to show generated opencl or cuda code
119 ```
120 HAT=INFO,SHOW_CODE java @hat/run ffi-opencl heal
121 ```
122
123 This is particularly useful for selecting PLATFORM + DEVICE if you have multiple GPU devices.
124
125 Here we select DEVICE 0 on PLATFORM 0 (actually the default)
126 ```
127 HAT=INFO,PLATFORM:0,DEVICE:0,SHOW_CODE ...
128 ```
129 or for DEVICE 1 on PLATFORM 1
130 ```
131 HAT=INFO,PLATFORM:1,DEVICE:1,SHOW_CODE ...
132 ```
133
134 Note the platform and device id's are 4 bits. This probably works for development, but we will need a more expressive way of capturing this via the accelerator selection.
135
136 This just allows us to test without code changes.
137
138 To keep he java code and the native code in sync. The `main` method at the end of
139 [hat.backend.ffi.Config](https://github.com/openjdk/babylon/blob/code-reflection/hat/backends/ffi/shared/src/main/java/hat/backend/ffi/Config.java)
140 is actually used to create the C99 header for Cuda and OpenCL ffi-backends.
141
142 So whenever we change the Java config class we should run the main method to generate the header. This is not really robust, (but proved way better than trying to remember for all backends) but you need to know, if you add move config bits to the Java side.
143
144 The Main method uses a variant of the code builders used for C99 style code (CUDA/OpenCL) to generate the config.h header.
145
146 This is how we keep the ffi based backends in sync
147
148 Some more useful `config bits`
149
150 ```
151 HAT=PTX java @hat/run ffi-cuda ....
152 ```
153 Sends PTX generated by our prototype PTX generator to the backend (for CUDA) rather than C99 code.
154
155 ```
156 HAT=INFO java @hat/run ....
157 ```
158
159 Will dump all of the `config bits` from the native side.
160
161 At present this yields
162 ```
163 native minimizeCopies 0
164 native trace 0
165 native profile 0
166 native showCode 0
167 native showKernelModel 0
168 native showComputeModel 0
169 native info 1
170 native traceCopies 0
171 native traceSkippedCopies 0
172 native traceEnqueues 0
173 native traceCalls 0
174 native showWhy 0
175 native showState 0
176 native ptx 0
177 native interpret 0
178 ```
179 Generally the flags all represent single bits (except PLATFORM:n and DEVICE:n) and are set using comma separated uppercase+underscore string forms.
180
181
182 So to experiment with `minimizeCopies` and to `showCode` we set `HAT=MINIMIZE_COPIES,SHOW_CODE`