当前位置: 首页 > news >正文

CANN/ops-sparse Csrgeam2算子

Csrgeam2算子

【免费下载链接】ops-sparse本项目是CANN提供的高性能稀疏矩阵计算的算子库,专注于优化稀疏矩阵的计算效率。项目地址: https://gitcode.com/cann/ops-sparse

算子概述

csrgeam2 算子用于计算两个 CSR(Compressed Sparse Row)格式稀疏矩阵的线性组合:

C = α * A + β * B

其中 A、B、C 均为 m × n 稀疏矩阵,以 CSR 格式存储;α 和 β 为 FP32 标量。

csrgeam2 采用两步法

  1. Nnz 阶段:计算输出矩阵 C 的行指针csrRowPtrC和非零元素总数nnzC
  2. Compute 阶段:根据 C 的行指针,计算列索引csrColIndC和非零元素值csrValC

C 的非零模式为 A 和 B 的并集(A ∪ B),与 α、β 的具体数值无关。

仅支持非转置(No-Transpose)模式,不支持 NT/TN/TT 组合。

包含以下接口:

接口名功能简述
aclsparseScsrgeam2_bufferSizeExt查询 workspace 大小(字节)
aclsparseXcsrgeam2Nnz计算 C 的行指针 csrRowPtrC 和非零元素总数 nnzC
aclsparseScsrgeam2执行 C = α * A + β * B,计算列索引和非零元素值

算子执行接口

aclsparseScsrgeam2_bufferSizeExt

产品支持情况
  • Ascend 950PR / Ascend 950DT:支持
  • Atlas A3 训练系列产品 / Atlas A3 推理系列产品:不支持
  • Atlas A2 训练系列产品 / Atlas A2 推理系列产品:不支持
函数原型
aclsparseStatus_t aclsparseScsrgeam2_bufferSizeExt( aclsparseHandle_t handle, int m, int n, const float *alpha, const aclsparseMatDescr_t descrA, int nnzA, const float *csrSortedValA, const int *csrSortedRowPtrA, const int *csrSortedColIndA, const float *beta, const aclsparseMatDescr_t descrB, int nnzB, const float *csrSortedValB, const int *csrSortedRowPtrB, const int *csrSortedColIndB, const aclsparseMatDescr_t descrC, const float *csrSortedValC, const int *csrSortedRowPtrC, const int *csrSortedColIndC, size_t *pBufferSizeInBytes);
参数说明
参数名输入/输出参数类型说明
handle输入aclsparseHandle_tops-sparse 库上下文句柄,携带 stream、pointerMode 等信息,Host 内存
m输入int矩阵 A、B、C 的行数,m >= 0,Host 内存
n输入int矩阵 A、B、C 的列数,n >= 0,Host 内存
alpha输入const float*标量 α 指针,用于 A 的乘法系数。内存位置由aclsparseSetPointerMode控制,Host/Device 内存
descrA输入const aclsparseMatDescr_t矩阵 A 的描述符,仅支持ACL_SPARSE_MATRIX_TYPE_GENERAL类型,Host 内存
nnzA输入int矩阵 A 的非零元素个数,nnzA >= 0,Host 内存
csrSortedValA输入const float*A 的非零元素值数组,长度为 nnzA(nnzA=0 时可为 nullptr,本函数不读取),Device 内存
csrSortedRowPtrA输入const int*A 的行指针数组,长度为 m+1(m=0 时可为 nullptr),Device 内存
csrSortedColIndA输入const int*A 的列索引数组,长度为 nnzA(nnzA=0 时可为 nullptr),Device 内存
beta输入const float*标量 β 指针,用于 B 的乘法系数。内存位置由aclsparseSetPointerMode控制,Host/Device 内存
descrB输入const aclsparseMatDescr_t矩阵 B 的描述符,仅支持ACL_SPARSE_MATRIX_TYPE_GENERAL类型,Host 内存
nnzB输入int矩阵 B 的非零元素个数,nnzB >= 0,Host 内存
csrSortedValB输入const float*B 的非零元素值数组,长度为 nnzB(nnzB=0 时可为 nullptr,本函数不读取),Device 内存
csrSortedRowPtrB输入const int*B 的行指针数组,长度为 m+1(m=0 时可为 nullptr),Device 内存
csrSortedColIndB输入const int*B 的列索引数组,长度为 nnzB(nnzB=0 时可为 nullptr),Device 内存
descrC输入const aclsparseMatDescr_t矩阵 C 的描述符,仅支持ACL_SPARSE_MATRIX_TYPE_GENERAL类型,Host 内存
csrSortedValC输入const float*C 的非零元素值数组(可为 nullptr,本函数不读取),Device 内存
csrSortedRowPtrC输入const int*C 的行指针数组(可为 nullptr,本函数不读取),Device 内存
csrSortedColIndC输入const int*C 的列索引数组(可为 nullptr,本函数不读取),Device 内存
pBufferSizeInBytes输出size_t*输出所需 workspace 大小(字节),Host 内存
约束说明
  • m >= 0,n >= 0
  • nnzA >= 0,nnzB >= 0
  • handle 不可为 nullptr
  • descrA / descrB / descrC 不可为 nullptr,且 type 仅支持ACL_SPARSE_MATRIX_TYPE_GENERAL
  • descrA / descrB / descrC 的 indexBase 必须为ACL_SPARSE_INDEX_BASE_ZEROACL_SPARSE_INDEX_BASE_ONE
  • alpha / beta 不可为 nullptr
  • 当 m > 0 时,csrSortedRowPtrA / csrSortedRowPtrB 不可为 nullptr
  • 当 nnzA > 0 时,csrSortedColIndA 不可为 nullptr
  • 当 nnzB > 0 时,csrSortedColIndB 不可为 nullptr
  • pBufferSizeInBytes 不可为 nullptr
  • workspace 大小公式:(m + 1) * sizeof(int32_t)(前 m 个 int32_t 用于 nnzPerRow,第 m+1 个用于 nnzC)
  • csrSortedValA / csrSortedValB / csrSortedValC / csrSortedRowPtrC / csrSortedColIndC 可为 nullptr(本函数不读取这些指针,仅查询 workspace 大小)

aclsparseXcsrgeam2Nnz

产品支持情况
  • Ascend 950PR / Ascend 950DT:支持
  • Atlas A3 训练系列产品 / Atlas A3 推理系列产品:不支持
  • Atlas A2 训练系列产品 / Atlas A2 推理系列产品:不支持
函数原型
aclsparseStatus_t aclsparseXcsrgeam2Nnz( aclsparseHandle_t handle, int m, int n, const aclsparseMatDescr_t descrA, int nnzA, const int *csrSortedRowPtrA, const int *csrSortedColIndA, const aclsparseMatDescr_t descrB, int nnzB, const int *csrSortedRowPtrB, const int *csrSortedColIndB, const aclsparseMatDescr_t descrC, int *csrSortedRowPtrC, int *nnzTotalDevHostPtr, void *workspace);
参数说明
参数名输入/输出参数类型说明
handle输入aclsparseHandle_tops-sparse 库上下文句柄,Host 内存
m输入int矩阵行数,m >= 0,Host 内存
n输入int矩阵列数,n >= 0,Host 内存
descrA输入const aclsparseMatDescr_t矩阵 A 的描述符,Host 内存
nnzA输入int矩阵 A 的非零元素个数,Host 内存
csrSortedRowPtrA输入const int*A 的行指针数组,长度为 m+1,Device 内存
csrSortedColIndA输入const int*A 的列索引数组,长度为 nnzA,Device 内存
descrB输入const aclsparseMatDescr_t矩阵 B 的描述符,Host 内存
nnzB输入int矩阵 B 的非零元素个数,Host 内存
csrSortedRowPtrB输入const int*B 的行指针数组,长度为 m+1,Device 内存
csrSortedColIndB输入const int*B 的列索引数组,长度为 nnzB,Device 内存
descrC输入const aclsparseMatDescr_t矩阵 C 的描述符,Host 内存
csrSortedRowPtrC输出int*C 的行指针数组(输出),长度为 m+1。调用前需分配,Device 内存
nnzTotalDevHostPtr输出int*C 的非零元素总数 nnzC。内存位置由aclsparseSetPointerMode控制,Host/Device 内存
workspace输入void*workspace 缓冲区(由 bufferSizeExt 返回的大小分配),Device 内存
约束说明
  • m >= 0,n >= 0
  • nnzA >= 0,nnzB >= 0
  • handle 不可为 nullptr
  • descrA / descrB / descrC 不可为 nullptr,且 type 仅支持ACL_SPARSE_MATRIX_TYPE_GENERAL
  • descrA / descrB / descrC 的 indexBase 必须为ACL_SPARSE_INDEX_BASE_ZEROACL_SPARSE_INDEX_BASE_ONE
  • 当 m > 0 时,csrSortedRowPtrA / csrSortedRowPtrB 不可为 nullptr
  • 当 nnzA > 0 时,csrSortedColIndA 不可为 nullptr
  • 当 nnzB > 0 时,csrSortedColIndB 不可为 nullptr
  • csrSortedRowPtrC 不可为 nullptr(调用前需分配 m+1 大小的 int 数组)
  • nnzTotalDevHostPtr 不可为 nullptr
  • workspace 不可为 nullptr(需按 bufferSizeExt 返回的大小分配)
  • 当 m = 0 或 n = 0 时,函数直接返回成功,nnzC = 0
  • 注意:此函数使用 X 前缀(大写),表示与数据类型无关(不涉及值数组,仅操作索引结构)

aclsparseScsrgeam2

产品支持情况
  • Ascend 950PR / Ascend 950DT:支持
  • Atlas A3 训练系列产品 / Atlas A3 推理系列产品:不支持
  • Atlas A2 训练系列产品 / Atlas A2 推理系列产品:不支持
函数原型
aclsparseStatus_t aclsparseScsrgeam2( aclsparseHandle_t handle, int m, int n, const float *alpha, const aclsparseMatDescr_t descrA, int nnzA, const float *csrSortedValA, const int *csrSortedRowPtrA, const int *csrSortedColIndA, const float *beta, const aclsparseMatDescr_t descrB, int nnzB, const float *csrSortedValB, const int *csrSortedRowPtrB, const int *csrSortedColIndB, const aclsparseMatDescr_t descrC, float *csrSortedValC, int *csrSortedRowPtrC, int *csrSortedColIndC, void *pBuffer);
参数说明
参数名输入/输出参数类型说明
handle输入aclsparseHandle_tops-sparse 库上下文句柄,Host 内存
m输入int矩阵行数,m >= 0,Host 内存
n输入int矩阵列数,n >= 0,Host 内存
alpha输入const float*标量 α 指针。内存位置由aclsparseSetPointerMode控制,Host/Device 内存
descrA输入const aclsparseMatDescr_t矩阵 A 的描述符,Host 内存
nnzA输入int矩阵 A 的非零元素个数,Host 内存
csrSortedValA输入const float*A 的非零元素值数组,长度为 nnzA,Device 内存
csrSortedRowPtrA输入const int*A 的行指针数组,长度为 m+1,Device 内存
csrSortedColIndA输入const int*A 的列索引数组,长度为 nnzA,Device 内存
beta输入const float*标量 β 指针。内存位置由aclsparseSetPointerMode控制,Host/Device 内存
descrB输入const aclsparseMatDescr_t矩阵 B 的描述符,Host 内存
nnzB输入int矩阵 B 的非零元素个数,Host 内存
csrSortedValB输入const float*B 的非零元素值数组,长度为 nnzB,Device 内存
csrSortedRowPtrB输入const int*B 的行指针数组,长度为 m+1,Device 内存
csrSortedColIndB输入const int*B 的列索引数组,长度为 nnzB,Device 内存
descrC输入const aclsparseMatDescr_t矩阵 C 的描述符,Host 内存
csrSortedValC输出float*C 的非零元素值数组(输出),长度为 nnzC,Device 内存
csrSortedRowPtrC输入int*C 的行指针数组(由 Nnz 阶段填充),长度为 m+1,Device 内存
csrSortedColIndC输出int*C 的列索引数组(输出),长度为 nnzC,Device 内存
pBuffer输入void*workspace 缓冲区(由 bufferSizeExt 返回的大小分配),Device 内存
约束说明
  • m >= 0,n >= 0
  • nnzA >= 0,nnzB >= 0
  • handle 不可为 nullptr
  • descrA / descrB / descrC 不可为 nullptr,且 type 仅支持ACL_SPARSE_MATRIX_TYPE_GENERAL
  • descrA / descrB / descrC 的 indexBase 必须为ACL_SPARSE_INDEX_BASE_ZEROACL_SPARSE_INDEX_BASE_ONE
  • 当 m > 0 时,csrSortedRowPtrA / csrSortedRowPtrB / csrSortedRowPtrC 不可为 nullptr
  • 当 nnzA > 0 时,csrSortedValA / csrSortedColIndA 不可为 nullptr
  • 当 nnzB > 0 时,csrSortedValB / csrSortedColIndB 不可为 nullptr
  • csrSortedValC / csrSortedColIndC 不可为 nullptr(需按 nnzC 分配)
  • pBuffer 不可为 nullptr
  • 调用前必须先调用aclsparseXcsrgeam2Nnz填充csrRowPtrC和获取nnzC
  • 当 m = 0 或 n = 0 时,函数直接返回成功

支持的稀疏格式

格式支持说明
CSRA、B、C 三个矩阵均为 CSR 格式
COOcsrgeam2 仅支持 CSR
CSCcsrgeam2 仅支持 CSR

CSR 格式索引结构

数组长度说明
csrRowPtrm + 1行偏移指针,csrRowPtr[i] 是第 i 行非零元素的起始索引
csrColIndnnz列索引数组
csrValnnz非零元素值数组

索引基址

通过 MatDescr 的indexBase字段指定:

  • ACL_SPARSE_INDEX_BASE_ZERO:0-based(C 风格)
  • ACL_SPARSE_INDEX_BASE_ONE:1-based(Fortran 风格)

A、B、C 的索引基址可以不同,各自通过独立的 MatDescr 指定。

数据类型

精度前缀计算类型值类型说明
SFP32FP32当前唯一支持的精度(S 前缀)

索引类型:int32(32 位有符号整数)。

调用示例

示例代码如下,仅供参考,具体编译和执行过程请参考编译与运行样例。

#include <cstdio> #include <memory> #include <vector> #include "acl/acl.h" #include "cann_ops_sparse.h" #define CHECK_RET(cond, return_expr) \ do { \ if (!(cond)) { \ return_expr; \ } \ } while (0) #define LOG_PRINT(message, ...) \ do { \ printf(message, ##__VA_ARGS__); \ } while (0) class AclContext { public: explicit AclContext(int32_t deviceId) : deviceId_(deviceId) {} ~AclContext() { if (stream_ != nullptr) { aclrtDestroyStream(stream_); stream_ = nullptr; } if (deviceSet_) { aclrtResetDevice(deviceId_); deviceSet_ = false; } if (aclInited_) { aclFinalize(); aclInited_ = false; } } int Init() { auto ret = aclInit(nullptr); CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclInit failed. ERROR: %d\n", ret); return ret); aclInited_ = true; ret = aclrtSetDevice(deviceId_); CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSetDevice failed. ERROR: %d\n", ret); return ret); deviceSet_ = true; ret = aclrtCreateStream(&stream_); CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtCreateStream failed. ERROR: %d\n", ret); return ret); return ACL_SUCCESS; } aclrtStream Stream() const { return stream_; } private: int32_t deviceId_; aclrtStream stream_ = nullptr; bool aclInited_ = false; bool deviceSet_ = false; }; // 辅助:分配 Device 内存并拷贝 Host 数据 static void* AllocAndCopyDevice(void *hostPtr, size_t sizeBytes) { void *dPtr = nullptr; aclrtMalloc(&dPtr, sizeBytes, ACL_MEM_MALLOC_HUGE_FIRST); if (hostPtr != nullptr && sizeBytes > 0) { aclrtMemcpy(dPtr, sizeBytes, hostPtr, sizeBytes, ACL_MEMCPY_HOST_TO_DEVICE); } return dPtr; } int aclsparseCsrgeam2Test(AclContext &ctx) { aclrtStream stream = ctx.Stream(); // 1. 创建 ops-sparse 句柄 aclsparseHandle_t rawHandle = nullptr; auto sparseRet = aclsparseCreate(&rawHandle); CHECK_RET(sparseRet == ACL_SPARSE_STATUS_SUCCESS, LOG_PRINT("aclsparseCreate failed: %d\n", sparseRet); return sparseRet); std::unique_ptr<aclsparseContext, aclsparseStatus_t (*)(aclsparseHandle_t)> handlePtr(rawHandle, aclsparseDestroy); aclsparseSetStream(handlePtr.get(), stream); aclsparseSetPointerMode(handlePtr.get(), ACL_SPARSE_POINTER_MODE_HOST); // 2. 准备 Host 端 CSR 数据 // 示例:两个 3x3 的稀疏矩阵 A 和 B // // A (3x3, nnzA=4): B (3x3, nnzB=2): // [1.0 0.0 2.0] [0.0 0.0 5.0] // [0.0 4.0 0.0] [6.0 0.0 0.0] // [3.0 0.0 0.0] [0.0 0.0 0.0] // // C = 1.0 * A + 1.0 * B: // C[0] = [1.0, 0.0, 7.0 ] (nnz: 2) // C[1] = [6.0, 4.0, 0.0 ] (nnz: 2) // C[2] = [3.0, 0.0, 0.0 ] (nnz: 1) // => nnzC = 5 int m = 3; int n = 3; int nnzA = 4; int nnzB = 2; float hAlpha = 1.0f; float hBeta = 1.0f; // A: CSR 数据 (3x3, nnzA=4) std::vector<int> hRowPtrA = {0, 2, 3, 4}; std::vector<int> hColIndA = {0, 2, 1, 0}; std::vector<float> hValA = {1.0f, 2.0f, 4.0f, 3.0f}; // B: CSR 数据 (3x3, nnzB=2) std::vector<int> hRowPtrB = {0, 1, 2, 2}; std::vector<int> hColIndB = {2, 0}; std::vector<float> hValB = {5.0f, 6.0f}; // 3. 创建 MatDescr(A/B/C 各自独立) aclsparseMatDescr_t descrA = nullptr, descrB = nullptr, descrC = nullptr; aclsparseCreateMatDescr(&descrA); aclsparseCreateMatDescr(&descrB); aclsparseCreateMatDescr(&descrC); aclsparseSetMatType(descrA, ACL_SPARSE_MATRIX_TYPE_GENERAL); aclsparseSetMatType(descrB, ACL_SPARSE_MATRIX_TYPE_GENERAL); aclsparseSetMatType(descrC, ACL_SPARSE_MATRIX_TYPE_GENERAL); aclsparseSetMatIndexBase(descrA, ACL_SPARSE_INDEX_BASE_ZERO); aclsparseSetMatIndexBase(descrB, ACL_SPARSE_INDEX_BASE_ZERO); aclsparseSetMatIndexBase(descrC, ACL_SPARSE_INDEX_BASE_ZERO); // 4. 拷贝 A/B 的 CSR 数据到 Device void *dRowPtrA = AllocAndCopyDevice(hRowPtrA.data(), (m + 1) * sizeof(int)); void *dColIndA = AllocAndCopyDevice(hColIndA.data(), nnzA * sizeof(int)); void *dValA = AllocAndCopyDevice(hValA.data(), nnzA * sizeof(float)); void *dRowPtrB = AllocAndCopyDevice(hRowPtrB.data(), (m + 1) * sizeof(int)); void *dColIndB = AllocAndCopyDevice(hColIndB.data(), nnzB * sizeof(int)); void *dValB = AllocAndCopyDevice(hValB.data(), nnzB * sizeof(float)); // 5. Step 1 — bufferSizeExt: 查询 workspace 大小 size_t bufferSize = 0; sparseRet = aclsparseScsrgeam2_bufferSizeExt( handlePtr.get(), m, n, &hAlpha, descrA, nnzA, static_cast<const float*>(dValA), static_cast<const int*>(dRowPtrA), static_cast<const int*>(dColIndA), &hBeta, descrB, nnzB, static_cast<const float*>(dValB), static_cast<const int*>(dRowPtrB), static_cast<const int*>(dColIndB), descrC, nullptr, nullptr, nullptr, &bufferSize); CHECK_RET(sparseRet == ACL_SPARSE_STATUS_SUCCESS, LOG_PRINT("bufferSizeExt failed: %d\n", sparseRet); return sparseRet); LOG_PRINT("bufferSize = %zu bytes\n", bufferSize); // 分配 workspace void *dWorkspace = nullptr; aclrtMalloc(&dWorkspace, bufferSize, ACL_MEM_MALLOC_HUGE_FIRST); // 6. Step 2 — Xcsrgeam2Nnz: 计算 C 的 csrRowPtrC 和 nnzC // 预分配 csrRowPtrC (m+1) void *dRowPtrC = nullptr; aclrtMalloc(&dRowPtrC, (m + 1) * sizeof(int), ACL_MEM_MALLOC_HUGE_FIRST); int nnzC = 0; // HOST 模式下,nnzC 直接写入 host 变量 sparseRet = aclsparseXcsrgeam2Nnz( handlePtr.get(), m, n, descrA, nnzA, static_cast<const int*>(dRowPtrA), static_cast<const int*>(dColIndA), descrB, nnzB, static_cast<const int*>(dRowPtrB), static_cast<const int*>(dColIndB), descrC, static_cast<int*>(dRowPtrC), &nnzC, // HOST 指针 dWorkspace); CHECK_RET(sparseRet == ACL_SPARSE_STATUS_SUCCESS, LOG_PRINT("Xcsrgeam2Nnz failed: %d\n", sparseRet); return sparseRet); LOG_PRINT("nnzC = %d\n", nnzC); // 7. Step 3 — Scsrgeam2: 计算 C 的列索引和值 void *dColIndC = nullptr; void *dValC = nullptr; aclrtMalloc(&dColIndC, nnzC * sizeof(int), ACL_MEM_MALLOC_HUGE_FIRST); aclrtMalloc(&dValC, nnzC * sizeof(float), ACL_MEM_MALLOC_HUGE_FIRST); // 分配主计算 pBuffer(可与 Nnz 阶段的 workspace 共用或独立分配) void *dPBuffer = nullptr; aclrtMalloc(&dPBuffer, bufferSize, ACL_MEM_MALLOC_HUGE_FIRST); sparseRet = aclsparseScsrgeam2( handlePtr.get(), m, n, &hAlpha, descrA, nnzA, static_cast<const float*>(dValA), static_cast<const int*>(dRowPtrA), static_cast<const int*>(dColIndA), &hBeta, descrB, nnzB, static_cast<const float*>(dValB), static_cast<const int*>(dRowPtrB), static_cast<const int*>(dColIndB), descrC, static_cast<float*>(dValC), static_cast<int*>(dRowPtrC), static_cast<int*>(dColIndC), dPBuffer); CHECK_RET(sparseRet == ACL_SPARSE_STATUS_SUCCESS, LOG_PRINT("Scsrgeam2 failed: %d\n", sparseRet); return sparseRet); // 8. 同步等待计算完成 aclrtSynchronizeStream(stream); // 9. 将结果拷贝回 Host 并打印 std::vector<int> hRowPtrC(m + 1, 0); std::vector<int> hColIndC(nnzC, 0); std::vector<float> hValC(nnzC, 0.0f); aclrtMemcpy(hRowPtrC.data(), (m + 1) * sizeof(int), dRowPtrC, (m + 1) * sizeof(int), ACL_MEMCPY_DEVICE_TO_HOST); aclrtMemcpy(hColIndC.data(), nnzC * sizeof(int), dColIndC, nnzC * sizeof(int), ACL_MEMCPY_DEVICE_TO_HOST); aclrtMemcpy(hValC.data(), nnzC * sizeof(float), dValC, nnzC * sizeof(float), ACL_MEMCPY_DEVICE_TO_HOST); LOG_PRINT("\nResult C (CSR):\n"); LOG_PRINT(" rowPtr: "); for (int i = 0; i <= m; i++) { LOG_PRINT("%d ", hRowPtrC[i]); } LOG_PRINT("\n colInd: "); for (int i = 0; i < nnzC; i++) { LOG_PRINT("%d ", hColIndC[i]); } LOG_PRINT("\n val: "); for (int i = 0; i < nnzC; i++) { LOG_PRINT("%.1f ", hValC[i]); } LOG_PRINT("\n"); // 10. 清理资源 aclsparseDestroyMatDescr(descrA); aclsparseDestroyMatDescr(descrB); aclsparseDestroyMatDescr(descrC); if (dRowPtrA) aclrtFree(dRowPtrA); if (dColIndA) aclrtFree(dColIndA); if (dValA) aclrtFree(dValA); if (dRowPtrB) aclrtFree(dRowPtrB); if (dColIndB) aclrtFree(dColIndB); if (dValB) aclrtFree(dValB); if (dRowPtrC) aclrtFree(dRowPtrC); if (dColIndC) aclrtFree(dColIndC); if (dValC) aclrtFree(dValC); if (dWorkspace) aclrtFree(dWorkspace); if (dPBuffer) aclrtFree(dPBuffer); return ACL_SPARSE_STATUS_SUCCESS; } int main() { AclContext ctx(0); auto ret = ctx.Init(); CHECK_RET(ret == ACL_SUCCESS, return ret); ret = aclsparseCsrgeam2Test(ctx); CHECK_RET(ret == ACL_SPARSE_STATUS_SUCCESS, LOG_PRINT("aclsparseCsrgeam2Test failed: %d\n", ret); return ret); return 0; }

预期输出如下:

bufferSize = 16 bytes nnzC = 5 Result C (CSR): rowPtr: 0 2 4 5 colInd: 0 2 0 1 0 val: 1.0 7.0 6.0 4.0 3.0

【免费下载链接】ops-sparse本项目是CANN提供的高性能稀疏矩阵计算的算子库,专注于优化稀疏矩阵的计算效率。项目地址: https://gitcode.com/cann/ops-sparse

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

http://www.jsqmd.com/news/1192845/

相关文章:

  • CANN/asc-devkit: asc_copy函数文档
  • 【Opencv-Python】数字图像处理(一) —— 从零搭建图像处理环境与核心操作
  • 2026 漳厦泉彩钢房活动板房拆除废旧金属回收商户 TOP5 实测测评 - LYL仔仔
  • opencode 调试环境搭建手记:从 bun install 到 VSCode 断点
  • ngx-ui对话框与抽屉组件:打造现代化模态交互体验的终极指南
  • 自身免疫“风暴眼“——GM-CSF/IFN-γ/IFN-α/IL-12/IL-17/IL-23/IL-6七联Panel锁定Th17/Treg失衡的分子推手
  • 基于PLC与多传感器协同的智能物料分拣系统课程设计
  • AMIC110串行通信接口硬件设计:I2C、SPI、UART引脚配置与电气特性实战
  • CANN/cannbot-skills CP2.2方案检查验收标准
  • 开源方案解析 | 基于多传感器融合的智能消防机器人自主巡检与灭火系统
  • Blender license 放大器,三款优化方案哪个最好
  • TradingView Webhooks Bot架构深度解析:事件驱动交易框架的核心原理
  • 系统硬件工程师实战指南--本安电路关键参数计算与选型
  • CANNBot直调算子工作流状态结构
  • openEuler OpenStack SIG:打造原生OpenStack云平台的终极指南
  • 电子器件系列:三输入与门芯片74LS11的实战应用与选型指南
  • 从接口到设备:MICIN、LINEIN、LINEOUT、HPOUT的电路原理与选型避坑指南
  • UDS DTC老化机制:从Pending到Confirmed再到Aging的完整生命周期解析
  • 保山边境特种作业考证中心|云南安崇职业技能培训学校市区校区,覆盖全市所有县域 - 资讯焦点
  • datalib核心功能详解:从统计分析到字符串模板的完整指南
  • 终极MMPlayerView使用教程:掌握视频缩放与全屏切换技巧
  • DS90UR910-Q1桥接芯片:FPD-Link转CSI-2接口的硬件设计与驱动开发实战
  • Kmesh在Istio环境中的部署与集成:提升服务网格性能的最佳实践
  • 2026官方认证!常州高端家居定制实测推荐与真实口碑盘点 - 热点速览
  • CANN/cannbot-skills编码红线与解决方案
  • CANN / hcomm 实验性NIC插件指南
  • 【技术解析】基于双矢量优化MPC的MMC-PET光储系统谐波抑制与电网稳定策略
  • 2026官方认证!泉州晋江代理记账首选,透明无套路 - 热点速览
  • openEuler/deepin-rpm-installer开发实战:构建高效RPM安装服务的10个核心技术
  • FileSync终极指南:如何实现跨设备实时文件传输的完整教程