1 /* 2 * Copyright (C) 2011 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 android.renderscript.RenderScript; 20 import android.renderscript.Allocation; 21 import android.renderscript.Element; 22 import android.renderscript.RSRuntimeException; 23 import android.util.Log; 24 25 /** 26 * Base RenderScript test class. This class provides a message handler and a 27 * convenient way to wait for compute scripts to complete their execution. 28 */ 29 public class RSBaseCompute extends RSBase { 30 RenderScript mRS; 31 protected int INPUTSIZE = 512; 32 33 @Override 34 protected void setUp() throws Exception { 35 super.setUp(); 36 mRS = RenderScript.create(mCtx); 37 mRS.setMessageHandler(mRsMessage); 38 } 39 40 @Override 41 protected void tearDown() throws Exception { 42 if (mRS != null) { 43 mRS.destroy(); 44 mRS = null; 45 } 46 super.tearDown(); 47 } 48 49 public void checkArray(float[] ref, float[] out, int height, int refStride, 50 int outStride, float ulpCount) { 51 int minStride = refStride > outStride ? outStride : refStride; 52 for (int i = 0; i < height; i++) { 53 for (int j = 0; j < minStride; j++) { 54 int refIdx = i * refStride + j; 55 int outIdx = i * outStride + j; 56 float ulp = Math.ulp(ref[refIdx]) * ulpCount; 57 assertEquals("Incorrect value @ idx = " + i + " |", 58 ref[refIdx], 59 out[outIdx], 60 ulp); 61 } 62 } 63 } 64 65 public void checkArray(int[] ref, int[] out, int height, int refStride, 66 int outStride) { 67 int minStride = refStride > outStride ? outStride : refStride; 68 for (int i = 0; i < height; i++) { 69 for (int j = 0; j < minStride; j++) { 70 int refIdx = i * refStride + j; 71 int outIdx = i * outStride + j; 72 assertEquals("Incorrect value @ idx = " + i + " |", 73 ref[refIdx], 74 out[outIdx]); 75 } 76 } 77 } 78 79 // TODO Is there a better way to do this 80 protected Element getElement(RenderScript rs, Element.DataType dataType, int size) { 81 Element element = null; 82 if (size == 1) { 83 if (dataType == Element.DataType.FLOAT_64) { 84 element = Element.F64(rs); 85 } else if (dataType == Element.DataType.FLOAT_32) { 86 element = Element.F32(rs); 87 } else if (dataType == Element.DataType.SIGNED_64) { 88 element = Element.I64(rs); 89 } else if (dataType == Element.DataType.UNSIGNED_64) { 90 element = Element.U64(rs); 91 } else if (dataType == Element.DataType.SIGNED_32) { 92 element = Element.I32(rs); 93 } else if (dataType == Element.DataType.UNSIGNED_32) { 94 element = Element.U32(rs); 95 } else if (dataType == Element.DataType.SIGNED_16) { 96 element = Element.I16(rs); 97 } else if (dataType == Element.DataType.UNSIGNED_16) { 98 element = Element.U16(rs); 99 } else if (dataType == Element.DataType.SIGNED_8) { 100 element = Element.I8(rs); 101 } else if (dataType == Element.DataType.UNSIGNED_8) { 102 element = Element.U8(rs); 103 } else { 104 android.util.Log.e("RenderscriptCTS", "Don't know how to create allocation of type" + 105 dataType.toString()); 106 } 107 } else { 108 element = Element.createVector(rs, dataType, size); 109 } 110 return element; 111 } 112 113 protected Allocation createRandomAllocation(RenderScript rs, Element.DataType dataType, 114 int size, long seed, boolean includeExtremes) { 115 Element element = getElement(rs, dataType, size); 116 Allocation alloc = Allocation.createSized(rs, element, INPUTSIZE); 117 int width = (size == 3) ? 4 : size; 118 if (dataType == Element.DataType.FLOAT_64) { 119 double[] inArray = new double[INPUTSIZE * width]; 120 // TODO The ranges for float is too small. We need to accept a wider range of values. 121 double min = -4.0 * Math.PI; 122 double max = 4.0 * Math.PI; 123 RSUtils.genRandomDoubles(seed, min, max, inArray, includeExtremes); 124 alloc.copy1DRangeFrom(0, INPUTSIZE, inArray); 125 } else if (dataType == Element.DataType.FLOAT_32) { 126 float[] inArray = new float[INPUTSIZE * width]; 127 // TODO The ranges for float is too small. We need to accept a wider range of values. 128 float min = -4.0f * (float) Math.PI; 129 float max = 4.0f * (float) Math.PI; 130 RSUtils.genRandomFloats(seed, min, max, inArray, includeExtremes); 131 alloc.copy1DRangeFrom(0, INPUTSIZE, inArray); 132 } else if (dataType == Element.DataType.SIGNED_64) { 133 long[] inArray = new long[INPUTSIZE * width]; 134 RSUtils.genRandomLongs(seed, inArray, true, 63); 135 alloc.copy1DRangeFrom(0, INPUTSIZE, inArray); 136 } else if (dataType == Element.DataType.UNSIGNED_64) { 137 long[] inArray = new long[INPUTSIZE * width]; 138 RSUtils.genRandomLongs(seed, inArray, false, 64); 139 alloc.copy1DRangeFrom(0, INPUTSIZE, inArray); 140 } else if (dataType == Element.DataType.SIGNED_32) { 141 int[] inArray = new int[INPUTSIZE * width]; 142 RSUtils.genRandomInts(seed, inArray, true, 31); 143 alloc.copy1DRangeFrom(0, INPUTSIZE, inArray); 144 } else if (dataType == Element.DataType.UNSIGNED_32) { 145 int[] inArray = new int[INPUTSIZE * width]; 146 RSUtils.genRandomInts(seed, inArray, false, 32); 147 alloc.copy1DRangeFrom(0, INPUTSIZE, inArray); 148 } else if (dataType == Element.DataType.SIGNED_16) { 149 short[] inArray = new short[INPUTSIZE * width]; 150 RSUtils.genRandomShorts(seed, inArray, true, 15); 151 alloc.copy1DRangeFrom(0, INPUTSIZE, inArray); 152 } else if (dataType == Element.DataType.UNSIGNED_16) { 153 short[] inArray = new short[INPUTSIZE * width]; 154 RSUtils.genRandomShorts(seed, inArray, false, 16); 155 alloc.copy1DRangeFrom(0, INPUTSIZE, inArray); 156 } else if (dataType == Element.DataType.SIGNED_8) { 157 byte[] inArray = new byte[INPUTSIZE * width]; 158 RSUtils.genRandomBytes(seed, inArray, true, 7); 159 alloc.copy1DRangeFrom(0, INPUTSIZE, inArray); 160 } else if (dataType == Element.DataType.UNSIGNED_8) { 161 byte[] inArray = new byte[INPUTSIZE * width]; 162 RSUtils.genRandomBytes(seed, inArray, true, 8); 163 alloc.copy1DRangeFrom(0, INPUTSIZE, inArray); 164 } else { 165 android.util.Log.e("RenderscriptCTS", "Don't know how to create allocation of type" + 166 dataType.toString()); 167 } 168 return alloc; 169 } 170 171 protected Allocation createRandomFloatAllocation(RenderScript rs, Element.DataType dataType, 172 int size, long seed, double minValue, double maxValue) { 173 Element element = getElement(rs, dataType, size); 174 Allocation alloc = Allocation.createSized(rs, element, INPUTSIZE); 175 int width = (size == 3) ? 4 : size; 176 if (dataType == Element.DataType.FLOAT_64) { 177 double[] inArray = new double[INPUTSIZE * width]; 178 RSUtils.genRandomDoubles(seed, minValue, maxValue, inArray, false); 179 alloc.copy1DRangeFrom(0, INPUTSIZE, inArray); 180 } else if (dataType == Element.DataType.FLOAT_32) { 181 float[] inArray = new float[INPUTSIZE * width]; 182 RSUtils.genRandomFloats(seed, (float) minValue, (float) maxValue, inArray, false); 183 alloc.copy1DRangeFrom(0, INPUTSIZE, inArray); 184 } else { 185 android.util.Log.e("RenderscriptCTS", 186 "Don't know how to create a random float allocation for " + 187 dataType.toString()); 188 } 189 return alloc; 190 } 191 192 protected Allocation createRandomIntegerAllocation(RenderScript rs, Element.DataType dataType, 193 int size, long seed, boolean signed, int numberOfBits) { 194 Element element = getElement(rs, dataType, size); 195 Allocation alloc = Allocation.createSized(rs, element, INPUTSIZE); 196 int width = (size == 3) ? 4 : size; 197 if (dataType == Element.DataType.SIGNED_64 || 198 dataType == Element.DataType.UNSIGNED_64) { 199 long[] inArray = new long[INPUTSIZE * width]; 200 RSUtils.genRandomLongs(seed, inArray, signed, numberOfBits); 201 alloc.copy1DRangeFrom(0, INPUTSIZE, inArray); 202 } else 203 if (dataType == Element.DataType.SIGNED_32 || 204 dataType == Element.DataType.UNSIGNED_32) { 205 int[] inArray = new int[INPUTSIZE * width]; 206 RSUtils.genRandomInts(seed, inArray, signed, numberOfBits); 207 alloc.copy1DRangeFrom(0, INPUTSIZE, inArray); 208 } else if (dataType == Element.DataType.SIGNED_16 || 209 dataType == Element.DataType.UNSIGNED_16) { 210 short[] inArray = new short[INPUTSIZE * width]; 211 RSUtils.genRandomShorts(seed, inArray, signed, numberOfBits); 212 alloc.copy1DRangeFrom(0, INPUTSIZE, inArray); 213 } else if (dataType == Element.DataType.SIGNED_8 || 214 dataType == Element.DataType.UNSIGNED_8) { 215 byte[] inArray = new byte[INPUTSIZE * width]; 216 RSUtils.genRandomBytes(seed, inArray, signed, numberOfBits); 217 alloc.copy1DRangeFrom(0, INPUTSIZE, inArray); 218 } else { 219 android.util.Log.e("RenderscriptCTS", 220 "Don't know how to create an integer allocation of type" + 221 dataType.toString()); 222 } 223 return alloc; 224 } 225 226 protected <T> void enforceOrdering(/*RenderScript rs,*/ Allocation minAlloc, Allocation maxAlloc) { 227 Element element = minAlloc.getElement(); 228 int stride = element.getVectorSize(); 229 if (stride == 3) { 230 stride = 4; 231 } 232 int size = INPUTSIZE * stride; 233 Element.DataType dataType = element.getDataType(); 234 if (dataType == Element.DataType.FLOAT_64) { 235 double[] minArray = new double[size]; 236 double[] maxArray = new double[size]; 237 minAlloc.copyTo(minArray); 238 maxAlloc.copyTo(maxArray); 239 for (int i = 0; i < size; i++) { 240 if (minArray[i] > maxArray[i]) { 241 double temp = minArray[i]; 242 minArray[i] = maxArray[i]; 243 maxArray[i] = temp; 244 } 245 } 246 minAlloc.copyFrom(minArray); 247 maxAlloc.copyFrom(maxArray); 248 } else 249 if (dataType == Element.DataType.FLOAT_32) { 250 float[] minArray = new float[size]; 251 float[] maxArray = new float[size]; 252 minAlloc.copyTo(minArray); 253 maxAlloc.copyTo(maxArray); 254 for (int i = 0; i < size; i++) { 255 if (minArray[i] > maxArray[i]) { 256 float temp = minArray[i]; 257 minArray[i] = maxArray[i]; 258 maxArray[i] = temp; 259 } 260 } 261 minAlloc.copyFrom(minArray); 262 maxAlloc.copyFrom(maxArray); 263 } else if (dataType == Element.DataType.SIGNED_64) { 264 long[] minArray = new long[size]; 265 long[] maxArray = new long[size]; 266 minAlloc.copyTo(minArray); 267 maxAlloc.copyTo(maxArray); 268 for (int i = 0; i < size; i++) { 269 if (minArray[i] > maxArray[i]) { 270 long temp = minArray[i]; 271 minArray[i] = maxArray[i]; 272 maxArray[i] = temp; 273 } 274 } 275 minAlloc.copyFrom(minArray); 276 maxAlloc.copyFrom(maxArray); 277 } else if (dataType == Element.DataType.UNSIGNED_64) { 278 long[] minArray = new long[size]; 279 long[] maxArray = new long[size]; 280 minAlloc.copyTo(minArray); 281 maxAlloc.copyTo(maxArray); 282 for (int i = 0; i < size; i++) { 283 if (RSUtils.compareUnsignedLong(minArray[i], maxArray[i]) > 0) { 284 long temp = minArray[i]; 285 minArray[i] = maxArray[i]; 286 maxArray[i] = temp; 287 } 288 } 289 minAlloc.copyFrom(minArray); 290 maxAlloc.copyFrom(maxArray); 291 } else if (dataType == Element.DataType.SIGNED_32) { 292 int[] minArray = new int[size]; 293 int[] maxArray = new int[size]; 294 minAlloc.copyTo(minArray); 295 maxAlloc.copyTo(maxArray); 296 for (int i = 0; i < size; i++) { 297 if (minArray[i] > maxArray[i]) { 298 int temp = minArray[i]; 299 minArray[i] = maxArray[i]; 300 maxArray[i] = temp; 301 } 302 } 303 minAlloc.copyFrom(minArray); 304 maxAlloc.copyFrom(maxArray); 305 } else if (dataType == Element.DataType.UNSIGNED_32) { 306 int[] minArray = new int[size]; 307 int[] maxArray = new int[size]; 308 minAlloc.copyTo(minArray); 309 maxAlloc.copyTo(maxArray); 310 for (int i = 0; i < size; i++) { 311 long min = minArray[i] &0xffffffffl; 312 long max = maxArray[i] &0xffffffffl; 313 if (min > max) { 314 minArray[i] = (int) max; 315 maxArray[i] = (int) min; 316 } 317 } 318 minAlloc.copyFrom(minArray); 319 maxAlloc.copyFrom(maxArray); 320 } else if (dataType == Element.DataType.SIGNED_16) { 321 short[] minArray = new short[size]; 322 short[] maxArray = new short[size]; 323 minAlloc.copyTo(minArray); 324 maxAlloc.copyTo(maxArray); 325 for (int i = 0; i < size; i++) { 326 if (minArray[i] > maxArray[i]) { 327 short temp = minArray[i]; 328 minArray[i] = maxArray[i]; 329 maxArray[i] = temp; 330 } 331 } 332 minAlloc.copyFrom(minArray); 333 maxAlloc.copyFrom(maxArray); 334 } else if (dataType == Element.DataType.UNSIGNED_16) { 335 short[] minArray = new short[size]; 336 short[] maxArray = new short[size]; 337 minAlloc.copyTo(minArray); 338 maxAlloc.copyTo(maxArray); 339 for (int i = 0; i < size; i++) { 340 int min = minArray[i] &0xffff; 341 int max = maxArray[i] &0xffff; 342 if (min > max) { 343 minArray[i] = (short) max; 344 maxArray[i] = (short) min; 345 } 346 } 347 minAlloc.copyFrom(minArray); 348 maxAlloc.copyFrom(maxArray); 349 } else if (dataType == Element.DataType.SIGNED_8) { 350 byte[] minArray = new byte[size]; 351 byte[] maxArray = new byte[size]; 352 minAlloc.copyTo(minArray); 353 maxAlloc.copyTo(maxArray); 354 for (int i = 0; i < size; i++) { 355 if (minArray[i] > maxArray[i]) { 356 byte temp = minArray[i]; 357 minArray[i] = maxArray[i]; 358 maxArray[i] = temp; 359 } 360 } 361 minAlloc.copyFrom(minArray); 362 maxAlloc.copyFrom(maxArray); 363 } else if (dataType == Element.DataType.UNSIGNED_8) { 364 byte[] minArray = new byte[size]; 365 byte[] maxArray = new byte[size]; 366 minAlloc.copyTo(minArray); 367 maxAlloc.copyTo(maxArray); 368 for (int i = 0; i < size; i++) { 369 int min = minArray[i] &0xff; 370 int max = maxArray[i] &0xff; 371 if (min > max) { 372 minArray[i] = (byte) max; 373 maxArray[i] = (byte) min; 374 } 375 } 376 minAlloc.copyFrom(minArray); 377 maxAlloc.copyFrom(maxArray); 378 } else { 379 android.util.Log.e("RenderscriptCTS", "Ordering not supported for " + 380 dataType.toString()); 381 } 382 } 383 384 public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException { 385 // Intentionally empty... subclass will likely define only one, but not both 386 } 387 388 public void forEach(int testId, Allocation mIn) throws RSRuntimeException { 389 // Intentionally empty... subclass will likely define only one, but not both 390 } 391 } 392