Home | History | Annotate | Download | only in test
      1 #include "shared.rsh"
      2 
      3 // Same as reduce_backward.rs, except this test case places the
      4 // pragmas before the functions (forward reference), and the other
      5 // test case places the pragmas after the functions (backward
      6 // reference).
      7 
      8 float negInf, posInf;
      9 
     10 /////////////////////////////////////////////////////////////////////////
     11 
     12 #pragma rs reduce(addint) \
     13   accumulator(aiAccum)
     14 
     15 static void aiAccum(int *accum, int val) { *accum += val; }
     16 
     17 /////////////////////////////////////////////////////////////////////////
     18 
     19 #pragma rs reduce(findMinAndMax) \
     20   initializer(fMMInit) accumulator(fMMAccumulator) \
     21   combiner(fMMCombiner) outconverter(fMMOutConverter)
     22 
     23 typedef struct {
     24   float val;
     25   int idx;
     26 } IndexedVal;
     27 
     28 typedef struct {
     29   IndexedVal min, max;
     30 } MinAndMax;
     31 
     32 static void fMMInit(MinAndMax *accum) {
     33   accum->min.val = posInf;
     34   accum->min.idx = -1;
     35   accum->max.val = negInf;
     36   accum->max.idx = -1;
     37 }
     38 
     39 static void fMMAccumulator(MinAndMax *accum, float in, int x) {
     40   IndexedVal me;
     41   me.val = in;
     42   me.idx = x;
     43 
     44   if (me.val < accum->min.val)
     45     accum->min = me;
     46   if (me.val > accum->max.val)
     47     accum->max = me;
     48 }
     49 
     50 static void fMMCombiner(MinAndMax *accum,
     51                         const MinAndMax *val) {
     52   if (val->min.val < accum->min.val)
     53     accum->min = val->min;
     54   if (val->max.val > accum->max.val)
     55     accum->max = val->max;
     56 }
     57 
     58 static void fMMOutConverter(int2 *result,
     59                             const MinAndMax *val) {
     60   result->x = val->min.idx;
     61   result->y = val->max.idx;
     62 }
     63 
     64 /////////////////////////////////////////////////////////////////////////
     65 
     66 #pragma rs reduce(fz) \
     67   initializer(fzInit) \
     68   accumulator(fzAccum) combiner(fzCombine)
     69 
     70 static void fzInit(int *accumIdx) { *accumIdx = -1; }
     71 
     72 static void fzAccum(int *accumIdx,
     73                     int inVal, int x /* special arg */) {
     74   if (inVal==0) *accumIdx = x;
     75 }
     76 
     77 static void fzCombine(int *accumIdx, const int *accumIdx2) {
     78   if (*accumIdx2 >= 0) *accumIdx = *accumIdx2;
     79 }
     80 
     81 /////////////////////////////////////////////////////////////////////////
     82 
     83 #pragma rs reduce(fz2) \
     84   initializer(fz2Init) \
     85   accumulator(fz2Accum) combiner(fz2Combine)
     86 
     87 static void fz2Init(int2 *accum) { accum->x = accum->y = -1; }
     88 
     89 static void fz2Accum(int2 *accum,
     90                      int inVal,
     91                      int x /* special arg */,
     92                      int y /* special arg */) {
     93   if (inVal==0) {
     94     accum->x = x;
     95     accum->y = y;
     96   }
     97 }
     98 
     99 static void fz2Combine(int2 *accum, const int2 *accum2) {
    100   if (accum2->x >= 0) *accum = *accum2;
    101 }
    102 
    103 /////////////////////////////////////////////////////////////////////////
    104 
    105 #pragma rs reduce(fz3) \
    106   initializer(fz3Init) \
    107   accumulator(fz3Accum) combiner(fz3Combine)
    108 
    109 static void fz3Init(int3 *accum) { accum->x = accum->y = accum->z = -1; }
    110 
    111 static void fz3Accum(int3 *accum,
    112                      int inVal,
    113                      int x /* special arg */,
    114                      int y /* special arg */,
    115                      int z /* special arg */) {
    116   if (inVal==0) {
    117     accum->x = x;
    118     accum->y = y;
    119     accum->z = z;
    120   }
    121 }
    122 
    123 static void fz3Combine(int3 *accum, const int3 *accum2) {
    124   if (accum->x >= 0) *accum = *accum2;
    125 }
    126 
    127 /////////////////////////////////////////////////////////////////////////
    128 
    129 #pragma rs reduce(histogram) \
    130   accumulator(hsgAccum) combiner(hsgCombine)
    131 
    132 #define BUCKETS 256
    133 typedef uint32_t Histogram[BUCKETS];
    134 
    135 static void hsgAccum(Histogram *h, uchar in) { ++(*h)[in]; }
    136 
    137 static void hsgCombine(Histogram *accum, const Histogram *addend) {
    138   for (int i = 0; i < BUCKETS; ++i)
    139     (*accum)[i] += (*addend)[i];
    140 }
    141 
    142 #pragma rs reduce(mode) \
    143   accumulator(hsgAccum) combiner(hsgCombine) \
    144   outconverter(modeOutConvert)
    145 
    146 static void modeOutConvert(int2 *result, const Histogram *h) {
    147   uint32_t mode = 0;
    148   for (int i = 1; i < BUCKETS; ++i)
    149     if ((*h)[i] > (*h)[mode]) mode = i;
    150   result->x = mode;
    151   result->y = (*h)[mode];
    152 }
    153