test_tensor.cu 8.03 KB
Newer Older
Li Zhang's avatar
Li Zhang committed
1
2
#include <iostream>
#include <unordered_map>
Chen Xin's avatar
Chen Xin committed
3
#include <vector>
Li Zhang's avatar
Li Zhang committed
4
5
6

#include <gtest/gtest.h>

lvhan028's avatar
lvhan028 committed
7
#include "src/turbomind/utils/Tensor.h"
Li Zhang's avatar
Li Zhang committed
8

lvhan028's avatar
lvhan028 committed
9
using namespace turbomind;
Li Zhang's avatar
Li Zhang committed
10
11
12

namespace {

Chen Xin's avatar
Chen Xin committed
13
14
15
16
17
18
19
20
21
22
23
#define EXPECT_EQUAL_TENSORS(t1, t2)                                                                                   \
    do {                                                                                                               \
        EXPECT_TRUE(t1.where == t2.where);                                                                             \
        EXPECT_TRUE(t1.type == t2.type);                                                                               \
        EXPECT_TRUE(t1.shape == t2.shape);                                                                             \
        EXPECT_TRUE(t1.data == t2.data);                                                                               \
    } while (false)

TEST(TensorMapTest, HasKeyCorrectness)
{
    bool*  v1 = new bool(true);
Li Zhang's avatar
Li Zhang committed
24
25
26
27
28
29
30
31
32
33
34
35
36
    float* v2 = new float[6]{1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f};
    Tensor t1 = Tensor{MEMORY_CPU, TYPE_BOOL, {1}, v1};
    Tensor t2 = Tensor{MEMORY_CPU, TYPE_FP32, {3, 2}, v2};

    TensorMap map({{"t1", t1}, {"t2", t2}});
    EXPECT_TRUE(map.isExist("t1"));
    EXPECT_TRUE(map.isExist("t2"));
    EXPECT_FALSE(map.isExist("t3"));

    delete v1;
    delete[] v2;
}

Chen Xin's avatar
Chen Xin committed
37
38
39
TEST(TensorMapTest, InsertCorrectness)
{
    int*   v1 = new int[4]{1, 10, 20, 30};
Li Zhang's avatar
Li Zhang committed
40
41
42
43
44
45
46
47
48
49
50
    float* v2 = new float[2]{1.0f, 2.0f};
    Tensor t1 = Tensor(MEMORY_CPU, TYPE_INT32, {4}, v1);
    Tensor t2 = Tensor(MEMORY_CPU, TYPE_INT32, {2}, v2);

    TensorMap map({{"t1", t1}});
    EXPECT_TRUE(map.size() == 1);
    EXPECT_TRUE(map.isExist("t1"));
    EXPECT_EQUAL_TENSORS(map.at("t1"), t1);
    EXPECT_FALSE(map.isExist("t2"));
}

Chen Xin's avatar
Chen Xin committed
51
52
TEST(TensorMapTest, InsertDoesNotAllowNoneTensor)
{
Li Zhang's avatar
Li Zhang committed
53
54
55
56
57
58
59
60
61
62
    TensorMap map;
    EXPECT_TRUE(map.size() == 0);
    // forbid a none tensor.
    EXPECT_THROW(map.insert("none", {}), std::runtime_error);

    // forbid a tensor having null data pointer.
    Tensor none_data_tensor = Tensor(MEMORY_CPU, TYPE_INT32, {}, nullptr);
    EXPECT_THROW(map.insert("empty", none_data_tensor), std::runtime_error);
}

Chen Xin's avatar
Chen Xin committed
63
64
65
66
67
TEST(TensorMapTest, InsertDoesNotAllowDuplicatedKey)
{
    int*      v1 = new int[4]{1, 10, 20, 30};
    Tensor    t1 = Tensor(MEMORY_CPU, TYPE_INT32, {4}, v1);
    Tensor    t2 = Tensor(MEMORY_CPU, TYPE_INT32, {2}, v1);
Li Zhang's avatar
Li Zhang committed
68
69
70
71
72
73
74
    TensorMap map({{"t1", t1}});
    EXPECT_TRUE(map.size() == 1);
    // forbid a duplicated key.
    EXPECT_THROW(map.insert("t1", t2), std::runtime_error);
    delete[] v1;
}

Chen Xin's avatar
Chen Xin committed
75
76
77
TEST(TensorMapTest, GetValCorrectness)
{
    int*   v1 = new int[4]{1, 10, 20, 30};
Li Zhang's avatar
Li Zhang committed
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
    Tensor t1 = Tensor(MEMORY_CPU, TYPE_INT32, {4}, v1);

    TensorMap map({{"t1", t1}});
    EXPECT_TRUE(map.size() == 1);
    // throw exception since the map doesn't have a key "t3".
    EXPECT_THROW(map.getVal<int>("t3"), std::runtime_error);
    EXPECT_TRUE(map.getVal<int>("t1") == 1);
    EXPECT_TRUE(map.getVal<int>("t1", 3) == 1);

    // map doesn't have t2 so return the default value 3.
    EXPECT_TRUE(map.getVal<int>("t2", 3) == 3);

    v1[0] += 1;  // update value.
    EXPECT_TRUE(map.getVal<int>("t1") == 2);
    EXPECT_TRUE(map.getVal<int>("t1", 3) == 2);

    size_t index = 2;
    EXPECT_TRUE(map.getValWithOffset<int>("t1", index) == 20);
    EXPECT_TRUE(map.getValWithOffset<int>("t1", index, 3) == 20);
    EXPECT_TRUE(map.getValWithOffset<int>("t2", index, 3) == 3);
    delete[] v1;
}

Chen Xin's avatar
Chen Xin committed
101
102
103
TEST(TensorMapTest, GetTensorCorrectness)
{
    bool*  t1_val = new bool(true);
Li Zhang's avatar
Li Zhang committed
104
    float* t2_val = new float[6]{1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f};
Chen Xin's avatar
Chen Xin committed
105
106
    Tensor t1     = Tensor{MEMORY_CPU, TYPE_BOOL, {1}, t1_val};
    Tensor t2     = Tensor{MEMORY_CPU, TYPE_FP32, {3, 2}, t2_val};
Li Zhang's avatar
Li Zhang committed
107

Chen Xin's avatar
Chen Xin committed
108
    int*   default_val    = new int[4]{0, 1, 2, 3};
Li Zhang's avatar
Li Zhang committed
109
110
111
112
113
114
115
116
117
118
119
120
121
122
    Tensor default_tensor = Tensor{MEMORY_CPU, TYPE_INT32, {4}, default_val};

    TensorMap map({{"t1", t1}, {"t2", t2}});
    EXPECT_THROW(map.at("t3"), std::runtime_error);
    EXPECT_EQUAL_TENSORS(map.at("t1", default_tensor), t1);
    EXPECT_EQUAL_TENSORS(map.at("t2", default_tensor), t2);
    EXPECT_EQUAL_TENSORS(map.at("t3", default_tensor), default_tensor);
    EXPECT_EQUAL_TENSORS(map.at("t3", {}), Tensor());

    delete[] default_val;
    delete[] t2_val;
    delete[] t1_val;
}

Chen Xin's avatar
Chen Xin committed
123
124
125
TEST(TensorMapTest, GetTensorCorrectnessAtConstTensorMap)
{
    bool*  t1_val = new bool(true);
Li Zhang's avatar
Li Zhang committed
126
    float* t2_val = new float[6]{1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f};
Chen Xin's avatar
Chen Xin committed
127
128
    Tensor t1     = Tensor{MEMORY_CPU, TYPE_BOOL, {1}, t1_val};
    Tensor t2     = Tensor{MEMORY_CPU, TYPE_FP32, {3, 2}, t2_val};
Li Zhang's avatar
Li Zhang committed
129

Chen Xin's avatar
Chen Xin committed
130
    int*   default_val    = new int[4]{0, 1, 2, 3};
Li Zhang's avatar
Li Zhang committed
131
132
133
134
135
136
137
138
139
140
141
142
143
144
    Tensor default_tensor = Tensor{MEMORY_CPU, TYPE_INT32, {4}, default_val};

    const TensorMap map({{"t1", t1}, {"t2", t2}});
    EXPECT_THROW(map.at("t3"), std::runtime_error);
    EXPECT_EQUAL_TENSORS(map.at("t1", default_tensor), t1);
    EXPECT_EQUAL_TENSORS(map.at("t2", default_tensor), t2);
    EXPECT_EQUAL_TENSORS(map.at("t3", default_tensor), default_tensor);
    EXPECT_EQUAL_TENSORS(map.at("t3", {}), Tensor());

    delete[] default_val;
    delete[] t2_val;
    delete[] t1_val;
}

Chen Xin's avatar
Chen Xin committed
145
146
TEST(TensorTest, EmptyTensorMinMaxRaiseError)
{
Li Zhang's avatar
Li Zhang committed
147
148
149
150
151
152
153
154
155
156
157
    Tensor t1;
    EXPECT_THROW(t1.min<int>(), std::runtime_error);
    EXPECT_THROW(t1.max<int>(), std::runtime_error);

    Tensor t2 = Tensor{MEMORY_CPU, TYPE_INT32, {}, nullptr};
    EXPECT_THROW(t2.min<int>(), std::runtime_error);
    EXPECT_THROW(t2.max<int>(), std::runtime_error);
}

using TensorTypes = testing::Types<int8_t, int, float>;

Chen Xin's avatar
Chen Xin committed
158
159
template<typename T>
class TensorFuncTest: public testing::Test {};
Li Zhang's avatar
Li Zhang committed
160
161
162

TYPED_TEST_SUITE(TensorFuncTest, TensorTypes);

Chen Xin's avatar
Chen Xin committed
163
164
TYPED_TEST(TensorFuncTest, MaxCorrectness)
{
Li Zhang's avatar
Li Zhang committed
165
166
167
168
    using T = TypeParam;

    size_t size = 4;

Chen Xin's avatar
Chen Xin committed
169
170
171
    T* v1 = new T[size]{T(1), T(2), T(3), T(4)};
    T* v2 = new T[size]{T(4), T(3), T(2), T(1)};
    T* v3 = new T[size]{T(1), T(2), T(4), T(3)};
Li Zhang's avatar
Li Zhang committed
172
173
174
175
176
177
178
179
180
181
182
183
184
185

    Tensor t1 = Tensor(MEMORY_CPU, getTensorType<T>(), {size}, v1);
    Tensor t2 = Tensor(MEMORY_CPU, getTensorType<T>(), {size}, v2);
    Tensor t3 = Tensor(MEMORY_CPU, getTensorType<T>(), {size}, v3);

    EXPECT_EQ(t1.max<T>(), T(4));
    EXPECT_EQ(t2.max<T>(), T(4));
    EXPECT_EQ(t3.max<T>(), T(4));

    delete[] v1;
    delete[] v2;
    delete[] v3;
}

Chen Xin's avatar
Chen Xin committed
186
187
TYPED_TEST(TensorFuncTest, MinCorrectness)
{
Li Zhang's avatar
Li Zhang committed
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
    using T = TypeParam;

    size_t size = 4;

    T* v1 = new T[size]{T(1), T(2), T(3), T(4)};
    T* v2 = new T[size]{T(4), T(3), T(2), T(1)};
    T* v3 = new T[size]{T(1), T(2), T(4), T(3)};

    Tensor t1 = Tensor(MEMORY_CPU, getTensorType<T>(), {size}, v1);
    Tensor t2 = Tensor(MEMORY_CPU, getTensorType<T>(), {size}, v2);
    Tensor t3 = Tensor(MEMORY_CPU, getTensorType<T>(), {size}, v3);

    EXPECT_EQ(t1.min<T>(), T(1));
    EXPECT_EQ(t2.min<T>(), T(1));
    EXPECT_EQ(t3.min<T>(), T(1));

    delete[] v1;
    delete[] v2;
    delete[] v3;
}

Chen Xin's avatar
Chen Xin committed
209
210
TYPED_TEST(TensorFuncTest, AnyCorrectness)
{
Li Zhang's avatar
Li Zhang committed
211
212
    using T = TypeParam;

Chen Xin's avatar
Chen Xin committed
213
    T*     v = new T[4]{T(1), T(2), T(3), T(4)};
Li Zhang's avatar
Li Zhang committed
214
215
216
217
218
219
    Tensor t = Tensor{MEMORY_CPU, getTensorType<T>(), {4}, v};
    EXPECT_TRUE(t.any<T>(T(1)));
    EXPECT_FALSE(t.any<T>(T(5)));
    delete[] v;
}

Chen Xin's avatar
Chen Xin committed
220
221
TYPED_TEST(TensorFuncTest, AllCorrectness)
{
Li Zhang's avatar
Li Zhang committed
222
223
224
    using T = TypeParam;

    constexpr size_t size = 4;
Chen Xin's avatar
Chen Xin committed
225
226
227
228
    T*               v1   = new T[size]{T(1), T(1), T(1), T(1)};
    T*               v2   = new T[size]{T(1), T(1), T(1), T(2)};
    Tensor           t1   = Tensor{MEMORY_CPU, getTensorType<T>(), {size}, v1};
    Tensor           t2   = Tensor{MEMORY_CPU, getTensorType<T>(), {size}, v2};
Li Zhang's avatar
Li Zhang committed
229
230
231
232
233
234
    EXPECT_TRUE(t1.all<T>(T(1)));
    EXPECT_FALSE(t2.all<T>(T(2)));
    delete[] v1;
    delete[] v2;
}

Chen Xin's avatar
Chen Xin committed
235
236
TYPED_TEST(TensorFuncTest, SliceCorrectness)
{
Li Zhang's avatar
Li Zhang committed
237
238
239
    using T = TypeParam;

    constexpr int size = 12;
Chen Xin's avatar
Chen Xin committed
240
    T*            v    = new T[size];
Li Zhang's avatar
Li Zhang committed
241
242
243
244
245
    for (int i = 0; i < size; ++i) {
        v[i] = i;
    }

    DataType dtype = getTensorType<T>();
Chen Xin's avatar
Chen Xin committed
246
247
    Tensor   t1    = Tensor(MEMORY_CPU, dtype, {3, 4}, v);
    Tensor   t2    = t1.slice({2, 4}, 4);
Li Zhang's avatar
Li Zhang committed
248
249
250
251
252
253
254
255

    EXPECT_EQUAL_TENSORS(t2, Tensor(MEMORY_CPU, dtype, {2, 4}, &v[4]));
    // An overflowed tensor throws an exception.
    EXPECT_THROW(t1.slice({2, 4}, 5), std::runtime_error);

    delete[] v;
}

Chen Xin's avatar
Chen Xin committed
256
}  // end of namespace