summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authortylov <[email protected]>2023-07-11 22:16:09 +0200
committertylov <[email protected]>2023-07-11 22:16:09 +0200
commit0bcb0fcd981cb15329dfd4fb675097564164da18 (patch)
tree2bb26e1c0940bdbab326b780bce0a89b47e79d16
parentafc968975a057f5b2653e3cfa51ef2eff83a8d5b (diff)
downloadSTC-modified-0bcb0fcd981cb15329dfd4fb675097564164da18.tar.gz
STC-modified-0bcb0fcd981cb15329dfd4fb675097564164da18.zip
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.
-rw-r--r--docs/cspan_api.md14
-rw-r--r--include/stc/cspan.h42
-rw-r--r--include/stc/priv/template.h6
-rw-r--r--misc/benchmarks/various/cspan_bench.c12
-rw-r--r--misc/examples/multidim.c6
-rw-r--r--misc/tests/cspan_test.c12
6 files changed, 52 insertions, 40 deletions
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; i<ms.shape[0]; i++)
for (int j=0; j<ms.shape[1]; j++)
@@ -147,26 +147,34 @@ using_cspan_tuple(7); using_cspan_tuple(8);
// 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]}, \
+#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) {