1 /*
2 * Copyright (c) 2025-2026, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package hat.test;
26
27 import hat.Accelerator;
28 import hat.ComputeContext;
29 import hat.KernelContext;
30 import hat.NDRange;
31 import hat.backend.Backend;
32 import hat.types.BF16;
33 import hat.buffer.BF16Array;
34 import hat.device.DeviceSchema;
35 import hat.device.NonMappableIface;
36 import hat.test.annotation.HatTest;
37 import hat.test.exceptions.HATAssertionError;
38 import hat.test.exceptions.HATAsserts;
39 import hat.test.exceptions.HATExpectedPrecisionError;
40 import jdk.incubator.code.Reflect;
41 import optkl.ifacemapper.MappableIface.*;
42
43 import java.lang.invoke.MethodHandles;
44 import java.util.Random;
45
46 public class TestBFloat16Type {
47
48 @Reflect
49 public static void kernel_copy(KernelContext kernelContext, BF16Array a, BF16Array b) {
50 if (kernelContext.gix < kernelContext.gsx) {
51 BF16 ha = a.array(kernelContext.gix);
52 b.array(kernelContext.gix).value(ha.value());
53 }
54 }
55
56 @Reflect
57 public static void bf16_02(KernelContext kernelContext, BF16Array a, BF16Array b, BF16Array c) {
58 if (kernelContext.gix < kernelContext.gsx) {
59 BF16 ha = a.array(kernelContext.gix);
60 BF16 hb = b.array(kernelContext.gix);
61 BF16 result = BF16.add(ha, hb);
62 BF16 hc = c.array(kernelContext.gix);
63 hc.value(result.value());
64 }
65 }
66
67 @Reflect
68 public static void bf16_03(KernelContext kernelContext, BF16Array a, BF16Array b, BF16Array c) {
69 if (kernelContext.gix < kernelContext.gsx) {
70 BF16 ha = a.array(kernelContext.gix);
71 BF16 hb = b.array(kernelContext.gix);
72
73 BF16 result = BF16.add(ha, BF16.add(hb, hb));
74 BF16 hC = c.array(kernelContext.gix);
75 hC.value(result.value());
76 }
77 }
78
79 @Reflect
80 public static void bf16_04(KernelContext kernelContext, BF16Array a, BF16Array b, BF16Array c) {
81 if (kernelContext.gix < kernelContext.gsx) {
82 BF16 ha = a.array(kernelContext.gix);
83 BF16 hb = b.array(kernelContext.gix);
84
85 BF16 r1 = BF16.mul(ha, hb);
86 BF16 r2 = BF16.div(ha, hb);
87 BF16 r3 = BF16.sub(ha, hb);
88 BF16 r4 = BF16.add(r1, r2);
89 BF16 r5 = BF16.add(r4, r3);
90 BF16 hC = c.array(kernelContext.gix);
91 hC.value(r5.value());
92 }
93 }
94
95 @Reflect
96 public static void bf16_05(KernelContext kernelContext, BF16Array a) {
97 if (kernelContext.gix < kernelContext.gsx) {
98 BF16 ha = a.array(kernelContext.gix);
99 BF16 initVal = BF16.of( 2.1f);
100 ha.value(initVal.value());
101 }
102 }
103
104 @Reflect
105 public static void bf16_06(KernelContext kernelContext, BF16Array a) {
106 if (kernelContext.gix < kernelContext.gsx) {
107 BF16 initVal = BF16.of(kernelContext.gix);
108 BF16 ha = a.array(kernelContext.gix);
109 ha.value(initVal.value());
110 }
111 }
112
113 @Reflect
114 public static void bf16_08(KernelContext kernelContext, BF16Array a) {
115 if (kernelContext.gix < kernelContext.gsx) {
116 BF16 initVal = BF16.float2bfloat16(kernelContext.gix);
117 BF16 ha = a.array(kernelContext.gix);
118 ha.value(initVal.value());
119 }
120 }
121
122 @Reflect
123 public static void bf16_09(KernelContext kernelContext, BF16Array a, BF16Array b) {
124 if (kernelContext.gix < kernelContext.gsx) {
125 BF16 ha = a.array(kernelContext.gix);
126 float f = BF16.bfloat162float(ha);
127 BF16 result = BF16.float2bfloat16(f);
128 BF16 hb = b.array(kernelContext.gix);
129 hb.value(result.value());
130 }
131 }
132
133 @Reflect
134 public static void bf16_10(KernelContext kernelContext, BF16Array a) {
135 if (kernelContext.gix < kernelContext.gsx) {
136 BF16 ha = a.array(kernelContext.gix);
137 BF16 f16 = BF16.of(1.1f);
138 float f = BF16.bfloat162float(f16);
139 BF16 result = BF16.float2bfloat16(f);
140 ha.value(result.value());
141 }
142 }
143
144 public interface LocalArray extends NonMappableIface {
145 BF16 array(int index);
146 DeviceSchema<LocalArray> deviceSchema = DeviceSchema.of(LocalArray.class,
147 builder -> builder.array("array", 1024, bfloat16 -> bfloat16.field("value")));
148
149 static LocalArray create(Accelerator accelerator) {
150 return null;
151 }
152
153 static LocalArray createLocal() {
154 return null;
155 }
156 }
157
158 @Reflect
159 public static void bf16_11(KernelContext kernelContext, BF16Array a, BF16Array b) {
160 LocalArray sm = LocalArray.createLocal();
161 if (kernelContext.gix < kernelContext.gsx) {
162 int lix = kernelContext.lix;
163 BF16 ha = a.array(kernelContext.gix);
164
165 sm.array(lix).value(ha.value());
166 kernelContext.barrier();
167
168 BF16 hb = sm.array(lix);
169 b.array(kernelContext.gix).value(hb.value());
170 }
171 }
172
173 @Reflect
174 public static void bf16_12(KernelContext kernelContext, BF16Array a, BF16Array b, BF16Array c) {
175 // Test the fluent API style
176 if (kernelContext.gix < kernelContext.gsx) {
177 BF16 ha = a.array(kernelContext.gix);
178 BF16 hb = b.array(kernelContext.gix);
179 BF16 result = BF16.add(ha,hb);
180 c.array(kernelContext.gix).value(result.value());
181 }
182 }
183
184 @Reflect
185 public static void bf16_13(KernelContext kernelContext, BF16Array a, BF16Array b, BF16Array c) {
186 // Test the fluent API style
187 if (kernelContext.gix < kernelContext.gsx) {
188 BF16 ha = a.array(kernelContext.gix);
189 BF16 hb = b.array(kernelContext.gix);
190 BF16 result = BF16.div(BF16.mul(BF16.sub(BF16.add(ha,hb),hb),ha),ha);
191 c.array(kernelContext.gix).value(result.value());
192 }
193 }
194
195 @Reflect
196 public static void bf16_14(KernelContext kernelContext, BF16Array a, BF16Array b) {
197 // Testing mixed float types
198 if (kernelContext.gix < kernelContext.gsx) {
199 BF16 ha = a.array(kernelContext.gix);
200 float myFloat = 32.1f;
201 BF16 result = BF16.add(myFloat, ha);
202 b.array(kernelContext.gix).value(result.value());
203 }
204 }
205
206 public interface PrivateArray extends NonMappableIface {
207 BF16 array(int index);
208 DeviceSchema<PrivateArray> deviceSchema = DeviceSchema.of(PrivateArray.class,
209 builder -> builder.array("array", 256, bfloat16 -> bfloat16.field("value")));
210
211 static PrivateArray create(Accelerator accelerator) {
212 return null;
213 }
214
215 static PrivateArray createPrivate() {
216 return null;
217 }
218 }
219
220 @Reflect
221 public static void bf16_15(KernelContext kernelContext, BF16Array a, BF16Array b) {
222 PrivateArray privateArray = PrivateArray.createPrivate();
223 if (kernelContext.gix < kernelContext.gsx) {
224 int lix = kernelContext.lix;
225 BF16 ha = a.array(kernelContext.gix);
226 privateArray.array(lix).value(ha.value());
227 BF16 hb = privateArray.array(lix);
228 b.array(kernelContext.gix).value(hb.value());
229 }
230 }
231
232 @Reflect
233 public static void bf16_16(KernelContext kernelContext, BF16Array a) {
234 BF16 ha = a.array(0);
235 BF16 hre = BF16.add(ha, ha);
236 hre = BF16.add(hre, hre);
237 a.array(0).value(hre.value());
238 }
239
240 @Reflect
241 public static void bf16_17(KernelContext kernelContext, BF16Array a) {
242
243 BF16 ha = a.array(0);
244 PrivateArray privateArray = PrivateArray.createPrivate();
245 privateArray.array(0).value(ha.value());
246
247 // Obtain the value from private memory
248 BF16 acc = privateArray.array(0);
249
250 // compute
251 acc = BF16.add(acc, acc);
252
253 // store the result
254 a.array(0).value(acc.value());
255 }
256
257 @Reflect
258 public static void compute01(@RO ComputeContext computeContext, @RO BF16Array a, @WO BF16Array b) {
259 computeContext.dispatchKernel(NDRange.of1D(a.length()), kernelContext -> TestBFloat16Type.kernel_copy(kernelContext, a, b));
260 }
261
262 @Reflect
263 public static void compute02(@RO ComputeContext computeContext, @RO BF16Array a, @RO BF16Array b, @WO BF16Array c) {
264 computeContext.dispatchKernel(NDRange.of1D(a.length()),
265 kernelContext -> TestBFloat16Type.bf16_02(kernelContext, a, b, c));
266 }
267
268 @Reflect
269 public static void compute03(@RO ComputeContext computeContext, @RO BF16Array a, @RO BF16Array b, @WO BF16Array c) {
270 computeContext.dispatchKernel(NDRange.of1D(a.length()),
271 kernelContext -> TestBFloat16Type.bf16_03(kernelContext, a, b, c));
272 }
273
274 @Reflect
275 public static void compute04(@RO ComputeContext computeContext, @RO BF16Array a, @RO BF16Array b, @WO BF16Array c) {
276 computeContext.dispatchKernel(NDRange.of1D(a.length()),
277 kernelContext -> TestBFloat16Type.bf16_04(kernelContext, a, b, c));
278 }
279
280 @Reflect
281 public static void compute05(@RO ComputeContext computeContext, @WO BF16Array a) {
282 computeContext.dispatchKernel(NDRange.of1D(a.length()), kernelContext -> TestBFloat16Type.bf16_05(kernelContext, a));
283 }
284
285 @Reflect
286 public static void compute06(@RO ComputeContext computeContext, @WO BF16Array a) {
287 computeContext.dispatchKernel(NDRange.of1D(a.length()), kernelContext -> TestBFloat16Type.bf16_06(kernelContext, a));
288 }
289
290 @Reflect
291 public static void compute08(@RO ComputeContext computeContext, @WO BF16Array a) {
292 computeContext.dispatchKernel(NDRange.of1D(a.length()), kernelContext -> TestBFloat16Type.bf16_08(kernelContext, a));
293 }
294
295 @Reflect
296 public static void compute09(@RO ComputeContext computeContext, @RW BF16Array a, @WO BF16Array b) {
297 computeContext.dispatchKernel(NDRange.of1D(a.length()), kernelContext -> TestBFloat16Type.bf16_09(kernelContext, a, b));
298 }
299
300 @Reflect
301 public static void compute10(@RO ComputeContext computeContext, @WO BF16Array a) {
302 computeContext.dispatchKernel(NDRange.of1D(a.length()), kernelContext -> TestBFloat16Type.bf16_10(kernelContext, a));
303 }
304
305 @Reflect
306 public static void compute11(@RO ComputeContext computeContext, @RO BF16Array a, @WO BF16Array b) {
307 computeContext.dispatchKernel(NDRange.of1D(a.length(),16), kernelContext -> TestBFloat16Type.bf16_11(kernelContext, a, b));
308 }
309
310 @Reflect
311 public static void compute12(@RO ComputeContext computeContext, @RO BF16Array a, @RO BF16Array b, @WO BF16Array c) {
312 computeContext.dispatchKernel(NDRange.of1D(a.length()), kernelContext -> TestBFloat16Type.bf16_12(kernelContext, a, b, c));
313 }
314
315 @Reflect
316 public static void compute13(@RO ComputeContext computeContext, @RO BF16Array a, @RO BF16Array b, @WO BF16Array c) {
317 computeContext.dispatchKernel(NDRange.of1D(a.length()), kernelContext -> TestBFloat16Type.bf16_13(kernelContext, a, b, c));
318 }
319
320 @Reflect
321 public static void compute14(@RO ComputeContext computeContext, @RO BF16Array a, @WO BF16Array b) {
322 computeContext.dispatchKernel(NDRange.of1D(a.length()), kernelContext -> TestBFloat16Type.bf16_14(kernelContext, a, b));
323 }
324
325 @Reflect
326 public static void compute15(@RO ComputeContext computeContext, @RO BF16Array a, @WO BF16Array b) {
327 computeContext.dispatchKernel(NDRange.of1D(a.length()), kernelContext -> TestBFloat16Type.bf16_15(kernelContext, a, b));
328 }
329
330 @Reflect
331 public static void compute16(@RO ComputeContext computeContext, @RW BF16Array a) {
332 computeContext.dispatchKernel(NDRange.of1D(1), kernelContext -> TestBFloat16Type.bf16_16(kernelContext, a));
333 }
334
335 @Reflect
336 public static void compute17(@RO ComputeContext computeContext, @RW BF16Array a) {
337 computeContext.dispatchKernel(NDRange.of1D(1), kernelContext -> TestBFloat16Type.bf16_17(kernelContext, a));
338 }
339
340 @HatTest
341 @Reflect
342 public void test_bfloat16_01() {
343 final int size = 256;
344 var accelerator = new Accelerator(MethodHandles.lookup(), Backend.FIRST);
345
346 BF16Array arrayA = BF16Array.create(accelerator, size);
347 BF16Array arrayB = BF16Array.create(accelerator, size);
348 for (int i = 0; i < size; i++) {
349 arrayA.array(i).value(BF16.float2bfloat16(i).value());
350 }
351
352 accelerator.compute(computeContext -> TestBFloat16Type.compute01(computeContext, arrayA, arrayB));
353
354 for (int i = 0; i < size; i++) {
355 BF16 result = arrayB.array(i);
356 HATAsserts.assertEquals((float)i, BF16.bfloat162float(result), 0.001f);
357 }
358 }
359
360 @HatTest
361 @Reflect
362 public void test_bfloat16_02() {
363 final int size = 256;
364 var accelerator = new Accelerator(MethodHandles.lookup(), Backend.FIRST);
365
366 BF16Array arrayA = BF16Array.create(accelerator, size);
367 BF16Array arrayB = BF16Array.create(accelerator, size);
368 BF16Array arrayC = BF16Array.create(accelerator, size);
369
370 Random r = new Random(19);
371 for (int i = 0; i < size; i++) {
372 arrayA.array(i).value(BF16.float2bfloat16(r.nextFloat()).value());
373 arrayA.array(i).value(BF16.float2bfloat16(r.nextFloat()).value());
374 }
375
376 accelerator.compute(computeContext -> TestBFloat16Type.compute02(computeContext, arrayA, arrayB, arrayC));
377
378 for (int i = 0; i < size; i++) {
379 BF16 result = arrayC.array(i);
380 BF16 a = arrayA.array(i);
381 BF16 b = arrayB.array(i);
382 float res = BF16.bfloat162float(a) + BF16.bfloat162float(b);
383 HATAsserts.assertEquals(res, BF16.bfloat162float(result), 0.001f);
384 }
385 }
386 @HatTest
387 @Reflect
388 public void test_bfloat16_03() {
389 var accelerator = new Accelerator(MethodHandles.lookup(), Backend.FIRST);
390
391 final int size = 256;
392 BF16Array arrayA = BF16Array.create(accelerator, size);
393 BF16Array arrayB = BF16Array.create(accelerator, size);
394 BF16Array arrayC = BF16Array.create(accelerator, size);
395
396 Random random = new Random();
397 for (int i = 0; i < arrayA.length(); i++) {
398 arrayA.array(i).value(BF16.float2bfloat16(random.nextFloat()).value());
399 arrayB.array(i).value(BF16.float2bfloat16(random.nextFloat()).value());
400 }
401
402 accelerator.compute(computeContext -> TestBFloat16Type.compute03(computeContext, arrayA, arrayB, arrayC));
403
404 for (int i = 0; i < arrayC.length(); i++) {
405 BF16 val = arrayC.array(i);
406 float fa = BF16.bfloat162float(arrayA.array(i));
407 float fb = BF16.bfloat162float(arrayB.array(i));
408 HATAsserts.assertEquals((fa + fb + fb), BF16.bfloat162float(val), 0.01f);
409 }
410 }
411
412 @HatTest
413 @Reflect
414 public void test_bfloat16_04() {
415 var accelerator = new Accelerator(MethodHandles.lookup(), Backend.FIRST);
416
417 final int size = 256;
418 BF16Array arrayA = BF16Array.create(accelerator, size);
419 BF16Array arrayB = BF16Array.create(accelerator, size);
420 BF16Array arrayC = BF16Array.create(accelerator, size);
421
422 Random random = new Random();
423 for (int i = 0; i < arrayA.length(); i++) {
424 arrayA.array(i).value(BF16.float2bfloat16(random.nextFloat()).value());
425 arrayB.array(i).value(BF16.float2bfloat16(random.nextFloat()).value());
426 }
427
428 accelerator.compute(computeContext -> {
429 TestBFloat16Type.compute04(computeContext, arrayA, arrayB, arrayC);
430 });
431
432 for (int i = 0; i < arrayC.length(); i++) {
433 BF16 gotResult = arrayC.array(i);
434
435 // CPU Computation
436 BF16 ha = arrayA.array(i);
437 BF16 hb = arrayB.array(i);
438 BF16 r1 = BF16.mul(ha, hb);
439 BF16 r2 = BF16.div(ha, hb);
440 BF16 r3 = BF16.sub(ha, hb);
441 BF16 r4 = BF16.add(r1, r2);
442 BF16 r5 = BF16.add(r4, r3);
443
444 HATAsserts.assertEquals(BF16.bfloat162float(r5), BF16.bfloat162float(gotResult), 0.01f);
445 }
446 }
447
448 @HatTest
449 @Reflect
450 public void test_bfloat16_05() {
451 var accelerator = new Accelerator(MethodHandles.lookup(), Backend.FIRST);
452
453 final int size = 16;
454 BF16Array arrayA = BF16Array.create(accelerator, size);
455 for (int i = 0; i < arrayA.length(); i++) {
456 arrayA.array(i).value(BF16.float2bfloat16(0.0f).value());
457 }
458
459 accelerator.compute(computeContext -> {
460 TestBFloat16Type.compute05(computeContext, arrayA);
461 });
462
463 for (int i = 0; i < arrayA.length(); i++) {
464 BF16 val = arrayA.array(i);
465 HATAsserts.assertEquals(2.1f, BF16.bfloat162float(val), 0.01f);
466 }
467 }
468
469 @HatTest
470 @Reflect
471 public void test_bfloat16_06() {
472 var accelerator = new Accelerator(MethodHandles.lookup(), Backend.FIRST);
473
474 final int size = 512;
475 BF16Array arrayA = BF16Array.create(accelerator, size);
476 for (int i = 0; i < arrayA.length(); i++) {
477 arrayA.array(i).value(BF16.float2bfloat16(0.0f).value());
478 }
479
480 accelerator.compute(computeContext -> {
481 TestBFloat16Type.compute06(computeContext, arrayA);
482 });
483
484 for (int i = 0; i < arrayA.length(); i++) {
485 BF16 val = arrayA.array(i);
486 try {
487 HATAsserts.assertEquals(i, BF16.bfloat162float(val), 0.01f);
488 } catch (HATAssertionError hatAssertionError) {
489 throw new HATExpectedPrecisionError(hatAssertionError.getMessage());
490 }
491
492 }
493 }
494
495 @HatTest
496 @Reflect
497 public void test_bfloat16_07() {
498 // Test CPU Implementation of BF16
499 BF16 a = BF16.of(2.5f);
500 BF16 b = BF16.of(3.5f);
501 BF16 c = BF16.add(a, b);
502 HATAsserts.assertEquals((2.5f + 3.5f), BF16.bfloat162float(c), 0.01f);
503
504 BF16 d = BF16.sub(a, b);
505 HATAsserts.assertEquals((2.5f - 3.5f), BF16.bfloat162float(d), 0.01f);
506
507 BF16 e = BF16.mul(a, b);
508 HATAsserts.assertEquals((2.5f * 3.5f), BF16.bfloat162float(e), 0.01f);
509
510 BF16 f = BF16.div(a, b);
511 HATAsserts.assertEquals((2.5f / 3.5f), BF16.bfloat162float(f), 0.01f);
512 }
513
514 @HatTest
515 @Reflect
516 public void test_bfloat16_08() {
517 var accelerator = new Accelerator(MethodHandles.lookup(), Backend.FIRST);
518
519 final int size = 256;
520 BF16Array arrayA = BF16Array.create(accelerator, size);
521 for (int i = 0; i < arrayA.length(); i++) {
522 arrayA.array(i).value(BF16.float2bfloat16(0.0f).value());
523 }
524
525 accelerator.compute(computeContext -> {
526 TestBFloat16Type.compute08(computeContext, arrayA);
527 });
528
529 for (int i = 0; i < arrayA.length(); i++) {
530 BF16 val = arrayA.array(i);
531 HATAsserts.assertEquals(i, BF16.bfloat162float(val), 0.01f);
532 }
533 }
534
535 @HatTest
536 @Reflect
537 public void test_bfloat16_09() {
538 var accelerator = new Accelerator(MethodHandles.lookup(), Backend.FIRST);
539
540 final int size = 16;
541 BF16Array arrayA = BF16Array.create(accelerator, size);
542 BF16Array arrayB = BF16Array.create(accelerator, size);
543
544 Random r = new Random(73);
545 for (int i = 0; i < arrayA.length(); i++) {
546 arrayA.array(i).value(BF16.float2bfloat16(r.nextFloat()).value());
547 }
548
549 accelerator.compute(computeContext -> TestBFloat16Type.compute09(computeContext, arrayA, arrayB));
550
551 for (int i = 0; i < arrayB.length(); i++) {
552 BF16 val = arrayB.array(i);
553 HATAsserts.assertEquals(BF16.bfloat162float(arrayA.array(i)), BF16.bfloat162float(val), 0.01f);
554 }
555 }
556
557 @HatTest
558 @Reflect
559 public void test_bfloat16_10() {
560 var accelerator = new Accelerator(MethodHandles.lookup(), Backend.FIRST);
561 final int size = 256;
562 BF16Array arrayA = BF16Array.create(accelerator, size);
563
564 accelerator.compute(computeContext -> TestBFloat16Type.compute10(computeContext, arrayA));
565
566 for (int i = 0; i < arrayA.length(); i++) {
567 BF16 val = arrayA.array(i);
568 HATAsserts.assertEquals(1.1f, BF16.bfloat162float(val), 0.01f);
569 }
570 }
571
572 @HatTest
573 @Reflect
574 public void test_bfloat16_11() {
575 var accelerator = new Accelerator(MethodHandles.lookup(), Backend.FIRST);
576 final int size = 256;
577 BF16Array arrayA = BF16Array.create(accelerator, size);
578 BF16Array arrayB = BF16Array.create(accelerator, size);
579
580 Random r = new Random(73);
581 for (int i = 0; i < arrayA.length(); i++) {
582 arrayA.array(i).value(BF16.float2bfloat16(r.nextFloat()).value());
583 }
584
585 accelerator.compute(computeContext -> TestBFloat16Type.compute11(computeContext, arrayA, arrayB));
586
587 for (int i = 0; i < arrayB.length(); i++) {
588 BF16 val = arrayB.array(i);
589 HATAsserts.assertEquals(arrayA.array(i).value(), val.value());
590 }
591 }
592
593 @HatTest
594 @Reflect
595 public void test_bfloat16_12() {
596 var accelerator = new Accelerator(MethodHandles.lookup(), Backend.FIRST);
597 final int size = 1024;
598 BF16Array arrayA = BF16Array.create(accelerator, size);
599 BF16Array arrayB = BF16Array.create(accelerator, size);
600 BF16Array arrayC = BF16Array.create(accelerator, size);
601
602 Random r = new Random(73);
603 for (int i = 0; i < arrayA.length(); i++) {
604 arrayA.array(i).value(BF16.float2bfloat16(r.nextFloat()).value());
605 arrayB.array(i).value(BF16.float2bfloat16(r.nextFloat()).value());
606 }
607
608 accelerator.compute(computeContext -> TestBFloat16Type.compute12(computeContext, arrayA, arrayB, arrayC));
609
610 for (int i = 0; i < arrayB.length(); i++) {
611 BF16 result = arrayC.array(i);
612 HATAsserts.assertEquals(BF16.bfloat162float(BF16.add(arrayA.array(i), arrayB.array(i))), BF16.bfloat162float(result), 0.01f);
613 }
614 }
615
616 @HatTest
617 @Reflect
618 public void test_bfloat16_13() {
619 var accelerator = new Accelerator(MethodHandles.lookup(), Backend.FIRST);
620 final int size = 1024;
621 BF16Array arrayA = BF16Array.create(accelerator, size);
622 BF16Array arrayB = BF16Array.create(accelerator, size);
623 BF16Array arrayC = BF16Array.create(accelerator, size);
624
625 Random r = new Random(73);
626 for (int i = 0; i < arrayA.length(); i++) {
627 arrayA.array(i).value(BF16.float2bfloat16(r.nextFloat()).value());
628 arrayB.array(i).value(BF16.float2bfloat16(r.nextFloat()).value());
629 }
630
631 accelerator.compute(computeContext -> TestBFloat16Type.compute13(computeContext, arrayA, arrayB, arrayC));
632
633 for (int i = 0; i < arrayB.length(); i++) {
634 BF16 result = arrayC.array(i);
635 HATAsserts.assertEquals(BF16.bfloat162float(arrayA.array(i)), BF16.bfloat162float(result), 0.01f);
636 }
637 }
638
639 @HatTest
640 @Reflect
641 public void test_bfloat16_14() {
642 // Testing mixed types
643 var accelerator = new Accelerator(MethodHandles.lookup(), Backend.FIRST);
644 final int size = 1024;
645 BF16Array arrayA = BF16Array.create(accelerator, size);
646 BF16Array arrayB = BF16Array.create(accelerator, size);
647
648 Random r = new Random(73);
649 for (int i = 0; i < arrayA.length(); i++) {
650 arrayA.array(i).value(BF16.float2bfloat16(r.nextFloat()).value());
651 }
652
653 accelerator.compute(computeContext -> TestBFloat16Type.compute14(computeContext, arrayA, arrayB));
654
655 for (int i = 0; i < arrayB.length(); i++) {
656 BF16 result = arrayB.array(i);
657 try {
658 HATAsserts.assertEquals(BF16.bfloat162float(arrayA.array(i)) + 32.1f, BF16.bfloat162float(result), 0.1f);
659 } catch (HATAssertionError hatAssertionError) {
660 throw new HATExpectedPrecisionError(hatAssertionError.getMessage());
661 }
662 }
663 }
664
665 @HatTest
666 @Reflect
667 public void test_bfloat16_15() {
668 var accelerator = new Accelerator(MethodHandles.lookup(), Backend.FIRST);
669 final int size = 256;
670 BF16Array arrayA = BF16Array.create(accelerator, size);
671 BF16Array arrayB = BF16Array.create(accelerator, size);
672
673 Random r = new Random(73);
674 for (int i = 0; i < arrayA.length(); i++) {
675 arrayA.array(i).value(BF16.float2bfloat16(r.nextFloat()).value());
676 }
677
678 accelerator.compute(computeContext -> TestBFloat16Type.compute15(computeContext, arrayA, arrayB));
679
680 for (int i = 0; i < arrayB.length(); i++) {
681 BF16 val = arrayB.array(i);
682 HATAsserts.assertEquals(arrayA.array(i).value(), val.value());
683 }
684 }
685
686 // Check accumulators
687 @HatTest
688 @Reflect
689 public void test_bfloat16_16() {
690 var accelerator = new Accelerator(MethodHandles.lookup(), Backend.FIRST);
691 final int size = 1;
692 BF16Array arrayA = BF16Array.create(accelerator, size);
693
694 Random r = new Random(73);
695 arrayA.array(0).value(BF16.float2bfloat16(10).value());
696
697 accelerator.compute(computeContext -> TestBFloat16Type.compute16(computeContext, arrayA));
698
699 BF16 val = arrayA.array(0);
700 HATAsserts.assertEquals(40.0f, BF16.bfloat162float(val), 0.01f);
701 }
702
703 // Check accumulators in private memory
704 @HatTest
705 @Reflect
706 public void test_bfloat16_17() {
707 var accelerator = new Accelerator(MethodHandles.lookup(), Backend.FIRST);
708 final int size = 1;
709 BF16Array arrayA = BF16Array.create(accelerator, size);
710
711 Random r = new Random(73);
712 arrayA.array(0).value(BF16.float2bfloat16(10).value());
713
714 accelerator.compute(computeContext -> TestBFloat16Type.compute17(computeContext, arrayA));
715
716 BF16 val = arrayA.array(0);
717 HATAsserts.assertEquals(20.0f, BF16.bfloat162float(val), 0.01f);
718 }
719
720 }