From 3fd1c075654c60b5f61ba76ae1dbfa112121b9fb Mon Sep 17 00:00:00 2001 From: Alexey Sachkov Date: Wed, 20 Nov 2024 08:19:13 -0800 Subject: [PATCH] [SYCL] Improve SYCL library versioning macro We have a macro `__SYCL_COMPILER_VERSION` which only corresponds to a date when build was performed - it does not give any indication of the actual compiler version, nor does it give any indication of the actual library build. This patch attempts to deprecate that old macro and replaces it with `__LIBSYCL_TIMESTAMP` which contains a date of the latest commit included into the SYCL library (and therefore SYCL headers) build. Using commit date is more relibable than build date and its naming speicifally refers to library instead of the compiler. "Attempts" above is because it is a bit tricky to deprecate a macro and heavily depends on the compiler which is being used. Not every 3rd-party host compiler is covered, i.e. deprecation message may only be emitted from device compilation pass in certain cases. Resolves #2250 --- sycl/CMakeLists.txt | 6 ++--- sycl/cmake/modules/SYCLVersionFromVCS.cmake | 15 +++++++++++ sycl/doc/PreprocessorMacros.md | 5 ++++ sycl/source/version.hpp.in | 26 ++++++++++++++++++- .../warnings/sycl-compiler-version-cl.cpp | 13 ++++++++++ .../warnings/sycl-compiler-version-clang.cpp | 10 +++++++ .../warnings/sycl-compiler-version-gcc.cpp | 13 ++++++++++ 7 files changed, 84 insertions(+), 4 deletions(-) create mode 100644 sycl/cmake/modules/SYCLVersionFromVCS.cmake create mode 100644 sycl/test/warnings/sycl-compiler-version-cl.cpp create mode 100644 sycl/test/warnings/sycl-compiler-version-clang.cpp create mode 100644 sycl/test/warnings/sycl-compiler-version-gcc.cpp diff --git a/sycl/CMakeLists.txt b/sycl/CMakeLists.txt index a29bfc6310e39..44bac01573347 100644 --- a/sycl/CMakeLists.txt +++ b/sycl/CMakeLists.txt @@ -188,10 +188,9 @@ set(SYCL_EXT_ONEAPI_BACKEND_CUDA ${LLVM_HAS_NVPTX_TARGET}) set(SYCL_EXT_ONEAPI_BACKEND_HIP ${LLVM_HAS_AMDGPU_TARGET}) # Configure SYCL version macro -set(sycl_inc_dir ${CMAKE_CURRENT_SOURCE_DIR}/include) +set(SYCL_ROOT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(sycl_src_dir ${CMAKE_CURRENT_SOURCE_DIR}/source) -string(TIMESTAMP __SYCL_COMPILER_VERSION "%Y%m%d") -configure_file("source/version.hpp.in" "${SYCL_INCLUDE_BUILD_DIR}/sycl/version.hpp") +include(SYCLVersionFromVCS) configure_file("source/feature_test.hpp.in" "${SYCL_INCLUDE_BUILD_DIR}/sycl/feature_test.hpp") # Generate device_aspect_macros.hpp @@ -217,6 +216,7 @@ install(FILES include(AddBoostMp11Headers) include(FetchBoostUnorderedHeaders) +set(sycl_inc_dir ${CMAKE_CURRENT_SOURCE_DIR}/include) # This is workaround to detect changes (add or modify) in subtree which # are not detected by copy_directory command. # TODO: detect and process remove header/directory case diff --git a/sycl/cmake/modules/SYCLVersionFromVCS.cmake b/sycl/cmake/modules/SYCLVersionFromVCS.cmake new file mode 100644 index 0000000000000..da4de1f2ee1fc --- /dev/null +++ b/sycl/cmake/modules/SYCLVersionFromVCS.cmake @@ -0,0 +1,15 @@ + +# Grab the date of the latest commit +execute_process( + COMMAND git log -1 --format=%as # date in YYYY-MM-DD mode + WORKING_DIRECTORY ${SYCL_ROOT_SOURCE_DIR} + OUTPUT_VARIABLE GIT_COMMIT_DATE_TEMP + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +string(REPLACE "-" "" __LIBSYCL_TIMESTAMP ${GIT_COMMIT_DATE_TEMP}) + +# Legacy thing for backwards compatibility. Use of the current date is not +# reliable, because we can always make new build from older commits. +string(TIMESTAMP __SYCL_COMPILER_VERSION "%Y%m%d") +configure_file("${sycl_src_dir}/version.hpp.in" "${SYCL_INCLUDE_BUILD_DIR}/sycl/version.hpp") diff --git a/sycl/doc/PreprocessorMacros.md b/sycl/doc/PreprocessorMacros.md index 3ee1e0e79aa63..93fdd6e8dc635 100644 --- a/sycl/doc/PreprocessorMacros.md +++ b/sycl/doc/PreprocessorMacros.md @@ -57,6 +57,11 @@ This file describes macros that have effect on SYCL compiler and run-time. ## Version macros +- `__LIBSYCL_TIMESTAMP` is set to an integer literal which corresponds to a date + when the latest commit into `sycl/` subproject was done. It could be used + to distinguish between different library builds (which includes SYCL headers) + to workaround any bugs, or API/ABI-breaking changes. The format is `YYYYMMDD`. + - `__LIBSYCL_MAJOR_VERSION` is set to SYCL runtime library major version. - `__LIBSYCL_MINOR_VERSION` is set to SYCL runtime library minor version. - `__LIBSYCL_PATCH_VERSION` is set to SYCL runtime library patch version. diff --git a/sycl/source/version.hpp.in b/sycl/source/version.hpp.in index c23df94a920a2..b933f58350eb9 100644 --- a/sycl/source/version.hpp.in +++ b/sycl/source/version.hpp.in @@ -1,4 +1,4 @@ -//==------ version.hpp --- SYCL compiler version macro ---------*- C++ -*---==// +//==------- version.hpp --- SYCL library version macro ---------*- C++ -*---==// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,7 +6,31 @@ // //===----------------------------------------------------------------------===// +// __SYCL_COMPILER_VERSION is a legacy macro which does not represent a compiler +// version, but instead only conveys a date when sycl library was built. + +#if /* defined(__GNUC__) || */ defined(__clang__) +// clang supports GCC-style pragma messages, but GCC does not! +// include/sycl/version.hpp error: missing binary operator before token "(" +// 14 | #define __SYCL_COMPILER_VERSION _Pragma("GCC warning \"..\"") 20241120 + +#cmakedefine __SYCL_COMPILER_VERSION _Pragma( \ + "GCC warning \"__SYCL_COMPILER_VERSION is deprecated, " \ + "use __LIBSYCL_TIMESTAMP instead\"") ${__SYCL_COMPILER_VERSION} +#elif defined(_MSC_VER) +#cmakedefine __SYCL_COMPILER_VERSION ${__SYCL_COMPILER_VERSION} +// It seems like MSVC ignores that pragma if its embedded into a macro +// definition, so we have it on a standalone line +_Pragma("deprecated(\"__SYCL_COMPILER_VERSION\")") +#else +// As a fallback, we still define the macro, but without a deprecation warning. +// This path is only expected to be taken when 3rd-party host compiler is used +// and that is not clang/msvc #cmakedefine __SYCL_COMPILER_VERSION ${__SYCL_COMPILER_VERSION} +#endif + +#cmakedefine __LIBSYCL_TIMESTAMP ${__LIBSYCL_TIMESTAMP} + #define __LIBSYCL_MAJOR_VERSION ${SYCL_MAJOR_VERSION} #define __LIBSYCL_MINOR_VERSION ${SYCL_MINOR_VERSION} #define __LIBSYCL_PATCH_VERSION ${SYCL_PATCH_VERSION} diff --git a/sycl/test/warnings/sycl-compiler-version-cl.cpp b/sycl/test/warnings/sycl-compiler-version-cl.cpp new file mode 100644 index 0000000000000..5627fd24de5b4 --- /dev/null +++ b/sycl/test/warnings/sycl-compiler-version-cl.cpp @@ -0,0 +1,13 @@ +// RUN: %clangxx -fsycl -fsycl-host-compiler=cl %s \ +// RUN: -fsycl-host-compiler-options="/std:c++17 /Zc:__cplusplus" -c \ +// RUN: -o %t.out | FileCheck %s +// REQUIRES: windows + +#include + +// CHECK: '__SYCL_COMPILER_VERSION': name was marked as #pragma deprecated +#if __SYCL_COMPILER_VERSION >= 2024 + +#endif + +int main() {} diff --git a/sycl/test/warnings/sycl-compiler-version-clang.cpp b/sycl/test/warnings/sycl-compiler-version-clang.cpp new file mode 100644 index 0000000000000..b4f9b03b767d6 --- /dev/null +++ b/sycl/test/warnings/sycl-compiler-version-clang.cpp @@ -0,0 +1,10 @@ +// RUN: %clangxx -fsycl %s -fsyntax-only -Xclang -verify + +#include + +// expected-warning@+1 {{__SYCL_COMPILER_VERSION is deprecated, use __LIBSYCL_TIMESTAMP instead}} +#if __SYCL_COMPILER_VERSION >= 2024 + +#endif + +int main() {} diff --git a/sycl/test/warnings/sycl-compiler-version-gcc.cpp b/sycl/test/warnings/sycl-compiler-version-gcc.cpp new file mode 100644 index 0000000000000..97283c7ec58a4 --- /dev/null +++ b/sycl/test/warnings/sycl-compiler-version-gcc.cpp @@ -0,0 +1,13 @@ +// RUN: %clangxx -fsycl -fsycl-host-compiler=g++ %s -c %t.out | FileCheck %s +// XFAIL: * +// XFAIL-TRACKER: TBD +// REQUIRES: linux + +#include + +// CHECK: __SYCL_COMPILER_VERSION is deprecated, use __LIBSYCL_TIMESTAMP instead +#if __SYCL_COMPILER_VERSION >= 2024 + +#endif + +int main() {}