Skip to content

Added support for TBB 2021#1027

Merged
Idclip merged 11 commits intoAcademySoftwareFoundation:masterfrom
Idclip:tbb2021
Jun 25, 2021
Merged

Added support for TBB 2021#1027
Idclip merged 11 commits intoAcademySoftwareFoundation:masterfrom
Idclip:tbb2021

Conversation

@Idclip
Copy link
Copy Markdown
Contributor

@Idclip Idclip commented Apr 13, 2021

I believe this is the remaining work needed to support TBB 2021 except for the updates to Queue.h. This also needs testing so marking as a draft and pushing up for visibility.

Signed-off-by: Nick Avramoussis 4256455+Idclip@users.noreply.github.com

@e4lam
Copy link
Copy Markdown
Contributor

e4lam commented May 10, 2021

@Idclip I've noticed that in tools/PointAdvect.h we're still making calls to tbb::task::self().cancel_group_execution();. Is this still something yet to be addressed for TBB 2021 support?

In H19, I've added a UTparallelCancelGroupExecution(); that wraps this in UT_ParallelUtil.h with the appropriate defines to suppress the TBB 2020 deprecation warnings. The intention here being that when we move up to oneTBB 2021 (or beyond), then we can switch this to current_context()->cancel_group_execution() in one place. I've made a stab at fixing this in openvdb_houdini/Utils.h like this:

#if SYS_VERSION_FULL_INT < 0x130000f7 // 19.0.247
#include <tbb/task.h>
static inline void
UTparallelCancelGroupExecution()
{
    tbb::task::self().cancel_group_execution();
}
#endif

However, then I realized that this is insufficient because of tools/PointAdvect.h. Have you had any thoughts on this? Offhand, it feels like we would need to have a similar wrapper in openvdb itself.

@Idclip
Copy link
Copy Markdown
Contributor Author

Idclip commented May 12, 2021

hey @e4lam! I don't remember running into this, but it may very well be that I didn't properly try to build all the unit tests. As this isn't instantiated anywhere in the core lib/bins I probably didn't see it. You're saying that tbb::task::self().cancel_group_execution(); needs replacing with current_context()->cancel_group_execution()? Did current_context()->cancel_group_execution() exist in TBB 2019/2020? If so we might just be able to switch to that outright? If not, and tbb::task::self().cancel_group_execution(); was completely removed, that complicates things. We'd need to compile time branch in the headers, so we'd need a reliable #TBB define to rely on along with some wrapper that would exist in VDB itself.

@e4lam
Copy link
Copy Markdown
Contributor

e4lam commented May 12, 2021

@Idclip Starting with oneTBB 2021, tbb::task::self() was removed and current_context() was added. If we want to support both TBB and oneTBB, then a compile time branch is necessary. Did you try building openvdb_houdini with oneTBB 2021? I would expect it to fail.

@Idclip
Copy link
Copy Markdown
Contributor Author

Idclip commented May 12, 2021

@e4lam I did not get that far, thanks for confirming. Up till this point it seemed everything had a replacement which overlapped the versions we support. As you say, we'll need a wrapper in the VDB headers for this which could subsequently be used in the houdini plugin.

@e4lam
Copy link
Copy Markdown
Contributor

e4lam commented May 13, 2021

For reference, I've looked into this and it looks like TBB_INTERFACE_VERSION_MAJOR >= 12 could be a good test for oneTBB.

Annoyingly, the macro is provided by different headers though.
TBB: #include <tbb/tbb_stddef.h>
oneTBB: #include <tbb/version.h>

@Idclip
Copy link
Copy Markdown
Contributor Author

Idclip commented May 13, 2021

Annoyingly, the macro is provided by different headers though.

I'm going to assume that at least something consistent in TBB 2020/2021 propagates this define? i.e. maybe we include blocked_range.h or something. Not ideal, but don't see a better way if the version header has changed.

@e4lam
Copy link
Copy Markdown
Contributor

e4lam commented May 13, 2021

Oh interesting, yeah including blocked_range.h looks like the easiest thing to do.

Idclip added 4 commits June 10, 2021 13:12
Signed-off-by: Nick Avramoussis <4256455+Idclip@users.noreply.github.com>
Signed-off-by: Nick Avramoussis <4256455+Idclip@users.noreply.github.com>
Signed-off-by: Nick Avramoussis <4256455+Idclip@users.noreply.github.com>
Signed-off-by: Nick Avramoussis <4256455+Idclip@users.noreply.github.com>
Idclip added 2 commits June 10, 2021 14:43
Signed-off-by: Nick Avramoussis <4256455+Idclip@users.noreply.github.com>
Signed-off-by: Nick Avramoussis <4256455+Idclip@users.noreply.github.com>
@Idclip
Copy link
Copy Markdown
Contributor Author

Idclip commented Jun 10, 2021

I think I'm almost at a point to make this PR official. @e4lam I've added the wrapper logic to a new header util/Threading.h. I'm going to add at least one kind of CI test for TBB2021 before un-drafting(?) this PR

@danrbailey
Copy link
Copy Markdown
Contributor

I like this new threading header a lot, that's a good idea. One question is about whether we could potentially introduce a new namespace for all threading-related functionality? openvdb::thread::cancelGroupExecution() ? I don't know whether that would mandate a new openvdb/thread dir as well, but it would be nice to at least separate out everything related to threading and interaction with TBB in terms of namespacing if possible. It could also pave the way for potentially adopting a wrapper to TBB in the future that would allow us to build without it (openvdb::thread::ParallelFor, openvdb::thread::BlockedRange, etc), similar to the approach that nanovdb has taken.

Copy link
Copy Markdown
Contributor

@e4lam e4lam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for all the work on this!

@Idclip
Copy link
Copy Markdown
Contributor Author

Idclip commented Jun 10, 2021

One question is about whether we could potentially introduce a new namespace for all threading-related functionality?

I have no problem with this, but yeah it should probably live in a new appropriately named folder. Slightly odd to have such small logic introduce a new folder but, as you say, the new infrastructure will set a precedent to allow us to extending any more threading logic.

@Idclip Idclip linked an issue Jun 10, 2021 that may be closed by this pull request
Idclip added 3 commits June 10, 2021 20:33
Signed-off-by: Nick Avramoussis <4256455+Idclip@users.noreply.github.com>
Signed-off-by: Nick Avramoussis <4256455+Idclip@users.noreply.github.com>
Signed-off-by: Nick Avramoussis <4256455+Idclip@users.noreply.github.com>
@Idclip
Copy link
Copy Markdown
Contributor Author

Idclip commented Jun 11, 2021

I've added a basic test with an additional Mac build which builds the lib, binaries and unit tests. This really warrants something like a new latest.yml file which builds everything, or additions to the ax and houdini configs too, but I've left that out for now.

@danrbailey I've moved Threading.h into thread/Threading.h and renamed the namespace

@Idclip Idclip marked this pull request as ready for review June 11, 2021 10:38
-DOPENVDB_CXX_STRICT=OFF -DUSE_BLOSC=OFF -DUSE_ZLIB=OFF
- name: test
shell: bash
run: cd build && ctest -V
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New, very basic CI for TBB2021 in lieu of the intel docker images

// compile time branching (as we still support 2018), we use it in 2018 too by
// enabling the below define.
#define TBB_PREVIEW_GLOBAL_CONTROL 1
#include <tbb/global_control.h>
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Significant change

The VDB Render binary now uses tbb::global_control over tbb::task_scheduler_init


// get the global task arena
tbb::task_arena arena(tbb::task_arena::attach{});
arena.enqueue([task = std::move(task)] { task.execute(); });
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Significant change

Instead of queueing tasks through task::enqueue, add them to the global task arena.

@jmlait I think this is correct? i.e. tbb::task_arena arena(tbb::task_arena::attach{}); gets a hooks to the "default" arena so I don't need to keep the arena in scope? This could be improved by having an arena per Queue, but I'm trying to keep the changes as minimal as possible.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change is faithful to what the code previously did. Offhand, I don't see an advantage to using an arena per queue?

Copy link
Copy Markdown
Contributor Author

@Idclip Idclip Jun 14, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for confirming @e4lam. I'm trying to figure out what the better API would be, us wrapping the logic or delegating it to the caller. i.e:

Queue q;
q.concurrency(/*max threads*/1); // where each queue has its own configurable arena
q.write(...);

vs

// set arena for current scope
{
    tbb::task_arena arena(/*1*/);
    Queue q;
    q.write(...)
}

It's the same debate as the bool threaded = true argument that appears everywhere. In any case, not relevant for this PR.


namespace tbb { class split; } // forward declaration

#include <tbb/blocked_range.h> // for tbb::split
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Significant change

I couldn't find a nice way to fix the forward declaration between versions.

{
const auto grainSize = std::max<size_t>(
length / tbb::task_scheduler_init::default_num_threads(), 1024);
length / tbb::this_task_arena::max_concurrency(), 1024);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Significant change

This should now be affected by the caller configuring their own arena


// @note this grain size is used for optimal threading
const size_t numThreads = size_t(tbb::task_scheduler_init::default_num_threads());
const size_t numThreads = size_t(tbb::this_task_arena::max_concurrency());
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Significant change

This should now be affected by the caller configuring their own arena

using IndexPairListMapPtr = std::shared_ptr<IndexPairListMap>;

size_t numTasks = 1, numThreads = size_t(tbb::task_scheduler_init::default_num_threads());
size_t numTasks = 1, numThreads = size_t(tbb::this_task_arena::max_concurrency());
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Significant change

This should now be affected by the caller configuring their own arena

{
const auto grainSize = std::max<size_t>(
length / tbb::task_scheduler_init::default_num_threads(), 1024);
length / tbb::this_task_arena::max_concurrency(), 1024);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Significant change

This should now be affected by the caller configuring their own arena

r[i] = new(allocate_child()) ReadTask(acc);
w[i] = new(allocate_child()) WriteTask(acc);
tasks.run([&] { ReadTask r(acc); r.execute(); });
tasks.run([&] { WriteTask w(acc); w.execute(); });
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Significant change

This test tests multiple read/write accesses running concurrently. I believe I've ported it to represent that, even though the behaviour is not exactly identical.

@Idclip
Copy link
Copy Markdown
Contributor Author

Idclip commented Jun 11, 2021

I've commented the significant changes that may warrant more review. The rest should be pretty trivial.

@Idclip Idclip changed the title Work in progress to support TBB 2021 Added support for TBB 2021 Jun 11, 2021
Signed-off-by: Nick Avramoussis <4256455+Idclip@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

@danrbailey danrbailey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great, thanks Nick!

Signed-off-by: Nick Avramoussis <4256455+Idclip@users.noreply.github.com>
@Idclip Idclip merged commit e620aa6 into AcademySoftwareFoundation:master Jun 25, 2021
@Idclip Idclip deleted the tbb2021 branch June 25, 2021 22:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Incompatible with oneapi 2021.02 tbb. [BUILD] Please support tbb new version 2021.1.1 [REQUEST] Please support openTBB

3 participants