Этот вопрос очень связан с:
A) Как разделить код CUDA на несколько файлов
B) Ошибка связи LNK2005 при попытке собрать несколько файлов CUDA вместе
Следующий совет здесь:
https://meta.stackexchange.com/questions/42343/same-question-but-not-quite
и здесь
https://meta.stackexchange.com/questions/8910/asking-a-similar-but-not-the-same-question
Я задаю очень похожий вопрос, но я хочу абсолютно четко понять, в чем разница между моим вопросом и вопросами, связанными выше.
Я получал ошибки компоновщика из заголовка при включении файла заголовка, который содержал определение функции __device__
, в несколько исходных файлов.
Это отличается от соединения А), когда те же ошибки возникают с функциями __kernel__
, поскольку __device__
в соответствии с руководством CUDA подразумевает inline
:
В коде устройства, скомпилированном для устройств с вычислительной возможностью 1.x, функция __device__
всегда встроена по умолчанию. Однако спецификатор функции __noinline__
может использоваться для подсказки компилятору, чтобы он не включал функцию, если это возможно (см. Раздел E.1).
Ссылка B) более связана (и один ответ правильно указывает на то, что кажется, что она не является встроенной независимо от того, что написано в руководстве), но ссылка B) относится к заголовку, поставляемому NVIDIA, а не к собственному заголовку, так что пока проблема скорее всего, лежит в моем заголовочном файле, наиболее вероятно, что он лежит в заголовочном файле NVIDIA. Другими словами, вполне вероятно, что ссылка B) и мои вопросы имеют разные ответы.
Тем временем я обнаружил, что объявление функции как __device__ inline
решает проблему, поэтому вышеизложенное только документирует решение для остального мира.
Открытый вопрос является причиной такого поведения.
Возможные объяснения, которые я придумал:
- Руководство неверно
nvcc -arch=compute_11
не квалифицируется как «компиляция для устройств с вычислительными возможностями 1.x» или есть ошибка в nvcc
- Это специфично для MS-VS и работает на платформах, протестированных NVIDIA
- У меня серьезное неправильное представление о том, как
inline
работает. Здесь можно найти пример, не относящийся к cuda: Многозначно определенная ошибка компоновщика с использованием встроенных функций Насколько я понимаю, в выражении "caf" указано, что "компилятор не должен генерировать внешнее определение функции, поэтому это не должно беспокоить компоновщика "другие там, казалось, не согласны.
Я бы очень признателен, если бы кто-то с большим умом мог прояснить, что здесь происходит.