defcumprod(data, axis=None, dtype=None, exclusive=None): """Numpy style cumprod op. Return the cumulative inclusive product of the elements along a given axis. Parameters ---------- data : relay.Expr The input data to the operator. axis : int, optional Axis along which the cumulative product is computed. The default (None) is to compute the cumprod over the flattened array. dtype : string, optional Type of the returned array and of the accumulator in which the elements are multiplied. If dtype is not specified, it defaults to the dtype of data. exclusive : bool, optional If true will return exclusive product in which the first element is not included. In other terms, if true, the j-th output element would be the product of the first (j-1) elements. Otherwise, it would be the product of the first j elements. The product of zero elements will be 1. Returns ------- result : relay.Expr The result has the same size as data, and the same shape as data if axis is not None. If axis is None, the result is a 1-d array. """
/*! \brief Attributes used in cumsum and cumprod operator */ structScanopAttrs : public tvm::AttrsNode<ScanopAttrs> { Integer axis; DataType dtype; Bool exclusive = Bool(false); TVM_DECLARE_ATTRS(ScanopAttrs, "relay.attrs.ScanopAttrs") { TVM_ATTR_FIELD(axis).describe("The axis to operate over").set_default(NullValue<Integer>()); TVM_ATTR_FIELD(dtype).describe("Output data type").set_default(NullValue<DataType>()); TVM_ATTR_FIELD(exclusive) .describe("The first element is not included") .set_default(Bool(false)); } };
但是如果是其他的算子,需要自己定义相应的属性节点。如BiasAdd就需要单独定义
1 2 3 4 5 6 7
structBiasAddAttrs : public tvm::AttrsNode<BiasAddAttrs> { int axis;
TVM_DECLARE_ATTRS(BiasAddAttrs, "relay.attrs.BiasAddAttrs") { TVM_ATTR_FIELD(axis).describe("The axis to add the bias").set_default(1); } };
TVM_REGISTER_NODE_TYPE(ScanopAttrs); boolScanopRel(const Array<Type>& types, int num_inputs, const Attrs& attrs, const TypeReporter& reporter){ // types: [data, output] ICHECK_EQ(types.size(), 2) << "Expects two types, one for the input and another for the output"; constauto* data = types[0].as<TensorTypeNode>(); //输入的tensor信息 if (data == nullptr) { ICHECK(types[0].as<IncompleteTypeNode>()) << "Scanop: expect input type to be TensorType but get " << types[0]; returnfalse; }
RELAY_REGISTER_OP("cumsum") .describe( R"doc(Return the cumulative sum of the elements along a given axis.)doc" TVM_ADD_FILELINE) .set_num_inputs(1) .add_argument("data", "Tensor", "The input tensor.") .set_support_level(3) .add_type_rel("Cumsum", ScanopRel) .set_attr<TOpPattern>("TOpPattern", kOpaque);
RELAY_REGISTER_OP("cumprod") .describe( R"doc(Return the cumulative product of the elements along a given axis.)doc" TVM_ADD_FILELINE) .set_num_inputs(1) .add_argument("data", "Tensor", "The input tensor.") .set_support_level(3) .add_type_rel("Cumprod", ScanopRel) .set_attr<TOpPattern>("TOpPattern", kOpaque);// 不融合
defconcat(*args): """Concatenate the input tensors along the zero axis. Parameters ---------- args: list of Tensor Returns ------- tensor: The concatenated tensor. """ tup = Tuple(list(args)) return _make.concat(tup)