1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14 15package com.android.rs.test; 16 17import android.content.Context; 18import android.renderscript.Allocation; 19import android.renderscript.Element; 20import android.renderscript.RenderScript; 21import android.renderscript.ScriptGroup; 22import android.renderscript.Type; 23import android.util.Log; 24 25public class UT_script_group2_gatherscatter extends UnitTest { 26 private static final int ARRAY_SIZE = 256; 27 28 private static final String TAG = "ScriptGroup2 (GatherScatter)"; 29 30 int[] mArray; 31 32 protected UT_script_group2_gatherscatter(RSTestCore rstc, Context ctx) { 33 super(rstc, TAG, ctx); 34 } 35 36 public void initializeGlobals(RenderScript RS, ScriptC_addup s) { 37 mArray = new int[ARRAY_SIZE * 4]; 38 39 for (int i = 0; i < ARRAY_SIZE; i++) { 40 mArray[i * 4] = i * 7; 41 mArray[i * 4 + 1] = i * 7 + 1; 42 mArray[i * 4 + 2] = i * 7 + 2; 43 mArray[i * 4 + 3] = i * 7 + 3; 44 } 45 } 46 47 // This test tests ScriptGroup2 API for handling gather scatter operations 48 // on global allocations that are passed across kernels in a script group. 49 // The test sums up all elements in the input int4 array of size ARRAY_SIZE. 50 // To do so, it adds up the second half of the array to its first half using 51 // kernel function add() in addsup.rs, and then repeatedly applies the same 52 // kernel function to the shrinking result arrays until the result is a 53 // single int4 value. 54 // These steps are created as a script group by repeatedly adding the 55 // same kernel function, with the input of one kernel being the output of 56 // the previous added kernel function. 57 // Since the kernel function relies on rsGetElementAt to access the counterpart 58 // of the current element in the second half of the array, the compiler cannot 59 // fuse it with the other kernel that it dependes on. 60 // This test verifies an ScriptGroup2 implementation correctly handles such 61 // a case. 62 public void run() { 63 RenderScript pRS = RenderScript.create(mCtx); 64 ScriptC_addup s = new ScriptC_addup(pRS); 65 pRS.setMessageHandler(mRsMessage); 66 initializeGlobals(pRS, s); 67 68 Allocation input = Allocation.createSized(pRS, Element.I32_4(pRS), ARRAY_SIZE); 69 input.copyFrom(mArray); 70 71 ScriptGroup.Builder2 builder = new ScriptGroup.Builder2(pRS); 72 73 ScriptGroup.Input unbound = builder.addInput(); 74 75 ScriptGroup.Closure c = null; 76 ScriptGroup.Future f = null; 77 int stride; 78 for (stride = ARRAY_SIZE / 2; stride >= 1; stride >>= 1) { 79 ScriptGroup.Binding binding; 80 if (f == null) { 81 binding = new ScriptGroup.Binding(s.getFieldID_a_in(), unbound); 82 } else { 83 binding = new ScriptGroup.Binding(s.getFieldID_a_in(), f); 84 } 85 c = builder.addKernel(s.getKernelID_add(), 86 Type.createX(pRS, Element.I32_4(pRS), stride), 87 new ScriptGroup.Binding(s.getFieldID_reduction_stride(), stride), 88 binding); 89 f = c.getReturn(); 90 } 91 92 ScriptGroup group = builder.create("Summation", c.getReturn()); 93 94 if (c == null) { 95 return; 96 } 97 98 int[] a = new int[4]; 99 ((Allocation) group.execute(input)[0]).copyTo(a); 100 101 pRS.finish(); 102 103 group.destroy(); 104 input.destroy(); 105 s.destroy(); 106 pRS.destroy(); 107 108 boolean failed = false; 109 for (int i = 0; i < 4; i++) { 110 if (failed == false && 111 a[i] != ARRAY_SIZE * (ARRAY_SIZE - 1) * 7 / 2 + i * ARRAY_SIZE) { 112 Log.e(TAG, "a[" + i + "]=" + a[i] + ", should be " + 113 (ARRAY_SIZE * (ARRAY_SIZE - 1) * 7 / 2 + i * ARRAY_SIZE)); 114 failed = true; 115 } 116 } 117 if (failed) { 118 failTest(); 119 return; 120 } 121 passTest(); 122 } 123} 124