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