LLVM OpenMP
TestOMPTraits.cpp
Go to the documentation of this file.
1//===- TestOMPTraits.cpp - Tests for OMP Trait classes -------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "kmp_traits.h"
10#include "gtest/gtest.h"
11
12using namespace kmp_traits;
13
14namespace {
15
16//===----------------------------------------------------------------------===//
17// kmp_wildcard_trait Tests
18//===----------------------------------------------------------------------===//
19
20TEST(kmp_wildcard_trait_test, MatchesAnyDevice) {
22
23 EXPECT_TRUE(trait->match(0));
24 EXPECT_TRUE(trait->match(1));
25 EXPECT_TRUE(trait->match(100));
26 EXPECT_TRUE(trait->match(-1));
27
28 delete trait;
29}
30
31TEST(kmp_wildcard_trait_test, Equality) {
34
35 EXPECT_TRUE(*t1 == *t2);
36
37 delete t1;
38 delete t2;
39}
40
41//===----------------------------------------------------------------------===//
42// kmp_literal_trait Tests
43//===----------------------------------------------------------------------===//
44
45TEST(kmp_literal_trait_test, MatchesExactDevice) {
47
48 EXPECT_TRUE(trait->match(5));
49 EXPECT_FALSE(trait->match(0));
50 EXPECT_FALSE(trait->match(4));
51 EXPECT_FALSE(trait->match(6));
52
53 delete trait;
54}
55
56TEST(kmp_literal_trait_test, MatchesZero) {
58
59 EXPECT_TRUE(trait->match(0));
60 EXPECT_FALSE(trait->match(1));
61
62 delete trait;
63}
64
65#ifndef NDEBUG
66TEST(kmp_literal_trait_test, MatchesNegative) {
67 EXPECT_DEATH(new kmp_literal_trait(-1), "Device number must be non-negative");
68}
69#endif
70
71TEST(kmp_literal_trait_test, EqualitySameValue) {
74
75 EXPECT_TRUE(*t1 == *t2);
76
77 delete t1;
78 delete t2;
79}
80
81TEST(kmp_literal_trait_test, EqualityDifferentValue) {
84
85 EXPECT_FALSE(*t1 == *t2);
86
87 delete t1;
88 delete t2;
89}
90
91//===----------------------------------------------------------------------===//
92// kmp_uid_trait Tests
93//===----------------------------------------------------------------------===//
94
95TEST(kmp_uid_trait_test, Construction) {
96 kmp_uid_trait *trait = new kmp_uid_trait(kmp_str_ref("test-uid"));
97
98 // Just verify it can be constructed without crashing
99 delete trait;
100}
101
102TEST(kmp_uid_trait_test, MatchWithMock) {
103 kmp_uid_trait *trait = new kmp_uid_trait(kmp_str_ref("device-0"));
104
105 // Uses the mock omp_get_uid_from_device
106 EXPECT_TRUE(trait->match(0)); // device-0 matches
107 EXPECT_FALSE(trait->match(1)); // device-1 doesn't match
108 EXPECT_FALSE(trait->match(2)); // device-2 doesn't match
109
110 delete trait;
111}
112
113TEST(kmp_uid_trait_test, MatchWithCustomMock) {
114 kmp_uid_trait *trait = new kmp_uid_trait(kmp_str_ref("custom-uid"));
115
116 // Set a custom mock function
117 trait->set_uid_from_device([](int device) -> const char * {
118 return device == 2 ? "custom-uid" : "other";
119 });
120
121 EXPECT_FALSE(trait->match(0));
122 EXPECT_FALSE(trait->match(1));
123 EXPECT_TRUE(trait->match(2)); // custom-uid matches device 2
124 EXPECT_FALSE(trait->match(3));
125
126 delete trait;
127}
128
129TEST(kmp_uid_trait_test, EqualitySameUID) {
130 kmp_uid_trait *t1 = new kmp_uid_trait(kmp_str_ref("my-device"));
131 kmp_uid_trait *t2 = new kmp_uid_trait(kmp_str_ref("my-device"));
132
133 EXPECT_TRUE(*t1 == *t2);
134
135 delete t1;
136 delete t2;
137}
138
139TEST(kmp_uid_trait_test, EqualityDifferentUID) {
140 kmp_uid_trait *t1 = new kmp_uid_trait(kmp_str_ref("device-a"));
141 kmp_uid_trait *t2 = new kmp_uid_trait(kmp_str_ref("device-b"));
142
143 EXPECT_FALSE(*t1 == *t2);
144
145 delete t1;
146 delete t2;
147}
148
149//===----------------------------------------------------------------------===//
150// kmp_trait_expr_single Tests
151//===----------------------------------------------------------------------===//
152
153TEST(kmp_trait_expr_single_test, CreateAndDestroy) {
155 EXPECT_NE(expr, nullptr);
156 delete expr;
157}
158
159TEST(kmp_trait_expr_single_test, CreateWithTrait) {
162
163 // Mock: 4 devices
164 expr->set_num_devices([]() { return 4; });
165
166 EXPECT_TRUE(expr->match(2));
167 EXPECT_FALSE(expr->match(0));
168 EXPECT_FALSE(expr->match(1));
169 EXPECT_FALSE(expr->match(5)); // Out of range
170
171 delete expr;
172}
173
174TEST(kmp_trait_expr_single_test, SetTrait) {
176 expr->set_trait(new kmp_literal_trait(3));
177
178 // Mock: 4 devices
179 expr->set_num_devices([]() { return 4; });
180
181 EXPECT_TRUE(expr->match(3));
182 EXPECT_FALSE(expr->match(0));
183
184 delete expr;
185}
186
187TEST(kmp_trait_expr_single_test, DefaultNotNegated) {
189
190 EXPECT_FALSE(expr->is_negated());
191
192 delete expr;
193}
194
195TEST(kmp_trait_expr_single_test, SetNegated) {
197
198 expr->set_negated(true);
199 EXPECT_TRUE(expr->is_negated());
200
201 expr->set_negated(false);
202 EXPECT_FALSE(expr->is_negated());
203
204 delete expr;
205}
206
207TEST(kmp_trait_expr_single_test, MatchNegated) {
210 expr->set_negated(true);
211
212 // Mock: 4 devices
213 expr->set_num_devices([]() { return 4; });
214
215 // Without negation: matches 2
216 // With negation: matches everything in-range except 2
217 EXPECT_FALSE(expr->match(2));
218 EXPECT_TRUE(expr->match(0));
219 EXPECT_TRUE(expr->match(1));
220 EXPECT_TRUE(expr->match(3));
221 // Out of range devices return false regardless of negation
222 EXPECT_FALSE(expr->match(5));
223
224 delete expr;
225}
226
227TEST(kmp_trait_expr_single_test, MatchWildcard) {
230
231 // Mock: 4 devices
232 expr->set_num_devices([]() { return 4; });
233
234 // Wildcard matches any in-range device
235 EXPECT_TRUE(expr->match(0));
236 EXPECT_TRUE(expr->match(3));
237 // Out of range devices return false
238 EXPECT_FALSE(expr->match(100));
239
240 delete expr;
241}
242
243TEST(kmp_trait_expr_single_test, Equality) {
248
249 EXPECT_TRUE(*e1 == *e2);
250
251 delete e1;
252 delete e2;
253}
254
255TEST(kmp_trait_expr_single_test, EqualityDifferentTrait) {
260
261 EXPECT_FALSE(*e1 == *e2);
262
263 delete e1;
264 delete e2;
265}
266
267TEST(kmp_trait_expr_single_test, EqualityDifferentNegation) {
272 e2->set_negated(true);
273
274 EXPECT_FALSE(*e1 == *e2);
275
276 delete e1;
277 delete e2;
278}
279
280//===----------------------------------------------------------------------===//
281// kmp_trait_expr_group Tests
282//===----------------------------------------------------------------------===//
283
284TEST(kmp_trait_expr_group_test, CreateAndDestroy) {
286 EXPECT_NE(group, nullptr);
287 delete group;
288}
289
290TEST(kmp_trait_expr_group_test, DefaultTypeIsOR) {
292
293 EXPECT_EQ(group->get_group_type(), kmp_trait_expr_group::OR);
294
295 delete group;
296}
297
298TEST(kmp_trait_expr_group_test, SetTypeAND) {
300
302 EXPECT_EQ(group->get_group_type(), kmp_trait_expr_group::AND);
303
304 delete group;
305}
306
307TEST(kmp_trait_expr_group_test, DefaultNotNegated) {
309
310 EXPECT_FALSE(group->is_negated());
311
312 delete group;
313}
314
315TEST(kmp_trait_expr_group_test, SetNegated) {
317
318 group->set_negated(true);
319 EXPECT_TRUE(group->is_negated());
320
321 group->set_negated(false);
322 EXPECT_FALSE(group->is_negated());
323
324 delete group;
325}
326
327TEST(kmp_trait_expr_group_test, AddTraitDirectly) {
329
330 group->add_expr(new kmp_wildcard_trait());
331
332 // Mock: 4 devices
333 group->set_num_devices([]() { return 4; });
334
335 // Wildcard matches any in-range device
336 EXPECT_TRUE(group->match(0));
337 EXPECT_TRUE(group->match(3));
338 // Out of range devices return false
339 EXPECT_FALSE(group->match(100));
340
341 delete group;
342}
343
344TEST(kmp_trait_expr_group_test, AddExpr) {
346
348
349 // Mock: 4 devices
350 group->set_num_devices([]() { return 4; });
351
352 EXPECT_TRUE(group->match(2));
353 EXPECT_FALSE(group->match(0));
354 EXPECT_FALSE(group->match(5)); // Out of range
355
356 delete group;
357}
358
359TEST(kmp_trait_expr_group_test, MatchORSemantics) {
362
363 group->add_expr(new kmp_literal_trait(1));
364 group->add_expr(new kmp_literal_trait(2));
365 group->add_expr(new kmp_literal_trait(3));
366
367 // Mock: 5 devices
368 group->set_num_devices([]() { return 5; });
369
370 // OR: matches if ANY trait matches
371 EXPECT_TRUE(group->match(1));
372 EXPECT_TRUE(group->match(2));
373 EXPECT_TRUE(group->match(3));
374 EXPECT_FALSE(group->match(0));
375 EXPECT_FALSE(group->match(4));
376
377 delete group;
378}
379
380TEST(kmp_trait_expr_group_test, MatchANDSemantics) {
383
384 // For AND to pass, ALL traits must match the same device
385 // A single literal only matches one device
386 group->add_expr(new kmp_literal_trait(2));
387
388 // Mock: 4 devices
389 group->set_num_devices([]() { return 4; });
390
391 EXPECT_TRUE(group->match(2));
392 EXPECT_FALSE(group->match(0));
393 // Out of range
394 EXPECT_FALSE(group->match(5));
395
396 delete group;
397}
398
399TEST(kmp_trait_expr_group_test, MatchANDWithWildcard) {
402
403 group->add_expr(new kmp_wildcard_trait());
404 group->add_expr(new kmp_literal_trait(2));
405
406 // Mock: 4 devices
407 group->set_num_devices([]() { return 4; });
408
409 // Wildcard matches all, literal matches 2
410 // AND: both must match
411 EXPECT_TRUE(group->match(2));
412 EXPECT_FALSE(group->match(0));
413 // Out of range
414 EXPECT_FALSE(group->match(5));
415
416 delete group;
417}
418
419TEST(kmp_trait_expr_group_test, MatchNegated) {
421
422 group->add_expr(new kmp_literal_trait(2));
423 group->set_negated(true);
424
425 // Mock: 4 devices
426 group->set_num_devices([]() { return 4; });
427
428 // Without negation: matches 2
429 // With negation: matches everything in-range except 2
430 EXPECT_FALSE(group->match(2));
431 EXPECT_TRUE(group->match(0));
432 EXPECT_TRUE(group->match(1));
433 EXPECT_TRUE(group->match(3));
434 // Out of range devices return false regardless of negation
435 EXPECT_FALSE(group->match(5));
436
437 delete group;
438}
439
440TEST(kmp_trait_expr_group_test, MatchEmptyGroupOR) {
443
444 // Mock: 4 devices
445 group->set_num_devices([]() { return 4; });
446
447 // Empty OR: no traits match, so result is false
448 EXPECT_FALSE(group->match(0));
449 EXPECT_FALSE(group->match(1));
450
451 delete group;
452}
453
454TEST(kmp_trait_expr_group_test, MatchEmptyGroupAND) {
457
458 // Mock: 4 devices
459 group->set_num_devices([]() { return 4; });
460
461 // Empty AND: vacuously true (0 out of 0 traits match)
462 EXPECT_TRUE(group->match(0));
463 EXPECT_TRUE(group->match(1));
464
465 delete group;
466}
467
468TEST(kmp_trait_expr_group_test, Equality) {
471
472 g1->add_expr(new kmp_literal_trait(1));
473 g2->add_expr(new kmp_literal_trait(1));
474
475 EXPECT_TRUE(*g1 == *g2);
476
477 delete g1;
478 delete g2;
479}
480
481TEST(kmp_trait_expr_group_test, EqualityDifferentNegation) {
484
485 g1->add_expr(new kmp_literal_trait(1));
486 g2->add_expr(new kmp_literal_trait(1));
487 g2->set_negated(true);
488
489 EXPECT_FALSE(*g1 == *g2);
490
491 delete g1;
492 delete g2;
493}
494
495TEST(kmp_trait_expr_group_test, EqualityDifferentGroupType) {
496 // Groups with the same sub-expressions but different AND/OR type are not
497 // equal.
500
501 g1->add_expr(new kmp_literal_trait(1));
502 g1->add_expr(new kmp_literal_trait(2));
504 g2->add_expr(new kmp_literal_trait(1));
505 g2->add_expr(new kmp_literal_trait(2));
507
508 EXPECT_FALSE(*g1 == *g2);
509
510 delete g1;
511 delete g2;
512}
513
514TEST(kmp_trait_expr_group_test, NestedGroups) {
517
520 inner->add_expr(new kmp_literal_trait(1));
521 inner->add_expr(new kmp_wildcard_trait());
522
523 outer->add_expr(inner);
524 outer->add_expr(new kmp_literal_trait(2));
525
526 // Mock: 4 devices
527 outer->set_num_devices([]() { return 4; });
528
529 // Inner matches device 1 (literal 1 AND wildcard)
530 // Outer matches 1 OR 2
531 EXPECT_TRUE(outer->match(1));
532 EXPECT_TRUE(outer->match(2));
533 EXPECT_FALSE(outer->match(0));
534 EXPECT_FALSE(outer->match(3));
535
536 delete outer;
537}
538
539//===----------------------------------------------------------------------===//
540// kmp_trait_clause Tests
541//===----------------------------------------------------------------------===//
542
543TEST(kmp_trait_clause_test, CreateAndDestroy) {
544 kmp_trait_clause *clause = new kmp_trait_clause();
545 EXPECT_NE(clause, nullptr);
546 delete clause;
547}
548
549TEST(kmp_trait_clause_test, SetExprWithTrait) {
550 kmp_trait_clause *clause = new kmp_trait_clause();
551 clause->set_expr(new kmp_literal_trait(2));
552
553 // The trait is wrapped in kmp_trait_expr_single internally
554 kmp_trait_expr *expr = clause->get_expr();
555 EXPECT_NE(expr, nullptr);
556
557 delete clause;
558}
559
560TEST(kmp_trait_clause_test, SetExprWithExpr) {
561 kmp_trait_clause *clause = new kmp_trait_clause();
563 group->add_expr(new kmp_literal_trait(1));
564 clause->set_expr(group);
565
566 EXPECT_EQ(clause->get_expr(), group);
567
568 delete clause;
569}
570
571TEST(kmp_trait_clause_test, Equality) {
574
575 c1->set_expr(new kmp_literal_trait(1));
576 c2->set_expr(new kmp_literal_trait(1));
577
578 EXPECT_TRUE(*c1 == *c2);
579
580 delete c1;
581 delete c2;
582}
583
584TEST(kmp_trait_clause_test, EqualityDifferentExprs) {
587
588 c1->set_expr(new kmp_literal_trait(1));
589 c2->set_expr(new kmp_literal_trait(2));
590
591 EXPECT_FALSE(*c1 == *c2);
592
593 delete c1;
594 delete c2;
595}
596
597//===----------------------------------------------------------------------===//
598// kmp_trait_context Tests
599//===----------------------------------------------------------------------===//
600
601TEST(kmp_trait_context_test, CreateAndDestroy) {
602 kmp_trait_context *context = new kmp_trait_context();
603 EXPECT_NE(context, nullptr);
604 delete context;
605}
606
607TEST(kmp_trait_context_test, AddClause) {
608 kmp_trait_context *context = new kmp_trait_context();
609 kmp_trait_clause *clause = new kmp_trait_clause();
610 clause->set_expr(new kmp_literal_trait(2));
611 context->add_clause(clause);
612
613 // Mock: 4 devices
614 context->set_num_devices([]() { return 4; });
615
616 EXPECT_TRUE(context->match(2));
617 EXPECT_FALSE(context->match(0));
618 // Out of range
619 EXPECT_FALSE(context->match(5));
620
621 delete context;
622}
623
624TEST(kmp_trait_context_test, MultipleClauses) {
625 kmp_trait_context *context = new kmp_trait_context();
626
628 c1->set_expr(new kmp_literal_trait(1));
629 context->add_clause(c1);
630
632 c2->set_expr(new kmp_literal_trait(2));
633 context->add_clause(c2);
634
636 c3->set_expr(new kmp_literal_trait(3));
637 context->add_clause(c3);
638
639 // Mock: 5 devices
640 context->set_num_devices([]() { return 5; });
641
642 // Context uses OR semantics between clauses
643 EXPECT_TRUE(context->match(1));
644 EXPECT_TRUE(context->match(2));
645 EXPECT_TRUE(context->match(3));
646 EXPECT_FALSE(context->match(0));
647 EXPECT_FALSE(context->match(4));
648
649 delete context;
650}
651
652TEST(kmp_trait_context_test, EmptyContextMatchesNothing) {
653 kmp_trait_context *context = new kmp_trait_context();
654
655 // Mock: 4 devices
656 context->set_num_devices([]() { return 4; });
657
658 EXPECT_FALSE(context->match(0));
659 EXPECT_FALSE(context->match(1));
660
661 delete context;
662}
663
664TEST(kmp_trait_context_test, WildcardClause) {
665 kmp_trait_context *context = new kmp_trait_context();
666 kmp_trait_clause *clause = new kmp_trait_clause();
667 clause->set_expr(new kmp_wildcard_trait());
668 context->add_clause(clause);
669
670 // Mock: 4 devices
671 context->set_num_devices([]() { return 4; });
672
673 // In-range devices match
674 EXPECT_TRUE(context->match(0));
675 EXPECT_TRUE(context->match(3));
676 // Out of range devices return false
677 EXPECT_FALSE(context->match(100));
678 EXPECT_FALSE(context->match(-1));
679
680 delete context;
681}
682
683TEST(kmp_trait_context_test, EvaluateWithMock) {
684 kmp_trait_context *context = new kmp_trait_context();
685
686 // Mock: 5 devices
687 context->set_num_devices([]() { return 5; });
688
690 c1->set_expr(new kmp_literal_trait(1));
691 context->add_clause(c1);
692
694 c2->set_expr(new kmp_literal_trait(3));
695 context->add_clause(c2);
696
697 kmp_vector<int> result = context->evaluate();
698 EXPECT_EQ(result.size(), 2u);
699 EXPECT_TRUE(result.contains(1));
700 EXPECT_TRUE(result.contains(3));
701 EXPECT_FALSE(result.contains(0));
702 EXPECT_FALSE(result.contains(2));
703 EXPECT_FALSE(result.contains(4));
704
705 delete context;
706}
707
708TEST(kmp_trait_context_test, Equality) {
711
713 c1->set_expr(new kmp_literal_trait(1));
714 ctx1->add_clause(c1);
715
717 c2->set_expr(new kmp_literal_trait(1));
718 ctx2->add_clause(c2);
719
720 EXPECT_TRUE(*ctx1 == *ctx2);
721
722 delete ctx1;
723 delete ctx2;
724}
725
726TEST(kmp_trait_context_test, EqualityDifferentClauses) {
729
731 c1->set_expr(new kmp_literal_trait(1));
732 ctx1->add_clause(c1);
733
735 c2->set_expr(new kmp_literal_trait(2));
736 ctx2->add_clause(c2);
737
738 EXPECT_FALSE(*ctx1 == *ctx2);
739
740 delete ctx1;
741 delete ctx2;
742}
743
744//===----------------------------------------------------------------------===//
745// kmp_trait_context Iterator Tests
746//===----------------------------------------------------------------------===//
747
748TEST(kmp_trait_context_test, IteratorRangeBasedFor) {
749 kmp_trait_context *context = new kmp_trait_context();
750
751 // Mock: 5 devices
752 context->set_num_devices([]() { return 5; });
753
755 c1->set_expr(new kmp_literal_trait(1));
756 context->add_clause(c1);
757
759 c2->set_expr(new kmp_literal_trait(3));
760 context->add_clause(c2);
761
762 // Use range-based for loop (should auto-evaluate)
763 kmp_vector<int> collected;
764 for (int d : *context) {
765 collected.push_back(d);
766 }
767
768 EXPECT_EQ(collected.size(), 2u);
769 EXPECT_TRUE(collected.contains(1));
770 EXPECT_TRUE(collected.contains(3));
771
772 delete context;
773}
774
775TEST(kmp_trait_context_test, IteratorAutoEvaluates) {
776 kmp_trait_context *context = new kmp_trait_context();
777
778 // Mock: 4 devices
779 context->set_num_devices([]() { return 4; });
780
781 kmp_trait_clause *clause = new kmp_trait_clause();
782 clause->set_expr(new kmp_wildcard_trait());
783 context->add_clause(clause);
784
785 // Directly use begin()/end() without calling evaluate() first
786 int count = 0;
787 for (const int *it = context->begin(); it != context->end(); ++it) {
788 EXPECT_GE(*it, 0);
789 EXPECT_LT(*it, 4);
790 count++;
791 }
792
793 EXPECT_EQ(count, 4);
794
795 delete context;
796}
797
798TEST(kmp_trait_context_test, IteratorEmptyContext) {
799 kmp_trait_context *context = new kmp_trait_context();
800
801 // Mock: 4 devices
802 context->set_num_devices([]() { return 4; });
803
804 // Empty context - no clauses added
805 int count = 0;
806 for (int d : *context) {
807 (void)d;
808 count++;
809 }
810
811 EXPECT_EQ(count, 0);
812 EXPECT_EQ(context->begin(), context->end());
813
814 delete context;
815}
816
817TEST(kmp_trait_context_test, IteratorBeginEnd) {
818 kmp_trait_context *context = new kmp_trait_context();
819
820 // Mock: 3 devices
821 context->set_num_devices([]() { return 3; });
822
823 kmp_trait_clause *clause = new kmp_trait_clause();
824 clause->set_expr(new kmp_literal_trait(2));
825 context->add_clause(clause);
826
827 // Test begin/end directly
828 const int *b = context->begin();
829 const int *e = context->end();
830
831 EXPECT_EQ(e - b, 1); // Should have exactly 1 element
832 EXPECT_EQ(*b, 2);
833
834 delete context;
835}
836
837TEST(kmp_trait_context_test, IteratorMultipleDevices) {
838 kmp_trait_context *context = new kmp_trait_context();
839
840 // Add clauses for devices 0, 2, 4
841 for (int i = 0; i < 6; i += 2) {
842 kmp_trait_clause *clause = new kmp_trait_clause();
843 clause->set_expr(new kmp_literal_trait(i));
844 context->add_clause(clause);
845 }
846
847 // Mock: 6 devices (must be set after adding clauses to propagate to them)
848 context->set_num_devices([]() { return 6; });
849
850 // Collect via iterator
851 kmp_vector<int> collected;
852 for (int d : *context) {
853 collected.push_back(d);
854 }
855
856 EXPECT_EQ(collected.size(), 3u);
857 EXPECT_TRUE(collected.contains(0));
858 EXPECT_TRUE(collected.contains(2));
859 EXPECT_TRUE(collected.contains(4));
860
861 delete context;
862}
863
864TEST(kmp_trait_context_test, IteratorConsistentWithEvaluate) {
865 kmp_trait_context *context = new kmp_trait_context();
866
867 // Mock: 5 devices
868 context->set_num_devices([]() { return 5; });
869
871 c1->set_expr(new kmp_literal_trait(1));
872 context->add_clause(c1);
873
875 c2->set_expr(new kmp_literal_trait(4));
876 context->add_clause(c2);
877
878 // Get result via evaluate()
879 const kmp_vector<int> &eval_result = context->evaluate();
880
881 // Collect via iterator
882 kmp_vector<int> iter_result;
883 for (int d : *context) {
884 iter_result.push_back(d);
885 }
886
887 // Both should give the same results
888 EXPECT_EQ(eval_result.size(), iter_result.size());
889 for (size_t i = 0; i < eval_result.size(); i++) {
890 EXPECT_EQ(eval_result[i], iter_result[i]);
891 }
892
893 delete context;
894}
895
896TEST(kmp_trait_context_test, EvaluateReturnsByReference) {
897 kmp_trait_context *context = new kmp_trait_context();
898
899 // Mock: 3 devices
900 context->set_num_devices([]() { return 3; });
901
902 kmp_trait_clause *clause = new kmp_trait_clause();
903 clause->set_expr(new kmp_wildcard_trait());
904 context->add_clause(clause);
905
906 // Multiple calls to evaluate() should return reference to the same data
907 const kmp_vector<int> &result1 = context->evaluate();
908 const kmp_vector<int> &result2 = context->evaluate();
909
910 EXPECT_EQ(&result1, &result2);
911
912 delete context;
913}
914
915//===----------------------------------------------------------------------===//
916// get_num_devices Propagation Tests
917//===----------------------------------------------------------------------===//
918
919TEST(kmp_trait_context_test, PropagationToClausesAddedAfterSetNumDevices) {
920 kmp_trait_context *context = new kmp_trait_context();
921
922 // Set mock BEFORE adding clauses - propagation should still work
923 context->set_num_devices([]() { return 6; });
924
925 // Add clauses for devices 0, 2, 4 (all require 6 devices to be in range)
926 for (int i = 0; i < 6; i += 2) {
927 kmp_trait_clause *clause = new kmp_trait_clause();
928 clause->set_expr(new kmp_literal_trait(i));
929 context->add_clause(clause);
930 }
931
932 // All three devices should match because propagation worked
933 kmp_vector<int> collected;
934 for (int d : *context) {
935 collected.push_back(d);
936 }
937
938 EXPECT_EQ(collected.size(), 3u);
939 EXPECT_TRUE(collected.contains(0));
940 EXPECT_TRUE(collected.contains(2));
941 EXPECT_TRUE(collected.contains(4));
942
943 delete context;
944}
945
946TEST(kmp_trait_context_test, PropagationToClausesAddedBeforeSetNumDevices) {
947 kmp_trait_context *context = new kmp_trait_context();
948
949 // Add clauses BEFORE setting mock
950 for (int i = 0; i < 6; i += 2) {
951 kmp_trait_clause *clause = new kmp_trait_clause();
952 clause->set_expr(new kmp_literal_trait(i));
953 context->add_clause(clause);
954 }
955
956 // Set mock AFTER adding clauses
957 context->set_num_devices([]() { return 6; });
958
959 // All three devices should match
960 kmp_vector<int> collected;
961 for (int d : *context) {
962 collected.push_back(d);
963 }
964
965 EXPECT_EQ(collected.size(), 3u);
966 EXPECT_TRUE(collected.contains(0));
967 EXPECT_TRUE(collected.contains(2));
968 EXPECT_TRUE(collected.contains(4));
969
970 delete context;
971}
972
973TEST(kmp_trait_expr_group_test, PropagationToExprsAddedAfterSetNumDevices) {
975
976 // Set mock BEFORE adding expressions
977 group->set_num_devices([]() { return 8; });
978
979 // Add expressions for devices 5, 6, 7 (require 8 devices)
980 group->add_expr(new kmp_literal_trait(5));
981 group->add_expr(new kmp_literal_trait(6));
982 group->add_expr(new kmp_literal_trait(7));
983
984 // All should match
985 EXPECT_TRUE(group->match(5));
986 EXPECT_TRUE(group->match(6));
987 EXPECT_TRUE(group->match(7));
988 EXPECT_FALSE(group->match(4));
989
990 delete group;
991}
992
993TEST(kmp_trait_expr_group_test, PropagationToExprsAddedBeforeSetNumDevices) {
995
996 // Add expressions BEFORE setting mock
997 group->add_expr(new kmp_literal_trait(5));
998 group->add_expr(new kmp_literal_trait(6));
999 group->add_expr(new kmp_literal_trait(7));
1000
1001 // Set mock AFTER adding expressions
1002 group->set_num_devices([]() { return 8; });
1003
1004 // All should match
1005 EXPECT_TRUE(group->match(5));
1006 EXPECT_TRUE(group->match(6));
1007 EXPECT_TRUE(group->match(7));
1008 EXPECT_FALSE(group->match(4));
1009
1010 delete group;
1011}
1012
1013TEST(kmp_trait_expr_group_test, PropagationToNestedGroups) {
1016
1017 // Set mock on outer group FIRST
1018 outer->set_num_devices([]() { return 10; });
1019
1020 // Create inner group and add high-numbered devices
1023 inner->add_expr(new kmp_literal_trait(8));
1024 inner->add_expr(new kmp_literal_trait(9));
1025
1026 // Add inner to outer - should propagate mock to inner and its children
1027 outer->add_expr(inner);
1028
1029 // Add another expression directly to outer
1030 outer->add_expr(new kmp_literal_trait(7));
1031
1032 // All should match with 10 devices
1033 EXPECT_TRUE(outer->match(7));
1034 EXPECT_TRUE(outer->match(8));
1035 EXPECT_TRUE(outer->match(9));
1036 EXPECT_FALSE(outer->match(10)); // Out of range
1037
1038 delete outer;
1039}
1040
1041TEST(kmp_trait_expr_group_test, PropagationToDeeplyNestedGroups) {
1042 // Create a deeply nested structure: outer -> middle -> inner
1045
1046 // Set mock on outer
1047 outer->set_num_devices([]() { return 12; });
1048
1051
1054 inner->add_expr(new kmp_literal_trait(10));
1055 inner->add_expr(new kmp_literal_trait(11));
1056
1057 middle->add_expr(inner);
1058 middle->add_expr(new kmp_literal_trait(9));
1059
1060 outer->add_expr(middle);
1061 outer->add_expr(new kmp_literal_trait(8));
1062
1063 // All devices 8-11 should match (requires 12 devices)
1064 EXPECT_TRUE(outer->match(8));
1065 EXPECT_TRUE(outer->match(9));
1066 EXPECT_TRUE(outer->match(10));
1067 EXPECT_TRUE(outer->match(11));
1068 EXPECT_FALSE(outer->match(12)); // Out of range
1069
1070 delete outer;
1071}
1072
1073TEST(kmp_trait_context_test, PropagationToNestedGroupsInClauses) {
1074 kmp_trait_context *context = new kmp_trait_context();
1075
1076 // Set mock on context FIRST
1077 context->set_num_devices([]() { return 10; });
1078
1079 // Create a group with nested structure
1082
1085 inner->add_expr(new kmp_literal_trait(8));
1086 inner->add_expr(new kmp_literal_trait(9));
1087
1088 group->add_expr(inner);
1089 group->add_expr(new kmp_literal_trait(7));
1090
1091 // Create clause with the group
1092 kmp_trait_clause *clause = new kmp_trait_clause();
1093 clause->set_expr(group);
1094
1095 // Add clause to context - should propagate to group and inner
1096 context->add_clause(clause);
1097
1098 // All should match
1099 kmp_vector<int> collected;
1100 for (int d : *context) {
1101 collected.push_back(d);
1102 }
1103
1104 EXPECT_EQ(collected.size(), 3u);
1105 EXPECT_TRUE(collected.contains(7));
1106 EXPECT_TRUE(collected.contains(8));
1107 EXPECT_TRUE(collected.contains(9));
1108
1109 delete context;
1110}
1111
1112TEST(kmp_trait_context_test, PropagationMixedOrder) {
1113 // Test a complex scenario with mixed ordering
1114 kmp_trait_context *context = new kmp_trait_context();
1115
1116 // Add first clause before set_num_devices
1118 c1->set_expr(new kmp_literal_trait(5));
1119 context->add_clause(c1);
1120
1121 // Set mock
1122 context->set_num_devices([]() { return 8; });
1123
1124 // Add second clause after set_num_devices
1126 c2->set_expr(new kmp_literal_trait(6));
1127 context->add_clause(c2);
1128
1129 // Add third clause with a group
1131 group->add_expr(new kmp_literal_trait(7));
1132
1134 c3->set_expr(group);
1135 context->add_clause(c3);
1136
1137 // All three should match
1138 kmp_vector<int> collected;
1139 for (int d : *context) {
1140 collected.push_back(d);
1141 }
1142
1143 EXPECT_EQ(collected.size(), 3u);
1144 EXPECT_TRUE(collected.contains(5));
1145 EXPECT_TRUE(collected.contains(6));
1146 EXPECT_TRUE(collected.contains(7));
1147
1148 delete context;
1149}
1150
1151} // namespace
#define TEST(test_suite_name, test_name)
int result[2]
kmp_str_ref is a non-owning string class (similar to llvm::StringRef).
Definition kmp_adt.h:34
const int * end()
Definition kmp_traits.h:503
void set_num_devices(int(*num_devices)())
Definition kmp_traits.h:476
bool match(int device)
Definition kmp_traits.h:467
const kmp_vector< int > & evaluate()
Definition kmp_traits.h:455
void add_clause(kmp_trait_clause *clause)
Definition kmp_traits.h:441
const int * begin()
Definition kmp_traits.h:502
Represents a specific device number.
Definition kmp_traits.h:135
bool match(int device) const override
Definition kmp_traits.h:144
void set_expr(kmp_trait *trait)
Definition kmp_traits.h:369
kmp_trait_expr * get_expr()
Definition kmp_traits.h:362
Represents a (possibly negated) collection of traits that are either ANDed or ORed together.
Definition kmp_traits.h:288
void set_num_devices(int(*num_devices)())
Definition kmp_traits.h:332
void set_group_type(group_type new_type)
Definition kmp_traits.h:330
void add_expr(kmp_trait *trait)
Definition kmp_traits.h:317
group_type get_group_type() const
Definition kmp_traits.h:328
Represents a single (possibly negated) trait.
Definition kmp_traits.h:250
void set_trait(kmp_trait *new_trait)
Definition kmp_traits.h:269
Abstract class representing either a single trait expression or a collection of trait expressions tha...
Definition kmp_traits.h:194
bool match(int device, int num_devices=-1) const
Definition kmp_traits.h:226
void set_num_devices(int(*num_devices)())
Definition kmp_traits.h:238
void set_negated(bool neg=true)
Definition kmp_traits.h:234
Represents a specific UID.
Definition kmp_traits.h:158
bool match(int device) const override
Definition kmp_traits.h:171
void set_uid_from_device(const char *(*uid_from_device)(int))
Definition kmp_traits.h:180
Represents a wildcard trait that matches any device.
Definition kmp_traits.h:123
bool match(int device) const override
Definition kmp_traits.h:127
kmp_vector is a vector class for managing small vectors.
Definition kmp_adt.h:148
size_t size() const
Definition kmp_adt.h:318
void push_back(const T &value)
Add a new element to the end of the vector.
Definition kmp_adt.h:302
bool contains(const T &value, const Fn &comp=Fn{}) const
Check if the vector contains the given value.
Definition kmp_adt.h:271
void
Definition ittnotify.h:3324
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t count
#define i
Definition kmp_stub.cpp:87