From dd2a534fe5357be5993e2b453061df4ef211617c Mon Sep 17 00:00:00 2001 From: Jeffrey Phillips Freeman <jeffrey.freeman@syncleus.com> Date: Fri, 16 Dec 2016 20:44:05 -0500 Subject: [PATCH] test: added back runtime tests. --- .../com/aparapi/runtime/BufferTransfer.java | 268 +++++++++ .../CallStaticFromAnonymousKernel.java | 75 +++ .../com/aparapi/runtime/ExplicitBoolean.java | 88 +++ .../java/com/aparapi/runtime/Issue102.java | 73 +++ .../java/com/aparapi/runtime/Issue103.java | 61 ++ .../java/com/aparapi/runtime/Issue68.java | 234 ++++++++ .../java/com/aparapi/runtime/Issue69.java | 51 ++ src/test/java/com/aparapi/runtime/LoadCL.java | 71 +++ .../java/com/aparapi/runtime/RangeSize.java | 43 ++ .../com/aparapi/runtime/Test12x4_4x2.java | 521 ++++++++++++++++++ .../com/aparapi/runtime/UseStaticArray.java | 61 ++ src/test/java/com/aparapi/runtime/Util.java | 76 +++ src/test/java/com/aparapi/runtime/squarer.cl | 6 + 13 files changed, 1628 insertions(+) create mode 100644 src/test/java/com/aparapi/runtime/BufferTransfer.java create mode 100644 src/test/java/com/aparapi/runtime/CallStaticFromAnonymousKernel.java create mode 100644 src/test/java/com/aparapi/runtime/ExplicitBoolean.java create mode 100644 src/test/java/com/aparapi/runtime/Issue102.java create mode 100644 src/test/java/com/aparapi/runtime/Issue103.java create mode 100644 src/test/java/com/aparapi/runtime/Issue68.java create mode 100644 src/test/java/com/aparapi/runtime/Issue69.java create mode 100644 src/test/java/com/aparapi/runtime/LoadCL.java create mode 100644 src/test/java/com/aparapi/runtime/RangeSize.java create mode 100644 src/test/java/com/aparapi/runtime/Test12x4_4x2.java create mode 100644 src/test/java/com/aparapi/runtime/UseStaticArray.java create mode 100644 src/test/java/com/aparapi/runtime/Util.java create mode 100644 src/test/java/com/aparapi/runtime/squarer.cl diff --git a/src/test/java/com/aparapi/runtime/BufferTransfer.java b/src/test/java/com/aparapi/runtime/BufferTransfer.java new file mode 100644 index 00000000..00fdc3d9 --- /dev/null +++ b/src/test/java/com/aparapi/runtime/BufferTransfer.java @@ -0,0 +1,268 @@ +/** + * Copyright (c) 2016 - 2017 Syncleus, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.aparapi.runtime; + +import com.aparapi.Kernel; +import com.aparapi.Range; +import com.aparapi.device.Device; +import com.aparapi.device.OpenCLDevice; +import com.aparapi.internal.kernel.KernelManager; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.Arrays; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +public class BufferTransfer { + + static OpenCLDevice openCLDevice = null; + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + + Device device = KernelManager.instance().bestDevice(); + if (device == null || !(device instanceof OpenCLDevice)) { + fail("no opencl device!"); + } + openCLDevice = (OpenCLDevice) device; + } + + @Test + public void inOutOnce() { + + final int SIZE = 1024; + final InOutKernel kernel = new InOutKernel(); + final Range range = openCLDevice.createRange(SIZE); + + kernel.in = new int[SIZE]; + kernel.out = new int[SIZE]; + + Util.fill(kernel.in, new Util.Filler() { + public void fill(int[] array, int index) { + array[index] = index; + } + }); + kernel.execute(range); + + assertTrue("in == out", Util.same(kernel.in, kernel.out)); + + } + + @Test + public void auto() { + + final int SIZE = 1024; + final AddKernel kernel = new AddKernel(); + final Range range = openCLDevice.createRange(SIZE); + + kernel.values = new int[SIZE]; + kernel.result = new int[SIZE]; + Util.zero(kernel.result); + Util.fill(kernel.values, new Util.Filler() { + public void fill(int[] array, int index) { + array[index] = index; + } + }); + + int[] expectedResult = Arrays.copyOf(kernel.result, kernel.result.length); + + Util.apply(expectedResult, kernel.values, new Util.Operator() { + + @Override + public void apply(int[] lhs, int[] rhs, int index) { + lhs[index] = lhs[index] + rhs[index]; + + } + }); + kernel.execute(range); + + assertTrue("expectedResult == result", Util.same(expectedResult, kernel.result)); + + kernel.execute(range); + + Util.apply(expectedResult, kernel.values, new Util.Operator() { + + @Override + public void apply(int[] lhs, int[] rhs, int index) { + lhs[index] = lhs[index] + rhs[index]; + + } + }); + assertTrue("expectedResult == result", Util.same(expectedResult, kernel.result)); + + Util.zero(kernel.values); + kernel.execute(range); + assertTrue("expectedResult == result", Util.same(expectedResult, kernel.result)); + + } + + @Test + public void explicit() { + + final int SIZE = 1024; + final AddKernel kernel = new AddKernel(); + kernel.setExplicit(true); + final Range range = openCLDevice.createRange(SIZE); + + kernel.values = new int[SIZE]; + kernel.result = new int[SIZE]; + Util.zero(kernel.result); + Util.fill(kernel.values, new Util.Filler() { + public void fill(int[] array, int index) { + array[index] = index; + } + }); + + int[] expectedResult = Arrays.copyOf(kernel.result, kernel.result.length); + + Util.apply(expectedResult, kernel.values, new Util.Operator() { + + @Override + public void apply(int[] lhs, int[] rhs, int index) { + lhs[index] = lhs[index] + rhs[index]; + + } + }); + + kernel.execute(range).get(kernel.result); + + assertTrue("after first explicit add expectedResult == result", Util.same(expectedResult, kernel.result)); + + kernel.execute(range).get(kernel.result); + + Util.apply(expectedResult, kernel.values, new Util.Operator() { + @Override + public void apply(int[] lhs, int[] rhs, int index) { + lhs[index] = lhs[index] + rhs[index]; + + } + }); + assertTrue("after second explicit add expectedResult == result", Util.same(expectedResult, kernel.result)); + + Util.zero(kernel.values); + + kernel.put(kernel.values).execute(range).get(kernel.result); + + assertTrue("after zeroing values and third explici add expectedResult == result", Util.same(expectedResult, kernel.result)); + + Util.zero(kernel.result); + + kernel.put(kernel.result).execute(range).get(kernel.result); + + Util.zero(expectedResult); + + assertTrue("after zeroing values and result and forth explicit add expectedResult == result", + Util.same(expectedResult, kernel.result)); + + } + + @Test + public void issue60Explicit() { + + TestKernel kernel = new TestKernel(); + kernel.setExplicit(true); + kernel.step(); + + } + + @Test + public void issue60Auto() { + TestKernel kernel = new TestKernel(); + kernel.step(); + + } + + public static class InOutKernel extends Kernel { + + int[] in; + + int[] out; + + @Override + public void run() { + int gid = getGlobalId(0); + in[gid] = out[gid]; + + } + + } + + public static class AddKernel extends Kernel { + + int[] values; + + int[] result; + + @Override + public void run() { + int gid = getGlobalId(0); + result[gid] = result[gid] + values[gid]; + + } + + } + + private class TestKernel extends Kernel { + int[] simStep = new int[1]; + + int[] neuronOutputs = new int[3]; + + int[] expected = new int[]{ + 3, + 0, + 0, + 0, + 3, + 0, + 0, + 0, + 3, + 0, + 0, + 0, + 3, + 0, + 0, + 0 + }; + + public void step() { + int simSteps = 16; + int[][] log = new int[neuronOutputs.length][simSteps]; + put(neuronOutputs); + for (simStep[0] = 0; simStep[0] < simSteps; simStep[0]++) { + put(simStep).execute(neuronOutputs.length).get(neuronOutputs); + for (int n = 0; n < neuronOutputs.length; n++) + log[n][simStep[0]] = neuronOutputs[n]; + } + System.out.println(getTargetDevice().getShortDescription() + (isExplicit() ? ", explicit" : ", auto")); + + for (int n = 0; n < neuronOutputs.length; n++) + System.out.println(Arrays.toString(log[n])); + + assertTrue("log[2] == expected", Util.same(log[2], expected)); + } + + @Override + public void run() { + int neuronID = getGlobalId(); + neuronOutputs[neuronID] = (simStep[0] % (neuronID + 2) == 0) ? (neuronID + 1) : 0; + } + } + +} diff --git a/src/test/java/com/aparapi/runtime/CallStaticFromAnonymousKernel.java b/src/test/java/com/aparapi/runtime/CallStaticFromAnonymousKernel.java new file mode 100644 index 00000000..854f3edb --- /dev/null +++ b/src/test/java/com/aparapi/runtime/CallStaticFromAnonymousKernel.java @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2016 - 2017 Syncleus, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.aparapi.runtime; + +import com.aparapi.Kernel; +import com.aparapi.device.Device; +import org.junit.Test; + +import static org.junit.Assert.assertTrue; + +class AnotherClass { + static public int foo(int i) { + return i + 42; + } +}; + +public class CallStaticFromAnonymousKernel { + + static final int size = 256; + + // This method is a static target in the anonymous + // kernel's containing class + public static int fooBar(int i) { + return i + 20; + } + + public static void main(String args[]) { + CallStaticFromAnonymousKernel k = new CallStaticFromAnonymousKernel(); + k.test(); + } + + @Test + public void test() { + final int[] values = new int[size]; + final int[] results = new int[size]; + for (int i = 0; i < size; i++) { + values[i] = i; + results[i] = 0; + } + Kernel kernel = new Kernel() { + + // Verify codegen for resolving static call from run's callees + public int doodoo(int i) { + return AnotherClass.foo(i); + } + + @Override + public void run() { + int gid = getGlobalId(); + // Call a static in the containing class and call a kernel method + // that calls a static in another class + results[gid] = CallStaticFromAnonymousKernel.fooBar(values[gid]) + doodoo(gid); + } + }; + kernel.execute(size); + assertTrue("ran on GPU", kernel.getTargetDevice().getType() == Device.TYPE.GPU); + + for (int i = 0; i < size; i++) { + assertTrue("results == fooBar", results[i] == (fooBar(values[i]) + AnotherClass.foo(i))); + } + } +} diff --git a/src/test/java/com/aparapi/runtime/ExplicitBoolean.java b/src/test/java/com/aparapi/runtime/ExplicitBoolean.java new file mode 100644 index 00000000..66261623 --- /dev/null +++ b/src/test/java/com/aparapi/runtime/ExplicitBoolean.java @@ -0,0 +1,88 @@ +/** + * Copyright (c) 2016 - 2017 Syncleus, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.aparapi.runtime; + +import com.aparapi.Kernel; +import org.junit.Test; + +import static org.junit.Assert.assertTrue; + +public class ExplicitBoolean { + + private static void printArray(boolean[] a) { + for (int i = 0; i < a.length; i++) { + System.out.print((a[i] ? 1 : 0) + "\t"); + } + System.out.println(); + } + + @Test + public void test() { + int size = 16; + ExplicitBooleanTestKernel k1 = new ExplicitBooleanTestKernel(size); + ExplicitBooleanTestKernel k2 = new ExplicitBooleanTestKernel(size); + k2.input = k1.output; + + for (int i = 0; i < size; i++) { + k1.input[i] = Math.random() > 0.5; + } + + if (size <= 32) + printArray(k1.input); + + k1.go(); + + if (size <= 32) + printArray(k1.output); + + assertTrue("k1.input == k1.output ", Util.same(k1.output, k1.output)); + + k2.go(); + + if (size <= 32) + printArray(k2.output); + + assertTrue("k1.input == k2.input", Util.same(k1.output, k1.output)); + System.out.println(k1.getTargetDevice().getShortDescription()); + } + + class ExplicitBooleanTestKernel extends Kernel { + public boolean[] input, output; + int size; // Number of work items. + int iterations; // Number of times to execute kernel. + + public ExplicitBooleanTestKernel(int _size) { + size = _size; + input = new boolean[size]; + output = new boolean[size]; + setExplicit(true); + put(output); + } + + public void go() { + put(input); + execute(size); + get(output); + } + + @Override + public void run() { + int id = getGlobalId(); + output[id] = input[id]; + } + } + +} diff --git a/src/test/java/com/aparapi/runtime/Issue102.java b/src/test/java/com/aparapi/runtime/Issue102.java new file mode 100644 index 00000000..88b57313 --- /dev/null +++ b/src/test/java/com/aparapi/runtime/Issue102.java @@ -0,0 +1,73 @@ +/** + * Copyright (c) 2016 - 2017 Syncleus, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.aparapi.runtime; + +import com.aparapi.Kernel; +import org.junit.Test; + +import static org.junit.Assert.assertTrue; + + +final class BugDataObject { + int value = 7; + + public int getValue() { + return value; + } + + public void setValue(int value) { + this.value = value; + } +} + + +public class Issue102 extends Kernel { + static final int size = 32; + + static BugDataObject[] objects = new BugDataObject[size]; + int[] target = new int[size]; + + public Issue102() { + for (int i = 0; i < size; ++i) { + objects[i] = new BugDataObject(); + target[i] = 99; + } + } + + public static void main(String[] args) { + Issue102 b = new Issue102(); + b.test(); + } + + @Override + public void run() { + int id = getGlobalId(); + target[id] = objects[id].getValue(); + } + + void validate() { + for (int i = 0; i < size; i++) { + System.out.println(target[i] + " ... " + objects[i].getValue()); + assertTrue("target == objects", target[i] == objects[i].getValue()); + } + } + + @Test + public void test() { + execute(size); + validate(); + } +} diff --git a/src/test/java/com/aparapi/runtime/Issue103.java b/src/test/java/com/aparapi/runtime/Issue103.java new file mode 100644 index 00000000..cf1ebad3 --- /dev/null +++ b/src/test/java/com/aparapi/runtime/Issue103.java @@ -0,0 +1,61 @@ +/** + * Copyright (c) 2016 - 2017 Syncleus, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.aparapi.runtime; + +import com.aparapi.Kernel; +import org.junit.Test; + +import static org.junit.Assert.assertArrayEquals; + + +public class Issue103 extends Kernel { + static final int size = 32; + + static int[] source = new int[size]; + static int[] target = new int[size]; + + public Issue103() { + for (int i = 0; i < size; ++i) { + source[i] = 7; + target[i] = 99; + } + } + + public static void main(String[] args) { + Issue103 b = new Issue103(); + b.test(); + } + + @Override + public void run() { + int id = getGlobalId(); + target[id] = source[id]; + } + + void validate() { + assertArrayEquals("target == source", target, source); +// for (int i = 0; i < size; i++) { +// System.out.println(target[i] + " ... " + source[i]); +// assertTrue("target == source", target[i] == source[i]); +// } + } + + @Test + public void test() { + execute(size); + validate(); + } +} diff --git a/src/test/java/com/aparapi/runtime/Issue68.java b/src/test/java/com/aparapi/runtime/Issue68.java new file mode 100644 index 00000000..ac302127 --- /dev/null +++ b/src/test/java/com/aparapi/runtime/Issue68.java @@ -0,0 +1,234 @@ +/** + * Copyright (c) 2016 - 2017 Syncleus, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.aparapi.runtime; + +import com.aparapi.Kernel; + +abstract class ArrayAccess { + private final int offset; + private final int length; + + protected ArrayAccess(int offset, int length) { + this.offset = offset; + this.length = length; + } + + public abstract int[] getIntData(); + + public int getOffset() { + return offset; + } + + public int getLength() { + return length; + } +} + +class IntMemoryArrayAccess extends ArrayAccess { + private final int[] data; + + public IntMemoryArrayAccess(int[] data, int offset, int length) { + super(offset, length); + this.data = data; + } + + @Override + public int[] getIntData() { + return data; + } +} + +public class Issue68 { + public static void main(String[] args) { + final int SQRT_LENGTH = 1024; + final int LENGTH = SQRT_LENGTH * SQRT_LENGTH; + final ArrayAccess arrayAccess = new IntMemoryArrayAccess(new int[LENGTH], 0, LENGTH); + new Issue68().transformColumns(SQRT_LENGTH, SQRT_LENGTH, false, arrayAccess, new int[SQRT_LENGTH], null); + } + + private void transformColumns(final int length, final int count, final boolean isInverse, final ArrayAccess arrayAccess, + final int[] wTable, final int[] permutationTable) { + final Kernel kernel = new ColumnTableFNTRunnable(length, isInverse, arrayAccess, wTable, permutationTable, getModulus()); + kernel.execute(count); + } + + private int getModulus() { + return 2113929217; + } + + // Runnable for calculating the column transforms in parallel + private class ColumnTableFNTRunnable extends Kernel { + private final int stride; + private final int length; + private final boolean isInverse; + private final int[] data; + private final int offset; + @Constant + private final int[] wTable; + @Constant + private final int[] permutationTable; + private final int permutationTableLength; + private int modulus; + private float inverseModulus; + + public ColumnTableFNTRunnable(int length, boolean isInverse, ArrayAccess arrayAccess, int[] wTable, int[] permutationTable, + int modulus) { + stride = arrayAccess.getLength() / length; + this.length = length; // Transform length + this.isInverse = isInverse; + data = arrayAccess.getIntData(); + offset = arrayAccess.getOffset(); + this.wTable = wTable; + this.permutationTable = permutationTable; + permutationTableLength = (permutationTable == null ? 0 : permutationTable.length); + setModulus(modulus); + } + + @Override + public void run() { + if (isInverse) { + inverseColumnTableFNT(); + } else { + columnTableFNT(); + } + } + + private void columnTableFNT() { + int nn, istep, mmax, r; + + final int offset = this.offset + getGlobalId(); + nn = length; + + if (nn < 2) { + return; + } + + r = 1; + mmax = nn >> 1; + while (mmax > 0) { + istep = mmax << 1; + + // Optimize first step when wr = 1 + + for (int i = offset; i < (offset + (nn * stride)); i += istep * stride) { + final int j = i + (mmax * stride); + final int a = data[i]; + final int b = data[j]; + data[i] = modAdd(a, b); + data[j] = modSubtract(a, b); + } + + int t = r; + + for (int m = 1; m < mmax; m++) { + for (int i = offset + (m * stride); i < (offset + (nn * stride)); i += istep * stride) { + final int j = i + (mmax * stride); + final int a = data[i]; + final int b = data[j]; + data[i] = modAdd(a, b); + data[j] = modMultiply(wTable[t], modSubtract(a, b)); + } + t += r; + } + r <<= 1; + mmax >>= 1; + } + + //if (permutationTable != null) + // { + columnScramble(offset); + // } + } + + private void inverseColumnTableFNT() { + int nn, istep, mmax, r; + + final int offset = this.offset + getGlobalId(); + nn = length; + + if (nn < 2) { + return; + } + + // if (permutationTable != null) + // { + columnScramble(offset); + // } + + r = nn; + mmax = 1; + istep = 0; + while (nn > mmax) { + istep = mmax << 1; + r >>= 1; + + // Optimize first step when w = 1 + + for (int i = offset; i < (offset + (nn * stride)); i += istep * stride) { + final int j = i + (mmax * stride); + final int wTemp = data[j]; + data[j] = modSubtract(data[i], wTemp); + data[i] = modAdd(data[i], wTemp); + } + + int t = r; + + for (int m = 1; m < mmax; m++) { + for (int i = offset + (m * stride); i < (offset + (nn * stride)); i += istep * stride) { + final int j = i + (mmax * stride); + final int wTemp = modMultiply(wTable[t], data[j]); + data[j] = modSubtract(data[i], wTemp); + data[i] = modAdd(data[i], wTemp); + } + t += r; + } + mmax = istep; + } + } + + private void columnScramble(int offset) { + for (int k = 0; k < permutationTableLength; k += 2) { + final int i = offset + (permutationTable[k] * stride), j = offset + (permutationTable[k + 1] * stride); + final int tmp = data[i]; + data[i] = data[j]; + data[j] = tmp; + } + } + + public final int modMultiply(int a, int b) { + final int r1 = (a * b) - ((int) (inverseModulus * a * b) * modulus), r2 = r1 - modulus; + + return (r2 < 0 ? r1 : r2); + } + + private int modAdd(int a, int b) { + final int r1 = a + b, r2 = r1 - modulus; + + return (r2 < 0 ? r1 : r2); + } + + private int modSubtract(int a, int b) { + final int r1 = a - b, r2 = r1 + modulus; + + return (r1 < 0 ? r2 : r1); + } + + private void setModulus(int modulus) { + inverseModulus = 1.0f / (modulus + 0.5f); // Round down + this.modulus = modulus; + } + } +} diff --git a/src/test/java/com/aparapi/runtime/Issue69.java b/src/test/java/com/aparapi/runtime/Issue69.java new file mode 100644 index 00000000..3c12deb0 --- /dev/null +++ b/src/test/java/com/aparapi/runtime/Issue69.java @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2016 - 2017 Syncleus, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.aparapi.runtime; + +import com.aparapi.Kernel; +import com.aparapi.Range; + +public class Issue69 { + + public static void main(String[] args) { + final int globalArray[] = new int[512]; + Kernel kernel = new Kernel() { + @Override + public void run() { + globalArray[getGlobalId()] = getGlobalId(); + } + }; + for (int loop = 0; loop < 100; loop++) { + + System.out.printf("%3d free = %10d\n", loop, Runtime.getRuntime().freeMemory()); + kernel.execute(Range.create(512, 64), 1); + for (int i = 0; i < globalArray.length; ++i) { + if (globalArray[i] != i) + System.err.println("Wrong!"); + } + } + for (int loop = 0; loop < 100; loop++) { + + System.out.printf("%3d free = %10d\n", loop, Runtime.getRuntime().freeMemory()); + kernel.execute(Range.create(512, 64), 2); + for (int i = 0; i < globalArray.length; ++i) { + if (globalArray[i] != i) + System.err.println("Wrong!"); + } + } + } + +} diff --git a/src/test/java/com/aparapi/runtime/LoadCL.java b/src/test/java/com/aparapi/runtime/LoadCL.java new file mode 100644 index 00000000..49fa4066 --- /dev/null +++ b/src/test/java/com/aparapi/runtime/LoadCL.java @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2016 - 2017 Syncleus, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.aparapi.runtime; + +import com.aparapi.Range; +import com.aparapi.device.Device; +import com.aparapi.device.OpenCLDevice; +import com.aparapi.internal.kernel.KernelManager; +import com.aparapi.opencl.OpenCL; +import com.aparapi.opencl.OpenCL.Resource; +import org.junit.Test; + +import static org.junit.Assert.assertTrue; + +public class LoadCL { + + @Test + public void test() { + final int size = 32; + final float[] in = new float[size]; + + for (int i = 0; i < size; i++) { + in[i] = i; + } + + final float[] squares = new float[size]; + final float[] quads = new float[size]; + final Range range = Range.create(size); + + final Device device = KernelManager.instance().bestDevice(); + + if (device instanceof OpenCLDevice) { + final OpenCLDevice openclDevice = (OpenCLDevice) device; + + final Squarer squarer = openclDevice.bind(Squarer.class); + squarer.square(range, in, squares); + + for (int i = 0; i < size; i++) { + assertTrue("in[" + i + "] * in[" + i + "] = in[" + i + "]^2", in[i] * in[i] == squares[i]); + } + + squarer.square(range, squares, quads); + + for (int i = 0; i < size; i++) { + assertTrue("in[" + i + "]^2 * in[" + i + "]^2 = in[" + i + "]^4", in[i] * in[i] * in[i] * in[i] == quads[i]); + } + } + } + + @Resource("com/aparapi/test/runtime/squarer.cl") + interface Squarer extends OpenCL<Squarer> { + public Squarer square(// + Range _range,// + @GlobalReadWrite("in") float[] in,// + @GlobalReadWrite("out") float[] out); + } +} + diff --git a/src/test/java/com/aparapi/runtime/RangeSize.java b/src/test/java/com/aparapi/runtime/RangeSize.java new file mode 100644 index 00000000..0cac50f3 --- /dev/null +++ b/src/test/java/com/aparapi/runtime/RangeSize.java @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2016 - 2017 Syncleus, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.aparapi.runtime; + +import com.aparapi.Range; +import org.junit.Test; + +import static org.junit.Assert.assertTrue; + +public class RangeSize { + + @Test + public void test384x384() { + Range range = Range.create2D(384, 384); + System.out.println("local[0] " + range.getLocalSize(0)); + System.out.println("local[1] " + range.getLocalSize(1)); + System.out.println("workGroupSize " + range.getWorkGroupSize()); + assertTrue("Range > max work size", range.getLocalSize(0) * range.getLocalSize(1) <= range.getWorkGroupSize()); + } + + @Test + public void test384x320() { + Range range = Range.create2D(384, 320); + System.out.println("local[0] " + range.getLocalSize(0)); + System.out.println("local[1] " + range.getLocalSize(1)); + System.out.println("workGroupSize " + range.getWorkGroupSize()); + assertTrue("Range > max work size", range.getLocalSize(0) * range.getLocalSize(1) <= range.getWorkGroupSize()); + } + +} diff --git a/src/test/java/com/aparapi/runtime/Test12x4_4x2.java b/src/test/java/com/aparapi/runtime/Test12x4_4x2.java new file mode 100644 index 00000000..a1a72032 --- /dev/null +++ b/src/test/java/com/aparapi/runtime/Test12x4_4x2.java @@ -0,0 +1,521 @@ +/** + * Copyright (c) 2016 - 2017 Syncleus, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.aparapi.runtime; + +import com.aparapi.Kernel; +import com.aparapi.Range; +import com.aparapi.device.Device; +import org.junit.Test; + +public class Test12x4_4x2 { + @SuppressWarnings("deprecation") + @Test + public void test() { + // globalThreadId, threadId, globalX, globalY, localX, localY + final int[][] test = new int[][]{ + { + 0, //globalThreadId + 0,//threadId + 0,//globalX + 0,//globalY + 0,//localX + 0 + //localY + }, + { + 1,//globalThreadId + 1,//threadId + 1,//globalX + 0,//globalY + 1,//localX + 0 + //localY + }, + { + 2,//globalThreadId + 2,//threadId + 2,//globalX + 0,//globalY + 2,//localX + 0 + //localY + }, + { + 3,//globalThreadId + 3,//threadId + 3,//globalX + 0,//globalY + 3,//localX + 0 + //localY + }, + { + 4,//globalThreadId + 4,//threadId + 0,//globalX + 1,//globalY + 0,//localX + 1 + //localY + }, + { + 5,//globalThreadId + 5,//threadId + 1,//globalX + 1,//globalY + 1,//localX + 1 + //localY + }, + { + 6,//globalThreadId + 6,//threadId + 2,//globalX + 1,//globalY + 2,//localX + 1 + //localY + }, + { + 7,//globalThreadId + 7,//threadId + 3,//globalX + 1,//globalY + 3,//localX + 1 + //localY + }, + { + 8,//globalThreadId + 0,//threadId + 4,//globalX + 0,//globalY + 0,//localX + 0 + //localY + }, + { + 9,//globalThreadId + 1,//threadId + 5,//globalX + 0,//globalY + 1,//localX + 0 + //localY + }, + { + 10,//globalThreadId + 2,//threadId + 6,//globalX + 0,//globalY + 2,//localX + 0 + //localY + }, + { + 11,//globalThreadId + 3,//threadId + 7,//globalX + 0,//globalY + 3,//localX + 0 + //localY + }, + { + 12,//globalThreadId + 4,//threadId + 4,//globalX + 1,//globalY + 0,//localX + 1 + //localY + }, + { + 13,//globalThreadId + 5,//threadId + 5,//globalX + 1,//globalY + 1,//localX + 1 + //localY + }, + { + 14,//globalThreadId + 6,//threadId + 6,//globalX + 1,//globalY + 2,//localX + 1 + //localY + }, + { + 15,//globalThreadId + 7,//threadId + 7,//globalX + 1,//globalY + 3,//localX + 1 + //localY + }, + { + 16,//globalThreadId + 0,//threadId + 8,//globalX + 0,//globalY + 0,//localX + 0 + //localY + }, + { + 17,//globalThreadId + 1,//threadId + 9,//globalX + 0,//globalY + 1,//localX + 0 + //localY + }, + { + 18,//globalThreadId + 2,//threadId + 10,//globalX + 0,//globalY + 2,//localX + 0 + //localY + }, + { + 19,//globalThreadId + 3,//threadId + 11,//globalX + 0,//globalY + 3,//localX + 0 + //localY + }, + + { + 20,//globalThreadId + 4,//threadId + 8,//globalX + 1,//globalY + 0,//localX + 1 + //localY + }, + { + 21,//globalThreadId + 5,//threadId + 9,//globalX + 1,//globalY + 1,//localX + 1 + //localY + }, + { + 22,//globalThreadId + 6,//threadId + 10,//globalX + 1, + 2,//localX + 1 + //localY + }, + { + 23,//globalThreadId + 7,//threadId + 11,//globalX + 1,//globalY + 3,//localX + 1 + //localY + }, + { + 24,//globalThreadId + 0,//threadId + 0,//globalX + 2,//globalY + 0,//localX + 0 + //localY + }, + { + 25,//globalThreadId + 1,//threadId + 1,//globalX + 2,//globalY + 1,//localX + 0 + //localY + }, + { + 26,//globalThreadId + 2,//threadId + 2,//globalX + 2,//globalY + 2,//localX + 0 + //localY + }, + { + 27,//globalThreadId + 3,//threadId + 3,//globalX + 2,//globalY + 3,//localX + 0 + //localY + }, + { + 28,//globalThreadId + 4,//threadId + 0,//globalX + 3,//globalY + 0,//localX + 1 + //localY + }, + { + 29,//globalThreadId + 5,//threadId + 1,//globalX + 3,//globalY + 1,//localX + 1 + //localY + }, + { + 30,//globalThreadId + 6,//threadId + 2,//globalX + 3,//globalY + 2,//localX + 1 + //localY + }, + { + 31,//globalThreadId + 7,//threadId + 3,//globalX + 3,//globalY + 3,//localX + 1 + //localY + }, + { + 32,//globalThreadId + 0,//threadId + 4,//globalX + 2,//globalY + 0,//localX + 0 + //localY + }, + { + 33,//globalThreadId + 1,//threadId + 5,//globalX + 2,//globalY + 1,//localX + 0 + //localY + }, + { + 34,//globalThreadId + 2,//threadId + 6,//globalX + 2,//globalY + 2,//localX + 0 + //localY + }, + { + 35,//globalThreadId + 3,//threadId + 7,//globalX + 2,//globalY + 3,//localX + 0 + //localY + }, + { + 36,//globalThreadId + 4,//threadId + 4,//globalX + 3,//globalY + 0,//localX + 1 + //localY + }, + { + 37,//globalThreadId + 5,//threadId + 5,//globalX + 3,//globalY + 1,//localX + 1 + //localY + }, + { + 38,//globalThreadId + 6,//threadId + 6,//globalX + 3,//globalY + 2,//localX + 1 + //localY + }, + { + 39,//globalThreadId + 7,//threadId + 7,//globalX + 3,//globalY + 3,//localX + 1 + //localY + }, + { + 40,//globalThreadId + 0,//threadId + 8,//globalX + 2,//globalY + 0,//localX + 0 + //localY + }, + { + 41,//globalThreadId + 1,//threadId + 9,//globalX + 2,//globalY + 1,//localX + 0 + //localY + }, + { + 42,//globalThreadId + 2,//threadId + 10,//globalX + 2,//globalY + 2,//localX + 0 + //localY + }, + { + 43,//globalThreadId + 3,//threadId + 11,//globalX + 2,//globalY + 3,//localX + 0 + //localY + }, + + { + 44,//globalThreadId + 4,//threadId + 8,//globalX + 3,//globalY + 0,//localX + 1 + //localY + }, + { + 45,//globalThreadId + 5,//threadId + 9,//globalX + 3,//globalY + 1,//localX + 1 + //localY + }, + { + 46,//globalThreadId + 6,//threadId + 10,//globalX + 3,//globalY + 2,//localX + 1 + //localY + }, + { + 47,//globalThreadId + 7,//threadId + 11,//globalX + 3,//globalY + 3,//localX + 1 + //localY + }, + }; + Kernel kernel = new Kernel() { + + @Override + public boolean isAllowDevice(Device _device) { + return _device.getType() == Device.TYPE.JTP; + } + + @Override + public void run() { + int x = getGlobalId(0); + int y = getGlobalId(1); + int lx = getLocalId(0); + int ly = getLocalId(1); + int w = getGlobalSize(0); + int h = getGlobalSize(1); + int globalThreadId = getGlobalId(1) * getGlobalSize(0) + getGlobalId(0); + int threadId = getLocalId(1) * getLocalSize(0) + getLocalId(0); + synchronized (test) { + boolean show = false; + if (globalThreadId != test[globalThreadId][0]) { + System.out.println("bad globalThreadId"); + show = true; + } + if (threadId != test[globalThreadId][1]) { + System.out.println("bad threadId"); + show = true; + } + if (x != test[globalThreadId][2]) { + System.out.println("bad globalx"); + show = true; + } + if (y != test[globalThreadId][3]) { + System.out.println("bad globaly"); + show = true; + } + if (lx != test[globalThreadId][4]) { + System.out.println("bad localx"); + show = true; + } + if (ly != test[globalThreadId][5]) { + System.out.println("bad localy"); + show = true; + } + if (show) { + System.out.println("derived =>" + globalThreadId + " " + threadId + " " + x + "," + y + " " + lx + "," + ly + " " + + w + "," + h); + System.out.println("data =>" + test[globalThreadId][0] + " " + test[globalThreadId][1] + " " + + test[globalThreadId][2] + "," + test[globalThreadId][3] + " " + test[globalThreadId][4] + "," + + test[globalThreadId][5] + " " + w + "," + h); + } + } + } + + }; + kernel.execute(Range.create2D(12, 4, 4, 2)); + + } +} diff --git a/src/test/java/com/aparapi/runtime/UseStaticArray.java b/src/test/java/com/aparapi/runtime/UseStaticArray.java new file mode 100644 index 00000000..2b0f631e --- /dev/null +++ b/src/test/java/com/aparapi/runtime/UseStaticArray.java @@ -0,0 +1,61 @@ +/** + * Copyright (c) 2016 - 2017 Syncleus, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.aparapi.runtime; + +import com.aparapi.Kernel; +import com.aparapi.device.Device; +import org.junit.Test; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertTrue; + +public class UseStaticArray extends Kernel { + + static final int size = 256; + + static final int[] values = new int[size]; + + static final int[] results = new int[size]; + + public static void main(String args[]) { + UseStaticArray k = new UseStaticArray(); + k.test(); + } + + @Override + public void run() { + int gid = getGlobalId(); + results[gid] = values[gid]; + } + + @Test + public void test() { + + for (int i = 0; i < size; i++) { + values[i] = i; + results[i] = 0; + } + + execute(size); + + assertTrue("ran on GPU", getTargetDevice().getType() == Device.TYPE.GPU); + + assertArrayEquals("results == fooBar", results, values); +// for (int i = 0; i < size; i++) { +// assertTrue("results == fooBar", results[i] == values[i]); +// } + } +} diff --git a/src/test/java/com/aparapi/runtime/Util.java b/src/test/java/com/aparapi/runtime/Util.java new file mode 100644 index 00000000..c354f1ed --- /dev/null +++ b/src/test/java/com/aparapi/runtime/Util.java @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2016 - 2017 Syncleus, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.aparapi.runtime; + +import java.util.Arrays; + +public class Util { + static void fill(int[] array, Filler _filler) { + for (int i = 0; i < array.length; i++) { + _filler.fill(array, i); + } + } + + static boolean same(int[] lhs, int[] rhs, Comparer _comparer) { + boolean same = lhs != null && rhs != null && lhs.length == rhs.length; + for (int i = 0; same && i < lhs.length; i++) { + same = _comparer.same(lhs, rhs, i); + } + return (same); + } + + static void zero(int[] array) { + Arrays.fill(array, 0); + } + + static boolean same(int[] lhs, int[] rhs) { + return (same(lhs, rhs, new Comparer() { + + @Override + public boolean same(int[] lhs, int[] rhs, int index) { + + return lhs[index] == rhs[index]; + } + })); + } + + static boolean same(boolean[] lhs, boolean[] rhs) { + boolean same = lhs != null && rhs != null && lhs.length == rhs.length; + for (int i = 0; same && i < lhs.length; i++) { + same = lhs[i] == rhs[i]; + } + return (same); + } + + static void apply(int[] lhs, int[] rhs, Operator _operator) { + for (int i = 0; i < lhs.length; i++) { + _operator.apply(lhs, rhs, i); + } + } + + interface Filler { + void fill(int[] array, int index); + } + + interface Comparer { + boolean same(int[] lhs, int[] rhs, int index); + } + + interface Operator { + void apply(int[] lhs, int[] rhs, int index); + } + +} diff --git a/src/test/java/com/aparapi/runtime/squarer.cl b/src/test/java/com/aparapi/runtime/squarer.cl new file mode 100644 index 00000000..2ccc8b07 --- /dev/null +++ b/src/test/java/com/aparapi/runtime/squarer.cl @@ -0,0 +1,6 @@ + +__kernel void square( __global float *in, __global float *out){ + const size_t id = get_global_id(0); + out[id] = in[id]*in[id]; +} + -- GitLab