diff --git a/sycl/test-e2e/AmdNvidiaJIT/kernel_and_bundle.cpp b/sycl/test-e2e/AmdNvidiaJIT/kernel_and_bundle.cpp index c1e52d1d4fc4e..3927fb87ee85d 100644 --- a/sycl/test-e2e/AmdNvidiaJIT/kernel_and_bundle.cpp +++ b/sycl/test-e2e/AmdNvidiaJIT/kernel_and_bundle.cpp @@ -1,6 +1,5 @@ // UNSUPPORTED: windows -// REQUIRES: cuda || hip -// REQUIRES: build-and-run-mode +// REQUIRES: target-nvidia || target-amd // This test relies on debug output from a pass, make sure that the compiler // can generate it. diff --git a/sycl/test-e2e/Basic/windows_version_agnostic_sycl_lib.cpp b/sycl/test-e2e/Basic/windows_version_agnostic_sycl_lib.cpp index c9487829314d8..cf7538ed495bc 100644 --- a/sycl/test-e2e/Basic/windows_version_agnostic_sycl_lib.cpp +++ b/sycl/test-e2e/Basic/windows_version_agnostic_sycl_lib.cpp @@ -1,5 +1,4 @@ // REQUIRES: windows -// REQUIRES: build-and-run-mode // RUN: %clangxx --driver-mode=cl /std:c++17 /EHsc %sycl_include -I%opencl_include_dir %s -o %t.out /link /defaultlib:%sycl_static_libs_dir/sycl.lib // RUN: %{run} %t.out diff --git a/sycl/test-e2e/Compression/no_zstd_warning.cpp b/sycl/test-e2e/Compression/no_zstd_warning.cpp index 4532f22b9845b..c87f2fe480096 100644 --- a/sycl/test-e2e/Compression/no_zstd_warning.cpp +++ b/sycl/test-e2e/Compression/no_zstd_warning.cpp @@ -1,5 +1,4 @@ // using --offload-compress without zstd should throw an error. // REQUIRES: !zstd -// REQUIRES: build-and-run-mode // RUN: not %{build} %O0 -g --offload-compress %S/Inputs/single_kernel.cpp -o %t_compress.out 2>&1 | FileCheck %s // CHECK: '--offload-compress' option is specified but zstd is not available. The device image will not be compressed. diff --git a/sycl/test-e2e/DeviceLib/math_fp64_windows_test.cpp b/sycl/test-e2e/DeviceLib/math_fp64_windows_test.cpp index 2641408261426..71e8a43387093 100644 --- a/sycl/test-e2e/DeviceLib/math_fp64_windows_test.cpp +++ b/sycl/test-e2e/DeviceLib/math_fp64_windows_test.cpp @@ -1,5 +1,4 @@ // REQUIRES: aspect-fp64, windows -// REQUIRES: build-and-run-mode // DEFINE: %{mathflags} = %if cl_options %{/clang:-fno-fast-math%} %else %{-fno-fast-math%} diff --git a/sycl/test-e2e/DeviceLib/math_windows_test.cpp b/sycl/test-e2e/DeviceLib/math_windows_test.cpp index 645493c496ae1..ab18cf1abe254 100644 --- a/sycl/test-e2e/DeviceLib/math_windows_test.cpp +++ b/sycl/test-e2e/DeviceLib/math_windows_test.cpp @@ -1,5 +1,4 @@ // REQUIRES: windows -// REQUIRES: build-and-run-mode // TODO: Add hypotf case back when the missing symbol is fixed. diff --git a/sycl/test-e2e/E2EExpr.py b/sycl/test-e2e/E2EExpr.py new file mode 100644 index 0000000000000..08dc667661803 --- /dev/null +++ b/sycl/test-e2e/E2EExpr.py @@ -0,0 +1,167 @@ +from lit.BooleanExpression import BooleanExpression + + +class E2EExpr(BooleanExpression): + build_specific_features = { + "build-and-run-mode", + "target-spir", + "target-nvidia", + "target-amd", + "target-native_cpu", + "any-target-is-spir", + "any-target-is-nvidia", + "any-target-is-amd", + "any-target-is-native_cpu", + "linux", + "system-linux", + "windows", + "system-windows", + "enable-perf-tests", + "preview-breaking-changes-supported", + "has_ndebug", + "ocloc", + "opencl-aot", + "opencl_icd", + "cm-compiler", + "xptifw", + "level_zero_dev_kit", + "cuda_dev_kit", + "zstd", + "vulkan", + "true", + "false", + } + + def __init__(self, string, variables, build_only_mode, final_unknown_value): + BooleanExpression.__init__(self, string, variables) + self.build_only_mode = build_only_mode + self.unknown = False + self.final_unknown_value = final_unknown_value + + @staticmethod + def evaluate(string, variables, build_only_mode, final_unknown_value=True): + """ + string: Expression to evaluate + variables: variables that evaluate to true + build_only_mode: if true enables unknown values + final_unknown_value: final boolean result if evaluation results in `unknown` + """ + try: + parser = E2EExpr( + string, set(variables), build_only_mode, final_unknown_value + ) + return parser.parseAll() + except ValueError as e: + raise ValueError(str(e) + ("\nin expression: %r" % string)) + + def parseMATCH(self): + token = self.token + BooleanExpression.parseMATCH(self) + if token not in self.build_specific_features and self.build_only_mode: + self.unknown = True + else: + self.unknown = False + if self.value and self.unknown: + raise ValueError( + 'Runtime feature "' + token + '" evaluated to True in build-only' + ) + + def parseAND(self): + self.parseNOT() + while self.accept("&&"): + left = self.value + left_unknown = self.unknown + self.parseNOT() + right = self.value + right_unknown = self.unknown + self.value = left and right + # Unknown if both are unknown or if one is true and the other is unknown + self.unknown = ( + (left_unknown and right_unknown) + or (left_unknown and right) + or (left and right_unknown) + ) + + def parseOR(self): + self.parseAND() + while self.accept("||"): + left = self.value + left_unknown = self.unknown + self.parseAND() + right = self.value + right_unknown = self.unknown + self.value = left or right + # Unknown if both are unknown or if one is false and the other is unknown + self.unknown = ( + (left_unknown and right_unknown) + or (left_unknown and not right) + or (not left and right_unknown) + ) + + def parseAll(self): + self.token = next(self.tokens) + self.parseOR() + self.expect(BooleanExpression.END) + return self.final_unknown_value if self.unknown else self.value + + +import unittest + + +class TestE2EExpr(unittest.TestCase): + def test_basic(self): + BuildOnly = True + BuildAndRun = False + RequiresDirective = True + UnsupportedDirective = False + RegularEval = lambda expr, features: E2EExpr.evaluate( + expr, features, BuildAndRun + ) + RequiresBuildEval = lambda expr, features: E2EExpr.evaluate( + expr, features, BuildOnly, RequiresDirective + ) + UnsupportedBuildEval = lambda expr, features: E2EExpr.evaluate( + expr, features, BuildOnly, UnsupportedDirective + ) + # Non build-only expressions should work the same + self.assertTrue(RegularEval("linux", {"linux", "rt_feature"})) + self.assertTrue(RegularEval("rt_feature", {"linux", "rt_feature"})) + self.assertFalse( + RegularEval("rt_feature1 && rt_feature2", {"linux", "rt_feature1"}) + ) + # build-only expressions with no unknowns should work the same + self.assertTrue(UnsupportedBuildEval("linux", {"linux"})) + self.assertFalse(RequiresBuildEval("linux && windows", {"linux"})) + self.assertTrue(UnsupportedBuildEval("!(windows || zstd)", {"linux"})) + # build-only expressions where unknown affects the resulting value + self.assertTrue(RequiresBuildEval("rt_feature", {})) + self.assertFalse(UnsupportedBuildEval("rt_feature", {})) + self.assertFalse(UnsupportedBuildEval("!rt_feature", {})) + self.assertTrue(RequiresBuildEval("windows || rt_feature", {"linux"})) + self.assertFalse(UnsupportedBuildEval("windows || rt_feature", {"linux"})) + self.assertTrue(RequiresBuildEval("linux && rt_feature", {"linux"})) + self.assertFalse(UnsupportedBuildEval("linux && rt_feature", {"linux"})) + self.assertTrue(RequiresBuildEval("linux && !(zstd || rt_feature)", {"linux"})) + self.assertFalse( + UnsupportedBuildEval("linux && !(zstd || rt_feature)", {"linux"}) + ) + # build-only expressions where unknown does not affect the resulting value + self.assertTrue(RequiresBuildEval("linux || rt_feature", {"linux"})) + self.assertTrue(UnsupportedBuildEval("linux || rt_feature", {"linux"})) + self.assertFalse(RequiresBuildEval("windows && rt_feature", {"linux"})) + self.assertFalse(UnsupportedBuildEval("windows && rt_feature", {"linux"})) + self.assertFalse( + RequiresBuildEval("linux && (vulkan && rt_feature)", {"linux"}) + ) + self.assertFalse( + UnsupportedBuildEval("linux && (vulkan && rt_feature)", {"linux"}) + ) + # runtime feature is present in build-only + with self.assertRaises(ValueError): + RequiresBuildEval("rt_feature", {"rt_feature"}) + with self.assertRaises(ValueError): + UnsupportedBuildEval("rt_feature", {"rt_feature"}) + + +if __name__ == "__main__": + unittest.main() diff --git a/sycl/test-e2e/EnqueueNativeCommand/custom-command-cuda.cpp b/sycl/test-e2e/EnqueueNativeCommand/custom-command-cuda.cpp index b777f314d2f92..7afbaf7cc14ed 100644 --- a/sycl/test-e2e/EnqueueNativeCommand/custom-command-cuda.cpp +++ b/sycl/test-e2e/EnqueueNativeCommand/custom-command-cuda.cpp @@ -1,7 +1,6 @@ // RUN: %{build} -Wno-error=deprecated-declarations -o %t.out %cuda_options // RUN: %{run} %t.out // REQUIRES: cuda, cuda_dev_kit -// REQUIRES: build-and-run-mode #include diff --git a/sycl/test-e2e/EnqueueNativeCommand/custom-command-hip.cpp b/sycl/test-e2e/EnqueueNativeCommand/custom-command-hip.cpp index 47bf42eee8158..00aafba08fc4a 100644 --- a/sycl/test-e2e/EnqueueNativeCommand/custom-command-hip.cpp +++ b/sycl/test-e2e/EnqueueNativeCommand/custom-command-hip.cpp @@ -2,8 +2,7 @@ // we should set this with some variable instead. // RUN: %{build} -Wno-error=deprecated-pragma -o %t.out -I%rocm_path/include -L%rocm_path/lib -lamdhip64 // RUN: %{run} %t.out -// REQUIRES: hip -// REQUIRES: build-and-run-mode +// REQUIRES: target-amd #include #include diff --git a/sycl/test-e2e/EnqueueNativeCommand/custom-command-multiple-dev-cuda.cpp b/sycl/test-e2e/EnqueueNativeCommand/custom-command-multiple-dev-cuda.cpp index f487b26026ec2..2dc30b44bfe94 100644 --- a/sycl/test-e2e/EnqueueNativeCommand/custom-command-multiple-dev-cuda.cpp +++ b/sycl/test-e2e/EnqueueNativeCommand/custom-command-multiple-dev-cuda.cpp @@ -1,5 +1,4 @@ // REQUIRES: cuda, cuda_dev_kit -// REQUIRES: build-and-run-mode // RUN: %{build} -o %t.out %cuda_options // RUN: %{run} %t.out diff --git a/sycl/test-e2e/HostInteropTask/interop-task-cuda-buffer-migrate.cpp b/sycl/test-e2e/HostInteropTask/interop-task-cuda-buffer-migrate.cpp index 2eea51a1ded9b..b6ac1f96f90e1 100644 --- a/sycl/test-e2e/HostInteropTask/interop-task-cuda-buffer-migrate.cpp +++ b/sycl/test-e2e/HostInteropTask/interop-task-cuda-buffer-migrate.cpp @@ -1,5 +1,4 @@ // REQUIRES: cuda, cuda_dev_kit -// REQUIRES: build-and-run-mode // // RUN: %{build} -o %t.out %cuda_options // RUN: %{run} %t.out diff --git a/sycl/test-e2e/HostInteropTask/interop-task-cuda.cpp b/sycl/test-e2e/HostInteropTask/interop-task-cuda.cpp index f3a61471d1d08..055160e8bb624 100644 --- a/sycl/test-e2e/HostInteropTask/interop-task-cuda.cpp +++ b/sycl/test-e2e/HostInteropTask/interop-task-cuda.cpp @@ -1,7 +1,6 @@ // RUN: %{build} -o %t.out %cuda_options // RUN: %{run} %t.out // REQUIRES: cuda, cuda_dev_kit -// REQUIRES: build-and-run-mode #include #include diff --git a/sycl/test-e2e/HostInteropTask/interop-task-hip.cpp b/sycl/test-e2e/HostInteropTask/interop-task-hip.cpp index 10e54f416f8a2..23856043230f2 100644 --- a/sycl/test-e2e/HostInteropTask/interop-task-hip.cpp +++ b/sycl/test-e2e/HostInteropTask/interop-task-hip.cpp @@ -2,8 +2,7 @@ // we should set this with some variable instead. // RUN: %{build} -Wno-error=deprecated-pragma -Wno-error=deprecated-declarations -o %t.out -I%rocm_path/include -L%rocm_path/lib -lamdhip64 // RUN: %{run} %t.out -// REQUIRES: hip -// REQUIRES: build-and-run-mode +// REQUIRES: target-amd #include #include diff --git a/sycl/test-e2e/OptionalKernelFeatures/is_compatible/is_compatible_amdgcn.cpp b/sycl/test-e2e/OptionalKernelFeatures/is_compatible/is_compatible_amdgcn.cpp index c0a1cb07db1e1..caf53df00e1d4 100644 --- a/sycl/test-e2e/OptionalKernelFeatures/is_compatible/is_compatible_amdgcn.cpp +++ b/sycl/test-e2e/OptionalKernelFeatures/is_compatible/is_compatible_amdgcn.cpp @@ -1,5 +1,4 @@ // REQUIRES: hip, opencl, gpu, cpu -// REQUIRES: build-and-run-mode // RUN: %clangxx -fsycl -Xsycl-target-backend=amdgcn-amd-amdhsa --offload-arch=gfx906 -fsycl-targets=amdgcn-amd-amdhsa %S/Inputs/is_compatible_with_env.cpp -o %t.out diff --git a/sycl/test-e2e/OptionalKernelFeatures/is_compatible/is_compatible_nvptx64.cpp b/sycl/test-e2e/OptionalKernelFeatures/is_compatible/is_compatible_nvptx64.cpp index 20a5139fc12cd..ccfa829293c3f 100644 --- a/sycl/test-e2e/OptionalKernelFeatures/is_compatible/is_compatible_nvptx64.cpp +++ b/sycl/test-e2e/OptionalKernelFeatures/is_compatible/is_compatible_nvptx64.cpp @@ -1,5 +1,4 @@ // REQUIRES: cuda, opencl, gpu, cpu -// REQUIRES: build-and-run-mode // RUN: %clangxx -fsycl -fsycl-targets=nvptx64-nvidia-cuda %S/Inputs/is_compatible_with_env.cpp -o %t.out diff --git a/sycl/test-e2e/OptionalKernelFeatures/is_compatible/is_compatible_several_targets.cpp b/sycl/test-e2e/OptionalKernelFeatures/is_compatible/is_compatible_several_targets.cpp index 3e9124954b774..eb7f4b0056162 100644 --- a/sycl/test-e2e/OptionalKernelFeatures/is_compatible/is_compatible_several_targets.cpp +++ b/sycl/test-e2e/OptionalKernelFeatures/is_compatible/is_compatible_several_targets.cpp @@ -1,8 +1,7 @@ // REQUIRES: ocloc, any-device-is-level_zero, any-device-is-gpu, any-device-is-cpu -// REQUIRES: build-and-run-mode // RUN: %clangxx -fsycl -fsycl-targets=spir64_gen -Xsycl-target-backend=spir64_gen "-device *" %S/Inputs/is_compatible_with_env.cpp -o %t.out // RUN: env ONEAPI_DEVICE_SELECTOR=opencl:cpu %{run-unfiltered-devices} not %t.out // RUN: env ONEAPI_DEVICE_SELECTOR=opencl:gpu %{run-unfiltered-devices} %t.out -// RUN: env ONEAPI_DEVICE_SELECTOR=level_zero:gpu %{run-unfiltered-devices} %t.out \ No newline at end of file +// RUN: env ONEAPI_DEVICE_SELECTOR=level_zero:gpu %{run-unfiltered-devices} %t.out diff --git a/sycl/test-e2e/OptionalKernelFeatures/is_compatible/is_compatible_spir64.cpp b/sycl/test-e2e/OptionalKernelFeatures/is_compatible/is_compatible_spir64.cpp index fcf6affb809fb..465a79056906a 100644 --- a/sycl/test-e2e/OptionalKernelFeatures/is_compatible/is_compatible_spir64.cpp +++ b/sycl/test-e2e/OptionalKernelFeatures/is_compatible/is_compatible_spir64.cpp @@ -1,5 +1,4 @@ // REQUIRES: cuda, opencl, gpu, cpu -// REQUIRES: build-and-run-mode // RUN: %clangxx -fsycl -fsycl-targets=spir64 %S/Inputs/is_compatible_with_env.cpp -o %t.out diff --git a/sycl/test-e2e/OptionalKernelFeatures/is_compatible/is_compatible_spir64_fpga.cpp b/sycl/test-e2e/OptionalKernelFeatures/is_compatible/is_compatible_spir64_fpga.cpp index 1372c352c09ea..57366482e7082 100644 --- a/sycl/test-e2e/OptionalKernelFeatures/is_compatible/is_compatible_spir64_fpga.cpp +++ b/sycl/test-e2e/OptionalKernelFeatures/is_compatible/is_compatible_spir64_fpga.cpp @@ -1,5 +1,4 @@ // REQUIRES: opencl-aot, accelerator, gpu, cpu -// REQUIRES: build-and-run-mode // RUN: %clangxx -fsycl -fsycl-targets=spir64_fpga %S/Inputs/is_compatible_with_env.cpp -o %t.out diff --git a/sycl/test-e2e/OptionalKernelFeatures/is_compatible/is_compatible_spir64_gen.cpp b/sycl/test-e2e/OptionalKernelFeatures/is_compatible/is_compatible_spir64_gen.cpp index c6a01b3a6dc18..5adb27e0ae697 100644 --- a/sycl/test-e2e/OptionalKernelFeatures/is_compatible/is_compatible_spir64_gen.cpp +++ b/sycl/test-e2e/OptionalKernelFeatures/is_compatible/is_compatible_spir64_gen.cpp @@ -1,5 +1,4 @@ // REQUIRES: ocloc, gpu, level_zero, cpu -// REQUIRES: build-and-run-mode // RUN: %clangxx -fsycl -fsycl-targets=spir64_gen -Xsycl-target-backend "-device *" %S/Inputs/is_compatible_with_env.cpp -o %t.out diff --git a/sycl/test-e2e/OptionalKernelFeatures/is_compatible/is_compatible_spir64_x86_64.cpp b/sycl/test-e2e/OptionalKernelFeatures/is_compatible/is_compatible_spir64_x86_64.cpp index 5de21b8984d71..0a6f2c39df8af 100644 --- a/sycl/test-e2e/OptionalKernelFeatures/is_compatible/is_compatible_spir64_x86_64.cpp +++ b/sycl/test-e2e/OptionalKernelFeatures/is_compatible/is_compatible_spir64_x86_64.cpp @@ -1,5 +1,4 @@ // REQUIRES: opencl-aot, cpu, gpu, level_zero -// REQUIRES: build-and-run-mode // RUN: %clangxx -fsycl -fsycl-targets=spir64_x86_64 %S/Inputs/is_compatible_with_env.cpp -o %t.out diff --git a/sycl/test-e2e/Regression/compile_on_win_with_mdd.cpp b/sycl/test-e2e/Regression/compile_on_win_with_mdd.cpp index ea1e1c7d49891..57826c81ece2e 100644 --- a/sycl/test-e2e/Regression/compile_on_win_with_mdd.cpp +++ b/sycl/test-e2e/Regression/compile_on_win_with_mdd.cpp @@ -1,5 +1,4 @@ // REQUIRES: windows -// REQUIRES: build-and-run-mode // RUN: %clangxx --driver-mode=cl -fsycl /MDd -c %s -o %t.obj // RUN: %clangxx --driver-mode=cl -fsycl %t.obj -Wno-unused-command-line-argument -o %t.out diff --git a/sycl/test-e2e/Regression/fsycl-host-compiler-win.cpp b/sycl/test-e2e/Regression/fsycl-host-compiler-win.cpp index e4073831bb71b..4ffe42c45c52f 100644 --- a/sycl/test-e2e/Regression/fsycl-host-compiler-win.cpp +++ b/sycl/test-e2e/Regression/fsycl-host-compiler-win.cpp @@ -1,7 +1,6 @@ // RUN: %{build} -fsycl-host-compiler=cl -DDEFINE_CHECK -fsycl-host-compiler-options="-DDEFINE_CHECK /std:c++17 /Zc:__cplusplus" -o %t.exe // RUN: %{run} %t.exe // REQUIRES: windows -// REQUIRES: build-and-run-mode // //==------- fsycl-host-compiler-win.cpp - external host compiler test ------==// // diff --git a/sycl/test-e2e/Regression/msvc_crt.cpp b/sycl/test-e2e/Regression/msvc_crt.cpp index a54570efd820c..9d59547e50d7b 100644 --- a/sycl/test-e2e/Regression/msvc_crt.cpp +++ b/sycl/test-e2e/Regression/msvc_crt.cpp @@ -3,7 +3,6 @@ // RUN: %{build} /MDd -o %t2.exe // RUN: %{run} %t2.exe // REQUIRES: system-windows, cl_options -// REQUIRES: build-and-run-mode //==-------------- msvc_crt.cpp - SYCL MSVC CRT test -----------------------==// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. diff --git a/sycl/test-e2e/Regression/multiple-targets.cpp b/sycl/test-e2e/Regression/multiple-targets.cpp index aa8c125d90738..9e1680453ccdb 100644 --- a/sycl/test-e2e/Regression/multiple-targets.cpp +++ b/sycl/test-e2e/Regression/multiple-targets.cpp @@ -2,18 +2,17 @@ // It tests if the target triples can be specified with any order. // The test is repeated for per_kernel device code splitting. // -// REQUIRES: cuda || hip || native_cpu -// REQUIRES: build-and-run-mode -// RUN: %clangxx -fsycl -fsycl-targets=%{sycl_triple},spir64 %if any-device-is-hip %{ %{hip_arch_opts} %} -o %t1.out %s +// REQUIRES: (target-nvidia || target-amd || target-native_cpu) && any-target-is-spir +// RUN: %clangxx -fsycl -fsycl-targets=%{sycl_triple},spir64 %if any-target-is-amd %{ %{hip_arch_opts} %} -o %t1.out %s // RUN: %{run} %t1.out // -// RUN: %clangxx -fsycl -fsycl-targets=spir64,%{sycl_triple} %if any-device-is-hip %{ %{hip_arch_opts} %} -o %t2.out %s +// RUN: %clangxx -fsycl -fsycl-targets=spir64,%{sycl_triple} %if any-target-is-amd %{ %{hip_arch_opts} %} -o %t2.out %s // RUN: %{run} %t2.out // -// RUN: %clangxx -fsycl -fsycl-targets=%{sycl_triple},spir64 %if any-device-is-hip %{ %{hip_arch_opts} %} -fsycl-device-code-split=per_kernel -o %t3.out %s +// RUN: %clangxx -fsycl -fsycl-targets=%{sycl_triple},spir64 %if any-target-is-amd %{ %{hip_arch_opts} %} -fsycl-device-code-split=per_kernel -o %t3.out %s // RUN: %{run} %t3.out // -// RUN: %clangxx -fsycl -fsycl-targets=spir64,%{sycl_triple} %if any-device-is-hip %{ %{hip_arch_opts} %} -fsycl-device-code-split=per_kernel -o %t4.out %s +// RUN: %clangxx -fsycl -fsycl-targets=spir64,%{sycl_triple} %if any-target-is-amd %{ %{hip_arch_opts} %} -fsycl-device-code-split=per_kernel -o %t4.out %s // RUN: %{run} %t4.out #include diff --git a/sycl/test-e2e/SpecConstants/2020/non_native/cuda.cpp b/sycl/test-e2e/SpecConstants/2020/non_native/cuda.cpp index af12b66208dad..12d2ce6a9faf9 100644 --- a/sycl/test-e2e/SpecConstants/2020/non_native/cuda.cpp +++ b/sycl/test-e2e/SpecConstants/2020/non_native/cuda.cpp @@ -1,5 +1,4 @@ // REQUIRES: cuda -// REQUIRES: build-and-run-mode // RUN: %clangxx -fsycl -fsycl-targets=nvptx64-nvidia-cuda %S/Inputs/common.cpp -o %t.out // RUN: %{run-unfiltered-devices} env ONEAPI_DEVICE_SELECTOR="cuda:*" %t.out diff --git a/sycl/test-e2e/format.py b/sycl/test-e2e/format.py index eac6ebe0ba2ed..a9e98a4ed8037 100644 --- a/sycl/test-e2e/format.py +++ b/sycl/test-e2e/format.py @@ -2,27 +2,16 @@ import lit.formats import platform -from lit.BooleanExpression import BooleanExpression from lit.TestRunner import ( ParserKind, IntegratedTestKeywordParser, - # parseIntegratedTestScript, ) +from E2EExpr import E2EExpr import os import re -def get_triple(backend): - if backend == "cuda": - return "nvptx64-nvidia-cuda" - if backend == "hip": - return "amdgcn-amd-amdhsa" - if backend == "native_cpu": - return "native_cpu" - return "spir64" - - def parse_min_intel_driver_req(line_number, line, output): """ Driver version looks like this for Intel devices: @@ -87,22 +76,85 @@ def parseTestScript(self, test): return script - def getMatchedFromList(self, features, alist): + def getMatchedFromList( + self, features, expression_list, build_only_mode, is_requires_directive + ): try: return [ - item for item in alist if BooleanExpression.evaluate(item, features) + item + for item in expression_list + if E2EExpr.evaluate( + item, features, build_only_mode, is_requires_directive + ) + != is_requires_directive ] except ValueError as e: - raise ValueError("Error in UNSUPPORTED list:\n%s" % str(e)) + raise ValueError("Error in expression:\n%s" % str(e)) + + BuildOnly = True + BuildAndRun = False + RequiresDirective = True + UnsupportedDirective = False + + def getMissingRequires(self, features, expression_list): + return self.getMatchedFromList( + features, expression_list, self.BuildAndRun, self.RequiresDirective + ) + + def getMissingRequiresBuildOnly(self, features, expression_list): + return self.getMatchedFromList( + features, expression_list, self.BuildOnly, self.RequiresDirective + ) + + def getMatchedUnsupported(self, features, expression_list): + return self.getMatchedFromList( + features, expression_list, self.BuildAndRun, self.UnsupportedDirective + ) + + def getMatchedUnsupportedBuildOnly(self, features, expression_list): + return self.getMatchedFromList( + features, expression_list, self.BuildOnly, self.UnsupportedDirective + ) + + getMatchedXFail = getMatchedUnsupported + + def select_build_targets_for_test(self, test): + supported_targets = set() + for t in test.config.sycl_build_targets: + features = test.config.available_features.union({t}) + if self.getMissingRequiresBuildOnly(features, test.requires): + continue + if self.getMatchedUnsupportedBuildOnly(features, test.unsupported): + continue + supported_targets.add(t) + + if len(supported_targets) <= 1: + return supported_targets + + # Treat XFAIL as UNSUPPORTED if the test is to be compiled for multiple + # triples. + + if "*" in test.xfails: + return [] + + triples_without_xfail = [ + t + for t in supported_targets + if not self.getMatchedXFail( + test.config.available_features.union({t}), test.xfails + ) + ] + + return triples_without_xfail def select_devices_for_test(self, test): devices = [] for d in test.config.sycl_devices: features = test.config.sycl_dev_features[d] - if test.getMissingRequiredFeaturesFromList(features): + if self.getMissingRequires(features, test.requires): continue - if self.getMatchedFromList(features, test.unsupported): + if self.getMatchedUnsupported(features, test.unsupported): continue driver_ok = True @@ -134,9 +186,7 @@ def select_devices_for_test(self, test): devices_without_xfail = [ d for d in devices - if not self.getMatchedFromList( - test.config.sycl_dev_features[d], test.xfails - ) + if not self.getMatchedXFail(test.config.sycl_dev_features[d], test.xfails) ] return devices_without_xfail @@ -152,13 +202,13 @@ def execute(self, test, litConfig): return script devices_for_test = [] - triples = set() + build_targets = set() if test.config.test_mode == "build-only": - if "build-and-run-mode" in test.requires or "true" in test.unsupported: + build_targets = self.select_build_targets_for_test(test) + if not build_targets: return lit.Test.Result( - lit.Test.UNSUPPORTED, "Test unsupported for this environment" + lit.Test.UNSUPPORTED, "No supported triple to build for" ) - triples = {"spir64"} else: devices_for_test = self.select_devices_for_test(test) if not devices_for_test: @@ -168,14 +218,16 @@ def execute(self, test, litConfig): for sycl_device in devices_for_test: (backend, _) = sycl_device.split(":") - triples.add(get_triple(backend)) + build_targets.add(test.config.backend_to_target[backend]) + + triples = set(test.config.target_to_triple[t] for t in build_targets) substitutions = lit.TestRunner.getDefaultSubstitutions(test, tmpDir, tmpBase) substitutions.append(("%{sycl_triple}", format(",".join(triples)))) sycl_target_opts = "-fsycl-targets=%{sycl_triple}" - if get_triple("hip") in triples: + if "target-amd" in build_targets: hip_arch_opts = ( " -Xsycl-target-backend=amdgcn-amd-amdhsa --offload-arch={}".format( test.config.amd_arch @@ -184,7 +236,7 @@ def execute(self, test, litConfig): sycl_target_opts += hip_arch_opts substitutions.append(("%{hip_arch_opts}", hip_arch_opts)) if ( - get_triple("spir64") in triples + "target-spir" in build_targets and "spirv-backend" in test.config.available_features ): sycl_target_opts += " -fsycl-use-spirv-backend-for-spirv-gen" @@ -323,19 +375,18 @@ def get_extra_env(sycl_devices): test, litConfig, useExternalSh, script, tmpBase ) - if len(devices_for_test) > 1 or test.config.test_mode == "build-only": - return result - - # Single device - might be an XFAIL. - device = devices_for_test[0] - if "*" in test.xfails or self.getMatchedFromList( - test.config.sycl_dev_features[device], test.xfails - ): - if result.code is lit.Test.PASS: - result.code = lit.Test.XPASS - # fail -> expected fail - elif result.code is lit.Test.FAIL: - result.code = lit.Test.XFAIL - return result - + # Single triple/device - might be an XFAIL. + def map_result(features, code): + if "*" in test.xfails or self.getMatchedXFail(features, test.xfails): + if code is lit.Test.PASS: + code = lit.Test.XPASS + elif code is lit.Test.FAIL: + code = lit.Test.XFAIL + return code + + if len(triples) == 1 and test.config.test_mode == "build-only": + result.code = map_result(test.config.available_features, result.code) + if len(devices_for_test) == 1: + device = devices_for_test[0] + result.code = map_result(test.config.sycl_dev_features[device], result.code) return result diff --git a/sycl/test-e2e/lit.cfg.py b/sycl/test-e2e/lit.cfg.py index 5b60d93387b7a..c58f702e6f5d5 100644 --- a/sycl/test-e2e/lit.cfg.py +++ b/sycl/test-e2e/lit.cfg.py @@ -15,6 +15,23 @@ from lit.llvm.subst import ToolSubst, FindTool # Configuration file for the 'lit' test runner. +config.backend_to_target = { + "level_zero": "target-spir", + "opencl": "target-spir", + "cuda": "target-nvidia", + "hip": "target-amd", + "native_cpu": "target-native_cpu", +} +config.target_to_triple = { + "target-spir": "spir64", + "target-nvidia": "nvptx64-nvidia-cuda", + "target-amd": "amdgcn-amd-amdhsa", + "target-native_cpu": "native_cpu", +} +config.triple_to_target = {v: k for k, v in config.target_to_triple.items()} +config.backend_to_triple = { + k: config.target_to_triple.get(v) for k, v in config.backend_to_target.items() +} # name: The name of this test suite. config.name = "SYCL" @@ -52,6 +69,8 @@ elif config.test_mode == "build-only": lit_config.note("build-only test mode enabled, only compiling tests") config.sycl_devices = [] + if not config.amd_arch: + config.amd_arch = "gfx1031" else: lit_config.error("Invalid argument for test-mode") @@ -677,12 +696,21 @@ def open_check_file(file_name): "Couldn't find pre-installed AOT device compiler " + aot_tool ) +# Clear build targets when not in build-only, to populate according to devices +if config.test_mode != "build-only": + config.sycl_build_targets = set() + for sycl_device in config.sycl_devices: be, dev = sycl_device.split(":") config.available_features.add("any-device-is-" + dev) # Use short names for LIT rules. config.available_features.add("any-device-is-" + be) + target = config.backend_to_target[be] + config.sycl_build_targets.add(target) + +for target in config.sycl_build_targets: + config.available_features.add("any-target-is-" + target.replace("target-", "")) # That has to be executed last so that all device-independent features have been # discovered already. config.sycl_dev_features = {} @@ -826,6 +854,9 @@ def open_check_file(file_name): features.add(dev.replace("fpga", "accelerator")) # Use short names for LIT rules. features.add(be) + # Add corresponding target feature + target = config.backend_to_target[be] + features.add(target) if be == "hip": if not config.amd_arch: diff --git a/sycl/test-e2e/lit.site.cfg.py.in b/sycl/test-e2e/lit.site.cfg.py.in index 00928dd9141fc..02f4125a4680f 100644 --- a/sycl/test-e2e/lit.site.cfg.py.in +++ b/sycl/test-e2e/lit.site.cfg.py.in @@ -30,6 +30,9 @@ config.igc_tag_file = os.path.join("/usr/local/lib/igc/", 'IGCTAG.txt') config.sycl_devices = lit_config.params.get("sycl_devices", "@SYCL_TEST_E2E_TARGETS@").split(';') +# FIXME: current test markup only supports spir in build-only +config.sycl_build_targets = set("target-" + t for t in lit_config.params.get("sycl_build_targets", "spir").split(';')) + config.amd_arch = lit_config.params.get("amd_arch", "@AMD_ARCH@") config.sycl_threads_lib = '@SYCL_THREADS_LIB@' config.extra_environment = lit_config.params.get("extra_environment", "@LIT_EXTRA_ENVIRONMENT@") diff --git a/sycl/test/e2e_test_requirements/check_e2eexpr_logic.cpp b/sycl/test/e2e_test_requirements/check_e2eexpr_logic.cpp new file mode 100644 index 0000000000000..2e394d4a78687 --- /dev/null +++ b/sycl/test/e2e_test_requirements/check_e2eexpr_logic.cpp @@ -0,0 +1,8 @@ +// E2E tests use a modified expression parser that allows for a third "unknown" +// boolean state to handle missing run-time features in REQUIRES/UNSUPPORTED +// statements. This test runs the unit tests related to these expressions. +// +// REQUIRES: linux +// DEFINE: %{E2EExpr}=%S/../../test-e2e/E2EExpr.py +// DEFINE: %{lit_source}=%S/../../../llvm/utils/lit +// RUN: env PYTHONPATH=%{lit_source} python %{E2EExpr}