2013-11-13 6 views
4

В качестве альтернативы accelerate, я пытаюсь вызвать код CUDA через FFI Haskell.Использование GHC с NVCC

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

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, и все работало просто отлично)

Howver, используя 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 варианты предназначены для linking gcc (и по-видимому icc) с неопределенными символами, что-то nvcc явно не нравится.

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

-------- EDIT -----------------

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

+0

Просто связывание gcc с -lcudart не совсем разрезает: я получаю неопределенные символы для своих функций, объявленных в cuda_code.cu. Возможно, разные форматы .o? – crockeea

ответ

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 

Compile с:

>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".

3

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.

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

Будьте любезны и держите людей в помиловании об этом на [email protected]. Я уверен, что есть и другие, которые тоже пытаются что-то подобное!

+1

Я предполагаю, что что-то подобное было сделано раньше, например, с http://hackage.haskell.org/package/cuda-0.5.1.0. В нем упоминается поиск 'nvcc' в $ PATH. – crockeea

Смежные вопросы