1 /*
2 * Copyright (c) 2025, 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.buffer.F32Array;
33 import hat.buffer.S32Array;
34 import hat.test.annotation.HatTest;
35 import hat.test.exceptions.HATAsserts;
36 import jdk.incubator.code.Reflect;
37 import optkl.ifacemapper.MappableIface.RO;
38 import optkl.ifacemapper.MappableIface.RW;
39 import optkl.ifacemapper.MappableIface.WO;
40
41 import java.lang.invoke.MethodHandles;
42 import java.util.Random;
43
44 public class TestArrays {
45
46 @Reflect
47 public static int squareit(int v) {
48 return v * v;
49
50 }
51
52 @Reflect
53 public static void squareKernel(KernelContext kc, S32Array array) {
54 if (kc.gix < kc.gsx) {
55 int value = array.array(kc.gix);
56 array.array(kc.gix, squareit(value));
57 }
58 }
59
60 @Reflect
61 public static void square(@RO ComputeContext cc, @RW S32Array array) {
62 cc.dispatchKernel(NDRange.of1D(array.length()),
63 kc -> squareKernel(kc, array)
64 );
65 }
66
67 @Reflect
68 public static void vectorAddition(KernelContext kc, S32Array arrayA, S32Array arrayB, S32Array arrayC) {
69 if (kc.gix < kc.gsx) {
70 int valueA = arrayA.array(kc.gix);
71 int valueB = arrayB.array(kc.gix);
72 arrayC.array(kc.gix, (valueA + valueB));
73 }
74 }
75
76 @Reflect
77 public static void vectorAdd(@RO ComputeContext cc, @RO S32Array arrayA, @RO S32Array arrayB, @WO S32Array arrayC) {
78 cc.dispatchKernel(NDRange.of1D(arrayA.length()),
79 kc -> vectorAddition(kc, arrayA, arrayB, arrayC)
80 );
81 }
82
83 @Reflect
84 public static void saxpy(KernelContext kc, F32Array arrayA, F32Array arrayB, F32Array arrayC, float alpha) {
85 if (kc.gix < kc.gsx) {
86 float valueA = arrayA.array(kc.gix);
87 float valueB = arrayB.array(kc.gix);
88 float result = alpha * valueA + valueB;
89 arrayC.array(kc.gix, result);
90 }
91 }
92
93 @Reflect
94 public static void computeSaxpy(@RO ComputeContext cc, @RO F32Array arrayA, @RO F32Array arrayB, @RW F32Array arrayC, float alpha) {
95 cc.dispatchKernel(NDRange.of1D(arrayA.length()),
96 kc -> saxpy(kc, arrayA, arrayB, arrayC, alpha)
97 );
98 }
99
100 @HatTest
101 @Reflect
102 public static void testHelloHat() {
103 final int size = 64;
104 var accelerator = new Accelerator(MethodHandles.lookup(), Backend.FIRST);
105 var array = S32Array.create(accelerator, size);
106
107 // Initialize array
108 for (int i = 0; i < array.length(); i++) {
109 array.array(i, i);
110 }
111
112 // Blocking call
113 accelerator.compute(cc -> TestArrays.square(cc, array));
114
115 S32Array test = S32Array.create(accelerator, size);
116
117 for (int i = 0; i < test.length(); i++) {
118 test.array(i, squareit(i));
119 }
120
121 for (int i = 0; i < test.length(); i++) {
122 HATAsserts.assertEquals(test.array(i), array.array(i));
123 }
124 }
125
126 @HatTest
127 @Reflect
128 public static void testVectorAddition() {
129 final int size = 8192;
130 var accelerator = new Accelerator(MethodHandles.lookup(), Backend.FIRST);
131 var arrayA = S32Array.create(accelerator, size);
132 var arrayB = S32Array.create(accelerator, size);
133 var arrayC = S32Array.create(accelerator, size);
134
135 // Initialize array
136 arrayA.fill(i -> i);
137 arrayB.fill(i -> 100 + i);
138
139 accelerator.compute(cc ->
140 TestArrays.vectorAdd(cc, arrayA, arrayB, arrayC));
141
142 S32Array test = S32Array.create(accelerator, size);
143
144 for (int i = 0; i < test.length(); i++) {
145 test.array(i, arrayA.array(i) + arrayB.array(i));
146 }
147
148 for (int i = 0; i < test.length(); i++) {
149 HATAsserts.assertEquals(test.array(i), arrayC.array(i));
150 }
151 }
152
153 @HatTest
154 @Reflect
155 public static void testVectorSaxpy() {
156 final int size = 8192;
157 var accelerator = new Accelerator(MethodHandles.lookup(), Backend.FIRST);
158 var arrayA = F32Array.create(accelerator, size);
159 var arrayB = F32Array.create(accelerator, size);
160 var arrayC = F32Array.create(accelerator, size);
161
162 // Initialize array
163 Random r = new Random(71);
164 for (int i = 0; i < arrayA.length(); i++) {
165 arrayA.array(i, r.nextFloat());
166 arrayB.array(i, r.nextFloat());
167 }
168
169 var alpha = 0.2f;
170 accelerator.compute(cc ->
171 TestArrays.computeSaxpy(cc, arrayA, arrayB, arrayC, alpha));
172
173 F32Array test = F32Array.create(accelerator, size);
174
175 for (int i = 0; i < test.length(); i++) {
176 test.array(i, alpha * arrayA.array(i) + arrayB.array(i));
177 }
178
179 for (int i = 0; i < test.length(); i++) {
180 HATAsserts.assertEquals(test.array(i), arrayC.array(i), 0.01f);
181 }
182 }
183
184 @HatTest
185 @Reflect
186 public static void testSmallGrid() {
187
188 final int size = 50;
189 var accelerator = new Accelerator(MethodHandles.lookup(), Backend.FIRST);
190 var arrayA = F32Array.create(accelerator, size);
191 var arrayB = F32Array.create(accelerator, size);
192 var arrayC = F32Array.create(accelerator, size);
193
194 // Initialize array
195 Random r = new Random(71);
196 for (int i = 0; i < arrayA.length(); i++) {
197 arrayA.array(i, r.nextFloat());
198 arrayB.array(i, r.nextFloat());
199 }
200
201 var alpha = 0.2f;
202 accelerator.compute(cc ->
203 TestArrays.computeSaxpy(cc, arrayA, arrayB, arrayC, alpha));
204
205 F32Array test = F32Array.create(accelerator, size);
206
207 for (int i = 0; i < test.length(); i++) {
208 test.array(i, alpha * arrayA.array(i) + arrayB.array(i));
209 }
210
211 for (int i = 0; i < test.length(); i++) {
212 HATAsserts.assertEquals(test.array(i), arrayC.array(i), 0.01f);
213 }
214 }
215
216 }