{算子名称}算子
算子概述
{一段话描述算子的功能定位和核心运算。例如:"{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_t | ops-sparse 库上下文句柄,携带 stream,Host 内存 |
| m | 输入 | int | {参数含义},Host 内存 |
| A | 输入 | const float*(FP32) | {参数含义},Device 内存 |
约束说明
- m >= 0
- n >= 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_ptr<aclsparseContext, aclsparseStatus_t (*)(aclsparseHandle_t)> handlePtr(rawHandle, aclsparseDestroy);
sparseRet = aclsparseSetStream(static_cast<aclsparseHandle_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_cast<aclsparseHandle_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::vector<float> hA(m * n, 0.0f); }
// 5. 申请 Device 内存并拷贝数据
// {按算子需求使用 aclrtMalloc + std::unique_ptr + aclrtFree 管理 Device 内存}
// {按算子需求使用 aclrtMemcpy 拷贝数据到 Device}
// 6. 调用 aclsparseS{op}
// sparseRet = aclsparseS{op}(static_cast<aclsparseHandle_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: xxx
aclsparseD{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_t | ops-sparse 库上下文句柄,携带 stream,Host 内存 |
| m | 输入 | int | {参数含义},Host 内存 |
| A | 输入 | const double*(FP64) | {参数含义},Device 内存 |
约束说明
- m >= 0
- n >= 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_ptr<aclsparseContext, aclsparseStatus_t (*)(aclsparseHandle_t)> handlePtr(rawHandle, aclsparseDestroy);
sparseRet = aclsparseSetStream(static_cast<aclsparseHandle_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_cast<aclsparseHandle_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::vector<double> hA(m * n, 0.0); }
// 5. 申请 Device 内存并拷贝数据
// {按算子需求使用 aclrtMalloc + std::unique_ptr + aclrtFree 管理 Device 内存}
// {按算子需求使用 aclrtMemcpy 拷贝数据到 Device}
// 6. 调用 aclsparseD{op}
// sparseRet = aclsparseD{op}(static_cast<aclsparseHandle_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