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
26 package experiments;
27
28 import hat.Accelerator;
29 import hat.Accelerator.Compute;
30 import hat.ComputeContext;
31 import hat.NDRange;
32
33 import static hat.KernelContext.*;
34 import hat.backend.Backend;
35 import hat.device.DeviceSchema;
36 import hat.device.NonMappableIface;
37 import hat.buffer.F32Array;
38 import optkl.ifacemapper.MappableIface.RO;
39 import jdk.incubator.code.Reflect;
40
41 import java.lang.invoke.MethodHandles;
42
43 /**
44 * Example of how to declare and use a custom data type in a method kernel on the GPU.
45 * This is just a proof of concept.
46 * <p>
47 * How to run?
48 * <code>
49 * HAT=SHOW_CODE java -cp job.jar hat.java exp ffi-opencl LocalArray
50 * HAT=SHOW_CODE java -cp job.jar hat.java exp ffi-cuda LocalArray
51 * </code>
52 * </p>
53 */
54 public class LocalArray {
55
56 private interface SharedMemory extends NonMappableIface {
57 void array(long index, float value);
58 float array(long index);
59
60 DeviceSchema<SharedMemory> deviceSchema = DeviceSchema.of(SharedMemory.class,
61 arr -> arr.array("array", 16));
62 static SharedMemory createLocal() {
63 return null;
64 }
65 }
66
67 @Reflect
68 private static void compute(F32Array data) {
69 SharedMemory mySharedArray = SharedMemory.createLocal();
70 int lix = LIX();
71 int blockId = BIX();
72 int blockSize = LSX();
73 mySharedArray.array(lix, lix);
74 barrier();
75 data.array(lix + (long) blockId * blockSize, mySharedArray.array(lix));
76 }
77
78 @Reflect
79 private static void myCompute(@RO ComputeContext computeContext, F32Array data) {
80 computeContext.dispatchKernel(NDRange.of1D(32,16),
81 () -> compute( data)
82 );
83 }
84
85 static void main() {
86 IO.println("Testing Shared Data Structures Mapping");
87 Accelerator accelerator = new Accelerator(MethodHandles.lookup(), Backend.FIRST);
88 F32Array data = F32Array.create(accelerator, 32);
89 accelerator.compute((@Reflect Compute) computeContext -> LocalArray.myCompute(computeContext, data));
90
91 // Check result
92 boolean isCorrect = true;
93 int jIndex = 0;
94 for (int i = 0; i < data.length(); i++) {
95 IO.println(data.array(i));
96 if (data.array(i) != jIndex) {
97 isCorrect = false;
98 break;
99 }
100 jIndex++;
101 if (jIndex == 16) {
102 jIndex = 0;
103 }
104 }
105 if (isCorrect) {
106 IO.println("Correct result");
107 } else {
108 IO.println("Wrong result");
109 }
110 }
111
112 }