uxlfoundation / oneTBB

oneAPI Threading Building Blocks (oneTBB)
https://uxlfoundation.github.io/oneTBB/
Apache License 2.0
5.75k stars 1.02k forks source link

tbb::parallel_for_each build fail on gcc 9.4.0 using C++20 #1552

Open mcaryl-digitalbarriers opened 3 weeks ago

mcaryl-digitalbarriers commented 3 weeks ago

Summary

We are trying to use tbb::parallel_for_each within a project compiled with gcc 9.4.0 within an Ubuntu 20.04 environment. We have been using C++17 and are moving to C++20. tbb was compiling correctly with C++17. However with C++20 we see build errors relating to missing std::random_access_iterator. I think this is due to a mistake in dealing with collections in development versions of C++20.

Specifically I think the problem is with an if-def in parallel_for_each.h:

#if __TBB_CPP20_PRESENT
...
#endif // __TBB_CPP20_PRESENT

I believe this should be:

#if __TBB_CPP20_CONCEPTS_PRESENT
...
#endif // __TBB_CPP20_CONCEPTS_PRESENT

Other if-def in this file use the second form to cope with the absence of concepts in development versions of C++20 for gcc 9.4.0. The first form is sufficient for non-development versions of C++20 but not early versions. Making this change fixes the build for me.

Version

define TBB_VERSION_MAJOR 2021

define TBB_VERSION_MINOR 13

define TBB_VERSION_PATCH 0

Environment

Ubuntu 20.04 (within WSL) gcc 9.4.0 It's probably just gcc that's important.

Observed Behavior

Trying to compile:

    std::vector<SampleStruct> tasks;
...
    tbb::parallel_for_each(tasks.begin(), tasks.end(), Invoker<SampleStruct>());

Build error:

.../vcpkg_installed/x64-ubuntu-20-04-release/include/oneapi/tbb/parallel_for_each.h:427:29: error: no member named 'random_access_iterator' in namespace 'std' [clang-diagnostic-error]
    std::conditional_t<std::random_access_iterator<It>,
                            ^
.../vcpkg_installed/x64-ubuntu-20-04-release/include/oneapi/tbb/parallel_for_each.h:427:52: error: 'It' does not refer to a value [clang-diagnostic-error]
    std::conditional_t<std::random_access_iterator<It>,
                                                   ^
.../vcpkg_installed/x64-ubuntu-20-04-release/include/oneapi/tbb/parallel_for_each.h:425:20: note: declared here
template <typename It>
                   ^
.../vcpkg_installed/x64-ubuntu-20-04-release/include/oneapi/tbb/parallel_for_each.h:427:55: error: expected ';' after alias declaration [clang-diagnostic-error]
    std::conditional_t<std::random_access_iterator<It>,
                                                      ^
.../vcpkg_installed/x64-ubuntu-20-04-release/include/oneapi/tbb/parallel_for_each.h:428:55: error: expected unqualified-id [clang-diagnostic-error]
                       std::random_access_iterator_tag,
                                                      ^
.../vcpkg_installed/x64-ubuntu-20-04-release/include/oneapi/tbb/parallel_for_each.h:435:5: error: no template named 'iterator_tag_dispatch_impl' [clang-diagnostic-error]
    iterator_tag_dispatch_impl<typename move_iterator_dispatch_helper<It>::type>;
    ^
.../vcpkg_installed/x64-ubuntu-20-04-release/include/oneapi/tbb/parallel_for_each.h:501:83: error: no template named 'iterator_tag_dispatch' [clang-diagnostic-error]
template <typename Iterator, typename Body, typename Item, typename IteratorTag = iterator_tag_dispatch<Iterator>>
                                                                                  ^
.../vcpkg_installed/x64-ubuntu-20-04-release/include/oneapi/tbb/parallel_for_each.h:629:9: error: too few template arguments for class template 'for_each_root_task' [clang-diagnostic-error]
        for_each_root_task<Iterator, Body, ItemType> root_task(first, last, body, w_context, context);
        ^
.../vcpkg_installed/x64-ubuntu-20-04-release/include/oneapi/tbb/parallel_for_each.h:502:7: note: template is declared here
class for_each_root_task : public for_each_root_task_base<Iterator, Body, Item>
      ^

Expected Behavior

Clean build.

Steps To Reproduce

Sorry. I haven't checked this as vcpkg isn't supplying the latest version. It should be visible with the correct compiler gcc 9.4.0 with a simple test program:

#include <tbb/parallel_for_each.h>

void ParallelApplyFooToList( const std::vector<Item>& list ) {
    parallel_for_each( list.begin(), list.end(), ApplyFoo() );
}
dnmokhov commented 3 weeks ago

Thank you for reporting this, @mcaryl-digitalbarriers. It seems that the build errors your are getting come from clang-tidy, not from GCC. Have you checked your project's clang-tidy settings (w.r.t. C++17 vs. C++20)?

mcaryl-digitalbarriers commented 2 weeks ago

Good point, my mistake. Thanks for the quick response.

It's a cmake project and we use set(CMAKE_CXX_STANDARD 20) which, I think, should ensure clang-tidy is getting the same settings. Disabling clang-tidy does allow the build to complete but isn't ideal. We can control which checks clang-tidy performs but clang-diagnostic-error aren't checks. They come from the clang compiler it is using to check the code. I've had to deal with some of those recently and the only solution I found was to change the code.

I think the bug and fix still stands but the cause is about clang-tidy. That reports LLVM version 10.0.0.