1 /*
   2  * Copyright (c) 2011, 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.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 package com.oracle.graal.compiler.hsail.test;
  24 
  25 import org.junit.*;
  26 
  27 import com.oracle.graal.compiler.test.GraalCompilerTest;
  28 import com.oracle.graal.compiler.hsail.HSAILCompilationResult;
  29 import com.oracle.graal.nodes.StructuredGraph;
  30 
  31 /**
  32  * Test class for small Java methods compiled to HSAIL kernels.
  33  */
  34 public class BasicHSAILTest extends GraalCompilerTest {
  35 
  36     public void testAdd() {
  37         test("testAddSnippet");
  38     }
  39 
  40     public static int testAddSnippet(int a) {
  41         return a * a;
  42     }
  43 
  44     public void testArrayConstantIndex() {
  45         test("testArrayReturnFirstElement");
  46     }
  47 
  48     public void testArrayVariableIndex() {
  49         test("testArrayReturnIthElement");
  50     }
  51 
  52     public void testArrayMultiplyConstant() {
  53         test("testArrayMultiplyZero");
  54     }
  55 
  56     public void testArrayMultiplyVar() {
  57         test("testArrayMultiplyGid");
  58     }
  59 
  60     public void testArrayMisc() {
  61         test("testArrayLocalVariable");
  62     }
  63 
  64     public void testArrayLoopVar() {
  65         test("testArrayMultiplyGidLoop");
  66     }
  67 
  68     void setupPalette(int[] in) {
  69         for (int i = 0; i < in.length; i++) {
  70             in[i] = i;
  71         }
  72     }
  73 
  74     public void testNBody() {
  75         test("nBodySpill");
  76     }
  77 
  78     public void testArrayMandel() {
  79         final int width = 768;
  80         final int height = width;
  81         int loopiterations = 1;
  82         int counter = 0;
  83         final int range = width * height;
  84         int[] rgb = new int[range];
  85         int[] palette = new int[range];
  86         setupPalette(palette);
  87         while (counter < loopiterations) {
  88             for (int gid = 0; gid < range; gid++) {
  89                 testMandelSimple(rgb, palette, -1.0f, 0.0f, 3f, gid);
  90             }
  91             counter++;
  92         }
  93         test("testMandelSimple");
  94     }
  95 
  96     public void testDanglingElse() {
  97         test("danglingElse");
  98     }
  99 
 100     public void testIntSquaresTernary() {
 101         test("intSquaresTernary");
 102     }
 103 
 104     public void testDanglingElse2() {
 105         test("danglingElse2");
 106     }
 107 
 108     public void testDanglingElse3() {
 109         test("danglingElse3");
 110     }
 111 
 112     public void testSimpleIf() {
 113         test("simpleIf");
 114     }
 115 
 116     public void testParams11() {
 117         test("testParams1");
 118     }
 119 
 120     public void testParams21() {
 121         test("testParams2");
 122     }
 123 
 124     public void testParams31() {
 125         test("testParams3");
 126     }
 127 
 128     public void testAssignment1() {
 129         test("testAssignment");
 130     }
 131 
 132     public void testArithmetic1() {
 133         test("testArithmetic");
 134     }
 135 
 136     public void testSimpleWhile1() {
 137         test("testSimpleWhile");
 138     }
 139 
 140     public void testComplexWhile1() {
 141         test("testComplexWhile");
 142     }
 143 
 144     public void testSquaresThree() {
 145         test("testMulThreeArrays");
 146     }
 147 
 148     @Test
 149     public void testCondMoves() {
 150         test("testMinI");
 151         test("testMinF");
 152     }
 153 
 154     public int testMinI(int a, int b) {
 155         return (a < b ? 1 : 2);
 156     }
 157 
 158     public float testMinF(int a, int b) {
 159         return (a < b ? 1.0f : 2.0f);
 160     }
 161 
 162     public static void testMulThreeArrays(int[] out, int[] ina, int[] inb, int gid) {
 163         out[gid] = ina[gid] * inb[gid];
 164     }
 165 
 166     public static int testArrayMultiplyZero(int[] array1, int[] array2) {
 167         return array1[0] = array2[0] * array2[0];
 168     }
 169 
 170     public static int testArrayMultiplyGid(int[] array1, int[] array2, int gid) {
 171         return array1[gid] = array2[gid] * array2[gid];
 172     }
 173 
 174     public static float testParams3(float c, float d, float e) {
 175         return c + d + e;
 176     }
 177 
 178     public static int testAssignment() {
 179         final int width = 768;
 180         final int height = 768;
 181         final int maxIterations = 64;
 182         return width * height * maxIterations;
 183     }
 184 
 185     public static int testSimpleWhile(int i) {
 186         int count = 0;
 187         int j = 0;
 188         final int maxIterations = 64;
 189         while (count < maxIterations) {
 190             j += count * i;
 191             count++;
 192         }
 193         return j;
 194     }
 195 
 196     public static void testComplexWhile() {
 197         float lx = 1;
 198         float ly = 2;
 199         float zx = lx;
 200         float zy = ly;
 201         float newzx = 0f;
 202         final int maxIterations = 64;
 203         int count = 0;
 204         while (count < maxIterations && zx * zx + zy * zy < 8) {
 205             newzx = zx * zx - zy * zy + lx;
 206             zy = 2 * zx * zy + ly;
 207             zx = newzx;
 208             count++;
 209         }
 210     }
 211 
 212     public static void testMandel(int[] rgb, int[] pallette, float xoffset, float yoffset, float scale, int gid) {
 213         final int width = 768;
 214         final int height = 768;
 215         final int maxIterations = 64;
 216         float lx = (((gid % width * scale) - ((scale / 2) * width)) / width) + xoffset;
 217         float ly = (((gid / width * scale) - ((scale / 2) * height)) / height) + yoffset;
 218         int count = 0;
 219         float zx = lx;
 220         float zy = ly;
 221         float newzx = 0f;
 222         /**
 223          * Iterate until the algorithm converges or until maxIterations are reached.
 224          */
 225         while (count < maxIterations && zx * zx + zy * zy < 8) {
 226             newzx = zx * zx - zy * zy + lx;
 227             zy = 2 * zx * zy + ly;
 228             zx = newzx;
 229             count++;
 230         }
 231         rgb[gid] = pallette[count];
 232     }
 233 
 234     public static void testMandelSimple(int[] rgb, int[] pallette, float xoffset, float yoffset, float scale, int gid) {
 235         final int width = 768;
 236         final int height = width;
 237         final int maxIterations = 64;
 238         float lx = (((gid % width * scale) - ((scale / 2) * width)) / width) + xoffset;
 239         float ly = (((gid / width * scale) - ((scale / 2) * height)) / height) + yoffset;
 240         int count = 0;
 241         float zx = lx;
 242         float zy = ly;
 243         float newzx = 0f;
 244         /**
 245          * Iterate until the algorithm converges or until maxIterations are reached.
 246          */
 247         while (count < maxIterations && zx * zx + zy * zy < 8) {
 248             newzx = zx * zx - zy * zy + lx;
 249             zy = 2 * zx * zy + ly;
 250             zx = newzx;
 251             count++;
 252         }
 253         rgb[gid] = pallette[count];
 254     }
 255 
 256     public static void testMandel2(int[] rgb, int[] pallette, int xoffseti, int yoffseti, int scalei, int gid) {
 257         final int width = 768;
 258         final int height = 768;
 259         final int maxIterations = 64;
 260         float xoffset = xoffseti;
 261         float yoffset = yoffseti;
 262         float scale = scalei;
 263         float lx = (((gid % width * scale) - ((scale / 2) * width)) / width) + xoffset;
 264         float ly = (((gid / width * scale) - ((scale / 2) * height)) / height) + yoffset;
 265         int count = 0;
 266         float zx = lx;
 267         float zy = ly;
 268         float newzx = 0f;
 269         /**
 270          * Iterate until the algorithm converges or until maxIterations are reached.
 271          */
 272         while (count < maxIterations && zx * zx + zy * zy < 8) {
 273             newzx = zx * zx - zy * zy + lx;
 274             zy = 2 * zx * zy + ly;
 275             zx = newzx;
 276             count++;
 277         }
 278         rgb[gid] = pallette[count];
 279     }
 280 
 281     public static int testArrayLocalVariable(int gid, int[] array) {
 282         int foo = 198;
 283         return array[gid + foo];
 284     }
 285 
 286     public static int testArrayReturnFirstElement(int[] array) {
 287         return array[0];
 288     }
 289 
 290     public static int testArrayReturnIthElement(int i, int[] array) {
 291         return array[i];
 292     }
 293 
 294     public static void simpleIf(int[] out, int[] in, int gid) {
 295         if (gid > 9) {
 296             out[gid] = in[gid] * in[gid];
 297         }
 298     }
 299 
 300     public static int danglingElse(int a) {
 301         return (a > 5) ? (a + 7) : (a - 3);
 302     }
 303 
 304     public static int danglingElse2(int a, int b) {
 305         if (a > 5) {
 306             return (a + 7 * (b - 4 + a));
 307         } else {
 308             return (a - 3 + b * 3 * a + 5);
 309         }
 310     }
 311 
 312     public static int danglingElse3(int a, int b) {
 313         int val;
 314         if (a > 5) {
 315             val = (a + 7 * (b - 4 + a));
 316         } else {
 317             val = (a - 3 + b * 3 * a + 5);
 318         }
 319         return val + a;
 320     }
 321 
 322     public static void intSquaresTernary(int[] out, int[] in, int gid) {
 323         int val = in[gid] * in[gid];
 324         val = (val % 2 == 1 ? val + 1 : val);
 325         out[gid] = val;
 326     }
 327 
 328     private void test(String snippet) {
 329         StructuredGraph graph = parse(snippet);
 330         HSAILCompilationResult compResult = HSAILCompilationResult.getHSAILCompilationResult(graph);
 331         compResult.dumpCompilationResult();
 332     }
 333 
 334     public static void nBodySpill(float[] inxyz, float[] outxyz, float[] invxyz, float[] outvxyz, int gid) {
 335         final int bodies = 8;
 336         final float delT = .005f;
 337         final float espSqr = 1.0f;
 338         final float mass = 5f;
 339         final int count = bodies * 3;
 340         final int globalId = gid * 3;
 341         float accx = 0.f;
 342         float accy = 0.f;
 343         float accz = 0.f;
 344         for (int i = 0; i < count; i += 3) {
 345             final float dx = inxyz[i + 0] - inxyz[globalId + 0];
 346             final float dy = inxyz[i + 1] - inxyz[globalId + 1];
 347             final float dz = inxyz[i + 2] - inxyz[globalId + 2];
 348             final float invDist = (float) (1.0 / (Math.sqrt((dx * dx) + (dy * dy) + (dz * dz) + espSqr)));
 349             accx += mass * invDist * invDist * invDist * dx;
 350             accy += mass * invDist * invDist * invDist * dy;
 351             accz += mass * invDist * invDist * invDist * dz;
 352         }
 353         accx *= delT;
 354         accy *= delT;
 355         accz *= delT;
 356         outxyz[globalId + 0] = inxyz[globalId + 0] + (invxyz[globalId + 0] * delT) + (accx * .5f * delT);
 357         outxyz[globalId + 1] = inxyz[globalId + 1] + (invxyz[globalId + 1] * delT) + (accy * .5f * delT);
 358         outxyz[globalId + 2] = inxyz[globalId + 2] + (invxyz[globalId + 2] * delT) + (accz * .5f * delT);
 359         outvxyz[globalId + 0] = invxyz[globalId + 0] + accx;
 360         outvxyz[globalId + 1] = invxyz[globalId + 1] + accy;
 361         outvxyz[globalId + 2] = invxyz[globalId + 2] + accz;
 362     }
 363 }