【问题标题】:Using GHC with NVCC将 GHC 与 NVCC 一起使用
【发布时间】:2013-11-13 15:02:54
【问题描述】:

作为accelerate 的替代方案,我试图通过Haskell 的FFI 调用CUDA 代码。

这是一个编译失败的简单程序:

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 的引用等)。这并不奇怪,显而易见的解决方案(对我来说)是使用-pgml nvcc 与 NVCC 链接。 (当我在 C 代码中使用 Intel CILK+ 时,这很有效:我只是将链接器更改为 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 选项适用于带有未定义符号的linking gcc(显然是icc),nvcc 显然不喜欢。

我不知道 GHC 如何链接文件。关于如何让 GHC 链接到我的 CUDA 代码的想法?

--------编辑-----------------

有人建议我尝试与 GCC 链接(像往常一样),但将必要的链接器选项传递给 gcc,以便它可以链接到 CUDA 库。如果有人知道这些可能是什么,这可能会起作用!

【问题讨论】:

  • 仅将 gcc 与 -lcudart 链接并不能完全解决问题:我在 cuda_code.cu 中声明的函数有未定义的符号。也许不同的 .o 格式?

标签: haskell linker ghc nvcc


【解决方案1】:

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 中。)

这是我为 RTS 找到的:

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

据我所知,这是在package.conf.dld-options: 部分中具有这些自定义-u 选项的唯一 包。

不幸的是,这些必须为使用不同选项接口的编译器/链接器翻译。

请保持友善,让人们在haskell-cafe@haskell.org 上发布相关信息。我敢肯定还有其他人也在尝试这样的事情!

【讨论】:

【解决方案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" 显式标记每个函数。

【讨论】:

    猜你喜欢
    • 2015-12-18
    • 2014-07-27
    • 2012-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多