From 50a16934dde8e65bbcf628d6342c1649f7e09365 Mon Sep 17 00:00:00 2001 From: Tyge Lovset Date: Thu, 18 May 2023 11:49:31 +0200 Subject: Huge update: cqueue and cdeq completely rewritten. cvec and cdeq API harmonized. Docs update/improved. --- misc/benchmarks/various/cspan_bench.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'misc/benchmarks/various/cspan_bench.c') diff --git a/misc/benchmarks/various/cspan_bench.c b/misc/benchmarks/various/cspan_bench.c index 589df13a..02ae3237 100644 --- a/misc/benchmarks/various/cspan_bench.c +++ b/misc/benchmarks/various/cspan_bench.c @@ -1,4 +1,4 @@ -#define STC_NDEBUG +#define NDEBUG #include #include #include -- cgit v1.2.3 From 2d1011251596edee16d3bd6afb0e3c3b9df1157b Mon Sep 17 00:00:00 2001 From: tylov Date: Sat, 8 Jul 2023 14:00:23 +0200 Subject: Added support for column-major md cspan. API change: the create function cspan_md(order, array, d1, d2, ...) has the new first argument order, which must be either 'C' or 'F' (C: row-major or Fortran: column-major). The representation of strides was changed. --- docs/cspan_api.md | 15 ++- include/stc/cspan.h | 164 +++++++++++++++------------ misc/benchmarks/various/cspan_bench.c | 12 +- misc/benchmarks/various/string_bench_STC.cpp | 5 +- misc/examples/multidim.c | 2 +- misc/tests/cspan_test.c | 10 +- 6 files changed, 117 insertions(+), 91 deletions(-) (limited to 'misc/benchmarks/various/cspan_bench.c') 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; iref += _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 #include #include -#define i_static +#define i_implement #include // string -#define i_static +#define i_implement #include // string_view +#include #define i_key_str #include // 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 -- cgit v1.2.3 From afc968975a057f5b2653e3cfa51ef2eff83a8d5b Mon Sep 17 00:00:00 2001 From: tylov Date: Tue, 11 Jul 2023 16:36:55 +0200 Subject: Internal updates and doc reorg. --- docs/cspan_api.md | 41 ++++++++-------- include/stc/cspan.h | 72 +++++++++++++++------------- misc/benchmarks/various/cspan_bench.c | 14 +++--- misc/benchmarks/various/string_bench_STD.cpp | 1 + misc/examples/multidim.c | 1 - 5 files changed, 67 insertions(+), 62 deletions(-) (limited to 'misc/benchmarks/various/cspan_bench.c') diff --git a/docs/cspan_api.md b/docs/cspan_api.md index 58b06af0..e2636086 100644 --- a/docs/cspan_api.md +++ b/docs/cspan_api.md @@ -29,7 +29,11 @@ a compile error is issued. Runtime bounds checks are enabled by default (define 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(char order, ValueType* data, d1, d2, ...); // make a multi-dim cspan. order: 'C' or 'F' (Fortran) + + // make a subspan of input span rank. Like e.g. cspan_slice(Span3, &ms3, {off,off+count}, {c_ALL}, {c_ALL}); +SpanType cspan_subspan(const SpanType* span, intptr_t offset, intptr_t count); +SpanType2 cspan_subspan2(const SpanType2* span, intptr_t offset, intptr_t count); +SpanType3 cspan_subspan3(const SpanType3* span, intptr_t offset, intptr_t count); intptr_t cspan_size(const SpanTypeN* self); // return number of elements intptr_t cspan_rank(const SpanTypeN* self); // dimensions; compile time constant @@ -39,35 +43,30 @@ ValueType* cspan_at(const SpanTypeN* self, intptr_t x, ...); // #args mus ValueType* cspan_front(const SpanTypeN* self); 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}); +SpanTypeN_iter SpanType_begin(const SpanTypeN* self); +SpanTypeN_iter SpanType_end(const SpanTypeN* self); +void SpanType_next(SpanTypeN_iter* it); +SpanTypeN cspan_md(char order, ValueType* data, d1, d2, ...); // make a multi-dim cspan. order: 'C' or 'F' (Fortran) // 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. -SpanTypeN cspan_submd3(const SpanType3* self, intptr_t x, ...); // return a 1d or 2d subspan from a 3d span. -SpanTypeN cspan_submd4(const SpanType4* self, intptr_t x, ...); // number of args determines rank of output span. - // 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); + // create a sub md span of lower rank. Like e.g. cspan_slice(Span2, &ms4, {x}, {y}, {c_ALL}, {c_ALL}); +OutSpan1 cspan_submd2(const SpanType2* parent, intptr_t x); // return a 1d subspan from a 2d span. +OutSpanN cspan_submd3(const SpanType3* parent, intptr_t x, ...); // return a 1d or 2d subspan from a 3d span. +OutSpanN cspan_submd4(const SpanType4* parent, intptr_t x, ...); // number of args decides rank of output span. -SpanTypeN_iter SpanType_begin(const SpanTypeN* self); -SpanTypeN_iter SpanType_end(const SpanTypeN* self); -void SpanType_next(SpanTypeN_iter* it); + // general slicing of an md span. + // {i}: reduce rank. {i,c_END}: slice to end. {c_ALL}: use full extent. +OutSpanN cspan_slice(TYPE OutSpanN, const SpanTypeN* parent, {x0,x1}, {y0,y1}.., {N0,N1}); ``` -## Types - -| Type name | Type definition | Used to represent... | +## TypesPd +| Type name | Type definition / usage | Used to represent... | |:------------------|:----------------------------------------------------|:---------------------| | SpanTypeN | `struct { ValueType *data; uint32_t shape[N]; .. }` | SpanType with rank N | | SpanTypeN`_value` | `ValueType` | The ValueType | -| `c_ALL` | | Full extent | -| `c_END` | | End of extent | +| `c_ALL` | Use with `cspan_slice()`. | Full extent | +| `c_END` | " | End of extent | ## Example 1 diff --git a/include/stc/cspan.h b/include/stc/cspan.h index 7a0e9c8d..027b5275 100644 --- a/include/stc/cspan.h +++ b/include/stc/cspan.h @@ -107,58 +107,37 @@ int demo2() { #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_tuple1; -typedef struct { int32_t d[2]; } cspan_tuple2; -typedef struct { int32_t d[3]; } cspan_tuple3; -typedef struct { int32_t d[4]; } cspan_tuple4; -typedef struct { int32_t d[5]; } cspan_tuple5; -typedef struct { int32_t d[6]; } cspan_tuple6; +#define using_cspan_tuple(N) typedef struct { int32_t d[N]; } cspan_tuple##N +using_cspan_tuple(1); using_cspan_tuple(2); +using_cspan_tuple(3); using_cspan_tuple(4); +using_cspan_tuple(5); using_cspan_tuple(6); +using_cspan_tuple(7); using_cspan_tuple(8); + #define c_END -1 #define c_ALL 0,-1 -#define cspan_md(order, array, ...) \ - {.data=array, .shape={__VA_ARGS__}, \ - .stride=*(c_PASTE(cspan_tuple, c_NUMARGS(__VA_ARGS__))*)_cspan_shape2stride(order, ((int32_t[]){__VA_ARGS__}), c_NUMARGS(__VA_ARGS__))} - -#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)}, .stride={.d={1}}} -#define cspan_slice(OutSpan, parent, ...) \ - OutSpan##_slice_((parent)->data, (parent)->shape, (parent)->stride.d, cspan_rank(parent) + \ - c_static_assert(cspan_rank(parent) == sizeof((int32_t[][2]){__VA_ARGS__})/sizeof(int32_t[2])), \ - (const int32_t[][2]){__VA_ARGS__}) - /* create a cspan from a cvec, cstack, cdeq, cqueue, or cpque (heap) */ #define cspan_from(container) \ {.data=(container)->data, .shape={(int32_t)(container)->_len}, .stride={.d={1}}} #define cspan_from_array(array) \ - {.data=(array) + c_static_assert(sizeof(array) != sizeof(void*)), .shape={c_arraylen(array)}, .stride={.d={1}}} + {.data=(array), .shape={c_arraylen(array)}, .stride={.d={1}}} #define cspan_size(self) _cspan_size((self)->shape, cspan_rank(self)) #define cspan_rank(self) c_arraylen((self)->shape) #define cspan_is_order_F(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_3 -#define cspan_idx_2 cspan_idx_3 -#define cspan_idx_3(self, ...) \ - c_PASTE(_cspan_idx, c_NUMARGS(__VA_ARGS__))((self)->shape, (self)->stride, __VA_ARGS__) // small/fast -#define cspan_idx_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_5 cspan_idx_4 -#define cspan_idx_6 cspan_idx_4 #define cspan_at(self, ...) ((self)->data + cspan_index(self, __VA_ARGS__)) #define cspan_front(self) ((self)->data) #define cspan_back(self) ((self)->data + cspan_size(self) - 1) -// cspan_subspanN. (N<=3) Optimized, same as e.g. cspan_slice(Span3, &ms3, {off,off+count}, {c_ALL}, {c_ALL}); +// cspan_subspanX: (X <= 3) optimized. Similar to cspan_slice(Span3, &ms3, {off,off+count}, {c_ALL}, {c_ALL}); #define cspan_subspan(self, offset, count) \ {.data=cspan_at(self, offset), .shape={count}, .stride=(self)->stride} #define cspan_subspan2(self, offset, count) \ @@ -166,16 +145,17 @@ typedef struct { int32_t d[6]; } cspan_tuple6; #define cspan_subspan3(self, offset, count) \ {.data=cspan_at(self, offset, 0, 0), .shape={count, (self)->shape[1], (self)->shape[2]}, .stride=(self)->stride} -// cspan_submdN: reduce rank (N<=4) Optimized, same as e.g. cspan_slice(Span2, &ms4, {x}, {y}, {c_ALL}, {c_ALL}); -#define cspan_submd4(...) c_MACRO_OVERLOAD(cspan_submd4, __VA_ARGS__) -#define cspan_submd3(...) c_MACRO_OVERLOAD(cspan_submd3, __VA_ARGS__) + +// cspan_submd(): Reduce rank (N <= 4) Optimized, same as e.g. cspan_slice(Span2, &ms4, {x}, {y}, {c_ALL}, {c_ALL}); #define cspan_submd2(self, x) \ {.data=cspan_at(self, x, 0), .shape={(self)->shape[1]}, .stride={.d={(self)->stride.d[1]}}} +#define cspan_submd3(...) c_MACRO_OVERLOAD(cspan_submd3, __VA_ARGS__) #define cspan_submd3_2(self, x) \ {.data=cspan_at(self, x, 0, 0), .shape={(self)->shape[1], (self)->shape[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]}, .stride={.d={(self)->stride.d[2]}}} +#define cspan_submd4(...) c_MACRO_OVERLOAD(cspan_submd4, __VA_ARGS__) #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={(self)->stride.d[1], (self)->stride.d[2], (self)->stride.d[3]}}} @@ -185,7 +165,33 @@ typedef struct { int32_t d[6]; } cspan_tuple6; #define cspan_submd4_4(self, x, y, z) \ {.data=cspan_at(self, x, y, z, 0), .shape={(self)->shape[3]}, .stride={.d={(self)->stride.d[3]}}} -// private definitions: + +#define cspan_md(order, array, ...) \ + {.data=array, .shape={__VA_ARGS__}, \ + .stride=*(c_PASTE(cspan_tuple, c_NUMARGS(__VA_ARGS__))*)_cspan_shape2stride(order, ((int32_t[]){__VA_ARGS__}), c_NUMARGS(__VA_ARGS__))} + +#define cspan_transpose(self) \ + _cspan_transpose((self)->shape, (self)->stride.d, cspan_rank(self)) + + +// General slicing function; +#define cspan_slice(OutSpan, parent, ...) \ + OutSpan##_slice_((parent)->data, (parent)->shape, (parent)->stride.d, cspan_rank(parent) + \ + c_static_assert(cspan_rank(parent) == sizeof((int32_t[][2]){__VA_ARGS__})/sizeof(int32_t[2])), \ + (const int32_t[][2]){__VA_ARGS__}) + +// ----------- private definitions ------------ + +// cspan_index() helpers: +#define cspan_idx_1 cspan_idx_3 +#define cspan_idx_2 cspan_idx_3 +#define cspan_idx_3(self, ...) \ + c_PASTE(_cspan_idx, c_NUMARGS(__VA_ARGS__))((self)->shape, (self)->stride, __VA_ARGS__) // small/fast +#define cspan_idx_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_5 cspan_idx_4 +#define cspan_idx_6 cspan_idx_4 STC_INLINE intptr_t _cspan_size(const int32_t shape[], int rank) { intptr_t sz = shape[0]; diff --git a/misc/benchmarks/various/cspan_bench.c b/misc/benchmarks/various/cspan_bench.c index 6ca7425d..e724bdbd 100644 --- a/misc/benchmarks/various/cspan_bench.c +++ b/misc/benchmarks/various/cspan_bench.c @@ -12,8 +12,8 @@ enum { nz = 64 }; int lx = 15, ly = 10, lz = 5; -int hx = 20, hy = 15, hz = 15; -intptr_t n = 1000000; +int hx = 30, hy = 15, hz = 15; +intptr_t n = 100000; // define the contents of two nx x ny x nz arrays in and out double Vout[nx * ny * nz]; @@ -49,10 +49,10 @@ static void TraditionalForLoop(intptr_t state) for (int s = 0; s < state; ++s) { for (int x = lx; x < hx; ++x) { for (int y = ly; y < hy; ++y) { - for (int z = lz; z < hz; ++z) - { - double d = Vin[nz*(ny*x + y) + z]; - Vout[nz*(ny*x + y) + z] += d; + for (int z = lz; z < hz; ++z) { + int i = nz*(ny*x + y) + z; + double d = Vin[i]; + Vout[i] += d; sum += d; } } @@ -64,13 +64,13 @@ static void TraditionalForLoop(intptr_t state) static void MDRanges_nested_loop(intptr_t state) { + clock_t t = clock(); 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}); // C++23: for (auto [o, i] : std::views::zip(flat(r_out), flat(r_in))) { o = i; } - clock_t t = clock(); double sum = 0; for (intptr_t s = 0; s < state; ++s) { diff --git a/misc/benchmarks/various/string_bench_STD.cpp b/misc/benchmarks/various/string_bench_STD.cpp index 8bb87937..07934948 100644 --- a/misc/benchmarks/various/string_bench_STD.cpp +++ b/misc/benchmarks/various/string_bench_STD.cpp @@ -12,6 +12,7 @@ #include #define i_static #include +#include std::vector read_file(const char* name) { diff --git a/misc/examples/multidim.c b/misc/examples/multidim.c index df8f485d..43c21443 100644 --- a/misc/examples/multidim.c +++ b/misc/examples/multidim.c @@ -28,7 +28,6 @@ int main() } puts("ss3 = ms3[:, 1:3, 1:3]"); ispan3 ss3 = ms3; - //cspan_slice(&ss3, {c_ALL}, {1,3}, {1,3}); ss3 = cspan_slice(ispan3, &ms3, {c_ALL}, {1,3}, {1,3}); for (int i=0; i != ss3.shape[0]; i++) { -- cgit v1.2.3 From 0bcb0fcd981cb15329dfd4fb675097564164da18 Mon Sep 17 00:00:00 2001 From: tylov Date: Tue, 11 Jul 2023 22:16:09 +0200 Subject: Fixed an issue in template.h Reverted to cspan_md() and cspan_md_left() for column-major. Changed cspan_submdX(): add OutputSpanType as first parameter - aligns with cspan_slice() and adds type safety. --- docs/cspan_api.md | 14 ++++++------ include/stc/cspan.h | 42 +++++++++++++++++++++-------------- include/stc/priv/template.h | 6 ++++- misc/benchmarks/various/cspan_bench.c | 12 +++++----- misc/examples/multidim.c | 6 ++--- misc/tests/cspan_test.c | 12 +++++----- 6 files changed, 52 insertions(+), 40 deletions(-) (limited to 'misc/benchmarks/various/cspan_bench.c') diff --git a/docs/cspan_api.md b/docs/cspan_api.md index e2636086..4262b1ef 100644 --- a/docs/cspan_api.md +++ b/docs/cspan_api.md @@ -52,9 +52,9 @@ SpanTypeN cspan_md(char order, ValueType* data, d1, d2, ...); // make a mu void cspan_transpose(const SpanTypeN* self); // create a sub md span of lower rank. Like e.g. cspan_slice(Span2, &ms4, {x}, {y}, {c_ALL}, {c_ALL}); -OutSpan1 cspan_submd2(const SpanType2* parent, intptr_t x); // return a 1d subspan from a 2d span. -OutSpanN cspan_submd3(const SpanType3* parent, intptr_t x, ...); // return a 1d or 2d subspan from a 3d span. -OutSpanN cspan_submd4(const SpanType4* parent, intptr_t x, ...); // number of args decides rank of output span. +OutSpan1 cspan_submd2(TYPE OutSpan1, const SpanType2* parent, intptr_t x); // return a 1d subspan from a 2d span. +OutSpanN cspan_submd3(TYPE OutSpanN, const SpanType3* parent, intptr_t x, ...); // return a 1d or 2d subspan from a 3d span. +OutSpanN cspan_submd4(TYPE OutSpanN, const SpanType4* parent, intptr_t x, ...); // number of args decides rank of output span. // general slicing of an md span. // {i}: reduce rank. {i,c_END}: slice to end. {c_ALL}: use full extent. @@ -101,9 +101,9 @@ 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('C', arr, 2, 3, 4); // C-order, i.e. row-major. + myspan3 ms3 = cspan_md(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); + myspan2 ss2 = cspan_submd3(myspan2, &ss3, 1); c_forrange (i, ss2.shape[0]) c_forrange (j, ss2.shape[1]) @@ -150,10 +150,10 @@ 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('C', span.data, 2, 4, 3); + Span3 span3 = cspan_md(span.data, 2, 4, 3); // reduce rank: (i.e. span3[1]) - Span2 span2 = cspan_submd3(&span3, 1); + Span2 span2 = cspan_submd3(Span2, &span3, 1); puts("\niterate span2 flat:"); c_foreach (i, Span2, span2) diff --git a/include/stc/cspan.h b/include/stc/cspan.h index 027b5275..89986d6f 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('C', raw, 4, 5); + Span2f ms = cspan_md(raw, 4, 5); for (int i=0; ishape[1]}, .stride={.d={(self)->stride.d[1]}}} -#define cspan_submd3(...) c_MACRO_OVERLOAD(cspan_submd3, __VA_ARGS__) -#define cspan_submd3_2(self, x) \ - {.data=cspan_at(self, x, 0, 0), .shape={(self)->shape[1], (self)->shape[2]}, \ +#define cspan_submd2(OutSpan, self, ...) _cspan_submdN(OutSpan, 2, self, __VA_ARGS__) +#define cspan_submd3(OutSpan, self, ...) _cspan_submdN(OutSpan, 3, self, __VA_ARGS__) +#define cspan_submd4(OutSpan, self, ...) _cspan_submdN(OutSpan, 4, self, __VA_ARGS__) + +#define _cspan_submdN(OutSpan, N, self, ...) \ + _cspan_submd##N(c_static_assert(cspan_rank((OutSpan*)0) == N - c_NUMARGS(__VA_ARGS__)), self, __VA_ARGS__) + +#define _cspan_submd2(ok, self, x) \ + {.data=cspan_at(self, x, 0) + ok, .shape={(self)->shape[1]}, .stride={.d={(self)->stride.d[1]}}} +#define _cspan_submd3(...) c_MACRO_OVERLOAD(_cspan_submd3, __VA_ARGS__) +#define _cspan_submd3_3(ok, self, x) \ + {.data=cspan_at(self, x, 0, 0) + ok, .shape={(self)->shape[1], (self)->shape[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]}, .stride={.d={(self)->stride.d[2]}}} -#define cspan_submd4(...) c_MACRO_OVERLOAD(cspan_submd4, __VA_ARGS__) -#define cspan_submd4_2(self, x) \ - {.data=cspan_at(self, x, 0, 0, 0), .shape={(self)->shape[1], (self)->shape[2], (self)->shape[3]}, \ +#define _cspan_submd3_4(ok, self, x, y) \ + {.data=cspan_at(self, x, y, 0) + ok, .shape={(self)->shape[2]}, .stride={.d={(self)->stride.d[2]}}} +#define _cspan_submd4(...) c_MACRO_OVERLOAD(_cspan_submd4, __VA_ARGS__) +#define _cspan_submd4_3(ok, self, x) \ + {.data=cspan_at(self, x, 0, 0, 0) + ok, .shape={(self)->shape[1], (self)->shape[2], (self)->shape[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]}, \ +#define _cspan_submd4_4(ok, self, x, y) \ + {.data=cspan_at(self, x, y, 0, 0) + ok, .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]}, .stride={.d={(self)->stride.d[3]}}} +#define _cspan_submd4_5(ok, self, x, y, z) \ + {.data=cspan_at(self, x, y, z, 0) + ok, .shape={(self)->shape[3]}, .stride={.d={(self)->stride.d[3]}}} - -#define cspan_md(order, array, ...) \ +#define cspan_md(array, ...) cspan_md_order('C', array, __VA_ARGS__) +#define cspan_md_left(array, ...) cspan_md_order('F', array, __VA_ARGS__) +#define cspan_md_order(order, array, ...) \ {.data=array, .shape={__VA_ARGS__}, \ .stride=*(c_PASTE(cspan_tuple, c_NUMARGS(__VA_ARGS__))*)_cspan_shape2stride(order, ((int32_t[]){__VA_ARGS__}), c_NUMARGS(__VA_ARGS__))} diff --git a/include/stc/priv/template.h b/include/stc/priv/template.h index 7138a87c..5551eeae 100644 --- a/include/stc/priv/template.h +++ b/include/stc/priv/template.h @@ -164,6 +164,8 @@ #error "No i_key or i_val defined" #elif defined i_keyraw ^ defined i_keyto #error "Both i_keyraw/valraw and i_keyto/valto must be defined, if any" +#elif defined i_keyfrom && !defined i_keyraw && !defined i_keyclone + #define i_keyclone i_keyfrom #elif defined i_keyfrom && !defined i_keyraw #error "i_keyfrom/valfrom defined without i_keyraw/valraw" #elif defined i_from || defined i_drop @@ -261,7 +263,9 @@ #error "i_val* must be defined for maps" #endif -#if !(defined i_valclone || defined i_no_clone) && (defined i_valdrop || defined i_valraw) +#if !defined i_valclone && defined i_valfrom && !defined i_valraw + #define i_valclone i_valfrom +#elif !(defined i_valclone || defined i_no_clone) && (defined i_valdrop || defined i_valraw) #error i_valclone should be defined when i_valdrop or i_valraw is defined #endif #ifndef i_valraw diff --git a/misc/benchmarks/various/cspan_bench.c b/misc/benchmarks/various/cspan_bench.c index e724bdbd..392c9d3f 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('C', Vin, nx, ny, nz); - MD3 r_out = cspan_md('C', Vout, nx, ny, nz); + MD3 r_in = cspan_md(Vin, nx, ny, nz); + MD3 r_out = cspan_md(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}); @@ -65,8 +65,8 @@ static void TraditionalForLoop(intptr_t state) static void MDRanges_nested_loop(intptr_t state) { clock_t t = clock(); - MD3 r_in = cspan_md('C', Vin, nx, ny, nz); - MD3 r_out = cspan_md('C', Vout, nx, ny, nz); + MD3 r_in = cspan_md(Vin, nx, ny, nz); + MD3 r_out = cspan_md(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('C', Vin, nx, ny, nz); - MD3 r_out = cspan_md('C', Vout, nx, ny, nz); + MD3 r_in = cspan_md(Vin, nx, ny, nz); + MD3 r_out = cspan_md(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/examples/multidim.c b/misc/examples/multidim.c index 43c21443..dbea9699 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('C', v.data, 2, 3, 4); + ispan3 ms3 = cspan_md(v.data, 2, 3, 4); puts("ms3:"); for (int i=0; i != ms3.shape[0]; i++) { @@ -45,7 +45,7 @@ int main() printf(" %d", *i.ref); puts(""); - ispan2 ms2 = cspan_submd3(&ms3, 0); + ispan2 ms2 = cspan_submd3(ispan2, &ms3, 0); // write data using 2D view for (int i=0; i != ms2.shape[0]; i++) @@ -58,7 +58,7 @@ int main() puts(""); puts("iterate subspan ms3[1]:"); - ispan2 sub = cspan_submd3(&ms3, 1); + ispan2 sub = cspan_submd3(ispan2, &ms3, 1); c_foreach (i, ispan2, sub) printf(" %d", *i.ref); puts(""); diff --git a/misc/tests/cspan_test.c b/misc/tests/cspan_test.c index b6953936..6834dce1 100644 --- a/misc/tests/cspan_test.c +++ b/misc/tests/cspan_test.c @@ -8,12 +8,12 @@ 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('C', array, 2, 2, 3); + intspan3 m = cspan_md(array, 2, 2, 3); for (size_t i = 0; i < m.shape[0]; ++i) { - intspan2 sub_i = cspan_submd3(&m, i); + intspan2 sub_i = cspan_submd3(intspan2, &m, i); for (size_t j = 0; j < m.shape[1]; ++j) { - intspan sub_i_j = cspan_submd2(&sub_i, j); + intspan sub_i_j = cspan_submd2(intspan, &sub_i, j); for (size_t k = 0; k < m.shape[2]; ++k) { ASSERT_EQ(*cspan_at(&sub_i_j, k), *cspan_at(&m, i, j, k)); } @@ -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('C', array, 3, 4); + intspan2 m1 = cspan_md(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('C', stack.data, 10, 20, 30); + intspan3 ms3 = cspan_md(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('C', _self->stack.data, CUBE, CUBE, CUBE); + intspan3 ms3 = cspan_md(_self->stack.data, CUBE, CUBE, CUBE); c_forrange (i, 0, ms3.shape[0], TSIZE) { c_forrange (j, 0, ms3.shape[1], TSIZE) { -- cgit v1.2.3 From e9121702a5d69624ef1e782e85a8f032e4f4e875 Mon Sep 17 00:00:00 2001 From: tylov Date: Sat, 15 Jul 2023 23:20:16 +0200 Subject: Improved warning, and other enhancements in ccommon.h --- README.md | 2 +- docs/carc_api.md | 2 +- docs/cbox_api.md | 2 +- docs/ccommon_api.md | 10 +++++----- docs/cdeq_api.md | 2 +- docs/clist_api.md | 6 +++--- docs/cmap_api.md | 12 ++++++------ docs/cpque_api.md | 2 +- docs/cqueue_api.md | 2 +- docs/crandom_api.md | 2 +- docs/cregex_api.md | 2 +- docs/cset_api.md | 2 +- docs/csmap_api.md | 8 ++++---- docs/cspan_api.md | 6 +++--- docs/csset_api.md | 2 +- docs/cstack_api.md | 2 +- docs/cstr_api.md | 2 +- docs/csview_api.md | 6 +++--- docs/cvec_api.md | 4 ++-- include/c11/fmt.h | 2 +- include/stc/algo/crange.h | 2 +- include/stc/algo/filter.h | 2 +- include/stc/algo/sort.h | 4 ++-- include/stc/carc.h | 4 ++-- include/stc/cbits.h | 2 +- include/stc/cbox.h | 4 ++-- include/stc/ccommon.h | 6 +++--- include/stc/clist.h | 2 +- include/stc/crand.h | 2 +- include/stc/cvec.h | 2 +- misc/benchmarks/plotbench/cpque_benchmark.cpp | 2 +- misc/benchmarks/various/cspan_bench.c | 2 +- misc/benchmarks/various/rust_cmap.c | 2 +- misc/benchmarks/various/sso_bench.cpp | 2 +- misc/benchmarks/various/string_bench_STC.cpp | 2 +- misc/benchmarks/various/string_bench_STD.cpp | 2 +- misc/examples/arc_containers.c | 2 +- misc/examples/arc_demo.c | 2 +- misc/examples/arcvec_erase.c | 2 +- misc/examples/birthday.c | 2 +- misc/examples/bits2.c | 2 +- misc/examples/books.c | 2 +- misc/examples/box.c | 2 +- misc/examples/cointerleave.c | 2 +- misc/examples/complex.c | 2 +- misc/examples/convert.c | 2 +- misc/examples/csmap_erase.c | 2 +- misc/examples/csmap_find.c | 2 +- misc/examples/csmap_insert.c | 2 +- misc/examples/csset_erase.c | 2 +- misc/examples/cstr_match.c | 2 +- misc/examples/demos.c | 18 +++++++++--------- misc/examples/dining_philosophers.c | 2 +- misc/examples/forloops.c | 2 +- misc/examples/functor.c | 2 +- misc/examples/gauss2.c | 2 +- misc/examples/generator.c | 2 +- misc/examples/intrusive.c | 2 +- misc/examples/list.c | 2 +- misc/examples/list_erase.c | 2 +- misc/examples/list_splice.c | 2 +- misc/examples/lower_bound.c | 2 +- misc/examples/mmap.c | 2 +- misc/examples/multidim.c | 2 +- misc/examples/multimap.c | 2 +- misc/examples/music_arc.c | 4 ++-- misc/examples/new_list.c | 2 +- misc/examples/new_map.c | 2 +- misc/examples/new_pque.c | 2 +- misc/examples/new_queue.c | 2 +- misc/examples/new_smap.c | 2 +- misc/examples/new_vec.c | 2 +- misc/examples/person_arc.c | 2 +- misc/examples/printspan.c | 2 +- misc/examples/priority.c | 2 +- misc/examples/queue.c | 2 +- misc/examples/random.c | 2 +- misc/examples/rawptr_elements.c | 2 +- misc/examples/read.c | 2 +- misc/examples/regex2.c | 2 +- misc/examples/regex_match.c | 2 +- misc/examples/regex_replace.c | 2 +- misc/examples/replace.c | 2 +- misc/examples/scheduler.c | 2 +- misc/examples/sidebyside.cpp | 2 +- misc/examples/sorted_map.c | 2 +- misc/examples/splitstr.c | 2 +- misc/examples/sso_map.c | 2 +- misc/examples/sso_substr.c | 2 +- misc/examples/stack.c | 2 +- misc/examples/sview_split.c | 2 +- misc/examples/triples.c | 2 +- misc/examples/unordered_set.c | 2 +- misc/examples/utf8replace_c.c | 2 +- misc/examples/vikings.c | 2 +- 95 files changed, 128 insertions(+), 128 deletions(-) (limited to 'misc/benchmarks/various/cspan_bench.c') diff --git a/README.md b/README.md index 1601204d..b7e06790 100644 --- a/README.md +++ b/README.md @@ -181,7 +181,7 @@ Switching to a different container type, e.g. a sorted set (csset): #include // Use a sorted set instead #include -int main() +int main(void) { Floats nums = {0}; Floats_push(&nums, 30.f); diff --git a/docs/carc_api.md b/docs/carc_api.md index 254f868a..8b7b67a1 100644 --- a/docs/carc_api.md +++ b/docs/carc_api.md @@ -97,7 +97,7 @@ bool carc_X_value_eq(const i_key* x, const i_key* y); #define i_keyboxed Arc // Note: use i_keyboxed for carc or cbox value types #include -int main() +int main(void) { Stack s1 = {0}, s2 = {0}; Map *map; diff --git a/docs/cbox_api.md b/docs/cbox_api.md index 83d59521..b6c76d2f 100644 --- a/docs/cbox_api.md +++ b/docs/cbox_api.md @@ -90,7 +90,7 @@ void int_drop(int* x) { #define i_keyboxed IBox // NB: use i_keyboxed instead of i_key #include // IVec : std::vector> -int main() +int main(void) { IVec vec = c_init(Vec, {2021, 2012, 2022, 2015}); ISet set = {0}; diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md index 6bce56af..e053f743 100644 --- a/docs/ccommon_api.md +++ b/docs/ccommon_api.md @@ -137,7 +137,7 @@ bool isPrime(long long i) { return true; } -int main() { +int main(void) { // Get 10 prime numbers starting from 1000. Skip the first 15 primes, // then select every 25th prime (including the initial). crange R = crange_make(1001, INT64_MAX, 2); // 1001, 1003, ... @@ -214,7 +214,7 @@ There is a [benchmark/test file here](../misc/benchmarks/various/csort_bench.c). #include #include -int main() { +int main(void) { int nums[] = {5, 3, 5, 9, 7, 4, 7, 2, 4, 9, 3, 1, 2, 6, 4}; intarray_sort_n(nums, c_arraylen(nums)); c_forrange (i, c_arraylen(arr)) printf(" %d", arr[i]); @@ -230,7 +230,7 @@ possible and very fast. Note that `i_more` must be defined to retain specified t #include #include -int main() { +int main(void) { MyDeq deq = c_init(MyDeq, {5, 3, 5, 9, 7, 4, 7, 2, 4, 9, 3, 1, 2, 6, 4}); MyDeq_sort_n(&deq, MyDeq_size(&deq)); c_foreach (i, MyDeq, deq) printf(" %d", *i.ref); @@ -348,7 +348,7 @@ int gcd(int a, int b) { // greatest common denominator return a; } -int main() +int main(void) { struct triples t = {.n=INT32_MAX}; int n = 0; @@ -500,7 +500,7 @@ cvec_str readFile(const char* name) return vec; } -int main() +int main(void) { c_with (cvec_str vec = readFile(__FILE__), cvec_str_drop(&vec)) c_foreach (i, cvec_str, vec) diff --git a/docs/cdeq_api.md b/docs/cdeq_api.md index 292b0933..c6de6cd6 100644 --- a/docs/cdeq_api.md +++ b/docs/cdeq_api.md @@ -101,7 +101,7 @@ void cdeq_X_value_drop(cdeq_X_value* pval); #include -int main() { +int main(void) { cdeq_i q = cdeq_i_init(); cdeq_i_push_front(&q, 10); c_foreach (i, cdeq_i, q) diff --git a/docs/clist_api.md b/docs/clist_api.md index 023cca41..3d785789 100644 --- a/docs/clist_api.md +++ b/docs/clist_api.md @@ -122,7 +122,7 @@ Interleave *push_front()* / *push_back()* then *sort()*: #include -int main() { +int main(void) { DList list = c_init(DList, {10., 20., 30., 40., 50., 60., 70., 80., 90.}); c_forrange (i, 1, 10) { @@ -159,7 +159,7 @@ Use of *erase_at()* and *erase_range()*: #include -int main () +int main(void) { clist_i L = c_init(clist_i, {10, 20, 30, 40, 50}); // 10 20 30 40 50 @@ -194,7 +194,7 @@ Splice `[30, 40]` from *L2* into *L1* before `3`: #include -int main() { +int main(void) { clist_i L1 = c_init(clist_i, {1, 2, 3, 4, 5}); clist_i L2 = c_init(clist_i, {10, 20, 30, 40, 50}); diff --git a/docs/cmap_api.md b/docs/cmap_api.md index 8ef322e6..eca350b4 100644 --- a/docs/cmap_api.md +++ b/docs/cmap_api.md @@ -121,7 +121,7 @@ bool c_memcmp_eq(const i_keyraw* a, const i_keyraw* b); // ! #define i_val_str #include -int main() +int main(void) { // Create an unordered_map of three strings (that map to strings) cmap_str umap = c_init(cmap_str, { @@ -165,7 +165,7 @@ This example uses a cmap with cstr as mapped value. #define i_val_str #include -int main() +int main(void) { uint32_t col = 0xcc7744ff; @@ -208,7 +208,7 @@ typedef struct { int x, y, z; } Vec3i; #define i_tag vi #include -int main() +int main(void) { // Define map with defered destruct cmap_vi vecs = {0}; @@ -243,7 +243,7 @@ typedef struct { int x, y, z; } Vec3i; #define i_tag iv #include -int main() +int main(void) { cmap_iv vecs = {0} @@ -304,7 +304,7 @@ static inline void Viking_drop(Viking* vk) { #define i_val int #include -int main() +int main(void) { // Use a HashMap to store the vikings' health points. Vikings vikings = {0}; @@ -380,7 +380,7 @@ static inline RViking Viking_toraw(const Viking* vp) { #define i_val int #include -int main() +int main(void) { Vikings vikings = {0}; diff --git a/docs/cpque_api.md b/docs/cpque_api.md index ca94e367..5b63dfd1 100644 --- a/docs/cpque_api.md +++ b/docs/cpque_api.md @@ -68,7 +68,7 @@ i_key cpque_X_value_clone(i_key value); #define i_tag i #include -int main() +int main(void) { intptr_t N = 10000000; crand_t rng = crand_init(1234); diff --git a/docs/cqueue_api.md b/docs/cqueue_api.md index bce62833..b324e5fc 100644 --- a/docs/cqueue_api.md +++ b/docs/cqueue_api.md @@ -74,7 +74,7 @@ void cqueue_X_value_drop(cqueue_X_value* pval); #include -int main() { +int main(void) { cqueue_i Q = cqueue_i_init(); // push() and pop() a few. diff --git a/docs/crandom_api.md b/docs/crandom_api.md index 74e23a6a..22a4f4dd 100644 --- a/docs/crandom_api.md +++ b/docs/crandom_api.md @@ -76,7 +76,7 @@ double crand_norm(crand_t* rng, crand_norm_t* dist); #define i_tag i #include -int main() +int main(void) { enum {N = 10000000}; const double Mean = -12.0, StdDev = 6.0, Scale = 74; diff --git a/docs/cregex_api.md b/docs/cregex_api.md index f87240f8..52476e09 100644 --- a/docs/cregex_api.md +++ b/docs/cregex_api.md @@ -102,7 +102,7 @@ If an error occurs ```cregex_compile``` returns a negative error code stored in #define i_import // include dependent cstr, utf8 and cregex function definitions. #include -int main() { +int main(void) { const char* input = "start date is 2023-03-01, end date 2025-12-31."; const char* pattern = "\\b(\\d\\d\\d\\d)-(\\d\\d)-(\\d\\d)\\b"; diff --git a/docs/cset_api.md b/docs/cset_api.md index 7bce3136..e894ad4f 100644 --- a/docs/cset_api.md +++ b/docs/cset_api.md @@ -83,7 +83,7 @@ cset_X_value cset_X_value_clone(cset_X_value val); #define i_key_str #include -int main () +int main(void) { Strset first, second={0}, third={0}, fourth={0}, fifth; diff --git a/docs/csmap_api.md b/docs/csmap_api.md index 2fd9f6a5..099d7dfc 100644 --- a/docs/csmap_api.md +++ b/docs/csmap_api.md @@ -108,7 +108,7 @@ void csmap_X_value_drop(csmap_X_value* pval); #define i_val_str // ditto #include -int main() +int main(void) { // Create a sorted map of three strings (maps to string) csmap_str colors = c_init(csmap_str, { @@ -166,7 +166,7 @@ static void print_result(strmap_result result) { print_node(result.ref); } -int main() +int main(void) { strmap m = {0}; @@ -191,7 +191,7 @@ This example uses a csmap with cstr as mapped value. #define i_val_str #include -int main() +int main(void) { uint32_t col = 0xcc7744ff; IDSMap idnames = c_init(IDSMap, { {100, "Red"}, {110, "Blue"} }); @@ -237,7 +237,7 @@ static int Vec3i_cmp(const Vec3i* a, const Vec3i* b) { #include #include -int main() +int main(void) { csmap_vi vmap = {0}; diff --git a/docs/cspan_api.md b/docs/cspan_api.md index 1089e48d..09821450 100644 --- a/docs/cspan_api.md +++ b/docs/cspan_api.md @@ -101,7 +101,7 @@ if __name__ == '__main__': #include using_cspan3(myspan, int); // define myspan, myspan2, myspan3. -int main() { +int main(void) { 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); // C-order, i.e. row-major. @@ -123,7 +123,7 @@ int main() { #include #include -int main() { +int main(void) { 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}; std::mdspan ms3(arr, 2, 3, 4); @@ -147,7 +147,7 @@ Slicing cspan without and with reducing the rank: using_cspan3(Span, int); // Shorthand to define Span, Span2, and Span3 -int main() +int main(void) { // c_init() can create any STC container/span from an initializer list: Span span = c_init(Span, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, diff --git a/docs/csset_api.md b/docs/csset_api.md index d086b660..aef3af3c 100644 --- a/docs/csset_api.md +++ b/docs/csset_api.md @@ -83,7 +83,7 @@ csset_X_value csset_X_value_clone(csset_X_value val); #define i_key_str #include -int main () +int main(void) { SSet second={0}, third={0}, fourth={0}, fifth={0}; diff --git a/docs/cstack_api.md b/docs/cstack_api.md index 51889d7f..e799b152 100644 --- a/docs/cstack_api.md +++ b/docs/cstack_api.md @@ -77,7 +77,7 @@ void cstack_X_value_drop(cvec_X_value* pval); #include -int main() { +int main(void) { IStack stk = IStack_init(); for (int i=0; i < 100; ++i) diff --git a/docs/cstr_api.md b/docs/cstr_api.md index c7d19e0c..dae5669f 100644 --- a/docs/cstr_api.md +++ b/docs/cstr_api.md @@ -160,7 +160,7 @@ char* cstrnstrn(const char* str, const char* search, intptr_t slen, intpt #define i_implement #include -int main() { +int main(void) { cstr s0, s1, full_path; c_defer( cstr_drop(&s0), diff --git a/docs/csview_api.md b/docs/csview_api.md index 33df6a64..79a5c07b 100644 --- a/docs/csview_api.md +++ b/docs/csview_api.md @@ -121,7 +121,7 @@ uint64_t csview_hash(const csview* x); #include #include -int main () +int main(void) { cstr str1 = cstr_lit("We think in generalities, but we live in details."); // (quoting Alfred N. Whitehead) @@ -151,7 +151,7 @@ red Apples #define i_import // include dependent cstr, utf8 and cregex function definitions. #include -int main() +int main(void) { cstr s1 = cstr_lit("hell😀 w😀rld"); @@ -198,7 +198,7 @@ cstack_str string_split(csview input, const char* sep) return out; } -int main() +int main(void) { print_split(c_sv("//This is a//double-slash//separated//string"), "//"); print_split(c_sv("This has no matching separator"), "xx"); diff --git a/docs/cvec_api.md b/docs/cvec_api.md index ce85e446..d38ef23f 100644 --- a/docs/cvec_api.md +++ b/docs/cvec_api.md @@ -112,7 +112,7 @@ cvec_X_raw cvec_X_value_drop(cvec_X_value* pval); #include -int main() +int main(void) { // Create a vector containing integers cvec_int vec = {0}; @@ -153,7 +153,7 @@ sorted: 5 7 8 13 16 25 #define i_key_str #include -int main() { +int main(void) { cvec_str names = cvec_str_init(); cvec_str_emplace(&names, "Mary"); diff --git a/include/c11/fmt.h b/include/c11/fmt.h index 45044e33..d2eab8bc 100644 --- a/include/c11/fmt.h +++ b/include/c11/fmt.h @@ -33,7 +33,7 @@ void fmt_close(fmt_stream* ss); #define FMT_SHORTS #include "c11/fmt.h" -int main() { +int main(void) { const double pi = 3.141592653589793; const size_t x = 1234567890; const char* string = "Hello world"; diff --git a/include/stc/algo/crange.h b/include/stc/algo/crange.h index 45ef53a1..03162a2d 100644 --- a/include/stc/algo/crange.h +++ b/include/stc/algo/crange.h @@ -25,7 +25,7 @@ #include #include -int main() +int main(void) { crange r1 = crange_make(80, 90); c_foreach (i, crange, r1) diff --git a/include/stc/algo/filter.h b/include/stc/algo/filter.h index f5de1811..4a227927 100644 --- a/include/stc/algo/filter.h +++ b/include/stc/algo/filter.h @@ -26,7 +26,7 @@ #include #include -int main() +int main(void) { cstack_int stk = c_init(cstack_int, {1, 2, 3, 4, 5, 6, 7, 8, 9}); diff --git a/include/stc/algo/sort.h b/include/stc/algo/sort.h index 01e7d521..06d7395f 100644 --- a/include/stc/algo/sort.h +++ b/include/stc/algo/sort.h @@ -31,7 +31,7 @@ template params: #define i_key int #include -int main() { +int main(void) { int nums[] = {23, 321, 5434, 25, 245, 1, 654, 33, 543, 21}; intarray_sort_n(nums, c_arraylen(nums)); @@ -48,7 +48,7 @@ int main() { #include #include -int main() { +int main(void) { IDeq nums = c_init(IDeq, {5434, 25, 245, 1, 654, 33, 543, 21}); IDeq_push_front(&nums, 23); IDeq_push_front(&nums, 321); diff --git a/include/stc/carc.h b/include/stc/carc.h index b77b7dfb..9ba2ddd1 100644 --- a/include/stc/carc.h +++ b/include/stc/carc.h @@ -46,7 +46,7 @@ void Person_drop(Person* p) { #define i_opt c_no_cmp|c_no_hash // exclude cmp, hash #include -int main() { +int main(void) { ArcPers p = ArcPers_from(Person_make("John", "Smiths")); ArcPers q = ArcPers_clone(p); // share the pointer @@ -225,4 +225,4 @@ STC_INLINE void _cx_MEMB(_assign)(_cx_Self* self, _cx_Self ptr) { #undef _i_atomic_inc #undef _i_atomic_dec_and_test #include "priv/template2.h" -#undef _i_carc \ No newline at end of file +#undef _i_carc diff --git a/include/stc/cbits.h b/include/stc/cbits.h index 66bc6354..3b5785d3 100644 --- a/include/stc/cbits.h +++ b/include/stc/cbits.h @@ -26,7 +26,7 @@ Similar to boost::dynamic_bitset / std::bitset #include #include "cbits.h" -int main() { +int main(void) { cbits bset = cbits_with_size(23, true); cbits_reset(&bset, 9); cbits_resize(&bset, 43, false); diff --git a/include/stc/cbox.h b/include/stc/cbox.h index 86d5a6a6..25d41b92 100644 --- a/include/stc/cbox.h +++ b/include/stc/cbox.h @@ -47,7 +47,7 @@ void Person_drop(Person* p) { #define i_no_cmp // no cmp/hash is defined #include -int main() { +int main(void) { c_auto (PBox, p, q) { p = PBox_from(Person_from("John Smiths", "josmiths@gmail.com")); @@ -205,4 +205,4 @@ STC_INLINE void _cx_MEMB(_assign)(_cx_Self* self, _cx_Self* moved) { { return c_default_hash(&self->get); } #endif #include "priv/template2.h" -#undef _i_cbox \ No newline at end of file +#undef _i_cbox diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h index 45c3a360..1f9ea80d 100644 --- a/include/stc/ccommon.h +++ b/include/stc/ccommon.h @@ -85,7 +85,7 @@ typedef long long _llong; #define c_assert(expr) assert(expr) #endif #define c_container_of(p, C, m) ((C*)((char*)(1 ? (p) : &((C*)0)->m) - offsetof(C, m))) -#define c_const_cast(T, p) ((T)(p) + 0*sizeof((T)0 == (p))) +#define c_const_cast(T, p) ((T)(1 ? (p) : (T)0)) #define c_swap(T, xp, yp) do { T *_xp = xp, *_yp = yp, \ _tv = *_xp; *_xp = *_yp; *_yp = _tv; } while (0) #define c_sizeof (intptr_t)sizeof @@ -96,8 +96,8 @@ typedef long long _llong; #define c_memmove(d, s, ilen) memmove(d, s, c_i2u(ilen)) #define c_memset(d, val, ilen) memset(d, val, c_i2u(ilen)) #define c_memcmp(a, b, ilen) memcmp(a, b, c_i2u(ilen)) -#define c_u2i(u) ((intptr_t)((u) + 0*sizeof((u) == 1U))) -#define c_i2u(i) ((size_t)(i) + 0*sizeof((i) == 1)) +#define c_u2i(u) ((intptr_t)(1 ? (u) : (size_t)1)) +#define c_i2u(i) ((size_t)(1 ? (i) : (intptr_t)1)) #define c_LTu(a, b) ((size_t)(a) < (size_t)(b)) // x and y are i_keyraw* type, defaults to i_key*: diff --git a/include/stc/clist.h b/include/stc/clist.h index 9cc1bb39..d7cf30b9 100644 --- a/include/stc/clist.h +++ b/include/stc/clist.h @@ -32,7 +32,7 @@ #define i_tag ix #include - int main() + int main(void) { c_auto (clist_ix, list) { diff --git a/include/stc/crand.h b/include/stc/crand.h index 89b681cd..0a6aa9e0 100644 --- a/include/stc/crand.h +++ b/include/stc/crand.h @@ -29,7 +29,7 @@ // crand: Pseudo-random number generator #include "stc/crand.h" -int main() { +int main(void) { uint64_t seed = 123456789; crand_t rng = crand_init(seed); crand_unif_t dist1 = crand_unif_init(1, 6); diff --git a/include/stc/cvec.h b/include/stc/cvec.h index 9b95306e..d08e382f 100644 --- a/include/stc/cvec.h +++ b/include/stc/cvec.h @@ -44,7 +44,7 @@ struct MyStruct { #define i_tag i32 #include -int main() { +int main(void) { cvec_i32 vec = {0}; cvec_i32_push(&vec, 123); cvec_i32_drop(&vec); diff --git a/misc/benchmarks/plotbench/cpque_benchmark.cpp b/misc/benchmarks/plotbench/cpque_benchmark.cpp index 2d4c7a28..6c62ae3e 100644 --- a/misc/benchmarks/plotbench/cpque_benchmark.cpp +++ b/misc/benchmarks/plotbench/cpque_benchmark.cpp @@ -58,7 +58,7 @@ void stc_test() } -int main() +int main(void) { puts("STD P.QUEUE:"); std_test(); diff --git a/misc/benchmarks/various/cspan_bench.c b/misc/benchmarks/various/cspan_bench.c index 392c9d3f..e3997ff0 100644 --- a/misc/benchmarks/various/cspan_bench.c +++ b/misc/benchmarks/various/cspan_bench.c @@ -114,7 +114,7 @@ static void MDRanges_loop_over_joined(intptr_t state) printf("joined: %.1f ms, %f\n", 1000.0f * t / CLOCKS_PER_SEC, sum); } -int main() +int main(void) { for (int i = 0; i < nx * ny * nz; ++i) Vin[i] = i + 1.23; diff --git a/misc/benchmarks/various/rust_cmap.c b/misc/benchmarks/various/rust_cmap.c index abdb42b0..97047e0b 100644 --- a/misc/benchmarks/various/rust_cmap.c +++ b/misc/benchmarks/various/rust_cmap.c @@ -22,7 +22,7 @@ uint64_t romu_trio(uint64_t s[3]) { return xp; } -int main() +int main(void) { cmap_u64 m = {0}; diff --git a/misc/benchmarks/various/sso_bench.cpp b/misc/benchmarks/various/sso_bench.cpp index 6d3d107a..244c1291 100644 --- a/misc/benchmarks/various/sso_bench.cpp +++ b/misc/benchmarks/various/sso_bench.cpp @@ -112,7 +112,7 @@ int benchmark_lookup(C& container, const int n, const int strsize) { } #include -int main() { +int main(void) { uint64_t seed = time(NULL); // 4321; int sum, n; diff --git a/misc/benchmarks/various/string_bench_STC.cpp b/misc/benchmarks/various/string_bench_STC.cpp index 319b0b19..a5dfd901 100644 --- a/misc/benchmarks/various/string_bench_STC.cpp +++ b/misc/benchmarks/various/string_bench_STC.cpp @@ -184,7 +184,7 @@ void benchmark( //const size_t MAX_LOOP = 1000000; const size_t MAX_LOOP = 2000; -int main() +int main(void) { c_auto (cvec_str, vec_string) c_auto (cvec_sv, vec_stringview) diff --git a/misc/benchmarks/various/string_bench_STD.cpp b/misc/benchmarks/various/string_bench_STD.cpp index 07934948..153ac02f 100644 --- a/misc/benchmarks/various/string_bench_STD.cpp +++ b/misc/benchmarks/various/string_bench_STD.cpp @@ -194,7 +194,7 @@ void benchmark( //const size_t MAX_LOOP = 1000000; const size_t MAX_LOOP = 2000; -int main() +int main(void) { std::vector vec_shortstr; std::vector vec_shortstrview; diff --git a/misc/examples/arc_containers.c b/misc/examples/arc_containers.c index 524758e7..2fb04c56 100644 --- a/misc/examples/arc_containers.c +++ b/misc/examples/arc_containers.c @@ -24,7 +24,7 @@ #define i_keyboxed Arc // as above #include -int main() +int main(void) { Stack stack = {0}; List list = {0}; diff --git a/misc/examples/arc_demo.c b/misc/examples/arc_demo.c index 547e1737..87d64e67 100644 --- a/misc/examples/arc_demo.c +++ b/misc/examples/arc_demo.c @@ -20,7 +20,7 @@ void int_drop(int* x) { #define i_keyboxed Arc // note: as above. #include // cvec_Arc (like: std::vector>) -int main() +int main(void) { const int years[] = {2021, 2012, 2022, 2015}; diff --git a/misc/examples/arcvec_erase.c b/misc/examples/arcvec_erase.c index f409258b..addef8b7 100644 --- a/misc/examples/arcvec_erase.c +++ b/misc/examples/arcvec_erase.c @@ -13,7 +13,7 @@ void show_drop(int* x) { printf("drop: %d\n", *x); } #include // Vec: cvec -int main() +int main(void) { Vec vec = c_init(Vec, {2012, 1990, 2012, 2019, 2015}); diff --git a/misc/examples/birthday.c b/misc/examples/birthday.c index 2820c42f..4742cb45 100644 --- a/misc/examples/birthday.c +++ b/misc/examples/birthday.c @@ -60,7 +60,7 @@ void test_distribution(void) cmap_x_drop(&map); } -int main() +int main(void) { seed = (uint64_t)time(NULL); test_distribution(); diff --git a/misc/examples/bits2.c b/misc/examples/bits2.c index 913bd185..de2f16f4 100644 --- a/misc/examples/bits2.c +++ b/misc/examples/bits2.c @@ -5,7 +5,7 @@ #define i_capacity 80 // enable fixed bitset on the stack #include -int main() +int main(void) { Bits s1 = Bits_from("1110100110111"); diff --git a/misc/examples/books.c b/misc/examples/books.c index 7f0660b8..1fd57f27 100644 --- a/misc/examples/books.c +++ b/misc/examples/books.c @@ -7,7 +7,7 @@ // Type inference lets us omit an explicit type signature (which // would be `HashMap` in this example). -int main() +int main(void) { cmap_str book_reviews = {0}; diff --git a/misc/examples/box.c b/misc/examples/box.c index 3f55e15d..94d126c0 100644 --- a/misc/examples/box.c +++ b/misc/examples/box.c @@ -36,7 +36,7 @@ void Person_drop(Person* p) { #define i_keyboxed PBox // "arcbox" informs that PBox is a smart pointer. #include -int main() +int main(void) { Persons vec = {0}; PBox p = PBox_from(Person_make("Laura", "Palmer")); diff --git a/misc/examples/cointerleave.c b/misc/examples/cointerleave.c index c3c5926a..599ceaab 100644 --- a/misc/examples/cointerleave.c +++ b/misc/examples/cointerleave.c @@ -56,7 +56,7 @@ void Use(void) c_drop(IVec, &a, &b); } -int main() +int main(void) { Use(); } diff --git a/misc/examples/complex.c b/misc/examples/complex.c index 405afef3..4eb1574b 100644 --- a/misc/examples/complex.c +++ b/misc/examples/complex.c @@ -28,7 +28,7 @@ #include -int main() +int main(void) { MapMap mmap = {0}; diff --git a/misc/examples/convert.c b/misc/examples/convert.c index 3f2f60f6..fa64560e 100644 --- a/misc/examples/convert.c +++ b/misc/examples/convert.c @@ -11,7 +11,7 @@ #define i_key_str #include -int main() +int main(void) { cmap_str map, mclone; cvec_str keys = {0}, values = {0}; diff --git a/misc/examples/csmap_erase.c b/misc/examples/csmap_erase.c index 9433d370..8d4eeae3 100644 --- a/misc/examples/csmap_erase.c +++ b/misc/examples/csmap_erase.c @@ -16,7 +16,7 @@ void printmap(mymap m) printf("\nsize() == %" c_ZI "\n\n", mymap_size(&m)); } -int main() +int main(void) { mymap m1 = {0}; diff --git a/misc/examples/csmap_find.c b/misc/examples/csmap_find.c index b535e9ad..c392338d 100644 --- a/misc/examples/csmap_find.c +++ b/misc/examples/csmap_find.c @@ -40,7 +40,7 @@ void findit(csmap_istr c, csmap_istr_key val) } } -int main() +int main(void) { csmap_istr m1 = c_init(csmap_istr, {{40, "Zr"}, {45, "Rh"}}); cvec_istr v = {0}; diff --git a/misc/examples/csmap_insert.c b/misc/examples/csmap_insert.c index df638c22..c9f02891 100644 --- a/misc/examples/csmap_insert.c +++ b/misc/examples/csmap_insert.c @@ -29,7 +29,7 @@ void print_istr(csmap_istr map) { puts(""); } -int main() +int main(void) { // insert single values csmap_ii m1 = {0}; diff --git a/misc/examples/csset_erase.c b/misc/examples/csset_erase.c index 649bb1e3..9c7f5e1a 100644 --- a/misc/examples/csset_erase.c +++ b/misc/examples/csset_erase.c @@ -3,7 +3,7 @@ #define i_key int #include -int main() +int main(void) { csset_int set = c_init(csset_int, {30, 20, 80, 40, 60, 90, 10, 70, 50}); diff --git a/misc/examples/cstr_match.c b/misc/examples/cstr_match.c index 10a843cf..be03e981 100644 --- a/misc/examples/cstr_match.c +++ b/misc/examples/cstr_match.c @@ -3,7 +3,7 @@ #include #include -int main() +int main(void) { cstr ss = cstr_lit("The quick brown fox jumps over the lazy dog.JPG"); diff --git a/misc/examples/demos.c b/misc/examples/demos.c index 2e91b20c..ecc89f2e 100644 --- a/misc/examples/demos.c +++ b/misc/examples/demos.c @@ -1,7 +1,7 @@ #define i_implement #include -void stringdemo1() +void stringdemo1(void) { cstr cs = cstr_lit("one-nine-three-seven-five"); printf("%s.\n", cstr_str(&cs)); @@ -32,7 +32,7 @@ void stringdemo1() #define i_tag ix #include -void vectordemo1() +void vectordemo1(void) { cvec_ix bignums = cvec_ix_with_capacity(100); cvec_ix_reserve(&bignums, 100); @@ -55,7 +55,7 @@ void vectordemo1() #define i_key_str #include -void vectordemo2() +void vectordemo2(void) { cvec_str names = {0}; cvec_str_emplace_back(&names, "Mary"); @@ -77,7 +77,7 @@ void vectordemo2() #define i_native_cmp #include -void listdemo1() +void listdemo1(void) { clist_ix nums = {0}, nums2 = {0}; for (int i = 0; i < 10; ++i) @@ -109,7 +109,7 @@ void listdemo1() #define i_tag i #include -void setdemo1() +void setdemo1(void) { cset_i nums = {0}; cset_i_insert(&nums, 8); @@ -125,7 +125,7 @@ void setdemo1() #define i_tag ii #include -void mapdemo1() +void mapdemo1(void) { cmap_ii nums = {0}; cmap_ii_insert(&nums, 8, 64); @@ -139,7 +139,7 @@ void mapdemo1() #define i_tag si #include -void mapdemo2() +void mapdemo2(void) { cmap_si nums = {0}; cmap_si_emplace_or_assign(&nums, "Hello", 64); @@ -161,7 +161,7 @@ void mapdemo2() #define i_val_str #include -void mapdemo3() +void mapdemo3(void) { cmap_str table = {0}; cmap_str_emplace(&table, "Map", "test"); @@ -181,7 +181,7 @@ void mapdemo3() cmap_str_drop(&table); // frees key and value cstrs, and hash table. } -int main() +int main(void) { printf("\nSTRINGDEMO1\n"); stringdemo1(); printf("\nVECTORDEMO1\n"); vectordemo1(); diff --git a/misc/examples/dining_philosophers.c b/misc/examples/dining_philosophers.c index 61fe67fb..a5063a42 100644 --- a/misc/examples/dining_philosophers.c +++ b/misc/examples/dining_philosophers.c @@ -86,7 +86,7 @@ int dining(struct Dining* d) return 0; } -int main() +int main(void) { struct Dining dine; cco_reset(&dine); diff --git a/misc/examples/forloops.c b/misc/examples/forloops.c index 99b12871..47cced8f 100644 --- a/misc/examples/forloops.c +++ b/misc/examples/forloops.c @@ -11,7 +11,7 @@ #include -int main() +int main(void) { puts("c_forrange:"); c_forrange (30) printf(" xx"); diff --git a/misc/examples/functor.c b/misc/examples/functor.c index ea409a56..e3bde1dd 100644 --- a/misc/examples/functor.c +++ b/misc/examples/functor.c @@ -30,7 +30,7 @@ static bool int_less(const int* x, const int* y) { return *x < *y; } static bool int_greater(const int* x, const int* y) { return *x > *y; } static bool int_lambda(const int* x, const int* y) { return (*x ^ 1) < (*y ^ 1); } -int main() +int main(void) { const int data[] = {1,8,5,6,3,4,0,9,7,2}, n = c_arraylen(data); printf("data: \t"); diff --git a/misc/examples/gauss2.c b/misc/examples/gauss2.c index 67586181..1ab8ade5 100644 --- a/misc/examples/gauss2.c +++ b/misc/examples/gauss2.c @@ -10,7 +10,7 @@ #define i_val int #include -int main() +int main(void) { enum {N = 5000000}; uint64_t seed = (uint64_t)time(NULL); diff --git a/misc/examples/generator.c b/misc/examples/generator.c index 3ff7a645..a15f9ba5 100644 --- a/misc/examples/generator.c +++ b/misc/examples/generator.c @@ -42,7 +42,7 @@ Triple_iter Triple_begin(Triple* g) { } -int main() +int main(void) { puts("Pythagorean triples with c < 100:"); Triple triple = {.size=30}; // max number of triples diff --git a/misc/examples/intrusive.c b/misc/examples/intrusive.c index 1e3f7b83..4fca654b 100644 --- a/misc/examples/intrusive.c +++ b/misc/examples/intrusive.c @@ -14,7 +14,7 @@ void printList(List list) { puts(""); } -int main() { +int main(void) { List list = {0}; c_forlist (i, int, {6, 9, 3, 1, 7, 4, 5, 2, 8}) List_push_back_node(&list, c_new(List_node, {0, *i.ref})); diff --git a/misc/examples/list.c b/misc/examples/list.c index a0045db9..fa33305a 100644 --- a/misc/examples/list.c +++ b/misc/examples/list.c @@ -8,7 +8,7 @@ #define i_native_cmp #include -int main() { +int main(void) { const int n = 3000000; DList list = {0}; diff --git a/misc/examples/list_erase.c b/misc/examples/list_erase.c index 357dd75b..211c5a5d 100644 --- a/misc/examples/list_erase.c +++ b/misc/examples/list_erase.c @@ -5,7 +5,7 @@ #define i_key int #include -int main () +int main(void) { IList L = c_init(IList, {10, 20, 30, 40, 50}); diff --git a/misc/examples/list_splice.c b/misc/examples/list_splice.c index 25c2a42d..f1fd6e1f 100644 --- a/misc/examples/list_splice.c +++ b/misc/examples/list_splice.c @@ -13,7 +13,7 @@ void print_ilist(const char* s, clist_i list) puts(""); } -int main () +int main(void) { clist_i list1 = c_init(clist_i, {1, 2, 3, 4, 5}); clist_i list2 = c_init(clist_i, {10, 20, 30, 40, 50}); diff --git a/misc/examples/lower_bound.c b/misc/examples/lower_bound.c index ee32f49b..e5d816e9 100644 --- a/misc/examples/lower_bound.c +++ b/misc/examples/lower_bound.c @@ -7,7 +7,7 @@ #define i_key int #include -int main() +int main(void) { // TEST SORTED VECTOR { diff --git a/misc/examples/mmap.c b/misc/examples/mmap.c index fd00499c..04a605a7 100644 --- a/misc/examples/mmap.c +++ b/misc/examples/mmap.c @@ -30,7 +30,7 @@ void insert(Multimap* mmap, int key, const char* str) clist_str_emplace_back(list, str); } -int main() +int main(void) { Multimap mmap = {0}; diff --git a/misc/examples/multidim.c b/misc/examples/multidim.c index 45b97378..798a1126 100644 --- a/misc/examples/multidim.c +++ b/misc/examples/multidim.c @@ -6,7 +6,7 @@ using_cspan3(ispan, int); -int main() +int main(void) { cstack_int v = c_init(cstack_int, {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24}); diff --git a/misc/examples/multimap.c b/misc/examples/multimap.c index a89b251b..1068a5dc 100644 --- a/misc/examples/multimap.c +++ b/misc/examples/multimap.c @@ -66,7 +66,7 @@ void OlympicLoc_drop(OlympicLoc* self) { } -int main() +int main(void) { // Define the multimap with destructor defered to when block is completed. csmap_OL multimap = {0}; diff --git a/misc/examples/music_arc.c b/misc/examples/music_arc.c index 49008523..16111b0b 100644 --- a/misc/examples/music_arc.c +++ b/misc/examples/music_arc.c @@ -31,7 +31,7 @@ void Song_drop(Song* s) { #define i_keyboxed SongArc // use i_keyboxed on carc / cbox (instead of i_key) #include -void example3() +void example3(void) { SongVec vec1 = c_init(SongVec, { Song_make("Bob Dylan", "The Times They Are A Changing"), @@ -61,7 +61,7 @@ void example3() c_drop(SongVec, &vec1, &vec2); } -int main() +int main(void) { example3(); } diff --git a/misc/examples/new_list.c b/misc/examples/new_list.c index ee250b2b..9676e7b4 100644 --- a/misc/examples/new_list.c +++ b/misc/examples/new_list.c @@ -43,7 +43,7 @@ void MyStruct_drop(MyStruct* s) { } -int main() +int main(void) { MyStruct my = {0}; clist_i32_push_back(&my.intlist, 123); diff --git a/misc/examples/new_map.c b/misc/examples/new_map.c index 277bcbc2..de990040 100644 --- a/misc/examples/new_map.c +++ b/misc/examples/new_map.c @@ -41,7 +41,7 @@ int point_cmp(const Point* a, const Point* b) { #include -int main() +int main(void) { cmap_pnt pmap = c_init(cmap_pnt, {{{42, 14}, 1}, {{32, 94}, 2}, {{62, 81}, 3}}); diff --git a/misc/examples/new_pque.c b/misc/examples/new_pque.c index 3df39e0e..16823bb6 100644 --- a/misc/examples/new_pque.c +++ b/misc/examples/new_pque.c @@ -8,7 +8,7 @@ typedef struct Point { int x, y; } Point; #include -int main() +int main(void) { PointQ pque = c_init(PointQ, {{23, 80}, {12, 32}, {54, 74}, {12, 62}}); // print diff --git a/misc/examples/new_queue.c b/misc/examples/new_queue.c index 104871bf..f3592df6 100644 --- a/misc/examples/new_queue.c +++ b/misc/examples/new_queue.c @@ -20,7 +20,7 @@ int point_cmp(const Point* a, const Point* b) { #define i_key int #include -int main() { +int main(void) { int n = 50000000; crand_t rng = crand_init((uint64_t)time(NULL)); crand_unif_t dist = crand_unif_init(0, n); diff --git a/misc/examples/new_smap.c b/misc/examples/new_smap.c index 77c4cdce..ee946c9a 100644 --- a/misc/examples/new_smap.c +++ b/misc/examples/new_smap.c @@ -36,7 +36,7 @@ int point_cmp(const Point* a, const Point* b) { #include -int main() +int main(void) { PMap pmap = c_init(PMap, { {{42, 14}, 1}, diff --git a/misc/examples/new_vec.c b/misc/examples/new_vec.c index 6d928cfc..88efd55a 100644 --- a/misc/examples/new_vec.c +++ b/misc/examples/new_vec.c @@ -23,7 +23,7 @@ typedef struct Point { int x, y; } Point; #define i_is_forward #include -int main() +int main(void) { MyStruct my = {0}; diff --git a/misc/examples/person_arc.c b/misc/examples/person_arc.c index 3a759610..38c883a7 100644 --- a/misc/examples/person_arc.c +++ b/misc/examples/person_arc.c @@ -39,7 +39,7 @@ void Person_drop(Person* p) { #include -int main() +int main(void) { PSPtr p = PSPtr_from(Person_make("Laura", "Palmer")); PSPtr q = PSPtr_from(Person_clone(*p.get)); // deep copy diff --git a/misc/examples/printspan.c b/misc/examples/printspan.c index 5084536a..cd3c5f4f 100644 --- a/misc/examples/printspan.c +++ b/misc/examples/printspan.c @@ -20,7 +20,7 @@ void printMe(intspan container) { puts(""); } -int main() +int main(void) { intspan sp1 = cspan_init(intspan, {1, 2}); printMe( sp1 ); diff --git a/misc/examples/priority.c b/misc/examples/priority.c index 148e8fc5..bf2e188a 100644 --- a/misc/examples/priority.c +++ b/misc/examples/priority.c @@ -8,7 +8,7 @@ #define i_tag i #include -int main() { +int main(void) { intptr_t N = 10000000; crand_t rng = crand_init((uint64_t)time(NULL)); crand_unif_t dist = crand_unif_init(0, N * 10); diff --git a/misc/examples/queue.c b/misc/examples/queue.c index 3154f115..56b5beb9 100644 --- a/misc/examples/queue.c +++ b/misc/examples/queue.c @@ -5,7 +5,7 @@ #define i_tag i #include -int main() { +int main(void) { int n = 100000000; crand_unif_t dist; crand_t rng = crand_init(1234); diff --git a/misc/examples/random.c b/misc/examples/random.c index e783fe55..b7c0f277 100644 --- a/misc/examples/random.c +++ b/misc/examples/random.c @@ -2,7 +2,7 @@ #include #include -int main() +int main(void) { const int N = 1000000000; const uint64_t seed = (uint64_t)time(NULL), range = 1000000; diff --git a/misc/examples/rawptr_elements.c b/misc/examples/rawptr_elements.c index 9c394d8e..694ce12e 100644 --- a/misc/examples/rawptr_elements.c +++ b/misc/examples/rawptr_elements.c @@ -25,7 +25,7 @@ #define i_valboxed IBox // i_valboxed: use properties from IBox automatically #include -int main() +int main(void) { // These have the same behaviour, except IBox has a get member: SIPtrMap map1 = {0}; diff --git a/misc/examples/read.c b/misc/examples/read.c index c25cd740..b12f7409 100644 --- a/misc/examples/read.c +++ b/misc/examples/read.c @@ -15,7 +15,7 @@ cvec_str read_file(const char* name) return vec; } -int main() +int main(void) { int n = 0; c_with (cvec_str vec = read_file(__FILE__), cvec_str_drop(&vec)) diff --git a/misc/examples/regex2.c b/misc/examples/regex2.c index 734190cb..a798b1a1 100644 --- a/misc/examples/regex2.c +++ b/misc/examples/regex2.c @@ -1,7 +1,7 @@ #define i_import #include -int main() +int main(void) { struct { const char *pattern, *input; } s[] = { {"(\\d\\d\\d\\d)[-_](1[0-2]|0[1-9])[-_](3[01]|[12][0-9]|0[1-9])", diff --git a/misc/examples/regex_match.c b/misc/examples/regex_match.c index 88d3747b..11426d2d 100644 --- a/misc/examples/regex_match.c +++ b/misc/examples/regex_match.c @@ -6,7 +6,7 @@ #define i_key float #include -int main() +int main(void) { // Lets find the first sequence of digits in a string const char *str = "Hello numeric world, there are 24 hours in a day, 3600 seconds in an hour." diff --git a/misc/examples/regex_replace.c b/misc/examples/regex_replace.c index 76664b1b..f1ea2711 100644 --- a/misc/examples/regex_replace.c +++ b/misc/examples/regex_replace.c @@ -12,7 +12,7 @@ bool add_10_years(int i, csview match, cstr* out) { return false; } -int main() +int main(void) { const char* pattern = "\\b(\\d\\d\\d\\d)-(1[0-2]|0[1-9])-(3[01]|[12][0-9]|0[1-9])\\b"; const char* input = "start date: 2015-12-31, end date: 2022-02-28"; diff --git a/misc/examples/replace.c b/misc/examples/replace.c index 9ac26c07..59a56bf7 100644 --- a/misc/examples/replace.c +++ b/misc/examples/replace.c @@ -1,7 +1,7 @@ #define i_implement #include -int main () +int main(void) { const char *base = "this is a test string."; const char *s2 = "n example"; diff --git a/misc/examples/scheduler.c b/misc/examples/scheduler.c index d812ff42..38defd0f 100644 --- a/misc/examples/scheduler.c +++ b/misc/examples/scheduler.c @@ -68,7 +68,7 @@ void Use(void) Scheduler_drop(&scheduler); } -int main() +int main(void) { Use(); } diff --git a/misc/examples/sidebyside.cpp b/misc/examples/sidebyside.cpp index a7c1008c..9414b691 100644 --- a/misc/examples/sidebyside.cpp +++ b/misc/examples/sidebyside.cpp @@ -13,7 +13,7 @@ #define i_val int #include -int main() { +int main(void) { { std::map hist; hist.emplace(12, 100).first->second += 1; diff --git a/misc/examples/sorted_map.c b/misc/examples/sorted_map.c index ff727632..89381554 100644 --- a/misc/examples/sorted_map.c +++ b/misc/examples/sorted_map.c @@ -5,7 +5,7 @@ #define i_val int #include -int main() +int main(void) { // empty map containers diff --git a/misc/examples/splitstr.c b/misc/examples/splitstr.c index 32b5f17f..ef7ed174 100644 --- a/misc/examples/splitstr.c +++ b/misc/examples/splitstr.c @@ -4,7 +4,7 @@ #define i_implement #include -int main() +int main(void) { puts("Split with c_fortoken (csview):"); diff --git a/misc/examples/sso_map.c b/misc/examples/sso_map.c index b78dcb2e..4f84b651 100644 --- a/misc/examples/sso_map.c +++ b/misc/examples/sso_map.c @@ -4,7 +4,7 @@ #define i_val_str #include -int main() +int main(void) { cmap_str m = {0}; cmap_str_emplace(&m, "Test short", "This is a short string"); diff --git a/misc/examples/sso_substr.c b/misc/examples/sso_substr.c index 9b062eed..687658df 100644 --- a/misc/examples/sso_substr.c +++ b/misc/examples/sso_substr.c @@ -3,7 +3,7 @@ #define i_implement #include -int main () +int main(void) { cstr str = cstr_lit("We think in generalities, but we live in details."); csview sv1 = cstr_substr_ex(&str, 3, 5); // "think" diff --git a/misc/examples/stack.c b/misc/examples/stack.c index 96bab24b..6297fb6f 100644 --- a/misc/examples/stack.c +++ b/misc/examples/stack.c @@ -10,7 +10,7 @@ #define i_key char #include -int main() { +int main(void) { cstack_i stack = {0}; cstack_c chars = {0}; diff --git a/misc/examples/sview_split.c b/misc/examples/sview_split.c index 782e4096..ac275da0 100644 --- a/misc/examples/sview_split.c +++ b/misc/examples/sview_split.c @@ -3,7 +3,7 @@ #define i_implement #include -int main() +int main(void) { // No memory allocations or string length calculations! const csview date = c_sv("2021/03/12"); diff --git a/misc/examples/triples.c b/misc/examples/triples.c index a8ca6b47..9f2fcc1e 100644 --- a/misc/examples/triples.c +++ b/misc/examples/triples.c @@ -52,7 +52,7 @@ int triples_coro(struct triples* t) { return 0; } -int main() +int main(void) { puts("Vanilla triples:"); triples_vanilla(5); diff --git a/misc/examples/unordered_set.c b/misc/examples/unordered_set.c index 14d69ce5..dd899d78 100644 --- a/misc/examples/unordered_set.c +++ b/misc/examples/unordered_set.c @@ -5,7 +5,7 @@ #define i_key_str #include -int main() +int main(void) { // declaring set for storing string data-type cset_str stringSet = {0}; diff --git a/misc/examples/utf8replace_c.c b/misc/examples/utf8replace_c.c index 17352fee..1d54486f 100644 --- a/misc/examples/utf8replace_c.c +++ b/misc/examples/utf8replace_c.c @@ -1,7 +1,7 @@ #define i_implement #include -int main() +int main(void) { cstr hello = cstr_lit("hell😀 w😀rld"); printf("%s\n", cstr_str(&hello)); diff --git a/misc/examples/vikings.c b/misc/examples/vikings.c index d9024052..d6125854 100644 --- a/misc/examples/vikings.c +++ b/misc/examples/vikings.c @@ -41,7 +41,7 @@ static inline RViking Viking_toraw(const Viking* vp) { #define i_val int // mapped type #include -int main() +int main(void) { Vikings vikings = {0}; Vikings_emplace(&vikings, c_LITERAL(RViking){"Einar", "Norway"}, 20); -- cgit v1.2.3 From 23eeedb3fc298602732f394adba6a43c876ca7d8 Mon Sep 17 00:00:00 2001 From: tylov Date: Sun, 16 Jul 2023 09:07:01 +0200 Subject: Moved _cspan_next2() to header section in cspan.h to allow optimizations. --- include/stc/cspan.h | 22 ++++++++++------------ misc/benchmarks/various/cspan_bench.c | 18 +++++++++--------- 2 files changed, 19 insertions(+), 21 deletions(-) (limited to 'misc/benchmarks/various/cspan_bench.c') diff --git a/include/stc/cspan.h b/include/stc/cspan.h index 582e1004..dcb02961 100644 --- a/include/stc/cspan.h +++ b/include/stc/cspan.h @@ -114,7 +114,7 @@ using_cspan_tuple(5); using_cspan_tuple(6); using_cspan_tuple(7); using_cspan_tuple(8); #define c_END -1 -#define c_ALL 0,-1 +#define c_ALL 0,c_END /* Use cspan_init() for static initialization only. c_init() for non-static init. */ #define cspan_init(SpanType, ...) \ @@ -221,8 +221,16 @@ STC_INLINE intptr_t _cspan_idxN(int rank, const int32_t shape[], const int32_t s return off; } +STC_INLINE 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; +} #define _cspan_next1(pos, shape, stride, rank, i, inc) (++pos[0], stride[0]) -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 @@ -254,16 +262,6 @@ STC_DEF int32_t* _cspan_shape2stride(char order, int32_t shape[], int rank) { return shape; } -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 oshape[], int32_t ostride[], int* orank, const int32_t shape[], const int32_t stride[], int rank, const int32_t a[][2]) { diff --git a/misc/benchmarks/various/cspan_bench.c b/misc/benchmarks/various/cspan_bench.c index e3997ff0..f4b067f8 100644 --- a/misc/benchmarks/various/cspan_bench.c +++ b/misc/benchmarks/various/cspan_bench.c @@ -13,7 +13,6 @@ enum { }; int lx = 15, ly = 10, lz = 5; int hx = 30, hy = 15, hz = 15; -intptr_t n = 100000; // define the contents of two nx x ny x nz arrays in and out double Vout[nx * ny * nz]; @@ -21,12 +20,12 @@ double Vin[nx * ny * nz]; //, 1.23; // define some slice indices for each dimension -static void MDRanges_setup(intptr_t state) +static void MDRanges_setup(intptr_t n) { double sum = 0; clock_t t = clock(); - for (intptr_t s = 0; s < state; ++s) + for (intptr_t s = 0; s < n; ++s) { MD3 r_in = cspan_md(Vin, nx, ny, nz); MD3 r_out = cspan_md(Vout, nx, ny, nz); @@ -41,12 +40,12 @@ static void MDRanges_setup(intptr_t state) printf("setup: %.1f ms, %f\n", 1000.0f * t / CLOCKS_PER_SEC, sum); } -static void TraditionalForLoop(intptr_t state) +static void TraditionalForLoop(intptr_t n) { clock_t t = clock(); double sum = 0; - for (int s = 0; s < state; ++s) { + for (int s = 0; s < n; ++s) { for (int x = lx; x < hx; ++x) { for (int y = ly; y < hy; ++y) { for (int z = lz; z < hz; ++z) { @@ -62,7 +61,7 @@ static void TraditionalForLoop(intptr_t state) printf("forloop: %.1f ms, %f\n", 1000.0f * t / CLOCKS_PER_SEC, sum); } -static void MDRanges_nested_loop(intptr_t state) +static void MDRanges_nested_loop(intptr_t n) { clock_t t = clock(); MD3 r_in = cspan_md(Vin, nx, ny, nz); @@ -73,7 +72,7 @@ static void MDRanges_nested_loop(intptr_t state) // C++23: for (auto [o, i] : std::views::zip(flat(r_out), flat(r_in))) { o = i; } double sum = 0; - for (intptr_t s = 0; s < state; ++s) { + for (intptr_t s = 0; s < n; ++s) { for (int x = 0; x < r_in.shape[0]; ++x) { for (int y = 0; y < r_in.shape[1]; ++y) { for (int z = 0; z < r_in.shape[2]; ++z) @@ -89,7 +88,7 @@ static void MDRanges_nested_loop(intptr_t state) printf("nested: %.1f ms, %f\n", 1000.0f * t / CLOCKS_PER_SEC, sum); } -static void MDRanges_loop_over_joined(intptr_t state) +static void MDRanges_loop_over_joined(intptr_t n) { MD3 r_in = cspan_md(Vin, nx, ny, nz); MD3 r_out = cspan_md(Vout, nx, ny, nz); @@ -100,7 +99,7 @@ static void MDRanges_loop_over_joined(intptr_t state) double sum = 0; clock_t t = clock(); - for (intptr_t s = 0; s < state; ++s) { + for (intptr_t s = 0; s < n; ++s) { MD3_iter i = MD3_begin(&r_in); MD3_iter o = MD3_begin(&r_out); @@ -116,6 +115,7 @@ static void MDRanges_loop_over_joined(intptr_t state) int main(void) { + intptr_t n = 100000; for (int i = 0; i < nx * ny * nz; ++i) Vin[i] = i + 1.23; -- cgit v1.2.3 From 7ae6e4d155e9c4835d2dbf80f6e27873b7c7439a Mon Sep 17 00:00:00 2001 From: tylov Date: Sat, 19 Aug 2023 21:46:52 +0200 Subject: Optimized cspan_next(): awesome speedup on gcc. --- include/stc/cspan.h | 15 ++++++--------- misc/benchmarks/various/cspan_bench.c | 5 ++--- 2 files changed, 8 insertions(+), 12 deletions(-) (limited to 'misc/benchmarks/various/cspan_bench.c') diff --git a/include/stc/cspan.h b/include/stc/cspan.h index 32921390..6f8de8ec 100644 --- a/include/stc/cspan.h +++ b/include/stc/cspan.h @@ -97,8 +97,9 @@ int demo2() { return it; \ } \ STC_INLINE void Self##_next(Self##_iter* it) { \ - int done; \ - it->ref += _cspan_next##RANK(it->pos, it->_s->shape, it->_s->stride.d, RANK, &done); \ + int i, inc, done; \ + if (it->_s->stride.d[0] < it->_s->stride.d[RANK - 1]) i=0, inc=1; else i=RANK-1, inc=-1; \ + it->ref += _cspan_next##RANK(it->pos, it->_s->shape, it->_s->stride.d, RANK, i, inc, &done); \ if (done) it->ref = NULL; \ } \ struct stc_nostruct @@ -223,8 +224,8 @@ STC_INLINE intptr_t _cspan_idxN(int rank, const int32_t shape[], const int32_t s return off; } -STC_API intptr_t _cspan_next2(int32_t pos[], const int32_t shape[], const int32_t stride[], int rank, int* done); -#define _cspan_next1(pos, shape, stride, rank, done) (*done = ++pos[0]==shape[0], stride[0]) +STC_API intptr_t _cspan_next2(int32_t pos[], const int32_t shape[], const int32_t stride[], int rank, int i, int inc, int* done); +#define _cspan_next1(pos, shape, stride, rank, i, inc, done) (*done = ++pos[0]==shape[0], stride[0]) #define _cspan_next3 _cspan_next2 #define _cspan_next4 _cspan_next2 #define _cspan_next5 _cspan_next2 @@ -242,11 +243,7 @@ STC_API int32_t* _cspan_shape2stride(char order, int32_t shape[], int rank); /* --------------------- IMPLEMENTATION --------------------- */ #if defined(i_implement) || defined(i_static) -STC_DEF intptr_t _cspan_next2(int32_t pos[], const int32_t shape[], const int32_t stride[], int rank, int* done) { - int i, inc; - if (stride[0] < stride[rank - 1]) i = rank - 1, inc = -1; - else /* order 'C' */ i = 0, inc = 1; - +STC_DEF intptr_t _cspan_next2(int32_t pos[], const int32_t shape[], const int32_t stride[], int rank, int i, int inc, int* done) { intptr_t off = stride[i]; ++pos[i]; while (--rank && pos[i] == shape[i]) { diff --git a/misc/benchmarks/various/cspan_bench.c b/misc/benchmarks/various/cspan_bench.c index f4b067f8..b5caca83 100644 --- a/misc/benchmarks/various/cspan_bench.c +++ b/misc/benchmarks/various/cspan_bench.c @@ -49,9 +49,8 @@ static void TraditionalForLoop(intptr_t n) for (int x = lx; x < hx; ++x) { for (int y = ly; y < hy; ++y) { for (int z = lz; z < hz; ++z) { - int i = nz*(ny*x + y) + z; - double d = Vin[i]; - Vout[i] += d; + double d = Vin[nz*(ny*x + y) + z]; + Vout[nz*(ny*x + y) + z] += d; sum += d; } } -- cgit v1.2.3 From 7b57eb4240ee886278b862ed8c90618376237afc Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Mon, 21 Aug 2023 18:26:59 +0200 Subject: Some cleanups. --- include/stc/forward.h | 20 ++++++++-------- misc/benchmarks/various/cspan_bench.c | 43 ++++++++--------------------------- misc/examples/spans/submdspan.c | 8 +++---- 3 files changed, 24 insertions(+), 47 deletions(-) (limited to 'misc/benchmarks/various/cspan_bench.c') diff --git a/include/stc/forward.h b/include/stc/forward.h index 2372a618..2fbff034 100644 --- a/include/stc/forward.h +++ b/include/stc/forward.h @@ -41,13 +41,13 @@ // csview : non-null terminated string view typedef const char csview_value; -typedef struct csview { - csview_value* buf; +typedef struct csview { + csview_value* buf; intptr_t size; } csview; -typedef union { - csview_value* ref; +typedef union { + csview_value* ref; csview chr; struct { csview chr; csview_value* end; } u8; } csview_iter; @@ -55,13 +55,13 @@ typedef union { // crawstr : null-terminated string view typedef csview_value crawstr_value; -typedef struct crawstr { - crawstr_value* str; +typedef struct crawstr { + crawstr_value* str; intptr_t size; } crawstr; -typedef union { - crawstr_value* ref; +typedef union { + crawstr_value* ref; csview chr; struct { csview chr; } u8; // [deprecated] } crawstr_iter; @@ -75,8 +75,8 @@ typedef union cstr { struct { cstr_value* data; size_t size, ncap; } lon; } cstr; -typedef union { - cstr_value* ref; +typedef union { + cstr_value* ref; csview chr; struct { csview chr; } u8; // [deprecated] } cstr_iter; diff --git a/misc/benchmarks/various/cspan_bench.c b/misc/benchmarks/various/cspan_bench.c index b5caca83..3b1c3132 100644 --- a/misc/benchmarks/various/cspan_bench.c +++ b/misc/benchmarks/various/cspan_bench.c @@ -1,3 +1,4 @@ +// ref: https://stackoverflow.com/questions/74382366/why-is-iterating-over-stdrangesviewsjoin-so-slow #define NDEBUG #include #include @@ -11,6 +12,7 @@ enum { ny = 64, nz = 64 }; +// subspan 15x5x10: int lx = 15, ly = 10, lz = 5; int hx = 30, hy = 15, hz = 15; @@ -20,27 +22,7 @@ double Vin[nx * ny * nz]; //, 1.23; // define some slice indices for each dimension -static void MDRanges_setup(intptr_t n) -{ - double sum = 0; - clock_t t = clock(); - - for (intptr_t s = 0; s < n; ++s) - { - MD3 r_in = cspan_md(Vin, nx, ny, nz); - MD3 r_out = cspan_md(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}); - MD3_iter i = MD3_begin(&r_in); // can be iterated "flat". - MD3_iter o = MD3_begin(&r_out); - sum += Vin[s % nx]; - } - t = clock() - t; - printf("setup: %.1f ms, %f\n", 1000.0f * t / CLOCKS_PER_SEC, sum); -} - -static void TraditionalForLoop(intptr_t n) +static void Traditional_for_loop(intptr_t n) { clock_t t = clock(); double sum = 0; @@ -57,7 +39,7 @@ static void TraditionalForLoop(intptr_t n) } } t = clock() - t; - printf("forloop: %.1f ms, %f\n", 1000.0f * t / CLOCKS_PER_SEC, sum); + printf("forloop : %.1f ms, %f\n", 1000.0f*t / CLOCKS_PER_SEC, sum); } static void MDRanges_nested_loop(intptr_t n) @@ -67,8 +49,6 @@ static void MDRanges_nested_loop(intptr_t n) MD3 r_out = cspan_md(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}); - - // C++23: for (auto [o, i] : std::views::zip(flat(r_out), flat(r_in))) { o = i; } double sum = 0; for (intptr_t s = 0; s < n; ++s) { @@ -76,27 +56,25 @@ static void MDRanges_nested_loop(intptr_t n) for (int y = 0; y < r_in.shape[1]; ++y) { for (int z = 0; z < r_in.shape[2]; ++z) { - double d = *cspan_at(&r_in, x, y, z); - *cspan_at(&r_out, x, y, z) += d; + double d = *cspan_at(&r_in, x,y,z); + *cspan_at(&r_out, x,y,z) += d; sum += d; } } } } t = clock() - t; - printf("nested: %.1f ms, %f\n", 1000.0f * t / CLOCKS_PER_SEC, sum); + printf("nested : %.1f ms, %f\n", 1000.0f*t / CLOCKS_PER_SEC, sum); } static void MDRanges_loop_over_joined(intptr_t n) { + clock_t t = clock(); MD3 r_in = cspan_md(Vin, nx, ny, nz); MD3 r_out = cspan_md(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}); - - // C++23: for (auto [o, i] : std::views::zip(flat(r_out), flat(r_in))) { o = i; } double sum = 0; - clock_t t = clock(); for (intptr_t s = 0; s < n; ++s) { MD3_iter i = MD3_begin(&r_in); @@ -109,7 +87,7 @@ static void MDRanges_loop_over_joined(intptr_t n) } } t = clock() - t; - printf("joined: %.1f ms, %f\n", 1000.0f * t / CLOCKS_PER_SEC, sum); + printf("joined : %.1f ms, %f\n", 1000.0f*t / CLOCKS_PER_SEC, sum); } int main(void) @@ -118,8 +96,7 @@ int main(void) for (int i = 0; i < nx * ny * nz; ++i) Vin[i] = i + 1.23; - MDRanges_setup(n); - TraditionalForLoop(n); + Traditional_for_loop(n); MDRanges_nested_loop(n); MDRanges_loop_over_joined(n); } diff --git a/misc/examples/spans/submdspan.c b/misc/examples/spans/submdspan.c index fa0d5762..0752dfa1 100644 --- a/misc/examples/spans/submdspan.c +++ b/misc/examples/spans/submdspan.c @@ -3,11 +3,11 @@ #include #include -using_cspan3(span, double); // define span, span2, span3 +using_cspan3(span, double); // shorthand for defining span, span2, span3 // Set all elements of a rank-2 mdspan to zero. void zero_2d(span2 grid2d) { - c_static_assert(cspan_rank(&grid2d) == 2); + (void)c_static_assert(cspan_rank(&grid2d) == 2); for (int i = 0; i < grid2d.shape[0]; ++i) { for (int j = 0; j < grid2d.shape[1]; ++j) { *cspan_at(&grid2d, i,j) = 0; @@ -16,7 +16,7 @@ void zero_2d(span2 grid2d) { } void zero_surface(span3 grid3d) { - c_static_assert(cspan_rank(&grid3d) == 3); + (void)c_static_assert(cspan_rank(&grid3d) == 3); zero_2d(cspan_slice(span2, &grid3d, {0}, {c_ALL}, {c_ALL})); zero_2d(cspan_slice(span2, &grid3d, {c_ALL}, {0}, {c_ALL})); zero_2d(cspan_slice(span2, &grid3d, {c_ALL}, {c_ALL}, {0})); @@ -41,4 +41,4 @@ int main() { } puts(""); } -} \ No newline at end of file +} -- cgit v1.2.3 From 80cd2adc2cd008aeee9f799f2dd5042f42b4ec82 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Wed, 30 Aug 2023 17:16:03 +0200 Subject: Smaller updates. --- include/stc/cspan.h | 20 ++++++---------- misc/benchmarks/various/cspan_bench.c | 43 ++++++++++++++++++----------------- misc/examples/spans/matmult.c | 22 +++++++++--------- src/libstc.c | 5 ++-- 4 files changed, 42 insertions(+), 48 deletions(-) (limited to 'misc/benchmarks/various/cspan_bench.c') diff --git a/include/stc/cspan.h b/include/stc/cspan.h index 3f2b300f..e72bb97a 100644 --- a/include/stc/cspan.h +++ b/include/stc/cspan.h @@ -63,12 +63,6 @@ int demo2() { #include "priv/linkage.h" #include "ccommon.h" -#ifdef i_ndebug - #define cspan_assert(x) ((void)0) -#else - #define cspan_assert(x) c_assert(x) -#endif - #define using_cspan(...) c_MACRO_OVERLOAD(using_cspan, __VA_ARGS__) #define using_cspan_2(Self, T) \ using_cspan_3(Self, T, 1); \ @@ -91,7 +85,7 @@ int demo2() { const int rank, const int32_t a[][2]) { \ Self s; int outrank; \ s.data = d + _cspan_slice(s.shape, s.stride.d, &outrank, shape, stri, rank, a); \ - cspan_assert(outrank == RANK); \ + c_assert(outrank == RANK); \ return s; \ } \ STC_INLINE Self##_iter Self##_begin(const Self* self) { \ @@ -193,7 +187,7 @@ typedef enum {c_ROWMAJOR, c_COLMAJOR} cspan_layout; STC_INLINE intptr_t _cspan_size(const int32_t shape[], int rank) { intptr_t sz = shape[0]; - while (--rank > 0) sz *= shape[rank]; + while (--rank) sz *= shape[rank]; return sz; } @@ -207,14 +201,15 @@ STC_INLINE void _cspan_transpose(int32_t shape[], int32_t stride[], int rank) { STC_INLINE intptr_t _cspan_index(int rank, const int32_t shape[], const int32_t stride[], const int32_t a[]) { intptr_t off = 0; while (rank--) { - cspan_assert(c_LTu(a[rank], shape[rank])); + c_assert(c_LTu(a[rank], shape[rank])); off += stride[rank]*a[rank]; } return off; } -STC_API intptr_t _cspan_next2(int32_t pos[], const int32_t shape[], const int32_t stride[], int rank, int* done); #define _cspan_next1(pos, shape, stride, rank, done) (*done = ++pos[0]==shape[0], stride[0]) +STC_API intptr_t + _cspan_next2(int32_t pos[], const int32_t shape[], const int32_t stride[], int rank, int* done); #define _cspan_next3 _cspan_next2 #define _cspan_next4 _cspan_next2 #define _cspan_next5 _cspan_next2 @@ -270,13 +265,13 @@ STC_DEF intptr_t _cspan_slice(int32_t oshape[], int32_t ostride[], int* orank, for (; i < rank; ++i) { off += stride[i]*a[i][0]; switch (a[i][1]) { - case 0: cspan_assert(c_LTu(a[i][0], shape[i])); continue; + case 0: c_assert(c_LTu(a[i][0], shape[i])); continue; case -1: end = shape[i]; break; default: end = a[i][1]; } oshape[oi] = end - a[i][0]; ostride[oi] = stride[i]; - cspan_assert(c_LTu(0, oshape[oi]) & !c_LTu(shape[i], end)); + c_assert((oshape[oi] > 0) & !c_LTu(shape[i], end)); ++oi; } *orank = oi; @@ -284,7 +279,6 @@ STC_DEF intptr_t _cspan_slice(int32_t oshape[], int32_t ostride[], int* orank, } #endif -#undef i_ndebug #undef i_opt #undef i_header #undef i_implement diff --git a/misc/benchmarks/various/cspan_bench.c b/misc/benchmarks/various/cspan_bench.c index 3b1c3132..bfc0ead3 100644 --- a/misc/benchmarks/various/cspan_bench.c +++ b/misc/benchmarks/various/cspan_bench.c @@ -42,7 +42,7 @@ static void Traditional_for_loop(intptr_t n) printf("forloop : %.1f ms, %f\n", 1000.0f*t / CLOCKS_PER_SEC, sum); } -static void MDRanges_nested_loop(intptr_t n) +static void MDRanges_loop_over_joined(intptr_t n) { clock_t t = clock(); MD3 r_in = cspan_md(Vin, nx, ny, nz); @@ -52,22 +52,20 @@ static void MDRanges_nested_loop(intptr_t n) double sum = 0; for (intptr_t s = 0; s < n; ++s) { - for (int x = 0; x < r_in.shape[0]; ++x) { - for (int y = 0; y < r_in.shape[1]; ++y) { - for (int z = 0; z < r_in.shape[2]; ++z) - { - double d = *cspan_at(&r_in, x,y,z); - *cspan_at(&r_out, x,y,z) += d; - sum += d; - } - } + MD3_iter i = MD3_begin(&r_in); + MD3_iter o = MD3_begin(&r_out); + + for (; i.ref; MD3_next(&i), MD3_next(&o)) + { + *o.ref += *i.ref; + sum += *i.ref; } } t = clock() - t; - printf("nested : %.1f ms, %f\n", 1000.0f*t / CLOCKS_PER_SEC, sum); + printf("joined : %.1f ms, %f\n", 1000.0f*t / CLOCKS_PER_SEC, sum); } -static void MDRanges_loop_over_joined(intptr_t n) +static void MDRanges_nested_loop(intptr_t n) { clock_t t = clock(); MD3 r_in = cspan_md(Vin, nx, ny, nz); @@ -77,19 +75,22 @@ static void MDRanges_loop_over_joined(intptr_t n) double sum = 0; for (intptr_t s = 0; s < n; ++s) { - MD3_iter i = MD3_begin(&r_in); - MD3_iter o = MD3_begin(&r_out); - - for (; i.ref; MD3_next(&i), MD3_next(&o)) - { - *o.ref += *i.ref; - sum += *i.ref; + for (int x = 0; x < r_in.shape[0]; ++x) { + for (int y = 0; y < r_in.shape[1]; ++y) { + for (int z = 0; z < r_in.shape[2]; ++z) + { + double d = *cspan_at(&r_in, x,y,z); + *cspan_at(&r_out, x,y,z) += d; + sum += d; + } + } } } t = clock() - t; - printf("joined : %.1f ms, %f\n", 1000.0f*t / CLOCKS_PER_SEC, sum); + printf("nested : %.1f ms, %f\n", 1000.0f*t / CLOCKS_PER_SEC, sum); } + int main(void) { intptr_t n = 100000; @@ -97,6 +98,6 @@ int main(void) Vin[i] = i + 1.23; Traditional_for_loop(n); - MDRanges_nested_loop(n); MDRanges_loop_over_joined(n); + MDRanges_nested_loop(n); } diff --git a/misc/examples/spans/matmult.c b/misc/examples/spans/matmult.c index 266fa121..ec992ff9 100644 --- a/misc/examples/spans/matmult.c +++ b/misc/examples/spans/matmult.c @@ -37,7 +37,7 @@ void base_case_matrix_product(Mat2 A, Mat2 B, OutMat C) void recursive_matrix_product(Mat2 A, Mat2 B, OutMat C) { // Some hardware-dependent constant - enum {recursion_threshold = 16}; + enum {recursion_threshold = 32}; if (C.shape[0] <= recursion_threshold || C.shape[1] <= recursion_threshold) { base_case_matrix_product(A, B, C); } else { @@ -63,28 +63,28 @@ void recursive_matrix_product(Mat2 A, Mat2 B, OutMat C) int main(void) { - enum {N = 10, D1 = 256, D2 = D1}; + enum {N = 10, D = 256}; Values values = {0}; - for (int i=0; i < N*D1*D2; ++i) + for (int i=0; i < N*D*D; ++i) Values_push(&values, (crandf() - 0.5)*4.0); - double out[D1*D2]; - Mat3 data = cspan_md_layout(c_ROWMAJOR, values.data, N, D1, D2); - OutMat c = cspan_md_layout(c_ROWMAJOR, out, D1, D2); + double out[D*D]; + Mat3 data = cspan_md_layout(c_ROWMAJOR, values.data, N, D, D); + OutMat c = cspan_md_layout(c_COLMAJOR, out, D, D); Mat2 a = cspan_submd3(&data, 0); - double sum = 0.0; - clock_t t = clock(); + clock_t t = clock(); for (int i=1; i= 201112L -# define i_implement # include "../include/c11/fmt.h" #endif -- cgit v1.2.3