Skip to content

Commit fdb5569

Browse files
authored
Cmake improvements and Coverage for C API (#242)
* Cmake build script changes for dpCtl C API. -- Create cmake modules to store logic to search for dpcpp, level zero, llvm-cov, lcov. -- Add new Cmake options to control level zero program creation and code coverage reporting. -- Two new rules llvm-cov and lcov-genhtml to produce code coverage metrics.
1 parent 5853eda commit fdb5569

File tree

10 files changed

+375
-91
lines changed

10 files changed

+375
-91
lines changed

dpctl-capi/CMakeLists.txt

Lines changed: 90 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,39 @@
11
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
2-
project("dpCtl - A lightweight SYCL wrapper for Python")
2+
project("dpCtl C API - A C wrapper for a subset of SYCL")
33

4-
# The function checks is DPCPP_ROOT is valid and points to a dpcpp installation
5-
function (check_for_dpcpp)
6-
string(COMPARE EQUAL "${DPCPP_ROOT}" "" no_dpcpp_root)
7-
if(${no_dpcpp_root})
8-
message(FATAL_ERROR "Set the DPCPP_ROOT argument providing the path to \
9-
a dpcpp installation.")
10-
endif()
11-
12-
if(WIN32)
13-
set (dpcpp_cmd "${DPCPP_ROOT}/bin/dpcpp")
14-
set (dpcpp_arg "--version")
15-
elseif(UNIX)
16-
set (dpcpp_cmd "${DPCPP_ROOT}/bin/dpcpp")
17-
set (dpcpp_arg "--version")
18-
else()
19-
message(FATAL_ERROR "Unsupported system.")
20-
endif()
4+
# Option to turn on support for creating Level Zero interoperability programs
5+
# from a SPIR-V binary file.
6+
option(DPCTL_ENABLE_LO_PROGRAM_CREATION
7+
"Enable Level Zero Program creation from SPIR-V"
8+
OFF
9+
)
10+
# Option to generate code coverage report using llvm-cov and lcov.
11+
option(DPCTL_GENERATE_COVERAGE
12+
"Build dpctl C API with coverage instrumentation instrumentation"
13+
OFF
14+
)
15+
# Option to output html coverage report at a specific location.
16+
option(DPCTL_COVERAGE_REPORT_OUTPUT_DIR
17+
"Save the generated lcov html report to the specified location"
18+
OFF
19+
)
20+
# Option to build the Gtests for dpctl C API
21+
option(DPCTL_BUILD_CAPI_TESTS
22+
"Build dpctl C API google tests"
23+
OFF
24+
)
2125

22-
# Check if dpcpp is available
23-
execute_process(
24-
COMMAND ${dpcpp_cmd} ${dpcpp_arg}
25-
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
26-
RESULT_VARIABLE dpcpp_result
27-
OUTPUT_VARIABLE dpcpp_ver
28-
)
26+
# Load our CMake modules to search for DPCPP and Level Zero
27+
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/modules/")
28+
find_package(DPCPP REQUIRED)
2929

30-
if(${dpcpp_result} MATCHES "0")
31-
string(REPLACE "\n" ";" DPCPP_VERSION_LIST "${dpcpp_ver}")
32-
list(GET DPCPP_VERSION_LIST 0 dpcpp_ver_line)
33-
foreach(X ${DPCPP_VERSION_LIST})
34-
message(STATUS "dpcpp ver[${dpcpp_result}]: ${X}")
35-
endforeach()
36-
else()
37-
message(FATAL_ERROR "DPCPP needed to build dpctl_sycl_interface")
38-
endif()
39-
endfunction()
30+
if(DPCTL_ENABLE_LO_PROGRAM_CREATION)
31+
set(DPCTL_ENABLE_LO_PROGRAM_CREATION 1)
32+
find_package(LevelZero REQUIRED)
33+
endif()
4034

41-
# Check for dpcpp in the specified DPCPP_ROOT
42-
check_for_dpcpp()
35+
configure_file(${CMAKE_SOURCE_DIR}/include/Config/dpctl_config.h.in
36+
${CMAKE_SOURCE_DIR}/include/Config/dpctl_config.h)
4337

4438
if(WIN32)
4539
set(CMAKE_CXX_COMPILER:PATH "${DPCPP_ROOT}/bin/dpcpp")
@@ -54,6 +48,9 @@ if(WIN32)
5448
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${WARNING_FLAGS} -ggdb3 -DDEBUG")
5549
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${WARNING_FLAGS} -ggdb3 -DDEBUG -Qstd=c++17")
5650
elseif(UNIX)
51+
set(CMAKE_CXX_COMPILER:PATH "${DPCPP_ROOT}/bin/dpcpp")
52+
set(CMAKE_C_COMPILER:PATH "${DPCPP_ROOT}/bin/clang")
53+
set(CMAKE_LINKER:PATH "${DPCPP_ROOT}/bin/lld")
5754
set(SDL_FLAGS "-fstack-protector -fstack-protector-all -fpic -fPIC -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -fno-strict-overflow -fno-delete-null-pointer-checks")
5855
set(WARNING_FLAGS "-Wall -Wextra -Winit-self -Wunused-function -Wuninitialized -Wmissing-declarations -fdiagnostics-color=auto")
5956
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS} ${SDL_FLAGS}")
@@ -80,30 +77,32 @@ add_library(
8077
helper/source/dpctl_utils_helper.cpp
8178
)
8279

83-
# Install DPCTLSyclInterface
84-
target_include_directories(
85-
DPCTLSyclInterface
86-
PRIVATE
87-
${CMAKE_SOURCE_DIR}/include/
88-
${CMAKE_SOURCE_DIR}/helper/include/
80+
target_include_directories(DPCTLSyclInterface
81+
PRIVATE
82+
${CMAKE_SOURCE_DIR}/include/
83+
${CMAKE_SOURCE_DIR}/helper/include/
84+
${DPCPP_SYCL_INCLUDE_DIR}
85+
)
86+
target_link_libraries(DPCTLSyclInterface
87+
PRIVATE ${DPCPP_SYCL_LIBRARY}
88+
PRIVATE ${DPCPP_OPENCL_LIBRARY}
8989
)
9090

91-
if(WIN32)
92-
message(
93-
STATUS
94-
"SYCL_INCLUDE_DIR: "
95-
${DPCPP_ROOT}/include/sycl
96-
)
97-
target_include_directories(
98-
DPCTLSyclInterface
99-
PUBLIC
100-
${DPCPP_ROOT}/include/sycl
101-
)
102-
target_link_libraries(
103-
DPCTLSyclInterface
104-
PRIVATE ${DPCPP_ROOT}/lib/sycl.lib
105-
PRIVATE ${DPCPP_ROOT}/lib/OpenCL.lib
106-
)
91+
if(DPCTL_ENABLE_LO_PROGRAM_CREATION)
92+
if(UNIX)
93+
target_include_directories(DPCTLSyclInterface
94+
PRIVATE
95+
${LEVEL_ZERO_INCLUDE_DIR}
96+
)
97+
target_link_libraries(DPCTLSyclInterface
98+
PRIVATE ${LEVEL_ZERO_LIBRARY}
99+
)
100+
else()
101+
message(WARNING
102+
"DPCTL support Level Zero program creation not supported "
103+
"on this system."
104+
)
105+
endif()
107106
endif()
108107

109108
install(
@@ -114,34 +113,52 @@ install(
114113
)
115114

116115
# Install all headers
117-
file(GLOB HEADERS "${CMAKE_SOURCE_DIR}/include/*.h*")
116+
file(GLOB HEADERS "${CMAKE_SOURCE_DIR}/include/*.h")
118117
foreach(HEADER ${HEADERS})
119118
install(FILES "${HEADER}" DESTINATION include)
120119
endforeach()
121120

122121
# Install all headers in include/Support
123-
file(GLOB HEADERS "${CMAKE_SOURCE_DIR}/include/Support/*.h*")
122+
file(GLOB HEADERS "${CMAKE_SOURCE_DIR}/include/Support/*.h")
124123
foreach(HEADER ${HEADERS})
125124
install(FILES "${HEADER}" DESTINATION include/Support)
126125
endforeach()
127126

128127
# Install all headers in helper/include
129-
file(GLOB HEADERS "${CMAKE_SOURCE_DIR}/helper/include/*.h*")
128+
file(GLOB HEADERS "${CMAKE_SOURCE_DIR}/helper/include/*.h")
130129
foreach(HEADER ${HEADERS})
131130
install(FILES "${HEADER}" DESTINATION helper/include)
132131
endforeach()
133132

134-
option(
135-
BUILD_CAPI_TESTS
136-
"Build dpctl C API google tests"
137-
OFF
138-
)
133+
# Install all headers in include/Config
134+
file(GLOB HEADERS "${CMAKE_SOURCE_DIR}/include/Config/*.h")
135+
foreach(HEADER ${HEADERS})
136+
install(FILES "${HEADER}" DESTINATION include/Config)
137+
endforeach()
139138

140-
# Enable to build the dpCtl backend test cases
141-
if(BUILD_CAPI_TESTS)
142-
add_subdirectory(tests)
139+
# Enable code coverage related settings
140+
if(DPCTL_GENERATE_COVERAGE)
141+
# check if llvm-cov and lcov are available
142+
find_package(Lcov REQUIRED)
143+
# These flags are set inside FindDPCPP
144+
if(NOT (${LLVM_COV_FOUND} AND ${LLVM_PROFDATA_FOUND}))
145+
message(FATAL_ERROR
146+
"llvm-cov and llvm-profdata are needed to generate coverage."
147+
)
148+
endif()
149+
# Turn on DPCTL_BUILD_CAPI_TESTS as building tests is needed to generate
150+
# coverage reports
151+
set(DPCTL_BUILD_CAPI_TESTS "ON")
152+
if(DPCTL_COVERAGE_REPORT_OUTPUT_DIR)
153+
set(COVERAGE_OUTPUT_DIR ${DPCTL_COVERAGE_REPORT_OUTPUT_DIR})
154+
message(STATUS "Coverage reports to be saved at ${COVERAGE_OUTPUT_DIR}")
155+
else()
156+
set(COVERAGE_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR})
157+
message(STATUS "Coverage reports to be saved at ${COVERAGE_OUTPUT_DIR}")
158+
endif()
143159
endif()
144160

145-
146-
# Todo : Add build rules for doxygen
147-
# maybe refer https://devblogs.microsoft.com/cppblog/clear-functional-c-documentation-with-sphinx-breathe-doxygen-cmake/
161+
# Add sub-directory to build the dpCtl C API test cases
162+
if(DPCTL_BUILD_CAPI_TESTS)
163+
add_subdirectory(tests)
164+
endif()
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
# Data Parallel Control Library (dpCtl)
2+
#
3+
# Copyright 2020 Intel Corporation
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
# CMake find_package() module for the DPCPP compiler and development
18+
# environment.
19+
#
20+
# Example usage:
21+
#
22+
# find_package(DPCPP)
23+
#
24+
# If successful, the following variables will be defined:
25+
# DPCPP_FOUND
26+
# DPCPP_VERSION
27+
# DPCPP_INCLUDE_DIR
28+
# DPCPP_SYCL_INCLUDE_DIR
29+
# DPCPP_LIBRARY_DIR
30+
# DPCPP_SYCL_LIBRARY
31+
# DPCPP_OPENCL_LIBRARY
32+
33+
include( FindPackageHandleStandardArgs )
34+
35+
string(COMPARE EQUAL "${DPCPP_INSTALL_DIR}" "" no_dpcpp_root)
36+
if(${no_dpcpp_root})
37+
message(STATUS "Set the DPCPP_ROOT argument providing the path to \
38+
a dpcpp installation.")
39+
return()
40+
endif()
41+
42+
if(WIN32 OR UNIX)
43+
set(dpcpp_cmd "${DPCPP_INSTALL_DIR}/bin/dpcpp")
44+
set(dpcpp_arg "--version")
45+
else()
46+
message(FATAL_ERROR "Unsupported system.")
47+
endif()
48+
49+
# Check if dpcpp is available
50+
execute_process(
51+
COMMAND ${dpcpp_cmd} ${dpcpp_arg}
52+
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
53+
RESULT_VARIABLE dpcpp_result
54+
OUTPUT_VARIABLE dpcpp_ver
55+
)
56+
57+
# If dpcpp is found then set then set the package variables
58+
if(${dpcpp_result} MATCHES "0")
59+
string(REPLACE "\n" ";" DPCPP_VERSION_LIST "${dpcpp_ver}")
60+
list(GET DPCPP_VERSION_LIST 0 dpcpp_ver_line)
61+
foreach(X ${DPCPP_VERSION_LIST})
62+
message(STATUS "dpcpp ver[${dpcpp_result}]: ${X}")
63+
endforeach()
64+
65+
# check if llvm-cov and llvm-profdata are packaged as part of dpcpp
66+
find_program(LLVM_COV_EXE
67+
llvm-cov
68+
PATHS ${DPCPP_INSTALL_DIR}/bin
69+
NO_DEFAULT_PATH
70+
)
71+
72+
if(LLVM_COV_EXE)
73+
set(LLVM_COV_FOUND TRUE)
74+
else()
75+
set(LLVM_COV_FOUND FALSE)
76+
endif()
77+
78+
find_program(LLVM_PROFDATA_EXE
79+
llvm-profdata
80+
PATHS ${DPCPP_INSTALL_DIR}/bin
81+
NO_DEFAULT_PATH
82+
)
83+
84+
if(LLVM_PROFDATA_EXE)
85+
set(LLVM_PROFDATA_FOUND TRUE)
86+
else()
87+
set(LLVM_PROFDATA_FOUND FALSE)
88+
endif()
89+
90+
# set package-level variables
91+
set(DPCPP_ROOT ${DPCPP_INSTALL_DIR})
92+
list(POP_FRONT DPCPP_VERSION_LIST DPCPP_VERSION)
93+
set(DPCPP_INCLUDE_DIR ${DPCPP_INSTALL_DIR}/include)
94+
set(DPCPP_SYCL_INCLUDE_DIR ${DPCPP_INSTALL_DIR}/include/sycl)
95+
set(DPCPP_LIBRARY_DIR ${DPCPP_INSTALL_DIR}/lib)
96+
if(WIN32)
97+
set(DPCPP_SYCL_LIBRARY ${DPCPP_INSTALL_DIR}/lib/sycl.lib)
98+
set(DPCPP_OPENCL_LIBRARY ${DPCPP_INSTALL_DIR}/lib/OpenCL.lib)
99+
elseif(UNIX)
100+
set(DPCPP_SYCL_LIBRARY ${DPCPP_INSTALL_DIR}/lib/libsycl.so)
101+
set(DPCPP_OPENCL_LIBRARY ${DPCPP_INSTALL_DIR}/lib/libOpenCL.so)
102+
endif()
103+
else()
104+
message(STATUS "DPCPP needed to build dpctl_sycl_interface")
105+
return()
106+
endif()
107+
108+
find_package_handle_standard_args(DPCPP DEFAULT_MSG
109+
DPCPP_VERSION
110+
DPCPP_INCLUDE_DIR
111+
DPCPP_SYCL_INCLUDE_DIR
112+
DPCPP_LIBRARY_DIR
113+
DPCPP_SYCL_LIBRARY
114+
DPCPP_OPENCL_LIBRARY
115+
)
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Data Parallel Control Library (dpCtl)
2+
#
3+
# Copyright 2020 Intel Corporation
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
# CMake find_package() module for lcov.
18+
#
19+
# Example usage:
20+
#
21+
# find_package(Lcov)
22+
#
23+
# If successful, the following variables will be defined:
24+
# LCOV_EXE- The path to lcov executable
25+
# LCOV_FOUND
26+
27+
find_program(LCOV_EXE lcov)
28+
find_program(GENHTML_EXE genhtml)
29+
30+
find_package_handle_standard_args(Lcov DEFAULT_MSG
31+
LCOV_EXE
32+
GENHTML_EXE
33+
)
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Data Parallel Control Library (dpCtl)
2+
#
3+
# Copyright 2020 Intel Corporation
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
# CMake find_package() module for the Level Zero loader library and headers.
18+
#
19+
# Example usage:
20+
#
21+
# find_package(LevelZero)
22+
#
23+
# If successful, the following variables will be defined:
24+
# LEVEL_ZERO_INCLUDE_DIR
25+
# LEVEL_ZERO_LIBRARY - the full path to the ze_loader library
26+
# TODO: Add a way to record the version of the level_zero library
27+
28+
find_library(LEVEL_ZERO_LIBRARY ze_loader)
29+
find_path(LEVEL_ZERO_INCLUDE_DIR NAMES level_zero/zet_api.h)
30+
31+
find_package_handle_standard_args(LevelZero DEFAULT_MSG
32+
LEVEL_ZERO_INCLUDE_DIR
33+
LEVEL_ZERO_LIBRARY
34+
)

0 commit comments

Comments
 (0)