Skip to content
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

[tools] Add opt-in build flags (and unit test) for OpenMP #16606

Merged
merged 1 commit into from
May 5, 2022
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
15 changes: 15 additions & 0 deletions common/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -1105,6 +1105,21 @@ drake_cc_googletest(
],
)

drake_cc_googletest(
name = "openmp_test",
# TODO(jwnimmer-tri) Encapsulate unit test concurrency configuration into
# Drake's starlark macros, so that we don't have to repeat ourselves here.
env = {
"OMP_NUM_THREADS": "2",
},
tags = [
"cpu:2",
],
deps = [
"//common:essential",
],
)

drake_cc_googletest(
name = "polynomial_test",
deps = [
Expand Down
55 changes: 55 additions & 0 deletions common/test/openmp_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#include <numeric>
#include <unordered_set>

#include <gmock/gmock.h>
#include <gtest/gtest.h>

#if defined(_OPENMP)
#include <omp.h>
#endif

#include "drake/common/text_logging.h"

namespace drake {
namespace {

#if defined(_OPENMP)
constexpr bool kHasOpenmp = true;
#else
constexpr bool kHasOpenmp = false;
// TODO(jwnimmer-tri) This should be a Drake helper function wrapper that
// abstracts away this difference. The openmp_helpers.hpp wrapper from
// common_robotics_utilities is a likely candidate to delegate to, or at
// least take as inspiration.
int omp_get_thread_num() { return 0; }
#endif

// Mostly, this just checks for compilation failures.
GTEST_TEST(OpenmpTest, ParallelFor) {
drake::log()->info("Using kHasOpenmp = {}", kHasOpenmp);

// Allocate storage for one integer result per loop.
constexpr int num_outputs = 100;
std::vector<int> outputs(static_cast<size_t>(num_outputs), 0);

// Populate the storage, in parallel.
#if defined(_OPENMP)
#pragma omp parallel for
#endif
for (int i = 0; i < num_outputs; ++i) {
outputs[i] = omp_get_thread_num();
}

// Our BUILD rule will run this program with a maximum of two threads.
// Confirm how many threads were used and that their thread numbers were the
// expected set of either {0, 1} (with OpenMP) or {0} (without OpenMP).
std::unordered_set<int> thread_nums(outputs.begin(), outputs.end());
if (kHasOpenmp) {
EXPECT_THAT(thread_nums, testing::UnorderedElementsAre(0, 1));
} else {
EXPECT_THAT(thread_nums, testing::UnorderedElementsAre(0));
}
}

} // namespace
} // namespace drake
19 changes: 19 additions & 0 deletions doc/_pages/bazel.md
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,25 @@ See [https://docs.bazel.build/versions/main/user-manual.html#bazelrc](https://do
SNOPT support has some known problems on certain programs (see drake issue
[#10422](https://github.com/RobotLocomotion/drake/issues/10422) for a summary).

# Other optional dependencies

## OpenMP

Drake is
[in the process](https://github.com/RobotLocomotion/drake/issues/14858)
of adding support for multiprocessing using
[OpenMP](https://en.wikipedia.org/wiki/OpenMP).
At the moment, that support is experimental and is not recommended for Drake's
users.

For Drake Developers who wish to enable OpenMP, use this config switch:

```
bazel test --config omp //...
```

This switch is enabled in CI under the "Ubuntu Everything" build flavor.

# Optional Tools

The Drake Bazel build system has integration support for some optional
Expand Down
5 changes: 5 additions & 0 deletions tools/ubuntu-focal.bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ build --action_env=PATH=/usr/bin:/bin
build --action_env=PYTHONNOUSERSITE=1
build --test_env=PYTHONNOUSERSITE=1

# Enable OpenMP (when requested via --config omp).
build:omp --copt=-DEIGEN_DONT_PARALLELIZE
build:omp --copt=-fopenmp
build:omp --linkopt=-fopenmp

# -- Options for explicitly using Clang.
common:clang --repo_env=CC=clang-9
common:clang --repo_env=CXX=clang++-9
Expand Down
1 change: 1 addition & 0 deletions tools/workspace/libcmaes/package.BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ cc_library(
"surrogatestrategy.h",
]),
copts = [
"-fno-openmp",
# Ignore OpenMP-related warnings.
"-Wno-unknown-pragmas",
],
Expand Down
1 change: 1 addition & 0 deletions tools/workspace/scs/package.BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ cc_library(
],
copts = [
"-fvisibility=hidden",
"-fno-openmp",
"-w",
"-Werror=incompatible-pointer-types",
],
Expand Down