Вопрос или проблема
Я компилировал свой .cu
файл с -arch=sm_75 -rdc=true --expt-extended-lambda
, переданными в nvcc (v12.4.99, windows, vs 17 2022). Однако я получил error LNK2019: unresolved external symbol
:
LINK : error LNK2019: unresolved external symbol __cudaRegisterLinkedBinary_81293256_4_t_cu_2bebb7d5_7784 referenced in function "void __cdecl __nv_cudaEntityRegisterCallback(void * *)" (?__nv_cudaEntityRegisterCallback@@YAXPEAPEAX@Z)
Код, который я компилировал:
template <typename F, typename... Args> __device__ void exec(F f, uint32_t tid, Args &&...args) {
f(tid, static_cast<Args &&>(args)...);
}
template <typename F, typename... Args> __global__ void kernel(F f, Args... args) {
uint32_t tid = blockIdx.x * blockDim.x + threadIdx.x;
exec(f, tid, args...);
}
template <uint32_t X, uint32_t Y, typename F, typename... Args> void launch(F f, Args &&...args) {
kernel<F><<<X, Y>>>(f, static_cast<Args &&>(args)...);
}
int main() {
launch<4, 4>([] __device__(uint32_t id, uint32_t v) { printf("%u %u\n", id, v); }, 1u);
return 0;
}
Я думаю, что это вызвано -rdc
, как я могу это решить?
Ответ или решение
Ошибка "unresolved external symbol" в CUDA при использовании лямбда-функций зачастую возникает из-за неправильной компиляции или связывания кода, особенно когда применяется флаг -rdc=true
, который позволяет разделять код на несколько объектов и требует корректной регистрации каждого используемого устройства.
Возможные причины и решения
-
Неправильные настройки компилятора:
Когда вы используете-rdc=true
, необходимо убедиться, что все ваши CUDA-объекты правильно связаны друг с другом. Решение здесь сводится к тому, чтобы убедиться, что все ваши файлы.cu
компилируются с одинаковыми флагами и затем правильно связаны. -
Отсутствие связи с промежуточными бинарными файлами:
Если вы используете-rdc
, это означает, что CUDA может создавать промежуточные бинарные файлы. Ваша ошибка, связанная с__cudaRegisterLinkedBinary
указывает на то, что не удается найти определение необходимого символа. Это может быть вызвано тем, что ваши промежуточные бинарные файлы не скомпилированы, либо они не связаны. Убедитесь, что вы собираете проект, включая все.cu
файлы. -
Правильное использование лямбда-функций:
Запись лямбда-функций с__device__
требует использования флага--expt-extended-lambda
, как вы указали. Однако, необходимо также проверить, что вы не пропустили какие-либо шаги при регистрации функции. Убедитесь, что вся лямбда-функция и все ее переменные правильно настроены для передачи в ядро. -
Обновление драйверов и инструментов:
Иногда проблемы подобного рода могут быть вызваны устаревшими версиями драйверов или инструментов. Поэтому, проверьте, что у вас установлены все последние версии CUDA Toolkit и драйверов NVIDIA.
Рекомендации по исправлению
-
Компиляция и связывание:
Убедитесь, что вы компилируете с использованием команд подобной следующей:nvcc -arch=sm_75 -rdc=true --expt-extended-lambda *.cu -o output
Это обеспечит корректную компиляцию всех ваших файлов в один исполняемый файл.
-
Поддержка лямбда-функций в CUDA:
Проверьте, что ваш проект действительно поддерживает лямбда-функции, и в случае необходимости протестируйте их использование в более простых случаях для изоляции проблемы. -
Изучение документации:
Ознакомьтесь с последней документацией NVIDIA по поводу-rdc=true
, лямбда-функций и межфайлового связывания. Документация иногда содержит ключевые заметки о проблемах совместимости и оптимальных практиках.
Заключение
Ошибка "unresolved external symbol" при использовании -rdc=true
и лямбда-функций в CUDA может быть вызвана различными факторами, включая неправильные настройки компиляции и связывания. Следуя приведенным рекомендациям, вы сможете устранить эти проблемы и добиться успешной компиляции вашего CUDA-кода. Если ошибка сохраняется после выполнения всех вышеуказанных шагов, рекомендуется обратиться в поддержку NVIDIA или на специализированные форумы разработчиков, где можно получить помощь от сообщества экспертов.