1// This file is automatically generated from
2// frameworks/rs/tests/java_api/RSUnitTests/RSUnitTests.py
3/*
4 * Copyright (C) 2017 The Android Open Source Project
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 *      http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19#include "shared.rsh"
20
21// Has a subset of the kernels from reduce.rs.
22//
23// This test case places the pragmas after the functions (backward
24// reference), and the other test case places the pragmas before the
25// functions (forward reference).
26
27float negInf, posInf;
28
29/////////////////////////////////////////////////////////////////////////
30
31static void aiAccum(int *accum, int val) { *accum += val; }
32
33#pragma rs reduce(addint) \
34  accumulator(aiAccum)
35
36/////////////////////////////////////////////////////////////////////////
37
38typedef struct {
39  float val;
40  int idx;
41} IndexedVal;
42
43typedef struct {
44  IndexedVal min, max;
45} MinAndMax;
46
47static void fMMInit(MinAndMax *accum) {
48  accum->min.val = posInf;
49  accum->min.idx = -1;
50  accum->max.val = negInf;
51  accum->max.idx = -1;
52}
53
54static void fMMAccumulator(MinAndMax *accum, float in, int x) {
55  IndexedVal me;
56  me.val = in;
57  me.idx = x;
58
59  if (me.val <= accum->min.val)
60    accum->min = me;
61  if (me.val >= accum->max.val)
62    accum->max = me;
63}
64
65static void fMMCombiner(MinAndMax *accum,
66                        const MinAndMax *val) {
67  if ((accum->min.idx < 0) || (val->min.val < accum->min.val))
68    accum->min = val->min;
69  if ((accum->max.idx < 0) || (val->max.val > accum->max.val))
70    accum->max = val->max;
71}
72
73static void fMMOutConverter(int2 *result,
74                            const MinAndMax *val) {
75  result->x = val->min.idx;
76  result->y = val->max.idx;
77}
78
79#pragma rs reduce(findMinAndMax) \
80  initializer(fMMInit) accumulator(fMMAccumulator) \
81  combiner(fMMCombiner) outconverter(fMMOutConverter)
82
83/////////////////////////////////////////////////////////////////////////
84
85static void fzInit(int *accumIdx) { *accumIdx = -1; }
86
87static void fzAccum(int *accumIdx,
88                    int inVal, int x /* special arg */) {
89  if (inVal==0) *accumIdx = x;
90}
91
92static void fzCombine(int *accumIdx, const int *accumIdx2) {
93  if (*accumIdx2 >= 0) *accumIdx = *accumIdx2;
94}
95
96#pragma rs reduce(fz) \
97  initializer(fzInit) \
98  accumulator(fzAccum) combiner(fzCombine)
99
100/////////////////////////////////////////////////////////////////////////
101
102static void fz2Init(int2 *accum) { accum->x = accum->y = -1; }
103
104static void fz2Accum(int2 *accum,
105                     int inVal,
106                     int x /* special arg */,
107                     int y /* special arg */) {
108  if (inVal==0) {
109    accum->x = x;
110    accum->y = y;
111  }
112}
113
114static void fz2Combine(int2 *accum, const int2 *accum2) {
115  if (accum2->x >= 0) *accum = *accum2;
116}
117
118#pragma rs reduce(fz2) \
119  initializer(fz2Init) \
120  accumulator(fz2Accum) combiner(fz2Combine)
121
122/////////////////////////////////////////////////////////////////////////
123
124static void fz3Init(int3 *accum) { accum->x = accum->y = accum->z = -1; }
125
126static void fz3Accum(int3 *accum,
127                     int inVal,
128                     int x /* special arg */,
129                     int y /* special arg */,
130                     int z /* special arg */) {
131  if (inVal==0) {
132    accum->x = x;
133    accum->y = y;
134    accum->z = z;
135  }
136}
137
138static void fz3Combine(int3 *accum, const int3 *accum2) {
139  if (accum2->x >= 0) *accum = *accum2;
140}
141
142#pragma rs reduce(fz3) \
143  initializer(fz3Init) \
144  accumulator(fz3Accum) combiner(fz3Combine)
145
146/////////////////////////////////////////////////////////////////////////
147
148#define BUCKETS 256
149typedef uint32_t Histogram[BUCKETS];
150
151static void hsgAccum(Histogram *h, uchar in) { ++(*h)[in]; }
152
153static void hsgCombine(Histogram *accum, const Histogram *addend) {
154  for (int i = 0; i < BUCKETS; ++i)
155    (*accum)[i] += (*addend)[i];
156}
157
158#pragma rs reduce(histogram) \
159  accumulator(hsgAccum) combiner(hsgCombine)
160
161static void modeOutConvert(int2 *result, const Histogram *h) {
162  uint32_t mode = 0;
163  for (int i = 1; i < BUCKETS; ++i)
164    if ((*h)[i] > (*h)[mode]) mode = i;
165  result->x = mode;
166  result->y = (*h)[mode];
167}
168
169#pragma rs reduce(mode) \
170  accumulator(hsgAccum) combiner(hsgCombine) \
171  outconverter(modeOutConvert)
172