cuda - 尝试使用 cuSPARSE 的 cusparseCsr2cscEx2() 函数执行矩阵转置时出现内部错误
问题描述
我需要使用 cuSPARSE 执行矩阵(CSR)的转置,但得到“内部错误”。我写我的代码是指如何在 cuSparse 中转置稀疏矩阵?和https://docs.nvidia.com/cuda/cusparse/index.html#csr2cscEx2。为了更清楚,我试图通过将矩阵从格式 csr 转换为格式 csc 来执行转置。
我在 Nvidia GeForce GTX 1080 上运行,带有驱动程序 cuda_11.1.0。我正在使用 Windows 10。
以下是我的代码。您可以从https://github.com/NVIDIA/CUDALibrarySamples/tree/master/cuSPARSE/sparse2dense下载该文件夹,并将 sparse2dense_example.c 替换为我的代码。然后使用CMake进行配置和制作,这样也许你可以重现我的问题。
#include <cuda_runtime_api.h> // cudaMalloc, cudaMemcpy, etc.
#include <cusparse.h> // cusparseSparseToDense
#include <stdio.h> // printf
#include <stdlib.h> // EXIT_FAILURE
#define CHECK_CUDA(func) \
{ \
cudaError_t status = (func); \
if (status != cudaSuccess) { \
printf("CUDA API failed at line %d with error: %s (%d)\n", \
__LINE__, cudaGetErrorString(status), status); \
return EXIT_FAILURE; \
} \
}
#define CHECK_CUSPARSE(func) \
{ \
cusparseStatus_t status = (func); \
if (status != CUSPARSE_STATUS_SUCCESS) { \
printf("CUSPARSE API failed at line %d with error: %s (%d)\n", \
__LINE__, cusparseGetErrorString(status), status); \
return EXIT_FAILURE; \
} \
}
int main(void) {
// CUSPARSE APIs
cusparseHandle_t handle = NULL;
cusparseStatus_t status = (cusparseCreate(&handle));
if (status != CUSPARSE_STATUS_SUCCESS) {
printf("CUSPARSE API failed at line %d with error: %s (%d)\n", __LINE__, cusparseGetErrorString(status), status);
}
// Initialize matrix A
// this matrix is the same as https://github.com/NVIDIA/CUDALibrarySamples/blob/master/cuSPARSE/sparse2dense/sparse2dense_example.c
int num_rows = 5;
int num_cols = 4;
int nnz = 11;
int h_csr_offsets[] = { 0, 3, 4, 7, 9, 11 };
int h_csr_columns[] = { 0, 2, 3, 1, 0, 2, 3, 1, 3, 1, 2 };
float h_csr_values[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f,
7.0f, 8.0f, 9.0f, 10.0f, 11.0f };
// Device memory management
int* d_csr_offsets, * d_csr_columns;
float* d_csr_values;
CHECK_CUDA(cudaMalloc((void**)&d_csr_offsets, (num_rows + 1) * sizeof(int)))
CHECK_CUDA(cudaMalloc((void**)&d_csr_columns, nnz * sizeof(int)))
CHECK_CUDA(cudaMalloc((void**)&d_csr_values, nnz * sizeof(float)))
CHECK_CUDA(cudaMemcpy(d_csr_offsets, h_csr_offsets, (num_rows + 1) * sizeof(int), cudaMemcpyHostToDevice))
CHECK_CUDA(cudaMemcpy(d_csr_columns, h_csr_columns, nnz * sizeof(int), cudaMemcpyHostToDevice))
CHECK_CUDA(cudaMemcpy(d_csr_values, h_csr_values, nnz * sizeof(float), cudaMemcpyHostToDevice))
// Memory allocation of transpose A
int* d_csr_offsets_AT, * d_csr_columns_AT;
float* d_csr_values_AT;
//first allocate memory to ATT
CHECK_CUDA(cudaMalloc((void**)&d_csr_offsets_AT, (num_cols + 1) * sizeof(int)))
CHECK_CUDA(cudaMalloc((void**)&d_csr_columns_AT, nnz * sizeof(int)))
CHECK_CUDA(cudaMalloc((void**)&d_csr_values_AT, nnz * sizeof(float)))
size_t buffer_temp_size;
cusparseCsr2cscEx2_bufferSize(
handle, num_rows, num_cols, nnz, h_csr_values, h_csr_offsets, h_csr_columns,
d_csr_values_AT, d_csr_offsets_AT, d_csr_columns_AT, CUDA_R_32F, CUSPARSE_ACTION_NUMERIC,
CUSPARSE_INDEX_BASE_ZERO, CUSPARSE_CSR2CSC_ALG1, &buffer_temp_size);
void* buffer_temp = NULL;
printf("buffer_temp_size is %zd\n", buffer_temp_size);
CHECK_CUDA(cudaMalloc(&buffer_temp, buffer_temp_size))
CHECK_CUSPARSE(cusparseCsr2cscEx2(handle, num_rows, num_cols, nnz, h_csr_values, h_csr_offsets, h_csr_columns,
d_csr_values_AT, d_csr_offsets_AT, d_csr_columns_AT, CUDA_R_32F, CUSPARSE_ACTION_NUMERIC,
CUSPARSE_INDEX_BASE_ZERO, CUSPARSE_CSR2CSC_ALG1, buffer_temp))
}
解决方案
该错误是由于您将指向主机数据的指针传递给打算处理设备数据的例程:
cusparseCsr2cscEx2_bufferSize(
handle, num_rows, num_cols, nnz, h_csr_values, h_csr_offsets, h_csr_columns,
^ ^ ^
和
CHECK_CUSPARSE(cusparseCsr2cscEx2(handle, num_rows, num_cols, nnz, h_csr_values, h_csr_offsets, h_csr_columns,
^ ^ ^
当我将这些实例更改为您分配的设备数据时:
d_csr_values, d_csr_offsets, d_csr_columns
根据我的测试,您所询问的“内部错误”消失了。
推荐阅读
- scala - 为什么 spark 的数据集中没有 reduceBykey
- powerbi - 带有切片器的 Power BI Sankey
- maven - 如何将 maven 项目导入现有的 android 项目?
- python - 如果给出空参数,如何处理 sys.argv
- powershell - 我想从包含广告组的文件中检索父广告组
- java - 如何在 wso2product 上将 TLS 1.0 升级到 TLS 1.2
- android - Android - 如何创建像 WhatsApp 聊天这样的操作栏?
- java - 如何在 Android Studio 中为图像创建色差滤镜?
- android - 自动滚动到包含在嵌套滚动视图中的特定回收器视图似乎不适用于 Android X
- formula - 具有 ISIN 和返回价格的 Bloomberg 函数