diff options
| -rw-r--r-- | docs/cspan_api.md | 15 | ||||
| -rw-r--r-- | include/stc/cspan.h | 164 | ||||
| -rw-r--r-- | misc/benchmarks/various/cspan_bench.c | 12 | ||||
| -rw-r--r-- | misc/benchmarks/various/string_bench_STC.cpp | 5 | ||||
| -rw-r--r-- | misc/examples/multidim.c | 2 | ||||
| -rw-r--r-- | misc/tests/cspan_test.c | 10 |
6 files changed, 117 insertions, 91 deletions
diff --git a/docs/cspan_api.md b/docs/cspan_api.md index c78bb8a0..58b06af0 100644 --- a/docs/cspan_api.md +++ b/docs/cspan_api.md @@ -22,14 +22,14 @@ using_cspan4(S, ValueType); // define span types S, S2, S3, S4 with ## Methods All functions are type-safe. Note that the span argument itself is generally not side-effect safe, -i.e., it may be expanded multiple times. However, all integer arguments are safe, e.g. +i.e., it may be expanded multiple times. However, all index arguments are safe, e.g. `cspan_at(&ms3, i++, j++, k++)` is allowed. If the number of arguments does not match the span rank, a compile error is issued. Runtime bounds checks are enabled by default (define `STC_NDEBUG` or `NDEBUG` to disable). ```c SpanType cspan_init(T SpanType, {v1, v2, ...}); // make a 1-d cspan from values SpanType cspan_from(STCContainer* cnt); // make a 1-d cspan from compatible STC container SpanType cspan_from_array(ValueType array[]); // make a 1-d cspan from C array -SpanTypeN cspan_md(ValueType* data, intptr_t xdim, ...); // make a multi-dimensional cspan +SpanTypeN cspan_md(char order, ValueType* data, d1, d2, ...); // make a multi-dim cspan. order: 'C' or 'F' (Fortran) intptr_t cspan_size(const SpanTypeN* self); // return number of elements intptr_t cspan_rank(const SpanTypeN* self); // dimensions; compile time constant @@ -42,6 +42,9 @@ ValueType* cspan_back(const SpanTypeN* self); // general index slicing to create a subspan. // {i} reduces rank. {i,c_END} slice to end. {c_ALL} use the full extent. SpanTypeR cspan_slice(T SpanTypeR, const SpanTypeN* self, {x0,x1}, {y0,y1}.., {N0,N1}); + + // transpose the md span (inverse axes). no changes to the underlying array. +void cspan_transpose(const SpanTypeN* self); // create a subspan of lower rank. Like e.g. cspan_slice(Span2, &ms4, {x}, {y}, {c_ALL}, {c_ALL}); SpanType cspan_submd2(const SpanType2* self, intptr_t x); // return a 1d subspan from a 2d span. @@ -50,8 +53,8 @@ SpanTypeN cspan_submd4(const SpanType4* self, intptr_t x, ...); // numbe // create a subspan of same rank. Like e.g. cspan_slice(Span3, &ms3, {off,off+count}, {c_ALL}, {c_ALL}); SpanType cspan_subspan(const SpanType* self, intptr_t offset, intptr_t count); -SpanType2 cspan_subspan2(const SpanType2 self, intptr_t offset, intptr_t count); -SpanType3 cspan_subspan3(const SpanType3 self, intptr_t offset, intptr_t count); +SpanType2 cspan_subspan2(const SpanType2* self, intptr_t offset, intptr_t count); +SpanType3 cspan_subspan3(const SpanType3* self, intptr_t offset, intptr_t count); SpanTypeN_iter SpanType_begin(const SpanTypeN* self); SpanTypeN_iter SpanType_end(const SpanTypeN* self); @@ -99,7 +102,7 @@ using_cspan3(myspan, int); // define myspan, myspan2, myspan3. int main() { int arr[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24}; - myspan3 ms3 = cspan_md(arr, 2, 3, 4); + myspan3 ms3 = cspan_md('C', arr, 2, 3, 4); // C-order, i.e. row-major. myspan3 ss3 = cspan_slice(myspan3, &ms3, {c_ALL}, {1,3}, {2,c_END}); myspan2 ss2 = cspan_submd3(&ss3, 1); @@ -148,7 +151,7 @@ int main() Span span = c_init(Span, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}); // create a 3d cspan: - Span3 span3 = cspan_md(span.data, 2, 4, 3); + Span3 span3 = cspan_md('C', span.data, 2, 4, 3); // reduce rank: (i.e. span3[1]) Span2 span2 = cspan_submd3(&span3, 1); diff --git a/include/stc/cspan.h b/include/stc/cspan.h index d7a72267..35f5029f 100644 --- a/include/stc/cspan.h +++ b/include/stc/cspan.h @@ -30,7 +30,7 @@ using_cspan(Intspan, int, 1); int demo1() { float raw[4*5]; - Span2f ms = cspan_md(raw, 4, 5); + Span2f ms = cspan_md('C', raw, 4, 5); for (int i=0; i<ms.shape[0]; i++) for (int j=0; j<ms.shape[1]; j++) @@ -72,7 +72,7 @@ int demo2() { typedef struct { \ Self##_value *data; \ int32_t shape[RANK]; \ - cspan_idx##RANK stride; \ + cspan_tup##RANK stride; \ } Self; \ \ typedef struct { Self##_value *ref; int32_t pos[RANK]; const Self *_s; } Self##_iter; \ @@ -96,27 +96,34 @@ int demo2() { return it; \ } \ STC_INLINE void Self##_next(Self##_iter* it) { \ - it->ref += _cspan_next##RANK(RANK, it->pos, it->_s->shape, it->_s->stride.d); \ - if (it->pos[0] == it->_s->shape[0]) it->ref = NULL; \ + static const struct { int8_t i, j, inc; } t[2] = {{RANK - 1, 0, -1}, {0, RANK - 1, 1}}; \ + const int order = (it->_s->stride.d[0] < it->_s->stride.d[RANK - 1]); /* 0='C', 1='F' */ \ + it->ref += _cspan_next##RANK(it->pos, it->_s->shape, it->_s->stride.d, RANK, t[order].i, t[order].inc); \ + if (it->pos[t[order].j] == it->_s->shape[t[order].j]) \ + it->ref = NULL; \ } \ struct stc_nostruct #define using_cspan2(Self, T) using_cspan_3(Self, T, 1); using_cspan_3(Self##2, T, 2) #define using_cspan3(Self, T) using_cspan2(Self, T); using_cspan_3(Self##3, T, 3) #define using_cspan4(Self, T) using_cspan3(Self, T); using_cspan_3(Self##4, T, 4) -typedef struct { int32_t d[1]; } cspan_idx1; -typedef struct { int32_t d[2]; } cspan_idx2; -typedef struct { int32_t d[3]; } cspan_idx3; -typedef struct { int32_t d[4]; } cspan_idx4; -typedef struct { int32_t d[5]; } cspan_idx5; -typedef struct { int32_t d[6]; } cspan_idx6; +typedef struct { int32_t d[1]; } cspan_tup1; +typedef struct { int32_t d[2]; } cspan_tup2; +typedef struct { int32_t d[3]; } cspan_tup3; +typedef struct { int32_t d[4]; } cspan_tup4; +typedef struct { int32_t d[5]; } cspan_tup5; +typedef struct { int32_t d[6]; } cspan_tup6; #define c_END -1 #define c_ALL 0,-1 -#define cspan_md(array, ...) \ - {.data=array, .shape={__VA_ARGS__}, .stride={.d={__VA_ARGS__}}} +#define cspan_md(order, array, ...) \ + {.data=array, .shape={__VA_ARGS__}, \ + .stride=*(c_PASTE(cspan_tup, c_NUMARGS(__VA_ARGS__))*)_cspan_shape2stride(order, ((int32_t[]){__VA_ARGS__}), c_NUMARGS(__VA_ARGS__))} -/* For static initialization, use cspan_init(). c_init() for non-static only. */ +#define cspan_transpose(self) \ + _cspan_transpose((self)->shape, (self)->stride.d, cspan_rank(self)) + +/* Use cspan_init() for static initialization only. c_init() for non-static init. */ #define cspan_init(SpanType, ...) \ {.data=(SpanType##_value[])__VA_ARGS__, .shape={sizeof((SpanType##_value[])__VA_ARGS__)/sizeof(SpanType##_value)}} @@ -134,17 +141,18 @@ typedef struct { int32_t d[6]; } cspan_idx6; #define cspan_size(self) _cspan_size((self)->shape, cspan_rank(self)) #define cspan_rank(self) c_arraylen((self)->shape) +#define cspan_order(self) ((self)->stride.d[0] < (self)->stride.d[cspan_rank(self) - 1]) -#define cspan_index(self, ...) c_PASTE(cspan_idx_, c_NUMARGS(__VA_ARGS__))(self, __VA_ARGS__) -#define cspan_idx_1 cspan_idx_4 -#define cspan_idx_2 cspan_idx_4 -#define cspan_idx_3 cspan_idx_4 -#define cspan_idx_4(self, ...) \ +#define cspan_index(self, ...) c_PASTE(cspan_tup_, c_NUMARGS(__VA_ARGS__))(self, __VA_ARGS__) +#define cspan_tup_1 cspan_tup_3 +#define cspan_tup_2 cspan_tup_3 +#define cspan_tup_3(self, ...) \ c_PASTE(_cspan_idx, c_NUMARGS(__VA_ARGS__))((self)->shape, (self)->stride, __VA_ARGS__) // small/fast -#define cspan_idx_5(self, ...) \ +#define cspan_tup_4(self, ...) \ (_cspan_idxN(c_NUMARGS(__VA_ARGS__), (self)->shape, (self)->stride.d, (int32_t[]){__VA_ARGS__}) + \ c_static_assert(cspan_rank(self) == c_NUMARGS(__VA_ARGS__))) // general -#define cspan_idx_6 cspan_idx_5 +#define cspan_tup_5 cspan_tup_4 +#define cspan_tup_6 cspan_tup_4 #define cspan_at(self, ...) ((self)->data + cspan_index(self, __VA_ARGS__)) #define cspan_front(self) ((self)->data) @@ -162,19 +170,20 @@ typedef struct { int32_t d[6]; } cspan_idx6; #define cspan_submd4(...) c_MACRO_OVERLOAD(cspan_submd4, __VA_ARGS__) #define cspan_submd3(...) c_MACRO_OVERLOAD(cspan_submd3, __VA_ARGS__) #define cspan_submd2(self, x) \ - {.data=cspan_at(self, x, 0), .shape={(self)->shape[1]}} + {.data=cspan_at(self, x, 0), .shape={(self)->shape[1]}, .stride={.d={(self)->stride.d[1]}}} #define cspan_submd3_2(self, x) \ {.data=cspan_at(self, x, 0, 0), .shape={(self)->shape[1], (self)->shape[2]}, \ - .stride={.d={0, (self)->stride.d[2]}}} + .stride={.d={(self)->stride.d[1], (self)->stride.d[2]}}} #define cspan_submd3_3(self, x, y) \ - {.data=cspan_at(self, x, y, 0), .shape={(self)->shape[2]}} + {.data=cspan_at(self, x, y, 0), .shape={(self)->shape[2]}, .stride={.d={(self)->stride.d[2]}}} #define cspan_submd4_2(self, x) \ {.data=cspan_at(self, x, 0, 0, 0), .shape={(self)->shape[1], (self)->shape[2], (self)->shape[3]}, \ - .stride={.d={0, (self)->stride.d[2], (self)->stride.d[3]}}} + .stride={.d={(self)->stride.d[1], (self)->stride.d[2], (self)->stride.d[3]}}} #define cspan_submd4_3(self, x, y) \ - {.data=cspan_at(self, x, y, 0, 0), .shape={(self)->shape[2], (self)->shape[3]}, .stride={.d={0, (self)->stride.d[3]}}} + {.data=cspan_at(self, x, y, 0, 0), .shape={(self)->shape[2], (self)->shape[3]}, \ + .stride={.d={(self)->stride.d[2], (self)->stride.d[3]}}} #define cspan_submd4_4(self, x, y, z) \ - {.data=cspan_at(self, x, y, z, 0), .shape={(self)->shape[3]}} + {.data=cspan_at(self, x, y, z, 0), .shape={(self)->shape[3]}, .stride={.d={(self)->stride.d[3]}}} // private definitions: @@ -184,83 +193,96 @@ STC_INLINE intptr_t _cspan_size(const int32_t shape[], int rank) { return sz; } -STC_INLINE intptr_t _cspan_idx1(const int32_t shape[1], const cspan_idx1 stri, int32_t x) +STC_INLINE void _cspan_transpose(int32_t shape[], int32_t stride[], int rank) { + for (int i = 0; i < --rank; ++i) { + c_swap(int32_t, shape + i, shape + rank); + c_swap(int32_t, stride + i, stride + rank); + } +} + +STC_INLINE intptr_t _cspan_idx1(const int32_t shape[1], const cspan_tup1 stri, int32_t x) { c_ASSERT(c_LTu(x, shape[0])); return x; } -STC_INLINE intptr_t _cspan_idx2(const int32_t shape[2], const cspan_idx2 stri, int32_t x, int32_t y) - { c_ASSERT(c_LTu(x, shape[0]) && c_LTu(y, shape[1])); return (intptr_t)stri.d[1]*x + y; } +STC_INLINE intptr_t _cspan_idx2(const int32_t shape[2], const cspan_tup2 stri, int32_t x, int32_t y) + { c_ASSERT(c_LTu(x, shape[0]) && c_LTu(y, shape[1])); return (intptr_t)stri.d[0]*x + stri.d[1]*y; } -STC_INLINE intptr_t _cspan_idx3(const int32_t shape[3], const cspan_idx3 stri, int32_t x, int32_t y, int32_t z) { +STC_INLINE intptr_t _cspan_idx3(const int32_t shape[3], const cspan_tup3 stri, int32_t x, int32_t y, int32_t z) { c_ASSERT(c_LTu(x, shape[0]) && c_LTu(y, shape[1]) && c_LTu(z, shape[2])); - return (intptr_t)stri.d[2]*(stri.d[1]*x + y) + z; + return (intptr_t)stri.d[0]*x + stri.d[1]*y + stri.d[2]*z; } -STC_INLINE intptr_t _cspan_idx4(const int32_t shape[4], const cspan_idx4 stri, int32_t x, int32_t y, - int32_t z, int32_t w) { - c_ASSERT(c_LTu(x, shape[0]) && c_LTu(y, shape[1]) && c_LTu(z, shape[2]) && c_LTu(w, shape[3])); - return (intptr_t)stri.d[3]*(stri.d[2]*(stri.d[1]*x + y) + z) + w; + +STC_INLINE intptr_t _cspan_idxN(int rank, const int32_t shape[], const int32_t stride[], const int32_t a[]) { + intptr_t off = 0; + while (rank--) { + c_ASSERT(c_LTu(a[rank], shape[rank])); + off += stride[rank]*a[rank]; + } + return off; } -STC_API intptr_t _cspan_idxN(int rank, const int32_t shape[], const int32_t stri[], const int32_t a[]); -STC_API intptr_t _cspan_next2(int rank, int32_t pos[], const int32_t shape[], const int32_t stride[]); -#define _cspan_next1(r, pos, d, s) (++pos[0], 1) +#define _cspan_next1(pos, d, s, r, i, inc) (++pos[0], 1) +STC_API intptr_t _cspan_next2(int32_t pos[], const int32_t shape[], const int32_t stride[], int rank, int i, int inc); #define _cspan_next3 _cspan_next2 #define _cspan_next4 _cspan_next2 #define _cspan_next5 _cspan_next2 #define _cspan_next6 _cspan_next2 -STC_API intptr_t _cspan_slice(int32_t odim[], int32_t ostri[], int* orank, - const int32_t shape[], const int32_t stri[], +STC_API intptr_t _cspan_slice(int32_t oshape[], int32_t ostride[], int* orank, + const int32_t shape[], const int32_t stride[], int rank, const int32_t a[][2]); + +STC_API int32_t* _cspan_shape2stride(char order, int32_t shape[], int rank); #endif // STC_CSPAN_H_INCLUDED /* -------------------------- IMPLEMENTATION ------------------------- */ #if defined(i_implement) || defined(i_static) -STC_DEF intptr_t _cspan_idxN(int rank, const int32_t shape[], const int32_t stri[], const int32_t a[]) { - intptr_t off = a[0]; - c_ASSERT(c_LTu(a[0], shape[0])); - for (int i = 1; i < rank; ++i) { - off *= stri[i]; - off += a[i]; - c_ASSERT(c_LTu(a[i], shape[i])); +STC_DEF int32_t* _cspan_shape2stride(char order, int32_t shape[], int rank) { + int32_t k = 1, i, j, inc, s1, s2; + if (order == 'F') i = 0, j = rank, inc = 1; + else /* 'C' */ i = rank - 1, j = -1, inc = -1; + s1 = shape[i]; shape[i] = 1; + + for (i += inc; i != j; i += inc) { + s2 = shape[i]; + shape[i] = (k *= s1); + s1 = s2; } - return off; + return shape; } -STC_DEF intptr_t _cspan_next2(int rank, int32_t pos[], const int32_t shape[], const int32_t stride[]) { - intptr_t off = 1, rs = 1; - ++pos[rank - 1]; - while (--rank && pos[rank] == shape[rank]) { - pos[rank] = 0, ++pos[rank - 1]; - const intptr_t ds = rs*shape[rank]; - rs *= stride[rank]; - off += rs - ds; +STC_DEF intptr_t _cspan_next2(int32_t pos[], const int32_t shape[], const int32_t stride[], int rank, int i, int inc) { + intptr_t off = stride[i]; + ++pos[i]; + for (; --rank && pos[i] == shape[i]; i += inc) { + pos[i] = 0; ++pos[i + inc]; + off += stride[i + inc] - stride[i]*shape[i]; } return off; } -STC_DEF intptr_t _cspan_slice(int32_t odim[], int32_t ostri[], int* orank, - const int32_t shape[], const int32_t stri[], +STC_DEF intptr_t _cspan_slice(int32_t oshape[], int32_t ostride[], int* orank, + const int32_t shape[], const int32_t stride[], int rank, const int32_t a[][2]) { intptr_t off = 0; - int i = 0, j = 0; - int32_t t, s = 1; + int i = 0, oi = 0; + int32_t end; for (; i < rank; ++i) { - off *= stri[i]; - off += a[i][0]; - switch (a[i][1]) { - case 0: s *= stri[i]; c_ASSERT(c_LTu(a[i][0], shape[i])); continue; - case -1: t = shape[i]; break; - default: t = a[i][1]; break; + off += stride[i]*a[i][0]; + switch (a[i][1]) { + case 0: c_ASSERT(c_LTu(a[i][0], shape[i])); continue; + case -1: end = shape[i]; break; + default: end = a[i][1]; } - odim[j] = t - a[i][0]; - ostri[j] = s*stri[i]; - c_ASSERT(c_LTu(0, odim[j]) & !c_LTu(shape[i], t)); - s = 1; ++j; + oshape[oi] = end - a[i][0]; + ostride[oi] = stride[i]; + c_ASSERT(c_LTu(0, oshape[oi]) & !c_LTu(shape[i], end)); + ++oi; } - *orank = j; + *orank = oi; return off; } + #endif #undef i_opt #undef i_header diff --git a/misc/benchmarks/various/cspan_bench.c b/misc/benchmarks/various/cspan_bench.c index 02ae3237..6ca7425d 100644 --- a/misc/benchmarks/various/cspan_bench.c +++ b/misc/benchmarks/various/cspan_bench.c @@ -28,8 +28,8 @@ static void MDRanges_setup(intptr_t state) for (intptr_t s = 0; s < state; ++s) { - MD3 r_in = cspan_md(Vin, nx, ny, nz); - MD3 r_out = cspan_md(Vout, nx, ny, nz); + MD3 r_in = cspan_md('C', Vin, nx, ny, nz); + MD3 r_out = cspan_md('C', Vout, nx, ny, nz); r_in = cspan_slice(MD3, &r_in, {lx, hx}, {ly, hy}, {lz, hz}); r_out = cspan_slice(MD3, &r_out, {lx, hx}, {ly, hy}, {lz, hz}); @@ -64,8 +64,8 @@ static void TraditionalForLoop(intptr_t state) static void MDRanges_nested_loop(intptr_t state) { - MD3 r_in = cspan_md(Vin, nx, ny, nz); - MD3 r_out = cspan_md(Vout, nx, ny, nz); + MD3 r_in = cspan_md('C', Vin, nx, ny, nz); + MD3 r_out = cspan_md('C', Vout, nx, ny, nz); r_in = cspan_slice(MD3, &r_in, {lx, hx}, {ly, hy}, {lz, hz}); r_out = cspan_slice(MD3, &r_out, {lx, hx}, {ly, hy}, {lz, hz}); @@ -91,8 +91,8 @@ static void MDRanges_nested_loop(intptr_t state) static void MDRanges_loop_over_joined(intptr_t state) { - MD3 r_in = cspan_md(Vin, nx, ny, nz); - MD3 r_out = cspan_md(Vout, nx, ny, nz); + MD3 r_in = cspan_md('C', Vin, nx, ny, nz); + MD3 r_out = cspan_md('C', Vout, nx, ny, nz); r_in = cspan_slice(MD3, &r_in, {lx, hx}, {ly, hy}, {lz, hz}); r_out = cspan_slice(MD3, &r_out, {lx, hx}, {ly, hy}, {lz, hz}); diff --git a/misc/benchmarks/various/string_bench_STC.cpp b/misc/benchmarks/various/string_bench_STC.cpp index ae8e4c38..319b0b19 100644 --- a/misc/benchmarks/various/string_bench_STC.cpp +++ b/misc/benchmarks/various/string_bench_STC.cpp @@ -4,10 +4,11 @@ #include <iostream> #include <iomanip> #include <chrono> -#define i_static +#define i_implement #include <stc/cstr.h> // string -#define i_static +#define i_implement #include <stc/csview.h> // string_view +#include <stc/algo/raii.h> #define i_key_str #include <stc/cvec.h> // vec of cstr with const char* lookup diff --git a/misc/examples/multidim.c b/misc/examples/multidim.c index 2f3ad907..df8f485d 100644 --- a/misc/examples/multidim.c +++ b/misc/examples/multidim.c @@ -14,7 +14,7 @@ int main() ispan ms1 = cspan_from(&v); // View the same data as a 3D array 2 x 3 x 4 - ispan3 ms3 = cspan_md(v.data, 2, 3, 4); + ispan3 ms3 = cspan_md('C', v.data, 2, 3, 4); puts("ms3:"); for (int i=0; i != ms3.shape[0]; i++) { diff --git a/misc/tests/cspan_test.c b/misc/tests/cspan_test.c index 9afa63f5..d266fa38 100644 --- a/misc/tests/cspan_test.c +++ b/misc/tests/cspan_test.c @@ -8,7 +8,7 @@ using_cspan3(intspan, int); CTEST(cspan, subdim) { int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; - intspan3 m = cspan_md(array, 2, 2, 3); + intspan3 m = cspan_md('C', array, 2, 2, 3); for (size_t i = 0; i < m.shape[0]; ++i) { intspan2 sub_i = cspan_submd3(&m, i); @@ -23,7 +23,7 @@ CTEST(cspan, subdim) { CTEST(cspan, slice) { int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; - intspan2 m1 = cspan_md(array, 3, 4); + intspan2 m1 = cspan_md('C', array, 3, 4); size_t sum1 = 0; for (size_t i = 0; i < m1.shape[0]; ++i) { @@ -53,7 +53,7 @@ CTEST(cspan, slice2) { c_forrange (i, 10*20*30) cstack_int_push(&stack, i); - intspan3 ms3 = cspan_md(stack.data, 10, 20, 30); + intspan3 ms3 = cspan_md('C', stack.data, 10, 20, 30); ms3 = cspan_slice(intspan3, &ms3, {1,4}, {3,7}, {20,24}); size_t sum = 0; @@ -93,7 +93,7 @@ CTEST_SETUP(cspan_cube) { c_forrange (i, N) cstack_int_push(&_self->stack, i+1); - intspan3 ms3 = cspan_md(_self->stack.data, CUBE, CUBE, CUBE); + intspan3 ms3 = cspan_md('C', _self->stack.data, CUBE, CUBE, CUBE); c_forrange (i, 0, ms3.shape[0], TSIZE) { c_forrange (j, 0, ms3.shape[1], TSIZE) { @@ -114,7 +114,7 @@ CTEST_TEARDOWN(cspan_cube) { CTEST_F(cspan_cube, slice3) { intptr_t n = cstack_int_size(&_self->stack); - //printf("\ntiles: %zi, cells: %zi\n", Tiles_size(&_self->tiles), n); + //printf("\ntiles: %d, cells: %d\n", (int)Tiles_size(&_self->tiles), (int)n); int64_t sum = 0; // iterate each 3d tile in sequence |
