Skip to content

Commit 31f18ba

Browse files
committed
New test on integral output
1 parent 1119591 commit 31f18ba

1 file changed

Lines changed: 358 additions & 0 deletions

File tree

tests/test_integral_output.c

Lines changed: 358 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,358 @@
1+
/*
2+
* Test integral output dtypes: int64, int32, bool outputs.
3+
*
4+
* On Windows (clang-cl), miniexpr has been reported to produce
5+
* wrong results when the output dtype is integral.
6+
*/
7+
8+
#include "../src/miniexpr.h"
9+
#include "minctest.h"
10+
#include <stdio.h>
11+
#include <stdlib.h>
12+
#include <stdint.h>
13+
#include <math.h>
14+
15+
#define N 20
16+
17+
static int failures = 0;
18+
19+
/* ------------------------------------------------------------------ */
20+
/* Test 1: int64 + int64 -> int64 output (basic arithmetic) */
21+
/* ------------------------------------------------------------------ */
22+
static void test_int64_add_int64(void) {
23+
printf("Test: int64 + int64 -> int64 output\n");
24+
int prev = failures;
25+
26+
int64_t a[N], b[N], result[N];
27+
for (int i = 0; i < N; i++) {
28+
a[i] = (int64_t)(i + 1);
29+
b[i] = (int64_t)(i * 2);
30+
}
31+
32+
me_variable vars[] = {{"a", ME_INT64}, {"b", ME_INT64}};
33+
int err;
34+
me_expr *expr = NULL;
35+
int rc = me_compile("a + b", vars, 2, ME_INT64, &err, &expr);
36+
if (rc != ME_COMPILE_SUCCESS) {
37+
printf(" FAIL: compile error %d at pos %d\n", rc, err);
38+
failures++;
39+
return;
40+
}
41+
42+
const void *ptrs[] = {a, b};
43+
ME_EVAL_CHECK(expr, ptrs, 2, result, N);
44+
45+
for (int i = 0; i < N; i++) {
46+
int64_t expected = a[i] + b[i];
47+
if (result[i] != expected) {
48+
printf(" FAIL [%d]: expected %lld, got %lld\n", i,
49+
(long long)expected, (long long)result[i]);
50+
failures++;
51+
}
52+
}
53+
54+
me_free(expr);
55+
printf(" %s\n", failures == prev ? "PASS" : "FAILED");
56+
}
57+
58+
/* ------------------------------------------------------------------ */
59+
/* Test 2: int64 * int64 -> int64 output */
60+
/* ------------------------------------------------------------------ */
61+
static void test_int64_mul_int64(void) {
62+
printf("Test: int64 * int64 -> int64 output\n");
63+
int prev = failures;
64+
65+
int64_t a[N], b[N], result[N];
66+
for (int i = 0; i < N; i++) {
67+
a[i] = (int64_t)(i + 1);
68+
b[i] = (int64_t)(i + 3);
69+
}
70+
71+
me_variable vars[] = {{"a", ME_INT64}, {"b", ME_INT64}};
72+
int err;
73+
me_expr *expr = NULL;
74+
int rc = me_compile("a * b", vars, 2, ME_INT64, &err, &expr);
75+
if (rc != ME_COMPILE_SUCCESS) {
76+
printf(" FAIL: compile error %d at pos %d\n", rc, err);
77+
failures++;
78+
return;
79+
}
80+
81+
const void *ptrs[] = {a, b};
82+
ME_EVAL_CHECK(expr, ptrs, 2, result, N);
83+
84+
for (int i = 0; i < N; i++) {
85+
int64_t expected = a[i] * b[i];
86+
if (result[i] != expected) {
87+
printf(" FAIL [%d]: expected %lld, got %lld\n", i,
88+
(long long)expected, (long long)result[i]);
89+
failures++;
90+
}
91+
}
92+
93+
me_free(expr);
94+
printf(" %s\n", failures == prev ? "PASS" : "FAILED");
95+
}
96+
97+
/* ------------------------------------------------------------------ */
98+
/* Test 3: int32 + int32 -> int32 output */
99+
/* ------------------------------------------------------------------ */
100+
static void test_int32_add_int32(void) {
101+
printf("Test: int32 + int32 -> int32 output\n");
102+
int prev = failures;
103+
104+
int32_t a[N], b[N], result[N];
105+
for (int i = 0; i < N; i++) {
106+
a[i] = (int32_t)(i + 1);
107+
b[i] = (int32_t)(i * 3);
108+
}
109+
110+
me_variable vars[] = {{"a", ME_INT32}, {"b", ME_INT32}};
111+
int err;
112+
me_expr *expr = NULL;
113+
int rc = me_compile("a + b", vars, 2, ME_INT32, &err, &expr);
114+
if (rc != ME_COMPILE_SUCCESS) {
115+
printf(" FAIL: compile error %d at pos %d\n", rc, err);
116+
failures++;
117+
return;
118+
}
119+
120+
const void *ptrs[] = {a, b};
121+
ME_EVAL_CHECK(expr, ptrs, 2, result, N);
122+
123+
for (int i = 0; i < N; i++) {
124+
int32_t expected = a[i] + b[i];
125+
if (result[i] != expected) {
126+
printf(" FAIL [%d]: expected %d, got %d\n", i, expected, result[i]);
127+
failures++;
128+
}
129+
}
130+
131+
me_free(expr);
132+
printf(" %s\n", failures == prev ? "PASS" : "FAILED");
133+
}
134+
135+
/* ------------------------------------------------------------------ */
136+
/* Test 4: float64 expression -> int64 output (truncation) */
137+
/* ------------------------------------------------------------------ */
138+
static void test_float64_to_int64(void) {
139+
printf("Test: float64 expr -> int64 output (truncation)\n");
140+
int prev = failures;
141+
142+
double a[N];
143+
int64_t result[N];
144+
for (int i = 0; i < N; i++) {
145+
a[i] = (double)i + 0.7;
146+
}
147+
148+
me_variable vars[] = {{"a", ME_FLOAT64}};
149+
int err;
150+
me_expr *expr = NULL;
151+
int rc = me_compile("a + 0.1", vars, 1, ME_INT64, &err, &expr);
152+
if (rc != ME_COMPILE_SUCCESS) {
153+
printf(" FAIL: compile error %d at pos %d\n", rc, err);
154+
failures++;
155+
return;
156+
}
157+
158+
const void *ptrs[] = {a};
159+
ME_EVAL_CHECK(expr, ptrs, 1, result, N);
160+
161+
for (int i = 0; i < N; i++) {
162+
int64_t expected = (int64_t)(a[i] + 0.1);
163+
if (result[i] != expected) {
164+
printf(" FAIL [%d]: expected %lld, got %lld\n", i,
165+
(long long)expected, (long long)result[i]);
166+
failures++;
167+
}
168+
}
169+
170+
me_free(expr);
171+
printf(" %s\n", failures == prev ? "PASS" : "FAILED");
172+
}
173+
174+
/* ------------------------------------------------------------------ */
175+
/* Test 5: float32 -> bool output (nonzero check) */
176+
/* ------------------------------------------------------------------ */
177+
static void test_float32_to_bool(void) {
178+
printf("Test: float32 -> bool output (x != 0)\n");
179+
int prev = failures;
180+
181+
float a[N];
182+
int8_t result[N]; /* ME_BOOL is stored as int8 */
183+
for (int i = 0; i < N; i++) {
184+
a[i] = (i % 3 == 0) ? 0.0f : (float)(i + 1);
185+
}
186+
187+
me_variable vars[] = {{"a", ME_FLOAT32}};
188+
int err;
189+
me_expr *expr = NULL;
190+
int rc = me_compile("a != 0", vars, 1, ME_BOOL, &err, &expr);
191+
if (rc != ME_COMPILE_SUCCESS) {
192+
printf(" FAIL: compile error %d at pos %d\n", rc, err);
193+
failures++;
194+
return;
195+
}
196+
197+
const void *ptrs[] = {a};
198+
ME_EVAL_CHECK(expr, ptrs, 1, result, N);
199+
200+
for (int i = 0; i < N; i++) {
201+
int8_t expected = (a[i] != 0.0f) ? 1 : 0;
202+
if (result[i] != expected) {
203+
printf(" FAIL [%d]: expected %d, got %d (a=%.1f)\n",
204+
i, expected, result[i], a[i]);
205+
failures++;
206+
}
207+
}
208+
209+
me_free(expr);
210+
printf(" %s\n", failures == prev ? "PASS" : "FAILED");
211+
}
212+
213+
/* ------------------------------------------------------------------ */
214+
/* Test 6: int64 arithmetic -> int64 via me_eval_nd */
215+
/* ------------------------------------------------------------------ */
216+
static void test_int64_add_nd(void) {
217+
printf("Test: int64 + int64 -> int64 via me_eval_nd\n");
218+
int prev = failures;
219+
220+
const int rows = 4, cols = 5;
221+
const int total = rows * cols;
222+
int64_t a[20], b[20], result[20];
223+
for (int i = 0; i < total; i++) {
224+
a[i] = (int64_t)(i + 1);
225+
b[i] = (int64_t)(i * 2);
226+
}
227+
228+
int64_t shape[] = {rows, cols};
229+
int32_t chunks[] = {rows, cols};
230+
int32_t blocks[] = {2, 5};
231+
232+
me_variable vars[] = {{"a", ME_INT64}, {"b", ME_INT64}};
233+
int err;
234+
me_expr *expr = NULL;
235+
int rc = me_compile_nd("a + b", vars, 2, ME_INT64, 2,
236+
shape, chunks, blocks, &err, &expr);
237+
if (rc != ME_COMPILE_SUCCESS) {
238+
printf(" FAIL: compile error %d at pos %d\n", rc, err);
239+
failures++;
240+
return;
241+
}
242+
243+
const void *ptrs[] = {a, b};
244+
int block_nitems = blocks[0] * blocks[1];
245+
rc = me_eval_nd(expr, ptrs, 2, result, block_nitems, 0, 0, NULL);
246+
if (rc != ME_EVAL_SUCCESS) {
247+
printf(" FAIL: me_eval_nd returned %d\n", rc);
248+
failures++;
249+
me_free(expr);
250+
return;
251+
}
252+
253+
for (int i = 0; i < block_nitems; i++) {
254+
int64_t expected = a[i] + b[i];
255+
if (result[i] != expected) {
256+
printf(" FAIL [%d]: expected %lld, got %lld\n", i,
257+
(long long)expected, (long long)result[i]);
258+
failures++;
259+
}
260+
}
261+
262+
me_free(expr);
263+
printf(" %s\n", failures == prev ? "PASS" : "FAILED");
264+
}
265+
266+
/* ------------------------------------------------------------------ */
267+
/* Test 7: int64 expression with constant -> int64 output */
268+
/* ------------------------------------------------------------------ */
269+
static void test_int64_expr_with_constant(void) {
270+
printf("Test: int64 * 3 + 1 -> int64 output\n");
271+
int prev = failures;
272+
273+
int64_t a[N], result[N];
274+
for (int i = 0; i < N; i++) {
275+
a[i] = (int64_t)(i + 1);
276+
}
277+
278+
me_variable vars[] = {{"a", ME_INT64}};
279+
int err;
280+
me_expr *expr = NULL;
281+
int rc = me_compile("a * 3 + 1", vars, 1, ME_INT64, &err, &expr);
282+
if (rc != ME_COMPILE_SUCCESS) {
283+
printf(" FAIL: compile error %d at pos %d\n", rc, err);
284+
failures++;
285+
return;
286+
}
287+
288+
const void *ptrs[] = {a};
289+
ME_EVAL_CHECK(expr, ptrs, 1, result, N);
290+
291+
for (int i = 0; i < N; i++) {
292+
int64_t expected = a[i] * 3 + 1;
293+
if (result[i] != expected) {
294+
printf(" FAIL [%d]: expected %lld, got %lld\n", i,
295+
(long long)expected, (long long)result[i]);
296+
failures++;
297+
}
298+
}
299+
300+
me_free(expr);
301+
printf(" %s\n", failures == prev ? "PASS" : "FAILED");
302+
}
303+
304+
/* ------------------------------------------------------------------ */
305+
/* Test 8: int64 comparison -> bool output */
306+
/* ------------------------------------------------------------------ */
307+
static void test_int64_comparison_to_bool(void) {
308+
printf("Test: int64 > 10 -> bool output\n");
309+
int prev = failures;
310+
311+
int64_t a[N];
312+
int8_t result[N];
313+
for (int i = 0; i < N; i++) {
314+
a[i] = (int64_t)(i + 1);
315+
}
316+
317+
me_variable vars[] = {{"a", ME_INT64}};
318+
int err;
319+
me_expr *expr = NULL;
320+
int rc = me_compile("a > 10", vars, 1, ME_BOOL, &err, &expr);
321+
if (rc != ME_COMPILE_SUCCESS) {
322+
printf(" FAIL: compile error %d at pos %d\n", rc, err);
323+
failures++;
324+
return;
325+
}
326+
327+
const void *ptrs[] = {a};
328+
ME_EVAL_CHECK(expr, ptrs, 1, result, N);
329+
330+
for (int i = 0; i < N; i++) {
331+
int8_t expected = (a[i] > 10) ? 1 : 0;
332+
if (result[i] != expected) {
333+
printf(" FAIL [%d]: expected %d, got %d (a=%lld)\n",
334+
i, expected, result[i], (long long)a[i]);
335+
failures++;
336+
}
337+
}
338+
339+
me_free(expr);
340+
printf(" %s\n", failures == prev ? "PASS" : "FAILED");
341+
}
342+
343+
int main(void) {
344+
printf("=== Integral output dtype tests ===\n\n");
345+
346+
test_int64_add_int64();
347+
test_int64_mul_int64();
348+
test_int32_add_int32();
349+
test_float64_to_int64();
350+
test_float32_to_bool();
351+
test_int64_add_nd();
352+
test_int64_expr_with_constant();
353+
test_int64_comparison_to_bool();
354+
355+
printf("\n=== %s: %d failure(s) ===\n",
356+
failures == 0 ? "ALL PASSED" : "FAILED", failures);
357+
return failures == 0 ? 0 : 1;
358+
}

0 commit comments

Comments
 (0)