Я пытался запустить простую программу CUDA, которая выполняет добавление матрицы по определенному размеру.undefined ссылка на функцию C++, создаваемую промежуточным объектным файлом
Вот мой код:
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
нормально здесь проблема
по команде макияжем, Компилируется но генерирует ошибку
/tmp/tmpxft_00002074_00000000-21_main.o: In function
main': tmpxft_00002074_00000000-3_main.cudafe1.cpp:(.text+0x543): undefined reference to
checkTransposeppt(int*, int*, int*)'
Я действительно не знаю, почему это происходит. Я компилирую и создаю код cpp отдельно (просто игнорируйте -x cu, он не вызывает ошибки) и выполните то же самое kernel.cu, которое я позже свяжу.
Но эта ошибка выбрасывается промежуточным main.o, что заставляет меня думать, что ему не удалось создать cpucompile.o. Но не смог ли компоновщик подождать, пока он не получит gpucompile.o, а затем свяжет два.
Кроме того, я попытался создать отдельные объектные файлы main.o, preprocess.o и kernel.o и связать их все в одном шаге
тогда я получаю следующую дополнительную ошибку:
/tmp/tmpxft_00002f88_00000000-16_main.o: In function
main': tmpxft_00002f88_00000000-3_main.cudafe1.cpp:(.text+0x532): undefined reference to
preprocess(int*, int*, int*, int**, int**, int**, int, int, int, int)'
я пропустил что-то основное, может кто-нибудь объяснить, что здесь происходит?
Также, что лучше всего подходит для выполнения такого проекта: Я имею в виду, что я разделяю код компилятора и код процессора, а затем связываю их. У меня также есть общий заголовок, где я определяю внешние заголовки и определения глобальных переменных/классов/функций. Какие-либо предложения?