0

我有一个 .cu 文件,当它自己编译时,右键单击并选择编译,它编译得很好,但是当我有另一个头文件,一个 c++ 头文件,它调用这个 .cu 文件时,构建失败。.cu 文件属性已被编辑为使用 CUDA 编译器构建。我得到的错误是 'blockIdx': undeclared identifier 'blockDim': undeclared identifier, etc.. 基本上是我期望用 c++ 编译器编译 cuda 代码的错误。那么是否可以在 c++ 标头中包含 .cu cuda 代码?

这是 .cu 文件:

矩阵.cu

#include <cuda.h>
#include <cuda_runtime.h>
#include <cuda_device_runtime_api.h>

#define BLOCKSIZE 32

using namespace std;



template<typename T> class Matrix
{
public:
typedef T value_type;
~Matrix();
Matrix();
Matrix(int rows, int columns);
int height;
int width;
int stride;
size_t size;

void CreateIdentity(Matrix<T>&I);
private:
vector<T> elements;
T* firstElement;
};


template<typename T>
Matrix<T>::~Matrix()
{
}

template<typename T>
Matrix<T>::Matrix()
{
}

template<typename T>
Matrix<T>::Matrix(int rows, int columns)
{
height = rows;
width = columns;
stride = columns; //in row major order this is equal to the # of columns
elements.resize(rows*columns);
firstElement = elements.data();
size = height*width*sizeof(T);
}



__global__ void IdentityMatrixKernel(float* identity, int size)
{
int index_x = blockIdx.x * blockDim.x + threadIdx.x;
int index_y = blockIdx.y * blockDim.y + threadIdx.y;

// map the two 2D indices to a single linear, 1D index
int grid_width = gridDim.x * blockDim.x;
int index = index_y * grid_width + index_x;

// map the two 2D block indices to a single linear, 1D block index
//int result = blockIdx.y * gridDim.x + blockIdx.x;

// write out the result

if (index % (size+1))
{
    identity[index] = 0;
}

else
{
    identity[index] = 1;
}
}


template<typename T>
void Matrix<T>::CreateIdentity(Matrix<T>&I)
{
float* d_I;
int size1 = I.height;
int size2 = I.height*I.width*sizeof(float);

cudaMalloc(&d_I,size2);

dim3 block_size;
block_size.x = BLOCKSIZE;
block_size.y = BLOCKSIZE;

dim3 grid_size;
grid_size.x = size1/ block_size.x + 1;
grid_size.y = size1/ block_size.y + 1;

IdentityMatrixKernel<<<block_size,grid_size>>>(d_I,size1);

cudaMemcpy(I.GetPointer(),d_I,size2,cudaMemcpyDeviceToHost);

cudaFree(d_I);
}

这是#include“Matrix.cu”的头文件

元素.h

#pragma once
#include "Matrix.cu"
#include <vector>

using namespace std;

class Element
{
public:
Element(void);
~Element(void);
Element(int iD, float k, vector<int> nodes);
Element(int iD, vector<int> nodes, int pId);

void SetElementType(DOF type);
DOF GetElementType();
int GetNodeId(int index);
int GetNodesPerElement();
int GetPartId();

void CalculateShapeFunctions(Matrix<int> spaceCoordinates);
void CalculateSShapeDerivative(Matrix<int> spaceCoordinates);
void CalculateTShapeDerivative(Matrix<int> spaceCoordinates);
Matrix<float> GetShapeFunctions();
float GetSShapeDerivative(int row, int column);
float GetTShapeDerivative(int row, int column);
void SetStrainDisplacement(Matrix<float> B);
Matrix<float> GetStrainDisplacement();

private:

int elementId;
float stiffness;
vector<int> nodeIds;
DOF elementType;
int partId;
Matrix<float> shapeFunctions;
Matrix<float> sShapeDerivative;
Matrix<float> tShapeDerivative;
Matrix<float> strainDisplacement;
};

编辑:

因此,我被指示尝试将实现 cuda 的模板类成员函数分离到一个 .cu 文件中,同时在原始头文件中保留模板类定义和任何不使用 cuda 的模板成员函数。这似乎在正确的路径上,c++ 编译器编译 .h 文件,而 cuda 编译器编译 .cu,但我无法摆脱链接错误。我知道我需要在 .cu 文件中为我需要的类型显式实例化我的模板类以避免链接错误,但我似乎仍然得到它们。

我在 .cu 文件的末尾实例化了我的模板类,如下所示:

template class Matrix<float>;
template class Matrix<int>;
template class Matrix<string>;

我现在使用 cuda 获取到模板成员函数的链接错误。

4

1 回答 1

1

答:.cu 文件不能像头文件一样用作#include "file.cu",因为它们将使用 C++ 编译器而不是 cuda 编译。解决方案是将任何实现 cuda 的东西移动到一个单独的 .cu 文件中,同时仍将模板函数的定义保留在标头中的模板类定义中,并在 file.cu 中添加一个#include“file.h”。为了解决移动到 .cu 文件的模板函数声明的任何链接错误,将模板类的显式实例添加到头文件的底部。由于在使用 cuda 的模板函数中只使用了浮点类型,因此只添加了浮点类型的实例:模板类 Matrix。上述解决方案编译并完美运行。

于 2014-03-28T17:48:36.573 回答