diff --git a/.github/workflows/generate-coverage.yaml b/.github/workflows/generate-coverage.yaml index 82aaa83319..8094bb1027 100644 --- a/.github/workflows/generate-coverage.yaml +++ b/.github/workflows/generate-coverage.yaml @@ -85,26 +85,7 @@ jobs: shell: bash -l {0} run: | source /opt/intel/oneapi/setvars.sh - export _SAVED_PATH=${PATH} - export PATH=$(dirname $(dirname $(which icx)))/bin-llvm:${PATH} - python setup.py develop -- \ - -G "Ninja" \ - -DCMAKE_BUILD_TYPE=Debug \ - -DCMAKE_C_COMPILER:PATH=icx \ - -DCMAKE_CXX_COMPILER:PATH=icpx \ - -DDPCTL_ENABLE_LO_PROGRAM_CREATION=ON \ - -DDPCTL_GENERATE_COVERAGE=ON \ - -DDPCTL_BUILD_CAPI_TESTS=ON \ - -DDPCTL_COVERAGE_REPORT_OUTPUT_DIR=$(pwd) - pushd $(find _skbuild -name cmake-build) - cmake --build . --target lcov-genhtml || exit 1 - popd - export PATH=${_SAVED_PATH} - unset _SAVED_PATH - python -c "import dpctl; print(dpctl.__version__); dpctl.lsplatform()" || exit 1 - pytest -q -ra --disable-warnings --cov-config pyproject.toml --cov dpctl \ - --cov-report term-missing --pyargs dpctl -vv \ - --ignore=dpctl/tensor/libtensor/tests + python scripts/gen_coverage.py - name: Install coverall dependencies shell: bash -l {0} @@ -115,8 +96,21 @@ jobs: - name: Upload coverage data to coveralls.io shell: bash -l {0} run: | - coveralls-lcov -v -n $(find _skbuild -name dpctl.lcov) > dpctl-c-api-coverage.json - coveralls --service=github --merge=dpctl-c-api-coverage.json + coveralls-lcov -v -n \ + $(find _skbuild -name dpctl.lcov) > dpctl-c-api-coverage.json + coveralls-lcov -v -n \ + $(find . -name dpctl_pytest.lcov) > pytest-dpctl-c-api-coverage.json + # merge json files + python -c "import json; \ + fh1 = open('dpctl-c-api-coverage.json', 'r'); \ + f1 = json.load(fh1); fh1.close(); \ + fh2 = open('pytest-dpctl-c-api-coverage.json', 'r'); \ + f2 = json.load(fh2); fh2.close(); \ + f3 = {'source_files': f1['source_files'] + f2['source_files']}; \ + fh3 = open('combined-dpctl-c-api-coverage.json', 'w'); \ + json.dump(f3, fh3); fh3.close()" || exit 1 + # merge combined file with coverage data and upload + coveralls --service=github --merge=combined-dpctl-c-api-coverage.json env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} COVERALLS_PARALLEL: true diff --git a/.github/workflows/generate-docs.yml b/.github/workflows/generate-docs.yml index 9581458ab7..63b3942033 100644 --- a/.github/workflows/generate-docs.yml +++ b/.github/workflows/generate-docs.yml @@ -68,7 +68,6 @@ jobs: -DCMAKE_BUILD_TYPE=Debug \ -DCMAKE_C_COMPILER:PATH=icx \ -DCMAKE_CXX_COMPILER:PATH=icpx \ - -DDPCTL_ENABLE_LO_PROGRAM_CREATION=ON \ -DDPCTL_GENERATE_DOCS=ON \ -DDPCTL_ENABLE_DOXYREST=ON \ -DDoxyrest_DIR=`pwd`/doxyrest-2.1.2-linux-amd64 diff --git a/.github/workflows/os-llvm-sycl-build.yml b/.github/workflows/os-llvm-sycl-build.yml index a9d4fa1814..6f84bb1004 100644 --- a/.github/workflows/os-llvm-sycl-build.yml +++ b/.github/workflows/os-llvm-sycl-build.yml @@ -97,6 +97,6 @@ jobs: export OCL_ICD_FILENAMES=libintelocl.so:libintelocl_emu.so clang++ --version sycl-ls - python setup.py develop -- -G Ninja -DCMAKE_C_COMPILER:PATH=clang -DCMAKE_CXX_COMPILER:PATH=clang++ -DDPCTL_ENABLE_LO_PROGRAM_CREATION=ON -DDPCTL_DPCPP_HOME_DIR=$(dirname $(dirname $(which clang))) -DDPCTL_DPCPP_FROM_ONEAPI=OFF + python setup.py develop -- -G Ninja -DCMAKE_C_COMPILER:PATH=clang -DCMAKE_CXX_COMPILER:PATH=clang++ python -c "import dpctl; dpctl.lsplatform()" || exit 1 SYCL_ENABLE_HOST_DEVICE=1 python -m pytest -v dpctl/tests diff --git a/CMakeLists.txt b/CMakeLists.txt index bfaf2d2396..51959f2bc2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,6 +8,12 @@ project(dpctl set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED True) +# Option to generate code coverage report using llvm-cov and lcov. +option(DPCTL_GENERATE_COVERAGE + "Build dpctl with coverage instrumentation" + OFF +) + find_package(IntelDPCPP REQUIRED PATHS ${CMAKE_SOURCE_DIR}/cmake NO_DEFAULT_PATH) add_subdirectory(libsyclinterface) diff --git a/conda-recipe/bld.bat b/conda-recipe/bld.bat index 9d6dde519f..9cf6c78466 100644 --- a/conda-recipe/bld.bat +++ b/conda-recipe/bld.bat @@ -4,7 +4,7 @@ set "LIB=%BUILD_PREFIX%\Library\lib;%BUILD_PREFIX%\compiler\lib;%LIB%" set "INCLUDE=%BUILD_PREFIX%\include;%INCLUDE%" "%PYTHON%" setup.py clean --all -set "SKBUILD_ARGS=-- -G Ninja -DDPCTL_DPCPP_HOME_DIR=%BUILD_PREFIX%\Library -DCMAKE_C_COMPILER:PATH=icx -DCMAKE_CXX_COMPILER:PATH=icx -DDPCTL_ENABLE_LO_PROGRAM_CREATION=ON" +set "SKBUILD_ARGS=-- -G Ninja -DCMAKE_C_COMPILER:PATH=icx -DCMAKE_CXX_COMPILER:PATH=icx" set "SYCL_INCLUDE_DIR_HINT=%BUILD_PREFIX%\Library\lib\clang\14.0.0" set "PLATFORM_DIR=%PREFIX%\Library\share\cmake-3.22\Modules\Platform" diff --git a/conda-recipe/build.sh b/conda-recipe/build.sh index 5bc85e861e..7b533bee36 100755 --- a/conda-recipe/build.sh +++ b/conda-recipe/build.sh @@ -7,7 +7,7 @@ export LDFLAGS="$LDFLAGS -Wl,-rpath,$PREFIX/lib" ${PYTHON} setup.py clean --all export CMAKE_GENERATOR="Ninja" -SKBUILD_ARGS="-- -DCMAKE_C_COMPILER:PATH=icx -DCMAKE_CXX_COMPILER:PATH=icpx -DDPCTL_ENABLE_LO_PROGRAM_CREATION=ON -DDPCTL_DPCPP_HOME_DIR=${BUILD_PREFIX}" +SKBUILD_ARGS="-- -DCMAKE_C_COMPILER:PATH=icx -DCMAKE_CXX_COMPILER:PATH=icpx" echo "${PYTHON} setup.py install ${SKBUILD_ARGS}" # Workaround for: diff --git a/docs/docfiles/user_guides/QuickStart.rst b/docs/docfiles/user_guides/QuickStart.rst index 94b4953ca3..0aa3034eec 100644 --- a/docs/docfiles/user_guides/QuickStart.rst +++ b/docs/docfiles/user_guides/QuickStart.rst @@ -152,13 +152,13 @@ Once the prerequisites are installed, building using ``scikit-build`` involves t .. code-block:: bash - python setup.py install -- -G Ninja -DCMAKE_C_COMPILER:PATH=icx -DCMAKE_CXX_COMPILER:PATH=icpx -DDPCTL_ENABLE_LO_PROGRAM_CREATION=ON + python setup.py install -- -G Ninja -DCMAKE_C_COMPILER:PATH=icx -DCMAKE_CXX_COMPILER:PATH=icpx , and to develop: .. code-block:: bash - python setup.py develop -G Ninja -DCMAKE_C_COMPILER:PATH=icx -DCMAKE_CXX_COMPILER:PATH=icpx -DDPCTL_ENABLE_LO_PROGRAM_CREATION=ON + python setup.py develop -G Ninja -DCMAKE_C_COMPILER:PATH=icx -DCMAKE_CXX_COMPILER:PATH=icpx On Windows, use ``icx`` for both C and CXX compilers. @@ -166,7 +166,7 @@ Developing on Linux can also be done using driver script: .. code-block:: bash - python scripts/build_locally.py --oneapi + python scripts/build_locally.py Building using custom dpcpp @@ -180,13 +180,13 @@ Following steps in `Build and install with scikit-build`_ use command line optio .. code-block:: bash - python setup.py develop -- -G Ninja -DCMAKE_C_COMPILER:PATH=clang -DCMAKE_CXX_COMPILER:PATH=clang++ -DDPCTL_ENABLE_LO_PROGRAM_CREATION=ONE -DDPCTL_DPCPP_HOME_DIR=${DPCPP_ROOT}/llvm/build -DDPCTL_DPCPP_FROM_ONEAPI=OFF + python setup.py develop -- -G Ninja -DCMAKE_C_COMPILER:PATH=$(which clang) -DCMAKE_CXX_COMPILER:PATH=$(which clang++) Alterantively, the driver script can be used .. code-block:: bash - python scripts/build_locally.py --c-compiler=clang --cxx-compiler=clang++ --compiler-root=${DPCPP_ROOT}/llvm/build + python scripts/build_locally.py --c-compiler=$(which clang) --cxx-compiler=$(which clang++) Available options and their descriptions can be retrieved using option :code:`--help`. @@ -264,7 +264,6 @@ library. -DDPCPP_INSTALL_DIR=${DPCPP_ROOT} \ -DCMAKE_C_COMPILER:PATH=${DPCPP_ROOT}/bin/icx \ -DCMAKE_CXX_COMPILER:PATH=${DPCPP_ROOT}/bin/dpcpp \ - -DDPCTL_ENABLE_LO_PROGRAM_CREATION=ON \ -DDPCTL_BUILD_CAPI_TESTS=ON \ .. diff --git a/libsyclinterface/CMakeLists.txt b/libsyclinterface/CMakeLists.txt index e63c992acb..695975f7ae 100644 --- a/libsyclinterface/CMakeLists.txt +++ b/libsyclinterface/CMakeLists.txt @@ -7,25 +7,22 @@ project( # Load our CMake modules to search for DPCPP and Level Zero set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/") + find_package(Git REQUIRED) -option(DPCTL_DPCPP_HOME_DIR - "The installation home for the DPC++ toolchain compiler." - OFF -) -option(DPCTL_DPCPP_FROM_ONEAPI - "Indicates whether DPCTL_DPCPP_HOME_DIR points to a oneAPI installation." - ON -) +if(NOT DEFINED IntelDPCPP_FOUND OR NOT IntelDPCPP_FOUND) + find_package(IntelDPCPP REQUIRED) +endif() + # Option to turn on support for creating Level Zero interoperability programs # from a SPIR-V binary file. -option(DPCTL_ENABLE_LO_PROGRAM_CREATION +option(DPCTL_ENABLE_L0_PROGRAM_CREATION "Enable Level Zero Program creation from SPIR-V" - OFF + ON ) # Option to generate code coverage report using llvm-cov and lcov. option(DPCTL_GENERATE_COVERAGE - "Build dpctl C API with coverage instrumentation instrumentation" + "Build dpctl C API with coverage instrumentation" OFF ) # Option to output html coverage report at a specific location. @@ -45,14 +42,15 @@ option(DPCTL_ENABLE_GLOG ) # Minimum version requirement only when oneAPI dpcpp is used. +find_package(IntelDPCPP REQUIRED) if(DPCTL_DPCPP_FROM_ONEAPI) find_package(IntelSycl 2021.3.0 REQUIRED) else() find_package(IntelSycl REQUIRED) endif() -if(DPCTL_ENABLE_LO_PROGRAM_CREATION) - set(DPCTL_ENABLE_LO_PROGRAM_CREATION 1) +if(DPCTL_ENABLE_L0_PROGRAM_CREATION) + set(DPCTL_ENABLE_L0_PROGRAM_CREATION 1) include(GetLevelZeroHeaders) get_level_zero_headers() if (UNIX) @@ -156,12 +154,34 @@ file(GLOB_RECURSE helper_sources ${CMAKE_CURRENT_SOURCE_DIR}/helper/source/*.cpp ) +# Enable code coverage related settings +if(DPCTL_GENERATE_COVERAGE) + include(SetupCoverage) + setup_coverage_generation() + + # Turn on DPCTL_BUILD_CAPI_TESTS as building tests is needed to generate + # coverage reports. + set(DPCTL_BUILD_CAPI_TESTS "ON") + if(DPCTL_COVERAGE_REPORT_OUTPUT_DIR) + set(COVERAGE_OUTPUT_DIR ${DPCTL_COVERAGE_REPORT_OUTPUT_DIR}) + else() + set(COVERAGE_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}) + endif() + message(STATUS "Coverage reports to be saved at ${COVERAGE_OUTPUT_DIR}") +endif() + add_library(DPCTLSyclInterface SHARED ${sources} ${helper_sources} ) +if(DPCTL_GENERATE_COVERAGE) + target_link_options(DPCTLSyclInterface + PRIVATE -fprofile-instr-generate -fcoverage-mapping + ) +endif() + target_include_directories(DPCTLSyclInterface PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include/ @@ -169,7 +189,7 @@ target_include_directories(DPCTLSyclInterface ${CMAKE_CURRENT_SOURCE_DIR}/include/Config PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/helper/include/ - ${IntelSycl_SYCL_INCLUDE_DIR} + ${SYCL_INCLUDE_DIR} ) target_link_libraries(DPCTLSyclInterface PRIVATE ${IntelSycl_SYCL_LIBRARY} @@ -201,7 +221,7 @@ set_target_properties(DPCTLSyclInterface SOVERSION ${VERSION_MAJOR} ) -if(DPCTL_ENABLE_LO_PROGRAM_CREATION) +if(DPCTL_ENABLE_L0_PROGRAM_CREATION) target_include_directories(DPCTLSyclInterface PRIVATE ${LEVEL_ZERO_INCLUDE_DIR} @@ -247,25 +267,6 @@ install( DESTINATION ${_include_destination}/Config ) -# Enable code coverage related settings -if(DPCTL_GENERATE_COVERAGE) - # check if lcov is available - find_package(Lcov REQUIRED) - # check if llvm-cov version 11 is available - find_package(LLVMCov 11 REQUIRED) - # check if llvm-profdata is available - find_package(LLVMProfdata REQUIRED) - # Turn on DPCTL_BUILD_CAPI_TESTS as building tests is needed to generate - # coverage reports. - set(DPCTL_BUILD_CAPI_TESTS "ON") - if(DPCTL_COVERAGE_REPORT_OUTPUT_DIR) - set(COVERAGE_OUTPUT_DIR ${DPCTL_COVERAGE_REPORT_OUTPUT_DIR}) - else() - set(COVERAGE_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}) - endif() - message(STATUS "Coverage reports to be saved at ${COVERAGE_OUTPUT_DIR}") -endif() - # Add sub-directory to build the dpctl C API test cases if(DPCTL_BUILD_CAPI_TESTS) add_subdirectory(tests) diff --git a/libsyclinterface/cmake/modules/FindIntelSycl.cmake b/libsyclinterface/cmake/modules/FindIntelSycl.cmake index 639e5c4328..d6d1e683a3 100644 --- a/libsyclinterface/cmake/modules/FindIntelSycl.cmake +++ b/libsyclinterface/cmake/modules/FindIntelSycl.cmake @@ -33,34 +33,7 @@ # IntelSycl_OPENCL_LIBRARY include(FindPackageHandleStandardArgs) - -# Check if a specific DPC++ installation directory was provided then set -# IntelSycl_ROOT to that path. -if(DPCTL_DPCPP_HOME_DIR) - set(IntelSycl_ROOT ${DPCTL_DPCPP_HOME_DIR}) - if(NOT DPCTL_DPCPP_FROM_ONEAPI) - message(STATUS - "Not using standard oneAPI installation, but IntelSycl at " - ${IntelSycl_ROOT} - ) - endif() -# If DPC++ installation was not specified, check for ONEAPI_ROOT -elseif(DEFINED ENV{ONEAPI_ROOT}) - if(CMAKE_SYSTEM_NAME STREQUAL "Windows") - set(IntelSycl_ROOT $ENV{ONEAPI_ROOT}/compiler/latest/windows) - elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") - set(IntelSycl_ROOT $ENV{ONEAPI_ROOT}/compiler/latest/linux) - else() - message(FATAL_ERROR "Unsupported system.") - endif() -else() - message(FATAL_ERROR - "Could not locate a DPC++ installation. Either pass the path to a " - "custom location using DPCTL_DPCPP_HOME_DIR or set the " - " ONEAPI_ROOT environment variable." - ) - return() -endif() +find_package(IntelDPCPP REQUIRED) # We will extract the version information from the compiler set(clangxx_cmd "${CMAKE_CXX_COMPILER}") @@ -96,13 +69,13 @@ if(${clangxx_result} MATCHES "0") list(GET IntelSycl_VERSION_LIST1 0 IntelSycl_VERSION_MAJOR) list(GET IntelSycl_VERSION_LIST1 1 IntelSycl_VERSION_MINOR) list(GET IntelSycl_VERSION_LIST1 2 IntelSycl_VERSION_PATCH) - set(IntelSycl_INCLUDE_DIR ${IntelSycl_ROOT}/include) - set(IntelSycl_SYCL_INCLUDE_DIR ${IntelSycl_ROOT}/include/sycl) - set(IntelSycl_LIBRARY_DIR ${IntelSycl_ROOT}/lib) - if(CMAKE_SYSTEM_NAME STREQUAL "Windows") + set(IntelSycl_INCLUDE_DIR ${SYCL_INCLUDE_DIR}) + set(IntelSycl_SYCL_INCLUDE_DIR ${SYCL_INCLUDE_DIR}/sycl) + set(IntelSycl_LIBRARY_DIR ${SYCL_LIBRARY_DIR}) + if("x${CMAKE_SYSTEM_NAME}" STREQUAL "xWindows") set(IntelSycl_SYCL_LIBRARY ${IntelSycl_LIBRARY_DIR}/sycl.lib) set(IntelSycl_OPENCL_LIBRARY ${IntelSycl_LIBRARY_DIR}/OpenCL.lib) - elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") + elseif("x${CMAKE_SYSTEM_NAME}" STREQUAL "xLinux") set(IntelSycl_SYCL_LIBRARY ${IntelSycl_LIBRARY_DIR}/libsycl.so) set(IntelSycl_OPENCL_LIBRARY ${IntelSycl_LIBRARY_DIR}/libOpenCL.so) endif() @@ -125,7 +98,6 @@ else() endif() find_package_handle_standard_args(IntelSycl DEFAULT_MSG - IntelSycl_ROOT IntelSycl_FOUND IntelSycl_VERSION IntelSycl_INCLUDE_DIR diff --git a/libsyclinterface/cmake/modules/SetupCoverage.cmake b/libsyclinterface/cmake/modules/SetupCoverage.cmake new file mode 100644 index 0000000000..e26f54102c --- /dev/null +++ b/libsyclinterface/cmake/modules/SetupCoverage.cmake @@ -0,0 +1,22 @@ + +function(setup_coverage_generation) + # check if lcov is available + find_package(Lcov REQUIRED) + # check if llvm-cov version 11 is available + find_package(LLVMCov 11 REQUIRED) + # check if llvm-profdata is available + find_package(LLVMProfdata REQUIRED) + + string(CONCAT PROFILE_FLAGS + "-fprofile-instr-generate " + "-fcoverage-mapping " + "-fno-sycl-use-footer " + "-DDPCTL_COVERAGE " + ) + + # Add profiling flags + set(CMAKE_CXX_FLAGS + "${CMAKE_CXX_FLAGS} ${PROFILE_FLAGS}" + PARENT_SCOPE + ) +endfunction(setup_coverage_generation) diff --git a/libsyclinterface/dbg_build.sh b/libsyclinterface/dbg_build.sh index 5b91001240..eaa1a02785 100755 --- a/libsyclinterface/dbg_build.sh +++ b/libsyclinterface/dbg_build.sh @@ -13,7 +13,7 @@ cmake \ -DCMAKE_CXX_COMPILER=dpcpp \ -DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} \ -DCMAKE_PREFIX_PATH=${INSTALL_PREFIX} \ - -DDPCTL_ENABLE_LO_PROGRAM_CREATION=ON \ + -DDPCTL_ENABLE_L0_PROGRAM_CREATION=ON \ -DDPCTL_BUILD_CAPI_TESTS=ON \ -DDPCTL_GENERATE_COVERAGE=ON \ .. diff --git a/libsyclinterface/dbg_build_custom.sh b/libsyclinterface/dbg_build_custom.sh index 5c8f6ccc94..ad738a0c8a 100755 --- a/libsyclinterface/dbg_build_custom.sh +++ b/libsyclinterface/dbg_build_custom.sh @@ -17,7 +17,7 @@ cmake \ -DCMAKE_PREFIX_PATH=${INSTALL_PREFIX} \ -DDPCTL_CUSTOM_DPCPP_INSTALL_DIR=${DPCPP_HOME} \ -DCMAKE_LINKER:PATH=${DPCPP_HOME}/bin/lld \ - -DDPCTL_ENABLE_LO_PROGRAM_CREATION=${USE_LO_HEADERS} \ + -DDPCTL_ENABLE_L0_PROGRAM_CREATION=${USE_LO_HEADERS} \ -DDPCTL_BUILD_CAPI_TESTS=ON \ -DDPCTL_GENERATE_COVERAGE=ON \ .. diff --git a/libsyclinterface/include/Config/dpctl_config.h.in b/libsyclinterface/include/Config/dpctl_config.h.in index a35197667a..c50b22db87 100644 --- a/libsyclinterface/include/Config/dpctl_config.h.in +++ b/libsyclinterface/include/Config/dpctl_config.h.in @@ -26,7 +26,7 @@ #pragma once /* Defined when dpctl was built with level zero program creation enabled. */ -#cmakedefine DPCTL_ENABLE_LO_PROGRAM_CREATION @DPCTL_ENABLE_LO_PROGRAM_CREATION@ +#cmakedefine DPCTL_ENABLE_L0_PROGRAM_CREATION @DPCTL_ENABLE_L0_PROGRAM_CREATION@ /* The DPCPP version used to build dpctl */ #define DPCTL_DPCPP_VERSION "@IntelSycl_VERSION@" diff --git a/libsyclinterface/source/dpctl_sycl_program_interface.cpp b/libsyclinterface/source/dpctl_sycl_program_interface.cpp index f5369f94ae..28e7edbfa9 100644 --- a/libsyclinterface/source/dpctl_sycl_program_interface.cpp +++ b/libsyclinterface/source/dpctl_sycl_program_interface.cpp @@ -38,7 +38,7 @@ #include #include -#ifdef DPCTL_ENABLE_LO_PROGRAM_CREATION +#ifdef DPCTL_ENABLE_L0_PROGRAM_CREATION #include "dpctl_dynamic_lib_helper.h" // Note: include ze_api.h before level_zero.hpp. Make sure clang-format does // not reorder the includes. @@ -52,7 +52,7 @@ using namespace cl::sycl; namespace { -#ifdef DPCTL_ENABLE_LO_PROGRAM_CREATION +#ifdef DPCTL_ENABLE_L0_PROGRAM_CREATION #ifdef __linux__ static const char *zeLoaderName = DPCTL_LIBZE_LOADER_FILENAME; @@ -72,7 +72,7 @@ typedef ze_result_t (*zeModuleCreateFT)(ze_context_handle_t, const char *zeModuleCreateFuncName = "zeModuleCreate"; -#endif // #ifdef DPCTL_ENABLE_LO_PROGRAM_CREATION +#endif // #ifdef DPCTL_ENABLE_L0_PROGRAM_CREATION DEFINE_SIMPLE_CONVERSION_FUNCTIONS(context, DPCTLSyclContextRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(program, DPCTLSyclProgramRef) @@ -125,7 +125,7 @@ createOpenCLInterOpProgram(const context &SyclCtx, } } -#ifdef DPCTL_ENABLE_LO_PROGRAM_CREATION +#ifdef DPCTL_ENABLE_L0_PROGRAM_CREATION zeModuleCreateFT getZeModuleCreateFn() { @@ -200,7 +200,7 @@ createLevelZeroInterOpProgram(const context &SyclCtx, return nullptr; } } -#endif /* #ifdef DPCTL_ENABLE_LO_PROGRAM_CREATION */ +#endif /* #ifdef DPCTL_ENABLE_L0_PROGRAM_CREATION */ } /* end of anonymous namespace */ @@ -226,7 +226,7 @@ DPCTLProgram_CreateFromSpirv(__dpctl_keep const DPCTLSyclContextRef CtxRef, Pref = createOpenCLInterOpProgram(*SyclCtx, IL, length, CompileOpts); break; case backend::ext_oneapi_level_zero: -#ifdef DPCTL_ENABLE_LO_PROGRAM_CREATION +#ifdef DPCTL_ENABLE_L0_PROGRAM_CREATION Pref = createLevelZeroInterOpProgram(*SyclCtx, IL, length, CompileOpts); #endif break; diff --git a/libsyclinterface/tests/CMakeLists.txt b/libsyclinterface/tests/CMakeLists.txt index 36037b1d4b..c0d9d1a8e6 100644 --- a/libsyclinterface/tests/CMakeLists.txt +++ b/libsyclinterface/tests/CMakeLists.txt @@ -25,30 +25,12 @@ if(DPCTL_GENERATE_COVERAGE) file(GLOB_RECURSE sources ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp ) - file(GLOB_RECURSE - dpctl_sources ${CMAKE_CURRENT_SOURCE_DIR}/../source/*.cpp - ) - file(GLOB_RECURSE - helper_sources ${CMAKE_CURRENT_SOURCE_DIR}/../helper/source/*.cpp - ) - # Exclude from sources - list(REMOVE_ITEM - dpctl_sources - "${CMAKE_CURRENT_SOURCE_DIR}/../source/dpctl_vector_templ.cpp" - ) - - # Add profiling flags - set(CMAKE_CXX_FLAGS - "${CMAKE_CXX_FLAGS} -fprofile-instr-generate -fcoverage-mapping -fno-sycl-use-footer -DDPCTL_COVERAGE" - ) # Add all dpctl sources into a single executable so that we can run coverage # analysis and generate a report. add_executable(dpctl_c_api_tests EXCLUDE_FROM_ALL ${sources} - ${dpctl_sources} - ${helper_sources} ) target_include_directories(dpctl_c_api_tests PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../helper/include" @@ -57,9 +39,11 @@ if(DPCTL_GENERATE_COVERAGE) target_link_libraries(dpctl_c_api_tests ${CMAKE_THREAD_LIBS_INIT} GTest::GTest + DPCTLSyclInterface ${IntelSycl_OPENCL_LIBRARY} ${CMAKE_DL_LIBS} ) + set(object_arg "-object;") add_custom_target(llvm-cov COMMAND ${CMAKE_COMMAND} -E env DPCTL_VERBOSITY=warning ${CMAKE_CURRENT_BINARY_DIR}/dpctl_c_api_tests COMMAND ${LLVMProfdata_EXE} @@ -69,28 +53,33 @@ if(DPCTL_GENERATE_COVERAGE) dpctl.profdata COMMAND ${LLVMCov_EXE} report - ${CMAKE_CURRENT_BINARY_DIR}/dpctl_c_api_tests -instr-profile=dpctl.profdata - ${dpctl_sources} - ${helper_sources} + "${object_arg}$,;${object_arg}>" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - DEPENDS dpctl_c_api_tests + COMMAND_EXPAND_LISTS + DEPENDS dpctl_c_api_tests ) add_custom_target(lcov-genhtml + COMMAND ${CMAKE_COMMAND} -E env DPCTL_VERBOSITY=warning ${CMAKE_CURRENT_BINARY_DIR}/dpctl_c_api_tests + COMMAND ${LLVMProfdata_EXE} + merge + -sparse default.profraw + -o + dpctl.profdata COMMAND ${LLVMCov_EXE} export -format=lcov - ${CMAKE_CURRENT_BINARY_DIR}/dpctl_c_api_tests -instr-profile=dpctl.profdata - ${dpctl_sources} - ${helper_sources} > dpctl.lcov + "${object_arg}$,;${object_arg}>" + > dpctl.lcov COMMAND ${GENHTML_EXE} ${CMAKE_CURRENT_BINARY_DIR}/dpctl.lcov --output-directory ${COVERAGE_OUTPUT_DIR}/dpctl-c-api-coverage WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - DEPENDS llvm-cov + COMMAND_EXPAND_LISTS + DEPENDS dpctl_c_api_tests ) else() file(GLOB_RECURSE sources ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) @@ -99,7 +88,7 @@ else() ${CMAKE_THREAD_LIBS_INIT} GTest::GTest DPCTLSyclInterface - ${LEVEL_ZERO_LIBRARY} + ${IntelSycl_OPENCL_LIBRARY} ) endif() diff --git a/libsyclinterface/tests/test_sycl_program_interface.cpp b/libsyclinterface/tests/test_sycl_program_interface.cpp index 13c4468a30..9824e09088 100644 --- a/libsyclinterface/tests/test_sycl_program_interface.cpp +++ b/libsyclinterface/tests/test_sycl_program_interface.cpp @@ -230,7 +230,7 @@ INSTANTIATE_TEST_SUITE_P(ProgramCreationFromSpriv, "opencl:gpu", "opencl:cpu", "opencl:gpu:0", -#ifdef DPCTL_ENABLE_LO_PROGRAM_CREATION +#ifdef DPCTL_ENABLE_L0_PROGRAM_CREATION "level_zero", "level_zero:gpu", #endif diff --git a/scripts/build_backend.py b/scripts/build_backend.py deleted file mode 100644 index ecbcffd2fd..0000000000 --- a/scripts/build_backend.py +++ /dev/null @@ -1,231 +0,0 @@ -# Data Parallel Control (dpctl) -# -# Copyright 2020-2021 Intel Corporation -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Invokes CMake build dpctl's C API library. -""" - - -def build_backend( - l0_support=False, code_coverage=False, glog=False, sycl_compiler_prefix=None -): - import glob - import os - import shutil - import subprocess - import sys - - IS_WIN = False - IS_LIN = False - - if "linux" in sys.platform: - IS_LIN = True - elif sys.platform in ["win32", "cygwin"]: - IS_WIN = True - else: - assert False, sys.platform + " not supported" - - if sycl_compiler_prefix is None: - oneapi_root = os.getenv("ONEAPI_ROOT") - if oneapi_root is None: - raise ValueError("Environment variable ONEAPI_ROOT is not set") - if IS_LIN: - DPCPP_ROOT = os.path.join(oneapi_root, r"compiler/latest/linux") - elif IS_WIN: - DPCPP_ROOT = os.path.join(oneapi_root, r"compiler\latest\windows") - else: - DPCPP_ROOT = os.path.join(sycl_compiler_prefix) - - if not os.path.isdir(DPCPP_ROOT): - raise ValueError( - "SYCL compile prefix {} is not a directry".format(DPCPP_ROOT) - ) - - dpctl_dir = os.getcwd() - build_cmake_dir = os.path.join(dpctl_dir, "build_cmake") - if os.path.exists(build_cmake_dir): - for f in os.listdir(build_cmake_dir): - f_path = os.path.join(build_cmake_dir, f) - if os.path.isdir(f_path): - if (f == "level-zero") and os.path.isdir( - os.path.join(f_path, ".git") - ): - # do not delete Git checkout of level zero headers - pass - else: - shutil.rmtree(f_path) - else: - os.remove(f_path) - else: - os.mkdir(build_cmake_dir) - os.chdir(build_cmake_dir) - - INSTALL_PREFIX = os.path.join(dpctl_dir, "install") - if os.path.exists(INSTALL_PREFIX): - shutil.rmtree(INSTALL_PREFIX) - - backends = os.path.join(dpctl_dir, "libsyclinterface") - - ENABLE_LO_PROGRAM_CREATION = "ON" if l0_support else "OFF" - - if IS_LIN: - if os.path.exists(os.path.join(DPCPP_ROOT, "bin", "dpcpp")): - cmake_compiler_args = [ - "-DDPCTL_DPCPP_HOME_DIR=" + DPCPP_ROOT, - "-DDPCTL_DPCPP_FROM_ONEAPI=ON", - "-DCMAKE_C_COMPILER:PATH=" - + os.path.join(DPCPP_ROOT, "bin", "icx"), - "-DCMAKE_CXX_COMPILER:PATH=" - + os.path.join(DPCPP_ROOT, "bin", "dpcpp"), - ] - else: - cmake_compiler_args = [ - "-DDPCTL_DPCPP_HOME_DIR=" + DPCPP_ROOT, - "-DDPCTL_DPCPP_FROM_ONEAPI=OFF", - "-DCMAKE_C_COMPILER:PATH=" - + os.path.join(DPCPP_ROOT, "bin", "clang"), - "-DCMAKE_CXX_COMPILER:PATH=" - + os.path.join(DPCPP_ROOT, "bin", "clang++"), - ] - if glog: - cmake_compiler_args.append("-DDPCTL_ENABLE_GLOG=ON") - if code_coverage: - cmake_args = ( - [ - "cmake", - "-DCMAKE_BUILD_TYPE=Debug", - "-DCMAKE_INSTALL_PREFIX=" + INSTALL_PREFIX, - "-DCMAKE_PREFIX_PATH=" + INSTALL_PREFIX, - ] - + cmake_compiler_args - + [ - "-DDPCTL_ENABLE_LO_PROGRAM_CREATION=" - + ENABLE_LO_PROGRAM_CREATION, - "-DDPCTL_BUILD_CAPI_TESTS=ON", - "-DDPCTL_GENERATE_COVERAGE=ON", - "-DDPCTL_COVERAGE_REPORT_OUTPUT_DIR=" + dpctl_dir, - backends, - ] - ) - subprocess.check_call( - cmake_args, stderr=subprocess.STDOUT, shell=False - ) - subprocess.check_call(["make", "V=1", "-j", "4"]) - subprocess.check_call(["make", "install"]) - subprocess.check_call(["make", "lcov-genhtml"]) - else: - cmake_args = ( - [ - "cmake", - "-DCMAKE_BUILD_TYPE=Release", - "-DCMAKE_INSTALL_PREFIX=" + INSTALL_PREFIX, - "-DCMAKE_PREFIX_PATH=" + INSTALL_PREFIX, - ] - + cmake_compiler_args - + [ - "-DDPCTL_ENABLE_LO_PROGRAM_CREATION=" - + ENABLE_LO_PROGRAM_CREATION, - backends, - ] - ) - subprocess.check_call( - cmake_args, stderr=subprocess.STDOUT, shell=False - ) - subprocess.check_call(["make", "V=1", "-j", "4"]) - subprocess.check_call(["make", "install"]) - - os.chdir(dpctl_dir) - for file in glob.glob( - os.path.join(dpctl_dir, "install", "lib", "*.so*") - ): - # Check if the file already exists before copying. The check is - # needed when dealing with symlinks. - if not os.path.exists( - os.path.join(dpctl_dir, "dpctl", os.path.basename(file)) - ): - shutil.copy( - src=file, - dst=os.path.join(dpctl_dir, "dpctl"), - follow_symlinks=False, - ) - elif IS_WIN: - if os.path.exists(os.path.join(DPCPP_ROOT, "bin", "dpcpp.exe")): - cmake_compiler_args = [ - "-DDPCTL_DPCPP_HOME_DIR=" + DPCPP_ROOT, - "-DDPCTL_DPCPP_FROM_ONEAPI=ON", - "-DCMAKE_C_COMPILER:PATH=" - + os.path.join(DPCPP_ROOT, "bin", "icx.exe"), - "-DCMAKE_CXX_COMPILER:PATH=" - + os.path.join(DPCPP_ROOT, "bin", "dpcpp.exe"), - ] - else: - cmake_compiler_args = [ - "-DDPCTL_DPCPP_HOME_DIR=" + DPCPP_ROOT, - "-DDPCTL_DPCPP_FROM_ONEAPI=OFF", - "-DCMAKE_C_COMPILER:PATH=" - + os.path.join(DPCPP_ROOT, "bin", "clang-cl.exe"), - "-DCMAKE_CXX_COMPILER:PATH=" - + os.path.join(DPCPP_ROOT, "bin", "clang++.exe"), - ] - if glog: - cmake_compiler_args.append("-DDPCTL_ENABLE_GLOG=ON") - cmake_args = ( - [ - "cmake", - "-G", - "Ninja", - "-DCMAKE_BUILD_TYPE=Release", - "-DCMAKE_INSTALL_PREFIX=" + INSTALL_PREFIX, - "-DCMAKE_PREFIX_PATH=" + INSTALL_PREFIX, - ] - + cmake_compiler_args - + [ - "-DDPCTL_ENABLE_LO_PROGRAM_CREATION=" - + ENABLE_LO_PROGRAM_CREATION, - backends, - ] - ) - subprocess.check_call(cmake_args, stderr=subprocess.STDOUT, shell=False) - subprocess.check_call(["ninja", "-n"]) - subprocess.check_call(["ninja", "install"]) - - os.chdir(dpctl_dir) - for file in glob.glob( - os.path.join(dpctl_dir, "install", "lib", "*.lib") - ): - shutil.copy(file, os.path.join(dpctl_dir, "dpctl")) - - for file in glob.glob( - os.path.join(dpctl_dir, "install", "bin", "*.dll") - ): - shutil.copy(file, os.path.join(dpctl_dir, "dpctl")) - - include_dir = os.path.join(dpctl_dir, "dpctl", "include") - if os.path.exists(include_dir): - shutil.rmtree(include_dir) - - shutil.copytree( - os.path.join(dpctl_dir, "libsyclinterface", "include"), - os.path.join(include_dir, "syclinterface"), - ) - - for file in glob.glob( - os.path.join(dpctl_dir, "dpctl", "apis", "include", "*.h*") - ): - shutil.copy(file, include_dir) - - -if __name__ == "__main__": - build_backend() diff --git a/scripts/build_locally.py b/scripts/build_locally.py index acd1a4a6a0..0486fe53a9 100644 --- a/scripts/build_locally.py +++ b/scripts/build_locally.py @@ -55,14 +55,9 @@ def run( "-DCMAKE_BUILD_TYPE=" + build_type, "-DCMAKE_C_COMPILER:PATH=" + c_compiler, "-DCMAKE_CXX_COMPILER:PATH=" + cxx_compiler, - "-DDPCTL_ENABLE_LO_PROGRAM_CREATION=" + ("ON" if level_zero else "OFF"), - "-DDPCTL_DPCPP_FROM_ONEAPI:BOOL=" + ("ON" if use_oneapi else "OFF"), + "-DDPCTL_ENABLE_L0_PROGRAM_CREATION=" + ("ON" if level_zero else "OFF"), "-DDPCTL_ENABLE_GLOG:BOOL=" + ("ON" if use_glog else "OFF"), ] - if compiler_root: - cmake_args += [ - "-DDPCTL_DPCPP_HOME_DIR:PATH=" + compiler_root, - ] subprocess.check_call( cmake_args, shell=False, cwd=setup_dir, env=os.environ ) @@ -93,10 +88,16 @@ def run( help="Set the compilation mode to debugging", ) driver.add_argument( - "--compiler-root", type=str, help="Path to compiler home directory" + "--compiler-root", + type=str, + help="Path to compiler home directory", + default=None, ) driver.add_argument( - "--cmake-executable", type=str, help="Path to cmake executable" + "--cmake-executable", + type=str, + help="Path to cmake executable", + default=None, ) driver.add_argument( "--no-level-zero", @@ -112,26 +113,47 @@ def run( ) args = parser.parse_args() - if args.oneapi: + args_to_validate = [ + "c_compiler", + "cxx_compiler", + "compiler_root", + ] + + if args.oneapi or ( + args.c_compiler is None + and args.cxx_compiler is None + and args.compiler_root is None + ): args.c_compiler = "icx" args.cxx_compiler = "icpx" if "linux" in sys.platform else "icx" args.compiler_root = None else: + cr = args.compiler_root + if isinstance(cr, str) and os.path.exists(cr): + if args.c_compiler is None: + args.c_compiler = "icx" + if args.cxx_compiler is None: + args.cxx_compiler = "icpx" if "linux" in sys.platform else "icx" + else: + raise RuntimeError( + "Option 'compiler-root' must be provided when " + "using non-default DPC++ layout." + ) args_to_validate = [ "c_compiler", "cxx_compiler", - "compiler_root", ] for p in args_to_validate: - arg = getattr(args, p, None) - if not isinstance(arg, str): - opt_name = p.replace("_", "-") - raise RuntimeError( - f"Option {opt_name} must be provided is " - "using non-default DPC++ layout" - ) + arg = getattr(args, p) + assert isinstance(arg, str) + if not os.path.exists(arg): + arg2 = os.path.join(cr, arg) + if os.path.exists(arg2): + arg = arg2 + setattr(args, p, arg) if not os.path.exists(arg): - raise RuntimeError(f"Path {arg} must exist") + opt_name = p.replace("_", "-") + raise RuntimeError(f"Option {opt_name} value {arg} must exist.") run( use_oneapi=args.oneapi, diff --git a/scripts/gen_coverage.py b/scripts/gen_coverage.py index 498bf7a534..878e426404 100644 --- a/scripts/gen_coverage.py +++ b/scripts/gen_coverage.py @@ -53,16 +53,11 @@ def run( "-DCMAKE_BUILD_TYPE=Debug", "-DCMAKE_C_COMPILER:PATH=" + c_compiler, "-DCMAKE_CXX_COMPILER:PATH=" + cxx_compiler, - "-DDPCTL_ENABLE_LO_PROGRAM_CREATION=" + ("ON" if level_zero else "OFF"), + "-DDPCTL_ENABLE_L0_PROGRAM_CREATION=" + ("ON" if level_zero else "OFF"), "-DDPCTL_GENERATE_COVERAGE=ON", "-DDPCTL_BUILD_CAPI_TESTS=ON", "-DDPCTL_COVERAGE_REPORT_OUTPUT_DIR=" + setup_dir, - "-DDPCTL_DPCPP_FROM_ONEAPI:BOOL=" + ("ON" if use_oneapi else "OFF"), ] - if compiler_root: - cmake_args += [ - "-DDPCTL_DPCPP_HOME_DIR:PATH=" + compiler_root, - ] env = None if bin_llvm: env = { @@ -84,6 +79,7 @@ def run( ["cmake", "--build", ".", "--target", "lcov-genhtml"], cwd=cmake_build_dir, ) + env["LLVM_PROFILE_FILE"] = "dpctl_pytest.profraw" subprocess.check_call( [ "pytest", @@ -103,8 +99,49 @@ def run( ], cwd=setup_dir, shell=False, + env=env, ) + def find_objects(): + import os + + objects = [] + for root, _, files in os.walk("_skbuild"): + for file in files: + if not file.endswith(".o"): + continue + if os.path.join("libsyclinterface", "tests") in root: + continue + if any(match in root for match in ["libsyclinterface"]): + objects.extend(["-object", os.path.join(root, file)]) + return objects + + objects = find_objects() + instr_profile_fn = "dpctl_pytest.profdata" + # generate instrumentation profile data + subprocess.check_call( + [ + os.path.join(bin_llvm, "llvm-profdata"), + "merge", + "-sparse", + env["LLVM_PROFILE_FILE"], + "-o", + instr_profile_fn, + ] + ) + # export lcov + with open("dpctl_pytest.lcov", "w") as fh: + subprocess.check_call( + [ + os.path.join(bin_llvm, "llvm-cov"), + "export", + "-format=lcov", + "-instr-profile=" + instr_profile_fn, + ] + + objects, + stdout=fh, + ) + if __name__ == "__main__": import argparse diff --git a/scripts/gen_docs.py b/scripts/gen_docs.py index 087bb32230..d833ad0b31 100644 --- a/scripts/gen_docs.py +++ b/scripts/gen_docs.py @@ -52,8 +52,7 @@ def run( "-DCMAKE_BUILD_TYPE=Debug", "-DCMAKE_C_COMPILER:PATH=" + c_compiler, "-DCMAKE_CXX_COMPILER:PATH=" + cxx_compiler, - "-DDPCTL_ENABLE_LO_PROGRAM_CREATION=" + ("ON" if level_zero else "OFF"), - "-DDPCTL_DPCPP_FROM_ONEAPI:BOOL=" + ("ON" if use_oneapi else "OFF"), + "-DDPCTL_ENABLE_L0_PROGRAM_CREATION=" + ("ON" if level_zero else "OFF"), "-DDPCTL_GENERATE_DOCS=ON", ] @@ -61,10 +60,6 @@ def run( cmake_args.append("-DDPCTL_ENABLE_DOXYREST=ON") cmake_args.append("-DDoxyrest_DIR=" + doxyrest_dir) - if compiler_root: - cmake_args += [ - "-DDPCTL_DPCPP_HOME_DIR:PATH=" + compiler_root, - ] env = None if bin_llvm: env = {