Ошибки компоновщика 2005 и 1169 (несколько определенных символов) при использовании функций CUDA __device__ (по умолчанию должны быть встроены) - PullRequest
2 голосов
/ 16 ноября 2010

Этот вопрос очень связан с:

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" указано, что "компилятор не должен генерировать внешнее определение функции, поэтому это не должно беспокоить компоновщика "другие там, казалось, не согласны.

Я бы очень признателен, если бы кто-то с большим умом мог прояснить, что здесь происходит.

1 Ответ

1 голос
/ 16 ноября 2010

В MS VS, а также в gcc и, возможно, в других компиляторах (но не в том, на который ссылается ваша ссылка «ошибка многократного компоновщика»), inline подразумевает статический по умолчанию. Вы можете заставить функцию быть внешней inline, но, если вы этого не сделаете, компилятор либо не поместит внешнее определение функции в объектный файл, либо пометит его как безопасное для дублирования.

ОДНАКО, нигде в документации не говорится, что функции CUDA __device__ эффективно объявлены встроенными (и, следовательно, статическими). В документации сказано, что функция «всегда встроена по умолчанию». Есть тонкая разница.

...