1 /*
2  * Copyright (c) 2017, NVIDIA CORPORATION.  All rights reserved.
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 #include <stdio.h>
18 #include <assert.h>
19 
20 extern int __hpf_lcpu;
21 
22 void
check_(int * res,int * exp,int * np)23 check_(int* res, int* exp, int* np)
24 {
25     int i;
26     int n = *np;
27     int tests_passed = 0;
28     int tests_failed = 0;
29 
30     for (i = 0; i < n; i++) {
31         if (exp[i] == res[i]) {
32 	    tests_passed ++;
33         } else {
34             tests_failed ++;
35 	    if( tests_failed < 100 )
36             printf(
37 	    "test number %d FAILED. res %d(%08x)  exp %d(%08x)\n",
38 	     i+1,res[i], res[i], exp[i], exp[i] );
39         }
40     }
41     if (tests_failed == 0) {
42 	    printf(
43 	"%3d tests completed. %d tests PASSED. %d tests failed.\n",
44                       n, tests_passed, tests_failed);
45     } else {
46 	printf("%3d tests completed. %d tests passed. %d tests FAILED.\n",
47                       n, tests_passed, tests_failed);
48     }
49 }
50 
51 void
check(int * res,int * exp,int * np)52 check(int* res, int* exp, int* np)
53 {
54     check_(res, exp, np);
55 }
56 
57 void
checkll_(long long * res,long long * exp,int * np)58 checkll_(long long *res, long long *exp, int *np)
59 {
60     int i;
61     int n = *np;
62     int tests_passed = 0;
63     int tests_failed = 0;
64 
65     for (i = 0; i < n; i++) {
66         if (exp[i] == res[i]) {
67 	    tests_passed ++;
68         } else {
69              tests_failed ++;
70 	    if( tests_failed < 100 )
71              printf( "test number %d FAILED. res %lld(%0llx)  exp %lld(%0llx)\n",
72 	     i+1,res[i], res[i], exp[i], exp[i] );
73         }
74     }
75     if (tests_failed == 0) {
76 	    printf(
77 	"%3d tests completed. %d tests PASSED. %d tests failed.\n",
78                       n, tests_passed, tests_failed);
79     } else {
80 	printf("%3d tests completed. %d tests passed. %d tests FAILED.\n",
81                       n, tests_passed, tests_failed);
82     }
83 }
84 
85 void
checkll(long long * res,long long * exp,int * np)86 checkll(long long *res, long long *exp, int *np)
87 {
88     checkll_(res, exp, np);
89 }
90 
91 /* maximum allowed difference in units in the last place */
92 #ifndef MAX_DIFF_ULPS
93 #define MAX_DIFF_ULPS 2
94 #endif
95 
96 void
checkf_(float * res,float * exp,int * np)97 checkf_(float* res, float* exp, int* np)
98 {
99     int i;
100     int n = *np;
101     int tests_passed = 0;
102     int tests_failed = 0;
103     int ires, iexp, diff;
104 
105     assert(sizeof(int) == 4);
106     assert(sizeof(float) == 4);
107     for (i = 0; i < n; i++) {
108 	ires = *(int *)(res + i);
109 	iexp = *(int *)(exp + i);
110 	if (ires < 0)
111 	    ires = 0x80000000 - ires;
112 	if (iexp < 0)
113 	    iexp = 0x80000000 - iexp;
114 	diff = abs(ires - iexp);
115         if (diff <= MAX_DIFF_ULPS)
116 	    tests_passed++;
117         else {
118             tests_failed++;
119 	    if (tests_failed < 100)
120 		printf("test number %d FAILED. diff in last place units: %d\n",
121 			i+1, diff);
122         }
123     }
124     if (tests_failed == 0) {
125 	printf("%3d tests completed. %d tests PASSED. %d tests failed.\n",
126                       n, tests_passed, tests_failed);
127     }
128     else {
129 	printf("%3d tests completed. %d tests passed. %d tests FAILED.\n",
130                       n, tests_passed, tests_failed);
131     }
132 }
133 
134 void
checkf(float * res,float * exp,int * np)135 checkf(float* res, float* exp, int* np)
136 {
137     checkf_(res, exp, np);
138 }
139 
140 void
checkd_(double * res,double * exp,int * np)141 checkd_(double* res, double* exp, int* np)
142 {
143     int i;
144     int n = *np;
145     int tests_passed = 0;
146     int tests_failed = 0;
147     int resh, exph, diffh;
148     unsigned int resl, expl, diffl;
149     int borrow;
150 
151     assert(sizeof(int) == 4);
152     assert(sizeof(double) == 8);
153     for (i = 0; i < n; i++) {
154 #ifdef BIG_ENDIAN
155 	resh = *(int *)(res + i);
156 	resl = *((unsigned int *)(res + i) + 1);
157 	exph = *(int *)(exp + i);
158 	expl = *((unsigned int *)(exp + i) + 1);
159 #else
160 	resl = *(unsigned int *)(res + i);
161 	resh = *((int *)(res + i) + 1);
162 	expl = *(unsigned int *)(exp + i);
163 	exph = *((int *)(exp + i) + 1);
164 #endif
165 	/* if (res < 0) res = 0x8000000000000000 - res; */
166 	if (resh < 0) {
167 	    resl = 0 - resl;
168 	    borrow = (resl != 0);
169 	    resh = 0x80000000 - resh - borrow;
170 	}
171 	/* if (exp < 0) exp = 0x8000000000000000 - exp; */
172 	if (exph < 0) {
173 	    expl = 0 - expl;
174 	    borrow = (expl != 0);
175 	    exph = 0x80000000 - exph - borrow;
176 	}
177 	/* diff = llabs(res - exp); */
178 	diffl = resl - expl;
179 	borrow = (int)((resl >> 31) - (expl >> 31)) < (int)(diffl >> 31);
180 	diffh = resh - exph - borrow;
181 	if (diffh < 0) {
182 	    diffl = -diffl;
183 	    borrow = (diffl != 0);
184 	    diffh = -diffh - borrow;
185 	}
186         if (diffh == 0 && diffl <= MAX_DIFF_ULPS)
187 	    tests_passed++;
188         else {
189             tests_failed++;
190 	    if (tests_failed < 100)
191 		printf("test number %d FAILED. diff in last place units: %d %d\n",
192 			i+1, diffh, diffl);
193         }
194     }
195     if (tests_failed == 0) {
196 	printf("%3d tests completed. %d tests PASSED. %d tests failed.\n",
197                       n, tests_passed, tests_failed);
198     }
199     else {
200 	printf("%3d tests completed. %d tests passed. %d tests FAILED.\n",
201                       n, tests_passed, tests_failed);
202     }
203 }
204 
205 void
checkd(double * res,double * exp,int * np)206 checkd(double* res, double* exp, int* np)
207 {
208     checkd_(res, exp, np);
209 }
210 
211 void
fcpyf_(float * r,float f)212 fcpyf_(float *r, float f)
213 {
214 *r = f;
215 }
216 
217 void
fcpyf(float * r,float f)218 fcpyf(float *r, float f)
219 {
220     fcpyf_(r, f);
221 }
222 
223 void
fcpyi_(int * r,int f)224 fcpyi_(int *r, int f)
225 {
226     *r = f;
227 }
228 
229 void
fcpyi(int * r,int f)230 fcpyi(int *r, int f)
231 {
232     fcpyi_(r, f);
233 }
234 
235 #if defined(WINNT) || defined(WIN32)
236 void
CHECK(int * res,int * exp,int * np)237 __stdcall CHECK(int* res, int* exp, int* np)
238 {
239     check_(res, exp, np);
240 }
241 
242 void
CHECKF(float * res,float * exp,int * np)243 __stdcall CHECKF(float* res, float* exp, int* np)
244 {
245     checkf_(res, exp, np);
246 }
247 
248 void
CHECKD(double * res,double * exp,int * np)249 __stdcall CHECKD(double* res, double* exp, int* np)
250 {
251     checkd_(res, exp, np);
252 }
253 
254 void
CHECKLL(long long * res,long long * exp,int * np)255 __stdcall CHECKLL(long long *res, long long *exp, int *np)
256 {
257     checkll_(res, exp, np);
258 }
259 
260 void
FCPYF(float * r,float f)261 __stdcall FCPYF(float *r, float f)
262 {
263     fcpyf_(r, f);
264 }
265 
266 void
FCPYI(int * r,int f)267 __stdcall FCPYI(int *r, int f)
268 {
269     fcpyi_(r, f);
270 }
271 #endif
272