Skip to content

Commit 0b35651

Browse files
committed
Add unit tests for template optimization helpers
Add Google Tests for optimized template utilities: - sequence_gen: Tests with custom functors (4 tests) - generate_identity_sequences: Tuple of identity sequences (4 tests) - find_in_tuple_of_sequences: O(1) sequence search (6 tests) - sequence_find_value: Value lookup in sequences (5 tests) - container_concat: Tuple/array concatenation (5 tests) - make_uniform_tuple: Repeated value tuples (4 tests) - compute_element_space_size: Fold expression (8 tests) - unpack_and_merge_sequences: Sequence merging (2 tests) Total: 43 new tests across 4 test files.
1 parent 05d9bef commit 0b35651

File tree

5 files changed

+461
-0
lines changed

5 files changed

+461
-0
lines changed

test/util/CMakeLists.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,18 @@ add_gtest_executable(unit_sequence unit_sequence.cpp)
55
if(result EQUAL 0)
66
target_link_libraries(unit_sequence PRIVATE utility)
77
endif()
8+
9+
add_gtest_executable(unit_sequence_helper unit_sequence_helper.cpp)
10+
if(result EQUAL 0)
11+
target_link_libraries(unit_sequence_helper PRIVATE utility)
12+
endif()
13+
14+
add_gtest_executable(unit_container_helper unit_container_helper.cpp)
15+
if(result EQUAL 0)
16+
target_link_libraries(unit_container_helper PRIVATE utility)
17+
endif()
18+
19+
add_gtest_executable(unit_tensor_descriptor_helper unit_tensor_descriptor_helper.cpp)
20+
if(result EQUAL 0)
21+
target_link_libraries(unit_tensor_descriptor_helper PRIVATE utility)
22+
endif()
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
// Copyright (c) Advanced Micro Devices, Inc., or its affiliates.
2+
// SPDX-License-Identifier: MIT
3+
4+
#include <gtest/gtest.h>
5+
#include "ck/utility/container_helper.hpp"
6+
#include "ck/utility/tuple_helper.hpp"
7+
8+
using namespace ck;
9+
10+
// Test container_concat with tuples
11+
TEST(ContainerConcat, ConcatTwoTuples)
12+
{
13+
constexpr auto t1 = make_tuple(Number<1>{}, Number<2>{});
14+
constexpr auto t2 = make_tuple(Number<3>{}, Number<4>{});
15+
constexpr auto result = container_concat(t1, t2);
16+
17+
EXPECT_EQ(result.Size(), 4);
18+
EXPECT_EQ(result[Number<0>{}], 1);
19+
EXPECT_EQ(result[Number<1>{}], 2);
20+
EXPECT_EQ(result[Number<2>{}], 3);
21+
EXPECT_EQ(result[Number<3>{}], 4);
22+
}
23+
24+
TEST(ContainerConcat, ConcatThreeTuples)
25+
{
26+
constexpr auto t1 = make_tuple(Number<1>{});
27+
constexpr auto t2 = make_tuple(Number<2>{});
28+
constexpr auto t3 = make_tuple(Number<3>{});
29+
constexpr auto result = container_concat(t1, t2, t3);
30+
31+
EXPECT_EQ(result.Size(), 3);
32+
EXPECT_EQ(result[Number<0>{}], 1);
33+
EXPECT_EQ(result[Number<1>{}], 2);
34+
EXPECT_EQ(result[Number<2>{}], 3);
35+
}
36+
37+
TEST(ContainerConcat, ConcatWithEmptyTuple)
38+
{
39+
constexpr auto t1 = make_tuple(Number<1>{}, Number<2>{});
40+
constexpr auto empty = make_tuple();
41+
constexpr auto result = container_concat(t1, empty);
42+
43+
EXPECT_EQ(result.Size(), 2);
44+
EXPECT_EQ(result[Number<0>{}], 1);
45+
EXPECT_EQ(result[Number<1>{}], 2);
46+
}
47+
48+
TEST(ContainerConcat, ConcatSingleTuple)
49+
{
50+
constexpr auto t1 = make_tuple(Number<1>{}, Number<2>{}, Number<3>{});
51+
constexpr auto result = container_concat(t1);
52+
53+
EXPECT_EQ(result.Size(), 3);
54+
}
55+
56+
// Test container_concat with arrays
57+
TEST(ContainerConcat, ConcatTwoArrays)
58+
{
59+
constexpr auto a1 = make_array(1, 2);
60+
constexpr auto a2 = make_array(3, 4);
61+
constexpr auto result = container_concat(a1, a2);
62+
63+
EXPECT_EQ(result.Size(), 4);
64+
EXPECT_EQ(result[Number<0>{}], 1);
65+
EXPECT_EQ(result[Number<1>{}], 2);
66+
EXPECT_EQ(result[Number<2>{}], 3);
67+
EXPECT_EQ(result[Number<3>{}], 4);
68+
}
69+
70+
// Test make_uniform_tuple
71+
TEST(MakeUniformTuple, Size3)
72+
{
73+
constexpr auto result = make_uniform_tuple<3>(Number<42>{});
74+
75+
EXPECT_EQ(result.Size(), 3);
76+
EXPECT_EQ(result[Number<0>{}], 42);
77+
EXPECT_EQ(result[Number<1>{}], 42);
78+
EXPECT_EQ(result[Number<2>{}], 42);
79+
}
80+
81+
TEST(MakeUniformTuple, Size1)
82+
{
83+
constexpr auto result = make_uniform_tuple<1>(Number<99>{});
84+
85+
EXPECT_EQ(result.Size(), 1);
86+
EXPECT_EQ(result[Number<0>{}], 99);
87+
}
88+
89+
TEST(MakeUniformTuple, Size0)
90+
{
91+
constexpr auto result = make_uniform_tuple<0>(Number<42>{});
92+
93+
EXPECT_EQ(result.Size(), 0);
94+
}
95+
96+
TEST(MakeUniformTuple, Size5)
97+
{
98+
constexpr auto result = make_uniform_tuple<5>(Number<7>{});
99+
100+
EXPECT_EQ(result.Size(), 5);
101+
EXPECT_EQ(result[Number<0>{}], 7);
102+
EXPECT_EQ(result[Number<1>{}], 7);
103+
EXPECT_EQ(result[Number<2>{}], 7);
104+
EXPECT_EQ(result[Number<3>{}], 7);
105+
EXPECT_EQ(result[Number<4>{}], 7);
106+
}
107+
108+
// Test make_tuple_functor (used internally by container_concat)
109+
TEST(MakeTupleFunctor, CreatesTuple)
110+
{
111+
make_tuple_functor functor;
112+
auto result = functor(Number<1>{}, Number<2>{}, Number<3>{});
113+
114+
EXPECT_EQ(result.Size(), 3);
115+
EXPECT_EQ(result[Number<0>{}], 1);
116+
EXPECT_EQ(result[Number<1>{}], 2);
117+
EXPECT_EQ(result[Number<2>{}], 3);
118+
}
119+
120+
// Test container_push_front and container_push_back
121+
TEST(ContainerPush, PushFront)
122+
{
123+
constexpr auto t = make_tuple(Number<2>{}, Number<3>{});
124+
constexpr auto result = container_push_front(t, Number<1>{});
125+
126+
EXPECT_EQ(result.Size(), 3);
127+
EXPECT_EQ(result[Number<0>{}], 1);
128+
EXPECT_EQ(result[Number<1>{}], 2);
129+
EXPECT_EQ(result[Number<2>{}], 3);
130+
}
131+
132+
TEST(ContainerPush, PushBack)
133+
{
134+
constexpr auto t = make_tuple(Number<1>{}, Number<2>{});
135+
constexpr auto result = container_push_back(t, Number<3>{});
136+
137+
EXPECT_EQ(result.Size(), 3);
138+
EXPECT_EQ(result[Number<0>{}], 1);
139+
EXPECT_EQ(result[Number<1>{}], 2);
140+
EXPECT_EQ(result[Number<2>{}], 3);
141+
}

test/util/unit_sequence.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,54 @@ TEST(Sequence, ReorderGivenOld2New)
185185
EXPECT_TRUE((is_same<Result, Expected>::value));
186186
}
187187

188+
// Test sequence_gen with custom functor
189+
TEST(SequenceGen, SequenceGenWithDoubleFunctor)
190+
{
191+
struct DoubleFunctor
192+
{
193+
__host__ __device__ constexpr index_t operator()(index_t i) const { return i * 2; }
194+
};
195+
using Result = typename sequence_gen<5, DoubleFunctor>::type;
196+
using Expected = Sequence<0, 2, 4, 6, 8>;
197+
EXPECT_TRUE((is_same<Result, Expected>::value));
198+
}
199+
200+
TEST(SequenceGen, SequenceGenWithSquareFunctor)
201+
{
202+
struct SquareFunctor
203+
{
204+
__host__ __device__ constexpr index_t operator()(index_t i) const { return i * i; }
205+
};
206+
using Result = typename sequence_gen<5, SquareFunctor>::type;
207+
using Expected = Sequence<0, 1, 4, 9, 16>;
208+
EXPECT_TRUE((is_same<Result, Expected>::value));
209+
}
210+
211+
TEST(SequenceGen, SequenceGenZeroSize)
212+
{
213+
struct IdentityFunctor
214+
{
215+
__host__ __device__ constexpr index_t operator()(index_t i) const { return i; }
216+
};
217+
using Result = typename sequence_gen<0, IdentityFunctor>::type;
218+
using Expected = Sequence<>;
219+
EXPECT_TRUE((is_same<Result, Expected>::value));
220+
// Also verify non-zero size works with identity
221+
using Result5 = typename sequence_gen<5, IdentityFunctor>::type;
222+
EXPECT_TRUE((is_same<Result5, Sequence<0, 1, 2, 3, 4>>::value));
223+
}
224+
225+
TEST(SequenceGen, SequenceGenSingleElement)
226+
{
227+
struct ConstantFunctor
228+
{
229+
__host__ __device__ constexpr index_t operator()(index_t) const { return 42; }
230+
};
231+
using Result = typename sequence_gen<1, ConstantFunctor>::type;
232+
using Expected = Sequence<42>;
233+
EXPECT_TRUE((is_same<Result, Expected>::value));
234+
}
235+
188236
// Test arithmetic_sequence_gen
189237
TEST(SequenceGen, ArithmeticSequence)
190238
{

test/util/unit_sequence_helper.cpp

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
// Copyright (c) Advanced Micro Devices, Inc., or its affiliates.
2+
// SPDX-License-Identifier: MIT
3+
4+
#include <gtest/gtest.h>
5+
#include "ck/utility/sequence.hpp"
6+
#include "ck/utility/sequence_helper.hpp"
7+
#include "ck/utility/tuple_helper.hpp"
8+
9+
using namespace ck;
10+
11+
// Test generate_identity_sequences
12+
TEST(GenerateIdentitySequences, Size5)
13+
{
14+
constexpr auto result = generate_identity_sequences<5>();
15+
// Should produce Tuple<Sequence<0>, Sequence<1>, Sequence<2>, Sequence<3>, Sequence<4>>
16+
EXPECT_TRUE((is_same<remove_cvref_t<decltype(result[Number<0>{}])>, Sequence<0>>::value));
17+
EXPECT_TRUE((is_same<remove_cvref_t<decltype(result[Number<1>{}])>, Sequence<1>>::value));
18+
EXPECT_TRUE((is_same<remove_cvref_t<decltype(result[Number<2>{}])>, Sequence<2>>::value));
19+
EXPECT_TRUE((is_same<remove_cvref_t<decltype(result[Number<3>{}])>, Sequence<3>>::value));
20+
EXPECT_TRUE((is_same<remove_cvref_t<decltype(result[Number<4>{}])>, Sequence<4>>::value));
21+
}
22+
23+
TEST(GenerateIdentitySequences, Size1)
24+
{
25+
constexpr auto result = generate_identity_sequences<1>();
26+
EXPECT_TRUE((is_same<remove_cvref_t<decltype(result[Number<0>{}])>, Sequence<0>>::value));
27+
EXPECT_EQ(result.Size(), 1);
28+
}
29+
30+
TEST(GenerateIdentitySequences, Size0)
31+
{
32+
constexpr auto result = generate_identity_sequences<0>();
33+
EXPECT_EQ(result.Size(), 0);
34+
}
35+
36+
TEST(GenerateIdentitySequences, WithNumber)
37+
{
38+
constexpr auto result = generate_identity_sequences(Number<3>{});
39+
EXPECT_TRUE((is_same<remove_cvref_t<decltype(result[Number<0>{}])>, Sequence<0>>::value));
40+
EXPECT_TRUE((is_same<remove_cvref_t<decltype(result[Number<1>{}])>, Sequence<1>>::value));
41+
EXPECT_TRUE((is_same<remove_cvref_t<decltype(result[Number<2>{}])>, Sequence<2>>::value));
42+
EXPECT_EQ(result.Size(), 3);
43+
}
44+
45+
// Test sequence_find_value
46+
TEST(SequenceFindValue, FindExistingElement)
47+
{
48+
constexpr auto result = sequence_find_value<3>(Sequence<1, 2, 3, 4, 5>{});
49+
EXPECT_EQ(result, 2); // 3 is at index 2
50+
}
51+
52+
TEST(SequenceFindValue, FindFirstElement)
53+
{
54+
constexpr auto result = sequence_find_value<10>(Sequence<10, 20, 30>{});
55+
EXPECT_EQ(result, 0);
56+
}
57+
58+
TEST(SequenceFindValue, FindLastElement)
59+
{
60+
constexpr auto result = sequence_find_value<30>(Sequence<10, 20, 30>{});
61+
EXPECT_EQ(result, 2);
62+
}
63+
64+
TEST(SequenceFindValue, ElementNotFound)
65+
{
66+
constexpr auto result = sequence_find_value<99>(Sequence<1, 2, 3, 4, 5>{});
67+
EXPECT_EQ(result, -1);
68+
}
69+
70+
TEST(SequenceFindValue, EmptySequence)
71+
{
72+
constexpr auto result = sequence_find_value<1>(Sequence<>{});
73+
EXPECT_EQ(result, -1);
74+
}
75+
76+
// Test find_in_tuple_of_sequences
77+
TEST(FindInTupleOfSequences, FindInFirstSequence)
78+
{
79+
constexpr auto tuple_of_seqs = make_tuple(Sequence<0, 1>{}, Sequence<2, 3>{}, Sequence<4, 5>{});
80+
constexpr auto result = find_in_tuple_of_sequences<1>(tuple_of_seqs);
81+
EXPECT_EQ(result.itran, 0); // Found in first sequence (index 0)
82+
EXPECT_EQ(result.idim_up, 1); // At position 1 within that sequence
83+
EXPECT_TRUE(result.found);
84+
}
85+
86+
TEST(FindInTupleOfSequences, FindInMiddleSequence)
87+
{
88+
constexpr auto tuple_of_seqs = make_tuple(Sequence<0, 1>{}, Sequence<2, 3>{}, Sequence<4, 5>{});
89+
constexpr auto result = find_in_tuple_of_sequences<3>(tuple_of_seqs);
90+
EXPECT_EQ(result.itran, 1); // Found in second sequence (index 1)
91+
EXPECT_EQ(result.idim_up, 1); // At position 1 within that sequence
92+
EXPECT_TRUE(result.found);
93+
}
94+
95+
TEST(FindInTupleOfSequences, FindInLastSequence)
96+
{
97+
constexpr auto tuple_of_seqs = make_tuple(Sequence<0, 1>{}, Sequence<2, 3>{}, Sequence<4, 5>{});
98+
constexpr auto result = find_in_tuple_of_sequences<5>(tuple_of_seqs);
99+
EXPECT_EQ(result.itran, 2); // Found in third sequence (index 2)
100+
EXPECT_EQ(result.idim_up, 1); // At position 1 within that sequence
101+
EXPECT_TRUE(result.found);
102+
}
103+
104+
TEST(FindInTupleOfSequences, NotFound)
105+
{
106+
constexpr auto tuple_of_seqs = make_tuple(Sequence<0, 1>{}, Sequence<2, 3>{}, Sequence<4, 5>{});
107+
constexpr auto result = find_in_tuple_of_sequences<99>(tuple_of_seqs);
108+
EXPECT_FALSE(result.found);
109+
}
110+
111+
TEST(FindInTupleOfSequences, EmptyTuple)
112+
{
113+
constexpr auto tuple_of_seqs = make_tuple();
114+
constexpr auto result = find_in_tuple_of_sequences<1>(tuple_of_seqs);
115+
EXPECT_FALSE(result.found);
116+
}
117+
118+
TEST(FindInTupleOfSequences, SingleSequence)
119+
{
120+
constexpr auto tuple_of_seqs = make_tuple(Sequence<10, 20, 30>{});
121+
constexpr auto result = find_in_tuple_of_sequences<20>(tuple_of_seqs);
122+
EXPECT_EQ(result.itran, 0);
123+
EXPECT_EQ(result.idim_up, 1);
124+
EXPECT_TRUE(result.found);
125+
}
126+
127+
// Test unpack_and_merge_sequences
128+
TEST(UnpackAndMergeSequences, MergeMultipleSequences)
129+
{
130+
constexpr auto tuple_of_seqs = make_tuple(Sequence<1, 2>{}, Sequence<3, 4>{}, Sequence<5, 6>{});
131+
constexpr auto result = unpack_and_merge_sequences(tuple_of_seqs);
132+
using Expected = Sequence<1, 2, 3, 4, 5, 6>;
133+
EXPECT_TRUE((is_same<remove_cvref_t<decltype(result)>, Expected>::value));
134+
}
135+
136+
TEST(UnpackAndMergeSequences, SingleSequence)
137+
{
138+
constexpr auto tuple_of_seqs = make_tuple(Sequence<1, 2, 3>{});
139+
constexpr auto result = unpack_and_merge_sequences(tuple_of_seqs);
140+
using Expected = Sequence<1, 2, 3>;
141+
EXPECT_TRUE((is_same<remove_cvref_t<decltype(result)>, Expected>::value));
142+
}

0 commit comments

Comments
 (0)