Можно ли использовать С++ 11 в .cu файлах (CUDA5.5) в Windows7x64 (MSVC) и Linux64 (GCC4.8.2)?

Когда я компилирую следующий код, содержащий конструкцию С++ 11, в Windows7x64 (MSVS2012 + Nsight 2.0 + CUDA5.5), то я не получаю ошибок, и все компилируется и работает хорошо:

#include <thrust/device_vector.h>

int main() {
    thrust::device_vector<int> dv(10);
    auto iter = dv.begin();

    return 0;
}

Но когда я пытаюсь скомпилировать его под Linux64 (Debian 7 Wheezey + Nsight Eclipse из CUDA5.5), я получаю ошибки:

../src/CudaCpp11.cu(5): ошибка: явный тип отсутствует ( "int" Предполагается)

../src/CudaCpp11.cu(5): ошибка: нет подходящей функции преобразования из

"thrust:: detail:: normal_iterator > " to "int" существует

2 ошибки, обнаруженные при компиляции "/tmp/tmpxft_00001520_00000000-6_CudaCpp11.cpp1.ii". делать: * [src/CudaCpp11.o] Ошибка 2

Когда я добавил строку: -stdС++ 11

в свойствах- > Строить- > Настройки- > Настройки инструмента- > Строки стажа- > Параметры препроцессора (-Xcompiler)

Я получаю больше ошибок:

/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h(432): ошибка: Идентификатор "nullptr" равен undefined

/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h(432): ошибка: ожидаемый ";"

...

/usr/include/С++/4.8/bits/cpp_type_traits.h(314): error: namespace "std:: __ gnu_cxx" не имеет члена

"__ normal_iterator"

/usr/include/С++/4.8/bits/cpp_type_traits.h(314): ошибка: ожидается a " > "

Ошибка nvcc: "cudafe" умер из-за сигнала 11 (Недопустимая память ссылка) make: * [src/CudaCpp11.o] Ошибка 11

Только когда я использую thrust::device_vector<int>::iterator iter = dv.begin(); в Linux-GCC, я не получаю ошибку. Но в Windows MSVS2012 все функции С++ 11 работают нормально!

Можно ли использовать С++ 11 в .cu файлах (CUDA5.5) в Windows7x64 (MSVC) и Linux64 (GCC4.8.2)?

Ответы

Ответ 1

Вам, вероятно, придется расколоть main.cpp из ваших других .cu вот так:

others.hpp:

void others();

others.cu:

#include "others.hpp"
#include <boost/typeof/std/utility.hpp>
#include <thrust/device_vector.h>

void others() {
    thrust::device_vector<int> dv(10);
    BOOST_AUTO(iter, dv.begin()); // regular C++
}

main.cpp:

#include "others.hpp"

int main() {
    others();

    return 0;
}

Этот конкретный ответ показывает, что компиляция с официально поддерживаемой версией gcc (как правильно утверждал Роберт Кровелла) должна работать хотя бы для кода С++ 11 в main.cpp:

g++ -std=c++0x -c main.cpp
nvcc -arch=sm_20 -c others.cu 
nvcc -lcudart -o test main.o others.o

(протестирован на Debian 8 с nvcc 5.5 и gcc 4.7.3).

Чтобы ответить на ваш основной вопрос: я не знаю, что можно использовать С++ 11 в .cu файлах с CUDA 5.5 в Linux (и я не знал, что показан пример с С++ 11 на стороне хоста, - в соответствии с MSVC). Я даже подал запрос функции для поддержки constexpr, которая все еще открыта.

CUDA programming для CUDA 5.5:

Для хост-кода nvcc поддерживает любую часть С++ ISO/IEC 14882: 2003, который поддерживает компилятор хоста С++.

Для кода устройства nvcc поддерживает функции, показанные в коде Образцы с некоторыми ограничениями, описанными в Ограничениях; Это не поддерживать информацию о типе времени выполнения (RTTI), обработку исключений и Стандартная библиотека С++.

Во всяком случае, можно использовать некоторые из возможностей С++ 11, таких как auto в ядрах, например. с boost:: auto. Как внешний вид, другие возможности С++ 11, такие как threads, вряд ли могут оказаться в CUDA, и я еще не слышал официальных планов о них (по суперкомпьютер 2013).

Бесстыдный плагин: если вас интересует больше этих твиков, не стесняйтесь смотреть в нашу библиотеку libPMacc, которая обеспечивает мульти -GPU и абстракции частиц для моделирования. Мы реализовали lambda, STL-подобную концепцию доступа для матриц 1-3D и другие полезные материалы.

Все самое лучшее, Axel


Обновление. Поскольку поддержка CUDA 7.0 С++ 11 в ядрах была официально добавлена. Поскольку BenC указал нам правильно, части этой функции уже были добавлены молча в CUDA 6.5.

Ответ 2

По словам Джареда Хоброка (Thrust разработчик), похоже, что поддержка С++ 11 была добавлена ​​в CUDA 6.5 (хотя она все еще экспериментальная и недокументированная). Это может облегчить работу при использовании С++ 11 в очень больших проектах С++/CUDA, так как разделение всего может быть довольно громоздким для больших проектов при использовании CMake, например.