From 94b705249d2b4a3fc58cbd3b1b38580cc8dad636 Mon Sep 17 00:00:00 2001 From: CoreRasurae <luis.p.mendes@gmail.com> Date: Fri, 24 Aug 2018 13:18:22 +0100 Subject: [PATCH] Fix: Fix arrays of AtomicInteger stored on local variables no longer fail with type cast exception - Partial fix for (refs #138) - support non-const indexed local variables --- .../aparapi/internal/writer/BlockWriter.java | 19 +++--- .../runtime/LocalAtomicVariableArrayTest.java | 68 ++++++++++++++++--- 2 files changed, 66 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/aparapi/internal/writer/BlockWriter.java b/src/main/java/com/aparapi/internal/writer/BlockWriter.java index ba7aca90..013239d0 100644 --- a/src/main/java/com/aparapi/internal/writer/BlockWriter.java +++ b/src/main/java/com/aparapi/internal/writer/BlockWriter.java @@ -796,7 +796,7 @@ public abstract class BlockWriter{ } else { //Arrays can be accessed through local variables instead of instance fields, thus, AccessField instruction //can be null. - LocalVariableConstIndexAccessor accessLocalVariable = getUltimateInstanceLocalVarAccess(arrayLoadInstruction); + AccessLocalVariable accessLocalVariable = getUltimateInstanceLocalVarAccess(arrayLoadInstruction); //Directly check for multi-dimensional array... return accessLocalVariable.getLocalVariableInfo().getVariableDescriptor().startsWith("[["); } @@ -813,27 +813,24 @@ public abstract class BlockWriter{ load = load.getFirstChild(); } - if (load instanceof I_ALOAD_0 || load instanceof I_ALOAD_1 || load instanceof I_ALOAD_2 || load instanceof I_ALOAD_3) { - //It is not a Field Access + if (load instanceof I_ALOAD || + load instanceof I_ALOAD_0 || load instanceof I_ALOAD_1 || load instanceof I_ALOAD_2 || load instanceof I_ALOAD_3) { + //It is not a Field Access, it is either a constant index local variable (0..3), or is a variable indexed local variable (>3) return null; } return (AccessField) load; } - private LocalVariableConstIndexAccessor getUltimateInstanceLocalVarAccess(AccessArrayElement arrayLoadInstruction) { + private AccessLocalVariable getUltimateInstanceLocalVarAccess(AccessArrayElement arrayLoadInstruction) { Instruction load = arrayLoadInstruction.getArrayRef(); while (load instanceof I_AALOAD) { load = load.getFirstChild(); } - if (load instanceof I_ALOAD) { - return null; - } - - return (LocalVariableConstIndexAccessor)load; - } - + return (AccessLocalVariable)load; + } + public void writeMethod(MethodCall _methodCall, MethodEntry _methodEntry) throws CodeGenException { boolean noCL = _methodEntry.getOwnerClassModel().getNoCLMethods() .contains(_methodEntry.getNameAndTypeEntry().getNameUTF8Entry().getUTF8()); diff --git a/src/test/java/com/aparapi/runtime/LocalAtomicVariableArrayTest.java b/src/test/java/com/aparapi/runtime/LocalAtomicVariableArrayTest.java index 26978d75..6f70f16c 100644 --- a/src/test/java/com/aparapi/runtime/LocalAtomicVariableArrayTest.java +++ b/src/test/java/com/aparapi/runtime/LocalAtomicVariableArrayTest.java @@ -72,32 +72,80 @@ public class LocalAtomicVariableArrayTest { } @Test - public void openCLTest() { - SimpleLocalVarKernel myKernel = new SimpleLocalVarKernel(); + public void simpleConstIndexOpenCLTest() { + SimpleConstIndexLocalVarKernel myKernel = new SimpleConstIndexLocalVarKernel(); Range range = openCLDevice.createRange(SIZE, SIZE); try { myKernel.execute(range); - assertEquals("Atomic increment doesn't match", SIZE, myKernel.atomics[1].get()); + assertEquals("Atomic increment doesn't match, index 1", SIZE, myKernel.atomics[1].get()); + assertEquals("Atomic increment doesn't match, index 2", SIZE, myKernel.atomics[2].get()); + assertEquals("Atomic increment doesn't match, index 3", SIZE, myKernel.atomics[3].get()); } finally { myKernel.dispose(); } } - - public class SimpleLocalVarKernel extends Kernel { + + @Test + public void simpleVarIndexOpenCLTest() { + SimpleVarIndexLocalVarKernel myKernel = new SimpleVarIndexLocalVarKernel(); + Range range = openCLDevice.createRange(SIZE, SIZE); + try { + myKernel.execute(range); + assertEquals("Atomic increment doesn't match", SIZE, myKernel.atomics[4].get()); + } finally { + myKernel.dispose(); + } + } + + public class SimpleConstIndexLocalVarKernel extends Kernel { private AtomicInteger[] atomics = new AtomicInteger[SIZE]; - public SimpleLocalVarKernel() { + public SimpleConstIndexLocalVarKernel() { for (int i = 0; i < atomics.length; i++) { atomics[i] = new AtomicInteger(0); } } - @Override public void run() { - atomicUpdate(atomics, 1); + @Override + public void run() { + atomicUpdate1(atomics, 1); + atomicUpdate2(2, atomics); + atomicUpdate3(3, 0, atomics); + } + + public int atomicUpdate1(AtomicInteger[] arr, int index) { + //Exercises I_ALOAD_1 + return atomicInc(arr[index]); } - public int atomicUpdate(AtomicInteger[] arr, int index) { + public int atomicUpdate2(int index, AtomicInteger[] arr) { + //Exercises I_ALOAD_2 return atomicInc(arr[index]); - } + } + + public int atomicUpdate3(int index, int indexB, AtomicInteger[] arr) { + //Exercises I_ALOAD_3 + return atomicInc(arr[index+indexB]); + } + } + + public class SimpleVarIndexLocalVarKernel extends Kernel { + private AtomicInteger[] atomics = new AtomicInteger[SIZE]; + + public SimpleVarIndexLocalVarKernel() { + for (int i = 0; i < atomics.length; i++) { + atomics[i] = new AtomicInteger(0); + } + } + + @Override + public void run() { + atomicUpdate4(4, 0, 0, atomics); + } + + public int atomicUpdate4(int index, int indexB, int indexC, AtomicInteger[] arr) { + //Exercises I_ALOAD - when index is greater than 3 + return atomicInc(arr[index+indexB+indexC]); + } } } -- GitLab