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