From b1a45f1539e093b60d645e6b336542da19fce740 Mon Sep 17 00:00:00 2001 From: Alexander Batashev Date: Fri, 13 Sep 2019 22:20:24 +0300 Subject: [PATCH 1/3] [SYCL] Add debug variant for SYCL RT Signed-off-by: Alexander Batashev --- sycl/CMakeLists.txt | 7 +- sycl/source/CMakeLists.txt | 217 ++++++++++++++++++++++--------------- 2 files changed, 138 insertions(+), 86 deletions(-) diff --git a/sycl/CMakeLists.txt b/sycl/CMakeLists.txt index 6d3ef64670a09..42ee96ab5c5b8 100644 --- a/sycl/CMakeLists.txt +++ b/sycl/CMakeLists.txt @@ -138,12 +138,17 @@ COMMENT "Copying SYCL headers ...") # Configure SYCL headers install(DIRECTORY "${sycl_inc_dir}/." DESTINATION "${LLVM_INST_INC_DIRECTORY}" COMPONENT sycl-headers) +set(SYCL_RT_LIBS sycl) +if (MSVC) + list(APPEND SYCL_RT_LIBS sycld) +endif() + # SYCL runtime library add_subdirectory(source) # SYCL toolchain builds all components: compiler, libraries, headers, etc. add_custom_target( sycl-toolchain - DEPENDS sycl + DEPENDS ${SYCL_RT_LIBS} clang clang-offload-wrapper clang-offload-bundler diff --git a/sycl/source/CMakeLists.txt b/sycl/source/CMakeLists.txt index 1e0dc19f55422..4f61faa82e34f 100644 --- a/sycl/source/CMakeLists.txt +++ b/sycl/source/CMakeLists.txt @@ -4,101 +4,148 @@ #cmake_policy(SET CMP0057 NEW) #include(AddLLVM) -add_library(sycl SHARED - "${sycl_inc_dir}/CL/sycl.hpp" - "detail/builtins_common.cpp" - "detail/builtins_geometric.cpp" - "detail/builtins_integer.cpp" - "detail/builtins_math.cpp" - "detail/builtins_relational.cpp" - "detail/pi.cpp" - "detail/pi_opencl.cpp" - "detail/common.cpp" - "detail/context_impl.cpp" - "detail/device_impl.cpp" - "detail/device_info.cpp" - "detail/event_impl.cpp" - "detail/force_device.cpp" - "detail/helpers.cpp" - "detail/image_accessor_util.cpp" - "detail/image_impl.cpp" - "detail/kernel_impl.cpp" - "detail/kernel_info.cpp" - "detail/memory_manager.cpp" - "detail/platform_impl.cpp" - "detail/platform_info.cpp" - "detail/program_impl.cpp" - "detail/program_manager/program_manager.cpp" - "detail/queue_impl.cpp" - "detail/os_util.cpp" - "detail/platform_util.cpp" - "detail/sampler_impl.cpp" - "detail/stream_impl.cpp" - "detail/scheduler/commands.cpp" - "detail/scheduler/scheduler.cpp" - "detail/scheduler/graph_processor.cpp" - "detail/scheduler/graph_builder.cpp" - "detail/usm/clusm.cpp" - "detail/usm/usm_dispatch.cpp" - "detail/usm/usm_impl.cpp" - "detail/util.cpp" - "context.cpp" - "device.cpp" - "device_selector.cpp" - "event.cpp" - "exception.cpp" - "exception_list.cpp" - "half_type.cpp" - "kernel.cpp" - "platform.cpp" - "queue.cpp" - "ordered_queue.cpp" - "sampler.cpp" - "stream.cpp" - "spirv_ops.cpp" -) +function(add_sycl_rt_library LIB_NAME) + + add_library(${LIB_NAME} SHARED ${ARGN}) + + add_dependencies(${LIB_NAME} + ocl-icd + ocl-headers + sycl-headers + ) + + set_target_properties(${LIB_NAME} PROPERTIES LINKER_LANGUAGE CXX) + + if (MSVC) + target_compile_definitions(${LIB_NAME} PRIVATE __SYCL_BUILD_SYCL_DLL ) + endif() + target_include_directories(${LIB_NAME} PRIVATE "${sycl_inc_dir}") + target_link_libraries(${LIB_NAME} + PRIVATE OpenCL::Headers + PRIVATE ${OpenCL_LIBRARIES} + ) + if (SYCL_USE_LIBCXX) + if ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR + (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")) + target_compile_options(${LIB_NAME} PRIVATE -nostdinc++) + if ((NOT (DEFINED SYCL_LIBCXX_INCLUDE_PATH)) OR (NOT (DEFINED SYCL_LIBCXX_LIBRARY_PATH))) + message(FATAL_ERROR "When building with libc++ SYCL_LIBCXX_INCLUDE_PATHS and" + "SYCL_LIBCXX_LIBRARY_PATH should be set") + endif() + target_include_directories(${LIB_NAME} PRIVATE "${SYCL_LIBCXX_INCLUDE_PATH}") + target_link_libraries(${LIB_NAME} PRIVATE "-L${SYCL_LIBCXX_LIBRARY_PATH}" -nodefaultlibs -lc++ -lc++abi -lm -lc -lgcc_s -lgcc) + else() + message(FATAL_ERROR "Build with libc++ is not yet supported for this compiler") + endif() + else() + +# Workaround for bug in GCC version 5 and higher. +# More information https://bugs.launchpad.net/ubuntu/+source/gcc-5/+bug/1568899 + if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND + CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 5.0) + target_link_libraries(${LIB_NAME} PRIVATE gcc_s gcc) + endif() -add_dependencies(sycl - ocl-icd - ocl-headers - sycl-headers + endif() +endfunction(add_sycl_rt_library) + +set(SYCL_SOURCES + "${sycl_inc_dir}/CL/sycl.hpp" + "detail/builtins_common.cpp" + "detail/builtins_geometric.cpp" + "detail/builtins_integer.cpp" + "detail/builtins_math.cpp" + "detail/builtins_relational.cpp" + "detail/pi.cpp" + "detail/pi_opencl.cpp" + "detail/common.cpp" + "detail/context_impl.cpp" + "detail/device_impl.cpp" + "detail/device_info.cpp" + "detail/event_impl.cpp" + "detail/force_device.cpp" + "detail/helpers.cpp" + "detail/image_accessor_util.cpp" + "detail/image_impl.cpp" + "detail/kernel_impl.cpp" + "detail/kernel_info.cpp" + "detail/memory_manager.cpp" + "detail/platform_impl.cpp" + "detail/platform_info.cpp" + "detail/program_impl.cpp" + "detail/program_manager/program_manager.cpp" + "detail/queue_impl.cpp" + "detail/os_util.cpp" + "detail/platform_util.cpp" + "detail/sampler_impl.cpp" + "detail/stream_impl.cpp" + "detail/scheduler/commands.cpp" + "detail/scheduler/scheduler.cpp" + "detail/scheduler/graph_processor.cpp" + "detail/scheduler/graph_builder.cpp" + "detail/usm/clusm.cpp" + "detail/usm/usm_dispatch.cpp" + "detail/usm/usm_impl.cpp" + "detail/util.cpp" + "context.cpp" + "device.cpp" + "device_selector.cpp" + "event.cpp" + "exception.cpp" + "exception_list.cpp" + "half_type.cpp" + "kernel.cpp" + "platform.cpp" + "queue.cpp" + "ordered_queue.cpp" + "sampler.cpp" + "stream.cpp" + "spirv_ops.cpp" ) -set_target_properties(sycl PROPERTIES LINKER_LANGUAGE CXX) +add_sycl_rt_library(sycl ${SYCL_SOURCES}) if (MSVC) - target_compile_definitions(sycl PRIVATE __SYCL_BUILD_SYCL_DLL ) -endif() -target_include_directories(sycl PRIVATE "${sycl_inc_dir}") -target_link_libraries(sycl - PRIVATE OpenCL::Headers - PRIVATE ${OpenCL_LIBRARIES} -) -if (SYCL_USE_LIBCXX) - if ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR - (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")) - target_compile_options(sycl PRIVATE -nostdinc++) - if ((NOT (DEFINED SYCL_LIBCXX_INCLUDE_PATH)) OR (NOT (DEFINED SYCL_LIBCXX_LIBRARY_PATH))) - message(FATAL_ERROR "When building with libc++ SYCL_LIBCXX_INCLUDE_PATHS and" - "SYCL_LIBCXX_LIBRARY_PATH should be set") - endif() - target_include_directories(sycl PRIVATE "${SYCL_LIBCXX_INCLUDE_PATH}") - target_link_libraries(sycl PRIVATE "-L${SYCL_LIBCXX_LIBRARY_PATH}" -nodefaultlibs -lc++ -lc++abi -lm -lc -lgcc_s -lgcc) - else() - message(FATAL_ERROR "Build with libc++ is not yet supported for this compiler") + # MSVC provides two incompatible build variants for its CRT: release and debug + # To avoid potential issues in user code we also need to provide two kinds + # of SYCL Runtime Library for release and debug configurations. + set(SYCL_CXX_FLAGS "") + if (CMAKE_BUILD_TYPE MATCHES "Debug") + set(SYCL_CXX_FLAGS "${CMAKE_CXX_FLAGS_DEBUG}") + string(REPLACE "/MDd" "" SYCL_CXX_FLAGS "${SYCL_CXX_FLAGS}") + string(REPLACE "/MTd" "" SYCL_CXX_FLAGS "${SYCL_CXX_FLAGS}") + else() + if (CMAKE_BUILD_TYPE MATCHES "Release") + set(SYCL_CXX_FLAGS "${CMAKE_CXX_FLAGS_RELEASE}") + elseif (CMAKE_BUILD_TYPE MATCHES "RelWithDebInfo") + set(SYCL_CXX_FLAGS "${CMAKE_CXX_FLAGS_MINSIZEREL}") + elseif (CMAKE_BUILD_TYPE MATCHES "MinSizeRel") + set(SYCL_CXX_FLAGS "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") endif() -else() + string(REPLACE "/MD" "" SYCL_CXX_FLAGS "${SYCL_CXX_FLAGS}") + string(REPLACE "/MT" "" SYCL_CXX_FLAGS "${SYCL_CXX_FLAGS}") + endif() -# Workaround for bug in GCC version 5 and higher. -# More information https://bugs.launchpad.net/ubuntu/+source/gcc-5/+bug/1568899 -if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND - CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 5.0) - target_link_libraries(sycl PRIVATE gcc_s gcc) -endif() + # target_compile_options requires list of options, not a string + string(REPLACE " " ";" SYCL_CXX_FLAGS "${SYCL_CXX_FLAGS}") + + set(SYCL_CXX_FLAGS_RELEASE "${SYCL_CXX_FLAGS};/MD") + set(SYCL_CXX_FLAGS_DEBUG "${SYCL_CXX_FLAGS};/MDd") + + # CMake automatically applies these flags to all targets. To override this + # behavior, options lists are reset. + set(CMAKE_CXX_FLAGS_RELEASE "") + set(CMAKE_CXX_FLAGS_MINSIZEREL "") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "") + set(CMAKE_CXX_FLAGS_DEBUG "") + + target_compile_options(sycl PUBLIC ${SYCL_CXX_FLAGS_RELEASE}) + add_sycl_rt_library(sycld ${SYCL_SOURCES}) + target_compile_options(sycld PUBLIC ${SYCL_CXX_FLAGS_DEBUG}) endif() -install(TARGETS sycl +install(TARGETS ${SYCL_RT_LIBS} ARCHIVE DESTINATION "lib" COMPONENT sycl LIBRARY DESTINATION "lib" COMPONENT sycl RUNTIME DESTINATION "bin" COMPONENT sycl) From d64f90355118dc5ac74f31d3249d07b1fa929560 Mon Sep 17 00:00:00 2001 From: Alexander Batashev Date: Tue, 17 Sep 2019 16:37:57 +0300 Subject: [PATCH 2/3] [SYCL] Choose SYCL RT wisely Signed-off-by: Alexander Batashev --- clang/lib/Driver/ToolChains/MSVC.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp index 5f16d02958533..3fca1d208964a 100644 --- a/clang/lib/Driver/ToolChains/MSVC.cpp +++ b/clang/lib/Driver/ToolChains/MSVC.cpp @@ -354,8 +354,13 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA, !C.getDriver().IsCLMode()) CmdArgs.push_back("-defaultlib:libcmt"); - if (!Args.hasArg(options::OPT_nostdlib) && Args.hasArg(options::OPT_fsycl)) - CmdArgs.push_back("-defaultlib:sycl.lib"); + if (!Args.hasArg(options::OPT_nostdlib) && Args.hasArg(options::OPT_fsycl)) { + if (Args.hasArg(options::OPT__SLASH_MDd) || + Args.hasArg(options::OPT__SLASH_MTd)) + CmdArgs.push_back("-defaultlib:sycld.lib"); + else + CmdArgs.push_back("-defaultlib:sycl.lib"); + } for (const auto *A : Args.filtered(options::OPT_foffload_static_lib_EQ)) CmdArgs.push_back( From d5faf83daefcb34730fc2ae945872bc05d2c399a Mon Sep 17 00:00:00 2001 From: Alexander Batashev Date: Thu, 26 Sep 2019 11:26:50 +0300 Subject: [PATCH 3/3] [SYCL] Add tests for MSVC CRT logic Signed-off-by: Alexander Batashev --- clang/test/Driver/sycl-offload.c | 6 ++++ sycl/doc/GetStartedWithSYCLCompiler.md | 1 + sycl/test/CMakeLists.txt | 1 + sycl/test/lit.cfg.py | 1 + sycl/test/lit.site.cfg.py.in | 1 + sycl/test/regression/msvc_crt.cpp | 46 ++++++++++++++++++++++++++ 6 files changed, 56 insertions(+) create mode 100644 sycl/test/regression/msvc_crt.cpp diff --git a/clang/test/Driver/sycl-offload.c b/clang/test/Driver/sycl-offload.c index 192f8070a0810..7fa177f2ba1aa 100644 --- a/clang/test/Driver/sycl-offload.c +++ b/clang/test/Driver/sycl-offload.c @@ -500,6 +500,12 @@ // CHECK-LINK-SYCL: "{{.*}}link{{(.exe)?}}" // CHECK-LINK-SYCL: "-defaultlib:sycl.lib" +/// Check sycld.lib is chosen with /MDd and /MTd +// RUN: %clang_cl -fsycl /MDd %s -o %t -### 2>&1 | FileCheck -check-prefix=CHECK-LINK-SYCL-DEBUG %s +// RUN: %clang_cl -fsycl /MTd %s -o %t -### 2>&1 | FileCheck -check-prefix=CHECK-LINK-SYCL-DEBUG %s +// CHECK-LINK-SYCL-DEBUG: "{{.*}}link{{(.exe)?}}" +// CHECK-LINK-SYCL-DEBUG: "-defaultlib:sycld.lib" + /// ########################################################################### /// test behaviors of -foffload-static-lib= diff --git a/sycl/doc/GetStartedWithSYCLCompiler.md b/sycl/doc/GetStartedWithSYCLCompiler.md index 0e13e0f196e4b..8f62ba286d63a 100644 --- a/sycl/doc/GetStartedWithSYCLCompiler.md +++ b/sycl/doc/GetStartedWithSYCLCompiler.md @@ -362,6 +362,7 @@ int main() { translation units. - SYCL host device is not fully supported. - SYCL works only with OpenCL implementations supporting out-of-order queues. +- On Windows linking SYCL applications with `/MTd` flag is known to cause crashes. # Find More diff --git a/sycl/test/CMakeLists.txt b/sycl/test/CMakeLists.txt index e9c161793c837..2bff5cc509ea5 100644 --- a/sycl/test/CMakeLists.txt +++ b/sycl/test/CMakeLists.txt @@ -3,6 +3,7 @@ set(LLVM_BUILD_BINARY_DIRS "${LLVM_BINARY_DIR}/bin/") set(LLVM_TOOLS_DIR "${LLVM_BINARY_DIR}/bin/") set(CLANG_IN_BUILD "${LLVM_BINARY_DIR}/bin/clang") set(CLANGXX_IN_BUILD "${LLVM_BINARY_DIR}/bin/clang++") +set(CLANGCL_IN_BUILD "${LLVM_BINARY_DIR}/bin/clang-cl") get_target_property(SYCL_BINARY_DIR sycl-toolchain BINARY_DIR) get_target_property(SYCL_SOURCE_DIR sycl-toolchain SOURCE_DIR) diff --git a/sycl/test/lit.cfg.py b/sycl/test/lit.cfg.py index 2a4c1e28ebd44..f190915a63993 100644 --- a/sycl/test/lit.cfg.py +++ b/sycl/test/lit.cfg.py @@ -58,6 +58,7 @@ config.substitutions.append( ('%clang_cc1', ' ' + config.clang + ' -cc1 ') ) config.substitutions.append( ('%clangxx', ' ' + config.clangxx + ' -I'+config.opencl_include ) ) +config.substitutions.append( ('%clang_cl', ' ' + config.clang_cl + ' /I '+config.opencl_include ) ) config.substitutions.append( ('%clang', ' ' + config.clang + ' -I'+config.opencl_include ) ) config.substitutions.append( ('%llvm_build_libs_dir', config.llvm_build_libs_dir ) ) config.substitutions.append( ('%opencl_include', config.opencl_include ) ) diff --git a/sycl/test/lit.site.cfg.py.in b/sycl/test/lit.site.cfg.py.in index 6156fc2670c2b..6f084b6428a96 100644 --- a/sycl/test/lit.site.cfg.py.in +++ b/sycl/test/lit.site.cfg.py.in @@ -4,6 +4,7 @@ import sys config.clang = "@CLANG_IN_BUILD@" config.clangxx = "@CLANGXX_IN_BUILD@" +config.clang_cl = "@CLANGCL_IN_BUILD@" config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@" config.llvm_build_libs_dir = "@LLVM_BUILD_LIBRARY_DIRS@" diff --git a/sycl/test/regression/msvc_crt.cpp b/sycl/test/regression/msvc_crt.cpp new file mode 100644 index 0000000000000..78903b52ccdb0 --- /dev/null +++ b/sycl/test/regression/msvc_crt.cpp @@ -0,0 +1,46 @@ +// RUN: %clang_cl -fsycl /MD -o %t1.exe %s +// RUN: %CPU_RUN_PLACEHOLDER %t1.exe +// RUN: %clang_cl -fsycl /MDd -o %t2.exe %s +// RUN: %CPU_RUN_PLACEHOLDER %t2.exe +// RUN: %clang_cl -fsycl /MT -o %t3.exe %s +// RUN: %CPU_RUN_PLACEHOLDER %t3.exe +// REQUIRES: system-windows +//==-------------- msvc_crt.cpp - SYCL MSVC CRT test -----------------------==// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// MSVC provides two different incompatible variants of CRT: debug and release. +// This test checks if clang driver is able to handle this properly. + +#include + +using namespace cl::sycl; + +int main() { + int data[] = {0, 0, 0}; + + { + buffer b(data, range<1>(3), {property::buffer::use_host_ptr()}); + queue q; + q.submit([&](handler &cgh) { + auto B = b.get_access(cgh); + cgh.parallel_for(range<1>(3), [=](id<1> idx) { + B[idx] = 1; + }); + }); + } + + bool isSuccess = true; + + for (int i = 0; i < 3; i++) + if (data[i] != 1) isSuccess = false; + + if (!isSuccess) + return -1; + + return 0; +}