summaryrefslogtreecommitdiffhomepage
path: root/misc/tests/cspan_test.c
blob: 83ac762b106fd34081f4235f6be7e9547cb35eff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include <stdio.h>
#include <stc/cspan.h>
#include "ctest.h"

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);
    
    for (size_t i = 0; i < m.shape[0]; ++i) {
        intspan2 sub_i = cspan_submd3(&m, i);
        for (size_t j = 0; j < m.shape[1]; ++j) {
            intspan sub_i_j = cspan_submd2(&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));
            }
        }
    }
}

CTEST(cspan, slice) {
    int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
    intspan2 m1 = cspan_md(array, 3, 4);

    size_t sum1 = 0;
    for (size_t i = 0; i < m1.shape[0]; ++i) {
        for (size_t j = 0; j < m1.shape[1]; ++j) {
            sum1 += *cspan_at(&m1, i, j);
        }
    }

    intspan2 m2 = cspan_slice(intspan2, &m1, {c_ALL}, {2,4});

    size_t sum2 = 0;
    for (size_t i = 0; i < m2.shape[0]; ++i) {
        for (size_t j = 0; j < m2.shape[1]; ++j) {
            sum2 += *cspan_at(&m2, i, j);
        }
    }
    ASSERT_EQ(78, sum1);
    ASSERT_EQ(45, sum2);
}

#define i_val int
#include <stc/cstack.h>

CTEST(cspan, slice2) {
    c_auto (cstack_int, stack)
    {
        c_forrange (i, 10*20*30)
            cstack_int_push(&stack, i);

        intspan3 ms3 = cspan_md(stack.data, 10, 20, 30);
        ms3 = cspan_slice(intspan3, &ms3, {1,4}, {3,7}, {20,24});

        size_t sum = 0;
        for (size_t i = 0; i < ms3.shape[0]; ++i) {
            for (size_t j = 0; j < ms3.shape[1]; ++j) {
                for (size_t k = 0; k < ms3.shape[2]; ++k) {
                    sum += *cspan_at(&ms3, i, j, k);
                }
            }
        }
        ASSERT_EQ(65112, sum);

        sum = 0;
        c_foreach (i, intspan3, ms3)
            sum += *i.ref;
        ASSERT_EQ(65112, sum);
    }
}


#define i_type Tiles
#define i_val intspan3
#include <stc/cstack.h>

CTEST_FIXTURE(cspan_cube) {
    cstack_int stack;
    Tiles tiles;
};

CTEST_SETUP(cspan_cube) {
    enum {TSIZE=4, CUBE=64, N=CUBE*CUBE*CUBE};

    _self->stack = cstack_int_init();
    _self->tiles = Tiles_init();

    cstack_int_reserve(&_self->stack, N);
    c_forrange (i, N)
        cstack_int_push(&_self->stack, i+1);

    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) {
            c_forrange (k, 0, ms3.shape[2], TSIZE) {
                intspan3 tile = cspan_slice(intspan3, &ms3, {i, i + TSIZE}, {j, j + TSIZE}, {k, k + TSIZE});
                Tiles_push(&_self->tiles, tile);
            }
        }
    }
}

// Optional teardown function for suite, called after every test in suite
CTEST_TEARDOWN(cspan_cube) {
    cstack_int_drop(&_self->stack);
    Tiles_drop(&_self->tiles);
}


CTEST_F(cspan_cube, slice3) {
    long long n = cstack_int_size(&_self->stack);
    long long sum = 0;

    // iterate each 3d tile in sequence
    c_foreach (i, Tiles, _self->tiles)
        c_foreach (t, intspan3, *i.ref)
            sum += *t.ref;

    ASSERT_EQ(n*(n + 1)/2, sum);
}