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