//===- unittest/IR/OpenMPContextTest.cpp - OpenMP Context handling tests --===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "llvm/Frontend/OpenMP/OMPConstants.h" #include "llvm/Frontend/OpenMP/OMPContext.h" #include "gtest/gtest.h" using namespace llvm; using namespace omp; namespace { class OpenMPContextTest : public testing::Test { protected: void SetUp() override {} void TearDown() override {} }; TEST_F(OpenMPContextTest, RoundTripAndAssociation) { #define OMP_TRAIT_SET(Enum, Str) \ EXPECT_EQ(TraitSet::Enum, \ getOpenMPContextTraitSetKind( \ getOpenMPContextTraitSetName(TraitSet::Enum))); \ EXPECT_EQ(Str, \ getOpenMPContextTraitSetName(getOpenMPContextTraitSetKind(Str))); #define OMP_TRAIT_SELECTOR(Enum, TraitSetEnum, Str, RequiresProperty) \ EXPECT_EQ(TraitSelector::Enum, \ getOpenMPContextTraitSelectorKind( \ getOpenMPContextTraitSelectorName(TraitSelector::Enum))); \ EXPECT_EQ(Str, getOpenMPContextTraitSelectorName( \ getOpenMPContextTraitSelectorKind(Str))); #define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \ EXPECT_EQ(TraitProperty::Enum, \ getOpenMPContextTraitPropertyKind( \ TraitSet::TraitSetEnum, TraitSelector::TraitSelectorEnum, \ getOpenMPContextTraitPropertyName(TraitProperty::Enum, Str))); \ EXPECT_EQ(Str, getOpenMPContextTraitPropertyName( \ getOpenMPContextTraitPropertyKind( \ TraitSet::TraitSetEnum, \ TraitSelector::TraitSelectorEnum, Str), \ Str)); \ EXPECT_EQ(TraitSet::TraitSetEnum, \ getOpenMPContextTraitSetForProperty(TraitProperty::Enum)); \ EXPECT_EQ(TraitSelector::TraitSelectorEnum, \ getOpenMPContextTraitSelectorForProperty(TraitProperty::Enum)); #include "llvm/Frontend/OpenMP/OMPKinds.def" } TEST_F(OpenMPContextTest, ValidNesting) { bool AllowsTraitScore, ReqProperty; #define OMP_TRAIT_SELECTOR(Enum, TraitSetEnum, Str, RequiresProperty) \ EXPECT_TRUE(isValidTraitSelectorForTraitSet(TraitSelector::Enum, \ TraitSet::TraitSetEnum, \ AllowsTraitScore, ReqProperty)); \ EXPECT_EQ(RequiresProperty, ReqProperty); #define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str) \ EXPECT_TRUE(isValidTraitPropertyForTraitSetAndSelector( \ TraitProperty::Enum, TraitSelector::TraitSelectorEnum, \ TraitSet::TraitSetEnum)); #include "llvm/Frontend/OpenMP/OMPKinds.def" } TEST_F(OpenMPContextTest, ApplicabilityNonConstruct) { OMPContext HostLinux(false, Triple("x86_64-unknown-linux")); OMPContext DeviceLinux(true, Triple("x86_64-unknown-linux")); OMPContext HostNVPTX(false, Triple("nvptx64-nvidia-cuda")); OMPContext DeviceNVPTX(true, Triple("nvptx64-nvidia-cuda")); VariantMatchInfo Empty; EXPECT_TRUE(isVariantApplicableInContext(Empty, HostLinux)); EXPECT_TRUE(isVariantApplicableInContext(Empty, DeviceLinux)); EXPECT_TRUE(isVariantApplicableInContext(Empty, HostNVPTX)); EXPECT_TRUE(isVariantApplicableInContext(Empty, DeviceNVPTX)); VariantMatchInfo UserCondFalse; UserCondFalse.addTrait(TraitProperty::user_condition_false, ""); EXPECT_FALSE(isVariantApplicableInContext(UserCondFalse, HostLinux)); EXPECT_FALSE(isVariantApplicableInContext(UserCondFalse, DeviceLinux)); EXPECT_FALSE(isVariantApplicableInContext(UserCondFalse, HostNVPTX)); EXPECT_FALSE(isVariantApplicableInContext(UserCondFalse, DeviceNVPTX)); VariantMatchInfo DeviceArchArm; DeviceArchArm.addTrait(TraitProperty::device_arch_arm, ""); EXPECT_FALSE(isVariantApplicableInContext(DeviceArchArm, HostLinux)); EXPECT_FALSE(isVariantApplicableInContext(DeviceArchArm, DeviceLinux)); EXPECT_FALSE(isVariantApplicableInContext(DeviceArchArm, HostNVPTX)); EXPECT_FALSE(isVariantApplicableInContext(DeviceArchArm, DeviceNVPTX)); VariantMatchInfo LLVMHostUserCondTrue; LLVMHostUserCondTrue.addTrait(TraitProperty::implementation_vendor_llvm, ""); LLVMHostUserCondTrue.addTrait(TraitProperty::device_kind_host, ""); LLVMHostUserCondTrue.addTrait(TraitProperty::device_kind_any, ""); LLVMHostUserCondTrue.addTrait(TraitProperty::user_condition_true, ""); EXPECT_TRUE(isVariantApplicableInContext(LLVMHostUserCondTrue, HostLinux)); EXPECT_FALSE(isVariantApplicableInContext(LLVMHostUserCondTrue, DeviceLinux)); EXPECT_TRUE(isVariantApplicableInContext(LLVMHostUserCondTrue, HostNVPTX)); EXPECT_FALSE(isVariantApplicableInContext(LLVMHostUserCondTrue, DeviceNVPTX)); VariantMatchInfo LLVMHostUserCondTrueCPU = LLVMHostUserCondTrue; LLVMHostUserCondTrueCPU.addTrait(TraitProperty::device_kind_cpu, ""); EXPECT_TRUE(isVariantApplicableInContext(LLVMHostUserCondTrueCPU, HostLinux)); EXPECT_FALSE( isVariantApplicableInContext(LLVMHostUserCondTrueCPU, DeviceLinux)); EXPECT_FALSE( isVariantApplicableInContext(LLVMHostUserCondTrueCPU, HostNVPTX)); EXPECT_FALSE( isVariantApplicableInContext(LLVMHostUserCondTrueCPU, DeviceNVPTX)); VariantMatchInfo GPU; GPU.addTrait(TraitProperty::device_kind_gpu, ""); EXPECT_FALSE(isVariantApplicableInContext(GPU, HostLinux)); EXPECT_FALSE(isVariantApplicableInContext(GPU, DeviceLinux)); EXPECT_TRUE(isVariantApplicableInContext(GPU, HostNVPTX)); EXPECT_TRUE(isVariantApplicableInContext(GPU, DeviceNVPTX)); VariantMatchInfo NoHost; NoHost.addTrait(TraitProperty::device_kind_nohost, ""); EXPECT_FALSE(isVariantApplicableInContext(NoHost, HostLinux)); EXPECT_TRUE(isVariantApplicableInContext(NoHost, DeviceLinux)); EXPECT_FALSE(isVariantApplicableInContext(NoHost, HostNVPTX)); EXPECT_TRUE(isVariantApplicableInContext(NoHost, DeviceNVPTX)); } TEST_F(OpenMPContextTest, ApplicabilityAllTraits) { OMPContext HostLinuxParallelParallel(false, Triple("x86_64-unknown-linux")); HostLinuxParallelParallel.addTrait( TraitProperty::construct_parallel_parallel); HostLinuxParallelParallel.addTrait( TraitProperty::construct_parallel_parallel); OMPContext DeviceLinuxTargetParallel(true, Triple("x86_64-unknown-linux")); DeviceLinuxTargetParallel.addTrait(TraitProperty::construct_target_target); DeviceLinuxTargetParallel.addTrait( TraitProperty::construct_parallel_parallel); OMPContext HostNVPTXFor(false, Triple("nvptx64-nvidia-cuda")); HostNVPTXFor.addTrait(TraitProperty::construct_for_for); OMPContext DeviceNVPTXTargetTeamsParallel(true, Triple("nvptx64-nvidia-cuda")); DeviceNVPTXTargetTeamsParallel.addTrait( TraitProperty::construct_target_target); DeviceNVPTXTargetTeamsParallel.addTrait(TraitProperty::construct_teams_teams); DeviceNVPTXTargetTeamsParallel.addTrait( TraitProperty::construct_parallel_parallel); { // non-construct variants VariantMatchInfo Empty; EXPECT_TRUE(isVariantApplicableInContext(Empty, HostLinuxParallelParallel)); EXPECT_TRUE(isVariantApplicableInContext(Empty, DeviceLinuxTargetParallel)); EXPECT_TRUE(isVariantApplicableInContext(Empty, HostNVPTXFor)); EXPECT_TRUE( isVariantApplicableInContext(Empty, DeviceNVPTXTargetTeamsParallel)); VariantMatchInfo UserCondFalse; UserCondFalse.addTrait(TraitProperty::user_condition_false, ""); EXPECT_FALSE( isVariantApplicableInContext(UserCondFalse, HostLinuxParallelParallel)); EXPECT_FALSE( isVariantApplicableInContext(UserCondFalse, DeviceLinuxTargetParallel)); EXPECT_FALSE(isVariantApplicableInContext(UserCondFalse, HostNVPTXFor)); EXPECT_FALSE(isVariantApplicableInContext(UserCondFalse, DeviceNVPTXTargetTeamsParallel)); VariantMatchInfo DeviceArchArm; DeviceArchArm.addTrait(TraitProperty::device_arch_arm, ""); EXPECT_FALSE( isVariantApplicableInContext(DeviceArchArm, HostLinuxParallelParallel)); EXPECT_FALSE( isVariantApplicableInContext(DeviceArchArm, DeviceLinuxTargetParallel)); EXPECT_FALSE(isVariantApplicableInContext(DeviceArchArm, HostNVPTXFor)); EXPECT_FALSE(isVariantApplicableInContext(DeviceArchArm, DeviceNVPTXTargetTeamsParallel)); APInt Score(32, 1000); VariantMatchInfo LLVMHostUserCondTrue; LLVMHostUserCondTrue.addTrait(TraitProperty::implementation_vendor_llvm, ""); LLVMHostUserCondTrue.addTrait(TraitProperty::device_kind_host, ""); LLVMHostUserCondTrue.addTrait(TraitProperty::device_kind_any, ""); LLVMHostUserCondTrue.addTrait(TraitProperty::user_condition_true, "", &Score); EXPECT_TRUE(isVariantApplicableInContext(LLVMHostUserCondTrue, HostLinuxParallelParallel)); EXPECT_FALSE(isVariantApplicableInContext(LLVMHostUserCondTrue, DeviceLinuxTargetParallel)); EXPECT_TRUE( isVariantApplicableInContext(LLVMHostUserCondTrue, HostNVPTXFor)); EXPECT_FALSE(isVariantApplicableInContext(LLVMHostUserCondTrue, DeviceNVPTXTargetTeamsParallel)); VariantMatchInfo LLVMHostUserCondTrueCPU = LLVMHostUserCondTrue; LLVMHostUserCondTrueCPU.addTrait(TraitProperty::device_kind_cpu, ""); EXPECT_TRUE(isVariantApplicableInContext(LLVMHostUserCondTrueCPU, HostLinuxParallelParallel)); EXPECT_FALSE(isVariantApplicableInContext(LLVMHostUserCondTrueCPU, DeviceLinuxTargetParallel)); EXPECT_FALSE( isVariantApplicableInContext(LLVMHostUserCondTrueCPU, HostNVPTXFor)); EXPECT_FALSE(isVariantApplicableInContext(LLVMHostUserCondTrueCPU, DeviceNVPTXTargetTeamsParallel)); VariantMatchInfo GPU; GPU.addTrait(TraitProperty::device_kind_gpu, ""); EXPECT_FALSE(isVariantApplicableInContext(GPU, HostLinuxParallelParallel)); EXPECT_FALSE(isVariantApplicableInContext(GPU, DeviceLinuxTargetParallel)); EXPECT_TRUE(isVariantApplicableInContext(GPU, HostNVPTXFor)); EXPECT_TRUE( isVariantApplicableInContext(GPU, DeviceNVPTXTargetTeamsParallel)); VariantMatchInfo NoHost; NoHost.addTrait(TraitProperty::device_kind_nohost, ""); EXPECT_FALSE( isVariantApplicableInContext(NoHost, HostLinuxParallelParallel)); EXPECT_TRUE( isVariantApplicableInContext(NoHost, DeviceLinuxTargetParallel)); EXPECT_FALSE(isVariantApplicableInContext(NoHost, HostNVPTXFor)); EXPECT_TRUE( isVariantApplicableInContext(NoHost, DeviceNVPTXTargetTeamsParallel)); } { // variants with all sets VariantMatchInfo DeviceArchArmParallel; DeviceArchArmParallel.addTrait(TraitProperty::construct_parallel_parallel, ""); DeviceArchArmParallel.addTrait(TraitProperty::device_arch_arm, ""); EXPECT_FALSE(isVariantApplicableInContext(DeviceArchArmParallel, HostLinuxParallelParallel)); EXPECT_FALSE(isVariantApplicableInContext(DeviceArchArmParallel, DeviceLinuxTargetParallel)); EXPECT_FALSE( isVariantApplicableInContext(DeviceArchArmParallel, HostNVPTXFor)); EXPECT_FALSE(isVariantApplicableInContext(DeviceArchArmParallel, DeviceNVPTXTargetTeamsParallel)); VariantMatchInfo LLVMHostUserCondTrueParallel; LLVMHostUserCondTrueParallel.addTrait( TraitProperty::implementation_vendor_llvm, ""); LLVMHostUserCondTrueParallel.addTrait(TraitProperty::device_kind_host, ""); LLVMHostUserCondTrueParallel.addTrait(TraitProperty::device_kind_any, ""); LLVMHostUserCondTrueParallel.addTrait(TraitProperty::user_condition_true, ""); LLVMHostUserCondTrueParallel.addTrait( TraitProperty::construct_parallel_parallel, ""); EXPECT_TRUE(isVariantApplicableInContext(LLVMHostUserCondTrueParallel, HostLinuxParallelParallel)); EXPECT_FALSE(isVariantApplicableInContext(LLVMHostUserCondTrueParallel, DeviceLinuxTargetParallel)); EXPECT_FALSE(isVariantApplicableInContext(LLVMHostUserCondTrueParallel, HostNVPTXFor)); EXPECT_FALSE(isVariantApplicableInContext(LLVMHostUserCondTrueParallel, DeviceNVPTXTargetTeamsParallel)); VariantMatchInfo LLVMHostUserCondTrueParallelParallel = LLVMHostUserCondTrueParallel; LLVMHostUserCondTrueParallelParallel.addTrait( TraitProperty::construct_parallel_parallel, ""); EXPECT_TRUE(isVariantApplicableInContext( LLVMHostUserCondTrueParallelParallel, HostLinuxParallelParallel)); EXPECT_FALSE(isVariantApplicableInContext( LLVMHostUserCondTrueParallelParallel, DeviceLinuxTargetParallel)); EXPECT_FALSE(isVariantApplicableInContext( LLVMHostUserCondTrueParallelParallel, HostNVPTXFor)); EXPECT_FALSE(isVariantApplicableInContext( LLVMHostUserCondTrueParallelParallel, DeviceNVPTXTargetTeamsParallel)); VariantMatchInfo LLVMHostUserCondTrueParallelParallelParallel = LLVMHostUserCondTrueParallelParallel; LLVMHostUserCondTrueParallelParallelParallel.addTrait( TraitProperty::construct_parallel_parallel, ""); EXPECT_FALSE(isVariantApplicableInContext( LLVMHostUserCondTrueParallelParallelParallel, HostLinuxParallelParallel)); EXPECT_FALSE(isVariantApplicableInContext( LLVMHostUserCondTrueParallelParallelParallel, DeviceLinuxTargetParallel)); EXPECT_FALSE(isVariantApplicableInContext( LLVMHostUserCondTrueParallelParallelParallel, HostNVPTXFor)); EXPECT_FALSE(isVariantApplicableInContext( LLVMHostUserCondTrueParallelParallelParallel, DeviceNVPTXTargetTeamsParallel)); VariantMatchInfo GPUTargetTeams; GPUTargetTeams.addTrait(TraitProperty::construct_target_target, ""); GPUTargetTeams.addTrait(TraitProperty::construct_teams_teams, ""); GPUTargetTeams.addTrait(TraitProperty::device_kind_gpu, ""); EXPECT_FALSE(isVariantApplicableInContext(GPUTargetTeams, HostLinuxParallelParallel)); EXPECT_FALSE(isVariantApplicableInContext(GPUTargetTeams, DeviceLinuxTargetParallel)); EXPECT_FALSE(isVariantApplicableInContext(GPUTargetTeams, HostNVPTXFor)); EXPECT_TRUE(isVariantApplicableInContext(GPUTargetTeams, DeviceNVPTXTargetTeamsParallel)); VariantMatchInfo GPUTargetParallel; GPUTargetParallel.addTrait(TraitProperty::construct_target_target, ""); GPUTargetParallel.addTrait(TraitProperty::construct_parallel_parallel, ""); GPUTargetParallel.addTrait(TraitProperty::device_kind_gpu, ""); EXPECT_FALSE(isVariantApplicableInContext(GPUTargetParallel, HostLinuxParallelParallel)); EXPECT_FALSE(isVariantApplicableInContext(GPUTargetParallel, DeviceLinuxTargetParallel)); EXPECT_FALSE(isVariantApplicableInContext(GPUTargetParallel, HostNVPTXFor)); EXPECT_TRUE(isVariantApplicableInContext(GPUTargetParallel, DeviceNVPTXTargetTeamsParallel)); } } TEST_F(OpenMPContextTest, ScoringSimple) { // TODO: Add scoring tests (via getBestVariantMatchForContext). } } // namespace