3

I tried to write a basic C++ program using TBB and lambda expression, but I can't compile it.

#include <iostream>
#include <cstdlib>
#include <tbb/parallel_for.h>
#include <tbb/blocked_range.h>

using namespace std;
using namespace tbb;

void Foo(int number) {
    cout<<number<<endl;
}

void ParallelApplyFoo(int* a, size_t n) {
    parallel_for(blocked_range<size_t > (0, n),
            [ = ](const blocked_range<size_t>& r){
        for (size_t i = r.begin(); i != r.end(); ++i)
                Foo(a[i]);
        }
    );
}

int main(int argc, char** argv) {
    int num = 10;
    int* a = new int[num];
    for(int i = 0; i < num; i++)
        a[i] = i;
    ParallelApplyFoo(a,num);
    return 0;
}

And compiler messages:

main.cpp: In function ‘void ParallelApplyFoo(int*, size_t)’:
main.cpp:25:9: warning: lambda expressions only available with -std=c++11 or -std=gnu++11 [enabled by default]
main.cpp:26:5: error: no matching function for call to ‘parallel_for(tbb::blocked_range, ParallelApplyFoo(int*, size_t)::&)>)’
main.cpp:26:5: note: candidates are:
In file included from main.cpp:10:0:
/usr/include/tbb/parallel_for.h:161:6: note: template void tbb::parallel_for(const Range&, const Body&)
main.cpp:26:5: error: template argument for ‘template void tbb::parallel_for(const Range&, const Body&)’ uses local type ‘ParallelApplyFoo(int*, size_t)::&)>’
main.cpp:26:5: error:   trying to instantiate ‘template void tbb::parallel_for(const Range&, const Body&)’
In file included from main.cpp:10:0:
/usr/include/tbb/parallel_for.h:168:6: note: template void tbb::parallel_for(const Range&, const Body&, const tbb::simple_partitioner&)
/usr/include/tbb/parallel_for.h:168:6: note:   template argument deduction/substitution failed:
main.cpp:26:5: note:   candidate expects 3 arguments, 2 provided
In file included from main.cpp:10:0:
/usr/include/tbb/parallel_for.h:175:6: note: template void tbb::parallel_for(const Range&, const Body&, const tbb::auto_partitioner&)
/usr/include/tbb/parallel_for.h:175:6: note:   template argument deduction/substitution failed:
main.cpp:26:5: note:   candidate expects 3 arguments, 2 provided
In file included from main.cpp:10:0:
/usr/include/tbb/parallel_for.h:182:6: note: template void tbb::parallel_for(const Range&, const Body&, tbb::affinity_partitioner&)
/usr/include/tbb/parallel_for.h:182:6: note:   template argument deduction/substitution failed:
main.cpp:26:5: note:   candidate expects 3 arguments, 2 provided
In file included from main.cpp:10:0:
/usr/include/tbb/parallel_for.h:190:6: note: template void tbb::parallel_for(const Range&, const Body&, const tbb::simple_partitioner&, tbb::task_group_context&)
/usr/include/tbb/parallel_for.h:190:6: note:   template argument deduction/substitution failed:
main.cpp:26:5: note:   candidate expects 4 arguments, 2 provided
In file included from main.cpp:10:0:
/usr/include/tbb/parallel_for.h:197:6: note: template void tbb::parallel_for(const Range&, const Body&, const tbb::auto_partitioner&, tbb::task_group_context&)
/usr/include/tbb/parallel_for.h:197:6: note:   template argument deduction/substitution failed:
main.cpp:26:5: note:   candidate expects 4 arguments, 2 provided
In file included from main.cpp:10:0:
/usr/include/tbb/parallel_for.h:204:6: note: template void tbb::parallel_for(const Range&, const Body&, tbb::affinity_partitioner&, tbb::task_group_context&)
/usr/include/tbb/parallel_for.h:204:6: note:   template argument deduction/substitution failed:
main.cpp:26:5: note:   candidate expects 4 arguments, 2 provided
In file included from main.cpp:10:0:
/usr/include/tbb/parallel_for.h:248:6: note: template void tbb::strict_ppl::parallel_for(Index, Index, const Function&, tbb::task_group_context&)
/usr/include/tbb/parallel_for.h:248:6: note:   template argument deduction/substitution failed:
main.cpp:26:5: note:   deduced conflicting types for parameter ‘Index’ (‘tbb::blocked_range’ and ‘ParallelApplyFoo(int*, size_t)::&)>’)
In file included from main.cpp:10:0:
/usr/include/tbb/parallel_for.h:235:6: note: template void tbb::strict_ppl::parallel_for(Index, Index, Index, const Function&, tbb::task_group_context&)
/usr/include/tbb/parallel_for.h:235:6: note:   template argument deduction/substitution failed:
main.cpp:26:5: note:   deduced conflicting types for parameter ‘Index’ (‘tbb::blocked_range’ and ‘ParallelApplyFoo(int*, size_t)::&)>’)
In file included from main.cpp:10:0:
/usr/include/tbb/parallel_for.h:228:6: note: template void tbb::strict_ppl::parallel_for(Index, Index, const Function&)
/usr/include/tbb/parallel_for.h:228:6: note:   template argument deduction/substitution failed:
main.cpp:26:5: note:   deduced conflicting types for parameter ‘Index’ (‘tbb::blocked_range’ and ‘ParallelApplyFoo(int*, size_t)::&)>’)
In file included from main.cpp:10:0:
/usr/include/tbb/parallel_for.h:215:6: note: template void tbb::strict_ppl::parallel_for(Index, Index, Index, const Function&)
/usr/include/tbb/parallel_for.h:215:6: note:   template argument deduction/substitution failed:
main.cpp:26:5: note:   deduced conflicting types for parameter ‘Index’ (‘tbb::blocked_range’ and ‘ParallelApplyFoo(int*, size_t)::&)>’)
gmake[2]: *** [build/Release/GNU-Linux-x86/main.o] Error 1

I tried compiler flag "-std=c++11" and "-std=gnu++11" which outputs then:

g++ -std=gnu++11    -o dist/Release/GNU-Linux-x86/test build/Release/GNU-Linux-x86/main.o  
build/Release/GNU-Linux-x86/main.o: In function `tbb::interface6::internal::start_for, ParallelApplyFoo(int*, unsigned int)::{lambda(tbb::blocked_range const&)#1}, tbb::auto_partitioner>::~start_for()':
main.cpp:(.text+0x6): undefined reference to `vtable for tbb::task'
build/Release/GNU-Linux-x86/main.o: In function `tbb::interface6::internal::start_for, ParallelApplyFoo(int*, unsigned int)::{lambda(tbb::blocked_range const&)#1}, tbb::auto_partitioner>::~start_for()':
main.cpp:(.text+0x26): undefined reference to `vtable for tbb::task'
build/Release/GNU-Linux-x86/main.o: In function `tbb::interface6::internal::start_for, ParallelApplyFoo(int*, unsigned int)::{lambda(tbb::blocked_range const&)#1}, tbb::auto_partitioner>::run(tbb::blocked_range const&, {lambda(tbb::blocked_range const&)#1} const&, ParallelApplyFoo(int*, unsigned int)::{lambda(tbb::blocked_range const&)#1} const&)':
main.cpp:(.text+0x9d): undefined reference to `tbb::task_group_context::init()'
main.cpp:(.text+0xb5): undefined reference to `tbb::internal::allocate_root_with_context_proxy::allocate(unsigned int) const'
main.cpp:(.text+0xe1): undefined reference to `tbb::internal::get_initial_auto_partitioner_divisor()'
main.cpp:(.text+0x107): undefined reference to `tbb::task_group_context::~task_group_context()'
main.cpp:(.text+0x116): undefined reference to `tbb::task_group_context::~task_group_context()'
main.cpp:(.text+0x12a): undefined reference to `vtable for tbb::task'
main.cpp:(.text+0x138): undefined reference to `tbb::internal::allocate_root_with_context_proxy::free(tbb::task&) const'
build/Release/GNU-Linux-x86/main.o: In function `tbb::interface6::internal::start_for, ParallelApplyFoo(int*, unsigned int)::{lambda(tbb::blocked_range const&)#1}, tbb::auto_partitioner>::execute()':
main.cpp:(.text+0x251): undefined reference to `tbb::internal::allocate_continuation_proxy::allocate(unsigned int) const'
main.cpp:(.text+0x27b): undefined reference to `tbb::internal::allocate_child_proxy::allocate(unsigned int) const'
main.cpp:(.text+0x313): undefined reference to `tbb::internal::allocate_continuation_proxy::allocate(unsigned int) const'
main.cpp:(.text+0x33d): undefined reference to `tbb::internal::allocate_child_proxy::allocate(unsigned int) const'
main.cpp:(.text+0x4b6): undefined reference to `tbb::internal::allocate_continuation_proxy::allocate(unsigned int) const'
main.cpp:(.text+0x4e8): undefined reference to `tbb::internal::allocate_child_proxy::allocate(unsigned int) const'
main.cpp:(.text+0x585): undefined reference to `tbb::task_group_context::is_group_execution_cancelled() const'
build/Release/GNU-Linux-x86/main.o: In function `tbb::interface6::internal::flag_task::~flag_task()':
main.cpp:(.text._ZN3tbb10interface68internal9flag_taskD2Ev[_ZN3tbb10interface68internal9flag_taskD5Ev]+0x6): undefined reference to `vtable for tbb::task'
build/Release/GNU-Linux-x86/main.o: In function `tbb::interface6::internal::signal_task::~signal_task()':
main.cpp:(.text._ZN3tbb10interface68internal11signal_taskD2Ev[_ZN3tbb10interface68internal11signal_taskD5Ev]+0x6): undefined reference to `vtable for tbb::task'
build/Release/GNU-Linux-x86/main.o: In function `tbb::interface6::internal::signal_task::~signal_task()':
main.cpp:(.text._ZN3tbb10interface68internal11signal_taskD0Ev[_ZN3tbb10interface68internal11signal_taskD0Ev]+0x6): undefined reference to `vtable for tbb::task'
build/Release/GNU-Linux-x86/main.o: In function `tbb::interface6::internal::flag_task::~flag_task()':
main.cpp:(.text._ZN3tbb10interface68internal9flag_taskD0Ev[_ZN3tbb10interface68internal9flag_taskD0Ev]+0x6): undefined reference to `vtable for tbb::task'
build/Release/GNU-Linux-x86/main.o:(.rodata+0x20): undefined reference to `typeinfo for tbb::task'
build/Release/GNU-Linux-x86/main.o:(.rodata._ZTVN3tbb10interface68internal11signal_taskE[_ZTVN3tbb10interface68internal11signal_taskE]+0x14): undefined reference to `tbb::task::note_affinity(unsigned short)'
build/Release/GNU-Linux-x86/main.o:(.rodata._ZTVN3tbb10interface68internal9flag_taskE[_ZTVN3tbb10interface68internal9flag_taskE]+0x14): undefined reference to `tbb::task::note_affinity(unsigned short)'
build/Release/GNU-Linux-x86/main.o:(.rodata._ZTIN3tbb10interface68internal11signal_taskE[_ZTIN3tbb10interface68internal11signal_taskE]+0x8): undefined reference to `typeinfo for tbb::task'
build/Release/GNU-Linux-x86/main.o:(.rodata._ZTIN3tbb10interface68internal9flag_taskE[_ZTIN3tbb10interface68internal9flag_taskE]+0x8): undefined reference to `typeinfo for tbb::task'

I am using Fedora 18 (tbb and tbb-devel packages installed of course).

Anyone some ideas please? The code is copied from here: http://software.intel.com/en-us/blogs/2009/08/03/parallel_for-is-easier-with-lambdas-intel-threading-building-blocks

8
  • 1
    lambda expressions only available with -std=c++11 or -std=gnu++11 - what do you think about adding one of those compilation flags? Commented Mar 17, 2013 at 23:55
  • @zch i tried -std=c++11, but firstly it says that it is "enabled by default" and secondly there are many more and weird errors than without the flag Commented Mar 18, 2013 at 0:01
  • @kolage Then post those errors. Also, what compiler are you using? Commented Mar 18, 2013 at 0:04
  • @kolage You forgot to link the libraries. Commented Mar 18, 2013 at 0:07
  • 1
    @kolage But you have to tell the linker to use them, i.e. -l<libraryname>, whatever the right one is, maybe -ltbb? Commented Mar 18, 2013 at 0:18

1 Answer 1

4

Solved it using -ltbb compiler flag, found here: http://goparallel.sourceforge.net/compiling-tbb-programs-and-examples-on-linux-ubuntu/. Anyway, thanks everyone for help :)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.