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.ComputeRange; 30 import hat.GlobalMesh1D; 31 import hat.KernelContext; 32 import hat.backend.Backend; 33 import hat.buffer.S32Array; 34 import hat.buffer.S32Array2D; 35 import hat.ifacemapper.MappableIface.RO; 36 import hat.ifacemapper.MappableIface.RW; 37 import jdk.incubator.code.CodeReflection; 38 import hat.test.annotation.HatTest; 39 import hat.test.engine.HatAsserts; 40 41 import java.lang.invoke.MethodHandles; 42 43 public class TestMandel { 44 45 @CodeReflection 46 public static void mandel(@RO KernelContext kc, @RW S32Array2D s32Array2D, @RO S32Array pallette, float offsetx, float offsety, float scale) { 47 if (kc.x < kc.maxX) { 48 float width = s32Array2D.width(); 49 float height = s32Array2D.height(); 50 float x = ((kc.x % s32Array2D.width()) * scale - (scale / 2f * width)) / width + offsetx; 51 float y = ((kc.x / s32Array2D.width()) * scale - (scale / 2f * height)) / height + offsety; 52 float zx = x; 53 float zy = y; 54 float new_zx; 55 int colorIdx = 0; 56 while ((colorIdx < pallette.length()) && (((zx * zx) + (zy * zy)) < 4f)) { 57 new_zx = ((zx * zx) - (zy * zy)) + x; 58 zy = (2f * zx * zy) + y; 59 zx = new_zx; 60 colorIdx++; 61 } 62 int color = colorIdx < pallette.length() ? pallette.array(colorIdx) : 0; 63 s32Array2D.array(kc.x, color); 64 } 65 } 66 67 @CodeReflection 68 static public void compute(final ComputeContext computeContext, S32Array pallete, S32Array2D s32Array2D, float x, float y, float scale) { 69 ComputeRange computeRange = new ComputeRange(new GlobalMesh1D(s32Array2D.width() & s32Array2D.height())); 70 computeContext.dispatchKernel(computeRange, 71 kc -> { 72 TestMandel.mandel(kc, s32Array2D, pallete, x, y, scale); 73 }); 74 } 75 76 public static void mandelSeq(@RW S32Array2D s32Array2D, @RO S32Array pallette, float offsetx, float offsety, float scale) { 77 for (int i = 0; i < pallette.length(); i++) { 78 float width = s32Array2D.width(); 79 float height = s32Array2D.height(); 80 float x = ((i % s32Array2D.width()) * scale - (scale / 2f * width)) / width + offsetx; 81 float y = (((float) i / s32Array2D.width()) * scale - (scale / 2f * height)) / height + offsety; 82 float zx = x; 83 float zy = y; 84 float new_zx; 85 int colorIdx = 0; 86 while ((colorIdx < pallette.length()) && (((zx * zx) + (zy * zy)) < 4f)) { 87 new_zx = ((zx * zx) - (zy * zy)) + x; 88 zy = (2f * zx * zy) + y; 89 zx = new_zx; 90 colorIdx++; 91 } 92 int color = colorIdx < pallette.length() ? pallette.array(colorIdx) : 0; 93 s32Array2D.array(i, color); 94 } 95 96 } 97 98 @HatTest 99 public void testMandel() { 100 Accelerator accelerator = new Accelerator(MethodHandles.lookup(), Backend.FIRST); 101 final int width = 1024; 102 final int height = 1024; 103 final float defaultScale = 3f; 104 final float originX = -1f; 105 final float originY = 0; 106 final int maxIterations = 64; 107 108 S32Array2D s32Array2D = S32Array2D.create(accelerator, width, height); 109 S32Array2D check = S32Array2D.create(accelerator, width, height); 110 111 int[] palletteArray = new int[maxIterations]; 112 for (int i = 1; i < maxIterations; i++) { 113 palletteArray[i]=(i/8+1);// 0-7? 114 } 115 palletteArray[0]=0; 116 S32Array pallette = S32Array.createFrom(accelerator, palletteArray); 117 118 accelerator.compute(cc -> TestMandel.compute(cc, pallette, s32Array2D, originX, originY, defaultScale)); 119 120 // Check 121 TestMandel.mandelSeq(check, pallette, originX, originY, defaultScale); 122 123 int subsample = 16; 124 for (int y = 0; y<height/subsample; y++) { 125 for (int x = 0; x<width/subsample; x++) { 126 int palletteValue = s32Array2D.get(x * subsample, y * subsample); // so 0->8 127 int palletteValueSeq = s32Array2D.get(x * subsample, y * subsample); // so 0->8 128 HatAsserts.assertEquals(palletteValueSeq, palletteValue); 129 } 130 } 131 } 132 }