自定义算子的C++接口说明
概述
MindSpore自定义算子的C++接口分为两类:
API 接口: 标记为 【API】 的接口是稳定的公开接口,供用户直接使用。这些接口经过充分测试,功能明确,向后兼容性较高。
实验性接口: 未标记为 【API】 的接口为实验性接口。这些接口可能会在未来版本中发生变动或被移除,使用时需谨慎。
自定义算子开发时,通过 #include "ms_extension/api.h"
即可引用下方接口涉及的头文件,无需关注每个接口的具体位置。
namespace ms
enum TypeId
TypeId
枚举类型定义在type_id.h头文件中,定义了 MindSpore 中支持的张量数据类型,包括布尔值、整数类型、浮点数类型、复数类型等。
此接口也被包含在 namespace ms
中,通过ms::TypeId
也可以访问。
kNumberTypeBegin, // Number 类型起始值
kNumberTypeBool, // 布尔类型
kNumberTypeInt, // 默认整数类型
kNumberTypeInt8, // 8 位有符号整数
kNumberTypeInt16, // 16 位有符号整数
kNumberTypeInt32, // 32 位有符号整数
kNumberTypeInt64, // 64 位有符号整数
kNumberTypeUInt, // 默认无符号整数类型
kNumberTypeUInt8, // 8 位无符号整数
kNumberTypeUInt16, // 16 位无符号整数
kNumberTypeUInt32, // 32 位无符号整数
kNumberTypeUInt64, // 64 位无符号整数
kNumberTypeFloat, // 默认浮点数类型
kNumberTypeFloat16, // 16 位半精度浮点数
kNumberTypeFloat32, // 32 位单精度浮点数
kNumberTypeFloat64, // 64 位双精度浮点数
kNumberTypeBFloat16, // 16 位脑浮点数
kNumberTypeDouble, // 双精度浮点数(等价于 kNumberTypeFloat64 )
kNumberTypeComplex, // 默认复数类型
kNumberTypeComplex64, // 64 位复数(由2 个 32 位浮点数组成)
kNumberTypeComplex128, // 128 位复数(由2 个 64 位浮点数组成)
kNumberTypeInt4, // 4 位有符号整数
kNumberTypeGLUInt, // OpenGL 无符号整数类型
kNumberTypeEnd, // Number 类型结束值
class Tensor
张量类定义在tensor.h头文件中,表示 MindSpore 的张量对象,提供操作和查询张量属性的方法。
构造函数
Tensor()
描述:【API】 构造一个未定义的占位符张量。
Tensor(TypeId, const ShapeVector &)
Tensor(TypeId type_id, const ShapeVector &shape)
描述:【API】 根据指定的数据类型和形状构造一个张量。
参数:
type_id
:张量的数据类型。shape
:张量的形状,表示为整数向量。
Tensor(const mindspore::ValuePtr &)
Tensor(const mindspore::ValuePtr &value)
描述:从给定的
ValuePtr
构造一个张量对象。参数:
value
:指向 MindSporeValue
对象的智能指针。如果值为nullptr
,则构造未定义的张量。
公共方法(属性及配置)
is_defined()
bool is_defined() const
描述:【API】 检查张量是否已定义。
返回值:如果张量已定义返回
true
,否则返回false
。
data_type()
TypeId data_type() const
描述:【API】 获取张量的数据类型。
返回值:张量的数据类型。
shape()
const ShapeVector &shape() const
描述:【API】 获取张量的形状。
返回值:张量形状的引用(
ShapeVector
, 即std::vector<int64_t>
)。
numel()
size_t numel() const
描述:【API】 返回张量中的元素总数。
返回值:元素的总数。
stride()
std::vector<int64_t> stride() const
描述:【API】 计算张量的步幅。
返回值:表示张量每个维度步幅的向量。
storage_offset()
int64_t storage_offset() const
描述:【API】 获取张量的存储偏移量。
返回值:从存储开始的偏移量(以元素为单位)。
is_contiguous()
bool is_contiguous() const
描述:【API】 检查张量在内存中的存储是否连续。
返回值:如果张量存储连续返回
true
,否则返回false
。
SetNeedContiguous(bool)
void SetNeedContiguous(bool flag) const
描述:【API】 设置张量是否需要连续存储空间。
参数:
flag
:一个布尔值,表示张量是否需要连续存储。
GetDataPtr()
void *GetDataPtr() const
描述:【API】 获取指向张量数据的指针。
返回值:指向张量数据的
void
指针。注意:返回的指针已经包含了
storage_offset()
接口指示的偏移量。
公共方法(算子调用)
cast(TypeId)
Tensor cast(TypeId dtype) const
描述:【API】将张量转换为指定的数据类型。
参数:
dtype
:目标数据类型,支持的类型包括float
、int
等。
返回值:返回一个具有指定数据类型的新张量。
chunk(int64_t, int64_t)
std::vector<Tensor> chunk(int64_t chunks, int64_t dim = 0) const
描述:【API】沿指定维度将张量拆分为多个小张量。
参数:
chunks
:拆分的块数,必须是正数。dim
:指定的拆分维度,默认为 0。
返回值:一个包含多个小张量的向量,每个块的大小相等。若维度大小无法整除块数,最后一个块可能较小。
contiguous()
Tensor contiguous() const
描述:【API】返回一个在内存中连续存储的张量。
返回值:一个连续存储的新张量。
flatten(int64_t, int64_t)
Tensor flatten(int64_t start_dim = 0, int64_t end_dim = -1) const
描述:【API】将张量的多个维度展平为一个维度。
参数:
start_dim
:开始展平的维度,默认为 0。end_dim
:结束展平的维度,默认为 -1(最后一个维度)。
返回值:一个展平后的张量。
index_select(int64_t, const Tensor &)
Tensor index_select(int64_t dim, const Tensor &index) const
描述:【API】根据索引张量在指定维度选择元素。
参数:
dim
:指定的维度。index
:包含索引的张量。张量的值必须在[0, shape(dim)-1]
区间内。
返回值:一个包含选定元素的新张量。
reshape(const std::vector<int64_t> &)
Tensor reshape(const std::vector<int64_t> &shape) const
描述:【API】将张量重塑为指定的形状。
参数:
shape
:一个向量,指定新形状。新形状的元素总数必须与原张量一致,可在其中一个维度中使用-1
进行自动推断。
返回值:一个具有新形状的张量。
repeat(const std::vector<int64_t> &)
Tensor repeat(const std::vector<int64_t> &repeats) const
描述:【API】沿每个维度重复张量。
参数:
repeats
:一个向量,指定每个维度的重复次数,其大小必须与张量的维度数相同。
返回值:一个重复后的新张量。
repeat_interleave
Tensor repeat_interleave(const Tensor &repeats, const std::optional<int64_t> &dim = std::nullopt, const std::optional<int64_t> &output_size = std::nullopt) const; Tensor repeat_interleave(int64_t repeats, const std::optional<int64_t> &dim = std::nullopt, const std::optional<int64_t> &output_size = std::nullopt) const;
描述:【API】沿指定维度重复张量的元素。
参数:
repeats
:一个标量或张量,指定每个元素的重复次数。如果是张量,其大小必须与该维度的张量大小一致。dim
:(可选)指定的维度,默认为std::nullopt
。output_size
:(可选)输出张量在该维度的大小,默认为std::nullopt
。
返回值:一个重复元素的新张量。
公共方法(内部流程)
以下方法非API,仅在内部模块流程中使用,但由于语法限制,需要设置成公共方法。不推荐用户直接使用。
need_contiguous()
bool need_contiguous() const
描述:检查张量是否需要连续存储空间。
返回值:如果张量需要连续存储返回
true
,否则返回false
。
stub_node()
const mindspore::ValuePtr &stub_node() const
描述:获取与张量关联的存根节点。
返回值:指向存根节点(
ValuePtr
)的智能指针。
tensor()
const mindspore::tensor::TensorPtr &tensor() const
描述:获取底层张量对象。
返回值:指向
TensorPtr
对象的智能指针。
ConvertStubNodeToTensor()
void ConvertStubNodeToTensor() const
描述:将存根节点转换为张量对象。
行为:确保张量从其存根表示中完全实现。转换完成后,存根节点被释放。
function tensor
构造常量张量的工厂方法,定义在tensor_utils.h头文件中。
Tensor tensor(int64_t value, TypeId dtype = TypeId::kNumberTypeInt64)
Tensor tensor(const std::vector<int64_t> &value, TypeId dtype = TypeId::kNumberTypeInt64)
Tensor tensor(double value, TypeId dtype = TypeId::kNumberTypeFloat64)
Tensor tensor(const std::vector<double> &value, TypeId dtype = TypeId::kNumberTypeFloat64)
描述:【API】根据给定的初始值创建一个张量。
参数:
value
:用于初始化张量的值,支持整型、浮点型、整型向量、浮点型向量。dtype
:张量的数据类型,对整数类型,默认值为ms::TypeId::kNumberTypeInt64
,对浮点数类型,默认值为ms::TypeId::kNumberTypeFloat64
。
返回值:一个包含指定值的张量。
function ones
构造全1张量的工厂方法,定义在tensor_utils.h头文件中。
Tensor ones(const ShapeVector &shape, TypeId dtype = TypeId::kNumberTypeFloat32)
描述:【API】创建一个形状为指定大小的张量,并将所有元素初始化为
1
。参数:
shape
:张量的形状,表示为一个整数向量。dtype
:张量的数据类型,默认为TypeId::kNumberTypeFloat32
。
返回值:一个所有元素都为
1
的张量。
function zeros
构造全0张量的工厂方法,定义在tensor_utils.h头文件中。
Tensor zeros(const ShapeVector &shape, TypeId dtype = TypeId::kNumberTypeFloat32)
描述:【API】创建一个形状为指定大小的张量,并将所有元素初始化为
0
。参数:
shape
:张量的形状,表示为一个整数向量。dtype
:张量的数据类型,默认为TypeId::kNumberTypeFloat32
。
返回值:一个所有元素都为
0
的张量。
namespace ms::pynative
class PyboostRunner
PyNative 流程的运行器类,定义在pyboost_extension.h头文件中,为管理执行、内存分配和内核启动提供方法。
PyboostRunner
是 std::enable_shared_from_this
的子类,需要使用智能指针 std::shared_ptr
管理其对象。
构造函数
PyboostRunner(const std::string &)
PyboostRunner(const std::string &op_name)
描述:【API】 构造一个
PyboostRunner
。参数:
op_name
:算子名。
静态公共方法
static Call(FuncType, Args &&…)
template <int OUT_NUM, typename FuncType, typename... Args> static py::object Call(FuncType func, Args &&... args)
描述:【API】 执行给定函数并将其输出转成Python对象。
模板参数:
OUT_NUM
:算子输出个数,需与func
返回的tensor列表长度一致。暂不支持可变输出个数的场景。FuncType
:算子入口函数原型,可通过函数入参自动识别。Args
:算子入参类型,可通过函数入参自动识别。传参顺序需与func
的参数顺序一致。
参数:
func
:要执行的函数。args
:函数执行所需的参数。
返回值:表示算子输出的 Python 对象。
公共方法
Run(const std::vector
&, const std::vector &) void Run(const std::vector<Tensor> &inputs, const std::vector<Tensor> &outputs)
描述:【API】 使用指定的输入和输出运行算子。
参数:
inputs
:输入张量列表。outputs
:输出张量列表。
CalcWorkspace()
virtual size_t CalcWorkspace()
描述:【API】 计算算子所需的工作区大小。
返回值:工作区大小(字节)。默认值为 0。
LaunchKernel()
virtual void LaunchKernel() = 0;
描述:【API】 启动算子的内核函数。
op_name()
const std::string &op_name() const
描述:【API】 获取与运行器关联的算子名称。
返回值:算子名称字符串。
inputs()
const std::vector<ms::Tensor> &inputs() const
描述:【API】 获取输入张量列表。
返回值:输入张量的引用。
outputs()
const std::vector<ms::Tensor> &outputs() const
描述:【API】 获取输出张量列表。
返回值:输出张量的引用。
stream_id()
uint32_t stream_id() const
描述:【API】 获取与运行器关联的流ID。
返回值:流ID。
stream()
void *stream()
描述:【API】 获取与运行器关联的流指针。
返回值:流指针。
workspace_ptr()
void *workspace_ptr()
描述:【API】 获取算子的工作区指针。
返回值:工作区内存的指针。
class AtbOpRunner
用于执行 Ascend Transformer Boost (ATB) 算子的运行器类,定义在atb_common.h头文件中。
此类继承自 PyboostRunner
,并封装了 ATB 算子的调用流程,包括初始化和运行 ATB 算子、管理输入输出 Tensor、内存分配及内核调度。
可以查看教程 CustomOpBuilder通过AtbOpRunner接入ATB算子 获取使用方法。
构造函数
AtbOpRunner
using PyboostRunner::PyboostRunner;
继承自
PyboostRunner
的构造函数。
公共方法
Init(const ParamType&)
template <typename ParamType> void Init(const ParamType ¶m)
描述: 【API】 使用给定参数初始化 ATB 算子。此方法通过
atb::CreateOperation
创建对应算子的atb::Operation
实例,并将其放入缓存中。对于param
哈希值相同的算子,只会创建一份atb::Operation
实例。参数
param
:用于配置 ATB 算子的参数。
注意: 对于传入的ParamType类型,需提前特例化
template <> struct HashOpParam<ParamType>::operator()
实例函数。
function RunAtbOp
动态图执行ATB算子的接口,定义在atb_common.h头文件中。
template <typename ParamType>
void RunAtbOp(const std::string &op_name, const ParamType ¶m, const std::vector<Tensor> &inputs,
const std::vector<Tensor> &outputs)
【API】 使用提供的参数、输入和输出执行一个 ATB 算子。此函数是对 AtbOpRunner
的一层封装。
参数
op_name
:要执行的 ATB 算子名称。param
:初始化 ATB 算子所需的参数。inputs
:算子的输入 Tensor 列表。outputs
:算子的输出 Tensor 列表。
class AsdSipFFTOpRunner
用于执行 Ascend Sip Boost (ASDSIP) 算子的运行器类,定义在asdsip_common.h头文件中。
此类继承自 PyboostRunner
,并封装了 ASDSIP FFT 算子的调用流程,包括初始化和运行 ASDSIP FFT 算子、管理输入输出 Tensor、内存分配及内核调度。
可以查看教程 CustomOpBuilder通过AsdSipFFTOpRunner接入ASDSIP FFT算子 获取使用方法。
构造函数
AsdSipFFTOpRunner
explicit AsdSipFFTOpRunner(std::string op_name) : PyboostRunner(op_name) {}
继承自
PyboostRunner
的构造函数。
公共方法
Init(const FFTParam ¶m);
void Init(const FFTParam ¶m);
描述: 【API】 使用给定参数初始化 ASDSIP FFT 算子。此方法通过
AsdFftCreate
创建对应算子的asdFftHandle
实例,并将其放入缓存中。对于param
相同的算子,只会创建一份asdFftHandle
实例。参数
param
:用于配置 ASDSIP FFT 算子的参数。
function RunAsdSipFFTOp
动态图执行ASDSIP FFT算子的接口,定义在asdsip_common.h头文件中。
inline void RunAsdSipFFTOp(const std::string &op_name, const FFTParam &fft_param, const ms::Tensor &input,
const ms::Tensor &output)
【API】 使用提供的参数、输入和输出执行一个 ASDSIP FFT 算子。此函数是对 AsdSipFFTOpRunner
的一层封装。
参数
op_name
:要执行的 ASDSIP FFT 算子名称。fft_param
:初始化 ASDSIP FFT 算子所需的参数。inputs
:算子的输入 Tensor。outputs
:算子的输出 Tensor。