Skip to content

Commit e620aa6

Browse files
authored
Merge pull request #1027 from Idclip/tbb2021
Added support for TBB 2021
2 parents bf2540b + e20dbf0 commit e620aa6

33 files changed

+337
-196
lines changed

.github/workflows/build.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,3 +200,28 @@ jobs:
200200
- name: test
201201
shell: bash
202202
run: cd build && ctest -V
203+
204+
testmacos1015_tbb2021:
205+
runs-on: macos-10.15
206+
env:
207+
CXX: clang++
208+
steps:
209+
- uses: actions/checkout@v2
210+
- name: install
211+
shell: bash
212+
run: |
213+
brew update
214+
brew install bash cmake ilmbase openexr@2 boost tbb glfw
215+
echo "IlmBase_ROOT=/usr/local/opt/ilmbase" >> $GITHUB_ENV
216+
echo "OpenEXR_ROOT=/usr/local/opt/openexr@2" >> $GITHUB_ENV
217+
echo "/usr/local/opt/openexr@2/bin" >> $GITHUB_PATH
218+
- name: install
219+
shell: bash
220+
run: ./ci/install_gtest.sh 1.10.0
221+
- name: build
222+
shell: bash
223+
run: ./ci/build.sh Release "core,bin,test" \
224+
-DOPENVDB_CXX_STRICT=OFF -DUSE_BLOSC=OFF -DUSE_ZLIB=OFF
225+
- name: test
226+
shell: bash
227+
run: cd build && ctest -V

ci/install_macos.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ brew install ilmbase
99
brew install openexr@2
1010
brew install boost
1111
brew install boost-python3 # also installs the dependent python version
12-
brew install gtest
1312
brew install tbb@2020
1413
brew install zlib
1514
brew install glfw

cmake/FindTBB.cmake

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,16 +169,30 @@ find_path(Tbb_INCLUDE_DIR tbb/tbb_stddef.h
169169
PATH_SUFFIXES ${CMAKE_INSTALL_INCLUDEDIR} include
170170
)
171171

172-
if(EXISTS "${Tbb_INCLUDE_DIR}/tbb/tbb_stddef.h")
173-
file(STRINGS "${Tbb_INCLUDE_DIR}/tbb/tbb_stddef.h"
172+
set(_tbb_version_file "${Tbb_INCLUDE_DIR}/tbb/tbb_stddef.h")
173+
174+
if(NOT EXISTS ${_tbb_version_file})
175+
# From TBB 2021, tbb_stddef is removed and the directory include/tbb is
176+
# simply an alias for include/oneapi/tbb. Try and find the version header
177+
# in oneapi/tbb
178+
find_path(Tbb_INCLUDE_DIR oneapi/tbb/version.h
179+
${_FIND_TBB_ADDITIONAL_OPTIONS}
180+
PATHS ${_TBB_INCLUDE_SEARCH_DIRS}
181+
PATH_SUFFIXES ${CMAKE_INSTALL_INCLUDEDIR} include
182+
)
183+
set(_tbb_version_file "${Tbb_INCLUDE_DIR}/oneapi/tbb/version.h")
184+
endif()
185+
186+
if(EXISTS ${_tbb_version_file})
187+
file(STRINGS ${_tbb_version_file}
174188
_tbb_version_major_string REGEX "#define TBB_VERSION_MAJOR "
175189
)
176190
string(REGEX REPLACE "#define TBB_VERSION_MAJOR" ""
177191
_tbb_version_major_string "${_tbb_version_major_string}"
178192
)
179193
string(STRIP "${_tbb_version_major_string}" Tbb_VERSION_MAJOR)
180194

181-
file(STRINGS "${Tbb_INCLUDE_DIR}/tbb/tbb_stddef.h"
195+
file(STRINGS ${_tbb_version_file}
182196
_tbb_version_minor_string REGEX "#define TBB_VERSION_MINOR "
183197
)
184198
string(REGEX REPLACE "#define TBB_VERSION_MINOR" ""
@@ -192,6 +206,8 @@ if(EXISTS "${Tbb_INCLUDE_DIR}/tbb/tbb_stddef.h")
192206
set(Tbb_VERSION ${Tbb_VERSION_MAJOR}.${Tbb_VERSION_MINOR})
193207
endif()
194208

209+
unset(_tbb_version_file)
210+
195211
# ------------------------------------------------------------------------
196212
# Search for TBB lib DIR
197213
# ------------------------------------------------------------------------

openvdb/openvdb/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,10 @@ set(OPENVDB_LIBRARY_UTIL_INCLUDE_FILES
439439
util/Util.h
440440
)
441441

442+
set(OPENVDB_LIBRARY_THREAD_INCLUDE_FILES
443+
thread/Threading.h
444+
)
445+
442446
# @todo CMake >= 3.12, use an object library to consolidate shared/static
443447
# builds. There are limitations with earlier versions of CMake when used with
444448
# imported targets.
@@ -594,3 +598,4 @@ install(FILES ${OPENVDB_LIBRARY_POINTS_INCLUDE_FILES} DESTINATION ${OPENVDB_INST
594598
install(FILES ${OPENVDB_LIBRARY_TOOLS_INCLUDE_FILES} DESTINATION ${OPENVDB_INSTALL_INCLUDEDIR}/tools)
595599
install(FILES ${OPENVDB_LIBRARY_TREE_INCLUDE_FILES} DESTINATION ${OPENVDB_INSTALL_INCLUDEDIR}/tree)
596600
install(FILES ${OPENVDB_LIBRARY_UTIL_INCLUDE_FILES} DESTINATION ${OPENVDB_INSTALL_INCLUDEDIR}/util)
601+
install(FILES ${OPENVDB_LIBRARY_THREAD_INCLUDE_FILES} DESTINATION ${OPENVDB_INSTALL_INCLUDEDIR}/thread)

openvdb/openvdb/cmd/openvdb_render.cc

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,14 @@
1919
#include <OpenEXR/ImfHeader.h>
2020
#include <OpenEXR/ImfOutputFile.h>
2121
#include <OpenEXR/ImfPixelType.h>
22-
#include <tbb/task_scheduler_init.h>
22+
23+
// tbb/task_scheduler_init.h was removed in TBB 2021. The best construct to swap
24+
// to is tbb/global_control (for executables). global_control was only officially
25+
// added in TBB 2019U4 but exists in 2018 as a preview feature. To avoid more
26+
// compile time branching (as we still support 2018), we use it in 2018 too by
27+
// enabling the below define.
28+
#define TBB_PREVIEW_GLOBAL_CONTROL 1
29+
#include <tbb/global_control.h>
2330
#include <tbb/tick_count.h>
2431

2532
#include <algorithm>
@@ -606,8 +613,12 @@ main(int argc, char *argv[])
606613
}
607614

608615
try {
609-
tbb::task_scheduler_init schedulerInit(
610-
(opts.threads == 0) ? tbb::task_scheduler_init::automatic : opts.threads);
616+
std::unique_ptr<tbb::global_control> control;
617+
if (opts.threads > 0) {
618+
// note, opts.threads == 0 means use all threads (default), so don't
619+
// manually create a tbb::global_control in this case
620+
control.reset(new tbb::global_control(tbb::global_control::max_allowed_parallelism, opts.threads));
621+
}
611622

612623
openvdb::initialize();
613624

openvdb/openvdb/io/Queue.cc

Lines changed: 31 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,22 @@
55
/// @author Peter Cucka
66

77
#include "Queue.h"
8-
98
#include "File.h"
109
#include "Stream.h"
11-
#include <openvdb/Exceptions.h>
12-
#include <openvdb/util/logging.h>
10+
#include "openvdb/Exceptions.h"
11+
#include "openvdb/util/logging.h"
12+
1313
#include <tbb/concurrent_hash_map.h>
14-
#include <tbb/task.h>
15-
#include <tbb/tbb_thread.h> // for tbb::this_tbb_thread::sleep()
16-
#include <tbb/tick_count.h>
14+
#include <tbb/task_arena.h>
15+
16+
#include <thread>
1717
#include <algorithm> // for std::max()
1818
#include <atomic>
1919
#include <iostream>
2020
#include <map>
2121
#include <mutex>
22+
#include <chrono>
23+
2224

2325
namespace openvdb {
2426
OPENVDB_USE_VERSION_NAMESPACE
@@ -28,18 +30,19 @@ namespace io {
2830
namespace {
2931

3032
// Abstract base class for queuable TBB tasks that adds a task completion callback
31-
class Task: public tbb::task
33+
class Task
3234
{
3335
public:
3436
Task(Queue::Id id): mId(id) {}
35-
~Task() override {}
37+
virtual ~Task() {}
3638

3739
Queue::Id id() const { return mId; }
3840

3941
void setNotifier(Queue::Notifier& notifier) { mNotify = notifier; }
42+
virtual void execute() const = 0;
4043

4144
protected:
42-
void notify(Queue::Status status) { if (mNotify) mNotify(this->id(), status); }
45+
void notify(Queue::Status status) const { if (mNotify) mNotify(this->id(), status); }
4346

4447
private:
4548
Queue::Id mId;
@@ -48,18 +51,18 @@ class Task: public tbb::task
4851

4952

5053
// Queuable TBB task that writes one or more grids to a .vdb file or an output stream
51-
class OutputTask: public Task
54+
class OutputTask : public Task
5255
{
5356
public:
5457
OutputTask(Queue::Id id, const GridCPtrVec& grids, const Archive& archive,
5558
const MetaMap& metadata)
5659
: Task(id)
5760
, mGrids(grids)
5861
, mArchive(archive.copy())
59-
, mMetadata(metadata)
60-
{}
62+
, mMetadata(metadata) {}
63+
~OutputTask() override {}
6164

62-
tbb::task* execute() override
65+
void execute() const override
6366
{
6467
Queue::Status status = Queue::FAILED;
6568
try {
@@ -69,10 +72,8 @@ class OutputTask: public Task
6972
if (const char* msg = e.what()) {
7073
OPENVDB_LOG_ERROR(msg);
7174
}
72-
} catch (...) {
73-
}
75+
} catch (...) {}
7476
this->notify(status);
75-
return nullptr; // no successor to this task
7677
}
7778

7879
private:
@@ -94,7 +95,6 @@ struct Queue::Impl
9495
/// @todo Provide more information than just "succeeded" or "failed"?
9596
using StatusMap = tbb::concurrent_hash_map<Queue::Id, Queue::Status>;
9697

97-
9898
Impl()
9999
: mTimeout(Queue::DEFAULT_TIMEOUT)
100100
, mCapacity(Queue::DEFAULT_CAPACITY)
@@ -159,12 +159,15 @@ struct Queue::Impl
159159

160160
bool canEnqueue() const { return mNumTasks < Int64(mCapacity); }
161161

162-
void enqueue(Task& task)
162+
void enqueue(OutputTask& task)
163163
{
164-
tbb::tick_count start = tbb::tick_count::now();
164+
auto start = std::chrono::steady_clock::now();
165165
while (!canEnqueue()) {
166-
tbb::this_tbb_thread::sleep(tbb::tick_count::interval_t(0.5/*sec*/));
167-
if ((tbb::tick_count::now() - start).seconds() > double(mTimeout)) {
166+
std::this_thread::sleep_for(/*0.5s*/std::chrono::milliseconds(500));
167+
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(
168+
std::chrono::steady_clock::now() - start);
169+
const double seconds = double(duration.count()) / 1000.0;
170+
if (seconds > double(mTimeout)) {
168171
OPENVDB_THROW(RuntimeError,
169172
"unable to queue I/O task; " << mTimeout << "-second time limit expired");
170173
}
@@ -173,7 +176,10 @@ struct Queue::Impl
173176
std::placeholders::_1, std::placeholders::_2);
174177
task.setNotifier(notify);
175178
this->setStatus(task.id(), Queue::PENDING);
176-
tbb::task::enqueue(task);
179+
180+
// get the global task arena
181+
tbb::task_arena arena(tbb::task_arena::attach{});
182+
arena.enqueue([task = std::move(task)] { task.execute(); });
177183
++mNumTasks;
178184
}
179185

@@ -204,7 +210,7 @@ Queue::~Queue()
204210
/// (e.g., by keeping a static registry of queues that also dispatches
205211
/// or blocks notifications)?
206212
while (mImpl->mNumTasks > 0) {
207-
tbb::this_tbb_thread::sleep(tbb::tick_count::interval_t(0.5/*sec*/));
213+
std::this_thread::sleep_for(/*0.5s*/std::chrono::milliseconds(500));
208214
}
209215
}
210216

@@ -290,16 +296,8 @@ Queue::Id
290296
Queue::writeGridVec(const GridCPtrVec& grids, const Archive& archive, const MetaMap& metadata)
291297
{
292298
const Queue::Id taskId = mImpl->mNextId++;
293-
// From the "GUI Thread" chapter in the TBB Design Patterns guide
294-
OutputTask* task =
295-
new(tbb::task::allocate_root()) OutputTask(taskId, grids, archive, metadata);
296-
try {
297-
mImpl->enqueue(*task);
298-
} catch (openvdb::RuntimeError&) {
299-
// Destroy the task if it could not be enqueued, then rethrow the exception.
300-
tbb::task::destroy(*task);
301-
throw;
302-
}
299+
OutputTask task(taskId, grids, archive, metadata);
300+
mImpl->enqueue(task);
303301
return taskId;
304302
}
305303

openvdb/openvdb/math/Coord.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@
1313
#include "Math.h"
1414
#include "Vec3.h"
1515

16-
namespace tbb { class split; } // forward declaration
17-
16+
#include <tbb/blocked_range.h> // for tbb::split
1817

1918
namespace openvdb {
2019
OPENVDB_USE_VERSION_NAMESPACE

openvdb/openvdb/points/PointSample.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,16 @@
1010
#ifndef OPENVDB_POINTS_POINT_SAMPLE_HAS_BEEN_INCLUDED
1111
#define OPENVDB_POINTS_POINT_SAMPLE_HAS_BEEN_INCLUDED
1212

13-
#include <openvdb/util/NullInterrupter.h>
14-
#include <openvdb/tools/Interpolation.h>
13+
#include "openvdb/util/NullInterrupter.h"
14+
#include "openvdb/thread/Threading.h"
15+
#include "openvdb/tools/Interpolation.h"
1516

1617
#include "PointDataGrid.h"
1718
#include "PointAttribute.h"
1819

1920
#include <sstream>
2021
#include <type_traits>
2122

22-
2323
namespace openvdb {
2424
OPENVDB_USE_VERSION_NAMESPACE
2525
namespace OPENVDB_VERSION_NAME {
@@ -300,7 +300,7 @@ class PointDataSampler
300300
using TargetHandleT = AttributeWriteHandle<typename SamplerWrapperT::ValueType>;
301301

302302
if (util::wasInterrupted(interrupter)) {
303-
tbb::task::self().cancel_group_execution();
303+
thread::cancelGroupExecution();
304304
return;
305305
}
306306

openvdb/openvdb/thread/Threading.h

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Copyright Contributors to the OpenVDB Project
2+
// SPDX-License-Identifier: MPL-2.0
3+
//
4+
/// @file Threading.h
5+
6+
#ifndef OPENVDB_THREAD_THREADING_HAS_BEEN_INCLUDED
7+
#define OPENVDB_THREAD_THREADING_HAS_BEEN_INCLUDED
8+
9+
#include "openvdb/version.h"
10+
11+
/// @note tbb/blocked_range.h is the ONLY include that persists from TBB 2020
12+
/// to TBB 2021 that itself includes the TBB specific version header files.
13+
/// In TBB 2020, the version header was called tbb/stddef.h. In 2021, it's
14+
/// called tbb/version.h. We include tbb/blocked_range.h here to indirectly
15+
/// access the version defines in a consistent way so that downstream
16+
/// software doesn't need to provide compile time defines.
17+
#include <tbb/blocked_range.h>
18+
#include <tbb/task.h>
19+
#include <tbb/task_group.h>
20+
21+
namespace openvdb {
22+
OPENVDB_USE_VERSION_NAMESPACE
23+
namespace OPENVDB_VERSION_NAME {
24+
namespace thread {
25+
26+
inline bool cancelGroupExecution()
27+
{
28+
// @note 12000 was the 2021.1-beta05 release. The 2021.1-beta08 release
29+
// introduced current_context().
30+
#if TBB_INTERFACE_VERSION >= 12002
31+
auto ctx = tbb::task::current_context();
32+
return ctx ? ctx->cancel_group_execution() : false;
33+
#else
34+
return tbb::task::self().cancel_group_execution();
35+
#endif
36+
}
37+
38+
inline bool isGroupExecutionCancelled()
39+
{
40+
// @note 12000 was the 2021.1-beta05 release. The 2021.1-beta08 release
41+
// introduced current_context().
42+
#if TBB_INTERFACE_VERSION >= 12002
43+
auto ctx = tbb::task::current_context();
44+
return ctx ? ctx->is_group_execution_cancelled() : false;
45+
#else
46+
return tbb::task::self().is_cancelled();
47+
#endif
48+
}
49+
50+
} // namespace thread
51+
} // namespace OPENVDB_VERSION_NAME
52+
} // namespace openvdb
53+
54+
#endif // OPENVDB_THREAD_THREADING_HAS_BEEN_INCLUDED

openvdb/openvdb/tools/Composite.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
#include <tbb/parallel_for.h>
2525
#include <tbb/parallel_reduce.h>
2626
#include <tbb/task_group.h>
27-
#include <tbb/task_scheduler_init.h>
2827

2928
#include <type_traits>
3029
#include <functional>

0 commit comments

Comments
 (0)