Skip to content

Add python and cython file coverage #238

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Feb 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[run]
plugins = Cython.Coverage
branch = True
source = dpctl
omit = dpctl/tests/*, *__init__.py
5 changes: 1 addition & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0


## [Unreleased]

### Added
- Documentation improvements
- Cmake improvements and Coverage for C API
- Cmake improvements and Coverage for C API, Cython and Python
- Add support for Level Zero
- Code of conduct

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


## [0.5.0] - 2020-12-17
### Added
- `_Memory.get_pointer_type` static method which returns kind of USM pointer.
Expand Down Expand Up @@ -67,7 +65,6 @@ supports USM.
- Fix Gtests configuration.

## [0.3.7] - 2020-10-08

### Fixed
- 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).

Expand Down
63 changes: 61 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Mechanical Source Issues
# Mechanical Source Issues

## Source Code Formatting
## Source Code Formatting

### C/C++ code style

Expand Down Expand Up @@ -87,3 +87,62 @@ Every Python and Cython file should only include the following license header:
# limitations under the License.
```
The copyright year should be updated every calendar year.

## Code Coverage

Implement python, cython and c++ file coverage using `coverage` and `llvm-cov` packages on Linux.

### Using Code Coverage

You need to install additional packages and add an environment variable to cover:
- conda install cmake
- conda install coverage
- conda install conda-forge::lcov
- conda install conda-forge::gtest
- export CODE_COVERAGE=ON

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.
It was added for the convenience of configuring the CI in the future.

Installing the dpctl package:
- python setup.py develop

It is important that there are no files of the old build in the folder.
Use `git clean -xdf` to clean up the working tree.

The coverage report will appear during the build in the console. This report contains information about c++ file coverage.
The `dpctl-c-api-coverage` folder will appear in the root folder after installation.
The folder contains a report on the coverage of c++ files in html format.

You need to run tests to cover the cython and python files:
- coverage run -m unittest dpctl.tests

The required flags for the command coverage run are contained in the file `.coveragerc`.

The simplest reporting is a textual summary produced with report:
- coverage report

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.

The `-m` flag also shows the line numbers of missing statements:
- coverage report -m

To create an annotated HTML listings with coverage results:
- coverage html

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.

Erase previously collected coverage data:
- coverage erase

### Error in the build process

An error occurs during the dcptl build with the CODE_COVERAGE environment variable:
```
error: '../compat/unistd.h' file not found, did you mean 'compat/unistd.h'?
# include "../compat/unistd.h"
^
1 error generated.
```
The error is related to the `tcl` package.
You need to remove the tcl package to resolve this error.
50 changes: 36 additions & 14 deletions scripts/build_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
assert False, sys.platform + " not supported"

ONEAPI_ROOT = os.environ.get("ONEAPI_ROOT")
CODE_COVERAGE = os.environ.get("CODE_COVERAGE")

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

if IS_LIN:
cmake_args = [
"cmake",
"-DCMAKE_BUILD_TYPE=Release",
"-DCMAKE_INSTALL_PREFIX=" + INSTALL_PREFIX,
"-DCMAKE_PREFIX_PATH=" + INSTALL_PREFIX,
"-DDPCPP_INSTALL_DIR=" + DPCPP_ROOT,
"-DCMAKE_C_COMPILER:PATH=" + os.path.join(DPCPP_ROOT, "bin", "clang"),
"-DCMAKE_CXX_COMPILER:PATH=" + os.path.join(DPCPP_ROOT, "bin", "dpcpp"),
"-DDPCTL_ENABLE_LO_PROGRAM_CREATION=ON",
backends,
]
subprocess.check_call(cmake_args, stderr=subprocess.STDOUT, shell=False)
subprocess.check_call(["make", "V=1", "-j", "4"])
subprocess.check_call(["make", "install"])
if CODE_COVERAGE:
cmake_args = [
"cmake",
"-DCMAKE_BUILD_TYPE=Debug",
"-DCMAKE_INSTALL_PREFIX=" + INSTALL_PREFIX,
"-DCMAKE_PREFIX_PATH=" + INSTALL_PREFIX,
"-DDPCPP_INSTALL_DIR=" + DPCPP_ROOT,
"-DCMAKE_C_COMPILER:PATH=" + os.path.join(DPCPP_ROOT, "bin", "clang"),
"-DCMAKE_CXX_COMPILER:PATH=" + os.path.join(DPCPP_ROOT, "bin", "dpcpp"),
"-DDPCTL_ENABLE_LO_PROGRAM_CREATION=ON",
"-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,
"-DDPCPP_INSTALL_DIR=" + DPCPP_ROOT,
"-DCMAKE_C_COMPILER:PATH=" + os.path.join(DPCPP_ROOT, "bin", "clang"),
"-DCMAKE_CXX_COMPILER:PATH=" + os.path.join(DPCPP_ROOT, "bin", "dpcpp"),
"-DDPCTL_ENABLE_LO_PROGRAM_CREATION=ON",
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")):
Expand Down
16 changes: 14 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ def extensions():
ela = get_sdl_ldflags()
libs = []
librarys = []
CODE_COVERAGE = os.environ.get("CODE_COVERAGE")

if IS_LIN:
libs += ["rt", "DPCTLSyclInterface"]
Expand Down Expand Up @@ -148,6 +149,15 @@ def extensions():
"language": "c++",
}

if CODE_COVERAGE:
extension_args.update(
{
"define_macros": [
("CYTHON_TRACE", "1"),
]
}
)

extensions = [
Extension(
"dpctl._sycl_context",
Expand Down Expand Up @@ -199,8 +209,10 @@ def extensions():
**extension_args
),
]

exts = cythonize(extensions)
if CODE_COVERAGE:
exts = cythonize(extensions, compiler_directives={"linetrace": True})
else:
exts = cythonize(extensions)
return exts


Expand Down