我试图运行一个简单的CUDA程序,该程序在特定大小上执行矩阵添加。
这是我的代码:
的main.cpp
/* sample CUDA programming to prove that (AB)transpose=(B)transpose*(A)transpose */
#include "common.h"
#include "utils.h"
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
void preprocess(int *A, int *B, int *C, int **da, int **db, int **dc,int M, int N, int P,int blksize);
void checktransposeppt(int *da, int *db, int *dc);
void display(int a[], int b[])
{
//display the matrices
}
int main()
{
int A[M*P],B[P*N];
int C[M*N];
int *da;
int *db;
int *dc;
//initializing values for A and B
display(A,B);
preprocess(A,B,C,&da,&db,&dc,M,N,P,blksize);
checktransposeppt(da,db,dc);
checkCudaErrors(cudaFree(da));
checkCudaErrors(cudaFree(db));
checkCudaErrors(cudaFree(dc));
}
这里是preprocess.cpp: - 基本上做cudamalloc,数组的cudamemcpy hosttodevice和结果的devicetohost
#include "utils.h"
void preprocess(int *h_a, int *h_b, int *h_c,int **d_a,int **d_b,int **d_c,int M, int N, int P, int blksize)
{
checkCudaErrors(cudaFree(0));
checkCudaErrors(cudaMalloc(d_a,(size_t)sizeof(int)*(M*P)));
checkCudaErrors(cudaMalloc(d_b,(size_t)sizeof(int)*(P*N)));
checkCudaErrors(cudaMalloc(d_c,(size_t)sizeof(int)*(M*N)));
checkCudaErrors(cudaMemset(d_c,0,(size_t)sizeof(int)*(M*N)));
checkCudaErrors(cudaMemcpy(*d_a,h_a,(size_t)sizeof(int)*(M*P),cudaMemcpyHostToDevice));
checkCudaErrors(cudaMemcpy(*d_b,h_b,(size_t)sizeof(int)*(P*N),cudaMemcpyHostToDevice));
checkCudaErrors(cudaMemcpy(h_c,*d_c,(size_t)sizeof(int)*(M*N),cudaMemcpyDeviceToHost));
}
这是common.h,它是定义大多数外部头文件和全局变量的中心位置
#ifndef COMMON_H
#include <cuda.h>
#include <cuda_runtime.h>
#define COMMON_H
extern int M=256;
extern int P=128;
extern int N=64;
extern int blksize=16;
extern dim3 gridsize(M/blksize,N/blksize,1);
extern dim3 blocksize(blksize,blksize,1);
#endif
kernel.cu
#include "utils.h"
#include "common.h"
__global__ void abkerneltranspose(int *d_a,int *d_b,int *d_c,int N);
__global__
void abkerneltranspose(int *d_a,int *d_b,int *d_c,int N)
{
int blkx=blockIdx.x;
int blky=blockIdx.y;
int thdx=threadIdx.x;
int thdy=threadIdx.y;
int row=blkx*blockDim.x+threadIdx.x;
int col=blky*blockDim.y+threadIdx.y;
d_c[row*N+col]=d_a[row*N+col]+d_b[row*N+col];
}
void checktransposeppt(int *d_a,int *d_b,int *d_c)
{
dim3 gridsize(M/blksize,N/blksize,1);
dim3 blocksize(blksize,blksize,1);
abkerneltranspose<<<gridsize,blocksize>>>(d_a,d_b,d_c,N);
}
这里是我怀疑罪魁祸首的地方:makefile
NVCC=nvcc
NVCC_OPTS=-O3 -arch=sm_20 -Xcompiler -Wall -Xcompiler -Wextra -m64
all: app
app: gpucompile.o cpucompile.o Makefile
nvcc -o app gpucompile.o cpucompile.o -L $(NVCC_OPTS) $(GCC_OPTS)
gpucompile.o: kernel.cu
nvcc -c kernel.cu $(NVCC_OPTS)
cpucompile.o: main.cpp preprocess.cpp
nvcc -x cu main.cpp preprocess.cpp -I. -I $(GCC_OPTS) -I $(CUDA_INCLUDEPATH)
clean:
rm -f *.o hw *.bin
好的,这是问题
on make命令,它正确编译但抛出错误
/tmp/tmpxft_00002074_00000000-21_main.o:在函数
main': tmpxft_00002074_00000000-3_main.cudafe1.cpp:(.text+0x543): undefined reference to
中checkTransposeppt(int *,int *,int *)&#39;
我真的不确定为什么会这样。我分别编译和创建cpp代码(只是忽略-x cu,它不会导致错误)并执行相同的操作 我稍后链接的kernel.cu。
但是这个错误是由中间main.o抛出的,这让我相信它在创建cpucompile.o时失败了。但是链接器无法等到它获得gpucompile.o然后链接这两个链接。
此外,我尝试创建单独的目标文件main.o,preprocess.o和kernel.o并将它们全部链接一步
然后我收到以下额外错误:
/tmp/tmpxft_00002f88_00000000-16_main.o:在函数
main': tmpxft_00002f88_00000000-3_main.cudafe1.cpp:(.text+0x532): undefined reference to
preprocess(int *,int *,int *,int **,int **,int **,int, int,int,int)&#39;
我错过了一些基本的东西,有人可以解释这里出了什么问题吗?
执行这样的项目的最佳做法是什么:我的意思是我将编译设备代码和cpu代码分开,然后将它们链接起来。我还有一个公共头,我在其中定义外部头和全局变量/类/函数定义。有什么建议吗?
答案 0 :(得分:2)
是的,你的makefile不正确。
您要构建的应用程序目标是app
,并且该makefile的目标设置可能是可行的。
app
目标需要gpucompile.o
和cpucompile.o
个对象。
您已为每个必需对象指定了目标。
gpucompile.o目标以可行的方式设置。还有一个问题是它默认创建kernel.o,而不是gpucompile.o
cpucompile.o目标无法使用。它在几个方面被打破。首先,它似乎是从包含链接阶段的makefile目标复制的,但这不是我们想要的 - 您此时正在创建一个未链接的对象(cpucompile.o)。此外,我们通常不会将两个单独的未链接对象(main.o和preprocess.o)构建到一个未链接的对象中。
一般情况下,我建议切换到一个makefile格式,它只是以类似的方式处理.cu文件和.cpp文件 - 为每个文件创建一个目标,并将每个文件构建到一个对象中。然后将所有对象链接在一起以创建可执行文件。没有必要尝试创建一个单独的&#34; gpu对象&#34;包括所有GPU代码,以及单独的&#34; cpu对象&#34;包括所有CPU代码,然后将它们链接在一起。
您的代码中有一个单独的问题,您在common.h中定义M
和其他变量,然后将其包含在多个文件中。这将导致多重定义链接错误。有多种方法可以解决这个问题。一种可能的方法是修改你的commons.h文件,如下所示:
#ifndef COMMON_H
#include <cuda.h>
#include <cuda_runtime.h>
#define COMMON_H
extern int M;
extern int P;
extern int N;
extern int blksize;
extern dim3 gridsize;
extern dim3 blocksize;
#endif
然后将以下初始化添加到文件的一个的顶部,例如main.cpp:
int M=256;
int P=128;
int N=64;
int blksize=16;
dim3 gridsize(M/blksize,N/blksize,1);
dim3 blocksize(blksize,blksize,1);
使用这些更改,并使用这样的makefile:
NVCC=nvcc -O3 -arch=sm_20 -Xcompiler -Wall -Xcompiler -Wextra -m64
all: app
app: kernel.o main.o preprocess.o Makefile
$(NVCC) -o app kernel.o main.o preprocess.o
kernel.o: kernel.cu
$(NVCC) -c kernel.cu
main.o: main.cpp
$(NVCC) -x cu -c main.cpp
preprocess.o: preprocess.cpp
$(NVCC) -x cu -c preprocess.cpp
clean:
rm -f *.o app
我能够使用以下警告构建您的代码: