CANN/ops-sparse稀疏算子开发指南
{算子名称}算子【免费下载链接】ops-sparse本项目是CANN提供的高性能稀疏矩阵计算的算子库专注于优化稀疏矩阵的计算效率。项目地址: https://gitcode.com/cann/ops-sparse算子概述{一段话描述算子的功能定位和核心运算。例如{op} 算子实现了{功能描述}核心运算为{运算描述}。}数学表达式{数学公式使用纯文本。如需要可用 LaTeX 格式$$...$$}包含以下接口接口名功能简述aclsparseS{op}{单精度功能描述}aclsparseD{op}{双精度功能描述}算子执行接口aclsparseS{op}产品支持情况Ascend 950PR / Ascend 950DT{支持/不支持}Atlas A3 训练系列产品 / Atlas A3 推理系列产品{支持/不支持}Atlas A2 训练系列产品 / Atlas A2 推理系列产品{支持/不支持}函数原型aclsparseStatus_t aclsparseS{op}(aclsparseHandle_t handle, int m, int n, const float *A, ...)参数说明参数名输入/输出参数类型说明handle输入aclsparseHandle_tops-sparse 库上下文句柄携带 streamHost 内存m输入int{参数含义}Host 内存A输入const float*FP32{参数含义}Device 内存约束说明m 0n 0{如无约束则写无不允许留空。}支持的稀疏格式{如算子涉及稀疏矩阵格式CSR/COO/CSC 等按下表列出支持情况如不涉及稀疏格式则删除本节。}格式支持说明CSR{✅/❌}{说明}COO{✅/❌}{说明}CSC{✅/❌}{说明}调用示例示例代码如下仅供参考具体编译和执行过程请参考编译与运行样例。#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; }; int aclsparseS{op}Test(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. ERROR: %d\n, sparseRet); return sparseRet); std::unique_ptraclsparseContext, aclsparseStatus_t (*)(aclsparseHandle_t) handlePtr(rawHandle, aclsparseDestroy); sparseRet aclsparseSetStream(static_castaclsparseHandle_t(handlePtr.get()), stream); CHECK_RET(sparseRet ACL_SPARSE_STATUS_SUCCESS, LOG_PRINT(aclsparseSetStream failed. ERROR: %d\n, sparseRet); return sparseRet); // 2. 设置 PointerMode如算子含标量指针参数如 alpha、beta须设置否则可省略 // sparseRet aclsparseSetPointerMode(static_castaclsparseHandle_t(handlePtr.get()), ACL_SPARSE_POINTER_MODE_HOST); // CHECK_RET(sparseRet ACL_SPARSE_STATUS_SUCCESS, LOG_PRINT(aclsparseSetPointerMode failed. ERROR: %d\n, sparseRet); // return sparseRet); // 3. 创建 MatDescr如算子需要 aclsparseMatDescr_t须创建并配置否则可省略 // aclsparseMatDescr_t matDescr nullptr; // sparseRet aclsparseCreateMatDescr(matDescr); // CHECK_RET(sparseRet ACL_SPARSE_STATUS_SUCCESS, LOG_PRINT(aclsparseCreateMatDescr failed. ERROR: %d\n, sparseRet); // return sparseRet); // aclsparseSetMatType(matDescr, ACL_SPARSE_MATRIX_TYPE_GENERAL); // aclsparseSetMatIndexBase(matDescr, ACL_SPARSE_INDEX_BASE_ZERO); // 4. 准备 Host 数据 // {按算子需求定义参数并初始化 Host 数据如 std::vectorfloat hA(m * n, 0.0f); } // 5. 申请 Device 内存并拷贝数据 // {按算子需求使用 aclrtMalloc std::unique_ptr aclrtFree 管理 Device 内存} // {按算子需求使用 aclrtMemcpy 拷贝数据到 Device} // 6. 调用 aclsparseS{op} // sparseRet aclsparseS{op}(static_castaclsparseHandle_t(handlePtr.get()), ...); // CHECK_RET(sparseRet ACL_SPARSE_STATUS_SUCCESS, LOG_PRINT(aclsparseS{op} failed. ERROR: %d\n, sparseRet); // return sparseRet); // 7. 同步等待任务执行结束 auto aclRet aclrtSynchronizeStream(stream); CHECK_RET(aclRet ACL_SUCCESS, LOG_PRINT(aclrtSynchronizeStream failed. ERROR: %d\n, aclRet); return aclRet); // 8. 将结果从 Device 拷贝回 Host 并打印 // {按算子需求使用 aclrtMemcpy 拷贝结果回 Host 并打印验证} // 9. 清理 MatDescr如步骤 3 已创建 // aclsparseDestroyMatDescr(matDescr); return ACL_SPARSE_STATUS_SUCCESS; } int main() { AclContext ctx(0); auto ret ctx.Init(); CHECK_RET(ret ACL_SUCCESS, return ret); ret aclsparseS{op}Test(ctx); CHECK_RET(ret ACL_SPARSE_STATUS_SUCCESS, LOG_PRINT(aclsparseS{op}Test failed. ERROR: %d\n, ret); return ret); return 0; }预期输出如下{按算子实际输出填写如} result[0] is: xxx result[1] is: xxxaclsparseD{op}产品支持情况Ascend 950PR / Ascend 950DT{支持/不支持}Atlas A3 训练系列产品 / Atlas A3 推理系列产品{支持/不支持}Atlas A2 训练系列产品 / Atlas A2 推理系列产品{支持/不支持}函数原型aclsparseStatus_t aclsparseD{op}(aclsparseHandle_t handle, int m, int n, const double *A, ...)参数说明参数名输入/输出参数类型说明handle输入aclsparseHandle_tops-sparse 库上下文句柄携带 streamHost 内存m输入int{参数含义}Host 内存A输入const double*FP64{参数含义}Device 内存约束说明m 0n 0{如无约束则写无不允许留空。}支持的稀疏格式{如算子涉及稀疏矩阵格式CSR/COO/CSC 等按下表列出支持情况如不涉及稀疏格式则删除本节。}格式支持说明CSR{✅/❌}{说明}COO{✅/❌}{说明}CSC{✅/❌}{说明}调用示例示例代码如下仅供参考具体编译和执行过程请参考编译与运行样例。#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; }; int aclsparseD{op}Test(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. ERROR: %d\n, sparseRet); return sparseRet); std::unique_ptraclsparseContext, aclsparseStatus_t (*)(aclsparseHandle_t) handlePtr(rawHandle, aclsparseDestroy); sparseRet aclsparseSetStream(static_castaclsparseHandle_t(handlePtr.get()), stream); CHECK_RET(sparseRet ACL_SPARSE_STATUS_SUCCESS, LOG_PRINT(aclsparseSetStream failed. ERROR: %d\n, sparseRet); return sparseRet); // 2. 设置 PointerMode如算子含标量指针参数如 alpha、beta须设置否则可省略 // sparseRet aclsparseSetPointerMode(static_castaclsparseHandle_t(handlePtr.get()), ACL_SPARSE_POINTER_MODE_HOST); // CHECK_RET(sparseRet ACL_SPARSE_STATUS_SUCCESS, LOG_PRINT(aclsparseSetPointerMode failed. ERROR: %d\n, sparseRet); // return sparseRet); // 3. 创建 MatDescr如算子需要 aclsparseMatDescr_t须创建并配置否则可省略 // aclsparseMatDescr_t matDescr nullptr; // sparseRet aclsparseCreateMatDescr(matDescr); // CHECK_RET(sparseRet ACL_SPARSE_STATUS_SUCCESS, LOG_PRINT(aclsparseCreateMatDescr failed. ERROR: %d\n, sparseRet); // return sparseRet); // aclsparseSetMatType(matDescr, ACL_SPARSE_MATRIX_TYPE_GENERAL); // aclsparseSetMatIndexBase(matDescr, ACL_SPARSE_INDEX_BASE_ZERO); // 4. 准备 Host 数据 // {按算子需求定义参数并初始化 Host 数据如 std::vectordouble hA(m * n, 0.0); } // 5. 申请 Device 内存并拷贝数据 // {按算子需求使用 aclrtMalloc std::unique_ptr aclrtFree 管理 Device 内存} // {按算子需求使用 aclrtMemcpy 拷贝数据到 Device} // 6. 调用 aclsparseD{op} // sparseRet aclsparseD{op}(static_castaclsparseHandle_t(handlePtr.get()), ...); // CHECK_RET(sparseRet ACL_SPARSE_STATUS_SUCCESS, LOG_PRINT(aclsparseD{op} failed. ERROR: %d\n, sparseRet); // return sparseRet); // 7. 同步等待任务执行结束 auto aclRet aclrtSynchronizeStream(stream); CHECK_RET(aclRet ACL_SUCCESS, LOG_PRINT(aclrtSynchronizeStream failed. ERROR: %d\n, aclRet); return aclRet); // 8. 将结果从 Device 拷贝回 Host 并打印 // {按算子需求使用 aclrtMemcpy 拷贝结果回 Host 并打印验证} // 9. 清理 MatDescr如步骤 3 已创建 // aclsparseDestroyMatDescr(matDescr); return ACL_SPARSE_STATUS_SUCCESS; } int main() { AclContext ctx(0); auto ret ctx.Init(); CHECK_RET(ret ACL_SUCCESS, return ret); ret aclsparseD{op}Test(ctx); CHECK_RET(ret ACL_SPARSE_STATUS_SUCCESS, LOG_PRINT(aclsparseD{op}Test failed. ERROR: %d\n, ret); return ret); return 0; }预期输出如下{按算子实际输出填写如} result[0] is: xxx result[1] is: xxx【免费下载链接】ops-sparse本项目是CANN提供的高性能稀疏矩阵计算的算子库专注于优化稀疏矩阵的计算效率。项目地址: https://gitcode.com/cann/ops-sparse创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
