I am getting an error on call to cudnnConvolutionForward function. I get this error on hidden layer of my CNN , it goes through for input convolution layer. I am pasting below the code of my function. while debugging with copilot in visual studio everything looks consistent.copilot couldn’t find any issues.
struct GPUTensor {
int n, c, h, w;
float* dptr; // device pointer
size_t sizeBytes() const { return (size_t)n * c * h * w * sizeof(float); }
GPUTensor();
~GPUTensor();
// allocate device memory for this shape
bool allocate();
// free device memory
void free();
// copy from host pointer (assumes contiguous NCHW float data)
bool copyFromHost(const float* hostPtr);
// copy to host pointer
bool copyToHost(float* hostPtr) const;
};
bool cudnn_conv_forward(const GPUTensor& input,
const GPUTensor& weights,
const GPUTensor* bias,
GPUTensor& output,
int pad_h, int pad_w,
int stride_h, int stride_w,
int groups)
{
char g_last_error[256] = { 0 };
if (!g_handle) {
snprintf(g_last_error, sizeof(g_last_error), “cuDNN not initialized”);
return false;
}
if (!input.dptr || !weights.dptr || !output.dptr) {
snprintf(g_last_error, sizeof(g_last_error), “null device pointers”);
return false;
}
cudnnStatus_t s;
cudnnTensorDescriptor_t inDesc = nullptr, outDesc = nullptr, biasDesc = nullptr;
cudnnFilterDescriptor_t filtDesc = nullptr;
cudnnConvolutionDescriptor_t convDesc = nullptr;
void* workspace = nullptr;
size_t workspaceBytes = 0;
cudnnConvolutionFwdAlgo_t algo;
int n, c, h, w;
const float alpha = 1.0f, beta = 0.0f;
// Input descriptor
s = cudnnCreateTensorDescriptor(&inDesc);
if (s != CUDNN_STATUS_SUCCESS) goto fail;
s = cudnnSetTensor4dDescriptor(inDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT,
input.n, input.c, input.h, input.w);
if (s != CUDNN_STATUS_SUCCESS) goto fail;
// Filter descriptor
s = cudnnCreateFilterDescriptor(&filtDesc);
if (s != CUDNN_STATUS_SUCCESS) goto fail;
s = cudnnSetFilter4dDescriptor(filtDesc, CUDNN_DATA_FLOAT, CUDNN_TENSOR_NCHW,
weights.n, weights.c, weights.h, weights.w);
if (s != CUDNN_STATUS_SUCCESS) goto fail;
// Output descriptor
s = cudnnCreateTensorDescriptor(&outDesc);
if (s != CUDNN_STATUS_SUCCESS) goto fail;
s = cudnnSetTensor4dDescriptor(outDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT,
output.n, output.c, output.h, output.w);
if (s != CUDNN_STATUS_SUCCESS) goto fail;
// Convolution descriptor
s = cudnnCreateConvolutionDescriptor(&convDesc);
if (s != CUDNN_STATUS_SUCCESS) goto fail;
s = cudnnSetConvolution2dDescriptor(convDesc,
pad_h, pad_w,
stride_h, stride_w,
1, 1,
CUDNN_CROSS_CORRELATION,
CUDNN_DATA_FLOAT);
if (s != CUDNN_STATUS_SUCCESS) goto fail;
// Grouped convolution
s = cudnnSetConvolutionGroupCount(convDesc, groups);
if (s != CUDNN_STATUS_SUCCESS) goto fail;
// Choose algorithm
int returnedAlgoCount;
cudnnConvolutionFwdAlgoPerf_t perfResults[10];
cudnnGetConvolution2dForwardOutputDim(convDesc, inDesc, filtDesc, &n, &c, &h, &w);
if (!(n == output.n && c == output.c && h == output.h && w == output.w))
{
printf("output sizes mismatch");
goto fail;
}
s = cudnnGetConvolutionForwardAlgorithm_v7(
g_handle,
inDesc,
filtDesc,
convDesc,
outDesc,
1,
&returnedAlgoCount,
&perfResults[0]);
if (s != CUDNN_STATUS_SUCCESS) goto fail;
algo = perfResults[0].algo;
// Workspace
s = cudnnGetConvolutionForwardWorkspaceSize(g_handle,
inDesc, filtDesc,
convDesc, outDesc,
algo,
&workspaceBytes);
if (s != CUDNN_STATUS_SUCCESS) goto fail;
workspaceBytes = 10000000;
if (workspaceBytes > 0) {
cudaError_t cerr = cudaMalloc(&workspace, workspaceBytes);
if (cerr != cudaSuccess) {
snprintf(g_last_error, sizeof(g_last_error), "cudaMalloc workspace failed: %s",
cudaGetErrorString(cerr));
goto fail;
}
}
else
workspace = nullptr;
extern void dumpTensorDesc(cudnnTensorDescriptor_t desc, const char* name);
extern void dumpFilterDesc(cudnnFilterDescriptor_t desc, const char* name);
extern void dumpConvDesc(cudnnConvolutionDescriptor_t desc, const char* name);
dumpTensorDesc(inDesc, "Input");
dumpFilterDesc(filtDesc, "Filter");
dumpConvDesc(convDesc, "Conv");
int outN, outC, outH, outW;
cudnnGetConvolution2dForwardOutputDim(convDesc, inDesc, filtDesc,
&outN, &outC, &outH, &outW);
printf("Output dims: N=%d C=%d H=%d W=%d\n", outN, outC, outH, outW);
// Forward convolution
s = cudnnConvolutionForward(g_handle,
&alpha,
inDesc, input.dptr,
filtDesc, weights.dptr,
convDesc,
(false?CUDNN_CONVOLUTION_FWD_ALGO_IMPLICIT_GEMM:algo),
workspace, workspaceBytes,
&beta,
outDesc, output.dptr);
if (s != CUDNN_STATUS_SUCCESS) goto fail;
// Add bias if present
if (bias && bias->dptr) {
s = cudnnCreateTensorDescriptor(&biasDesc);
if (s != CUDNN_STATUS_SUCCESS) goto fail;
s = cudnnSetTensor4dDescriptor(biasDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT,
1, bias->c, 1, 1);
if (s != CUDNN_STATUS_SUCCESS) goto fail;
s = cudnnAddTensor(g_handle, &alpha, biasDesc, bias->dptr,
&alpha, outDesc, output.dptr);
if (s != CUDNN_STATUS_SUCCESS) goto fail;
}
// Cleanup
if (workspace) cudaFree(workspace);
if (inDesc) cudnnDestroyTensorDescriptor(inDesc);
if (outDesc) cudnnDestroyTensorDescriptor(outDesc);
if (filtDesc) cudnnDestroyFilterDescriptor(filtDesc);
if (convDesc) cudnnDestroyConvolutionDescriptor(convDesc);
if (biasDesc) cudnnDestroyTensorDescriptor(biasDesc);
return true;
fail:
snprintf(g_last_error, sizeof(g_last_error), “cuDNN error: %s”, cudnnGetErrorString(s));
if (workspace) cudaFree(workspace);
if (inDesc) cudnnDestroyTensorDescriptor(inDesc);
if (outDesc) cudnnDestroyTensorDescriptor(outDesc);
if (filtDesc) cudnnDestroyFilterDescriptor(filtDesc);
if (convDesc) cudnnDestroyConvolutionDescriptor(convDesc);
if (biasDesc) cudnnDestroyTensorDescriptor(biasDesc);
return false;
}