Qt и cuda, ошибка в режиме отладки
Я пытаюсь использовать CUDA для кода Qt; он отлично работает в выпуске, но не в отладке, где у меня есть следующее предупреждение:
Это не похоже на отладочную сборку. Установка точек останова по имени файла и номеру строки может быть неудачной.
В основном проекте у меня есть TestCUDA.pro и main.cpp. Он вызывает библиотеку, сгенерированную из matMul.cu.
Я нахожусь на Windows 10, я использую Qt 5.10.1 (с qmake) с MSVC2017 64bit для TestCUDA. Для генерации lib я использую командную строку:
=> release: nvcc.exe -lib -o lib_cuda / matMul.lib -c matMul.cu
=> debug: nvcc.exe –lib --debug -D_DEBUG -o lib_cuda / matMul_d.lib -c matMul.cu
matMul.lib - 44ko, а matMul_d.lib - 73ko, поэтому я думаю, что действительно генерирую отладочную библиотеку...
Кто-нибудь имеет представление о проблеме, пожалуйста?
TestCUDA.pro
QT -= gui
CONFIG += console
CONFIG -= app_bundle
SOURCES += main.cpp
OTHER_FILES =+ matMul.cu
# The following library conflicts with something in Cuda
QMAKE_LFLAGS_RELEASE = /NODEFAULTLIB:msvcrt.lib
QMAKE_LFLAGS_DEBUG = /NODEFAULTLIB:msvcrtd.lib
QMAKE_LFLAGS_DEBUG = /NODEFAULTLIB:libcmt.lib
# Used to avoid conflicting flags between CUDA and MSVC files, should make everything static
QMAKE_CFLAGS_DEBUG += /MTd
QMAKE_CFLAGS_RELEASE += /MT
QMAKE_CXXFLAGS_DEBUG += /MTd
QMAKE_CXXFLAGS_RELEASE += /MT
# CUDA settings <-- may change depending on your system
CUDA_DIR = "C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v9.2" # Path to cuda toolkit install
# include paths
INCLUDEPATH += $$CUDA_DIR\include
INCLUDEPATH += $$PWD/lib_cuda
DEPENDPATH += $$PWD/lib_cuda
# library directories
win32:contains(QT_ARCH, x86_64) {
QMAKE_LIBDIR += $$CUDA_DIR/lib/x64
}
# Add the necessary CUDA libraries
LIBS += -lcuda -lcudart
# Add project related libraries containing kernels
CONFIG(debug, debug | release) {
LIBS += -L$$PWD/lib_cuda/ -lmatMul_d
}
else {
LIBS += -L$$PWD/lib_cuda/ -lmatMul
}
main.cpp
#include <cmath>
#include <chrono>
#include <iostream>
#include <cuda.h>
#include <cuda_runtime.h>
typedef struct
{
int width;
int height;
int stride;
float *elements;
} Matrix;
void matMul_wrapper(Matrix &C, const Matrix &A, const Matrix &B, cudaDeviceProp devProp);
int main()
{
int devCount;
cudaGetDeviceCount(&devCount);
cudaDeviceProp devProp;
for(int i=0; i < devCount; ++i)
{
cudaGetDeviceProperties(&devProp, i);
std::cout << "\nDevice: " << devProp.name << "\n";
std::cout << " Compute capability: " << devProp.major << "\n";
std::cout << " Max threads per block: " << devProp.maxThreadsPerBlock << "\n";
std::cout << " Warp size: " << devProp.warpSize << "\n\n";
}
Matrix A {1000, 1000, 1, new float[1000*1000]};
Matrix B {1000, 1000, 1, new float[1000*1000]};
Matrix C {B.width, A.height, 1, new float[1000*1000]};
for(int row=0; row < A.height; ++row)
{
for(int col=0; col < A.width; ++col)
A.elements[row*A.width + col] = (float)(row*A.width + col) / (float)100000;
}
for(int row=0; row < B.height; ++row)
{
for(int col=0; col < B.width; ++col)
B.elements[row*B.width + col] = (float)(row*B.width + col) / (float)100000;
}
std::cout << A.elements[20000] << '\n';
matMul_wrapper(C, A, B, devProp);
std::cout << A.elements[20000] << '\n';
delete[] A.elements;
delete[] B.elements;
delete[] C.elements;
return 0;
}
И matMul.cu
#include <cuda.h>
#include <cuda_runtime.h>
#define BLOCK_SIZE 16
typedef struct
{
int width;
int height;
int stride;
float *elements;
} Matrix;
__global__
void matMulKernel(Matrix C, const Matrix A, const Matrix B)
{
int col = blockIdx.x * blockDim.x + threadIdx.x;
int row = blockIdx.y * blockDim.y + threadIdx.y;
int idx = row*C.width + col;
float out = 0;
if(idx < C.width * C.height)
{
for(int j=0; j < A.width; ++j)
out += A.elements[row*A.width + j] * B.elements[j*B.width + col];
}
C.elements[idx] = out;
}
void matMul_wrapper(Matrix &C, const Matrix &A, const Matrix &B, cudaDeviceProp devProp)
{
dim3 block(BLOCK_SIZE, BLOCK_SIZE, 1);
dim3 grid( (C.width + block.x - 1) / block.x,
(C.height + block.y - 1) / block.y,
1);
Matrix d_A {A.width, A.height, A.stride};
size_t size = A.height * A.width * sizeof(float);
cudaMallocManaged(&d_A.elements, size);
cudaMemcpy(d_A.elements, A.elements, size, cudaMemcpyHostToDevice);
Matrix d_B {B.width, B.height, B.stride};
size = B.height * B.width * sizeof(float);
cudaMallocManaged(&d_B.elements, size);
cudaMemcpy(d_B.elements, B.elements, size, cudaMemcpyHostToDevice);
Matrix d_C {C.width, C.height, C.stride};
size = C.height * C.width * sizeof(float);
cudaMallocManaged(&d_C.elements, size);
cudaMemcpy(d_C.elements, C.elements, size, cudaMemcpyHostToDevice);
matMulKernel<<<grid, block>>>(d_C, d_A, d_B);
cudaDeviceSynchronize();
cudaMemcpy(C.elements, d_C.elements, size, cudaMemcpyDeviceToHost);
cudaFree(d_A.elements);
cudaFree(d_B.elements);
cudaFree(d_C.elements);
}