xref: /llvm-project/llvm/unittests/Frontend/OpenMPContextTest.cpp (revision 1228d42ddab832a236563515da5e6de3312fd93c)
1 //===- unittest/IR/OpenMPContextTest.cpp - OpenMP Context handling tests --===//
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 "llvm/Frontend/OpenMP/OMPConstants.h"
10 #include "llvm/Frontend/OpenMP/OMPContext.h"
11 #include "gtest/gtest.h"
12 
13 using namespace llvm;
14 using namespace omp;
15 
16 namespace {
17 
18 class OpenMPContextTest : public testing::Test {
19 protected:
20   void SetUp() override {}
21 
22   void TearDown() override {}
23 };
24 
25 TEST_F(OpenMPContextTest, RoundTripAndAssociation) {
26 #define OMP_TRAIT_SET(Enum, Str)                                               \
27   EXPECT_EQ(TraitSet::Enum,                                                    \
28             getOpenMPContextTraitSetKind(                                      \
29                 getOpenMPContextTraitSetName(TraitSet::Enum)));                \
30   EXPECT_EQ(Str,                                                               \
31             getOpenMPContextTraitSetName(getOpenMPContextTraitSetKind(Str)));
32 #define OMP_TRAIT_SELECTOR(Enum, TraitSetEnum, Str, RequiresProperty)          \
33   EXPECT_EQ(TraitSelector::Enum,                                               \
34             getOpenMPContextTraitSelectorKind(                                 \
35                 getOpenMPContextTraitSelectorName(TraitSelector::Enum)));      \
36   EXPECT_EQ(Str, getOpenMPContextTraitSelectorName(                            \
37                      getOpenMPContextTraitSelectorKind(Str)));
38 #define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str)         \
39   EXPECT_EQ(TraitProperty::Enum,                                               \
40             getOpenMPContextTraitPropertyKind(                                 \
41                 TraitSet::TraitSetEnum,                                        \
42                 getOpenMPContextTraitPropertyName(TraitProperty::Enum)));      \
43   EXPECT_EQ(Str, getOpenMPContextTraitPropertyName(                            \
44                      getOpenMPContextTraitPropertyKind(TraitSet::TraitSetEnum, \
45                                                        Str)));                 \
46   EXPECT_EQ(TraitSet::TraitSetEnum,                                            \
47             getOpenMPContextTraitSetForProperty(TraitProperty::Enum));         \
48   EXPECT_EQ(TraitSelector::TraitSelectorEnum,                                  \
49             getOpenMPContextTraitSelectorForProperty(TraitProperty::Enum));
50 #include "llvm/Frontend/OpenMP/OMPKinds.def"
51 }
52 
53 TEST_F(OpenMPContextTest, ValidNesting) {
54   bool AllowsTraitScore, ReqProperty;
55 #define OMP_TRAIT_SELECTOR(Enum, TraitSetEnum, Str, RequiresProperty)          \
56   EXPECT_TRUE(isValidTraitSelectorForTraitSet(TraitSelector::Enum,             \
57                                               TraitSet::TraitSetEnum,          \
58                                               AllowsTraitScore, ReqProperty)); \
59   EXPECT_EQ(RequiresProperty, ReqProperty);
60 #define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str)         \
61   EXPECT_TRUE(isValidTraitPropertyForTraitSetAndSelector(                      \
62       TraitProperty::Enum, TraitSelector::TraitSelectorEnum,                   \
63       TraitSet::TraitSetEnum));
64 #include "llvm/Frontend/OpenMP/OMPKinds.def"
65 }
66 
67 TEST_F(OpenMPContextTest, ApplicabilityNonConstruct) {
68   OMPContext HostLinux(false, Triple("x86_64-unknown-linux"));
69   OMPContext DeviceLinux(true, Triple("x86_64-unknown-linux"));
70   OMPContext HostNVPTX(false, Triple("nvptx64-nvidia-cuda"));
71   OMPContext DeviceNVPTX(true, Triple("nvptx64-nvidia-cuda"));
72 
73   VariantMatchInfo Empty;
74   EXPECT_TRUE(isVariantApplicableInContext(Empty, HostLinux));
75   EXPECT_TRUE(isVariantApplicableInContext(Empty, DeviceLinux));
76   EXPECT_TRUE(isVariantApplicableInContext(Empty, HostNVPTX));
77   EXPECT_TRUE(isVariantApplicableInContext(Empty, DeviceNVPTX));
78 
79   VariantMatchInfo UserCondFalse;
80   UserCondFalse.addTrait(TraitProperty::user_condition_false);
81   EXPECT_FALSE(isVariantApplicableInContext(UserCondFalse, HostLinux));
82   EXPECT_FALSE(isVariantApplicableInContext(UserCondFalse, DeviceLinux));
83   EXPECT_FALSE(isVariantApplicableInContext(UserCondFalse, HostNVPTX));
84   EXPECT_FALSE(isVariantApplicableInContext(UserCondFalse, DeviceNVPTX));
85 
86   VariantMatchInfo DeviceArchArm;
87   DeviceArchArm.addTrait(TraitProperty::device_arch_arm);
88   EXPECT_FALSE(isVariantApplicableInContext(DeviceArchArm, HostLinux));
89   EXPECT_FALSE(isVariantApplicableInContext(DeviceArchArm, DeviceLinux));
90   EXPECT_FALSE(isVariantApplicableInContext(DeviceArchArm, HostNVPTX));
91   EXPECT_FALSE(isVariantApplicableInContext(DeviceArchArm, DeviceNVPTX));
92 
93   VariantMatchInfo LLVMHostUserCondTrue;
94   LLVMHostUserCondTrue.addTrait(TraitProperty::implementation_vendor_llvm);
95   LLVMHostUserCondTrue.addTrait(TraitProperty::device_kind_host);
96   LLVMHostUserCondTrue.addTrait(TraitProperty::device_kind_any);
97   LLVMHostUserCondTrue.addTrait(TraitProperty::user_condition_true);
98   EXPECT_TRUE(isVariantApplicableInContext(LLVMHostUserCondTrue, HostLinux));
99   EXPECT_FALSE(isVariantApplicableInContext(LLVMHostUserCondTrue, DeviceLinux));
100   EXPECT_TRUE(isVariantApplicableInContext(LLVMHostUserCondTrue, HostNVPTX));
101   EXPECT_FALSE(isVariantApplicableInContext(LLVMHostUserCondTrue, DeviceNVPTX));
102 
103   VariantMatchInfo LLVMHostUserCondTrueCPU = LLVMHostUserCondTrue;
104   LLVMHostUserCondTrueCPU.addTrait(TraitProperty::device_kind_cpu);
105   EXPECT_TRUE(isVariantApplicableInContext(LLVMHostUserCondTrueCPU, HostLinux));
106   EXPECT_FALSE(
107       isVariantApplicableInContext(LLVMHostUserCondTrueCPU, DeviceLinux));
108   EXPECT_FALSE(
109       isVariantApplicableInContext(LLVMHostUserCondTrueCPU, HostNVPTX));
110   EXPECT_FALSE(
111       isVariantApplicableInContext(LLVMHostUserCondTrueCPU, DeviceNVPTX));
112 
113   VariantMatchInfo GPU;
114   GPU.addTrait(TraitProperty::device_kind_gpu);
115   EXPECT_FALSE(isVariantApplicableInContext(GPU, HostLinux));
116   EXPECT_FALSE(isVariantApplicableInContext(GPU, DeviceLinux));
117   EXPECT_TRUE(isVariantApplicableInContext(GPU, HostNVPTX));
118   EXPECT_TRUE(isVariantApplicableInContext(GPU, DeviceNVPTX));
119 
120   VariantMatchInfo NoHost;
121   NoHost.addTrait(TraitProperty::device_kind_nohost);
122   EXPECT_FALSE(isVariantApplicableInContext(NoHost, HostLinux));
123   EXPECT_TRUE(isVariantApplicableInContext(NoHost, DeviceLinux));
124   EXPECT_FALSE(isVariantApplicableInContext(NoHost, HostNVPTX));
125   EXPECT_TRUE(isVariantApplicableInContext(NoHost, DeviceNVPTX));
126 }
127 
128 TEST_F(OpenMPContextTest, ApplicabilityAllTraits) {
129   OMPContext HostLinuxParallelParallel(false, Triple("x86_64-unknown-linux"));
130   HostLinuxParallelParallel.addTrait(
131       TraitProperty::construct_parallel_parallel);
132   HostLinuxParallelParallel.addTrait(
133       TraitProperty::construct_parallel_parallel);
134   OMPContext DeviceLinuxTargetParallel(true, Triple("x86_64-unknown-linux"));
135   DeviceLinuxTargetParallel.addTrait(TraitProperty::construct_target_target);
136   DeviceLinuxTargetParallel.addTrait(
137       TraitProperty::construct_parallel_parallel);
138   OMPContext HostNVPTXFor(false, Triple("nvptx64-nvidia-cuda"));
139   HostNVPTXFor.addTrait(TraitProperty::construct_for_for);
140   OMPContext DeviceNVPTXTargetTeamsParallel(true,
141                                             Triple("nvptx64-nvidia-cuda"));
142   DeviceNVPTXTargetTeamsParallel.addTrait(
143       TraitProperty::construct_target_target);
144   DeviceNVPTXTargetTeamsParallel.addTrait(TraitProperty::construct_teams_teams);
145   DeviceNVPTXTargetTeamsParallel.addTrait(
146       TraitProperty::construct_parallel_parallel);
147 
148   { // non-construct variants
149     VariantMatchInfo Empty;
150     EXPECT_TRUE(isVariantApplicableInContext(Empty, HostLinuxParallelParallel));
151     EXPECT_TRUE(isVariantApplicableInContext(Empty, DeviceLinuxTargetParallel));
152     EXPECT_TRUE(isVariantApplicableInContext(Empty, HostNVPTXFor));
153     EXPECT_TRUE(
154         isVariantApplicableInContext(Empty, DeviceNVPTXTargetTeamsParallel));
155 
156     VariantMatchInfo UserCondFalse;
157     UserCondFalse.addTrait(TraitProperty::user_condition_false);
158     EXPECT_FALSE(
159         isVariantApplicableInContext(UserCondFalse, HostLinuxParallelParallel));
160     EXPECT_FALSE(
161         isVariantApplicableInContext(UserCondFalse, DeviceLinuxTargetParallel));
162     EXPECT_FALSE(isVariantApplicableInContext(UserCondFalse, HostNVPTXFor));
163     EXPECT_FALSE(isVariantApplicableInContext(UserCondFalse,
164                                               DeviceNVPTXTargetTeamsParallel));
165 
166     VariantMatchInfo DeviceArchArm;
167     DeviceArchArm.addTrait(TraitProperty::device_arch_arm);
168     EXPECT_FALSE(
169         isVariantApplicableInContext(DeviceArchArm, HostLinuxParallelParallel));
170     EXPECT_FALSE(
171         isVariantApplicableInContext(DeviceArchArm, DeviceLinuxTargetParallel));
172     EXPECT_FALSE(isVariantApplicableInContext(DeviceArchArm, HostNVPTXFor));
173     EXPECT_FALSE(isVariantApplicableInContext(DeviceArchArm,
174                                               DeviceNVPTXTargetTeamsParallel));
175 
176     APInt Score(32, 1000);
177     VariantMatchInfo LLVMHostUserCondTrue;
178     LLVMHostUserCondTrue.addTrait(TraitProperty::implementation_vendor_llvm);
179     LLVMHostUserCondTrue.addTrait(TraitProperty::device_kind_host);
180     LLVMHostUserCondTrue.addTrait(TraitProperty::device_kind_any);
181     LLVMHostUserCondTrue.addTrait(TraitProperty::user_condition_true, &Score);
182     EXPECT_TRUE(isVariantApplicableInContext(LLVMHostUserCondTrue,
183                                              HostLinuxParallelParallel));
184     EXPECT_FALSE(isVariantApplicableInContext(LLVMHostUserCondTrue,
185                                               DeviceLinuxTargetParallel));
186     EXPECT_TRUE(
187         isVariantApplicableInContext(LLVMHostUserCondTrue, HostNVPTXFor));
188     EXPECT_FALSE(isVariantApplicableInContext(LLVMHostUserCondTrue,
189                                               DeviceNVPTXTargetTeamsParallel));
190 
191     VariantMatchInfo LLVMHostUserCondTrueCPU = LLVMHostUserCondTrue;
192     LLVMHostUserCondTrueCPU.addTrait(TraitProperty::device_kind_cpu);
193     EXPECT_TRUE(isVariantApplicableInContext(LLVMHostUserCondTrueCPU,
194                                              HostLinuxParallelParallel));
195     EXPECT_FALSE(isVariantApplicableInContext(LLVMHostUserCondTrueCPU,
196                                               DeviceLinuxTargetParallel));
197     EXPECT_FALSE(
198         isVariantApplicableInContext(LLVMHostUserCondTrueCPU, HostNVPTXFor));
199     EXPECT_FALSE(isVariantApplicableInContext(LLVMHostUserCondTrueCPU,
200                                               DeviceNVPTXTargetTeamsParallel));
201 
202     VariantMatchInfo GPU;
203     GPU.addTrait(TraitProperty::device_kind_gpu);
204     EXPECT_FALSE(isVariantApplicableInContext(GPU, HostLinuxParallelParallel));
205     EXPECT_FALSE(isVariantApplicableInContext(GPU, DeviceLinuxTargetParallel));
206     EXPECT_TRUE(isVariantApplicableInContext(GPU, HostNVPTXFor));
207     EXPECT_TRUE(
208         isVariantApplicableInContext(GPU, DeviceNVPTXTargetTeamsParallel));
209 
210     VariantMatchInfo NoHost;
211     NoHost.addTrait(TraitProperty::device_kind_nohost);
212     EXPECT_FALSE(
213         isVariantApplicableInContext(NoHost, HostLinuxParallelParallel));
214     EXPECT_TRUE(
215         isVariantApplicableInContext(NoHost, DeviceLinuxTargetParallel));
216     EXPECT_FALSE(isVariantApplicableInContext(NoHost, HostNVPTXFor));
217     EXPECT_TRUE(
218         isVariantApplicableInContext(NoHost, DeviceNVPTXTargetTeamsParallel));
219   }
220   { // variants with all sets
221     VariantMatchInfo DeviceArchArmParallel;
222     DeviceArchArmParallel.addTrait(TraitProperty::construct_parallel_parallel);
223     DeviceArchArmParallel.addTrait(TraitProperty::device_arch_arm);
224     EXPECT_FALSE(isVariantApplicableInContext(DeviceArchArmParallel,
225                                               HostLinuxParallelParallel));
226     EXPECT_FALSE(isVariantApplicableInContext(DeviceArchArmParallel,
227                                               DeviceLinuxTargetParallel));
228     EXPECT_FALSE(
229         isVariantApplicableInContext(DeviceArchArmParallel, HostNVPTXFor));
230     EXPECT_FALSE(isVariantApplicableInContext(DeviceArchArmParallel,
231                                               DeviceNVPTXTargetTeamsParallel));
232 
233     VariantMatchInfo LLVMHostUserCondTrueParallel;
234     LLVMHostUserCondTrueParallel.addTrait(
235         TraitProperty::implementation_vendor_llvm);
236     LLVMHostUserCondTrueParallel.addTrait(TraitProperty::device_kind_host);
237     LLVMHostUserCondTrueParallel.addTrait(TraitProperty::device_kind_any);
238     LLVMHostUserCondTrueParallel.addTrait(TraitProperty::user_condition_true);
239     LLVMHostUserCondTrueParallel.addTrait(
240         TraitProperty::construct_parallel_parallel);
241     EXPECT_TRUE(isVariantApplicableInContext(LLVMHostUserCondTrueParallel,
242                                              HostLinuxParallelParallel));
243     EXPECT_FALSE(isVariantApplicableInContext(LLVMHostUserCondTrueParallel,
244                                               DeviceLinuxTargetParallel));
245     EXPECT_FALSE(isVariantApplicableInContext(LLVMHostUserCondTrueParallel,
246                                               HostNVPTXFor));
247     EXPECT_FALSE(isVariantApplicableInContext(LLVMHostUserCondTrueParallel,
248                                               DeviceNVPTXTargetTeamsParallel));
249 
250     VariantMatchInfo LLVMHostUserCondTrueParallelParallel =
251         LLVMHostUserCondTrueParallel;
252     LLVMHostUserCondTrueParallelParallel.addTrait(
253         TraitProperty::construct_parallel_parallel);
254     EXPECT_TRUE(isVariantApplicableInContext(
255         LLVMHostUserCondTrueParallelParallel, HostLinuxParallelParallel));
256     EXPECT_FALSE(isVariantApplicableInContext(
257         LLVMHostUserCondTrueParallelParallel, DeviceLinuxTargetParallel));
258     EXPECT_FALSE(isVariantApplicableInContext(
259         LLVMHostUserCondTrueParallelParallel, HostNVPTXFor));
260     EXPECT_FALSE(isVariantApplicableInContext(
261         LLVMHostUserCondTrueParallelParallel, DeviceNVPTXTargetTeamsParallel));
262 
263     VariantMatchInfo LLVMHostUserCondTrueParallelParallelParallel =
264         LLVMHostUserCondTrueParallelParallel;
265     LLVMHostUserCondTrueParallelParallelParallel.addTrait(
266         TraitProperty::construct_parallel_parallel);
267     EXPECT_FALSE(isVariantApplicableInContext(
268         LLVMHostUserCondTrueParallelParallelParallel,
269         HostLinuxParallelParallel));
270     EXPECT_FALSE(isVariantApplicableInContext(
271         LLVMHostUserCondTrueParallelParallelParallel,
272         DeviceLinuxTargetParallel));
273     EXPECT_FALSE(isVariantApplicableInContext(
274         LLVMHostUserCondTrueParallelParallelParallel, HostNVPTXFor));
275     EXPECT_FALSE(isVariantApplicableInContext(
276         LLVMHostUserCondTrueParallelParallelParallel,
277         DeviceNVPTXTargetTeamsParallel));
278 
279     VariantMatchInfo GPUTargetTeams;
280     GPUTargetTeams.addTrait(TraitProperty::construct_target_target);
281     GPUTargetTeams.addTrait(TraitProperty::construct_teams_teams);
282     GPUTargetTeams.addTrait(TraitProperty::device_kind_gpu);
283     EXPECT_FALSE(isVariantApplicableInContext(GPUTargetTeams,
284                                               HostLinuxParallelParallel));
285     EXPECT_FALSE(isVariantApplicableInContext(GPUTargetTeams,
286                                               DeviceLinuxTargetParallel));
287     EXPECT_FALSE(isVariantApplicableInContext(GPUTargetTeams, HostNVPTXFor));
288     EXPECT_TRUE(isVariantApplicableInContext(GPUTargetTeams,
289                                              DeviceNVPTXTargetTeamsParallel));
290 
291     VariantMatchInfo GPUTargetParallel;
292     GPUTargetParallel.addTrait(TraitProperty::construct_target_target);
293     GPUTargetParallel.addTrait(TraitProperty::construct_parallel_parallel);
294     GPUTargetParallel.addTrait(TraitProperty::device_kind_gpu);
295     EXPECT_FALSE(isVariantApplicableInContext(GPUTargetParallel,
296                                               HostLinuxParallelParallel));
297     EXPECT_FALSE(isVariantApplicableInContext(GPUTargetParallel,
298                                               DeviceLinuxTargetParallel));
299     EXPECT_FALSE(isVariantApplicableInContext(GPUTargetParallel, HostNVPTXFor));
300     EXPECT_TRUE(isVariantApplicableInContext(GPUTargetParallel,
301                                              DeviceNVPTXTargetTeamsParallel));
302   }
303 }
304 
305 TEST_F(OpenMPContextTest, ScoringSimple) {
306   // TODO: Add scoring tests (via getBestVariantMatchForContext).
307 }
308 
309 } // namespace
310