@@ -32,10 +32,9 @@ TYPED_TEST_SUITE_P(simdkvsort);
32
32
33
33
template <typename T>
34
34
bool same_values (T* v1, T* v2, size_t size){
35
- // Checks that the values are the same except (maybe) their ordering
35
+ // Checks that the values are the same except ordering
36
36
auto cmp_eq = compare<T, std::equal_to<T>>();
37
37
38
- // TODO hardcoding hasnan to true doesn't break anything right?
39
38
x86simdsort::qsort (v1, size, true );
40
39
x86simdsort::qsort (v2, size, true );
41
40
@@ -49,7 +48,7 @@ bool same_values(T* v1, T* v2, size_t size){
49
48
}
50
49
51
50
template <typename T1, typename T2>
52
- bool kv_equivalent (T1* keys_comp, T2* vals_comp, T1* keys_ref, T2* vals_ref, size_t size){
51
+ bool is_kv_sorted (T1* keys_comp, T2* vals_comp, T1* keys_ref, T2* vals_ref, size_t size){
53
52
auto cmp_eq = compare<T1, std::equal_to<T1>>();
54
53
55
54
// First check keys are exactly identical
@@ -66,7 +65,7 @@ bool kv_equivalent(T1* keys_comp, T2* vals_comp, T1* keys_ref, T2* vals_ref, siz
66
65
size_t i = 0 ;
67
66
for (; i < size; i++){
68
67
if (!cmp_eq (keys_comp[i], key_start)){
69
- // Check that every value in
68
+ // Check that every value in this block of constant keys
70
69
71
70
if (!same_values (vals_ref + i_start, vals_comp + i_start, i - i_start)){
72
71
return false ;
@@ -78,6 +77,66 @@ bool kv_equivalent(T1* keys_comp, T2* vals_comp, T1* keys_ref, T2* vals_ref, siz
78
77
}
79
78
}
80
79
80
+ // Handle the last group
81
+ if (!same_values (vals_ref + i_start, vals_comp + i_start, i - i_start)){
82
+ return false ;
83
+ }
84
+
85
+ return true ;
86
+ }
87
+
88
+ template <typename T1, typename T2>
89
+ bool is_kv_partialsorted (T1* keys_comp, T2* vals_comp, T1* keys_ref, T2* vals_ref, size_t size, size_t k){
90
+ auto cmp_eq = compare<T1, std::equal_to<T1>>();
91
+
92
+ // First check keys are exactly identical (up to k)
93
+ for (size_t i = 0 ; i < k; i++){
94
+ if (!cmp_eq (keys_comp[i], keys_ref[i])){
95
+ return false ;
96
+ }
97
+ }
98
+
99
+ size_t i_start = 0 ;
100
+ T1 key_start = keys_comp[0 ];
101
+ // Loop through all identical keys in a block, then compare the sets of values to make sure they are identical
102
+ for (size_t i = 0 ; i < k; i++){
103
+ if (!cmp_eq (keys_comp[i], key_start)){
104
+ // Check that every value in this block of constant keys
105
+
106
+ if (!same_values (vals_ref + i_start, vals_comp + i_start, i - i_start)){
107
+ return false ;
108
+ }
109
+
110
+ // Now setup the start variables to begin gathering keys for the next group
111
+ i_start = i;
112
+ key_start = keys_comp[i];
113
+ }
114
+ }
115
+
116
+ // Now, we need to do some more work to handle keys exactly equal to the true kth
117
+ // First, fully kvsort both arrays
118
+ xss::scalar::keyvalue_qsort<T1, T2>(keys_ref, vals_ref, size, true , false );
119
+ xss::scalar::keyvalue_qsort<T1, T2>(keys_comp, vals_comp, size, true , false );
120
+
121
+ auto trueKth = keys_ref[k];
122
+ bool notFoundFirst = true ;
123
+ size_t i = 0 ;
124
+
125
+ for (; i < size; i++){
126
+ if (notFoundFirst && cmp_eq (keys_ref[i], trueKth)){
127
+ notFoundFirst = false ;
128
+ i_start = i;
129
+ }else if (!notFoundFirst && !cmp_eq (keys_ref[i], trueKth)){
130
+ break ;
131
+ }
132
+ }
133
+
134
+ if (notFoundFirst) return false ;
135
+
136
+ if (!same_values (vals_ref + i_start, vals_comp + i_start, i - i_start)){
137
+ return false ;
138
+ }
139
+
81
140
return true ;
82
141
}
83
142
@@ -96,8 +155,8 @@ TYPED_TEST_P(simdkvsort, test_kvsort_ascending)
96
155
xss::scalar::keyvalue_qsort (
97
156
key_bckp.data (), val_bckp.data (), size, hasnan, false );
98
157
99
- bool is_kv_equivalent = kv_equivalent <T1, T2>(key.data (), val.data (), key_bckp.data (), val_bckp.data (), size);
100
- ASSERT_EQ (is_kv_equivalent , true );
158
+ bool is_kv_sorted_ = is_kv_sorted <T1, T2>(key.data (), val.data (), key_bckp.data (), val_bckp.data (), size);
159
+ ASSERT_EQ (is_kv_sorted_ , true );
101
160
102
161
key.clear ();
103
162
val.clear ();
@@ -122,8 +181,8 @@ TYPED_TEST_P(simdkvsort, test_kvsort_descending)
122
181
xss::scalar::keyvalue_qsort (
123
182
key_bckp.data (), val_bckp.data (), size, hasnan, true );
124
183
125
- bool is_kv_equivalent = kv_equivalent <T1, T2>(key.data (), val.data (), key_bckp.data (), val_bckp.data (), size);
126
- ASSERT_EQ (is_kv_equivalent , true );
184
+ bool is_kv_sorted_ = is_kv_sorted <T1, T2>(key.data (), val.data (), key_bckp.data (), val_bckp.data (), size);
185
+ ASSERT_EQ (is_kv_sorted_ , true );
127
186
128
187
key.clear ();
129
188
val.clear ();
@@ -155,9 +214,10 @@ TYPED_TEST_P(simdkvsort, test_kvselect_ascending)
155
214
IS_ARR_PARTITIONED<T1>(key, k, key_bckp[k], type);
156
215
xss::scalar::keyvalue_qsort (key.data (), val.data (), k, hasnan, false );
157
216
217
+ ASSERT_EQ (key[k], key_bckp[k]);
158
218
159
- bool is_kv_equivalent = kv_equivalent <T1, T2>(key.data (), val.data (), key_bckp.data (), val_bckp.data (), k);
160
- ASSERT_EQ (is_kv_equivalent , true );
219
+ bool is_kv_partialsorted_ = is_kv_partialsorted <T1, T2>(key.data (), val.data (), key_bckp.data (), val_bckp.data (), size , k);
220
+ ASSERT_EQ (is_kv_partialsorted_ , true );
161
221
162
222
key.clear ();
163
223
val.clear ();
@@ -189,9 +249,10 @@ TYPED_TEST_P(simdkvsort, test_kvselect_descending)
189
249
IS_ARR_PARTITIONED<T1>(key, k, key_bckp[k], type, true );
190
250
xss::scalar::keyvalue_qsort (key.data (), val.data (), k, hasnan, true );
191
251
252
+ ASSERT_EQ (key[k], key_bckp[k]);
192
253
193
- bool is_kv_equivalent = kv_equivalent <T1, T2>(key.data (), val.data (), key_bckp.data (), val_bckp.data (), k);
194
- ASSERT_EQ (is_kv_equivalent , true );
254
+ bool is_kv_partialsorted_ = is_kv_partialsorted <T1, T2>(key.data (), val.data (), key_bckp.data (), val_bckp.data (), size , k);
255
+ ASSERT_EQ (is_kv_partialsorted_ , true );
195
256
196
257
key.clear ();
197
258
val.clear ();
@@ -220,8 +281,8 @@ TYPED_TEST_P(simdkvsort, test_kvpartial_sort_ascending)
220
281
221
282
IS_ARR_PARTIALSORTED<T1>(key, k, key_bckp, type);
222
283
223
- bool is_kv_equivalent = kv_equivalent <T1, T2>(key.data (), val.data (), key_bckp.data (), val_bckp.data (), k);
224
- ASSERT_EQ (is_kv_equivalent , true );
284
+ bool is_kv_partialsorted_ = is_kv_partialsorted <T1, T2>(key.data (), val.data (), key_bckp.data (), val_bckp.data (), size , k);
285
+ ASSERT_EQ (is_kv_partialsorted_ , true );
225
286
226
287
key.clear ();
227
288
val.clear ();
@@ -250,8 +311,8 @@ TYPED_TEST_P(simdkvsort, test_kvpartial_sort_descending)
250
311
251
312
IS_ARR_PARTIALSORTED<T1>(key, k, key_bckp, type);
252
313
253
- bool is_kv_equivalent = kv_equivalent <T1, T2>(key.data (), val.data (), key_bckp.data (), val_bckp.data (), k);
254
- ASSERT_EQ (is_kv_equivalent , true );
314
+ bool is_kv_partialsorted_ = is_kv_partialsorted <T1, T2>(key.data (), val.data (), key_bckp.data (), val_bckp.data (), size , k);
315
+ ASSERT_EQ (is_kv_partialsorted_ , true );
255
316
256
317
key.clear ();
257
318
val.clear ();
@@ -275,26 +336,26 @@ TYPED_TEST_P(simdkvsort, test_validator)
275
336
std::vector<T2> val_bckp = val;
276
337
277
338
// Duplicate keys, but otherwise exactly identical
278
- is_kv_equivalent = kv_equivalent <T1, T2>(key.data (), val.data (), key_bckp.data (), val_bckp.data (), key.size ());
339
+ is_kv_equivalent = is_kv_sorted <T1, T2>(key.data (), val.data (), key_bckp.data (), val_bckp.data (), key.size ());
279
340
ASSERT_EQ (is_kv_equivalent, true );
280
341
281
342
val = {2 ,1 ,4 ,3 };
282
343
283
344
// Now values are backwards, but this is still fine
284
- is_kv_equivalent = kv_equivalent <T1, T2>(key.data (), val.data (), key_bckp.data (), val_bckp.data (), key.size ());
345
+ is_kv_equivalent = is_kv_sorted <T1, T2>(key.data (), val.data (), key_bckp.data (), val_bckp.data (), key.size ());
285
346
ASSERT_EQ (is_kv_equivalent, true );
286
347
287
348
val = {1 ,3 ,2 ,4 };
288
349
289
350
// Now values are mixed up, should fail
290
- is_kv_equivalent = kv_equivalent <T1, T2>(key.data (), val.data (), key_bckp.data (), val_bckp.data (), key.size ());
351
+ is_kv_equivalent = is_kv_sorted <T1, T2>(key.data (), val.data (), key_bckp.data (), val_bckp.data (), key.size ());
291
352
ASSERT_EQ (is_kv_equivalent, false );
292
353
293
354
val = {1 ,2 ,3 ,4 };
294
355
key = {0 ,0 ,0 ,0 };
295
356
296
357
// Now keys are messed up, should fail
297
- is_kv_equivalent = kv_equivalent <T1, T2>(key.data (), val.data (), key_bckp.data (), val_bckp.data (), key.size ());
358
+ is_kv_equivalent = is_kv_sorted <T1, T2>(key.data (), val.data (), key_bckp.data (), val_bckp.data (), key.size ());
298
359
ASSERT_EQ (is_kv_equivalent, false );
299
360
300
361
key = {0 ,0 ,0 ,0 ,0 ,0 };
@@ -303,7 +364,7 @@ TYPED_TEST_P(simdkvsort, test_validator)
303
364
val = {4 ,3 ,1 ,6 ,5 ,2 };
304
365
305
366
// All keys identical, simply reordered values
306
- is_kv_equivalent = kv_equivalent <T1, T2>(key.data (), val.data (), key_bckp.data (), val_bckp.data (), key.size ());
367
+ is_kv_equivalent = is_kv_sorted <T1, T2>(key.data (), val.data (), key_bckp.data (), val_bckp.data (), key.size ());
307
368
ASSERT_EQ (is_kv_equivalent, true );
308
369
}
309
370
0 commit comments