使用 g++ 编译器与 CUDA 目标文件链接的 Makefile
Makefile linking using g++ compiler with CUDA object files
我正在尝试使用 nvcc
编译 cuda 目标文件,并使用 g++
编译器编译最终的主脚本。我已经看到 this post 但无法让我的示例正常工作。我得到的错误似乎是链接错误:
nvcc -c -g -I -dlink -I/usr/local/cuda-11/include -I. -L/usr/local/cuda-11/lib64 -lcudart -lcurand module.cu -o module.o
g++ -I/usr/local/cuda-11/include -I. -L/usr/local/cuda-11/lib64 -lcudart -lcurand module.o main.cpp -o main
module.o: In function `call_kernel()':
/home/ubuntu/Desktop/CUDA/MPI&CUDA/module.cu:16: undefined reference to `__cudaPushCallConfiguration'
module.o: In function `__cudaUnregisterBinaryUtil()':
/usr/local/cuda-11/include/crt/host_runtime.h:259: undefined reference to `__cudaUnregisterFatBinary'
module.o: In function `__nv_init_managed_rt_with_module(void**)':
/usr/local/cuda-11/include/crt/host_runtime.h:264: undefined reference to `__cudaInitModule'
我做错了什么?我知道我可以简单地用 nvcc
编译 main.cpp
但这是我不想要的,因为在我的问题中,我稍后会用 mpicxx
替换 g++
并且有我的 main.cpp
脚本中的 MPI 代码。
我的 makefile 是:
INC := -I$(CUDA_HOME)/include -I.
LIB := -L$(CUDA_HOME)/lib64 -lcudart -lcurand
CUDAFLAGS=-c -g -I -dlink $(INC) $(LIB)
all: main
main: module.o
g++ $(INC) $(LIB) module.o main.cpp -o main
module.o: module.cu module.h
nvcc -c -g -I -dlink $(INC) $(LIB) module.cu -o module.o
clean:
rm -rf *.o
main.cpp
#include "module.h"
int main(){
return 0;
}
module.cu
#ifdef __CUDACC__
#define CUDA_GLOBAL __global__
#else
#define CUDA_GLOBAL
#endif
#include <cuda.h>
#include "module.h"
CUDA_GLOBAL
void kernel(){
}
void call_kernel(){
kernel<<<1,1>>>();
}
module.h
#ifndef _MODULE_H_
#define _MODULE_H_
#ifdef __CUDACC__
#define CUDA_GLOBAL __global__
#else
#define CUDA_GLOBAL
#endif
#include <numeric>
#include <cuda.h>
CUDA_GLOBAL
void kernel();
void call_kernel();
#endif
您的 link 行有误。所有库(例如 -lfoo
)必须位于 link 行的 end 处,位于所有目标文件(例如 .o
文件)之后。
不仅如此,它们还需要正确排序(但我不知道正确的顺序是什么所以也许上面是正确的)。
几乎所有现代 linker 都是“单程”linker,这意味着他们只通过图书馆一次,并且由于他们只提取符号,因为他们已经需要你必须首先为您的库排序“最高级别”的内容,然后是“较低级别”的内容。
感谢 MadScientist 的解释,linkages 必须在 link 行的末尾完成,毕竟 .o
个文件:
INC := -I$(CUDA_HOME)/include -I.
LIB := -L$(CUDA_HOME)/lib64 -lcudart -lcurand
all: main
main: module.o
mpicxx module.o main.cpp -o main $(INC) $(LIB)
module.o: module.cu module.h
nvcc -c -g module.cu -o module.o -I -dlink
clean:
rm -rf *.o
我正在尝试使用 nvcc
编译 cuda 目标文件,并使用 g++
编译器编译最终的主脚本。我已经看到 this post 但无法让我的示例正常工作。我得到的错误似乎是链接错误:
nvcc -c -g -I -dlink -I/usr/local/cuda-11/include -I. -L/usr/local/cuda-11/lib64 -lcudart -lcurand module.cu -o module.o
g++ -I/usr/local/cuda-11/include -I. -L/usr/local/cuda-11/lib64 -lcudart -lcurand module.o main.cpp -o main
module.o: In function `call_kernel()':
/home/ubuntu/Desktop/CUDA/MPI&CUDA/module.cu:16: undefined reference to `__cudaPushCallConfiguration'
module.o: In function `__cudaUnregisterBinaryUtil()':
/usr/local/cuda-11/include/crt/host_runtime.h:259: undefined reference to `__cudaUnregisterFatBinary'
module.o: In function `__nv_init_managed_rt_with_module(void**)':
/usr/local/cuda-11/include/crt/host_runtime.h:264: undefined reference to `__cudaInitModule'
我做错了什么?我知道我可以简单地用 nvcc
编译 main.cpp
但这是我不想要的,因为在我的问题中,我稍后会用 mpicxx
替换 g++
并且有我的 main.cpp
脚本中的 MPI 代码。
我的 makefile 是:
INC := -I$(CUDA_HOME)/include -I.
LIB := -L$(CUDA_HOME)/lib64 -lcudart -lcurand
CUDAFLAGS=-c -g -I -dlink $(INC) $(LIB)
all: main
main: module.o
g++ $(INC) $(LIB) module.o main.cpp -o main
module.o: module.cu module.h
nvcc -c -g -I -dlink $(INC) $(LIB) module.cu -o module.o
clean:
rm -rf *.o
main.cpp
#include "module.h"
int main(){
return 0;
}
module.cu
#ifdef __CUDACC__
#define CUDA_GLOBAL __global__
#else
#define CUDA_GLOBAL
#endif
#include <cuda.h>
#include "module.h"
CUDA_GLOBAL
void kernel(){
}
void call_kernel(){
kernel<<<1,1>>>();
}
module.h
#ifndef _MODULE_H_
#define _MODULE_H_
#ifdef __CUDACC__
#define CUDA_GLOBAL __global__
#else
#define CUDA_GLOBAL
#endif
#include <numeric>
#include <cuda.h>
CUDA_GLOBAL
void kernel();
void call_kernel();
#endif
您的 link 行有误。所有库(例如 -lfoo
)必须位于 link 行的 end 处,位于所有目标文件(例如 .o
文件)之后。
不仅如此,它们还需要正确排序(但我不知道正确的顺序是什么所以也许上面是正确的)。
几乎所有现代 linker 都是“单程”linker,这意味着他们只通过图书馆一次,并且由于他们只提取符号,因为他们已经需要你必须首先为您的库排序“最高级别”的内容,然后是“较低级别”的内容。
感谢 MadScientist 的解释,linkages 必须在 link 行的末尾完成,毕竟 .o
个文件:
INC := -I$(CUDA_HOME)/include -I.
LIB := -L$(CUDA_HOME)/lib64 -lcudart -lcurand
all: main
main: module.o
mpicxx module.o main.cpp -o main $(INC) $(LIB)
module.o: module.cu module.h
nvcc -c -g module.cu -o module.o -I -dlink
clean:
rm -rf *.o