diff --git a/pom.xml b/pom.xml index 2d81ee4d..6aa2a7da 100644 --- a/pom.xml +++ b/pom.xml @@ -89,9 +89,51 @@ aparapi-jni 1.4.2-SNAPSHOT + + + + junit + junit + + + org.mockito + mockito-all + 1.10.19 + test + junit junit + 4.11 + test + + + + org.powermock + powermock-api-mockito + 1.7.4 + test + + + + org.powermock + powermock-module-junit4 + 1.7.4 + + + junit + junit + + + org.powermock + powermock-core + + + org.powermock + powermock-reflect + + + test @@ -101,6 +143,10 @@ org.apache.maven.plugins maven-compiler-plugin + + 8 + 8 + org.apache.maven.plugins @@ -145,6 +191,44 @@ org.jacoco jacoco-maven-plugin + + + + pre-unit-test + + prepare-agent + + + + ${project.build.directory}/coverage-reports/jacoco-ut.exec + + surefireArgLine + + + + + post-unit-test + test + + report + + + + ${project.build.directory}/coverage-reports/jacoco-ut.exec + + ${project.reporting.outputDirectory}/jacoco-ut + + + com.mycila.maven-license-plugin diff --git a/src/main/java/com/aparapi/Range.java b/src/main/java/com/aparapi/Range.java index 06561269..f9666d7f 100644 --- a/src/main/java/com/aparapi/Range.java +++ b/src/main/java/com/aparapi/Range.java @@ -654,4 +654,19 @@ public int[] getMaxWorkItemSize() { public void setMaxWorkItemSize(int[] maxWorkItemSize) { this.maxWorkItemSize = maxWorkItemSize; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Range range = (Range) o; + return maxWorkGroupSize == range.maxWorkGroupSize && + Objects.equals(device, range.device) && + Arrays.equals(maxWorkItemSize, range.maxWorkItemSize); + } + + @Override + public int hashCode() { + return Objects.hash(device, maxWorkGroupSize, maxWorkItemSize); + } } diff --git a/src/main/java/com/aparapi/internal/opencl/OpenCLArgDescriptor.java b/src/main/java/com/aparapi/internal/opencl/OpenCLArgDescriptor.java index 713b48dd..66112f22 100644 --- a/src/main/java/com/aparapi/internal/opencl/OpenCLArgDescriptor.java +++ b/src/main/java/com/aparapi/internal/opencl/OpenCLArgDescriptor.java @@ -18,6 +18,8 @@ */ package com.aparapi.internal.opencl; +import java.util.Objects; + public class OpenCLArgDescriptor{ public final static int ARG_BYTE_BIT = 1 << 0x000; @@ -114,4 +116,21 @@ public OpenCLArgDescriptor(String _name, long _bits) { return (argBuilder.toString()); } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + OpenCLArgDescriptor that = (OpenCLArgDescriptor) o; + return bits == that.bits && + Objects.equals(memVal, that.memVal) && + Objects.equals(name, that.name) && + Objects.equals(kernel, that.kernel); + } + + @Override + public int hashCode() { + + return Objects.hash(memVal, name, bits, kernel); + } } diff --git a/src/main/java/com/aparapi/internal/util/UnsafeWrapper.java b/src/main/java/com/aparapi/internal/util/UnsafeWrapper.java index ec53e9eb..5f93d22d 100644 --- a/src/main/java/com/aparapi/internal/util/UnsafeWrapper.java +++ b/src/main/java/com/aparapi/internal/util/UnsafeWrapper.java @@ -116,7 +116,7 @@ public class UnsafeWrapper{ arrayBaseOffsetMethod = uc.getDeclaredMethod("arrayBaseOffset", Class.class); arrayIndexScaleMethod = uc.getDeclaredMethod("arrayIndexScale", Class.class); getObjectMethod = uc.getDeclaredMethod("getObject", Object.class, long.class); - getIntMethod = uc.getDeclaredMethod("getInt", Object.class, long.class); + getIntMethod = uc.getDeclaredMethod("getInt", Object.class, long.class); getFloatMethod = uc.getDeclaredMethod("getFloat", Object.class, long.class); getByteMethod = uc.getDeclaredMethod("getByte", Object.class, long.class); getBooleanMethod = uc.getDeclaredMethod("getBoolean", Object.class, long.class); diff --git a/src/test/java/com/aparapi/device/DeviceTest.java b/src/test/java/com/aparapi/device/DeviceTest.java new file mode 100644 index 00000000..39d903d9 --- /dev/null +++ b/src/test/java/com/aparapi/device/DeviceTest.java @@ -0,0 +1,74 @@ +/** + * Copyright (c) 2016 - 2018 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.device; + +import com.aparapi.Range; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class DeviceTest { + + private static final int LOCAL_WIDTH = 11; + private static final int GLOBAL_WIDTH = 11; + private static final int GLOBAL_HEIGHT = 12; + private static final int LOCAL_HEIGHT = 14; + private static final int GLOBAL_DEPTH = 15; + private static final int LOCAL_DEPTH = 17; + private static final String TEST = "test"; + + @Test + public void shouldCreateRangeWithCurrentDevice() { + Device sut = Utils.createDevice(Utils.createPlatform(TEST), Device.TYPE.ACC); + assertEquals(Range.create(sut, GLOBAL_WIDTH, LOCAL_WIDTH), sut.createRange(GLOBAL_WIDTH, LOCAL_WIDTH)); + } + + @Test + public void shouldCreateRange2DGlobalParamsWithCurrentDevice() { + Device sut = Utils.createDevice(Utils.createPlatform(TEST), Device.TYPE.ACC); + assertEquals(Range.create2D(sut, GLOBAL_WIDTH, GLOBAL_HEIGHT), sut.createRange2D(GLOBAL_WIDTH, GLOBAL_HEIGHT)); + } + + @Test + public void shouldCreateRange2DGlobalAndLocalWithCurrentDevice() { + Device sut = Utils.createDevice(Utils.createPlatform(TEST), Device.TYPE.ACC); + assertEquals(Range.create2D(sut, GLOBAL_WIDTH, GLOBAL_HEIGHT, LOCAL_WIDTH, LOCAL_HEIGHT), + sut.createRange2D(GLOBAL_WIDTH, GLOBAL_HEIGHT, LOCAL_WIDTH, LOCAL_HEIGHT)); + } + + @Test + public void shouldCreateRange3DGlobalWithCurrentDevice() { + Device sut = Utils.createDevice(Utils.createPlatform(TEST), Device.TYPE.ACC); + assertEquals(Range.create3D(sut, GLOBAL_WIDTH, GLOBAL_HEIGHT, GLOBAL_DEPTH), + sut.createRange3D(GLOBAL_WIDTH, GLOBAL_HEIGHT, GLOBAL_DEPTH)); + } + + @Test + public void shouldCreateRange3DGlobalAndLocalWithCurrentDevice() { + Device sut = Utils.createDevice(Utils.createPlatform(TEST), Device.TYPE.ACC); + assertEquals(Range.create3D(sut, GLOBAL_WIDTH, GLOBAL_HEIGHT, GLOBAL_DEPTH, LOCAL_WIDTH, LOCAL_HEIGHT, LOCAL_DEPTH), + sut.createRange3D(GLOBAL_WIDTH, GLOBAL_HEIGHT, GLOBAL_DEPTH, LOCAL_WIDTH, LOCAL_HEIGHT, LOCAL_DEPTH)); + } + + @Test + public void shouldCompareDevicesAccordingToTheirRank() { + Device least = Utils.createDevice(Utils.createPlatform(TEST), Device.TYPE.ACC); + Device largest = Utils.createDevice(Utils.createPlatform(TEST), Device.TYPE.SEQ); + assertEquals(-1, least.compareTo(largest)); + assertEquals(1, largest.compareTo(least)); + assertEquals(0, least.compareTo(least)); + } +} diff --git a/src/test/java/com/aparapi/device/JavaDeviceTest.java b/src/test/java/com/aparapi/device/JavaDeviceTest.java new file mode 100644 index 00000000..a51f72f3 --- /dev/null +++ b/src/test/java/com/aparapi/device/JavaDeviceTest.java @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2016 - 2018 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.device; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class JavaDeviceTest { + + @Test + public void shouldReturnCorrectPropertiesForThreadPoolDevice() { + assertEquals("Java Thread Pool", JavaDevice.THREAD_POOL.getShortDescription()); + assertEquals(-3, JavaDevice.THREAD_POOL.getDeviceId()); + assertEquals(Device.TYPE.JTP, JavaDevice.THREAD_POOL.getType()); + assertEquals("Java Thread Pool", JavaDevice.THREAD_POOL.toString()); + + } + + @Test + public void shouldReturnCorrectPropertiesForAlternativeAlgorithm() { + assertEquals("Java Alternative Algorithm", JavaDevice.ALTERNATIVE_ALGORITHM.getShortDescription()); + assertEquals(-2, JavaDevice.ALTERNATIVE_ALGORITHM.getDeviceId()); + assertEquals(Device.TYPE.ALT, JavaDevice.ALTERNATIVE_ALGORITHM.getType()); + assertEquals("Java Alternative Algorithm", JavaDevice.ALTERNATIVE_ALGORITHM.toString()); + + } + + @Test + public void shouldReturnCorrectPropertiesForSequential() { + assertEquals("Java Sequential", JavaDevice.SEQUENTIAL.getShortDescription()); + assertEquals(-1, JavaDevice.SEQUENTIAL.getDeviceId()); + assertEquals(Device.TYPE.SEQ, JavaDevice.SEQUENTIAL.getType()); + assertEquals("Java Sequential", JavaDevice.SEQUENTIAL.toString()); + + } +} diff --git a/src/test/java/com/aparapi/device/OpenCLDeviceGetArgsTest.java b/src/test/java/com/aparapi/device/OpenCLDeviceGetArgsTest.java new file mode 100644 index 00000000..91f92e34 --- /dev/null +++ b/src/test/java/com/aparapi/device/OpenCLDeviceGetArgsTest.java @@ -0,0 +1,154 @@ +/** + * Copyright (c) 2016 - 2018 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.device; + +import com.aparapi.Range; +import com.aparapi.internal.opencl.OpenCLArgDescriptor; +import com.aparapi.opencl.OpenCL; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import static com.aparapi.internal.opencl.OpenCLArgDescriptor.*; +import static java.util.Arrays.asList; +import static java.util.Collections.singletonList; +import static org.junit.Assert.assertEquals; + +@RunWith(Parameterized.class) +public class OpenCLDeviceGetArgsTest { + + static final String TEST = "test"; + + public OpenCLDeviceGetArgsTest(Method method, List expectedDescriptors) { + this.method = method; + this.expectedDescriptors = expectedDescriptors; + } + + @Parameterized.Parameters + public static Collection data() { + return asList(new Object[][]{ + {methodByName("rangeTest"), new ArrayList<>()}, + {methodByName("globalReadOnlyAnnotationTest"), singletonList(descriptor(ARG_GLOBAL_BIT, ARG_READONLY_BIT))}, + {methodByName("globalWriteOnlyAnnotationTest"), singletonList(descriptor(ARG_GLOBAL_BIT, ARG_WRITEONLY_BIT))}, + {methodByName("globalReadWriteAnnotationTest"), singletonList(descriptor(ARG_GLOBAL_BIT, ARG_READWRITE_BIT))}, + {methodByName("localAnnotationTest"), singletonList(descriptor(ARG_LOCAL_BIT))}, + {methodByName("constantAnnotationTest"), singletonList(descriptor(ARG_CONST_BIT, ARG_READONLY_BIT))}, + {methodByName("argAnnotationTest"), singletonList(descriptor(ARG_ISARG_BIT))}, + {methodByName("floatArrayTest"), singletonList(descriptor(ARG_ISARG_BIT, ARG_FLOAT_BIT, ARG_ARRAY_BIT))}, + {methodByName("intArrayTest"), singletonList(descriptor(ARG_ISARG_BIT, ARG_INT_BIT, ARG_ARRAY_BIT))}, + {methodByName("doubleArrayTest"), singletonList(descriptor(ARG_ISARG_BIT, ARG_DOUBLE_BIT, ARG_ARRAY_BIT))}, + {methodByName("byteArrayTest"), singletonList(descriptor(ARG_ISARG_BIT, ARG_BYTE_BIT, ARG_ARRAY_BIT))}, + {methodByName("shortArrayTest"), singletonList(descriptor(ARG_ISARG_BIT, ARG_SHORT_BIT, ARG_ARRAY_BIT))}, + {methodByName("longArrayTest"), singletonList(descriptor(ARG_ISARG_BIT, ARG_LONG_BIT, ARG_ARRAY_BIT))}, + {methodByName("floatTest"), singletonList(descriptor(ARG_ISARG_BIT, ARG_FLOAT_BIT, ARG_PRIMITIVE_BIT))}, + {methodByName("intTest"), singletonList(descriptor(ARG_ISARG_BIT, ARG_INT_BIT, ARG_PRIMITIVE_BIT))}, + {methodByName("doubleTest"), singletonList(descriptor(ARG_ISARG_BIT, ARG_DOUBLE_BIT, ARG_PRIMITIVE_BIT))}, + {methodByName("byteTest"), singletonList(descriptor(ARG_ISARG_BIT, ARG_BYTE_BIT, ARG_PRIMITIVE_BIT))}, + {methodByName("shortTest"), singletonList(descriptor(ARG_ISARG_BIT, ARG_SHORT_BIT, ARG_PRIMITIVE_BIT))}, + {methodByName("longTest"), singletonList(descriptor(ARG_ISARG_BIT, ARG_LONG_BIT, ARG_PRIMITIVE_BIT))}, + {methodByName("multipleParametersTest"), asList(descriptor(ARG_ISARG_BIT, ARG_LONG_BIT, ARG_PRIMITIVE_BIT), descriptor(ARG_LOCAL_BIT))} + }); + } + + private final Method method; + private final List expectedDescriptors; + + @Test + public void shouldReturnCorrespondingDescriptorsForTests() { + OpenCLDevice sut = Utils.createDevice(Utils.createPlatform("Intel (R)"), Device.TYPE.CPU); + assertEquals(expectedDescriptors, sut.getArgs(method)); + } + + private static class MethodsForTests { + public void rangeTest(Range parameter) { + } + + public void globalReadOnlyAnnotationTest(@OpenCL.GlobalReadOnly(TEST) String parameter) { + } + + public void globalWriteOnlyAnnotationTest(@OpenCL.GlobalWriteOnly(TEST) String parameter) { + } + + public void globalReadWriteAnnotationTest(@OpenCL.GlobalReadWrite(TEST) String parameter) { + } + + public void localAnnotationTest(@OpenCL.Local(TEST) String parameter) { + } + + public void constantAnnotationTest(@OpenCL.Constant(TEST) String parameter) { + } + + public void argAnnotationTest(@OpenCL.Arg(TEST) String parameter) { + } + + public void floatArrayTest(@OpenCL.Arg(TEST) float[] parameter) { + } + + public void intArrayTest(@OpenCL.Arg(TEST) int[] parameter) { + } + + public void doubleArrayTest(@OpenCL.Arg(TEST) double[] parameter) { + } + + public void byteArrayTest(@OpenCL.Arg(TEST) byte[] parameter) { + } + + public void shortArrayTest(@OpenCL.Arg(TEST) short[] parameter) { + } + + public void longArrayTest(@OpenCL.Arg(TEST) long[] parameter) { + } + + public void floatTest(@OpenCL.Arg(TEST) float parameter) { + } + + public void intTest(@OpenCL.Arg(TEST) int parameter) { + } + + public void doubleTest(@OpenCL.Arg(TEST) double parameter) { + } + + public void byteTest(@OpenCL.Arg(TEST) byte parameter) { + } + + public void shortTest(@OpenCL.Arg(TEST) short parameter) { + } + + public void longTest(@OpenCL.Arg(TEST) long parameter) { + } + + public void multipleParametersTest(@OpenCL.Arg(TEST) long parameter1, @OpenCL.Local(TEST) String parameter2) { + } + + public void noAnnotationForParameterTest(long parameter) { + } + } + + private static OpenCLArgDescriptor descriptor(int... bitList) { + long bits = Arrays.stream(bitList).asLongStream().reduce(0L, (a, b) -> a | b); + return new OpenCLArgDescriptor(TEST, bits); + } + + private static Method methodByName(String name) { + return Utils.methodByName(name, MethodsForTests.class); + } +} diff --git a/src/test/java/com/aparapi/device/OpenCLDeviceTest.java b/src/test/java/com/aparapi/device/OpenCLDeviceTest.java new file mode 100644 index 00000000..5384b982 --- /dev/null +++ b/src/test/java/com/aparapi/device/OpenCLDeviceTest.java @@ -0,0 +1,83 @@ +/** + * Copyright (c) 2016 - 2018 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.device; + +import com.aparapi.internal.opencl.OpenCLPlatform; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +public class OpenCLDeviceTest { + + public static final String TEST = "test"; + public static final String INTEL = "Intel"; + + @Before + public void resetConfigurator() { + OpenCLDevice.setConfigurator(null); + } + + @Test + public void shouldSetShortDescriptionBasedOnPlatformNameWithBrackets() { + OpenCLDevice sut = Utils.createDevice(Utils.createPlatform("Intel (R)"), Device.TYPE.CPU); + assertEquals("Intel", sut.getShortDescription()); + } + + @Test + public void shouldSetShortDescriptionBasedOnPlatformNameWithSpaces() { + OpenCLDevice sut = Utils.createDevice(Utils.createPlatform("Intel Core"), Device.TYPE.CPU); + assertEquals("Intel", sut.getShortDescription()); + } + + + /** + * once device description is calculated, + * it should be set to object field and should not be calculated again + */ + @Test + public void shouldSetShortDescriptionToDeviceProperty() { + OpenCLPlatform platform = Utils.createPlatform(INTEL); + OpenCLDevice sut = Utils.createDevice(platform, Device.TYPE.CPU); + sut.getShortDescription(); + sut.getShortDescription(); + verify(platform).getName(); + } + + @Test(expected = IllegalStateException.class) + public void shouldThrowAnExceptionIfAnnotationValueIsNull() { + OpenCLDevice sut = Utils.createDevice(Utils.createPlatform("Intel (R)"), Device.TYPE.CPU); + sut.getArgs(Utils.methodByName("charAt", String.class)); + } + + @Test + public void shouldConfigureDevice() { + OpenCLDevice sut = Utils.createDevice(Utils.createPlatform(INTEL), Device.TYPE.CPU); + IOpenCLDeviceConfigurator testConfigurator = mock(IOpenCLDeviceConfigurator.class); + OpenCLDevice.setConfigurator(testConfigurator); + sut.configure(); + verify(testConfigurator).configure(sut); + } + + @Test + public void shouldSkipConfigurationIfConfiguratorIsNotSet() { + OpenCLDevice sut = Utils.createDevice(Utils.createPlatform(INTEL), Device.TYPE.CPU); + OpenCLDevice.setConfigurator(null); + sut.configure(); + } +} diff --git a/src/test/java/com/aparapi/device/OpenCLInvocationHandlerTest.java b/src/test/java/com/aparapi/device/OpenCLInvocationHandlerTest.java new file mode 100644 index 00000000..1da0c916 --- /dev/null +++ b/src/test/java/com/aparapi/device/OpenCLInvocationHandlerTest.java @@ -0,0 +1,129 @@ +/** + * Copyright (c) 2016 - 2018 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.device; + +import com.aparapi.internal.opencl.OpenCLKernel; +import com.aparapi.internal.opencl.OpenCLProgram; +import org.junit.Test; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +public class OpenCLInvocationHandlerTest { + + private static final String PROXY = "test"; + private static final Object[] ARGS = new Object[0]; + + @Test + public void shouldInvokeCorrespondingKernelForNonInterfaceMethods() throws Throwable { + Method method = Object.class.getMethod("toString"); + OpenCLProgram program = mock(OpenCLProgram.class); + Map kernelMap = new HashMap<>(); + OpenCLKernel kernel = mock(OpenCLKernel.class); + kernelMap.put(method.getName(), kernel); + InvocationHandler sut = new OpenCLDevice.OpenCLInvocationHandler(program, kernelMap); + Object[] args = new Object[0]; + assertEquals(PROXY, sut.invoke(PROXY, method, args)); + verify(kernel).invoke(args); + } + + @Test + public void shouldDoNothingIfThereAreNoCorrespondingKernelForNonInterfaceMethods() throws Throwable { + Method method = Object.class.getMethod("toString"); + OpenCLProgram program = mock(OpenCLProgram.class); + InvocationHandler sut = new OpenCLDevice.OpenCLInvocationHandler(program, new HashMap<>()); + assertEquals(PROXY, sut.invoke(PROXY, method, ARGS)); + } + + @Test + public void shouldDisposeAllKernelsForDispose() throws Throwable { + // set up test variables + Method method = ReservedInterfaceMethods.class.getMethod("dispose"); + OpenCLProgram program = mock(OpenCLProgram.class); + Map kernelMap = new HashMap<>(); + OpenCLKernel disposeKernel = mock(OpenCLKernel.class); + kernelMap.put(method.getName(), disposeKernel); + OpenCLKernel putKernel = mock(OpenCLKernel.class); + kernelMap.put("put", putKernel); + InvocationHandler sut = new OpenCLDevice.OpenCLInvocationHandler(program, kernelMap); + // test + sut.invoke(PROXY, method, ARGS); + //checks + verify(disposeKernel).dispose(); + verify(putKernel).dispose(); + verify(program).dispose(); + assertTrue(kernelMap.isEmpty()); + //ensure that disposed has been set to true + Field f = sut.getClass().getDeclaredField("disposed"); //NoSuchFieldException + f.setAccessible(true); + assertTrue((Boolean) f.get(sut)); + } + + @Test(expected = IllegalStateException.class) + public void shouldThrowIllegalStateExceptionIfAlreadyDisposed() throws Throwable { + // set up test variables + Method method = ReservedInterfaceMethods.class.getMethod("dispose"); + OpenCLProgram program = mock(OpenCLProgram.class); + Map kernelMap = new HashMap<>(); + OpenCLKernel disposeKernel = mock(OpenCLKernel.class); + kernelMap.put(method.getName(), disposeKernel); + InvocationHandler sut = new OpenCLDevice.OpenCLInvocationHandler(program, kernelMap); + // test + sut.invoke(PROXY, method, ARGS); + sut.invoke(PROXY, method, ARGS); + } + + + static class ReservedInterfaceMethods { + public void put() { + } + + ; + + public void get() { + } + + ; + + public void begin() { + } + + ; + + public void end() { + } + + ; + + public void dispose() { + } + + ; + + public void getProfileInfo() { + } + + ; + } +} diff --git a/src/test/java/com/aparapi/device/Utils.java b/src/test/java/com/aparapi/device/Utils.java new file mode 100644 index 00000000..571c79fe --- /dev/null +++ b/src/test/java/com/aparapi/device/Utils.java @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2016 - 2018 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.device; + +import com.aparapi.internal.opencl.OpenCLPlatform; + +import java.lang.reflect.Method; +import java.util.Arrays; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class Utils { + + static final int DEVICE_ID = 1; + + static OpenCLDevice createDevice(OpenCLPlatform platform, Device.TYPE type) { + return new OpenCLDevice(platform, DEVICE_ID, type); + } + + static OpenCLPlatform createPlatform(String name) { + OpenCLPlatform platform = mock(OpenCLPlatform.class); + when(platform.getName()).thenReturn(name); + return platform; + } + + static Method methodByName(String name, Class clazz) { + return Arrays.stream(clazz.getMethods()) + .filter(m -> m.getName().equals(name)) + .findFirst().orElseThrow(() -> new RuntimeException("method with name not found " + name)); + } +} diff --git a/src/test/java/com/aparapi/internal/kernel/KernelDeviceProfileTest.java b/src/test/java/com/aparapi/internal/kernel/KernelDeviceProfileTest.java new file mode 100644 index 00000000..2bfa61ce --- /dev/null +++ b/src/test/java/com/aparapi/internal/kernel/KernelDeviceProfileTest.java @@ -0,0 +1,165 @@ +/** + * Copyright (c) 2016 - 2018 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.internal.kernel; + +import org.junit.Test; + +import java.lang.reflect.Field; +import java.util.Map; + +import static com.aparapi.internal.kernel.ProfilingEvent.*; +import static com.aparapi.internal.kernel.Utils.createKernelDeviceProfile; +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.assertTrue; + +public class KernelDeviceProfileTest { + private static final double MILLION = 1000 * 1000; + + @Test + public void shouldReturnZeroForElapsedTimeForStageStart() { + KernelDeviceProfile sut = createKernelDeviceProfile(); + assertEquals(0d, sut.getElapsedTimeCurrentThread(START.ordinal())); + } + + @Test + public void shouldReturnNonZeroForElapsedTimeIfProfilingEventWasCalled() { + KernelDeviceProfile sut = createKernelDeviceProfile(); + sut.onEvent(PREPARE_EXECUTE); + long[] currentTimes = getCurrentTimesArrayForCurrentThread(sut); + long prepareExecuteTime = currentTimes[PREPARE_EXECUTE.ordinal()]; + assertTrue(prepareExecuteTime > 0); + assertEquals(prepareExecuteTime / MILLION, sut.getElapsedTimeCurrentThread(PREPARE_EXECUTE.ordinal())); + } + + @Test + public void shouldReturnNaNForElapsedTimeIfProfilingEventWasNotCalled() { + KernelDeviceProfile sut = createKernelDeviceProfile(); + assertEquals(Double.NaN, sut.getElapsedTimeCurrentThread(EXECUTED.ordinal())); + } + + @Test + public void shouldReturnZeroElapsedTimeIfNothingWasProfiled() { + KernelDeviceProfile sut = createKernelDeviceProfile(); + assertEquals(0d, sut.getCumulativeElapsedTimeAllCurrentThread()); + } + + @Test + public void shouldReturnZeroForProfiledEventsIfExecutedEventWasNotCalled() { + KernelDeviceProfile sut = createKernelDeviceProfile(); + sut.onEvent(START); + sut.onEvent(ProfilingEvent.PREPARE_EXECUTE); + sut.onEvent(ProfilingEvent.CLASS_MODEL_BUILT); + assertEquals(0d, sut.getCumulativeElapsedTimeAllCurrentThread()); + } + + @Test + public void shouldReturnSumOfProfileTimesForProfiledEventsAfterExecutedEventIsProfiled() { + KernelDeviceProfile sut = createKernelDeviceProfile(); + sut.onEvent(START); + sut.onEvent(ProfilingEvent.PREPARE_EXECUTE); + sut.onEvent(ProfilingEvent.EXECUTED); + long[] accumulatedTimes = getAccumulatedTimesArrayForCurrentThread(sut); + long prepareExecuteTime = accumulatedTimes[PREPARE_EXECUTE.ordinal()]; + long executedTime = accumulatedTimes[EXECUTED.ordinal()]; + assertTrue(prepareExecuteTime > 0); + assertTrue(executedTime > 0); + assertEquals((double) (prepareExecuteTime + executedTime), sut.getCumulativeElapsedTimeAllCurrentThread()); + } + + @Test + public void shouldReturnZeroForElapsedTimeLastThreadForStageStart() { + KernelDeviceProfile sut = createKernelDeviceProfile(); + assertEquals(0d, sut.getElapsedTimeLastThread(START.ordinal())); + } + + @Test + public void shouldReturnNanForElapsedTimeLastThreadIfNothingWasProfiled() { + KernelDeviceProfile sut = createKernelDeviceProfile(); + assertEquals(Double.NaN, sut.getElapsedTimeLastThread(EXECUTED.ordinal())); + } + + @Test + public void shouldReturnDifferenceBetweenElapsedTimesForElapsedTimeLastThreadIfTheyWereProfiled() { + KernelDeviceProfile sut = createKernelDeviceProfile(); + sut.onEvent(ProfilingEvent.START); + sut.onEvent(ProfilingEvent.CLASS_MODEL_BUILT); + sut.onEvent(ProfilingEvent.INIT_JNI); + sut.onEvent(EXECUTED); + long[] currentTimes = getCurrentTimesArrayForCurrentThread(sut); + long jniExecuteTime = currentTimes[INIT_JNI.ordinal()]; + long classModelBuiltTime = currentTimes[CLASS_MODEL_BUILT.ordinal()]; + assertTrue(classModelBuiltTime > 0); + assertTrue(jniExecuteTime > 0); + assertEquals((jniExecuteTime - classModelBuiltTime) / MILLION, sut.getElapsedTimeLastThread(INIT_JNI.ordinal())); + } + + @Test + public void shouldReturnDifferenceBetweenElapsedTimesForLastThreadByIndex() { + KernelDeviceProfile sut = createKernelDeviceProfile(); + sut.onEvent(ProfilingEvent.START); + sut.onEvent(ProfilingEvent.CLASS_MODEL_BUILT); + sut.onEvent(ProfilingEvent.INIT_JNI); + sut.onEvent(EXECUTED); + long[] currentTimes = getCurrentTimesArrayForCurrentThread(sut); + long jniExecuteTime = currentTimes[INIT_JNI.ordinal()]; + long classModelBuiltTime = currentTimes[CLASS_MODEL_BUILT.ordinal()]; + assertTrue(classModelBuiltTime > 0); + assertTrue(jniExecuteTime > 0); +// assertEquals((jniExecuteTime - classModelBuiltTime) / MILLION, sut.getElapsedTimeLastThread(INIT_JNI.ordinal(), EXECUTED.ordinal())); + assertTrue(sut.getElapsedTimeLastThread(INIT_JNI.ordinal(), EXECUTED.ordinal()) > 0); + } + + private static long[] getCurrentTimesArrayForCurrentThread(KernelDeviceProfile kernelDeviceProfile) { + try { + Map allAccumulators = getAccumulatorMap(kernelDeviceProfile); + Object currentThreadAccumulator = allAccumulators.get(Thread.currentThread()); + return (long[]) getFieldAndMakeItAccessible(currentThreadAccumulator.getClass(), "currentTimes") + .get(currentThreadAccumulator); + } catch (Exception e) { + throw new RuntimeException(e.getMessage()); + } + } + + private static long[] getAccumulatedTimesArrayForCurrentThread(KernelDeviceProfile kernelDeviceProfile) { + try { + Map allAccumulators = getAccumulatorMap(kernelDeviceProfile); + Object currentThreadAccumulator = allAccumulators.get(Thread.currentThread()); + return (long[]) getFieldAndMakeItAccessible(currentThreadAccumulator.getClass(), "accumulatedTimes") + .get(currentThreadAccumulator); + } catch (Exception e) { + throw new RuntimeException(e.getMessage()); + } + } + + private static Map getAccumulatorMap(KernelDeviceProfile kernelDeviceProfile) { + try { + return (Map) getFieldAndMakeItAccessible(KernelDeviceProfile.class, "accs").get(kernelDeviceProfile); + } catch (IllegalAccessException e) { + throw new RuntimeException(e.getMessage()); + } + } + + private static Field getFieldAndMakeItAccessible(Class clazz, String fieldName) { + Field field = null; + try { + field = clazz.getDeclaredField(fieldName); + } catch (NoSuchFieldException e) { + throw new RuntimeException(e.getMessage()); + } + field.setAccessible(true); + return field; + } +} diff --git a/src/test/java/com/aparapi/internal/kernel/KernelRunnerCheckPropertiesSetTest.java b/src/test/java/com/aparapi/internal/kernel/KernelRunnerCheckPropertiesSetTest.java new file mode 100644 index 00000000..0f72dcf9 --- /dev/null +++ b/src/test/java/com/aparapi/internal/kernel/KernelRunnerCheckPropertiesSetTest.java @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2016 - 2018 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.internal.kernel; + +import com.aparapi.opencl.OpenCL; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.mockito.internal.util.collections.Sets; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.HashSet; + +import static java.util.Arrays.asList; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +@RunWith(Parameterized.class) +public class KernelRunnerCheckPropertiesSetTest { + private final String methodName; + private final String capability; + + public KernelRunnerCheckPropertiesSetTest(String methodName, String capability) { + this.methodName = methodName; + this.capability = capability; + } + + @Parameterized.Parameters + public static Collection data() { + return asList(new Object[][]{ + {"hasFP64Support", OpenCL.CL_KHR_FP64}, + {"hasSelectFPRoundingModeSupport", OpenCL.CL_KHR_SELECT_FPROUNDING_MODE}, + {"hasGlobalInt32BaseAtomicsSupport", OpenCL.CL_KHR_GLOBAL_INT32_BASE_ATOMICS}, + {"hasGlobalInt32ExtendedAtomicsSupport", OpenCL.CL_KHR_GLOBAL_INT32_EXTENDED_ATOMICS}, + {"hasLocalInt32BaseAtomicsSupport", OpenCL.CL_KHR_LOCAL_INT32_BASE_ATOMICS}, + {"hasLocalInt32ExtendedAtomicsSupport", OpenCL.CL_KHR_LOCAL_INT32_EXTENDED_ATOMICS}, + {"hasInt64BaseAtomicsSupport", OpenCL.CL_KHR_INT64_BASE_ATOMICS}, + {"hasInt64ExtendedAtomicsSupport", OpenCL.CL_KHR_INT64_EXTENDED_ATOMICS}, + {"has3DImageWritesSupport", OpenCL.CL_KHR_3D_IMAGE_WRITES}, + {"hasByteAddressableStoreSupport", OpenCL.CL_KHR_BYTE_ADDRESSABLE_SUPPORT}, + {"hasFP16Support", OpenCL.CL_KHR_FP16}, + {"hasGLSharingSupport", OpenCL.CL_KHR_GL_SHARING} + }); + } + + @Test(expected = InvocationTargetException.class) + public void shouldThrowAnExceptionIfCapabilitiesSetIsNull() throws Exception { + KernelRunner sut = Utils.createKernelRunner(); + invokeMethod(sut); + } + + @Test + public void shouldReturnFalseIfCapabilitiesSetIsEmpty() throws Exception { + KernelRunner sut = Utils.createKernelRunner(); + Utils.setFieldValue(sut, "capabilitiesSet", new HashSet<>()); + assertFalse(invokeMethod(sut)); + } + + @Test + public void shouldReturnTrueIfCapabilityIsSet() throws Exception { + KernelRunner sut = Utils.createKernelRunner(); + Utils.setFieldValue(sut, "capabilitiesSet", Sets.newSet(capability)); + assertTrue(invokeMethod(sut)); + } + + private boolean invokeMethod(KernelRunner sut) throws Exception { + Method method = KernelRunner.class.getDeclaredMethod(methodName); + return (boolean) method.invoke(sut); + } +} + diff --git a/src/test/java/com/aparapi/internal/kernel/KernelRunnerTest.java b/src/test/java/com/aparapi/internal/kernel/KernelRunnerTest.java new file mode 100644 index 00000000..2fec8a26 --- /dev/null +++ b/src/test/java/com/aparapi/internal/kernel/KernelRunnerTest.java @@ -0,0 +1,261 @@ +/** + * Copyright (c) 2016 - 2018 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.internal.kernel; + +import com.aparapi.Kernel; +import org.junit.Test; +import org.mockito.Mockito; +import org.mockito.internal.util.collections.Sets; + +import java.lang.reflect.Array; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.IntBuffer; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +public class KernelRunnerTest { + + private static final int[] INITIAL_ARRAY = {1}; + private static final int[] NEW_REF = {11}; + private static final int TOTAL_BUFFER_SIZE = 3; + private static final int TOTAL_STRUCT_SIZE = 2; + private static final int OBJ_ARRAY_SIZE = 1; + private static final int EXPECTED_CURRENT_PASS_VALUE = 1; + private static final int PASS_ID = 2; + + @Test + public void shouldCleanUpArrays() throws Exception { + Kernel kernel = mock(Kernel.class); + KernelRunner sut = new KernelRunner(kernel); + KernelArg arg = mock(KernelArg.class); + KernelArg[] args = new KernelArg[]{arg}; + Field argsField = KernelRunner.class.getDeclaredField("args"); + argsField.setAccessible(true); + argsField.set(sut, args); + when(kernel.isRunningCL()).thenReturn(true); + sut.cleanUpArrays(); + verify(kernel).execute(0); + } + + + @Test + public void shouldCleanUpArraysShouldNotSetValueForFinalArrays() throws Exception { + TestKernelWithFinalArray kernel = Mockito.spy(new TestKernelWithFinalArray(INITIAL_ARRAY)); + when(kernel.isRunningCL()).thenReturn(true); + KernelRunner sut = new KernelRunner(kernel); + Field field = TestKernelWithFinalArray.class.getDeclaredField("values"); + KernelArg kernelArg = Utils.createKernelArg(field, 128); + setArgsArray(sut, kernelArg); + sut.cleanUpArrays(); + verify(kernel).execute(0); + assertArraysEqual(INITIAL_ARRAY, kernel); + } + + @Test + public void shouldCleanUpArraysShouldSetValueForNonFinalArrays() throws Exception { + TestKernelWithNonFinalArray kernel = Mockito.spy(new TestKernelWithNonFinalArray(INITIAL_ARRAY)); + when(kernel.isRunningCL()).thenReturn(true); + KernelRunner sut = new KernelRunner(kernel); + Field field = TestKernelWithNonFinalArray.class.getDeclaredField("values"); + KernelArg kernelArg = Utils.createKernelArg(field, 128); + setArgsArray(sut, kernelArg); + sut.cleanUpArrays(); + verify(kernel).execute(0); + assertArraysEqual((int[]) Array.newInstance(int.class, 1), kernel); + } + + @Test + public void shouldDisposeAndClearBinaryKeys() throws Exception { + TestKernelWithNonFinalArray kernel = Mockito.spy(new TestKernelWithNonFinalArray(INITIAL_ARRAY)); + when(kernel.isRunningCL()).thenReturn(true); + KernelRunner sut = new KernelRunner(kernel); + Utils.setFieldValue(sut, "seenBinaryKeys", Sets.newSet("test")); + sut.dispose(); + HashSet keys = (HashSet) Utils.getFieldValue(sut, "seenBinaryKeys"); + assertTrue(keys.isEmpty()); + } + + @Test + public void shouldAllocateArrayBufferIfFirstTime() throws Exception { + TestKernelWithNonFinalArray kernel = Mockito.spy(new TestKernelWithNonFinalArray(INITIAL_ARRAY)); + KernelRunner sut = new KernelRunner(kernel); + Field field = TestKernelWithNonFinalArray.class.getDeclaredField("values"); + KernelArg kernelArg = Utils.createKernelArg(field, 128); + assertTrue(sut.allocateArrayBufferIfFirstTimeOrArrayChanged(kernelArg, NEW_REF, OBJ_ARRAY_SIZE, TOTAL_STRUCT_SIZE, TOTAL_BUFFER_SIZE)); + ByteBuffer structBuffer = ByteBuffer.allocate(TOTAL_BUFFER_SIZE); + assertEquals(structBuffer.order(ByteOrder.LITTLE_ENDIAN), kernelArg.getObjArrayByteBuffer()); + assertEquals(structBuffer.order(ByteOrder.LITTLE_ENDIAN).array().length, kernelArg.getObjArrayBuffer().length); + } + + @Test + public void shouldAllocateArrayBufferIfArrayWasChanged() throws Exception { + TestKernelWithNonFinalArray kernel = Mockito.spy(new TestKernelWithNonFinalArray(INITIAL_ARRAY)); + KernelRunner sut = new KernelRunner(kernel); + Field field = TestKernelWithNonFinalArray.class.getDeclaredField("values"); + KernelArg kernelArg = Utils.createKernelArg(field, 128); + kernelArg.setObjArrayBuffer(ByteBuffer.allocate(TOTAL_BUFFER_SIZE).array()); + assertTrue(sut.allocateArrayBufferIfFirstTimeOrArrayChanged(kernelArg, NEW_REF, OBJ_ARRAY_SIZE, TOTAL_STRUCT_SIZE, TOTAL_BUFFER_SIZE)); + ByteBuffer structBuffer = ByteBuffer.allocate(TOTAL_BUFFER_SIZE); + assertEquals(structBuffer.order(ByteOrder.LITTLE_ENDIAN), kernelArg.getObjArrayByteBuffer()); + assertEquals(structBuffer.order(ByteOrder.LITTLE_ENDIAN).array().length, kernelArg.getObjArrayBuffer().length); + } + + @Test + public void shouldNotAllocateArrayBufferIfArrayWasNotChanged() throws Exception { + TestKernelWithNonFinalArray kernel = Mockito.spy(new TestKernelWithNonFinalArray(INITIAL_ARRAY)); + KernelRunner sut = new KernelRunner(kernel); + Field field = TestKernelWithNonFinalArray.class.getDeclaredField("values"); + KernelArg kernelArg = Utils.createKernelArg(field, 128); + kernelArg.setObjArrayBuffer(ByteBuffer.allocate(TOTAL_BUFFER_SIZE).array()); + assertTrue(sut.allocateArrayBufferIfFirstTimeOrArrayChanged(kernelArg, NEW_REF, OBJ_ARRAY_SIZE, TOTAL_STRUCT_SIZE, TOTAL_BUFFER_SIZE)); + assertFalse(sut.allocateArrayBufferIfFirstTimeOrArrayChanged(kernelArg, kernelArg.getArray(), OBJ_ARRAY_SIZE, TOTAL_STRUCT_SIZE, TOTAL_BUFFER_SIZE)); + } + + @Test + public void shouldReturnZeroIfCancelStateWasNotSet() { + KernelRunner sut = Utils.createKernelRunner(); + assertEquals(0, sut.getCancelState()); + } + + @Test + public void shouldReturn1IfCancelStateWasSet() { + KernelRunner sut = Utils.createKernelRunner(); + sut.cancelMultiPass(); + assertEquals(1, sut.getCancelState()); + } + + @Test + public void shouldReturn0IfCancelStateWasCleared() throws Exception { + KernelRunner sut = Utils.createKernelRunner(); + sut.cancelMultiPass(); + assertEquals(1, sut.getCancelState()); + Method clearCancelMultiPass = KernelRunner.class.getDeclaredMethod("clearCancelMultiPass"); + clearCancelMultiPass.setAccessible(true); + clearCancelMultiPass.invoke(sut); + assertEquals(0, sut.getCancelState()); + } + + @Test + public void shouldReturnCompletedAsCurrentPassIfNotExecuting() { + KernelRunner sut = Utils.createKernelRunner(); + assertEquals(-1, sut.getCurrentPass()); + } + + @Test + public void shouldReturnCurrentPassRemoteIfKernelIsExecuting() throws Exception { + TestKernelWithNonFinalArray kernel = Mockito.spy(new TestKernelWithNonFinalArray(INITIAL_ARRAY)); + KernelRunner sut = new KernelRunner(kernel); + IntBuffer outBufferRemoteInt = ByteBuffer.allocateDirect(4).asIntBuffer(); + outBufferRemoteInt.put(EXPECTED_CURRENT_PASS_VALUE); + Utils.setFieldValue(sut, "executing", true); + Utils.setFieldValue(sut, "outBufferRemoteInt", outBufferRemoteInt); + when(kernel.isRunningCL()).thenReturn(true); + assertEquals(EXPECTED_CURRENT_PASS_VALUE, sut.getCurrentPass()); + } + + @Test + public void shouldReturnCurrentPassLocalIfKernelIsExecuting() throws Exception { + TestKernelWithNonFinalArray kernel = Mockito.spy(new TestKernelWithNonFinalArray(INITIAL_ARRAY)); + KernelRunner sut = new KernelRunner(kernel); + Utils.setFieldValue(sut, "executing", true); + Utils.setFieldValue(sut, "passId", PASS_ID); + when(kernel.isRunningCL()).thenReturn(false); + assertEquals(PASS_ID, sut.getCurrentPass()); + } + + @Test(expected = IllegalStateException.class) + public void shouldExecuteShouldThrowExceptionIfRangeIsNull() throws Exception { + TestKernelWithNonFinalArray kernel = Mockito.spy(new TestKernelWithNonFinalArray(INITIAL_ARRAY)); + KernelRunner sut = new KernelRunner(kernel); + sut.execute("", null, 1); + } + + @Test + public void shouldReturnNullForKernelProfileInfoIfNotExplicit() throws Exception { + TestKernelWithNonFinalArray kernel = Mockito.spy(new TestKernelWithNonFinalArray(INITIAL_ARRAY)); + KernelRunner sut = new KernelRunner(kernel); + when(kernel.isRunningCL()).thenReturn(true); + assertEquals(null, sut.getProfileInfo()); + } + + @Test + public void shouldReturnNullForKernelProfileInfoIfExplicitKernelNotCL() throws Exception { + TestKernelWithNonFinalArray kernel = Mockito.spy(new TestKernelWithNonFinalArray(INITIAL_ARRAY)); + KernelRunner sut = new KernelRunner(kernel); + Utils.setFieldValue(sut, "explicit", true); + when(kernel.isRunningCL()).thenReturn(false); + assertEquals(null, sut.getProfileInfo()); + } + + @Test + public void shouldPutArrayIfExplicitAndKernelIsOpenCL() throws Exception { + TestKernelWithNonFinalArray kernel = Mockito.spy(new TestKernelWithNonFinalArray(INITIAL_ARRAY)); + KernelRunner sut = new KernelRunner(kernel); + Utils.setFieldValue(sut, "explicit", true); + when(kernel.isRunningCL()).thenReturn(true); + sut.put(INITIAL_ARRAY); + Set actualAray = (Set) Utils.getFieldValue(sut, "puts"); + assertFalse(actualAray.isEmpty()); + assertEquals(actualAray.iterator().next(), INITIAL_ARRAY); + } + + private static void assertArraysEqual(int[] expectedArray, TestKernelWithNonFinalArray updatedKernel) { + assertTrue(Arrays.equals(expectedArray, updatedKernel.values)); + } + + private static void assertArraysEqual(int[] expectedArray, TestKernelWithFinalArray updatedKernel) { + assertTrue(Arrays.equals(expectedArray, updatedKernel.values)); + } + + private static void setArgsArray(KernelRunner kernelRunner, KernelArg... args) throws Exception { + Field argsField = KernelRunner.class.getDeclaredField("args"); + argsField.setAccessible(true); + argsField.set(kernelRunner, args); + } + + private static class TestKernelWithFinalArray extends Kernel { + private final int[] values; + + private TestKernelWithFinalArray(int[] values) { + this.values = values; + } + + @Override + public void run() { + + } + } + + private static class TestKernelWithNonFinalArray extends Kernel { + private int[] values; + + private TestKernelWithNonFinalArray(int[] values) { + this.values = values; + } + + @Override + public void run() { + + } + } +} diff --git a/src/test/java/com/aparapi/internal/kernel/Utils.java b/src/test/java/com/aparapi/internal/kernel/Utils.java new file mode 100644 index 00000000..f649b130 --- /dev/null +++ b/src/test/java/com/aparapi/internal/kernel/Utils.java @@ -0,0 +1,61 @@ +/** + * Copyright (c) 2016 - 2018 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.internal.kernel; + +import com.aparapi.Kernel; +import com.aparapi.codegen.test.CallObject; +import com.aparapi.device.Device; + +import java.lang.reflect.Field; + +import static org.mockito.Mockito.mock; + +class Utils { + + static KernelDeviceProfile createKernelDeviceProfile() { + Device device = mock(Device.class); + KernelProfile kernelProfile = mock(KernelProfile.class); + return new KernelDeviceProfile(kernelProfile, Kernel.class, device); + } + + static Kernel createKernel() { + return new CallObject(); + } + + static KernelRunner createKernelRunner() { + Kernel kernel = mock(Kernel.class); + return new KernelRunner(kernel); + } + + static KernelArg createKernelArg(Field field, int type) { + KernelArg arg = new KernelArg(); + arg.setField(field); + arg.setType(type); + return arg; + } + + static Object getFieldValue(KernelRunner kernelRunner, String fieldName) throws Exception { + Field field = KernelRunner.class.getDeclaredField(fieldName); + field.setAccessible(true); + return field.get(kernelRunner); + } + + static void setFieldValue(KernelRunner kernelRunner, String fieldName, T fieldValue) throws Exception { + Field field = KernelRunner.class.getDeclaredField(fieldName); + field.setAccessible(true); + field.set(kernelRunner, fieldValue); + } +} diff --git a/src/test/java/com/aparapi/internal/opencl/OpenCLArgDescriptorTest.java b/src/test/java/com/aparapi/internal/opencl/OpenCLArgDescriptorTest.java new file mode 100644 index 00000000..fe0338b6 --- /dev/null +++ b/src/test/java/com/aparapi/internal/opencl/OpenCLArgDescriptorTest.java @@ -0,0 +1,64 @@ +/** + * Copyright (c) 2016 - 2018 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.internal.opencl; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import java.util.Collection; + +import static java.util.Arrays.asList; +import static junit.framework.TestCase.assertEquals; + +@RunWith(Parameterized.class) +public class OpenCLArgDescriptorTest { + public static final String NAME = "test"; + private final String name; + private final long bits; + private final String expectedToString; + + public OpenCLArgDescriptorTest(String name, long bits, String expectedToString) { + this.name = name; + this.bits = bits; + this.expectedToString = expectedToString; + } + + + @Parameterized.Parameters + public static Collection data() { + return asList(new Object[][]{ + {NAME, 1 << 0x008, "__global test"}, + {NAME, 1 << 0x000, "WHATISTHIS?test"}, + {NAME, 1 << 0x001, "WHATISTHIS?short test"}, + {NAME, 1 << 0x002, "WHATISTHIS?int test"}, + {NAME, 1 << 0x003, "WHATISTHIS?float test"}, + {NAME, 1 << 0x009, "__local test"}, + {NAME, 1 << 0x00A, "__constant test"}, + {NAME, 1 << 0x00B, "WHATISTHIS?test /* readonly */"}, + {NAME, 1 << 0x00C, "WHATISTHIS?test /* writeonly */"}, + {NAME, 1 << 0x00D, "WHATISTHIS?test /* readwrite */"}, + {NAME, 1 << 0x00E, "test"}, + {NAME, 0b1000000100, "__local int test"} + }); + } + + @Test + public void shouldReturnCorrectToStringValue() { + OpenCLArgDescriptor sut = new OpenCLArgDescriptor(name, bits); + assertEquals(expectedToString, sut.toString()); + } +} diff --git a/src/test/java/com/aparapi/runtime/PreDecrementTest.java b/src/test/java/com/aparapi/internal/opencl/OpenCLKernelTest.java similarity index 59% rename from src/test/java/com/aparapi/runtime/PreDecrementTest.java rename to src/test/java/com/aparapi/internal/opencl/OpenCLKernelTest.java index 648ce40c..23f784bd 100644 --- a/src/test/java/com/aparapi/runtime/PreDecrementTest.java +++ b/src/test/java/com/aparapi/internal/opencl/OpenCLKernelTest.java @@ -1,36 +1,28 @@ /** * Copyright (c) 2016 - 2018 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 - * + *

+ * 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; +package com.aparapi.internal.opencl; -import com.aparapi.Kernel; import org.junit.Test; +public class OpenCLKernelTest { -public class PreDecrementTest { @Test - public void test() { - PreDecrement kernel = new PreDecrement(); - kernel.execute(1); - } - - public class PreDecrement extends Kernel { - public void run() { - int idx = 34; - if(idx < 5) { - } - } + public void shouldCreateOpenCLKernel() { +// OpenCLProgram program = new OpenCLProgram(mock(OpenCLDevice.class), "test"); +// +// OpenCLKernel kernel = OpenCLKernel.createKernel(program, "test", new ArrayList<>()); } } diff --git a/src/test/java/com/aparapi/internal/util/ReflectionTest.java b/src/test/java/com/aparapi/internal/util/ReflectionTest.java new file mode 100644 index 00000000..dd403090 --- /dev/null +++ b/src/test/java/com/aparapi/internal/util/ReflectionTest.java @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2016 - 2018 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.internal.util; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.modules.junit4.PowerMockRunner; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +@RunWith(PowerMockRunner.class) +public class ReflectionTest { + + @Test + public void shouldReturnSimpleNameForNonAnonymousClass() { + assertEquals("String", Reflection.getSimpleName(String.class)); + } + + @Test + public void shouldReturnSimpleNameForAnonymousClass() { + Runnable runnable = new Runnable() { + @Override + public void run() { + + } + }; + assertTrue(Reflection.getSimpleName(runnable.getClass()).startsWith("ReflectionTest")); + } +} diff --git a/src/test/java/com/aparapi/internal/util/UnsafeWrapperTest.java b/src/test/java/com/aparapi/internal/util/UnsafeWrapperTest.java new file mode 100644 index 00000000..0911d553 --- /dev/null +++ b/src/test/java/com/aparapi/internal/util/UnsafeWrapperTest.java @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2016 - 2018 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.internal.util; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class UnsafeWrapperTest { + + @Test + public void shouldAtomicAdd() { + int[] array = new int[]{1, 2}; + UnsafeWrapper.atomicAdd(array, 1, 3); + assertEquals(array[1], 5); + } + + @Test(expected = IndexOutOfBoundsException.class) + public void shouldAtomicAddShouldThrowAnExceptionIfIndexIsLessThanZero() { + int[] array = new int[]{1, 2}; + UnsafeWrapper.atomicAdd(array, -1, 3); + } + + @Test(expected = IndexOutOfBoundsException.class) + public void shouldAtomicAddShouldThrowAnExceptionIfIndexIsOutOfBounds() { + int[] array = new int[]{}; + UnsafeWrapper.atomicAdd(array, 0, 3); + } + + @Test + public void shouldGetInt() { +// assertEquals(5 , UnsafeWrapper.getInt(new IntHolder(), 0)); + } + + +// @Test +// public void shouldGetFloat(){ +// assertEquals(5 , UnsafeWrapper.getFloat(new Float(11), 0)); +// } + + + private static class IntHolder { + private int value = 10; + } + + +} diff --git a/src/test/java/com/aparapi/runtime/AccessGetterSetterTest.java b/src/test/java/com/aparapi/runtime/AccessGetterSetterTest.java deleted file mode 100644 index 17f4f488..00000000 --- a/src/test/java/com/aparapi/runtime/AccessGetterSetterTest.java +++ /dev/null @@ -1,74 +0,0 @@ -/** - * Copyright (c) 2016 - 2018 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 AccessGetterSetterTest { - - @Test - public void test() { - Issue102Kernel b = new Issue102Kernel(); - b.test(); - } - - protected static class Issue102Kernel extends Kernel { - private static final int SIZE = 32; - - private static BugDataObject[] objects = new BugDataObject[SIZE]; - int[] target = new int[SIZE]; - - public Issue102Kernel() { - for (int i = 0; i < SIZE; ++i) { - objects[i] = new BugDataObject(); - target[i] = 99; - } - } - - @Override - public void run() { - int id = getGlobalId(); - target[id] = objects[id].getValue(); - } - - void validate() { - for (int i = 0; i < SIZE; i++) { - assertTrue("target == objects", target[i] == objects[i].getValue()); - } - } - - public void test() { - execute(SIZE); - validate(); - } - - static final class BugDataObject { - int value = 7; - - public int getValue() { - return value; - } - - public void setValue(int value) { - this.value = value; - } - } - } -} diff --git a/src/test/java/com/aparapi/runtime/ArbitraryScopeTest.java b/src/test/java/com/aparapi/runtime/ArbitraryScopeTest.java deleted file mode 100644 index bb186621..00000000 --- a/src/test/java/com/aparapi/runtime/ArbitraryScopeTest.java +++ /dev/null @@ -1,59 +0,0 @@ -/** - * Copyright (c) 2016 - 2018 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 org.junit.Ignore; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; - -public class ArbitraryScopeTest -{ - @Ignore("Known bug, ignoring test") - @Test - public void UnusedInArbitraryScopeTest() - { - Kernel kernel = new Kernel() - { - public void run() { - int count = 0; - { - @SuppressWarnings("unused") int value = count + 1; - } - } - }; - kernel.execute(1); - } - - @Ignore("Known bug, ignoring test") - @Test - public void UnusedInNormalScopeTest() - { - Kernel kernel = new Kernel() { - int[] ints = new int[1024]; - - public void run() { - if (ints != null) { - int value = ints[0]; - } - - } - }; - kernel.execute(1); - } -} diff --git a/src/test/java/com/aparapi/runtime/ArrayTest.java b/src/test/java/com/aparapi/runtime/ArrayTest.java deleted file mode 100644 index 6c3fb288..00000000 --- a/src/test/java/com/aparapi/runtime/ArrayTest.java +++ /dev/null @@ -1,82 +0,0 @@ -/** - * Copyright (c) 2016 - 2018 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 static org.junit.Assert.assertArrayEquals; - -import com.aparapi.Kernel; -import java.util.Arrays; -import org.junit.Test; - - -public class ArrayTest { - @Test - public void test() { - VectorKernel b = new VectorKernel(); - b.test(); - } - - public static class VectorKernel extends Kernel { - private static final int SIZE = 32; - - static int[][] target = new int[SIZE][SIZE]; - - public VectorKernel() { - for (int i = 0; i < SIZE; ++i) { - int[] ints = new int[SIZE]; - Arrays.fill(ints, 99); - - target[i] = ints; - } - } - - private static void fillArray(int[] ints_$private$, int id) { - for (int i = 0; i < SIZE; i++) { - ints_$private$[i] = i + id; - } - } - - @Override - public void run() { - int id = getGlobalId(); - - int[] ints = new int[SIZE]; - - fillArray(ints, id); - - for (int i = 0; i < SIZE; i++) { - target[id][i] = ints[i]; - } - } - - void validate() { - for (int j = 0; j < SIZE; j++) { - - int[] expected = new int[SIZE]; - for (int i = 0; i < SIZE; i++) { - expected[i] = i + j; - } - - assertArrayEquals("target["+j+"]", expected, target[j]); - } - } - - public void test() { - execute(SIZE); - validate(); - } - } -} diff --git a/src/test/java/com/aparapi/runtime/AtomicsSupportAdvTest.java b/src/test/java/com/aparapi/runtime/AtomicsSupportAdvTest.java deleted file mode 100644 index 94a8a62c..00000000 --- a/src/test/java/com/aparapi/runtime/AtomicsSupportAdvTest.java +++ /dev/null @@ -1,333 +0,0 @@ -/** - * Copyright (c) 2016 - 2018 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 static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeTrue; - -import java.util.Arrays; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aparapi.Kernel; -import com.aparapi.Range; -import com.aparapi.device.Device; -import com.aparapi.device.JavaDevice; -import com.aparapi.device.OpenCLDevice; -import com.aparapi.internal.kernel.KernelManager; - -/** - * Advanced tests for validation of the correctness of the atomics implementation both on Java and on OpenCL. - * @author CodeRasurae - */ -public class AtomicsSupportAdvTest { - - private static OpenCLDevice openCLDevice = null; - - private static final int SIZE = 100; - private final static int LOCK_IDX = 3; - private final static int MAX_VAL_IDX = 0; - private final static int MAX_POS_LEFT_IDX = 1; - private final static int MAX_POS_RIGHT_IDX = 2; - - private class CLKernelManager extends KernelManager { - @Override - protected List getPreferredDeviceTypes() { - return Arrays.asList(Device.TYPE.ACC, Device.TYPE.GPU, Device.TYPE.CPU); - } - } - - private class JTPKernelManager extends KernelManager { - private JTPKernelManager() { - LinkedHashSet preferredDevices = new LinkedHashSet(1); - preferredDevices.add(JavaDevice.THREAD_POOL); - setDefaultPreferredDevices(preferredDevices); - } - @Override - protected List getPreferredDeviceTypes() { - return Arrays.asList(Device.TYPE.JTP); - } - } - - @Before - public void setUpBeforeClass() throws Exception { - KernelManager.setKernelManager(new CLKernelManager()); - Device device = KernelManager.instance().bestDevice(); - assumeTrue (device != null && device instanceof OpenCLDevice); - openCLDevice = (OpenCLDevice) device; - } - - @After - public void classTeardown() { - Util.resetKernelManager(); - } - - @Test - public void testOpenCLExplicit() { - final int in[] = new int[SIZE]; - - final int[] out = new int[3]; - for (int i = 0; i < SIZE/2; i++) { - in[i] = i; - in[i + SIZE/2] = SIZE - i; - } - in[10] = SIZE; - - final AtomicKernel kernel = new AtomicKernel(in, out); - try { - final Range range = openCLDevice.createRange(SIZE/2, SIZE/2); - kernel.setExplicit(true); - kernel.put(in); - kernel.execute(range); - kernel.get(out); - } finally { - kernel.dispose(); - } - - assertEquals("Max value doesn't match", 100, out[0]); - assertTrue("Left max found at unexpected position: " + out[MAX_POS_LEFT_IDX], out[MAX_POS_LEFT_IDX] == 10 || out[MAX_POS_LEFT_IDX] == 50); - assertTrue("Right max found at unexpected position: " + out[MAX_POS_RIGHT_IDX], out[MAX_POS_RIGHT_IDX] == 100-10 || out[MAX_POS_RIGHT_IDX] == 100-50); - } - - @Test - public void testOpenCL() { - final int in[] = new int[SIZE]; - - final int[] out = new int[3]; - for (int i = 0; i < SIZE/2; i++) { - in[i] = i; - in[i + SIZE/2] = SIZE - i; - } - in[10] = SIZE; - - final AtomicKernel kernel = new AtomicKernel(in, out); - try { - final Range range = openCLDevice.createRange(SIZE/2, SIZE/2); - kernel.execute(range); - } finally { - kernel.dispose(); - } - - assertEquals("Max value doesn't match", 100, out[0]); - assertTrue("Left max found at unexpected position: " + out[MAX_POS_LEFT_IDX], out[MAX_POS_LEFT_IDX] == 10 || out[MAX_POS_LEFT_IDX] == 50); - assertTrue("Right max found at unexpected position: " + out[MAX_POS_RIGHT_IDX], out[MAX_POS_RIGHT_IDX] == 100-10 || out[MAX_POS_RIGHT_IDX] == 100-50); - } - - @Test - public void testJTP() { - KernelManager.setKernelManager(new JTPKernelManager()); - Device device = KernelManager.instance().bestDevice(); - final int in[] = new int[SIZE]; - - final int[] out = new int[3]; - for (int i = 0; i < SIZE/2; i++) { - in[i] = i; - in[i + SIZE/2] = SIZE - i; - } - in[10] = SIZE; - - final AtomicKernel kernel = new AtomicKernel(in, out); - try { - final Range range = device.createRange(SIZE/2, SIZE/2); - kernel.execute(range); - } finally { - kernel.dispose(); - } - assertEquals("Max value doesn't match", 100, out[0]); - assertTrue("Left max found at unexpected position: " + out[MAX_POS_LEFT_IDX], out[MAX_POS_LEFT_IDX] == 10 || out[MAX_POS_LEFT_IDX] == 50); - assertTrue("Right max found at unexpected position: " + out[MAX_POS_RIGHT_IDX], out[MAX_POS_RIGHT_IDX] == 100-10 || out[MAX_POS_RIGHT_IDX] == 100-50); - } - - @Test - public void testBOpenCL() { - final int in[] = new int[SIZE]; - final AtomicInteger[] out = new AtomicInteger[3]; - for (int i = 0; i < out.length; i++) { - out[i] = new AtomicInteger(0); - } - for (int i = 0; i < SIZE/2; i++) { - in[i] = i; - in[i + SIZE/2] = SIZE - i; - } - in[10] = SIZE; - - final AtomicBKernel kernel = new AtomicBKernel(in, out); - try { - final Range range = openCLDevice.createRange(SIZE/2, SIZE/2); - kernel.execute(range); - } finally { - kernel.dispose(); - } - - assertEquals("Max value doesn't match", 100, out[0].get()); - assertTrue("Left max found at unexpected position: " + out[MAX_POS_LEFT_IDX], out[MAX_POS_LEFT_IDX].get() == 10 || out[MAX_POS_LEFT_IDX].get() == 50); - assertTrue("Right max found at unexpected position: " + out[MAX_POS_RIGHT_IDX], out[MAX_POS_RIGHT_IDX].get() == 100-10 || out[MAX_POS_RIGHT_IDX].get() == 100-50); - } - - @Test - public void testBJTP() { - KernelManager.setKernelManager(new JTPKernelManager()); - Device device = KernelManager.instance().bestDevice(); - final int in[] = new int[SIZE]; - final AtomicInteger[] out = new AtomicInteger[3]; - for (int i = 0; i < out.length; i++) { - out[i] = new AtomicInteger(0); - } - for (int i = 0; i < SIZE/2; i++) { - in[i] = i; - in[i + SIZE/2] = SIZE - i; - } - in[10] = SIZE; - - final AtomicBKernel kernel = new AtomicBKernel(in, out); - try { - final Range range = device.createRange(SIZE/2, SIZE/2); - kernel.execute(range); - } finally { - kernel.dispose(); - } - assertEquals("Max value doesn't match", 100, out[0].get()); - assertTrue("Left max found at unexpected position: " + out[MAX_POS_LEFT_IDX], out[MAX_POS_LEFT_IDX].get() == 10 || out[MAX_POS_LEFT_IDX].get() == 50); - assertTrue("Right max found at unexpected position: " + out[MAX_POS_RIGHT_IDX], out[MAX_POS_RIGHT_IDX].get() == 100-10 || out[MAX_POS_RIGHT_IDX].get() == 100-50); - } - - private static final class AtomicKernel extends Kernel { - private int in[]; - private int out[]; - - @Local - private final AtomicInteger maxs[] = new AtomicInteger[4]; - - public AtomicKernel(int[] in, int[] out) { - this.in = in; - this.out = out; - for (int idx = 0; idx < 4; idx++) { - maxs[idx] = new AtomicInteger(0); - } - } - - @Override - public void run() { - final int localId = getLocalId(0); - - //Ensure that initial values are initialized... this must be enforced for OpenCL, otherwise they may contain - //random values, as for Java, it is not needed, as they are already initialized in AtomicInteger constructor. - //Since this is Aparapi, it must be initialized on both platforms. - if (localId == 0) { - atomicSet(maxs[MAX_VAL_IDX], 0); - atomicSet(maxs[LOCK_IDX], 0); - } - //Ensure all threads start with the initialized atomic max value and lock. - localBarrier(); - - final int offset = localId * 2; - int localMaxVal = 0; - int localMaxPosFromLeft = 0; - int localMaxPosFromRight = 0; - for (int i = 0; i < 2; i++) { - localMaxVal = max(in[offset + i], localMaxVal); - if (localMaxVal == in[offset + i]) { - localMaxPosFromLeft = offset + i; - localMaxPosFromRight = SIZE - (offset + i); - } - } - - atomicMax(maxs[MAX_VAL_IDX], localMaxVal); - //Ensure all threads have updated the atomic maxs[MAX_VAL_IDX] - localBarrier(); - - int maxValue = atomicGet(maxs[MAX_VAL_IDX]); - //Only the threads that have the max value will reach this point, however the max value, may - //occur at multiple indices of the input array. - if (maxValue == localMaxVal && atomicXchg(maxs[LOCK_IDX], 0xff) == 0) { - //Only one of the threads with the max value will get here, thus ensuring consistent update of - //maxPosFromRight and maxPosFromLeft. - atomicSet(maxs[MAX_POS_LEFT_IDX], localMaxPosFromLeft); - atomicSet(maxs[MAX_POS_RIGHT_IDX], localMaxPosFromRight); - out[MAX_VAL_IDX] = maxValue; - out[MAX_POS_LEFT_IDX] = atomicGet(maxs[MAX_POS_LEFT_IDX]); - out[MAX_POS_RIGHT_IDX] = localMaxPosFromRight; - } - } - } - - private static final class AtomicBKernel extends Kernel { - private int in[]; - private AtomicInteger out[]; - - @Local - private final AtomicInteger maxs[] = new AtomicInteger[4]; - - public AtomicBKernel(int[] in, AtomicInteger[] out) { - this.in = in; - this.out = out; - for (int idx = 0; idx < 4; idx++) { - maxs[idx] = new AtomicInteger(0); - } - } - - @Override - public void run() { - final int localId = getLocalId(0); - - //Ensure that initial values are initialized... this must be enforced for OpenCL, otherwise they may contain - //random values, as for Java, it is not needed, as they are already initialized in AtomicInteger constructor. - //Since this is Aparapi, it must be initialized on both platforms. - if (localId == 0) { - atomicSet(maxs[MAX_VAL_IDX], 0); - atomicSet(maxs[LOCK_IDX], 0); - } - //Ensure all threads start with the initialized atomic max value and lock. - localBarrier(); - - final int offset = localId * 2; - int localMaxVal = 0; - int localMaxPosFromLeft = 0; - int localMaxPosFromRight = 0; - for (int i = 0; i < 2; i++) { - localMaxVal = max(in[offset + i], localMaxVal); - if (localMaxVal == in[offset + i]) { - localMaxPosFromLeft = offset + i; - localMaxPosFromRight = SIZE - (offset + i); - } - } - - atomicMax(maxs[MAX_VAL_IDX], localMaxVal); - //Ensure all threads have updated the atomic maxs[MAX_VAL_IDX] - localBarrier(); - - int maxValue = atomicGet(maxs[MAX_VAL_IDX]); - //Only the threads that have the max value will reach this point, however the max value, may - //occur at multiple indices of the input array. - if (maxValue == localMaxVal && atomicXchg(maxs[LOCK_IDX], 0xff) == 0) { - //Only one of the threads with the max value will get here, thus ensuring consistent update of - //maxPosFromRight and maxPosFromLeft. - atomicSet(maxs[MAX_POS_LEFT_IDX], localMaxPosFromLeft); - atomicSet(maxs[MAX_POS_RIGHT_IDX], localMaxPosFromRight); - atomicSet(out[MAX_VAL_IDX], maxValue); - atomicSet(out[MAX_POS_LEFT_IDX], atomicGet(maxs[MAX_POS_LEFT_IDX])); - atomicSet(out[MAX_POS_RIGHT_IDX], localMaxPosFromRight); - } - } - } - -} diff --git a/src/test/java/com/aparapi/runtime/AtomicsSupportTest.java b/src/test/java/com/aparapi/runtime/AtomicsSupportTest.java deleted file mode 100644 index b7aca3cc..00000000 --- a/src/test/java/com/aparapi/runtime/AtomicsSupportTest.java +++ /dev/null @@ -1,1235 +0,0 @@ -/** - * Copyright (c) 2016 - 2018 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 static org.junit.Assert.assertEquals; -import static org.junit.Assume.assumeTrue; - -import java.util.Arrays; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.aparapi.Kernel; -import com.aparapi.Range; -import com.aparapi.device.Device; -import com.aparapi.device.JavaDevice; -import com.aparapi.device.OpenCLDevice; -import com.aparapi.internal.kernel.KernelManager; - -/** - * Base tests for validation of the correctness of the atomics function computations, both on Java and on OpenCL. - * @author CodeRasurae - */ -public class AtomicsSupportTest { - - private static OpenCLDevice openCLDevice = null; - - private class CLKernelManager extends KernelManager { - @Override - protected List getPreferredDeviceTypes() { - return Arrays.asList(Device.TYPE.ACC, Device.TYPE.GPU, Device.TYPE.CPU); - } - } - - private class JTPKernelManager extends KernelManager { - private JTPKernelManager() { - LinkedHashSet preferredDevices = new LinkedHashSet(1); - preferredDevices.add(JavaDevice.THREAD_POOL); - setDefaultPreferredDevices(preferredDevices); - } - @Override - protected List getPreferredDeviceTypes() { - return Arrays.asList(Device.TYPE.JTP); - } - } - - @After - public void classTeardown() { - Util.resetKernelManager(); - } - - @Before - public void setUpBeforeClass() throws Exception { - KernelManager.setKernelManager(new CLKernelManager()); - Device device = KernelManager.instance().bestDevice(); - assumeTrue (device != null && device instanceof OpenCLDevice); - openCLDevice = (OpenCLDevice) device; - } - - @Test - public void testAtomicAddOpenCLExplicit() { - final int in[] = new int[2]; - final int[] out = new int[2]; - in[0] = 10; - in[1] = 20; - - final AtomicAdd kernel = new AtomicAdd(in, out); - try { - final Range range = openCLDevice.createRange(1,1); - kernel.setExplicit(true); - kernel.put(in); - kernel.execute(range); - kernel.get(out); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", in[0] + in[1], out[1]); - } - - @Test - public void testAtomicAddOpenCL() { - final int in[] = new int[2]; - final int[] out = new int[2]; - in[0] = 10; - in[1] = 20; - - final AtomicAdd kernel = new AtomicAdd(in, out); - try { - final Range range = openCLDevice.createRange(1,1); - kernel.execute(range); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", in[0] + in[1], out[1]); - } - - @Test - public void testAtomicAddJTP() { - KernelManager.setKernelManager(new JTPKernelManager()); - Device device = KernelManager.instance().bestDevice(); - final int in[] = new int[2]; - final int[] out = new int[2]; - in[0] = 10; - in[1] = 20; - - final AtomicAdd kernel = new AtomicAdd(in, out); - try { - final Range range = device.createRange(1,1); - kernel.execute(range); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", in[0] + in[1], out[1]); - } - - /** - * Kernel for single threaded validation of atomicAdd. - * Validates that a add operation is actually performed. - * @author lpnm - * - */ - private static final class AtomicAdd extends Kernel { - private int in[]; - private int out[]; - - @Local - private AtomicInteger atomicValues[]; - - public AtomicAdd(int[] in, int out[]) { - this.in = in; - this.out = out; - atomicValues = new AtomicInteger[2]; - atomicValues[0] = new AtomicInteger(0); - atomicValues[1] = new AtomicInteger(0); - } - - @Override - public void run() { - atomicSet(atomicValues[0], in[0]); - out[0] = atomicAdd(atomicValues[0], in[1]); - out[1] = atomicGet(atomicValues[0]); - } - } - - @Test - public void testAtomicSubOpenCLExplicit() { - final int in[] = new int[2]; - final int[] out = new int[2]; - in[0] = 10; - in[1] = 20; - - final AtomicSub kernel = new AtomicSub(in, out); - try { - final Range range = openCLDevice.createRange(1,1); - kernel.setExplicit(true); - kernel.put(in); - kernel.execute(range); - kernel.get(out); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", in[0] - in[1], out[1]); - } - - @Test - public void testAtomicSubOpenCL() { - final int in[] = new int[2]; - final int[] out = new int[2]; - in[0] = 10; - in[1] = 20; - - final AtomicSub kernel = new AtomicSub(in, out); - try { - final Range range = openCLDevice.createRange(1,1); - kernel.execute(range); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", in[0] - in[1], out[1]); - } - - @Test - public void testAtomicSubJTP() { - KernelManager.setKernelManager(new JTPKernelManager()); - Device device = KernelManager.instance().bestDevice(); - final int in[] = new int[2]; - final int[] out = new int[2]; - in[0] = 10; - in[1] = 20; - - final AtomicSub kernel = new AtomicSub(in, out); - try { - final Range range = device.createRange(1,1); - kernel.execute(range); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", in[0] - in[1], out[1]); - } - - /** - * Kernel for single threaded validation of atomicSub. - * Validates that a subtraction operation is actually performed. - * @author lpnm - * - */ - private static final class AtomicSub extends Kernel { - private int in[]; - private int out[]; - - @Local - private AtomicInteger atomicValues[]; - - public AtomicSub(int[] in, int out[]) { - this.in = in; - this.out = out; - atomicValues = new AtomicInteger[2]; - atomicValues[0] = new AtomicInteger(0); - atomicValues[1] = new AtomicInteger(0); - } - - @Override - public void run() { - atomicSet(atomicValues[0], in[0]); - out[0] = atomicSub(atomicValues[0], in[1]); - out[1] = atomicGet(atomicValues[0]); - } - - } - - @Test - public void testAtomicXchgOpenCLExplicit() { - - final int in[] = new int[2]; - final int[] out = new int[2]; - in[0] = 10; - in[1] = 20; - - final AtomicXchg kernel = new AtomicXchg(in, out); - try { - final Range range = openCLDevice.createRange(1,1); - kernel.setExplicit(true); - kernel.put(in); - kernel.execute(range); - kernel.get(out); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", in[1], out[1]); - } - - @Test - public void testAtomicXchgOpenCL() { - final int in[] = new int[2]; - final int[] out = new int[2]; - in[0] = 10; - in[1] = 20; - - final AtomicXchg kernel = new AtomicXchg(in, out); - try { - final Range range = openCLDevice.createRange(1,1); - kernel.execute(range); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", in[1], out[1]); - } - - @Test - public void testAtomicXchgJTP() { - KernelManager.setKernelManager(new JTPKernelManager()); - Device device = KernelManager.instance().bestDevice(); - final int in[] = new int[2]; - final int[] out = new int[2]; - in[0] = 10; - in[1] = 20; - - final AtomicXchg kernel = new AtomicXchg(in, out); - try { - final Range range = device.createRange(1,1); - kernel.execute(range); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", in[1], out[1]); - } - - /** - * Kernel for single threaded validation of atomicXchg. - * Validates that a value exchange operation is actually performed. - * @author lpnm - * - */ - private static final class AtomicXchg extends Kernel { - private int in[]; - private int out[]; - - @Local - private AtomicInteger atomicValues[]; - - public AtomicXchg(int[] in, int out[]) { - this.in = in; - this.out = out; - atomicValues = new AtomicInteger[2]; - atomicValues[0] = new AtomicInteger(0); - atomicValues[1] = new AtomicInteger(0); - } - - @Override - public void run() { - atomicSet(atomicValues[0], in[0]); - out[0] = atomicXchg(atomicValues[0], in[1]); - out[1] = atomicGet(atomicValues[0]); - } - - } - - @Test - public void testAtomicIncOpenCLExplicit() { - final int in[] = new int[1]; - final int[] out = new int[2]; - in[0] = 50; - - final AtomicInc kernel = new AtomicInc(in, out); - try { - final Range range = openCLDevice.createRange(1,1); - kernel.setExplicit(true); - kernel.put(in); - kernel.execute(range); - kernel.get(out); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", in[0] + 1, out[1]); - } - - @Test - public void testAtomicIncOpenCL() { - final int in[] = new int[1]; - final int[] out = new int[2]; - in[0] = 50; - - final AtomicInc kernel = new AtomicInc(in, out); - try { - final Range range = openCLDevice.createRange(1,1); - kernel.execute(range); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", in[0] + 1, out[1]); - } - - @Test - public void testAtomicInc() { - KernelManager.setKernelManager(new JTPKernelManager()); - Device device = KernelManager.instance().bestDevice(); - final int in[] = new int[1]; - final int[] out = new int[2]; - in[0] = 50; - - final AtomicInc kernel = new AtomicInc(in, out); - try { - final Range range = device.createRange(1,1); - kernel.execute(range); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", in[0] + 1, out[1]); - } - - /** - * Kernel for single threaded validation of atomicInc. - * Validates that an increment operation is actually performed. - * @author lpnm - * - */ - private static final class AtomicInc extends Kernel { - private int in[]; - private int out[]; - - @Local - private AtomicInteger atomicValues[]; - - public AtomicInc(int[] in, int out[]) { - this.in = in; - this.out = out; - atomicValues = new AtomicInteger[2]; - atomicValues[0] = new AtomicInteger(0); - atomicValues[1] = new AtomicInteger(0); - } - - @Override - public void run() { - atomicSet(atomicValues[0], in[0]); - out[0] = atomicInc(atomicValues[0]); - out[1] = atomicGet(atomicValues[0]); - } - - } - - @Test - public void testAtomicDecOpenCLExplicit() { - final int in[] = new int[1]; - final int[] out = new int[2]; - in[0] = 50; - - final AtomicDec kernel = new AtomicDec(in, out); - try { - final Range range = openCLDevice.createRange(1,1); - kernel.setExplicit(true); - kernel.put(in); - kernel.execute(range); - kernel.get(out); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", in[0] - 1, out[1]); - } - - @Test - public void testAtomicDecOpenCL() { - final int in[] = new int[1]; - final int[] out = new int[2]; - in[0] = 50; - - final AtomicDec kernel = new AtomicDec(in, out); - try { - final Range range = openCLDevice.createRange(1,1); - kernel.execute(range); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", in[0] - 1, out[1]); - } - - @Test - public void testAtomicDecJTP() { - KernelManager.setKernelManager(new JTPKernelManager()); - Device device = KernelManager.instance().bestDevice(); - final int in[] = new int[1]; - final int[] out = new int[2]; - in[0] = 50; - - final AtomicDec kernel = new AtomicDec(in, out); - try { - final Range range = device.createRange(1,1); - kernel.execute(range); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", in[0] - 1, out[1]); - } - - /** - * Kernel for single threaded validation of atomicDec. - * Validates that a decrement operation is actually performed. - * @author lpnm - * - */ - private static final class AtomicDec extends Kernel { - private int in[]; - private int out[]; - - @Local - private AtomicInteger atomicValues[]; - - public AtomicDec(int[] in, int out[]) { - this.in = in; - this.out = out; - atomicValues = new AtomicInteger[2]; - atomicValues[0] = new AtomicInteger(0); - atomicValues[1] = new AtomicInteger(0); - } - - @Override - public void run() { - atomicSet(atomicValues[0], in[0]); - out[0] = atomicDec(atomicValues[0]); - out[1] = atomicGet(atomicValues[0]); - } - - } - - @Test - public void testAtomicCmpXchg1OpenCLExplicit() { - final int in[] = new int[3]; - final int[] out = new int[2]; - in[0] = 50; - in[1] = 50; - in[2] = 100; - - final AtomicCmpXchg kernel = new AtomicCmpXchg(in, out); - try { - final Range range = openCLDevice.createRange(1,1); - kernel.setExplicit(true); - kernel.put(in); - kernel.execute(range); - kernel.get(out); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", in[2], out[1]); - } - - @Test - public void testAtomicCmpXchg1OpenCL() { - final int in[] = new int[3]; - final int[] out = new int[2]; - in[0] = 50; - in[1] = 50; - in[2] = 100; - - final AtomicCmpXchg kernel = new AtomicCmpXchg(in, out); - try { - final Range range = openCLDevice.createRange(1,1); - kernel.execute(range); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", in[2], out[1]); - } - - @Test - public void testAtomicCmpXchg1JTP() { - KernelManager.setKernelManager(new JTPKernelManager()); - Device device = KernelManager.instance().bestDevice(); - final int in[] = new int[3]; - final int[] out = new int[2]; - in[0] = 50; - in[1] = 50; - in[2] = 100; - - final AtomicCmpXchg kernel = new AtomicCmpXchg(in, out); - try { - final Range range = device.createRange(1,1); - kernel.execute(range); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", in[2], out[1]); - } - - @Test - public void testAtomicCmpXchg2OpenCLExplicit() { - - final int in[] = new int[3]; - final int[] out = new int[2]; - in[0] = 50; - in[1] = 51; - in[2] = 100; - - final AtomicCmpXchg kernel = new AtomicCmpXchg(in, out); - try { - final Range range = openCLDevice.createRange(1,1); - kernel.setExplicit(true); - kernel.put(in); - kernel.execute(range); - kernel.get(out); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", in[0], out[1]); - } - - @Test - public void testAtomicCmpXchg2OpenCL() { - final int in[] = new int[3]; - final int[] out = new int[2]; - in[0] = 50; - in[1] = 51; - in[2] = 100; - - final AtomicCmpXchg kernel = new AtomicCmpXchg(in, out); - try { - final Range range = openCLDevice.createRange(1,1); - kernel.execute(range); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", in[0], out[1]); - } - - @Test - public void testAtomicCmpXchg2JTP() { - KernelManager.setKernelManager(new JTPKernelManager()); - Device device = KernelManager.instance().bestDevice(); - final int in[] = new int[3]; - final int[] out = new int[2]; - in[0] = 50; - in[1] = 51; - in[2] = 100; - - final AtomicCmpXchg kernel = new AtomicCmpXchg(in, out); - try { - final Range range = device.createRange(1,1); - kernel.execute(range); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", in[0], out[1]); - } - - /** - * Kernel for single threaded validation of atomicCmpXchg. - * Validates that a cmpXchg operation is actually performed. - * @author lpnm - * - */ - private static final class AtomicCmpXchg extends Kernel { - private int in[]; - private int out[]; - - @Local - private AtomicInteger atomicValues[]; - - public AtomicCmpXchg(int[] in, int out[]) { - this.in = in; - this.out = out; - atomicValues = new AtomicInteger[2]; - atomicValues[0] = new AtomicInteger(0); - atomicValues[1] = new AtomicInteger(0); - } - - @Override - public void run() { - atomicSet(atomicValues[0], in[0]); - out[0] = atomicCmpXchg(atomicValues[0], in[1], in[2]); - out[1] = atomicGet(atomicValues[0]); - } - - } - - @Test - public void testAtomicMin1OpenCLExplicit() { - final int in[] = new int[2]; - final int[] out = new int[2]; - in[0] = 50; - in[1] = 49; - - final AtomicMin kernel = new AtomicMin(in, out); - try { - final Range range = openCLDevice.createRange(1,1); - kernel.setExplicit(true); - kernel.put(in); - kernel.execute(range); - kernel.get(out); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", in[1], out[1]); - } - - @Test - public void testAtomicMin1OpenCL() { - final int in[] = new int[2]; - final int[] out = new int[2]; - in[0] = 50; - in[1] = 49; - - final AtomicMin kernel = new AtomicMin(in, out); - try { - final Range range = openCLDevice.createRange(1,1); - kernel.execute(range); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", in[1], out[1]); - } - - @Test - public void testAtomicMin1JTP() { - KernelManager.setKernelManager(new JTPKernelManager()); - Device device = KernelManager.instance().bestDevice(); - final int in[] = new int[2]; - final int[] out = new int[2]; - in[0] = 50; - in[1] = 49; - - final AtomicMin kernel = new AtomicMin(in, out); - try { - final Range range = device.createRange(1,1); - kernel.execute(range); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", in[1], out[1]); - } - - @Test - public void testAtomicMin2OpenCLExplicit() { - final int in[] = new int[2]; - final int[] out = new int[2]; - in[0] = 50; - in[1] = 51; - - final AtomicMin kernel = new AtomicMin(in, out); - try { - final Range range = openCLDevice.createRange(1,1); - kernel.setExplicit(true); - kernel.put(in); - kernel.execute(range); - kernel.get(out); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", in[0], out[1]); - } - - @Test - public void testAtomicMin2OpenCL() { - final int in[] = new int[2]; - final int[] out = new int[2]; - in[0] = 50; - in[1] = 51; - - final AtomicMin kernel = new AtomicMin(in, out); - try { - final Range range = openCLDevice.createRange(1,1); - kernel.execute(range); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", in[0], out[1]); - } - - @Test - public void testAtomicMin2JTP() { - KernelManager.setKernelManager(new JTPKernelManager()); - Device device = KernelManager.instance().bestDevice(); - final int in[] = new int[2]; - final int[] out = new int[2]; - in[0] = 50; - in[1] = 51; - - final AtomicMin kernel = new AtomicMin(in, out); - try { - final Range range = device.createRange(1,1); - kernel.execute(range); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", in[0], out[1]); - } - - /** - * Kernel for single threaded validation of atomicMin. - * Validates that a min operation is actually performed. - * @author lpnm - * - */ - private static final class AtomicMin extends Kernel { - private int in[]; - private int out[]; - - @Local - private AtomicInteger atomicValues[]; - - public AtomicMin(int[] in, int out[]) { - this.in = in; - this.out = out; - atomicValues = new AtomicInteger[2]; - atomicValues[0] = new AtomicInteger(0); - atomicValues[1] = new AtomicInteger(0); - } - - @Override - public void run() { - atomicSet(atomicValues[0], in[0]); - out[0] = atomicMin(atomicValues[0], in[1]); - out[1] = atomicGet(atomicValues[0]); - } - - } - - @Test - public void testAtomicMax1OpenCLExplicit() { - final int in[] = new int[2]; - final int[] out = new int[2]; - in[0] = 50; - in[1] = 51; - - final AtomicMax kernel = new AtomicMax(in, out); - try { - final Range range = openCLDevice.createRange(1,1); - kernel.setExplicit(true); - kernel.put(in); - kernel.execute(range); - kernel.get(out); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", in[1], out[1]); - } - - @Test - public void testAtomicMax1OpenCL() { - final int in[] = new int[2]; - final int[] out = new int[2]; - in[0] = 50; - in[1] = 51; - - final AtomicMax kernel = new AtomicMax(in, out); - try { - final Range range = openCLDevice.createRange(1,1); - kernel.execute(range); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", in[1], out[1]); - } - - @Test - public void testAtomicMax1JTP() { - KernelManager.setKernelManager(new JTPKernelManager()); - Device device = KernelManager.instance().bestDevice(); - final int in[] = new int[2]; - final int[] out = new int[2]; - in[0] = 50; - in[1] = 51; - - final AtomicMax kernel = new AtomicMax(in, out); - try { - final Range range = device.createRange(1,1); - kernel.execute(range); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", in[1], out[1]); - } - - @Test - public void testAtomicMax2OpenCLExplicit() { - final int in[] = new int[2]; - final int[] out = new int[2]; - in[0] = 50; - in[1] = 49; - - final AtomicMax kernel = new AtomicMax(in, out); - try { - final Range range = openCLDevice.createRange(1,1); - kernel.setExplicit(true); - kernel.put(in); - kernel.execute(range); - kernel.get(out); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", in[0], out[1]); - } - - @Test - public void testAtomicMax2OpenCL() { - final int in[] = new int[2]; - final int[] out = new int[2]; - in[0] = 50; - in[1] = 49; - - final AtomicMax kernel = new AtomicMax(in, out); - try { - final Range range = openCLDevice.createRange(1,1); - kernel.execute(range); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", in[0], out[1]); - } - - @Test - public void testAtomicMax2JTP() { - KernelManager.setKernelManager(new JTPKernelManager()); - Device device = KernelManager.instance().bestDevice(); - final int in[] = new int[2]; - final int[] out = new int[2]; - in[0] = 50; - in[1] = 49; - - final AtomicMax kernel = new AtomicMax(in, out); - try { - final Range range = device.createRange(1,1); - kernel.execute(range); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", in[0], out[1]); - } - - /** - * Kernel for single threaded validation of atomicMax. - * Validates that a max operation is actually performed. - * @author lpnm - * - */ - private static final class AtomicMax extends Kernel { - private int in[]; - private int out[]; - - @Local - private AtomicInteger atomicValues[]; - - public AtomicMax(int[] in, int out[]) { - this.in = in; - this.out = out; - atomicValues = new AtomicInteger[2]; - atomicValues[0] = new AtomicInteger(0); - atomicValues[1] = new AtomicInteger(0); - } - - @Override - public void run() { - atomicSet(atomicValues[0], in[0]); - out[0] = atomicMax(atomicValues[0], in[1]); - out[1] = atomicGet(atomicValues[0]); - } - - } - - @Test - public void testAtomicAndOpenCLExplicit() { - - final int in[] = new int[2]; - final int[] out = new int[2]; - in[0] = 0xf1; - in[1] = 0x8f; - - final AtomicAnd kernel = new AtomicAnd(in, out); - try { - final Range range = openCLDevice.createRange(1,1); - kernel.setExplicit(true); - kernel.put(in); - kernel.execute(range); - kernel.get(out); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", 0x81, out[1]); - } - - @Test - public void testAtomicAndOpenCL() { - - final int in[] = new int[2]; - final int[] out = new int[2]; - in[0] = 0xf1; - in[1] = 0x8f; - - final AtomicAnd kernel = new AtomicAnd(in, out); - try { - final Range range = openCLDevice.createRange(1,1); - kernel.execute(range); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", 0x81, out[1]); - } - - @Test - public void testAtomicAndJTP() { - KernelManager.setKernelManager(new JTPKernelManager()); - Device device = KernelManager.instance().bestDevice(); - final int in[] = new int[2]; - final int[] out = new int[2]; - in[0] = 0xf1; - in[1] = 0x8f; - - final AtomicAnd kernel = new AtomicAnd(in, out); - try { - final Range range = device.createRange(1,1); - kernel.execute(range); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", 0x81, out[1]); - } - - /** - * Kernel for single threaded validation of atomicXor. - * Validates that an and operation is actually performed. - * @author lpnm - * - */ - private static final class AtomicAnd extends Kernel { - private int in[]; - private int out[]; - - @Local - private AtomicInteger atomicValues[]; - - public AtomicAnd(int[] in, int out[]) { - this.in = in; - this.out = out; - atomicValues = new AtomicInteger[2]; - atomicValues[0] = new AtomicInteger(0); - atomicValues[1] = new AtomicInteger(0); - } - - @Override - public void run() { - atomicSet(atomicValues[0], in[0]); - out[0] = atomicAnd(atomicValues[0], in[1]); - out[1] = atomicGet(atomicValues[0]); - } - - } - - @Test - public void testAtomicOrOpenCLExplicit() { - - final int in[] = new int[2]; - final int[] out = new int[2]; - in[0] = 0x80; - in[1] = 0x02; - - final AtomicOr kernel = new AtomicOr(in, out); - try { - final Range range = openCLDevice.createRange(1,1); - kernel.setExplicit(true); - kernel.put(in); - kernel.execute(range); - kernel.get(out); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", 0x82, out[1]); - } - - @Test - public void testAtomicOrOpenCL() { - final int in[] = new int[2]; - final int[] out = new int[2]; - in[0] = 0x80; - in[1] = 0x02; - - final AtomicOr kernel = new AtomicOr(in, out); - try { - final Range range = openCLDevice.createRange(1,1); - kernel.execute(range); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", 0x82, out[1]); - } - - @Test - public void testAtomicOrJTP() { - KernelManager.setKernelManager(new JTPKernelManager()); - Device device = KernelManager.instance().bestDevice(); - final int in[] = new int[2]; - final int[] out = new int[2]; - in[0] = 0x80; - in[1] = 0x02; - - final AtomicOr kernel = new AtomicOr(in, out); - try { - final Range range = device.createRange(1,1); - kernel.execute(range); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", 0x82, out[1]); - } - - /** - * Kernel for single threaded validation of atomicOr. - * Validates that an or operation is actually performed. - * @author lpnm - * - */ - private static final class AtomicOr extends Kernel { - private int in[]; - private int out[]; - - @Local - private AtomicInteger atomicValues[]; - - public AtomicOr(int[] in, int out[]) { - this.in = in; - this.out = out; - atomicValues = new AtomicInteger[2]; - atomicValues[0] = new AtomicInteger(0); - atomicValues[1] = new AtomicInteger(0); - } - - @Override - public void run() { - atomicSet(atomicValues[0], in[0]); - out[0] = atomicOr(atomicValues[0], in[1]); - out[1] = atomicGet(atomicValues[0]); - } - - } - - @Test - public void testAtomicXorOpenCLExplicit() { - final int in[] = new int[2]; - final int[] out = new int[2]; - in[0] = 0xf1; - in[1] = 0x8f; - - final AtomicXor kernel = new AtomicXor(in, out); - try { - final Range range = openCLDevice.createRange(1,1); - kernel.setExplicit(true); - kernel.put(in); - kernel.execute(range); - kernel.get(out); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", 0x7e, out[1]); - } - - @Test - public void testAtomicXorOpenCL() { - final int in[] = new int[2]; - final int[] out = new int[2]; - in[0] = 0xf1; - in[1] = 0x8f; - - final AtomicXor kernel = new AtomicXor(in, out); - try { - final Range range = openCLDevice.createRange(1,1); - kernel.execute(range); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", 0x7e, out[1]); - } - - @Test - public void testAtomicXorJTP() { - KernelManager.setKernelManager(new JTPKernelManager()); - Device device = KernelManager.instance().bestDevice(); - final int in[] = new int[2]; - final int[] out = new int[2]; - in[0] = 0xf1; - in[1] = 0x8f; - - final AtomicXor kernel = new AtomicXor(in, out); - try { - final Range range = device.createRange(1,1); - kernel.execute(range); - } finally { - kernel.dispose(); - } - assertEquals("Old value doesn't match", in[0], out[0]); - assertEquals("Final value doesn't match", 0x7e, out[1]); - } - - /** - * Kernel for single threaded validation of atomicXor. - * Validates that a xor operation is actually performed. - * @author lpnm - * - */ - private static final class AtomicXor extends Kernel { - private int in[]; - private int out[]; - - @Local - private AtomicInteger atomicValues[]; - - public AtomicXor(int[] in, int out[]) { - this.in = in; - this.out = out; - atomicValues = new AtomicInteger[2]; - atomicValues[0] = new AtomicInteger(0); - atomicValues[1] = new AtomicInteger(0); - } - - @Override - public void run() { - atomicSet(atomicValues[0], in[0]); - out[0] = atomicXor(atomicValues[0], in[1]); - out[1] = atomicGet(atomicValues[0]); - } - } -} diff --git a/src/test/java/com/aparapi/runtime/BarrierSupportTest.java b/src/test/java/com/aparapi/runtime/BarrierSupportTest.java deleted file mode 100644 index b6b65c67..00000000 --- a/src/test/java/com/aparapi/runtime/BarrierSupportTest.java +++ /dev/null @@ -1,303 +0,0 @@ -/** - * Copyright (c) 2016 - 2018 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.JavaDevice; -import com.aparapi.device.OpenCLDevice; -import com.aparapi.internal.kernel.KernelManager; - -import static org.junit.Assert.*; -import static org.junit.Assume.*; - -import java.util.Arrays; -import java.util.LinkedHashSet; -import java.util.List; - -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.Test; - -public class BarrierSupportTest { - private static OpenCLDevice openCLDevice = null; - private static int SIZE; - private int[] targetArray; - - private class CLKernelManager extends KernelManager { - @Override - protected List getPreferredDeviceTypes() { - return Arrays.asList(Device.TYPE.ACC, Device.TYPE.GPU, Device.TYPE.CPU); - } - } - - private class JTPKernelManager extends KernelManager { - private JTPKernelManager() { - LinkedHashSet preferredDevices = new LinkedHashSet(1); - preferredDevices.add(JavaDevice.THREAD_POOL); - setDefaultPreferredDevices(preferredDevices); - } - @Override - protected List getPreferredDeviceTypes() { - return Arrays.asList(Device.TYPE.JTP); - } - } - - @AfterClass - public static void classTeardown() { - Util.resetKernelManager(); - } - - @Before - public void setUpBefore() throws Exception { - KernelManager.setKernelManager(new CLKernelManager()); - Device device = KernelManager.instance().bestDevice(); - assumeTrue (device != null && device instanceof OpenCLDevice); - openCLDevice = (OpenCLDevice) device; - SIZE = openCLDevice.getMaxWorkGroupSize(); - } - - @Test - public void testBarrier1() { - final Barrrier1Kernel kernel = new Barrrier1Kernel(SIZE); - try { - final Range range = openCLDevice.createRange(SIZE, SIZE); - targetArray = initInputArray(); - kernel.setExplicit(false); - kernel.setArray(targetArray); - kernel.execute(range); - assertTrue(validate()); - } finally { - kernel.dispose(); - } - } - - @Test - public void testBarrier1Explicit() { - final Barrrier1Kernel kernel = new Barrrier1Kernel(SIZE); - try { - final Range range = openCLDevice.createRange(SIZE, SIZE); - targetArray = initInputArray(); - kernel.setExplicit(true); - kernel.setArray(targetArray); - kernel.put(targetArray); - kernel.execute(range); - kernel.get(targetArray); - assertTrue(validate()); - } finally { - kernel.dispose(); - } - } - - @Test - public void testBarrier1JTP() { - SIZE = 256; - KernelManager.setKernelManager(new JTPKernelManager()); - Device device = KernelManager.instance().bestDevice(); - assumeTrue (device != null && device instanceof JavaDevice); - - final Barrrier1Kernel kernel = new Barrrier1Kernel(SIZE); - try { - final Range range = device.createRange(SIZE, SIZE); - targetArray = initInputArray(); - kernel.setExplicit(false); - kernel.setArray(targetArray); - kernel.execute(range); - assertTrue(validate()); - } finally { - kernel.dispose(); - } - } - - @Test - public void testBarrier2() { - final Barrrier2Kernel kernel = new Barrrier2Kernel(SIZE); - try { - final Range range = openCLDevice.createRange(SIZE, SIZE); - targetArray = initInputArray(); - kernel.setExplicit(false); - kernel.setArray(targetArray); - kernel.execute(range); - assertTrue(validate()); - } finally { - kernel.dispose(); - } - } - - @Test - public void testBarrier2Explicit() { - final Barrrier2Kernel kernel = new Barrrier2Kernel(SIZE); - try { - final Range range = openCLDevice.createRange(SIZE, SIZE); - targetArray = initInputArray(); - kernel.setExplicit(true); - kernel.setArray(targetArray); - kernel.put(targetArray); - kernel.execute(range); - kernel.get(targetArray); - assertTrue(validate()); - } finally { - kernel.dispose(); - } - } - - @Test - public void testBarrier2JTP() { - SIZE = 256; - KernelManager.setKernelManager(new JTPKernelManager()); - Device device = KernelManager.instance().bestDevice(); - assumeTrue (device != null && device instanceof JavaDevice); - - final Barrrier2Kernel kernel = new Barrrier2Kernel(SIZE); - try { - final Range range = device.createRange(SIZE, SIZE); - targetArray = initInputArray(); - kernel.setExplicit(false); - kernel.setArray(targetArray); - kernel.execute(range); - assertTrue(validate()); - } finally { - kernel.dispose(); - } - } - - private int[] initInputArray() { - int[] inputArray = new int[SIZE]; - for (int i = 0; i < SIZE; i++) { - inputArray[i] = i; - } - return inputArray; - } - - private boolean validate() { - int[] inputArray = initInputArray(); - int[] expected = new int[SIZE]; - for (int threadId = 0; threadId < SIZE; threadId++) { - final int targetId = (SIZE - 1) - ((threadId + SIZE/2) % SIZE); - expected[targetId] += inputArray[threadId]; - for (int i = 0; i < SIZE; i++) { - expected[threadId] += i; - } - } - - int[] temp = expected; - expected = new int[SIZE]; - for (int threadId = 0; threadId < SIZE; threadId++) { - int targetId = ((threadId + SIZE/2) % SIZE); - expected[targetId] = temp[threadId]; - } - - for (int threadId = 0; threadId < SIZE; threadId++) { - if (threadId < SIZE/2) { - expected[threadId] += expected[(SIZE-1) - threadId]; - } - } - - assertArrayEquals("targetArray", expected, targetArray); - - return true; - } - - private static class Barrrier1Kernel extends Kernel { - private final int SIZE; - private int[] resultArray; - - @Local - private int[] myArray; - - private Barrrier1Kernel(int size) { - this.SIZE = size; - myArray = new int[size]; - } - - @NoCL - public void setArray(int[] target) { - resultArray = target; - } - - private void doInitialCopy(@Local int[] target, int[] source, int id) { - int targetId = (SIZE - 1) - ((id + SIZE/2) % SIZE); - target[targetId] = source[id]; - } - - private void doComputation1(@Local int[] arr, int id) { - for (int i = 0; i < SIZE; i++) { - arr[id] += i; - } - } - - @Override - public void run() { - int id = getLocalId(); - - doInitialCopy(myArray, resultArray, id); - localBarrier(); - doComputation1(myArray, id); - int targetId = ((id + SIZE/2) % SIZE); - resultArray[targetId] = myArray[id]; - globalBarrier(); - if (id < SIZE/2) { - resultArray[id] += resultArray[(SIZE - 1) - id]; - } - } - } - - private static class Barrrier2Kernel extends Kernel { - private final int SIZE; - private int[] resultArray; - - @Local - private int[] myArray; - - private Barrrier2Kernel(int size) { - this.SIZE = size; - myArray = new int[size]; - } - - @NoCL - public void setArray(int[] target) { - resultArray = target; - } - - private void doInitialCopy(@Local int[] target, int[] source, int id) { - int targetId = (SIZE - 1) - ((id + SIZE/2) % SIZE); - target[targetId] = source[id]; - } - - private void doComputation1(@Local int[] arr, int id) { - for (int i = 0; i < SIZE; i++) { - arr[id] += i; - } - } - - @Override - public void run() { - int id = getLocalId(); - - doInitialCopy(myArray, resultArray, id); - localGlobalBarrier(); - doComputation1(myArray, id); - int targetId = ((id + SIZE/2) % SIZE); - resultArray[targetId] = myArray[id]; - localGlobalBarrier(); - if (id < SIZE/2) { - resultArray[id] += resultArray[(SIZE - 1) - id]; - } - } - } - -} diff --git a/src/test/java/com/aparapi/runtime/BufferTransferTest.java b/src/test/java/com/aparapi/runtime/BufferTransferTest.java deleted file mode 100644 index df5fcbb1..00000000 --- a/src/test/java/com/aparapi/runtime/BufferTransferTest.java +++ /dev/null @@ -1,263 +0,0 @@ -/** - * Copyright (c) 2016 - 2018 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; -import static org.junit.Assume.assumeTrue; - -public class BufferTransferTest { - - static OpenCLDevice openCLDevice = null; - - @BeforeClass - public static void setUpBeforeClass() throws Exception { - - Device device = KernelManager.instance().bestDevice(); - assumeTrue (device != null && device instanceof OpenCLDevice); - openCLDevice = (OpenCLDevice) device; - } - - @Test - public void testInOutOnce() { - - 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 testAuto() { - - 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 testExplicit() { - - 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 testExplicitSimple() { - - TestKernel kernel = new TestKernel(); - kernel.setExplicit(true); - kernel.step(); - - } - - @Test - public void testAutoSimple() { - 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]; - } - - 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/CallStaticFromAnonymousKernelTest.java b/src/test/java/com/aparapi/runtime/CallStaticFromAnonymousKernelTest.java deleted file mode 100644 index 25328dd4..00000000 --- a/src/test/java/com/aparapi/runtime/CallStaticFromAnonymousKernelTest.java +++ /dev/null @@ -1,74 +0,0 @@ -/** - * Copyright (c) 2016 - 2018 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; - -public class CallStaticFromAnonymousKernelTest { - - 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[]) { - CallStaticFromAnonymousKernelTest k = new CallStaticFromAnonymousKernelTest(); - 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] = CallStaticFromAnonymousKernelTest.fooBar(values[gid]) + doodoo(gid); - } - }; - kernel.execute(size); - - for (int i = 0; i < size; i++) { - assertTrue("results == fooBar", results[i] == (fooBar(values[i]) + AnotherClass.foo(i))); - } - } - - static class AnotherClass { - static public int foo(int i) { - return i + 42; - } - } -} diff --git a/src/test/java/com/aparapi/runtime/ExplicitBoolean.java b/src/test/java/com/aparapi/runtime/ExplicitBoolean.java deleted file mode 100644 index 28efd83f..00000000 --- a/src/test/java/com/aparapi/runtime/ExplicitBoolean.java +++ /dev/null @@ -1,88 +0,0 @@ -/** - * Copyright (c) 2016 - 2018 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/JtpRangeIdsTest.java b/src/test/java/com/aparapi/runtime/JtpRangeIdsTest.java deleted file mode 100644 index dbad276a..00000000 --- a/src/test/java/com/aparapi/runtime/JtpRangeIdsTest.java +++ /dev/null @@ -1,530 +0,0 @@ -/** - * Copyright (c) 2016 - 2018 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.Assert; -import org.junit.Ignore; -import org.junit.Test; - -public class JtpRangeIdsTest { - // 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 - 0,//threadId - 4,//globalX - 0,//globalY - 0,//localX - 0 - //localY - }, - { - 5,//globalThreadId - 1,//threadId - 5,//globalX - 0,//globalY - 1,//localX - 0 - //localY - }, - { - 6,//globalThreadId - 2,//threadId - 6,//globalX - 0,//globalY - 2,//localX - 0 - //localY - }, - { - 7,//globalThreadId - 3,//threadId - 7,//globalX - 0,//globalY - 3,//localX - 0 - //localY - }, - { - 8,//globalThreadId - 0,//threadId - 8,//globalX - 0,//globalY - 0,//localX - 0 - //localY - }, - { - 9,//globalThreadId - 1,//threadId - 9,//globalX - 0,//globalY - 1,//localX - 0 - //localY - }, - { - 10,//globalThreadId - 2,//threadId - 10,//globalX - 0,//globalY - 2,//localX - 0 - //localY - }, - { - 11,//globalThreadId - 3,//threadId - 11,//globalX - 0,//globalY - 3,//localX - 0 - //localY - }, - { - 12,//globalThreadId - 4,//threadId - 0,//globalX - 1,//globalY - 0,//localX - 1 - //localY - }, - { - 13,//globalThreadId - 5,//threadId - 1,//globalX - 1,//globalY - 1,//localX - 1 - //localY - }, - { - 14,//globalThreadId - 6,//threadId - 2,//globalX - 1,//globalY - 2,//localX - 1 - //localY - }, - { - 15,//globalThreadId - 7,//threadId - 3,//globalX - 1,//globalY - 3,//localX - 1 - //localY - }, - { - 16,//globalThreadId - 4,//threadId - 4,//globalX - 1,//globalY - 0,//localX - 1 - //localY - }, - { - 17,//globalThreadId - 5,//threadId - 5,//globalX - 1,//globalY - 1,//localX - 1 - //localY - }, - { - 18,//globalThreadId - 6,//threadId - 6,//globalX - 1,//globalY - 2,//localX - 1 - //localY - }, - { - 19,//globalThreadId - 7,//threadId - 7,//globalX - 1,//globalY - 3,//localX - 1 - //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 - 0,//threadId - 4,//globalX - 2,//globalY - 0,//localX - 0 - //localY - }, - { - 29,//globalThreadId - 1,//threadId - 5,//globalX - 2,//globalY - 1,//localX - 0 - //localY - }, - { - 30,//globalThreadId - 2,//threadId - 6,//globalX - 2,//globalY - 2,//localX - 0 - //localY - }, - { - 31,//globalThreadId - 3,//threadId - 7,//globalX - 2,//globalY - 3,//localX - 0 - //localY - }, - { - 32,//globalThreadId - 0,//threadId - 8,//globalX - 2,//globalY - 0,//localX - 0 - //localY - }, - { - 33,//globalThreadId - 1,//threadId - 9,//globalX - 2,//globalY - 1,//localX - 0 - //localY - }, - { - 34,//globalThreadId - 2,//threadId - 10,//globalX - 2,//globalY - 2,//localX - 0 - //localY - }, - { - 35,//globalThreadId - 3,//threadId - 11,//globalX - 2,//globalY - 3,//localX - 0 - //localY - }, - { - 36,//globalThreadId - 4,//threadId - 0,//globalX - 3,//globalY - 0,//localX - 1 - //localY - }, - { - 37,//globalThreadId - 5,//threadId - 1,//globalX - 3,//globalY - 1,//localX - 1 - //localY - }, - { - 38,//globalThreadId - 6,//threadId - 2,//globalX - 3,//globalY - 2,//localX - 1 - //localY - }, - { - 39,//globalThreadId - 7,//threadId - 3,//globalX - 3,//globalY - 3,//localX - 1 - //localY - }, - { - 40,//globalThreadId - 4,//threadId - 4,//globalX - 3,//globalY - 0,//localX - 1 - //localY - }, - { - 41,//globalThreadId - 5,//threadId - 5,//globalX - 3,//globalY - 1,//localX - 1 - //localY - }, - { - 42,//globalThreadId - 6,//threadId - 6,//globalX - 3,//globalY - 2,//localX - 1 - //localY - }, - { - 43,//globalThreadId - 7,//threadId - 7,//globalX - 3,//globalY - 3,//localX - 1 - //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 - }, - }; - - @Test - public void test() { - MatrixKernel kernel = new MatrixKernel(); - kernel.execute(Range.create2D(12, 4, 4, 2)); - for(boolean hasPassed : kernel.passed) { - Assert.assertTrue("Resulting matrix was invalid", hasPassed); - } - - } - - private class MatrixKernel extends Kernel { - public boolean passed[] = new boolean[test.length]; - - @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) { - passed[globalThreadId] = false; - 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); - System.out.println(); - } - else - passed[globalThreadId] = true; - } - } - - } -} diff --git a/src/test/java/com/aparapi/runtime/KernelManagerPreferredDeviceTest.java b/src/test/java/com/aparapi/runtime/KernelManagerPreferredDeviceTest.java deleted file mode 100644 index 490738cb..00000000 --- a/src/test/java/com/aparapi/runtime/KernelManagerPreferredDeviceTest.java +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Copyright (c) 2016 - 2018 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 static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.Test; - -import com.aparapi.Kernel; -import com.aparapi.device.Device; -import com.aparapi.internal.kernel.KernelManager; -import com.aparapi.internal.kernel.KernelManagers; - -public class KernelManagerPreferredDeviceTest { - private Kernel testKernel; - - @Before - public void setUp() { - testKernel = new Kernel() { - - /** - * This kernel does nothing. - */ - @Override - public void run() { - // this block was intentionally left empty, as the kernel should do nothing - } - }; - } - - @After - public void tearDown() { - testKernel.dispose(); - } - - @AfterClass - public static void tearDownClass() { - // reset the KernelManager after we are done, as some tests expect a openCL device - KernelManager.setKernelManager(new KernelManager() {}); - } - - @Test - public void testUseJtpOnly() { - KernelManager.setKernelManager(KernelManagers.JTP_ONLY); - - Device device = KernelManager.instance().getDefaultPreferences().getPreferredDevice(testKernel); - - assertThat(device.getType(), is(Device.TYPE.JTP)); - } - - @Test - public void testUseSequentialOnly() { - KernelManager.setKernelManager(KernelManagers.SEQUENTIAL_ONLY); - - Device device = KernelManager.instance().getDefaultPreferences().getPreferredDevice(testKernel); - - assertThat(device.getType(), is(Device.TYPE.SEQ)); - } -} diff --git a/src/test/java/com/aparapi/runtime/LoadClTest.java b/src/test/java/com/aparapi/runtime/LoadClTest.java deleted file mode 100644 index 0f6c126f..00000000 --- a/src/test/java/com/aparapi/runtime/LoadClTest.java +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Copyright (c) 2016 - 2018 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.Ignore; -import org.junit.Test; - -import static org.junit.Assert.assertTrue; - -public class LoadClTest { - - @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("squarer.cl") - interface Squarer extends OpenCL { - public Squarer square( - Range _range, - @GlobalReadWrite("in") float[] in,// - @GlobalReadWrite("out") float[] out); - } -} - diff --git a/src/test/java/com/aparapi/runtime/LocalArrayArgsTest.java b/src/test/java/com/aparapi/runtime/LocalArrayArgsTest.java deleted file mode 100644 index 2ea3ba7b..00000000 --- a/src/test/java/com/aparapi/runtime/LocalArrayArgsTest.java +++ /dev/null @@ -1,140 +0,0 @@ -/** - * Copyright (c) 2016 - 2018 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 static org.junit.Assert.*; -import static org.junit.Assume.*; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -public class LocalArrayArgsTest { - private static OpenCLDevice openCLDevice = null; - private static final int SIZE = 32; - private int[] targetArray; - - @Before - public void setUpBeforeClass() throws Exception { - Device device = KernelManager.instance().bestDevice(); - assumeTrue (device != null && device instanceof OpenCLDevice); - openCLDevice = (OpenCLDevice) device; - } - - @After - public void classTeardown() { - Util.resetKernelManager(); - } - - - @Test - public void test() { - final LocalArrayArgsKernel kernel = new LocalArrayArgsKernel(); - try { - final Range range = openCLDevice.createRange(SIZE, SIZE); - targetArray = new int[SIZE]; - kernel.setExplicit(false); - kernel.setArray(targetArray); - kernel.execute(range); - assertTrue(validate()); - } finally { - kernel.dispose(); - } - } - - @Test - public void testExplicit() { - final LocalArrayArgsKernel kernel = new LocalArrayArgsKernel(); - try { - final Range range = openCLDevice.createRange(SIZE, SIZE); - targetArray = new int[SIZE]; - kernel.setExplicit(true); - kernel.setArray(targetArray); - kernel.put(targetArray); - kernel.execute(range); - kernel.get(targetArray); - assertTrue(validate()); - } finally { - kernel.dispose(); - } - } - - private boolean validate() { - int[] expected = new int[SIZE]; - for (int threadId = 0; threadId < SIZE; threadId++) { - for (int i = 0; i < SIZE; i++) { - expected[threadId] += i + threadId; - } - expected[threadId] *= threadId; - } - - assertArrayEquals("targetArray", expected, targetArray); - - return true; - } - - public static class LocalArrayArgsKernel extends Kernel { - private int[] resultArray; - - @Local - private int[] myArray = new int[SIZE]; - - @PrivateMemorySpace(SIZE) - private int[] other_$private$ = new int[SIZE]; - - @NoCL - public void setArray(int[] target) { - resultArray = target; - } - - private void doInitialCopy(@Local int[] target, int[] source, int id) { - target[id] = source[id]; - } - - private void doComputation1(@Local int[] arr, int id) { - for (int i = 0; i < SIZE; i++) { - arr[id] += i + id; - } - } - - private void doComputation2(int[] arr_$local$, int id) { - arr_$local$[id] *= id; - } - - private void doComputation3(int[] arr_$local$, int[] arr_$private$, int id) { - arr_$private$[id] = arr_$local$[id]; - } - - @Override - public void run() { - int id = getLocalId(); - - - doInitialCopy(myArray, resultArray, id); - doComputation1(myArray, id); - doComputation2(myArray, id); - doComputation3(myArray, other_$private$, id); - - resultArray[id] = myArray[id]; - } - } -} diff --git a/src/test/java/com/aparapi/runtime/MultiDimensionalLocalArrayTest.java b/src/test/java/com/aparapi/runtime/MultiDimensionalLocalArrayTest.java deleted file mode 100644 index 4a88236c..00000000 --- a/src/test/java/com/aparapi/runtime/MultiDimensionalLocalArrayTest.java +++ /dev/null @@ -1,354 +0,0 @@ -/** - * Copyright (c) 2016 - 2018 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 static org.junit.Assert.*; -import static org.junit.Assume.assumeTrue; - -import java.util.Arrays; -import java.util.LinkedHashSet; -import java.util.List; - -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; - -import com.aparapi.Kernel; -import com.aparapi.Range; -import com.aparapi.device.Device; -import com.aparapi.device.JavaDevice; -import com.aparapi.device.OpenCLDevice; -import com.aparapi.internal.kernel.KernelManager; - -/** - * This class provides tests for Issue #51 - */ -public class MultiDimensionalLocalArrayTest -{ - - private static OpenCLDevice openCLDevice = null; - - private class CLKernelManager extends KernelManager { - @Override - protected List getPreferredDeviceTypes() { - return Arrays.asList(Device.TYPE.ACC, Device.TYPE.GPU, Device.TYPE.CPU); - } - } - - private class JTPKernelManager extends KernelManager { - private JTPKernelManager() { - LinkedHashSet preferredDevices = new LinkedHashSet(1); - preferredDevices.add(JavaDevice.THREAD_POOL); - setDefaultPreferredDevices(preferredDevices); - } - @Override - protected List getPreferredDeviceTypes() { - return Arrays.asList(Device.TYPE.JTP); - } - } - - @After - public void classTeardown() { - Util.resetKernelManager(); - } - - @Before - public void setUpBeforeClass() throws Exception { - KernelManager.setKernelManager(new CLKernelManager()); - Device device = KernelManager.instance().bestDevice(); - if (device == null || !(device instanceof OpenCLDevice)) { - System.out.println("!!!No OpenCLDevice available for running the integration test"); - } - assumeTrue (device != null && device instanceof OpenCLDevice); - openCLDevice = (OpenCLDevice) device; - } - - private Device getDevice() { - boolean openCL = true; - if (openCL) { - return openCLDevice; - } else { - KernelManager.setKernelManager(new JTPKernelManager()); - return KernelManager.instance().bestDevice(); - } - } - - @Test - public void singleDimensionTest() - { - final Device device = getDevice(); - final int SIZE = 16; - final float[] RESULT = new float[2]; - Kernel kernel = new Kernel() - { - @Local final float[] localArray = new float[SIZE*SIZE]; - - @Override - public void run() - { - int row = getGlobalId(0); - int column = getGlobalId(1); - localArray[row + column*SIZE] = row + column; - localBarrier(); - float value = 0; - for (int x = 0; x < SIZE; x++) - { - for (int y = 0; y < SIZE; y++) - { - value += localArray[x + y*SIZE]; - } - } - RESULT[0] = value; - } - }; - try { - kernel.execute(Range.create2D(device, SIZE, SIZE, SIZE, SIZE)); - } finally { - kernel.dispose(); - } - assertEquals(3840, RESULT[0], 1E-6F); - } - - @Test - public void singleDimensionMultipleExecutionTest() - { - final Device device = getDevice(); - final int SIZE = 16; - final float[] RESULT = new float[2]; - Kernel kernel = new Kernel() - { - @Local final float[] localArray = new float[SIZE*SIZE]; - - @Override - public void run() - { - int row = getGlobalId(0); - int column = getGlobalId(1); - localArray[row + column*SIZE] = row + column; - localBarrier(); - float value = 0; - for (int x = 0; x < SIZE; x++) - { - for (int y = 0; y < SIZE; y++) - { - value += localArray[x + y*SIZE]; - } - } - RESULT[0] = value; - } - }; - try { - kernel.execute(Range.create2D(device, SIZE, SIZE, SIZE, SIZE)); - assertEquals(3840, RESULT[0], 1E-6F); - kernel.execute(Range.create2D(device, SIZE, SIZE, SIZE, SIZE)); - assertEquals(3840, RESULT[0], 1E-6F); - } finally { - kernel.dispose(); - } - } - - @Test - public void twoDimensionTest() - { - final Device device = getDevice(); - final int SIZE = 16; - final float[][] RESULT = new float[2][2]; - Kernel kernel = new Kernel() - { - @Local final float[][] localArray = new float[SIZE][SIZE]; - - @Override - public void run() - { - int row = getGlobalId(0); - int column = getGlobalId(1); - localArray[row][column] = row + column; - localBarrier(); - float value = 0; - for (int x = 0; x < SIZE; x++) - { - for (int y = 0; y < SIZE; y++) - { - value += localArray[x][y]; - } - } - RESULT[0][0] = value; - } - }; - try { - kernel.execute(Range.create2D(device, SIZE, SIZE, SIZE, SIZE)); - } finally { - kernel.dispose(); - } - assertEquals(3840, RESULT[0][0], 1E-6F); - } - - @Test - public void twoDimensionMultipleExecutionTest() - { - final Device device = getDevice(); - final int SIZE = 16; - final float[][] RESULT = new float[2][2]; - Kernel kernel = new Kernel() - { - @Local final float[][] localArray = new float[SIZE][SIZE]; - - @Override - public void run() - { - int row = getGlobalId(0); - int column = getGlobalId(1); - localArray[row][column] = row + (float)column; - localBarrier(); - float value = 0; - for (int x = 0; x < SIZE; x++) - { - for (int y = 0; y < SIZE; y++) - { - value += localArray[x][y]; - } - } - RESULT[0][0] = value; - } - }; - - try { - kernel.execute(Range.create2D(device, SIZE, SIZE, SIZE, SIZE)); - assertEquals(3840, RESULT[0][0], 1E-6F); - kernel.execute(Range.create2D(device, SIZE, SIZE, SIZE, SIZE)); - assertEquals(3840, RESULT[0][0], 1E-6F); - } finally { - kernel.dispose(); - } - } - - private class Resizable1DKernel extends Kernel { - private int size; - private float[] result; - - @Local - private float[] localArray; - - @NoCL - public void setResult(float[] result) { - this.result = result; - } - - @NoCL - public void setArray(int size, float[] array) { - this.size = size; - localArray = array; - } - - @Override - public void run() - { - int row = getGlobalId(0); - int column = getGlobalId(1); - localArray[row + column*size] = row + column; - localBarrier(); - float value = 0; - for (int x = 0; x < size; x++) - { - for (int y = 0; y < size; y++) - { - value += localArray[x + y*size]; - } - } - result[0] = value; - } - } - - private class Resizable2DKernel extends Kernel { - private int size; - private float[] result; - - @Local - private float[][] localArray; - - @NoCL - public void setResult(float[] result) { - this.result = result; - } - - @NoCL - public void setArray(int size, float[][] array) { - this.size = size; - localArray = array; - } - - @Override - public void run() - { - int row = getGlobalId(0); - int column = getGlobalId(1); - localArray[row][column] = row + (float)column; - localBarrier(); - float value = 0; - for (int x = 0; x < size; x++) - { - for (int y = 0; y < size; y++) - { - value += localArray[x][y]; - } - } - result[0] = value; - } - } - - @Test - public void resizableOneDimensionTest() - { - final Device device = getDevice(); - final int SIZE = 8; - final float[] RESULT = new float[2]; - - Resizable1DKernel kernel = new Resizable1DKernel(); - try { - kernel.setResult(RESULT); - kernel.setArray(SIZE, new float[SIZE*SIZE]); - kernel.execute(Range.create2D(device, SIZE, SIZE, SIZE, SIZE)); - assertEquals(448, RESULT[0], 1E-6F); - kernel.setArray(2*SIZE, new float[2*SIZE*2*SIZE]); - kernel.execute(Range.create2D(device, 2*SIZE, 2*SIZE, 2*SIZE, 2*SIZE)); - assertTrue("Result is not greater than 448", RESULT[0]>448); - } finally { - kernel.dispose(); - } - - } - - @Test - public void resizableTwoDimensionTest() - { - final Device device = getDevice(); - final int SIZE = 8; - final float[] RESULT = new float[2]; - Resizable2DKernel kernel = new Resizable2DKernel(); - try { - kernel.setResult(RESULT); - kernel.setArray(SIZE, new float[SIZE][SIZE]); - kernel.execute(Range.create2D(device, SIZE, SIZE, SIZE, SIZE)); - assertEquals(448, RESULT[0], 1E-6F); - kernel.setArray(2*SIZE, new float[2*SIZE][2*SIZE]); - kernel.execute(Range.create2D(device, 2*SIZE, 2*SIZE, 2*SIZE, 2*SIZE)); - assertTrue("Result is not greater than 448", RESULT[0]>448); - } finally { - kernel.dispose(); - } - } -} \ No newline at end of file diff --git a/src/test/java/com/aparapi/runtime/MultiplePassesMemoryConsumptionTest.java b/src/test/java/com/aparapi/runtime/MultiplePassesMemoryConsumptionTest.java deleted file mode 100644 index 0cffdad1..00000000 --- a/src/test/java/com/aparapi/runtime/MultiplePassesMemoryConsumptionTest.java +++ /dev/null @@ -1,61 +0,0 @@ -/** - * Copyright (c) 2016 - 2018 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 org.junit.Assert; -import org.junit.Test; - -public class MultiplePassesMemoryConsumptionTest { - - @Test - public void test() { - final int globalArray[] = new int[512]; - Kernel kernel = new Kernel() { - @Override - public void run() { - globalArray[getGlobalId()] = getGlobalId(); - } - }; - System.gc(); - long baseFree = Runtime.getRuntime().freeMemory(); - for (int loop = 0; loop < 100; loop++) { - System.gc(); - if( baseFree > Runtime.getRuntime().freeMemory()) - baseFree = Runtime.getRuntime().freeMemory(); - kernel.execute(Range.create(512, 64), 1); - for (int i = 0; i < globalArray.length; ++i) { - Assert.assertEquals("Wrong", i, globalArray[i]); - } - } - - System.gc(); - long testFree = Runtime.getRuntime().freeMemory(); - for (int loop = 0; loop < 100; loop++) { - System.gc(); - if( testFree > Runtime.getRuntime().freeMemory()) - testFree = Runtime.getRuntime().freeMemory(); - kernel.execute(Range.create(512, 64), 2); - for (int i = 0; i < globalArray.length; ++i) { - Assert.assertEquals("Wrong", i, globalArray[i]); - } - } - long extraMemory = baseFree - testFree; - Assert.assertTrue("Too much memory consumed: " + extraMemory, extraMemory < 4000000); - } - -} diff --git a/src/test/java/com/aparapi/runtime/NegativeIntegerTest.java b/src/test/java/com/aparapi/runtime/NegativeIntegerTest.java deleted file mode 100644 index 8cd9a540..00000000 --- a/src/test/java/com/aparapi/runtime/NegativeIntegerTest.java +++ /dev/null @@ -1,84 +0,0 @@ -/** - * Copyright (c) 2016 - 2018 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 static org.junit.Assert.assertEquals; -import static org.junit.Assume.assumeTrue; - -import java.util.Arrays; -import java.util.List; - -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; - -import com.aparapi.Kernel; -import com.aparapi.Range; -import com.aparapi.device.Device; -import com.aparapi.device.OpenCLDevice; -import com.aparapi.internal.kernel.KernelManager; - -/** - * Originally created for testing issue #78 - * - */ -public class NegativeIntegerTest -{ - - private static OpenCLDevice openCLDevice = null; - - private class CLKernelManager extends KernelManager { - @Override - protected List getPreferredDeviceTypes() { - return Arrays.asList(Device.TYPE.ACC, Device.TYPE.GPU, Device.TYPE.CPU); - } - } - - @Before - public void setUpBeforeClass() throws Exception { - KernelManager.setKernelManager(new CLKernelManager()); - Device device = KernelManager.instance().bestDevice(); - if (device == null || !(device instanceof OpenCLDevice)) { - System.out.println("!!!No OpenCLDevice available for running the integration test"); - } - assumeTrue (device != null && device instanceof OpenCLDevice); - openCLDevice = (OpenCLDevice) device; - } - - @After - public void classTeardown() { - Util.resetKernelManager(); - } - - @Test - public void negativeIntegerTestPass() - { - final Device device = openCLDevice; - final int SIZE = 1; - final int[] RESULT = new int[2]; - Kernel kernel = new Kernel() - { - @Override - public void run() - { - RESULT[0] = -800; - } - }; - kernel.execute(Range.create(device, SIZE, SIZE)); - assertEquals("Result doesn't match", -800, RESULT[0]); - } -} diff --git a/src/test/java/com/aparapi/runtime/NullRefTest.java b/src/test/java/com/aparapi/runtime/NullRefTest.java deleted file mode 100644 index 8d312509..00000000 --- a/src/test/java/com/aparapi/runtime/NullRefTest.java +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Copyright (c) 2016 - 2018 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.Ignore; -import org.junit.Test; - -public class NullRefTest { - @Ignore("Known bug, runs on CPU but not GPU.") - @Test - public void test() { - new NullRefTest().doTest(); - } - - private void doTest() { - final Kernel kernel = new NullRefKernel(); - kernel.execute(1); - } - - private class NullRefKernel extends Kernel { - private final int[] nullArray = null; - - @Override - public void run() { - if(nullArray == null) { - noop(); - } - } - - private void noop() { - //no op - } - } -} diff --git a/src/test/java/com/aparapi/runtime/OpenCLDeviceConfiguratorTest.java b/src/test/java/com/aparapi/runtime/OpenCLDeviceConfiguratorTest.java deleted file mode 100644 index a474894a..00000000 --- a/src/test/java/com/aparapi/runtime/OpenCLDeviceConfiguratorTest.java +++ /dev/null @@ -1,240 +0,0 @@ -/** - * Copyright (c) 2016 - 2018 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 static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeTrue; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; - -import org.junit.After; -import org.junit.Test; - -import com.aparapi.device.Device; -import com.aparapi.device.IOpenCLDeviceConfigurator; -import com.aparapi.device.JavaDevice; -import com.aparapi.device.OpenCLDevice; -import com.aparapi.internal.kernel.KernelManager; -import com.aparapi.internal.kernel.KernelPreferences; -import com.aparapi.internal.opencl.OpenCLPlatform; - -/** - * Tests for feature OpenCLDeviceConfigurator set 1/2 - * - * @author CoreRasurae - */ -public class OpenCLDeviceConfiguratorTest { - private static OpenCLDevice openCLDevice = null; - private final AtomicInteger callCounter = new AtomicInteger(0); - - public static List listDevices(OpenCLDevice.TYPE type) { - final ArrayList results = new ArrayList<>(); - - for (final OpenCLPlatform p : OpenCLPlatform.getUncachedOpenCLPlatforms()) { - for (final OpenCLDevice device : p.getOpenCLDevices()) { - if (type == null || device.getType() == type) { - results.add(device); - } - } - } - - return results; - } - - private class UncachedCLKernelManager extends KernelManager { - private KernelPreferences defaultPreferences; - - @Override - protected void setup() { - callCounter.set(0); - defaultPreferences = createDefaultPreferences(); - } - - @Override - public KernelPreferences getDefaultPreferences() { - return defaultPreferences; - } - - private List filter(OpenCLDevice.TYPE type, List devices) { - final ArrayList results = new ArrayList<>(); - - for (final OpenCLDevice device : devices) { - if (type == null || device.getType() == type) { - results.add(device); - } - } - - return results; - } - - @Override - protected LinkedHashSet createDefaultPreferredDevices() { - LinkedHashSet devices = new LinkedHashSet<>(); - - List all = listDevices(null); - - List accelerators = filter(Device.TYPE.ACC, all); - List gpus = filter(Device.TYPE.GPU, all); - List cpus = filter(Device.TYPE.CPU, all); - - Collections.sort(accelerators, getDefaultAcceleratorComparator()); - Collections.sort(gpus, getDefaultGPUComparator()); - - List preferredDeviceTypes = getPreferredDeviceTypes(); - - for (Device.TYPE type : preferredDeviceTypes) { - switch (type) { - case UNKNOWN: - throw new AssertionError("UNKNOWN device type not supported"); - case GPU: - devices.addAll(gpus); - break; - case CPU: - devices.addAll(cpus); - break; - case JTP: - devices.add(JavaDevice.THREAD_POOL); - break; - case SEQ: - devices.add(JavaDevice.SEQUENTIAL); - break; - case ACC: - devices.addAll(accelerators); - break; - case ALT: - devices.add(JavaDevice.ALTERNATIVE_ALGORITHM); - break; - default: - } - } - - return devices; - } - - @Override - protected List getPreferredDeviceTypes() { - return Arrays.asList(Device.TYPE.ACC, Device.TYPE.GPU, Device.TYPE.CPU); - } - } - - public void setUp() throws Exception { - KernelManager.setKernelManager(new UncachedCLKernelManager()); - Device device = KernelManager.instance().bestDevice(); - if (device == null || !(device instanceof OpenCLDevice)) { - System.out.println("!!!No OpenCLDevice available for running the integration test"); - } - assumeTrue (device != null && device instanceof OpenCLDevice); - openCLDevice = (OpenCLDevice) device; - } - - @After - public void teardDown() { - Util.resetKernelManager(); - } - - - public void setUpWithConfigurator(IOpenCLDeviceConfigurator configurator) throws Exception { - OpenCLDevice.setConfigurator(configurator); - setUp(); - } - - @Test - public void configuratorCallbackTest() throws Exception { - IOpenCLDeviceConfigurator configurator = new IOpenCLDeviceConfigurator() { - @Override - public void configure(OpenCLDevice device) { - callCounter.incrementAndGet(); - device.setName("Configured"); - device.setSharedMemory(false); - } - }; - setUpWithConfigurator(configurator); - assertTrue("Number of configured devices should be > 0", callCounter.get() > 0); - int numberOfConfiguredDevices = callCounter.get(); - - assertFalse("Device isShareMempory() should return false", openCLDevice.isSharedMemory()); - assertEquals("Device name should be \"Configured\"", "Configured", openCLDevice.getName()); - - int numberOfDevices = 0; - List platforms = OpenCLPlatform.getUncachedOpenCLPlatforms(); - for (OpenCLPlatform platform : platforms) { - for (OpenCLDevice device : platform.getOpenCLDevices()) { - assertFalse("Device isShareMempory() should return false", device.isSharedMemory()); - assertEquals("Device name should be \"Configured\"", "Configured", device.getName()); - numberOfDevices++; - } - } - - assertEquals("Number of configured devices should match numnber of devices", numberOfDevices, numberOfConfiguredDevices); - assertEquals("Number of calls doesn't match the expected", numberOfDevices*2, callCounter.get()); - } - - @Test - public void noConfiguratorTest() throws Exception { - setUp(); - assertTrue("Device isShareMempory() should return true", openCLDevice.isSharedMemory()); - assertNotEquals("Device name should not be \"Configured\"", "Configured", openCLDevice.getName()); - List platforms = OpenCLPlatform.getUncachedOpenCLPlatforms(); - for (OpenCLPlatform platform : platforms) { - for (OpenCLDevice device : platform.getOpenCLDevices()) { - assertTrue("Device isSharedMempory() should return true", device.isSharedMemory()); - assertNotEquals("Device name should not be \"Configured\"", "Configured", device.getName()); - } - } - } - - @Test - public void protectionAgainstRecursiveConfiguresTest() { - OpenCLDevice dev = new OpenCLDevice(null, 101L, Device.TYPE.CPU); - final AtomicInteger callCounter = new AtomicInteger(0); - IOpenCLDeviceConfigurator configurator = new IOpenCLDeviceConfigurator() { - @Override - public void configure(OpenCLDevice device) { - callCounter.incrementAndGet(); - device.configure(); - } - }; - OpenCLDevice.setConfigurator(configurator); - dev.configure(); - - assertEquals("Number of confgure() calls should be one", 1, callCounter.get()); - } - - @Test(expected=IllegalArgumentException.class) - public void exceptionConfiguratorTestFail() { - final AtomicBoolean called = new AtomicBoolean(false); - OpenCLDevice dev = new OpenCLDevice(null, 101L, Device.TYPE.CPU); - IOpenCLDeviceConfigurator configurator = new IOpenCLDeviceConfigurator() { - @Override - public void configure(OpenCLDevice device) { - called.set(true); - throw new IllegalArgumentException("This exception is part of the test, shouldn't cause test to fail"); - } - }; - OpenCLDevice.setConfigurator(configurator); - dev.configure(); - assertTrue("Configurator should have benn called", called.get()); - } - } diff --git a/src/test/java/com/aparapi/runtime/OriginalKernelManager.java b/src/test/java/com/aparapi/runtime/OriginalKernelManager.java deleted file mode 100644 index 423c8034..00000000 --- a/src/test/java/com/aparapi/runtime/OriginalKernelManager.java +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright (c) 2016 - 2018 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.internal.kernel.KernelManager; - -/** - * Provides a way for re-establishing the default Aparapi KernelManager - * @author CoreRasurae - */ -public class OriginalKernelManager extends KernelManager { -} diff --git a/src/test/java/com/aparapi/runtime/ProfileReportBackwardsCompatTest.java b/src/test/java/com/aparapi/runtime/ProfileReportBackwardsCompatTest.java deleted file mode 100644 index 180fdc45..00000000 --- a/src/test/java/com/aparapi/runtime/ProfileReportBackwardsCompatTest.java +++ /dev/null @@ -1,321 +0,0 @@ -/** - * Copyright (c) 2016 - 2018 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 static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeTrue; - -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import java.util.logging.Level; -import java.util.logging.Logger; - -import org.junit.After; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestName; - -import com.aparapi.Config; -import com.aparapi.Kernel; -import com.aparapi.ProfileReport; -import com.aparapi.Range; -import com.aparapi.device.Device; -import com.aparapi.device.JavaDevice; -import com.aparapi.device.OpenCLDevice; -import com.aparapi.internal.kernel.KernelManager; - -/** - * Provides integration tests to help assure backwards compatibility under single thread per kernel per device - * execution environments. - * - * @author CoreRasurae - * - */ -public class ProfileReportBackwardsCompatTest { - private static OpenCLDevice openCLDevice; - - private static Logger logger = Logger.getLogger(Config.getLoggerName()); - - @Rule - public TestName name = new TestName(); - - private class CLKernelManager extends KernelManager { - @Override - protected List getPreferredDeviceTypes() { - return Arrays.asList(Device.TYPE.ACC, Device.TYPE.GPU, Device.TYPE.CPU); - } - } - - private class JTPKernelManager extends KernelManager { - private JTPKernelManager() { - LinkedHashSet preferredDevices = new LinkedHashSet(1); - preferredDevices.add(JavaDevice.THREAD_POOL); - setDefaultPreferredDevices(preferredDevices); - } - @Override - protected List getPreferredDeviceTypes() { - return Arrays.asList(Device.TYPE.JTP); - } - } - - @After - public void classTeardown() { - Util.resetKernelManager(); - } - - public void setUpBefore() throws Exception { - KernelManager.setKernelManager(new CLKernelManager()); - Device device = KernelManager.instance().bestDevice(); - if (device == null || !(device instanceof OpenCLDevice)) { - logger.log(Level.WARNING, "!!!No OpenCLDevice available for running the integration test - test will be skipped"); - } - assumeTrue (device != null && device instanceof OpenCLDevice); - openCLDevice = (OpenCLDevice) device; - } - - - /** - * This integration test validates that previous Kernel methods for retrieving profiling data - * are still consistent in the new implementation and with the new profile reports. - * @throws Exception - */ - @Test - public void sequentialSingleThreadOpenCLTest() throws Exception { - setUpBefore(); - logger.log(Level.INFO, "Test " + name.getMethodName() + " - Executing on device: " + openCLDevice.getShortDescription() + " - " + openCLDevice.getName()); - assertTrue(sequentialSingleThreadTestHelper(openCLDevice, 128)); - } - - /** - * This integration test validates that previous Kernel methods for retrieving profiling data - * are still consistent in the new implementation and with the new profile reports. - */ - @Test - public void sequentialSingleThreadJTPTest() { - KernelManager.setKernelManager(new JTPKernelManager()); - Device device = KernelManager.instance().bestDevice(); - assertTrue(sequentialSingleThreadTestHelper(device, 16)); - } - - - public boolean sequentialSingleThreadTestHelper(Device device, int size) { - final int runs = 100; - final int inputArray[] = new int[size]; - double accumulatedExecutionTime = 0.0; - double lastExecutionTime = 0.0; - double lastConversionTime = 0.0; - final Basic1Kernel kernel = new Basic1Kernel(); - - int[] outputArray = null; - Range range = device.createRange(size, size); - long startOfExecution = System.currentTimeMillis(); - try { - for (int i = 0; i < runs; i++) { - outputArray = Arrays.copyOf(inputArray, inputArray.length); - kernel.setInputOuputArray(outputArray); - kernel.execute(range); - lastExecutionTime = kernel.getExecutionTime(); - accumulatedExecutionTime += lastExecutionTime; - lastConversionTime = kernel.getConversionTime(); - } - long runTime = System.currentTimeMillis() - startOfExecution; - WeakReference reportRef = kernel.getProfileReportLastThread(device); - ProfileReport report = reportRef.get(); - assertEquals("Number of profiling reports doesn't match the expected", runs, report.getReportId()); - assertEquals("Aparapi Accumulated execution time doesn't match", accumulatedExecutionTime, kernel.getAccumulatedExecutionTime(), 1e-10); - assertEquals("Aparapi last execution time doesn't match last report", lastExecutionTime, report.getExecutionTime(), 1e-10); - assertEquals("Aparapi last conversion time doesn't match last report", lastConversionTime, report.getConversionTime(), 1e-10); - assertEquals("Test estimated accumulated time doesn't match within 500ms window", runTime, accumulatedExecutionTime, 500); - assertTrue(validateBasic1Kernel(inputArray, outputArray)); - } finally { - kernel.registerProfileReportObserver(null); - kernel.dispose(); - } - - return true; - } - - private class TestData { - private int[] outputArray; - private double accumulatedExecutionTime = 0.0; - private double lastExecutionTime = 0.0; - private double lastConversionTime = 0.0; - private long startOfExecution = 0; - private long runTime = 0; - } - - /** - * This test executes two threads one for each kernel on an OpenCL device and checks that the traditional Aparapi profiling interfaces work. - * @throws Exception - */ - @Test - public void threadedSingleThreadPerKernelOpenCLTest() throws Exception { - setUpBefore(); - logger.log(Level.INFO, "Test " + name.getMethodName() + " - Executing on device: " + openCLDevice.getShortDescription() + " - " + openCLDevice.getName()); - assertTrue(threadedSingleThreadPerKernelTestHelper(openCLDevice, 128)); - } - - /** - * This test executes two threads one for each kernel on Java Thread Pool and checks that the traditional Aparapi profiling interfaces work. - */ - @Test - public void threadedSingleThreadPerKernelJTPTest() { - KernelManager.setKernelManager(new JTPKernelManager()); - Device device = KernelManager.instance().bestDevice(); - assertTrue(threadedSingleThreadPerKernelTestHelper(device, 16)); - } - - public boolean threadedSingleThreadPerKernelTestHelper(Device device, final int size) { - final int runs = 100; - final int inputArray[] = new int[size]; - - final Basic1Kernel kernel1 = new Basic1Kernel(); - final Basic1Kernel kernel2 = new Basic2Kernel(); - List kernels = new ArrayList(2); - kernels.add(kernel1); - kernels.add(kernel2); - - final TestData[] results = new TestData[2]; - results[0] = new TestData(); - results[1] = new TestData(); - - boolean terminatedOk = false; - try { - ExecutorService executorService = Executors.newFixedThreadPool(2); - try { - kernels.forEach(k -> executorService.submit(() -> { - results[k.getId() - 1].startOfExecution = System.currentTimeMillis(); - for (int i = 0; i < runs; i++) { - results[k.getId() - 1].outputArray = Arrays.copyOf(inputArray, inputArray.length); - k.setInputOuputArray(results[k.getId() - 1].outputArray); - k.execute(Range.create(device, size, size)); - results[k.getId() - 1].lastExecutionTime = k.getExecutionTime(); - results[k.getId() - 1].accumulatedExecutionTime += results[k.getId() - 1].lastExecutionTime; - results[k.getId() - 1].lastConversionTime = k.getConversionTime(); - } - results[k.getId() - 1].runTime = System.currentTimeMillis() - results[k.getId() - 1].startOfExecution; - })); - } finally { - executorService.shutdown(); - try { - terminatedOk = executorService.awaitTermination(5, TimeUnit.MINUTES); - } catch (InterruptedException ex) { - //For the purposes of the test this suffices - terminatedOk = false; - } - if (!terminatedOk) { - executorService.shutdownNow(); - } - } - - assertTrue(terminatedOk); - - //Validate kernel1 reports - WeakReference reportRef = kernel1.getProfileReportLastThread(device); - ProfileReport report = reportRef.get(); - assertEquals("Number of profiling reports doesn't match the expected", runs, report.getReportId()); - assertEquals("Aparapi Accumulated execution time doesn't match", results[0].accumulatedExecutionTime, kernel1.getAccumulatedExecutionTime(), 1e-10); - assertEquals("Aparapi last execution time doesn't match last report", results[0].lastExecutionTime, report.getExecutionTime(), 1e-10); - assertEquals("Aparapi last conversion time doesn't match last report", results[0].lastConversionTime, report.getConversionTime(), 1e-10); - assertEquals("Test estimated accumulated time doesn't match within 300ms window", results[0].runTime, results[0].accumulatedExecutionTime, 300); - assertTrue(validateBasic1Kernel(inputArray, results[0].outputArray)); - - //Validate kernel2 reports - reportRef = kernel2.getProfileReportLastThread(device); - report = reportRef.get(); - assertEquals("Number of profiling reports doesn't match the expected", runs, report.getReportId()); - assertEquals("Aparapi Accumulated execution time doesn't match", results[1].accumulatedExecutionTime, kernel2.getAccumulatedExecutionTime(), 1e-10); - assertEquals("Aparapi last execution time doesn't match last report", results[1].lastExecutionTime, report.getExecutionTime(), 1e-10); - assertEquals("Aparapi last conversion time doesn't match last report", results[1].lastConversionTime, report.getConversionTime(), 1e-10); - assertEquals("Test estimated accumulated time doesn't match within 300ms window", results[1].runTime, results[1].accumulatedExecutionTime, 300); - assertTrue(validateBasic2Kernel(inputArray, results[1].outputArray)); - } finally { - kernel1.registerProfileReportObserver(null); - kernel2.registerProfileReportObserver(null); - kernel1.dispose(); - kernel2.dispose(); - } - - return true; - } - - private boolean validateBasic1Kernel(final int[] inputArray, final int[] resultArray) { - int[] expecteds = Arrays.copyOf(inputArray, inputArray.length); - for (int threadId = 0; threadId < inputArray.length; threadId++) { - expecteds[threadId] += threadId; - } - - assertArrayEquals(expecteds, resultArray); - - return true; - } - - private boolean validateBasic2Kernel(final int[] inputArray, final int[] resultArray) { - int[] expecteds = Arrays.copyOf(inputArray, inputArray.length); - for (int threadId = 0; threadId < inputArray.length; threadId++) { - expecteds[threadId] += threadId+1; - } - - assertArrayEquals(expecteds, resultArray); - - return true; - } - - private class Basic1Kernel extends Kernel { - protected int[] workArray; - - @NoCL - public void setInputOuputArray(int[] array) { - workArray = array; - } - - @NoCL - public int getId() { - return 1; - } - - @Override - public void run() { - int id = getLocalId(); - - workArray[id]+=id; - } - } - - private class Basic2Kernel extends Basic1Kernel { - @Override - @NoCL - public int getId() { - return 2; - } - - @Override - public void run() { - int id = getLocalId(); - - workArray[id]+=id+1; - } - } - -} diff --git a/src/test/java/com/aparapi/runtime/ProfileReportNewAPITest.java b/src/test/java/com/aparapi/runtime/ProfileReportNewAPITest.java deleted file mode 100644 index 21daa4d3..00000000 --- a/src/test/java/com/aparapi/runtime/ProfileReportNewAPITest.java +++ /dev/null @@ -1,380 +0,0 @@ -/** - * Copyright (c) 2016 - 2018 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 static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeTrue; - -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.concurrent.ConcurrentSkipListMap; -import java.util.concurrent.ConcurrentSkipListSet; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.logging.Level; -import java.util.logging.Logger; - -import org.junit.After; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestName; - -import com.aparapi.Config; -import com.aparapi.IProfileReportObserver; -import com.aparapi.Kernel; -import com.aparapi.ProfileReport; -import com.aparapi.Range; -import com.aparapi.device.Device; -import com.aparapi.device.JavaDevice; -import com.aparapi.device.OpenCLDevice; -import com.aparapi.internal.kernel.KernelManager; - -/** - * Provides integration tests to help in assuring that new APIs for ProfileReports are working, - * in single threaded and multi-threaded environments. - * - * @author CoreRasurae - */ -public class ProfileReportNewAPITest { - - private static OpenCLDevice openCLDevice; - - private static Logger logger = Logger.getLogger(Config.getLoggerName()); - - @Rule - public TestName name = new TestName(); - - - @After - public void classTeardown() { - Util.resetKernelManager(); - } - - - private class CLKernelManager extends KernelManager { - @Override - protected List getPreferredDeviceTypes() { - return Arrays.asList(Device.TYPE.ACC, Device.TYPE.GPU, Device.TYPE.CPU); - } - } - - private class JTPKernelManager extends KernelManager { - private JTPKernelManager() { - LinkedHashSet preferredDevices = new LinkedHashSet(1); - preferredDevices.add(JavaDevice.THREAD_POOL); - setDefaultPreferredDevices(preferredDevices); - } - @Override - protected List getPreferredDeviceTypes() { - return Arrays.asList(Device.TYPE.JTP); - } - } - - public void setUpBefore() throws Exception { - KernelManager.setKernelManager(new CLKernelManager()); - Device device = KernelManager.instance().bestDevice(); - if (device == null || !(device instanceof OpenCLDevice)) { - logger.log(Level.WARNING, "!!!No OpenCLDevice available for running the integration test - test will be skipped"); - } - assumeTrue (device != null && device instanceof OpenCLDevice); - openCLDevice = (OpenCLDevice) device; - } - - /** - * Tests the ProfileReport observer interface in a single threaded, single kernel environment running on - * an OpenCL device. - * @throws Exception - */ - @Test - public void singleThreadedSingleKernelObserverOpenCLTest() throws Exception { - setUpBefore(); - logger.log(Level.INFO, "Test " + name.getMethodName() + " - Executing on device: " + openCLDevice.getShortDescription() + " - " + openCLDevice.getName()); - assertTrue(singleThreadedSingleKernelReportObserverTestHelper(openCLDevice, 128)); - } - - /** - * Tests the ProfileReport observer interface in a single threaded, single kernel environment running on - * Java Thread Pool. - */ - @Test - public void singleThreadedSingleKernelObserverJTPTest() { - KernelManager.setKernelManager(new JTPKernelManager()); - Device device = KernelManager.instance().bestDevice(); - assertTrue(singleThreadedSingleKernelReportObserverTestHelper(device, 16)); - } - - private class ThreadTestState { - private double accumulatedElapsedTime = 0.0; - private long receivedReportsCount = 0; - } - - private class ReportObserver implements IProfileReportObserver { - private final ConcurrentSkipListSet expectedThreadsIds = new ConcurrentSkipListSet<>(); - private final ConcurrentSkipListMap observedThreadsIds = new ConcurrentSkipListMap<>(); - private final Device device; - private final int threads; - private final int runs; - private final boolean[] receivedReportIds; - - private ReportObserver(Device _device, int _threads, int _runs) { - device = _device; - threads = _threads; - runs = _runs; - - receivedReportIds = new boolean[threads * runs]; - } - - private void addAcceptedThreadId(long threadId) { - expectedThreadsIds.add(threadId); - } - - private ConcurrentSkipListMap getObservedThreadsIds() { - return observedThreadsIds; - } - - @Override - public void receiveReport(Class kernelClass, Device _device, WeakReference profileInfoRef) { - ProfileReport profileInfo = profileInfoRef.get(); - assertEquals("Kernel class does not match", Basic1Kernel.class, kernelClass); - assertEquals("Device does not match", device, _device); - boolean isThreadAccepted = expectedThreadsIds.contains(profileInfo.getThreadId()); - assertTrue("Thread generating the report (" + profileInfo.getThreadId() + - ") is not among the accepted ones: " + expectedThreadsIds.toString(), isThreadAccepted); - Long threadId = profileInfo.getThreadId(); - ThreadTestState state = observedThreadsIds.computeIfAbsent(threadId, k -> new ThreadTestState()); - state.accumulatedElapsedTime += profileInfo.getExecutionTime(); - state.receivedReportsCount++; - receivedReportIds[(int)profileInfo.getReportId() - 1] = true; - } - } - - public boolean singleThreadedSingleKernelReportObserverTestHelper(Device device, int size) { - final int runs = 100; - final int inputArray[] = new int[size]; - final Basic1Kernel kernel = new Basic1Kernel(); - - int[] outputArray = null; - Range range = device.createRange(size, size); - - ReportObserver observer = new ReportObserver(device, 1, runs); - observer.addAcceptedThreadId(Thread.currentThread().getId()); - kernel.registerProfileReportObserver(observer); - - for (int i = 0; i < runs; i++) { - assertFalse("Report with id " + i + " shouldn't have been received yet", observer.receivedReportIds[i]); - } - - long startOfExecution = System.currentTimeMillis(); - try { - for (int i = 0; i < runs; i++) { - outputArray = Arrays.copyOf(inputArray, inputArray.length); - kernel.setInputOuputArray(outputArray); - kernel.execute(range); - } - long runTime = System.currentTimeMillis() - startOfExecution; - ConcurrentSkipListMap results = observer.getObservedThreadsIds(); - ThreadTestState state = results.get(Thread.currentThread().getId()); - assertNotNull("Reports should have been received for thread", state); - - assertEquals("Number of profiling reports doesn't match the expected", runs, state.receivedReportsCount); - assertEquals("Aparapi Accumulated execution time doesn't match", kernel.getAccumulatedExecutionTimeAllThreads(device), state.accumulatedElapsedTime, 1e-10); - assertEquals("Test estimated accumulated time doesn't match within 200ms window", runTime, kernel.getAccumulatedExecutionTimeAllThreads(device), 200); - for (int i = 0; i < runs; i++) { - assertTrue("Report with id " + i + " wasn't received", observer.receivedReportIds[i]); - } - assertTrue(validateBasic1Kernel(inputArray, outputArray)); - } finally { - kernel.registerProfileReportObserver(null); - kernel.dispose(); - } - - return true; - } - - /** - * Tests the ProfileReport observer interface in a multi threaded, single kernel environment running on - * an OpenCL device. - */ - @Test - public void multiThreadedSingleKernelObserverOpenCLTest() throws Exception { - setUpBefore(); - logger.log(Level.INFO, "Test " + name.getMethodName() + " - Executing on device: " + openCLDevice.getShortDescription() + " - " + openCLDevice.getName()); - assertTrue(multiThreadedSingleKernelReportObserverTestHelper(openCLDevice, 128)); - } - - /** - * Tests the ProfileReport observer interface in a multi threaded, single kernel environment running on - * Java Thread Pool. - */ - @Test - public void multiThreadedSingleKernelObserverJTPTest() throws Exception { - KernelManager.setKernelManager(new JTPKernelManager()); - Device device = KernelManager.instance().bestDevice(); - assertTrue(multiThreadedSingleKernelReportObserverTestHelper(device, 16)); - } - - private class ThreadResults { - private long runTime; - private long threadId; - private int kernelCalls; - private double accumulatedExecutionTime; - private int[] outputArray; - } - - @SuppressWarnings("unchecked") - public boolean multiThreadedSingleKernelReportObserverTestRunner(final ExecutorService executorService, - final List kernels, final ThreadResults[] results, int[] inputArray, int runs, int javaThreads, - final Device device, final ReportObserver observer, int size) throws InterruptedException, ExecutionException { - final AtomicInteger atomicResultId = new AtomicInteger(0); - boolean terminatedOk = false; - try { - List> futures = new ArrayList<>(javaThreads); - for (Basic1Kernel k : kernels) { - futures.add((Future)executorService.submit(new Runnable() { - @Override - public void run() { - int id = atomicResultId.getAndIncrement(); - results[id].threadId = Thread.currentThread().getId(); - observer.addAcceptedThreadId(results[id].threadId); - long startOfExecution = System.currentTimeMillis(); - results[id].kernelCalls = 0; - for (int i = 0; i < runs; i++) { - results[id].outputArray = Arrays.copyOf(inputArray, inputArray.length); - k.setInputOuputArray(results[id].outputArray); - k.execute(Range.create(device, size, size)); - results[id].kernelCalls++; - } - results[id].runTime = System.currentTimeMillis() - startOfExecution; - results[id].accumulatedExecutionTime = k.getAccumulatedExecutionTimeCurrentThread(device); - } - })); - } - for (Future future : futures) { - future.get(); - } - } finally { - for (Basic1Kernel k : kernels) { - k.registerProfileReportObserver(null); - } - executorService.shutdown(); - try { - terminatedOk = executorService.awaitTermination(1, TimeUnit.MINUTES); - } catch (InterruptedException ex) { - //For the purposes of the test this suffices - terminatedOk = false; - } - if (!terminatedOk) { - executorService.shutdownNow(); - } - } - - return terminatedOk; - } - - public boolean multiThreadedSingleKernelReportObserverTestHelper(Device device, int size) throws InterruptedException, ExecutionException { - final int runs = 100; - final int javaThreads = 10; - final int inputArray[] = new int[size]; - ExecutorService executorService = Executors.newFixedThreadPool(javaThreads); - - final ReportObserver observer = new ReportObserver(device, javaThreads, runs); - - for (int i = 0; i < runs; i++) { - assertFalse("Report with id " + i + " shouldn't have been received yet", observer.receivedReportIds[i]); - } - - final List kernels = new ArrayList(javaThreads); - for (int i = 0; i < javaThreads; i++) { - final Basic1Kernel kernel = new Basic1Kernel(); - kernel.registerProfileReportObserver(observer); - kernels.add(kernel); - } - - final ThreadResults[] results = new ThreadResults[javaThreads]; - for (int i = 0; i < results.length; i++) { - results[i] = new ThreadResults(); - } - - - boolean terminatedOk = multiThreadedSingleKernelReportObserverTestRunner(executorService, kernels, results, - inputArray, runs, javaThreads, device, observer, size); - - assertTrue("Threads did not terminate correctly", terminatedOk); - - double allThreadsAccumulatedTime = 0; - ConcurrentSkipListMap states = observer.getObservedThreadsIds(); - assertEquals("Number of Java threads sending profile reports should match the number of JavaThreads", javaThreads, states.values().size()); - for (int i = 0; i < javaThreads; i++) { - ThreadTestState state = states.get(results[i].threadId); - assertNotNull("Report should have been received for thread with index " + i, state); - assertEquals("Number of total iteration should match number of runs for thread with index " + i, runs, results[i].kernelCalls); - assertEquals("Number of received reports should match total number of calls for thread with index " + i, runs, state.receivedReportsCount); - assertEquals("Overall elapsed time received in reports doesn't match KernelDeviceProfile.Accumulator for threa with index " + i, - results[i].accumulatedExecutionTime, state.accumulatedElapsedTime, 1e-10); - allThreadsAccumulatedTime += state.accumulatedElapsedTime; - assertTrue("Thread index " + i + " kernel computation doesn't match the expected", validateBasic1Kernel(inputArray, results[i].outputArray)); - assertEquals("Runtime is not within 600ms of the kernel estimated", results[i].runTime, state.accumulatedElapsedTime, 600); - } - - assertEquals("Overall kernel execution time doesn't match", - kernels.get(0).getAccumulatedExecutionTimeAllThreads(device), allThreadsAccumulatedTime, 1e10); - - return true; - } - - private boolean validateBasic1Kernel(final int[] inputArray, final int[] resultArray) { - int[] expecteds = Arrays.copyOf(inputArray, inputArray.length); - for (int threadId = 0; threadId < inputArray.length; threadId++) { - expecteds[threadId] += threadId; - } - - assertArrayEquals(expecteds, resultArray); - - return true; - } - - private class Basic1Kernel extends Kernel { - protected int[] workArray; - - @NoCL - public void setInputOuputArray(int[] array) { - workArray = array; - } - - @NoCL - public int getId() { - return 1; - } - - @Override - public void run() { - int id = getLocalId(); - - workArray[id]+=id; - } - } -} diff --git a/src/test/java/com/aparapi/runtime/ProfileReportUnitTest.java b/src/test/java/com/aparapi/runtime/ProfileReportUnitTest.java deleted file mode 100644 index f65411c8..00000000 --- a/src/test/java/com/aparapi/runtime/ProfileReportUnitTest.java +++ /dev/null @@ -1,171 +0,0 @@ -/** - * Copyright (c) 2016 - 2018 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 static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.lang.ref.WeakReference; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.ConcurrentSkipListSet; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - -import org.junit.Test; - -import com.aparapi.IProfileReportObserver; -import com.aparapi.Kernel; -import com.aparapi.ProfileReport; -import com.aparapi.device.Device; -import com.aparapi.device.JavaDevice; -import com.aparapi.internal.kernel.KernelDeviceProfile; -import com.aparapi.internal.kernel.KernelProfile; -import com.aparapi.internal.kernel.ProfilingEvent; - -/** - * This class provides unit tests to help in validation of thread-safe ProfileReports. - * - * @author CoreRasurae - */ -public class ProfileReportUnitTest { - - private class SimpleKernel extends Kernel { - - @Override - public void run() { - //Empty method intended - } - } - - /** - * This test validates that all threads can start a profiling process after another thread - * that has already started profiling. - * @throws InterruptedException - * @throws Exception - */ - @Test - public void testAllThreadCanStartPass() throws IllegalStateException, InterruptedException { - final int javaThreads = ProfilingEvent.values().length; - final KernelProfile kernelProfile = new KernelProfile(SimpleKernel.class); - final KernelDeviceProfile kernelDeviceProfile = new KernelDeviceProfile(kernelProfile, SimpleKernel.class, JavaDevice.THREAD_POOL); - final AtomicInteger receivedReports = new AtomicInteger(0); - final ConcurrentSkipListSet onEventAccepted = new ConcurrentSkipListSet(); - final AtomicInteger index = new AtomicInteger(0); - final long[] threadIds = new long[javaThreads + 1]; - - kernelProfile.setReportObserver(new IProfileReportObserver() { - @Override - public void receiveReport(Class kernelClass, Device device, WeakReference profileInfo) { - receivedReports.incrementAndGet(); - onEventAccepted.add(profileInfo.get().getThreadId()); - } - }); - - //Ensure that the first thread as started profiling, before testing the others - kernelDeviceProfile.onEvent(ProfilingEvent.START); - - List events = Arrays.asList(ProfilingEvent.values()); - - ExecutorService executorService = Executors.newFixedThreadPool(javaThreads); - try { - try { - events.forEach(evt -> { - final int idx = index.getAndIncrement(); - executorService.submit(() -> { - threadIds[idx] = Thread.currentThread().getId(); - kernelDeviceProfile.onEvent(ProfilingEvent.START); - kernelDeviceProfile.onEvent(ProfilingEvent.EXECUTED); - }); - }); - } finally { - executorService.shutdown(); - if (!executorService.awaitTermination(1, TimeUnit.MINUTES)) { - executorService.shutdownNow(); - throw new IllegalStateException("ExecutorService terminated abnormaly"); - } - } - - threadIds[index.get()] = Thread.currentThread().getId(); - for (int i = 0; i < javaThreads; i++) { - assertTrue("Report wasn't received for thread with index " + i, onEventAccepted.contains(threadIds[i])); - } - assertFalse("Report was received for main thread", onEventAccepted.contains(threadIds[javaThreads])); - assertEquals("Reports from all threads should have been received", javaThreads, receivedReports.get()); - - //Only after this event should the main thread have received a report - kernelDeviceProfile.onEvent(ProfilingEvent.EXECUTED); - - assertTrue("Report wasn't received for main thread", onEventAccepted.contains(threadIds[javaThreads])); - assertEquals("Reports from all threads should have been received", javaThreads + 1, receivedReports.get()); - } finally { - kernelProfile.setReportObserver(null); - } - } - - @Test - public void testGetProfilingEventsNames() { - String[] stages = ProfilingEvent.getStagesNames(); - int i = 0; - for (String stage : stages) { - assertNotNull("Stage is null at index " + i, stage); - assertFalse("Stage name is empty at index " + i, stage.isEmpty()); - ProfilingEvent event = ProfilingEvent.valueOf(stage); - assertTrue("Stage name does not translate to an event", event != null); - assertEquals("Stage name does match correct order", i, event.ordinal()); - i++; - } - } - - @Test - public void testProfileReportClone() { - final int reportId = 101; - final int threadId = 192; - final long[] values = new long[ProfilingEvent.values().length]; - for (int i = 0; i < values.length; i++) { - values[i] = 900 + i; - } - - ProfileReport report = new ProfileReport(threadId, SimpleKernel.class, JavaDevice.THREAD_POOL); - report.setProfileReport(reportId, values); - - ProfileReport clonedReport = report.clone(); - assertNotEquals("Object references shouldn't be the same", report, clonedReport); - assertEquals("Report Id doesn't match", reportId, clonedReport.getReportId()); - assertEquals("Class doesn't match", SimpleKernel.class, clonedReport.getKernelClass()); - assertEquals("Device doesn't match", JavaDevice.THREAD_POOL, clonedReport.getDevice()); - - for (int i = 0; i < values.length; i++) { - assertEquals("Values don't match for index " + i, report.getElapsedTime(i), clonedReport.getElapsedTime(i), 1e-10); - } - - long[] valuesB = new long[ProfilingEvent.values().length]; - for (int i = 0; i < valuesB.length; i++) { - valuesB[i] = 100 + i*100; - } - report.setProfileReport(reportId + 1, valuesB); - - for (int i = 1; i < values.length; i++) { - assertNotEquals("Values match after new assingment for index " + i, report.getElapsedTime(i), clonedReport.getElapsedTime(i), 1e-10); - } - - } -} diff --git a/src/test/java/com/aparapi/runtime/RangeSizeTest.java b/src/test/java/com/aparapi/runtime/RangeSizeTest.java deleted file mode 100644 index 2b1db170..00000000 --- a/src/test/java/com/aparapi/runtime/RangeSizeTest.java +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright (c) 2016 - 2018 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 RangeSizeTest { - - @Test - public void test384x384() { - Range range = Range.create2D(384, 384); - assertTrue("Range > max work size", range.getLocalSize(0) * range.getLocalSize(1) <= range.getWorkGroupSize()); - } - - @Test - public void test384x320() { - Range range = Range.create2D(384, 320); - assertTrue("Range > max work size", range.getLocalSize(0) * range.getLocalSize(1) <= range.getWorkGroupSize()); - } - -} diff --git a/src/test/java/com/aparapi/runtime/ReturnInstantiatedArrayDirectlyTest.java b/src/test/java/com/aparapi/runtime/ReturnInstantiatedArrayDirectlyTest.java deleted file mode 100644 index 5ae9c182..00000000 --- a/src/test/java/com/aparapi/runtime/ReturnInstantiatedArrayDirectlyTest.java +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Copyright (c) 2016 - 2018 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.Ignore; -import org.junit.Test; - -import java.util.Arrays; - -import static org.junit.Assert.assertArrayEquals; - - -public class ReturnInstantiatedArrayDirectlyTest { - @Test - @Ignore("Knon bug, ignoring until fixed.") - public void test() { - ReturnDoubleArrayNew kernel = new ReturnDoubleArrayNew(); - kernel.execute(1); - } - - public class ReturnDoubleArrayNew extends Kernel { - - double[] returnDoubleArrayNew() { - return new double[1024]; - } - - public void run() { - returnDoubleArrayNew(); - } - } -} diff --git a/src/test/java/com/aparapi/runtime/StaticArrayAssignmentTest.java b/src/test/java/com/aparapi/runtime/StaticArrayAssignmentTest.java deleted file mode 100644 index 2a979e56..00000000 --- a/src/test/java/com/aparapi/runtime/StaticArrayAssignmentTest.java +++ /dev/null @@ -1,61 +0,0 @@ -/** - * Copyright (c) 2016 - 2018 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.Ignore; -import org.junit.Test; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertTrue; - -public class StaticArrayAssignmentTest { - @Test - @Ignore("Solution not implemented yet, will pass on cpu but not gpu") - public void test() { - UseStaticArrayKernel k = new UseStaticArrayKernel(); - k.test(); - } - - protected static class UseStaticArrayKernel extends Kernel { - - static final int size = 256; - - static final int[] values = new int[size]; - - static final int[] results = new int[size]; - - @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); - - assertArrayEquals("results == fooBar", results, values); - } - } -} diff --git a/src/test/java/com/aparapi/runtime/StaticVariableAssignmentTest.java b/src/test/java/com/aparapi/runtime/StaticVariableAssignmentTest.java deleted file mode 100644 index 89806191..00000000 --- a/src/test/java/com/aparapi/runtime/StaticVariableAssignmentTest.java +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Copyright (c) 2016 - 2018 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.Ignore; -import org.junit.Test; - -import static org.junit.Assert.assertArrayEquals; - - -public class StaticVariableAssignmentTest { - @Test - @Ignore("Solution not implemented yet, will pass on cpu but not gpu") - public void test() { - Issue103Kernel b = new Issue103Kernel(); - b.test(); - } - - public static class Issue103Kernel extends Kernel { - static final int size = 32; - - static int[] source = new int[size]; - static int[] target = new int[size]; - - public Issue103Kernel() { - for (int i = 0; i < size; ++i) { - source[i] = 7; - target[i] = 99; - } - } - - @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]); -// } - } - - public void test() { - execute(size); - validate(); - } - } -} diff --git a/src/test/java/com/aparapi/runtime/UseBooleanTest.java b/src/test/java/com/aparapi/runtime/UseBooleanTest.java deleted file mode 100644 index 3fa6a828..00000000 --- a/src/test/java/com/aparapi/runtime/UseBooleanTest.java +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Copyright (c) 2016 - 2018 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.Ignore; -import org.junit.Test; - -public class UseBooleanTest { - @Ignore("Known bug not currently fixed on GPU, works on CPU") - @Test - public void test() { - new UseBooleanTest().executeTest(); - } - - private void executeTest() { - final Kernel kernel = new BooleanKernel(); - kernel.execute(1); - } - - private class BooleanKernel extends Kernel { - private boolean isInverse = true; - - @Override - public void run() { - if (isInverse) { - noop(); - } - } - - private void noop() { - //no op - } - } -} diff --git a/src/test/java/com/aparapi/runtime/Util.java b/src/test/java/com/aparapi/runtime/Util.java deleted file mode 100644 index 3ef75930..00000000 --- a/src/test/java/com/aparapi/runtime/Util.java +++ /dev/null @@ -1,82 +0,0 @@ -/** - * Copyright (c) 2016 - 2018 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; - -import com.aparapi.internal.kernel.KernelManager; - -public class Util { - public static void resetKernelManager() { - KernelManager.setKernelManager(new OriginalKernelManager()); - } - - 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); - } - -}