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