This document lists the coding rules for Compute Benchmarks. They apply to all new and modified code. clang-format checks the formatting automatically; the code review checks the rules below.
The rules do not apply to definitions that are copied from a specification or an API header, for example extension types, function pointer types, structures and macros of OpenCL, Level Zero or other APIs. Keep these definitions exactly as the source writes them, and when the source changes, update the copy to match it.
- 1. C++ usage
- 2. Naming conventions
- 3. Coding rules
- 4. Error handling
- 5. Benchmark implementation
- 6. Comments
- 7. Documentation
- Use C++ style casts instead of C style casts.
- Do not use default parameters.
- Prefer
usingovertypedef. - Use
constexprinstead of#definefor constants. - Do not define global constants with internal linkage in header files; use C++17
inlinevariables instead. - Do not use
using namespacein headers. - Manage ownership with smart pointers (
std::unique_ptr,std::make_unique); do not use rawnewanddelete. - Prefer const-correctness: mark members, locals and parameters
constwhere possible, and pass non-trivial types by const reference. - Prefer named constants over magic numbers. The parameter values in a gtest registration file are the test configuration and stay inline, for example
::testing::Values(128 * megaByte). - Inside methods, use an explicit
this->pointer to refer to non-static class members. - Do not use Unicode characters in code.
- Use snake_case for file names, for example
usm_copy.h,usm_copy.cppandusm_copy_l0.cpp. - Use PascalCase for class, struct, enum and namespace names, and for the test case name returned by
getTestCaseName(). - Use camelCase for variable and function names, and for the command line keys of test case arguments.
- Prefer verbose names for variables and functions:
bad examples : sz, cnt, buf
good examples: bufferSize, kernelCount, stagingBuffer
- Favor self-explanatory code over comments, see Comments.
- Avoid code duplication. When two benchmarks need the same logic, put it in a helper in
source/frameworkand reuse the existing helpers there, instead of copying code between benchmarks. - Refactor existing code when it improves clarity or removes duplication introduced by your change.
- One-line branches use braces.
- Headers are guarded using
#pragma once. - Do not use
TODOs in the code. - Do not leave dead or commented-out code. This includes code that is disabled with a
#defineswitch set to0.
- Do not use
assert. It is removed in Release builds, so the check does not run in the configuration that is measured. - Check every API call with the macro of that API, for example
ASSERT_ZE_RESULT_SUCCESSorASSERT_CL_SUCCESS. On failure, the macro prints the error and returnsTestResult::Error, so only the current test case fails. - When the device, the driver or the API cannot run a configuration, return the
TestResultthat names the reason, for exampleDeviceNotCapable,ApiNotCapableorDriverFunctionNotFound. Do not report it asTestResult::Error. - Use
FATAL_ERRORandFATAL_ERROR_IFonly when the framework is in a state from which it cannot continue, for example an incorrect use of a framework class. They stop the whole binary, not only the current test case. - Do not throw exceptions in benchmark code; return a
TestResultinstead.
- Measure only what is required. The timed region between
timer.measureStart()andtimer.measureEnd()contains the operation under test and nothing else. Collateral work, for example the creation of resources that the operation uses, data initialization and result verification, stays outside of it. - Handle
isNoopRun()before you create resources: push the unit and type of the measurement tostatisticsand returnTestResult::Nooped. - Keep the test case independent of other test cases; do not rely on the execution order or on state that a different test case leaves behind.
The expected number of comments added by a change is zero; every comment has to earn its place on its own. That the file being modified already contains comments is not a reason to add another one.
- A comment earns its place when it carries a fact that lives outside the source code and that a future edit would break silently, for example: a hardware, specification or driver behavior that the measurement depends on (name the document or the workaround identifier), an ordering, a warmup or an extra synchronization that reads as arbitrary but is required for the measured number to be valid, a constant whose origin cannot be derived from the code, a language or toolchain constraint that forces the shape of the code, or the reason why the obvious simpler form is wrong.
- Do not restate what the code already says, i.e.
// synchronize the queueabove afinish()call. - Do not document why the change was made or what the bug was; that is the content of the commit message.
- Do not pre-empt an expected review objection in the code; answer it in the pull request instead.
- Do not add a comment describing a test case in its definition, registration or implementation file. The test case name and its arguments identify the scenario, and the user-facing description of what is measured belongs in
getHelp()and in the argument help strings, which is what TESTS.md is generated from. - When a comment is only needed because the code is hard to follow, fix the code instead: a named
constexpr, a better function or variable name, or a helper whose name is the explanation. Those survive refactoring, a comment does not. - In C++ sources, use double slash instead of block comments, except for the copyright header, which stays in its required block form.
- Keep documentation in sync with the code, and update it in the same change. When a change adds, removes or changes a test case, an argument or a help string, regenerate TESTS.md. When a change modifies the build, run or contribution flow that README.md, FAQ.md or CONTRIBUTING.md describes, update that document.
- Do not leave stale documentation behind.
- Keep code, comments, help strings and documentation generic and free of internal-only or non-public information, because they may be published.