How do I compile while using Boost's lockfree

2019-07-15 04:53发布

问题:

I'm trying to write a program in CUDA that will use Boost's single-producer/single-consumer queue on the host side, but I run into compiler errors as soon as I include <boost/lockfree/spsc_queue.hpp>.

At this point, I am doing nothing on the device, nor am I creating an spsc_queue object. The errors occurred as soon as I tried to compile with the above header.

Originally I was using Boost 1.54, compiling with GCC 4.8.4, and using all of the flags that come as part of the CUDA 7.0 makefile along with the following custom flags: -Xcompiler -fopenmp -lgomp -std=c++11 -lpthread. These are in the variable MYFLAGS, seen below:

main.o: main.cu
    $(EXEC) $(NVCC) $(INCLUDES) $(ALL_CCFLAGS) $(GENCODE_FLAGS) -c $(MYFLAGS) main.cu.

Then in the linking step, I have

$(EXEC) $(NVCC) $(ALL_LDFLAGS) $(GENCODE_FLAGS) -O2 $(MYFLAGS) -o runnable $(OBJECTS) $(LIBRARIES).

As soon as I included the header, I received this error:

/usr/include/boost/utility/detail/result_of_iterate.hpp:135:75: error:
    invalid use of qualified-name std::allocator_traits<_Alloc>::propagate_on_container_swap’

I searched for possible bugs in Boost, and I discovered this one. Unfortunately, that's not at all the issue I'm having.

I upgraded to Boost 1.58, and now I receive a different error:

boost_1_58_0/boost/lockfree/spsc_queue.hpp(352): error: too few arguments in function call.

The problem code in spsc_queue.hpp is part of a "reset" routine, but again, I haven't even declared an object yet.

void reset(void)
{
    if ( !boost::has_trivial_destructor<T>::value ) {
        // make sure to call all destructors!

        T dummy_element;
        while (pop(dummy_element))
        {}
    } else {
        write_index_.store(0, memory_order_relaxed);
        read_index_.store(0, memory_order_release);
    }
}

Hence, my question: How do I compile while using Boost's lockfree spsc_queue? What am I doing wrong?

回答1:

The problem is that nvcc is not as mature as e.g. g++ when it comes to complex C++ code such as Boost. Some Boost libraries work with nvcc, others fail to compile; boost::lockfree seems to belong to latter group.

A possible solution is to split host and device code, and compile all host code which includes headers nvcc does not understand with g++.