如何在cuSparse中使用cusparseXcoo2csr从coo转换为csc
How to use cusparseXcoo2csr in cuSparse to convert from coo to csc?
在cuSparse的文档中,它指出函数cusparseXcoo2csr
还可以用于转换包含未压缩的列索引(对应COO格式(到列数组中指针(对应CSC格式(
然而,我找不到复制它的方法。请参阅下面的最小代码:
CMakeLists.txt
cmake_minimum_required(VERSION 3.11)
project(sample)
find_package(CUDA REQUIRED)
add_executable(${PROJECT_NAME} main.cpp)
target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_14)
target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC ${CUDA_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} ${CUDA_LIBRARIES} ${CUDA_cusparse_LIBRARY})
main.cpp
#include <iostream>
#include <vector>
#include <cuda_runtime_api.h>
#include <cusparse_v2.h>
int main(){
// using the matrix as shown in https://docs.nvidia.com/cuda/cusparse/index.html#coo-format
// 1 4 0 0 0
// 0 2 3 0 0
// 5 0 0 7 8
// 0 0 9 0 6
std::vector<int> row;
std::vector<int> col;
std::vector<double> val;
row.emplace_back(0);
row.emplace_back(0);
row.emplace_back(1);
row.emplace_back(1);
row.emplace_back(2);
row.emplace_back(2);
row.emplace_back(2);
row.emplace_back(3);
row.emplace_back(3);
col.emplace_back(0);
col.emplace_back(1);
col.emplace_back(1);
col.emplace_back(2);
col.emplace_back(0);
col.emplace_back(3);
col.emplace_back(4);
col.emplace_back(2);
col.emplace_back(4);
val.emplace_back(1);
val.emplace_back(4);
val.emplace_back(2);
val.emplace_back(3);
val.emplace_back(5);
val.emplace_back(7);
val.emplace_back(8);
val.emplace_back(9);
val.emplace_back(6);
int *d_row;
int *d_col;
double *d_val;
cudaMalloc(reinterpret_cast<void **>(&d_row), row.size() * sizeof(int));
cudaMalloc(reinterpret_cast<void **>(&d_col), col.size() * sizeof(int));
cudaMalloc(reinterpret_cast<void **>(&d_val), val.size() * sizeof(double));
cudaMemcpy(d_row, row.data(), sizeof(int) * row.size(), cudaMemcpyHostToDevice);
cudaMemcpy(d_col, col.data(), sizeof(int) * col.size(), cudaMemcpyHostToDevice);
cudaMemcpy(d_val, val.data(), sizeof(double) * val.size(), cudaMemcpyHostToDevice);
cusparseHandle_t handle;
cusparseCreate(&handle);
cusparseMatDescr_t descr;
cusparseCreateMatDescr(&descr);
cusparseSetMatType(descr, CUSPARSE_MATRIX_TYPE_GENERAL);
cusparseSetMatIndexBase(descr, CUSPARSE_INDEX_BASE_ZERO);
cusparseMatDescr_t descr_out;
cusparseCreateMatDescr(&descr_out);
cusparseSetMatType(descr_out, CUSPARSE_MATRIX_TYPE_GENERAL);
cusparseSetMatIndexBase(descr_out, CUSPARSE_INDEX_BASE_ZERO);
int *d_row_csr;
cudaMalloc(reinterpret_cast<void **>(&d_row_csr), (4 + 1) * sizeof(int));
cusparseXcoo2csr(handle, d_row, 9, 4, d_row_csr, CUSPARSE_INDEX_BASE_ZERO);
std::vector<int> row_csr(4 + 1);
cudaMemcpy(row_csr.data(), d_row_csr, sizeof(int) * (4 + 1), cudaMemcpyDeviceToHost);
std::cout << "row" << std::endl;
for (int i : row_csr){
std::cout << i << std::endl; // prints 0 2 4 7 9 as expected
}
// however when I try to compress the column the same way...
int *d_col_csc;
cudaMalloc(reinterpret_cast<void **>(&d_col_csc), (5 + 1) * sizeof(int));
cusparseXcoo2csr(handle, d_col, 9, 5, d_col_csc, CUSPARSE_INDEX_BASE_ZERO);
std::vector<int> col_csc(5 + 1);
cudaMemcpy(col_csc.data(), d_col_csc, sizeof(int) * (5 + 1), cudaMemcpyDeviceToHost);
std::cout << "col" << std::endl;
for (int i : col_csc){
std::cout << i << std::endl; // prints 0 5 3 8 6 9, shouldn't it be 0 2 4 6 7 9?
}
return 0;
}
正如您所看到的,出于某种原因,从coo到csc的转换是不正确的。我暂时解决了这个问题,调用cusparseXcoo2csr
进行coo到csr的转换,然后调用另一个cusparseDcsr2csc
将csr中间结果转换为csc。这是额外的计算,所以我想知道如何使用cusparseXcoo2csr
直接将coo转换为csc,如文档中所示。
COO行坐标到行指针的行压缩和COO列坐标到列指针的列压缩基本上是相同的操作(基本上只是按键的前缀和(。尽管没有明确记录,cusparseXcoo2csr
要求对输入坐标数据进行排序。
在您的示例中,CSR转换之所以有效,是因为您所拥有的坐标是按行顺序排序的,而CSC失败是因为列坐标没有按列顺序排序。如果对输入进行重新排序,以便对列索引进行排序,则转换将起作用。
相关文章:
- 防止主数据类型C++的隐式转换
- 模板参数替换失败,并且未完成隐式转换
- 努力将整数转换为链表。不知道我在这里做错了什么
- HEX值到wchar_t字符(UTF-8)的转换
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将 Qvector<uint8_t> 转换为 QString
- 如何在cuSparse中使用cusparseXcoo2csr从coo转换为csc
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 在c++中使用nlohmann从类到json的转换
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 如何使用OpenCV将RBG图像转换为HSV,并将H、S和V值保存为C++中的3个独立图像
- 复制列表初始化的隐式转换的等级是多少
- 正在将指针转换为范围
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 是否可以从int转换为enum类类型
- 了解 GLM- openGL 中的相机转换
- 将无符号char*转换为std::istream*C++