Skip to content

Commit 6babd3f

Browse files
authored
Add python and cython file coverage (#238)
1 parent 77bc086 commit 6babd3f

File tree

5 files changed

+117
-22
lines changed

5 files changed

+117
-22
lines changed

.coveragerc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[run]
2+
plugins = Cython.Coverage
3+
branch = True
4+
source = dpctl
5+
omit = dpctl/tests/*, *__init__.py

CHANGELOG.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77

88
## [Unreleased]
9-
109
### Added
1110
- Documentation improvements
12-
- Cmake improvements and Coverage for C API
11+
- Cmake improvements and Coverage for C API, Cython and Python
1312
- Add support for Level Zero
1413
- Code of conduct
1514

1615
### Fixed
1716
- Remove `cython` from `install_requires`. It allows use `dpCtl` in `numba` extensions.
1817
- Incorrect import in example.
1918

20-
2119
## [0.5.0] - 2020-12-17
2220
### Added
2321
- `_Memory.get_pointer_type` static method which returns kind of USM pointer.
@@ -67,7 +65,6 @@ supports USM.
6765
- Fix Gtests configuration.
6866

6967
## [0.3.7] - 2020-10-08
70-
7168
### Fixed
7269
- A crash on Windows due a Level Zero driver problem. Each device was getting enumerated twice. To handle the issue, we added a temporary fix to use only first device for each device type and backend (#118).
7370

CONTRIBUTING.md

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
# Mechanical Source Issues
1+
# Mechanical Source Issues
22

3-
## Source Code Formatting
3+
## Source Code Formatting
44

55
### C/C++ code style
66

@@ -87,3 +87,62 @@ Every Python and Cython file should only include the following license header:
8787
# limitations under the License.
8888
```
8989
The copyright year should be updated every calendar year.
90+
91+
## Code Coverage
92+
93+
Implement python, cython and c++ file coverage using `coverage` and `llvm-cov` packages on Linux.
94+
95+
### Using Code Coverage
96+
97+
You need to install additional packages and add an environment variable to cover:
98+
- conda install cmake
99+
- conda install coverage
100+
- conda install conda-forge::lcov
101+
- conda install conda-forge::gtest
102+
- export CODE_COVERAGE=ON
103+
104+
CODE_COVERAGE allows you to build a debug version of dpctl and enable string tracing, which allows you to analyze strings to create a coverage report.
105+
It was added for the convenience of configuring the CI in the future.
106+
107+
Installing the dpctl package:
108+
- python setup.py develop
109+
110+
It is important that there are no files of the old build in the folder.
111+
Use `git clean -xdf` to clean up the working tree.
112+
113+
The coverage report will appear during the build in the console. This report contains information about c++ file coverage.
114+
The `dpctl-c-api-coverage` folder will appear in the root folder after installation.
115+
The folder contains a report on the coverage of c++ files in html format.
116+
117+
You need to run tests to cover the cython and python files:
118+
- coverage run -m unittest dpctl.tests
119+
120+
The required flags for the command coverage run are contained in the file `.coveragerc`.
121+
122+
The simplest reporting is a textual summary produced with report:
123+
- coverage report
124+
125+
For each module executed, the report shows the count of executable statements, the number of those statements missed, and the resulting coverage, expressed as a percentage.
126+
127+
The `-m` flag also shows the line numbers of missing statements:
128+
- coverage report -m
129+
130+
To create an annotated HTML listings with coverage results:
131+
- coverage html
132+
133+
The `htmlcov` folder will appear in the root folder of the project. It contains reports on the coverage of python and cython files in html format.
134+
135+
Erase previously collected coverage data:
136+
- coverage erase
137+
138+
### Error in the build process
139+
140+
An error occurs during the dcptl build with the CODE_COVERAGE environment variable:
141+
```
142+
error: '../compat/unistd.h' file not found, did you mean 'compat/unistd.h'?
143+
# include "../compat/unistd.h"
144+
^
145+
1 error generated.
146+
```
147+
The error is related to the `tcl` package.
148+
You need to remove the tcl package to resolve this error.

scripts/build_backend.py

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
assert False, sys.platform + " not supported"
3636

3737
ONEAPI_ROOT = os.environ.get("ONEAPI_ROOT")
38+
CODE_COVERAGE = os.environ.get("CODE_COVERAGE")
3839

3940
if IS_LIN:
4041
DPCPP_ROOT = os.path.join(ONEAPI_ROOT, "compiler/latest/linux")
@@ -55,20 +56,41 @@
5556
backends = os.path.join(dpctl_dir, "dpctl-capi")
5657

5758
if IS_LIN:
58-
cmake_args = [
59-
"cmake",
60-
"-DCMAKE_BUILD_TYPE=Release",
61-
"-DCMAKE_INSTALL_PREFIX=" + INSTALL_PREFIX,
62-
"-DCMAKE_PREFIX_PATH=" + INSTALL_PREFIX,
63-
"-DDPCPP_INSTALL_DIR=" + DPCPP_ROOT,
64-
"-DCMAKE_C_COMPILER:PATH=" + os.path.join(DPCPP_ROOT, "bin", "clang"),
65-
"-DCMAKE_CXX_COMPILER:PATH=" + os.path.join(DPCPP_ROOT, "bin", "dpcpp"),
66-
"-DDPCTL_ENABLE_LO_PROGRAM_CREATION=ON",
67-
backends,
68-
]
69-
subprocess.check_call(cmake_args, stderr=subprocess.STDOUT, shell=False)
70-
subprocess.check_call(["make", "V=1", "-j", "4"])
71-
subprocess.check_call(["make", "install"])
59+
if CODE_COVERAGE:
60+
cmake_args = [
61+
"cmake",
62+
"-DCMAKE_BUILD_TYPE=Debug",
63+
"-DCMAKE_INSTALL_PREFIX=" + INSTALL_PREFIX,
64+
"-DCMAKE_PREFIX_PATH=" + INSTALL_PREFIX,
65+
"-DDPCPP_INSTALL_DIR=" + DPCPP_ROOT,
66+
"-DCMAKE_C_COMPILER:PATH=" + os.path.join(DPCPP_ROOT, "bin", "clang"),
67+
"-DCMAKE_CXX_COMPILER:PATH=" + os.path.join(DPCPP_ROOT, "bin", "dpcpp"),
68+
"-DDPCTL_ENABLE_LO_PROGRAM_CREATION=ON",
69+
"-DDPCTL_BUILD_CAPI_TESTS=ON",
70+
"-DDPCTL_GENERATE_COVERAGE=ON",
71+
"-DDPCTL_COVERAGE_REPORT_OUTPUT_DIR=" + dpctl_dir,
72+
backends,
73+
]
74+
subprocess.check_call(cmake_args, stderr=subprocess.STDOUT, shell=False)
75+
subprocess.check_call(["make", "V=1", "-j", "4"])
76+
subprocess.check_call(["make", "install"])
77+
subprocess.check_call(["make", "lcov-genhtml"])
78+
79+
else:
80+
cmake_args = [
81+
"cmake",
82+
"-DCMAKE_BUILD_TYPE=Release",
83+
"-DCMAKE_INSTALL_PREFIX=" + INSTALL_PREFIX,
84+
"-DCMAKE_PREFIX_PATH=" + INSTALL_PREFIX,
85+
"-DDPCPP_INSTALL_DIR=" + DPCPP_ROOT,
86+
"-DCMAKE_C_COMPILER:PATH=" + os.path.join(DPCPP_ROOT, "bin", "clang"),
87+
"-DCMAKE_CXX_COMPILER:PATH=" + os.path.join(DPCPP_ROOT, "bin", "dpcpp"),
88+
"-DDPCTL_ENABLE_LO_PROGRAM_CREATION=ON",
89+
backends,
90+
]
91+
subprocess.check_call(cmake_args, stderr=subprocess.STDOUT, shell=False)
92+
subprocess.check_call(["make", "V=1", "-j", "4"])
93+
subprocess.check_call(["make", "install"])
7294

7395
os.chdir(dpctl_dir)
7496
for file in glob.glob(os.path.join(dpctl_dir, "install", "lib", "*.so")):

setup.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ def extensions():
113113
ela = get_sdl_ldflags()
114114
libs = []
115115
librarys = []
116+
CODE_COVERAGE = os.environ.get("CODE_COVERAGE")
116117

117118
if IS_LIN:
118119
libs += ["rt", "DPCTLSyclInterface"]
@@ -148,6 +149,15 @@ def extensions():
148149
"language": "c++",
149150
}
150151

152+
if CODE_COVERAGE:
153+
extension_args.update(
154+
{
155+
"define_macros": [
156+
("CYTHON_TRACE", "1"),
157+
]
158+
}
159+
)
160+
151161
extensions = [
152162
Extension(
153163
"dpctl._sycl_context",
@@ -199,8 +209,10 @@ def extensions():
199209
**extension_args
200210
),
201211
]
202-
203-
exts = cythonize(extensions)
212+
if CODE_COVERAGE:
213+
exts = cythonize(extensions, compiler_directives={"linetrace": True})
214+
else:
215+
exts = cythonize(extensions)
204216
return exts
205217

206218

0 commit comments

Comments
 (0)