Merge "Test for improper kernel fusion." into klp-dev
diff --git a/tests/src/android/renderscript/cts/group1.rs b/tests/src/android/renderscript/cts/group1.rs
new file mode 100644
index 0000000..f1172dc
--- /dev/null
+++ b/tests/src/android/renderscript/cts/group1.rs
@@ -0,0 +1,13 @@
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+#include "shared.rsh"
+
+rs_allocation aSharedInt;
+
+uint32_t __attribute__((kernel)) setSharedInt(uint32_t x) {
+ if (x == 1) {
+ rsSetElementAt_int(aSharedInt, -5, 0);
+ }
+ return x;
+}
diff --git a/tests/src/android/renderscript/cts/group2.rs b/tests/src/android/renderscript/cts/group2.rs
new file mode 100644
index 0000000..f7b62dd
--- /dev/null
+++ b/tests/src/android/renderscript/cts/group2.rs
@@ -0,0 +1,32 @@
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+#include "shared.rsh"
+
+rs_allocation aSharedInt;
+rs_allocation aFailed;
+
+static bool failed[2] = { false, false };
+
+void __attribute__((kernel)) getSharedInt(uint32_t in, uint32_t x) {
+ int v = rsGetElementAt_int(aSharedInt, 0);
+ if (in != x) {
+ rsDebug("Failed to read in on iteration: ", x);
+ rsDebug("Read: ", in);
+ failed[x] = true;
+ }
+ if (v != -5) {
+ rsDebug("Failed to read -5 on iteration: ", x);
+ rsDebug("Read: ", v);
+ failed[x] = true;
+ }
+}
+
+// Write out aFailed if either of our kernel instances read old data.
+void verify() {
+ for (int i = 0; i < 2; i++) {
+ if (failed[i]) {
+ rsSetElementAt_int(aFailed, 1, 0);
+ }
+ }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/ScriptGroupTest.java b/tests/tests/renderscript/src/android/renderscript/cts/ScriptGroupTest.java
index 64496ef..c9a79c8 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/ScriptGroupTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/ScriptGroupTest.java
@@ -202,13 +202,13 @@
Type compareType = new Type.Builder(mRS, Element.I32(mRS)).create();
ScriptC_scriptgroup node1, node2, node3, node4, node5, compare;
- node1 = new ScriptC_scriptgroup(mRS, mRes, R.raw.scriptgroup);
- node2 = new ScriptC_scriptgroup(mRS, mRes, R.raw.scriptgroup);
- node3 = new ScriptC_scriptgroup(mRS, mRes, R.raw.scriptgroup);
- node4 = new ScriptC_scriptgroup(mRS, mRes, R.raw.scriptgroup);
- node5 = new ScriptC_scriptgroup(mRS, mRes, R.raw.scriptgroup);
+ node1 = new ScriptC_scriptgroup(mRS);
+ node2 = new ScriptC_scriptgroup(mRS);
+ node3 = new ScriptC_scriptgroup(mRS);
+ node4 = new ScriptC_scriptgroup(mRS);
+ node5 = new ScriptC_scriptgroup(mRS);
- compare = new ScriptC_scriptgroup(mRS, mRes, R.raw.scriptgroup);
+ compare = new ScriptC_scriptgroup(mRS);
Allocation in1, in2, out, resultAlloc;
in1 = Allocation.createTyped(mRS, connect);
@@ -265,4 +265,50 @@
assertTrue(result[0] == 2);
}
+ /**
+ * Tests a case where a shared global variable is updated by the first kernel in a group,
+ * but then read by a subsequent kernel.
+ *
+ * The test ensures that we don't accidentally apply any fusion optimizations to the kernel
+ * pair, since there is a potential dependency that crosses the kernel cell boundary.
+ */
+ public void testScriptGroupSharedGlobal() {
+ Type i32 = new Type.Builder(mRS, Element.I32(mRS)).setX(1).create();
+ Type u32 = new Type.Builder(mRS, Element.U32(mRS)).setX(2).create();
+
+ Allocation aFailed = Allocation.createTyped(mRS, i32);
+ Allocation aSharedInt = Allocation.createTyped(mRS, i32);
+
+ ScriptC_group1 mG1 = new ScriptC_group1(mRS);
+ ScriptC_group2 mG2 = new ScriptC_group2(mRS);
+
+ mG1.set_aSharedInt(aSharedInt);
+ mG2.set_aSharedInt(aSharedInt);
+ mG2.set_aFailed(aFailed);
+
+ int [] Failed = new int [1];
+ Failed[0] = 0;
+ aFailed.copyFrom(Failed);
+
+ ScriptGroup.Builder b = new ScriptGroup.Builder(mRS);
+
+ // Writes to aSharedInt[x] in the kernel.
+ b.addKernel(mG1.getKernelID_setSharedInt());
+ // Reads aSharedInt[1] to verify it is -5.
+ b.addKernel(mG2.getKernelID_getSharedInt());
+ // If we fuse mG1/mG2, we won't see the update to the aSharedInt[1] during mG2 for x == 0.
+ // The update is only visible if we correctly identify the dependency and execute all of
+ // mG1 before starting on mG2.
+ b.addConnection(u32, mG1.getKernelID_setSharedInt(), mG2.getKernelID_getSharedInt());
+ ScriptGroup group = b.create();
+ group.execute();
+
+ mG2.invoke_verify();
+ aFailed.copyTo(Failed);
+ if (Failed[0] != 0) {
+ FoundError = true;
+ }
+
+ checkForErrors();
+ }
}