Использование GHC с NVCC

В качестве альтернативы ускорению я пытаюсь вызвать код CUDA вместо FFI на Haskell.

Вот простая программа, которая не компилируется:

cuda_code.cu:

void cuda_init() {
    cudaFree (0);
    cudaThreadSynchronize ();
}

Test.hs:

foreign import ccall unsafe "cuda_init" cuda_init :: IO ()
main = cuda_init

Я собрал с

$> nvcc -c -o cuda_code.o cuda_code.cu
$> ghc Test cuda_code.o

и получил несколько ошибок компоновки (неопределенная ссылка на cudaFree и т. д.). Это не очень удивительно, и очевидное решение (для меня) состоит в том, чтобы связаться с NVCC, используя -pgml nvcc, (Это работало, когда я использовал Intel CILK+ в своем коде C: я просто изменил компоновщик на ICC, и все работало просто отлично.)

Однако использование NVCC для связи приводит к ошибке компоновки:

ghc Test -pgml nvcc cuda_code.o
[1 of 1] Compiling Main             ( Test.hs, Test.o )
Linking Test ...
nvcc fatal   : Unknown option 'u'

Бег

strace -v -f -e execve ghc Test -pgml nvcc cuda_code.o

(есть ли более простой способ?) Я обнаружил ghc звонит nvcc с

nvcc ... -L~/ghc... -L... -l... -l... -u ghczmprim_GHC... -u ghc...

Я предполагаю -u варианты предназначены для связыванияgcc (и, видимо, icc) с неопределенными символами, что-то nvcc явно не нравится

Я не знаю, как GHC связывает файлы. Мысли о том, как я могу получить GHC для ссылки на мой код CUDA?

--------РЕДАКТИРОВАТЬ-----------------

Кто-то предложил мне попробовать установить связь с GCC (как обычно), но передать необходимые параметры компоновщика, чтобы gcc так что он может ссылаться на библиотеки CUDA. Если кто-нибудь знает, что это может быть, это, вероятно, сработает!

2 ответа

Решение

Я понял, как заставить это работать.

cudaTest.cu:

// the `extern "C"` is important! It tells nvcc to not 
// mangle the name, since nvcc assumes C++ code by default
extern "C" 
void cudafunc() {
  cudaFree(0);
  cudaThreadSynchronize();
}

Test.hs

foreign import ccall unsafe "cudafunc" cudaFunc :: IO ()
main = cudaFunc

Компилировать с:

>nvcc -c -o cudaTest.o cudaTest.cu
>ghc --make Test.hs -o Test cudaTest.o -optl-lcudart

Я также попытался дать GHC возможность -pgmc g++ и удаление extern "C" (что я ожидал работать), но получил ошибки компиляции в некоторых заголовочных файлах CUDA. Вероятно, есть какой-то простой способ исправить это, так что вам не нужно явно отмечать каждую функцию extern "C",

GHC использует /usr/lib/ghc/settings определить параметры компилятора и компоновщика, а также файлы для каждого пакета, такие как /var/lib/ghc/package.conf.d/builtin_rts.conf определить специфичные для пакета опции компоновщика. (Выборочная директория будет иметь их в ${GHC}/lib/ghc-${VERSION}/settings а также ${GHC}/lib/ghc-${VERSION}/package.conf.d соответственно.)

Вот что я нашел для РТС:

ld-options: -u ghczmprim_GHCziTypes_Izh_static_info -u
            ghczmprim_GHCziTypes_Czh_static_info -u
            ghczmprim_GHCziTypes_Fzh_static_info -u
            ghczmprim_GHCziTypes_Dzh_static_info
            ...

Согласно ld справочная страница, -u опция определяет символ как неопределенный extern это должно быть определено где-то еще.

Насколько я знаю, это единственный пакет, который имеет эти обычаи -u варианты в ld-options: раздел package.conf.d,

К сожалению, они должны быть переведены для компилятора / компоновщика, который использует другой интерфейс опции.

Будьте так добры и держите людей в курсе об этом на haskell-cafe@haskell.org. Я уверен, что другие тоже пытаются что-то подобное!

Другие вопросы по тегам