@@ -29,6 +29,57 @@ class simdkvsort : public ::testing::Test {
29
29
30
30
TYPED_TEST_SUITE_P (simdkvsort);
31
31
32
+ template <typename T>
33
+ bool same_values (T* v1, T* v2, size_t size){
34
+ // Checks that the values are the same except (maybe) their ordering
35
+ auto cmp_eq = compare<T, std::equal_to<T>>();
36
+
37
+ // TODO hardcoding hasnan to true doesn't break anything right?
38
+ x86simdsort::qsort (v1, size, true );
39
+ x86simdsort::qsort (v2, size, true );
40
+
41
+ for (size_t i = 0 ; i < size; i++){
42
+ if (!cmp_eq (v1[i], v2[i])){
43
+ return false ;
44
+ }
45
+ }
46
+
47
+ return true ;
48
+ }
49
+
50
+ template <typename T1, typename T2>
51
+ bool kv_equivalent (T1* keys_comp, T2* vals_comp, T1* keys_ref, T2* vals_ref, size_t size){
52
+ auto cmp_eq = compare<T1, std::equal_to<T1>>();
53
+
54
+ // First check keys are exactly identical
55
+ for (size_t i = 0 ; i < size; i++){
56
+ if (!cmp_eq (keys_comp[i], keys_ref[i])){
57
+ return false ;
58
+ }
59
+ }
60
+
61
+ size_t i_start = 0 ;
62
+ T1 key_start = keys_comp[0 ];
63
+ // Loop through all identical keys in a block, then compare the sets of values to make sure they are identical
64
+ // We need the index after the loop
65
+ size_t i = 0 ;
66
+ for (; i < size; i++){
67
+ if (!cmp_eq (keys_comp[i], key_start)){
68
+ // Check that every value in
69
+
70
+ if (!same_values (vals_ref + i_start, vals_comp + i_start, i - i_start)){
71
+ return false ;
72
+ }
73
+
74
+ // Now setup the start variables to begin gathering keys for the next group
75
+ i_start = i;
76
+ key_start = keys_comp[i];
77
+ }
78
+ }
79
+
80
+ return true ;
81
+ }
82
+
32
83
TYPED_TEST_P (simdkvsort, test_kvsort)
33
84
{
34
85
using T1 = typename std::tuple_element<0 , decltype (TypeParam ())>::type;
@@ -43,10 +94,10 @@ TYPED_TEST_P(simdkvsort, test_kvsort)
43
94
x86simdsort::keyvalue_qsort (key.data (), val.data (), size, hasnan);
44
95
xss::scalar::keyvalue_qsort (
45
96
key_bckp.data (), val_bckp.data (), size, hasnan);
46
- ASSERT_EQ (key, key_bckp);
47
- const bool hasDuplicates
48
- = std::adjacent_find (key. begin (), key. end ()) != key. end ( );
49
- if (!hasDuplicates) { ASSERT_EQ (val, val_bckp); }
97
+
98
+ bool is_kv_equivalent = kv_equivalent<T1, T2>(key. data (), val. data (), key_bckp. data (), val_bckp. data (), size);
99
+ ASSERT_EQ (is_kv_equivalent, true );
100
+
50
101
key.clear ();
51
102
val.clear ();
52
103
key_bckp.clear ();
@@ -55,7 +106,53 @@ TYPED_TEST_P(simdkvsort, test_kvsort)
55
106
}
56
107
}
57
108
58
- REGISTER_TYPED_TEST_SUITE_P (simdkvsort, test_kvsort);
109
+ TYPED_TEST_P (simdkvsort, test_validator)
110
+ {
111
+ // Tests a few edge cases to verify the tests are working correctly and identifying it as functional
112
+ using T1 = typename std::tuple_element<0 , decltype (TypeParam ())>::type;
113
+ using T2 = typename std::tuple_element<1 , decltype (TypeParam ())>::type;
114
+
115
+ bool is_kv_equivalent;
116
+
117
+ std::vector<T1> key = {0 , 0 , 1 , 1 };
118
+ std::vector<T2> val = {1 , 2 , 3 , 4 };
119
+ std::vector<T1> key_bckp = key;
120
+ std::vector<T2> val_bckp = val;
121
+
122
+ // Duplicate keys, but otherwise exactly identical
123
+ is_kv_equivalent = kv_equivalent<T1, T2>(key.data (), val.data (), key_bckp.data (), val_bckp.data (), key.size ());
124
+ ASSERT_EQ (is_kv_equivalent, true );
125
+
126
+ val = {2 ,1 ,4 ,3 };
127
+
128
+ // Now values are backwards, but this is still fine
129
+ is_kv_equivalent = kv_equivalent<T1, T2>(key.data (), val.data (), key_bckp.data (), val_bckp.data (), key.size ());
130
+ ASSERT_EQ (is_kv_equivalent, true );
131
+
132
+ val = {1 ,3 ,2 ,4 };
133
+
134
+ // Now values are mixed up, should fail
135
+ is_kv_equivalent = kv_equivalent<T1, T2>(key.data (), val.data (), key_bckp.data (), val_bckp.data (), key.size ());
136
+ ASSERT_EQ (is_kv_equivalent, false );
137
+
138
+ val = {1 ,2 ,3 ,4 };
139
+ key = {0 ,0 ,0 ,0 };
140
+
141
+ // Now keys are messed up, should fail
142
+ is_kv_equivalent = kv_equivalent<T1, T2>(key.data (), val.data (), key_bckp.data (), val_bckp.data (), key.size ());
143
+ ASSERT_EQ (is_kv_equivalent, false );
144
+
145
+ key = {0 ,0 ,0 ,0 ,0 ,0 };
146
+ key_bckp = key;
147
+ val_bckp = {1 ,2 ,3 ,4 ,5 ,6 };
148
+ val = {4 ,3 ,1 ,6 ,5 ,2 };
149
+
150
+ // All keys identical, simply reordered values
151
+ is_kv_equivalent = kv_equivalent<T1, T2>(key.data (), val.data (), key_bckp.data (), val_bckp.data (), key.size ());
152
+ ASSERT_EQ (is_kv_equivalent, true );
153
+ }
154
+
155
+ REGISTER_TYPED_TEST_SUITE_P (simdkvsort, test_kvsort, test_validator);
59
156
60
157
#define CREATE_TUPLES (type ) \
61
158
std::tuple<double , type>, std::tuple<uint64_t , type>, \
0 commit comments