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