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