当我想用动态并行支持编译MPI + CUDA混合程序时遇到了一个编译问题。
dyn_pal.cu的源代码
#include <stdio.h>
#include <cuda.h>
#define N 100
#define M 32
#define K 2
__device__ volatile int vint = 0;
__global__ void entry( volatile int* foo ) {
for (int i = 0; i < N; ++i) {
atomicAdd((int*)foo, 1);
}
}
//extern "C" __global__ void diverge_cta( volatile int *foo )
extern "C" __global__ void diverge_cta( volatile int *foo )
{
__shared__ int x;
if ((threadIdx.x%32) != 0) {return;}
//// entry(foo); //original design: each thread call entry()
if (threadIdx.x == 0) {
entry<<<1,M>>>( foo );
cudaDeviceSynchronize();
x = 5;
return;
}
__syncthreads();
atomicAdd((int*)foo, x);
}
extern "C" void mycal(int myrank){
int *foo; int h_foo;
cudaMalloc((void**)&foo, sizeof(int)); cudaMemset(foo, 0, sizeof(int));
printf("foo addr: 0x%x\n", (unsigned)(size_t)foo);
diverge_cta<<<K,M*32>>>( foo );
cudaDeviceSynchronize();
cudaMemcpy(&h_foo, foo, sizeof(int), cudaMemcpyDeviceToHost);
if (h_foo == K*(M*N+5*(M-1))) {
printf("simple_scan_test test PASSED\n");
} else {
printf("Result: %d\n", h_foo); printf("simple_scan_test test FAILED\n");
}
}
MPI代码的源代码:indexed_gpu.c。
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <cuda.h>
#include <cuda_runtime.h>
void diverge_cta( volatile int *foo);
void mycal(int myrank);
int main(int argc, char *argv[]){
int myid, numprocs, i, j, k;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
mycal(myid);
MPI_Barrier(MPI_COMM_WORLD);
MPI_Finalize();
return EXIT_SUCCESS;
}
我使用的编译命令:
我得到的错误:
dynpal.o:在函数__sti____cudaRegisterAll_42_tmpxft_000044ae_00000000_6_dyn_pal_cpp1_ii_vint()':
tmpxft_000044ae_00000000-3_dyn_pal.cudafe1.cpp:(.text+0x314): undefined reference to
__ cudaRegisterLinkedBinary_42_tmpxft_000044ae_00000000_6_dyn_pal_cpp1_ii_vint'
collect2:ld返回1退出状态
BTW,如果我在编译cuda目标文件(第1行)时没有包含'-dc',我收到了这个错误:
dyn_pal.cu(25):错误:从设备或全局函数启动内核需要单独的编译模式 在编译“/tmp/tmpxft_00004303_00000000-6_dyn_pal.cpp1.ii”时检测到1错误。
如果我不使用MPI程序,支持并行性的纯CUDA程序可以在我的Kepler GPU上成功编译和运行。
我想知道,混合程序是否支持CUDA动态并行?
非常感谢。
答案 0 :(得分:2)
nvcc -arch=sm_35 -dc dyn_pal.cu -o dynpal.o -lcudadevrt
没有必要提供-lcudadevrt
开关。这是一个链接器开关,您没有使用此命令链接任何内容。通过以下命令序列和上述更改,我能够编译和链接您的代码:
nvcc -arch=sm_35 -dc dyn_pal.cu -o dynpal.o
mpicc -c indexed_gpu.c -o mpi_bench.o
nvcc -arch=sm_35 -dlink dynpal.o -o dynpal_link.o -lcudadevrt
mpicc mpi_bench.o dynpal.o dynpal_link.o -o gpu_idx -L/opt/cuda/5.5/lib64 -lcudart