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 experiments;
 26 
 27 import hat.Accelerator;
 28 import hat.Accelerator.Compute;
 29 import hat.ComputeContext;
 30 import hat.NDRange;
 31 
 32 import static hat.KernelContext.*;
 33 import hat.backend.Backend;
 34 import hat.buffer.S32Array;
 35 import optkl.ifacemapper.MappableIface.RO;
 36 import optkl.ifacemapper.MappableIface.RW;
 37 import jdk.incubator.code.Reflect;
 38 
 39 import java.lang.invoke.MethodHandles;
 40 import java.util.stream.IntStream;
 41 
 42 /**
 43  * How to test?
 44  * <code>
 45  *     HAT=SHOW_CODE java -cp job.jar hat.java exp ffi-opencl LocalIds
 46  * </code>
 47  */
 48 public class LocalIds {
 49 
 50     private static boolean PRINT_RESULTS = false;
 51 
 52     @Reflect
 53     private static void assign(  S32Array arrayA, S32Array arrayB, S32Array arrayC) {
 54         int gx = GIX();
 55         int lx = LIX();
 56         int lsx = LSX();
 57         int bix = BIX();
 58         arrayA.array(gx, lx);
 59         arrayB.array(gx, lsx);
 60         arrayC.array(gx, bix);
 61     }
 62 
 63     private static final int BLOCK_SIZE = 16;
 64 
 65     @Reflect
 66     private static void mySimpleCompute(@RO ComputeContext cc,  @RW S32Array arrayA, @RW S32Array arrayB, @RW S32Array arrayC) {
 67         cc.dispatchKernel(NDRange.of1D(32,BLOCK_SIZE), () -> assign( arrayA, arrayB, arrayC));
 68     }
 69 
 70     public static void main(String[] args) {
 71         System.out.println("Experiment: local IDs and local groups");
 72 
 73         Accelerator accelerator = new Accelerator(MethodHandles.lookup(), Backend.FIRST);
 74         final int size = 32;
 75         S32Array arrayA = S32Array.create(accelerator, size);
 76         S32Array arrayB = S32Array.create(accelerator, size);
 77         S32Array arrayC = S32Array.create(accelerator, size);
 78 
 79         // Set initial value to 0
 80         arrayA.fill(i -> 0);
 81         arrayB.fill(i -> 0);
 82         arrayC.fill(i -> 0);
 83 
 84         // Compute on the accelerator
 85         accelerator.compute((@Reflect Compute)
 86                 cc -> LocalIds.mySimpleCompute(cc, arrayA, arrayB, arrayC));
 87 
 88         int[] expectedIds = new int[size];
 89         int j = 0;
 90         for (int i = 0; i < size; i++) {
 91             expectedIds[i] = j++;
 92             if (j == BLOCK_SIZE) {
 93                 j = 0;
 94             }
 95         }
 96 
 97         System.out.println("Execution finished");
 98 
 99         if (PRINT_RESULTS) {
100             System.out.println("Result Locals: ");
101             for (int i = 0; i < arrayA.length(); i++) {
102                 System.out.println(arrayA.array(i));
103             }
104             System.out.println("Result Blocks: ");
105             for (int i = 0; i < arrayB.length(); i++) {
106                 System.out.println(arrayB.array(i));
107             }
108             System.out.println("Result Block ID: ");
109             for (int i = 0; i < arrayC.length(); i++) {
110                 System.out.println(arrayC.array(i));
111             }
112         }
113 
114         boolean correct = true;
115         for (int i = 0; i < arrayA.length(); i++) {
116             if (expectedIds[i] != arrayA.array(i)) {
117                 System.out.println("Mismatch local ids");
118                 correct = false;
119             }
120         }
121         if (correct) {
122             System.out.println("Local IDs are correct");
123         }
124 
125 
126         correct = true;
127         for (int i = 0; i < arrayB.length(); i++) {
128             if (BLOCK_SIZE != arrayB.array(i)) {
129                 System.out.println("Mismatch group Sizes");
130                 correct = false;
131             }
132         }
133         if (correct) {
134             System.out.println("Group Size are correct");
135         }
136 
137         IntStream.range(0, size).forEach(i -> {
138             int v = i < BLOCK_SIZE ? 0 : 1;
139             expectedIds[i] = v;
140         });
141         for (int i = 0; i < arrayC.length(); i++) {
142             if (expectedIds[i] != arrayC.array(i)) {
143                 System.out.println("Mismatch group IDs");
144                 correct = false;
145             }
146         }
147         if (correct) {
148             System.out.println("Group IDs are correct");
149         }
150     }
151 
152 }