1 /* 2 * Copyright (C) 2011-2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.renderscript.cts; 18 19 import com.android.cts.stub.R; 20 21 import android.graphics.Bitmap; 22 import android.renderscript.Allocation; 23 import android.renderscript.AllocationAdapter; 24 import android.renderscript.Allocation.MipmapControl; 25 import android.renderscript.Element; 26 import android.renderscript.RSIllegalArgumentException; 27 import android.renderscript.RSInvalidStateException; 28 import android.renderscript.Type; 29 import android.renderscript.Type.Builder; 30 31 import android.renderscript.ScriptIntrinsicColorMatrix; 32 import android.renderscript.ScriptIntrinsicConvolve3x3; 33 import android.renderscript.ScriptGroup; 34 import android.renderscript.Matrix4f; 35 import android.util.Log; 36 37 public class ScriptGroupTest extends RSBaseCompute { 38 39 static int bDimX = 48; 40 static int bDimY = 8; 41 42 public void testScriptGroupSingleKernel() { 43 ScriptGroup group; 44 45 Type connect = new Type.Builder(mRS, Element.U8_4(mRS)).setX(bDimX).setY(bDimY).create(); 46 47 ScriptIntrinsicColorMatrix mColorMatrix; 48 49 mColorMatrix = ScriptIntrinsicColorMatrix.create(mRS, Element.U8_4(mRS)); 50 51 Allocation a1_copy, a2_copy; 52 a1_copy = Allocation.createTyped(mRS, connect); 53 a2_copy = Allocation.createTyped(mRS, connect); 54 55 Matrix4f m = new Matrix4f(); 56 m.set(1, 0, 0.2f); 57 m.set(1, 1, 0.9f); 58 m.set(1, 2, 0.2f); 59 mColorMatrix.setColorMatrix(m); 60 61 ScriptGroup.Builder b = new ScriptGroup.Builder(mRS); 62 b.addKernel(mColorMatrix.getKernelID()); 63 group = b.create(); 64 65 group.setInput(mColorMatrix.getKernelID(), a1_copy); 66 group.setOutput(mColorMatrix.getKernelID(), a2_copy); 67 68 group.execute(); 69 } 70 71 public void testScriptGroupDisconnectedKernel() { 72 ScriptGroup group; 73 74 Type connect = new Type.Builder(mRS, Element.U8_4(mRS)).setX(bDimX).setY(bDimY).create(); 75 76 ScriptIntrinsicColorMatrix mColorMatrix, mColorMatrix2; 77 78 mColorMatrix = ScriptIntrinsicColorMatrix.create(mRS, Element.U8_4(mRS)); 79 mColorMatrix2 = ScriptIntrinsicColorMatrix.create(mRS, Element.U8_4(mRS)); 80 81 Allocation a1_copy, a2_copy; 82 83 a1_copy = Allocation.createTyped(mRS, connect); 84 a2_copy = Allocation.createTyped(mRS, connect); 85 86 Matrix4f m = new Matrix4f(); 87 m.set(1, 0, 0.2f); 88 m.set(1, 1, 0.9f); 89 m.set(1, 2, 0.2f); 90 mColorMatrix.setColorMatrix(m); 91 mColorMatrix2.setColorMatrix(m); 92 93 ScriptGroup.Builder b = new ScriptGroup.Builder(mRS); 94 b.addKernel(mColorMatrix.getKernelID()); 95 b.addKernel(mColorMatrix2.getKernelID()); 96 try { 97 group = b.create(); 98 fail("should throw RSInvalidStateException."); 99 } catch (RSInvalidStateException e) { 100 101 } 102 } 103 104 105 public void testScriptGroupFieldConnection() { 106 ScriptGroup group; 107 108 Type connect = new Type.Builder(mRS, Element.U8_4(mRS)).setX(bDimX).setY(bDimY).create(); 109 110 ScriptIntrinsicConvolve3x3 mConvolve3x3; 111 ScriptIntrinsicColorMatrix mColorMatrix; 112 113 mConvolve3x3 = ScriptIntrinsicConvolve3x3.create(mRS, Element.U8_4(mRS)); 114 mColorMatrix = ScriptIntrinsicColorMatrix.create(mRS, Element.U8_4(mRS)); 115 116 Allocation a1_copy, a2_copy; 117 a1_copy = Allocation.createTyped(mRS, connect); 118 a2_copy = Allocation.createTyped(mRS, connect); 119 120 float f[] = new float[9]; 121 f[0] = 0.f; f[1] = -1.f; f[2] = 0.f; 122 f[3] = -1.f; f[4] = 5.f; f[5] = -1.f; 123 f[6] = 0.f; f[7] = -1.f; f[8] = 0.f; 124 125 mConvolve3x3.setCoefficients(f); 126 127 Matrix4f m = new Matrix4f(); 128 m.set(1, 0, 0.2f); 129 m.set(1, 1, 0.9f); 130 m.set(1, 2, 0.2f); 131 mColorMatrix.setColorMatrix(m); 132 133 ScriptGroup.Builder b = new ScriptGroup.Builder(mRS); 134 b.addKernel(mColorMatrix.getKernelID()); 135 b.addKernel(mConvolve3x3.getKernelID()); 136 b.addConnection(connect, mColorMatrix.getKernelID(), mConvolve3x3.getFieldID_Input()); 137 group = b.create(); 138 139 group.setInput(mColorMatrix.getKernelID(), a1_copy); 140 group.setOutput(mConvolve3x3.getKernelID(), a2_copy); 141 142 group.execute(); 143 144 } 145 146 public void testScriptGroupDisconnectedDAG() { 147 ScriptGroup group; 148 149 Type connect = new Type.Builder(mRS, Element.U8_4(mRS)).setX(bDimX).setY(bDimY).create(); 150 151 ScriptIntrinsicConvolve3x3 mConvolve3x3, mConvolve3x32; 152 ScriptIntrinsicColorMatrix mColorMatrix, mColorMatrix2; 153 154 mConvolve3x3 = ScriptIntrinsicConvolve3x3.create(mRS, Element.U8_4(mRS)); 155 mConvolve3x32 = ScriptIntrinsicConvolve3x3.create(mRS, Element.U8_4(mRS)); 156 mColorMatrix = ScriptIntrinsicColorMatrix.create(mRS, Element.U8_4(mRS)); 157 mColorMatrix2 = ScriptIntrinsicColorMatrix.create(mRS, Element.U8_4(mRS)); 158 159 Allocation a1_copy, a2_copy; 160 a1_copy = Allocation.createTyped(mRS, connect); 161 a2_copy = Allocation.createTyped(mRS, connect); 162 163 float f[] = new float[9]; 164 f[0] = 0.f; f[1] = -1.f; f[2] = 0.f; 165 f[3] = -1.f; f[4] = 5.f; f[5] = -1.f; 166 f[6] = 0.f; f[7] = -1.f; f[8] = 0.f; 167 168 mConvolve3x3.setCoefficients(f); 169 mConvolve3x32.setCoefficients(f); 170 171 Matrix4f m = new Matrix4f(); 172 m.set(1, 0, 0.2f); 173 m.set(1, 1, 0.9f); 174 m.set(1, 2, 0.2f); 175 mColorMatrix.setColorMatrix(m); 176 mColorMatrix2.setColorMatrix(m); 177 178 ScriptGroup.Builder b = new ScriptGroup.Builder(mRS); 179 b.addKernel(mColorMatrix.getKernelID()); 180 b.addKernel(mColorMatrix2.getKernelID()); 181 b.addKernel(mConvolve3x3.getKernelID()); 182 b.addKernel(mConvolve3x32.getKernelID()); 183 b.addConnection(connect, mColorMatrix.getKernelID(), mConvolve3x3.getFieldID_Input()); 184 b.addConnection(connect, mColorMatrix2.getKernelID(), mConvolve3x32.getFieldID_Input()); 185 try { 186 group = b.create(); 187 fail("RSInvalidStateException expected"); 188 } catch (RSInvalidStateException e) { 189 190 } 191 192 } 193 194 public void testScriptGroupTorture() { 195 ScriptGroup group; 196 197 int[] result = new int[1]; 198 199 bDimX = 1; 200 201 Type connect = new Type.Builder(mRS, Element.I32(mRS)).setX(bDimX).create(); 202 Type compareType = new Type.Builder(mRS, Element.I32(mRS)).create(); 203 204 ScriptC_scriptgroup node1, node2, node3, node4, node5, compare; 205 node1 = new ScriptC_scriptgroup(mRS); 206 node2 = new ScriptC_scriptgroup(mRS); 207 node3 = new ScriptC_scriptgroup(mRS); 208 node4 = new ScriptC_scriptgroup(mRS); 209 node5 = new ScriptC_scriptgroup(mRS); 210 211 compare = new ScriptC_scriptgroup(mRS); 212 213 Allocation in1, in2, out, resultAlloc; 214 in1 = Allocation.createTyped(mRS, connect); 215 in2 = Allocation.createTyped(mRS, connect); 216 217 out = Allocation.createTyped(mRS, connect); 218 resultAlloc = Allocation.createTyped(mRS, compareType); 219 220 node1.set_memset_toValue(1); 221 node1.forEach_memset(in1); 222 node1.set_memset_toValue(2); 223 node1.forEach_memset(in2); 224 225 node1.set_arith_operation(2); 226 node2.set_arith_operation(1); 227 node3.set_arith_operation(0); 228 node4.set_arith_operation(0); 229 node5.set_arith_operation(1); 230 231 node3.set_arith_use_rs_allocation(1); 232 node4.set_arith_use_rs_allocation(1); 233 234 node1.set_arith_value(5); 235 node2.set_arith_value(3); 236 node5.set_arith_value(7); 237 238 ScriptGroup.Builder b = new ScriptGroup.Builder(mRS); 239 b.addKernel(node1.getKernelID_arith()); 240 b.addKernel(node2.getKernelID_arith()); 241 b.addKernel(node3.getKernelID_arith()); 242 b.addKernel(node4.getKernelID_arith()); 243 b.addKernel(node5.getKernelID_arith()); 244 245 b.addConnection(connect, node1.getKernelID_arith(), node2.getKernelID_arith()); 246 b.addConnection(connect, node1.getKernelID_arith(), node3.getFieldID_arith_rs_input()); 247 b.addConnection(connect, node2.getKernelID_arith(), node4.getFieldID_arith_rs_input()); 248 b.addConnection(connect, node3.getKernelID_arith(), node4.getKernelID_arith()); 249 b.addConnection(connect, node4.getKernelID_arith(), node5.getKernelID_arith()); 250 251 group = b.create(); 252 group.setInput(node1.getKernelID_arith(), in1); 253 group.setInput(node3.getKernelID_arith(), in2); 254 255 group.setOutput(node5.getKernelID_arith(), out); 256 257 group.execute(); 258 259 mRS.finish(); 260 261 compare.set_compare_value(2); 262 compare.forEach_compare(out); 263 compare.forEach_getCompareResult(resultAlloc); 264 resultAlloc.copyTo(result); 265 assertTrue(result[0] == 2); 266 } 267 268 /** 269 * Tests a case where a shared global variable is updated by the first kernel in a group, 270 * but then read by a subsequent kernel. 271 * 272 * The test ensures that we don't accidentally apply any fusion optimizations to the kernel 273 * pair, since there is a potential dependency that crosses the kernel cell boundary. 274 */ 275 public void testScriptGroupSharedGlobal() { 276 Type i32 = new Type.Builder(mRS, Element.I32(mRS)).setX(1).create(); 277 Type u32 = new Type.Builder(mRS, Element.U32(mRS)).setX(2).create(); 278 279 Allocation aFailed = Allocation.createTyped(mRS, i32); 280 Allocation aSharedInt = Allocation.createTyped(mRS, i32); 281 282 ScriptC_group1 mG1 = new ScriptC_group1(mRS); 283 ScriptC_group2 mG2 = new ScriptC_group2(mRS); 284 285 mG1.set_aSharedInt(aSharedInt); 286 mG2.set_aSharedInt(aSharedInt); 287 mG2.set_aFailed(aFailed); 288 289 int [] Failed = new int [1]; 290 Failed[0] = 0; 291 aFailed.copyFrom(Failed); 292 293 ScriptGroup.Builder b = new ScriptGroup.Builder(mRS); 294 295 // Writes to aSharedInt[x] in the kernel. 296 b.addKernel(mG1.getKernelID_setSharedInt()); 297 // Reads aSharedInt[1] to verify it is -5. 298 b.addKernel(mG2.getKernelID_getSharedInt()); 299 // If we fuse mG1/mG2, we won't see the update to the aSharedInt[1] during mG2 for x == 0. 300 // The update is only visible if we correctly identify the dependency and execute all of 301 // mG1 before starting on mG2. 302 b.addConnection(u32, mG1.getKernelID_setSharedInt(), mG2.getKernelID_getSharedInt()); 303 ScriptGroup group = b.create(); 304 group.execute(); 305 306 mG2.invoke_verify(); 307 aFailed.copyTo(Failed); 308 if (Failed[0] != 0) { 309 FoundError = true; 310 } 311 312 checkForErrors(); 313 } 314 } 315