/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * License); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* * Copyright (c) 2019, Open AI Lab * Author: jingyou@openailab.com */ #include #include "tm2_op_save.hpp" // #include "utility/log.h" // #include "tengine_ir.h" inline void SetTmOperator(TM2_Operator* tm_op, const uint32_t op_type, const tm_uoffset_t offset) { tm_op->op_ver = TM2_OP_VER; tm_op->operator_type = op_type; tm_op->offset_t_param = offset; } tm_uoffset_t SaveTmBatchNormOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct batchnorm_param* p = (struct batchnorm_param*)node->op.param_mem; TM2_BatchNormParam tm_param; tm_param.rescale_factor = p->rescale_factor; tm_param.eps = p->eps; tm_param.caffe_flavor = p->caffe_flavor; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_BATCHNORMALIZATION, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_BatchNormParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmConcatOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct concat_param* p = (struct concat_param*)node->op.param_mem; TM2_ConcatParam tm_param; tm_param.axis = p->axis; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_CONCAT, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_ConcatParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmConstOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_CONST, TM2_NOT_SET); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmConvOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct conv_param* p = (struct conv_param*)node->op.param_mem; TM2_ConvParam tm_param; tm_param.kernel_h = p->kernel_h; tm_param.kernel_w = p->kernel_w; tm_param.stride_h = p->stride_h; tm_param.stride_w = p->stride_w; tm_param.dilation_h = p->dilation_h; tm_param.dilation_w = p->dilation_w; tm_param.input_channel = p->input_channel; tm_param.output_channel = p->output_channel; tm_param.group = p->group; tm_param.activation = p->activation; tm_param.pad_h0 = p->pad_h0; tm_param.pad_h1 = p->pad_h1; tm_param.pad_w0 = p->pad_w0; tm_param.pad_w1 = p->pad_w1; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_CONVOLUTION, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_ConvParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmDeconvOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct deconv_param* p = (struct deconv_param*)node->op.param_mem; TM2_DeconvParam tm_param; tm_param.kernel_h = p->kernel_h; tm_param.kernel_w = p->kernel_w; tm_param.stride_h = p->stride_h; tm_param.stride_w = p->stride_w; tm_param.pad_w0 = p->pad_w0; tm_param.pad_w1 = p->pad_w1; tm_param.pad_h0 = p->pad_h0; tm_param.pad_h1 = p->pad_h1; tm_param.num_output = p->num_output; tm_param.dilation_h = p->dilation_h; tm_param.dilation_w = p->dilation_w; tm_param.group = p->group; tm_param.activation = p->activation; tm_param.output_pad_h0 = p->output_pad_h0; tm_param.output_pad_w0 = p->output_pad_w0; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_DECONVOLUTION, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_DeconvParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmDetectionOutputOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct detection_output_param* p = (struct detection_output_param*)node->op.param_mem; TM2_DetectionOutputParam tm_param; tm_param.num_classes = p->num_classes; tm_param.keep_top_k = p->keep_top_k; tm_param.nms_top_k = p->nms_top_k; tm_param.confidence_threshold = p->confidence_threshold; tm_param.nms_threshold = p->nms_threshold; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_DETECTIONOUTPUT, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_DetectionOutputParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmDropoutOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_DROPOUT, TM2_NOT_SET); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmMishOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_MISH, TM2_NOT_SET); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmEltwiseOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct eltwise_param* p = (struct eltwise_param*)node->op.param_mem; TM2_EltwiseParam tm_param; tm_param.type = p->type; tm_param.caffe_flavor = p->caffe_flavor; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_ELTWISE, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_EltwiseParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmFCOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct fc_param* p = (struct fc_param*)node->op.param_mem; TM2_FCParam tm_param; tm_param.num_output = p->num_output; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_FULLYCONNECTED, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_FCParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmFlattenOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct flatten_param* p = (struct flatten_param*)node->op.param_mem; TM2_FlattenParam tm_param; tm_param.axis = p->axis; tm_param.end_axis = p->end_axis; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_FLATTEN, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_FlattenParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmInputOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_INPUTOP, TM2_NOT_SET); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmLRNOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct lrn_param* p = (struct lrn_param*)node->op.param_mem; TM2_LRNParam tm_param; tm_param.local_size = p->local_size; tm_param.alpha = p->alpha; tm_param.beta = p->beta; tm_param.norm_region = p->norm_region; tm_param.k = p->k; // tm_param.is_onnx = p->is_onnx; tm_param.is_onnx = 0; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_LRN, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_LRNParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmNormalizeOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct normalize_param* p = (struct normalize_param*)node->op.param_mem; TM2_NormalizeParam tm_param; tm_param.across_spatial = p->across_spatial; tm_param.channel_shared = p->channel_shared; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_NORMALIZE, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_NormalizeParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmPermuteOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct permute_param* p = (struct permute_param*)node->op.param_mem; TM2_PermuteParam tm_param; tm_param.flag = p->flag; tm_param.order0 = p->order0; tm_param.order1 = p->order1; tm_param.order2 = p->order2; tm_param.order3 = p->order3; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_PERMUTE, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_PermuteParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmPoolingOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct pool_param* p = (struct pool_param*)node->op.param_mem; TM2_PoolParam tm_param; // tm_param.alg = p->alg; tm_param.alg = p->pool_method; tm_param.kernel_h = p->kernel_h; tm_param.kernel_w = p->kernel_w; tm_param.stride_h = p->stride_h; tm_param.stride_w = p->stride_w; tm_param.global = p->global; tm_param.caffe_flavor = p->caffe_flavor; tm_param.pad_h0 = p->pad_h0; tm_param.pad_w0 = p->pad_w0; tm_param.pad_h1 = p->pad_h1; tm_param.pad_w1 = p->pad_w1; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_POOLING, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_PoolParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmPreluOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_PRELU, TM2_NOT_SET); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmPriorBoxOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct priorbox_param* p = (struct priorbox_param*)node->op.param_mem; TM2_PriorBoxParam tm_param; size_t vector_size = sizeof(tm_size_t) + sizeof(float) * p->min_size_num; TM2_Vector_floats* v_minsizes = (TM2_Vector_floats*)malloc(vector_size); v_minsizes->v_num = p->min_size_num; for (unsigned int i = 0; i < p->min_size_num; i++) { v_minsizes->data[i] = p->min_size[i]; } tm_param.offset_vf_min_size = WriteTmObject(start_ptr, cur_pos, v_minsizes, vector_size); free(v_minsizes); vector_size = sizeof(tm_size_t) + sizeof(float) * p->max_size_num; TM2_Vector_floats* v_maxsizes = (TM2_Vector_floats*)malloc(vector_size); v_maxsizes->v_num = p->max_size_num; for (unsigned int i = 0; i < p->max_size_num; i++) { v_maxsizes->data[i] = p->max_size[i]; } tm_param.offset_vf_max_size = WriteTmObject(start_ptr, cur_pos, v_maxsizes, vector_size); free(v_maxsizes); int variance_num = 4; // tengine lite does not set the variable. vector_size = sizeof(tm_size_t) + sizeof(float) * variance_num; TM2_Vector_floats* v_variance = (TM2_Vector_floats*)malloc(vector_size); v_variance->v_num = variance_num; for (unsigned int i = 0; i < variance_num; i++) { v_variance->data[i] = p->variance[i]; } tm_param.offset_vf_variance = WriteTmObject(start_ptr, cur_pos, v_variance, vector_size); free(v_variance); vector_size = sizeof(tm_size_t) + sizeof(float) * p->aspect_ratio_size; TM2_Vector_floats* v_ratios = (TM2_Vector_floats*)malloc(vector_size); v_ratios->v_num = p->aspect_ratio_size; for (unsigned int i = 0; i < p->aspect_ratio_size; i++) { v_ratios->data[i] = p->aspect_ratio[i]; } tm_param.offset_vf_aspect_ratio = WriteTmObject(start_ptr, cur_pos, v_ratios, vector_size); free(v_ratios); tm_param.flip = p->flip; tm_param.clip = p->clip; tm_param.img_size = p->image_size; tm_param.img_h = p->image_h; tm_param.img_w = p->image_w; tm_param.step_w = p->step_w; tm_param.step_h = p->step_h; tm_param.offset = p->offset; tm_param.num_priors = p->num_priors; tm_param.out_dim = p->out_dim; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_PRIORBOX, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_PriorBoxParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmRegionOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct region_param* p = (struct region_param*)node->op.param_mem; TM2_RegionParam tm_param; tm_param.num_classes = p->num_classes; tm_param.side = p->side; tm_param.num_box = p->num_box; tm_param.coords = p->coords; tm_param.confidence_threshold = p->confidence_threshold; tm_param.nms_threshold = p->nms_threshold; size_t vector_size = sizeof(tm_size_t) + sizeof(float) * p->biases_num; TM2_Vector_floats* v_biases = (TM2_Vector_floats*)malloc(vector_size); v_biases->v_num = p->biases_num; for (unsigned int i = 0; i < p->biases_num; i++) { v_biases->data[i] = p->biases[i]; } tm_param.offset_vf_biases = WriteTmObject(start_ptr, cur_pos, v_biases, vector_size); free(v_biases); TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_REGION, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_RegionParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmReLuOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct relu_param* p = (struct relu_param*)node->op.param_mem; TM2_ReLuParam tm_param; tm_param.negative_slope = p->negative_slope; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_RELU, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_ReLuParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmRelu6Op(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_RELU6, TM2_NOT_SET); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmReorgOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct reorg_param* p = (struct reorg_param*)node->op.param_mem; TM2_ReorgParam tm_param; tm_param.stride = p->stride; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_REORG, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_ReorgParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmReshapeOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct reshape_param* p = (struct reshape_param*)node->op.param_mem; TM2_ReshapeParam tm_param; if (p->reverse) tm_param.reverse = 1; else tm_param.reverse = 0; if (p->is_mxnet) tm_param.is_mxnet = 1; else tm_param.is_mxnet = 0; if (p->is_onnx) tm_param.is_onnx = 1; else tm_param.is_onnx = 0; if (p->dim_size) { size_t vector_size = sizeof(tm_size_t) + sizeof(int32_t) * p->dim_size; TM2_Vector_dims* v_re_shape = (TM2_Vector_dims*)malloc(vector_size); v_re_shape->v_num = p->dim_size; for (unsigned int i = 0; i < p->dim_size; i++) { v_re_shape->dims[i] = p->re_shape[i]; } tm_param.offset_re_shape = WriteTmObject(start_ptr, cur_pos, v_re_shape, vector_size); free(v_re_shape); } else { tm_param.offset_re_shape = TM2_NOT_SET; } TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_RESHAPE, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_ReshapeParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmResizeOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct resize_param* p = (struct resize_param*)node->op.param_mem; TM2_ResizeParam tm_param; tm_param.scale_x = p->scale_w; tm_param.scale_y = p->scale_h; tm_param.type = p->type; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_RESIZE, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_ResizeParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmROIPoolingOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct roipooling_param* p = (struct roipooling_param*)node->op.param_mem; TM2_ROIPoolingParam tm_param; tm_param.pooled_h = p->pooled_h; tm_param.pooled_w = p->pooled_w; tm_param.spatial_scale = p->spatial_scale; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_ROIPOOLING, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_ROIPoolingParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmRPNOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct rpn_param* p = (struct rpn_param*)node->op.param_mem; TM2_RPNParam tm_param; size_t vector_size = sizeof(tm_size_t) + sizeof(float) * p->ratios->elem_num; TM2_Vector_floats* v_ratios = (TM2_Vector_floats*)malloc(vector_size); v_ratios->v_num = p->ratios->elem_num; for (unsigned int i = 0; i < p->ratios->elem_num; i++) { v_ratios->data[i] = *(float*)get_vector_data(p->ratios, i); } tm_param.offset_vf_ratios = WriteTmObject(start_ptr, cur_pos, v_ratios, vector_size); free(v_ratios); vector_size = sizeof(tm_size_t) + sizeof(float) * p->anchor_scales->elem_num; TM2_Vector_floats* v_scales = (TM2_Vector_floats*)malloc(vector_size); v_scales->v_num = p->anchor_scales->elem_num; for (unsigned int i = 0; i < p->anchor_scales->elem_num; i++) { v_scales->data[i] = *(float*)get_vector_data(p->anchor_scales, i); } tm_param.offset_vf_anchor_scales = WriteTmObject(start_ptr, cur_pos, v_scales, vector_size); free(v_scales); vector_size = sizeof(tm_size_t) + sizeof(float) * p->anchors_->elem_num * 4; TM2_Vector_anchors* v_anchors = (TM2_Vector_anchors*)malloc(vector_size); v_anchors->v_num = p->anchors_->elem_num; for (unsigned int i = 0; i < p->anchors_->elem_num; i++) { v_anchors->data[i][0] = ((Anchor_t*)get_vector_data(p->anchors_, i))->x0; v_anchors->data[i][1] = ((Anchor_t*)get_vector_data(p->anchors_, i))->y0; v_anchors->data[i][2] = ((Anchor_t*)get_vector_data(p->anchors_, i))->x1; v_anchors->data[i][3] = ((Anchor_t*)get_vector_data(p->anchors_, i))->y1; } tm_param.offset_va_anchors = WriteTmObject(start_ptr, cur_pos, v_anchors, vector_size); free(v_anchors); tm_param.feat_stride = p->feat_stride; tm_param.basesize = p->basesize; tm_param.min_size = p->min_size; tm_param.per_nms_topn = p->per_nms_topn; tm_param.post_nms_topn = p->post_nms_topn; tm_param.nms_thresh = p->nms_thresh; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_RPN, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_RPNParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmScaleOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct scale_param* p = (struct scale_param*)node->op.param_mem; TM2_ScaleParam tm_param; tm_param.axis = p->axis; tm_param.num_axes = p->num_axes; tm_param.bias_term = p->bias_term; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_SCALE, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_ScaleParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmSliceOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct slice_param* p = (struct slice_param*)node->op.param_mem; TM2_SliceParam tm_param; tm_param.axis = p->axis; tm_param.begin = p->begin; tm_param.end = p->end; tm_param.step = p->step; tm_param.iscaffe = p->iscaffe; tm_param.isonnx = p->isonnx; tm_param.ismxnet = p->ismxnet; if (p->slice_point_ && p->slice_point_->elem_num) { size_t vector_size = sizeof(tm_size_t) + sizeof(int32_t) * p->slice_point_->elem_num; TM2_Vector_dims* v_slice_points = (TM2_Vector_dims*)malloc(vector_size); v_slice_points->v_num = p->slice_point_->elem_num; for (unsigned int i = 0; i < p->slice_point_->elem_num; i++) { v_slice_points->dims[i] = *(int32_t*)get_vector_data(p->slice_point_, i); } tm_param.offset_vi_slice_points = WriteTmObject(start_ptr, cur_pos, v_slice_points, vector_size); free(v_slice_points); } else tm_param.offset_vi_slice_points = TM2_NOT_SET; if (p->begin_ && p->begin_->elem_num) { size_t vector_size = sizeof(tm_size_t) + sizeof(int32_t) * p->begin_->elem_num; TM2_Vector_dims* v_begins = (TM2_Vector_dims*)malloc(vector_size); v_begins->v_num = p->begin_->elem_num; for (unsigned int i = 0; i < p->begin_->elem_num; i++) { v_begins->dims[i] = *(int32_t*)get_vector_data(p->begin_, i); } tm_param.offset_vi_begins = WriteTmObject(start_ptr, cur_pos, v_begins, vector_size); free(v_begins); } else tm_param.offset_vi_begins = TM2_NOT_SET; if (p->size_ && p->size_->elem_num) { size_t vector_size = sizeof(tm_size_t) + sizeof(int32_t) * p->size_->elem_num; TM2_Vector_dims* v_sizes = (TM2_Vector_dims*)malloc(vector_size); v_sizes->v_num = p->size_->elem_num; for (unsigned int i = 0; i < p->size_->elem_num; i++) { v_sizes->dims[i] = *(int32_t*)get_vector_data(p->size_, i); } tm_param.offset_vi_sizes = WriteTmObject(start_ptr, cur_pos, v_sizes, vector_size); free(v_sizes); } else tm_param.offset_vi_sizes = TM2_NOT_SET; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_SLICE, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_SliceParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmSoftmaxOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct softmax_param* p = (struct softmax_param*)node->op.param_mem; TM2_SoftmaxParam tm_param; tm_param.axis = p->axis; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_SOFTMAX, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_SoftmaxParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmSplitOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct split_param* p = (struct split_param*)node->op.param_mem; TM2_SplitParam tm_param; if (p->is_caffe) tm_param.is_caffe = 1; else tm_param.is_caffe = 0; if (p->is_onnx) { tm_param.is_onnx = 1; } else { tm_param.is_onnx = 0; } if (!p->is_caffe) { if (p->is_onnx) tm_param.axis = p->axis; size_t vector_size = sizeof(tm_size_t) + sizeof(int32_t) * p->split_sizes_->elem_num; TM2_Vector_dims* v_split_sizes = (TM2_Vector_dims*)malloc(vector_size); v_split_sizes->v_num = p->split_sizes_->elem_num; for (unsigned int i = 0; i < p->split_sizes_->elem_num; i++) { v_split_sizes->dims[i] = *(int32_t*)get_vector_data(p->split_sizes_, i); } tm_param.offset_split_sizes = WriteTmObject(start_ptr, cur_pos, v_split_sizes, vector_size); free(v_split_sizes); tm_param.split_dim = p->split_dim; } TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_SPLIT, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_SplitParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmDetectionPostProcessOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct detection_postprocess_param* p = (struct detection_postprocess_param*)node->op.param_mem; TM2_DetectionPostProcessParam tm_param; tm_param.max_detections = p->max_detections; tm_param.max_classes_per_detection = p->max_classes_per_detection; tm_param.nms_score_threshold = p->nms_score_threshold; tm_param.nms_iou_threshold = p->nms_iou_threshold; tm_param.num_classes = p->num_classes; int param_scales_num = 4; size_t vector_size = sizeof(tm_size_t) + sizeof(float) * param_scales_num; TM2_Vector_floats* v_scales = (TM2_Vector_floats*)malloc(vector_size); v_scales->v_num = param_scales_num; for (unsigned int i = 0; i < param_scales_num; i++) { v_scales->data[i] = p->scales[i]; } tm_param.offset_vf_scales = WriteTmObject(start_ptr, cur_pos, v_scales, vector_size); TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_DETECTIONPOSTPROCESS, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_DetectionPostProcessParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmGemmOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct gemm_param* p = (struct gemm_param*)node->op.param_mem; TM2_GemmParam tm_param; tm_param.alpha = p->alpha; tm_param.beta = p->beta; tm_param.transA = p->transA; tm_param.transB = p->transB; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_GEMM, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_GemmParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmLogisticOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_LOGISTIC, TM2_NOT_SET); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmLstmOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct lstm_param* p = (struct lstm_param*)node->op.param_mem; TM2_LstmParam tm_param; tm_param.forget_bias = p->forget_bias; tm_param.clip = p->clip; tm_param.output_len = p->output_len; tm_param.sequence_len = p->sequence_len; tm_param.input_size = p->input_size; tm_param.hidden_size = p->hidden_size; tm_param.cell_size = p->cell_size; tm_param.has_peephole = p->has_peephole; tm_param.has_projection = p->has_projection; tm_param.has_clip = p->has_clip; tm_param.has_bias = p->has_bias; tm_param.has_init_state = p->has_init_state; tm_param.forget_act = p->forget_act; tm_param.input_act = p->input_act; tm_param.output_act = p->output_act; tm_param.cellin_act = p->cellin_act; tm_param.cellout_act = p->cellout_act; tm_param.mxnet_flag = p->mxnet_flag; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_LSTM, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_LstmParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmRnnOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct rnn_param* p = (struct rnn_param*)node->op.param_mem; TM2_RnnParam tm_param; tm_param.clip = p->clip; tm_param.output_len = p->output_len; tm_param.sequence_len = p->sequence_len; tm_param.input_size = p->input_size; tm_param.hidden_size = p->hidden_size; tm_param.has_clip = p->has_clip; tm_param.has_bias = p->has_bias; tm_param.has_init_state = p->has_init_state; tm_param.activation = p->activation; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_RNN, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_RnnParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmTanhOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_TANH, TM2_NOT_SET); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmSigmoidOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_SIGMOID, TM2_NOT_SET); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmMaximumOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_MAX, TM2_NOT_SET); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmMinimumOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_MIN, TM2_NOT_SET); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmSqueezeOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct squeeze_param* p = (struct squeeze_param*)node->op.param_mem; TM2_SqueezeParam tm_param; tm_param.dim_0 = p->dim_0; tm_param.dim_1 = p->dim_1; tm_param.dim_2 = p->dim_2; tm_param.dim_3 = p->dim_3; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_SQUEEZE, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_SqueezeParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmArgMaxOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct argmax_param* p = (struct argmax_param*)node->op.param_mem; TM2_ArgMaxParam tm_param; tm_param.axis = p->axis; tm_param.keepdims = p->keepdims; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_ARGMAX, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_ArgMaxParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmArgMinOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct argmin_param* p = (struct argmin_param*)node->op.param_mem; TM2_ArgMinParam tm_param; tm_param.axis = p->axis; tm_param.keepdims = p->keepdims; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_ARGMIN, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_ArgMinParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmTopKV2Op(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct topkv2_param* p = (struct topkv2_param*)node->op.param_mem; TM2_TopKV2Param tm_param; tm_param.k = p->k; if (p->sorted) tm_param.sorted = 1; else tm_param.sorted = 0; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_TOPKV2, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_TopKV2Param))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmStridedSliceOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct strided_slice_param* p = (struct strided_slice_param*)node->op.param_mem; TM2_StridedSliceParam tm_param; tm_param.begin_n = p->begin[0]; tm_param.begin_c = p->begin[1]; tm_param.begin_h = p->begin[2]; tm_param.begin_w = p->begin[3]; tm_param.end_n = p->end[0]; tm_param.end_c = p->end[1]; tm_param.end_h = p->end[2]; tm_param.end_w = p->end[3]; tm_param.stride_n = p->stride[0]; tm_param.stride_c = p->stride[1]; tm_param.stride_h = p->stride[2]; tm_param.stride_w = p->stride[3]; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_STRIDEDSLICE, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_StridedSliceParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmPadOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct pad_param* p = (struct pad_param*)node->op.param_mem; TM2_PadParam tm_param; tm_param.mode = p->mode; tm_param.value = p->value; tm_param.pad_n_0 = p->pad_0_h; tm_param.pad_n_1 = p->pad_0_w; tm_param.pad_c_0 = p->pad_1_h; tm_param.pad_c_1 = p->pad_1_w; tm_param.pad_h_0 = p->pad_2_h; tm_param.pad_h_1 = p->pad_2_w; tm_param.pad_w_0 = p->pad_3_h; tm_param.pad_w_1 = p->pad_3_w; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_PAD, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_PadParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmReductionOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct reduction_param* p = (struct reduction_param*)node->op.param_mem; TM2_ReductionParam tm_param; tm_param.dim_0 = p->dim_0; tm_param.dim_1 = p->dim_1; tm_param.dim_2 = p->dim_2; tm_param.dim_3 = p->dim_3; tm_param.keepdim = p->keepdim; tm_param.type = p->type; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_REDUCTION, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_ReductionParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmSwapAxisOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct swap_axis_param* p = (struct swap_axis_param*)node->op.param_mem; TM2_SwapAxisParam tm_param; tm_param.dim_0 = p->dim_0; tm_param.dim_1 = p->dim_1; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_SWAPAXIS, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_SwapAxisParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmGruOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct gru_param* p = (struct gru_param*)node->op.param_mem; TM2_GRUParam tm_param; tm_param.clip = p->clip; tm_param.output_len = p->output_len; tm_param.sequence_len = p->sequence_len; tm_param.input_size = p->input_size; tm_param.hidden_size = p->hidden_size; tm_param.has_clip = p->has_clip; tm_param.has_gate_bias = p->has_gate_bias; tm_param.has_candidate_bias = p->has_candidate_bias; tm_param.has_init_state = p->has_init_state; tm_param.mxnet_flag = p->mxnet_flag; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_GRU, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_GRUParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmUpsampleOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct upsample_param* p = (struct upsample_param*)node->op.param_mem; TM2_UpsampleParam tm_param; tm_param.scale = p->scale; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_UPSAMPLE, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_UpsampleParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmShuffleChannelOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct shuffle_channel_param* p = (struct shuffle_channel_param*)node->op.param_mem; TM2_ShuffleChannelParam tm_param; tm_param.group = p->group; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_SHUFFLECHANNEL, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_ShuffleChannelParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmSpaceToBatchNDOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct spacetobatchnd_param* p = (struct spacetobatchnd_param*)node->op.param_mem; TM2_SpaceToBatchNDParam tm_param; tm_param.dilation_x = p->dilation_x; tm_param.dilation_y = p->dilation_y; tm_param.pad_top = p->pad_top; tm_param.pad_bottom = p->pad_bottom; tm_param.pad_left = p->pad_left; tm_param.pad_right = p->pad_right; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_SPACETOBATCHND, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_SpaceToBatchNDParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmBatchToSpaceNDOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct batchtospacend_param* p = (struct batchtospacend_param*)node->op.param_mem; TM2_BatchToSpaceNDParam tm_param; tm_param.dilation_x = p->dilation_x; tm_param.dilation_y = p->dilation_y; tm_param.crop_top = p->crop_top; tm_param.crop_bottom = p->crop_bottom; tm_param.crop_left = p->crop_left; tm_param.crop_right = p->crop_right; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_BATCHTOSPACEND, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_BatchToSpaceNDParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmCropOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct crop_param* p = (struct crop_param*)node->op.param_mem; TM2_CropParam tm_param; tm_param.axis = p->axis; tm_param.center_crop = p->center_crop; tm_param.crop_h = p->crop_h; tm_param.crop_w = p->crop_w; tm_param.num_args = p->num_args; tm_param.offset_c = p->offset_c; tm_param.offset_h = p->offset_h; tm_param.offset_w = p->offset_w; tm_param.flag = p->flag; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_CROP, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_CropParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmUnaryOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct unary_param* p = (struct unary_param*)node->op.param_mem; TM2_UnaryParam tm_param; tm_param.type = p->type; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_UNARY, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_UnaryParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmPsroipoolingOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct psroipooling_param* p = (struct psroipooling_param*)node->op.param_mem; TM2_PsroipoolingParam tm_param; tm_param.spatial_scale = p->spatial_scale; tm_param.pooled_w = p->pooled_w; tm_param.pooled_h = p->pooled_h; tm_param.output_dim = p->output_dim; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_PSROIPOOLING, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_PsroipoolingParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmExpanddimsOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct expanddims_param* p = (struct expanddims_param*)node->op.param_mem; TM2_ExpanddimsParam tm_param; tm_param.axis = p->axis; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_EXPANDDIMS, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_ExpanddimsParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmRoialignOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct roialign_param* p = (struct roialign_param*)node->op.param_mem; TM2_RoialignParam tm_param; tm_param.spatial_scale = p->spatial_scale; tm_param.pooled_width = p->pooled_width; tm_param.pooled_height = p->pooled_height; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_ROIALIGN, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_RoialignParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmThresholdOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct threshold_param* p = (struct threshold_param*)node->op.param_mem; TM2_ThresholdParam tm_param; tm_param.threshold = p->threshold; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_THRESHOLD, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_ThresholdParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmNoopOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_NOOP, TM2_NOT_SET); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmEmbedOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct embedding_param* p = (struct embedding_param*)node->op.param_mem; TM2_EmbedParam tm_param; //tm_param.bias_term = p->bias_term; tm_param.input_dim = p->input_dim; tm_param.num_output = p->num_output; tm_param.weight_data_size = p->weight_data_size; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_EMBED, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_EmbedParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmHardsigmoidOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct hard_sigmoid_param* p = (struct hard_sigmoid_param*)node->op.param_mem; TM2_HardsigmoidParam tm_param; tm_param.alpha = p->alpha; tm_param.beta = p->beta; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_HARDSIGMOID, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_HardsigmoidParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmInstanceNormOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct instancenorm_Param* p = (struct instancenorm_Param*)node->op.param_mem; TM2_InstanceNormParam tm_param; tm_param.eps = p->eps; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_INSTANCENORM, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_InstanceNormParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmMVNOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct mvn_param* p = (struct mvn_param*)node->op.param_mem; TM2_MVNParam tm_param; tm_param.across_channels = p->across_channels; tm_param.eps = p->eps; tm_param.normalize_variance = p->normalize_variance; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_MVN, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_MVNParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmCastOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct cast_param* p = (struct cast_param*)node->op.param_mem; TM2_CastParam tm_param; tm_param.type_from = p->type_from; tm_param.type_to = p->type_to; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_CAST, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_CastParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmHardSwishOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct hardswish_param* p = (struct hardswish_param*)node->op.param_mem; TM2_HardSwishParam tm_param; tm_param.alpha = p->alpha; tm_param.beta = p->beta; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_HARDSWISH, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_HardSwishParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmInterpOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct interp_param* p = (struct interp_param*)node->op.param_mem; TM2_InterpParam tm_param; tm_param.height_scale = p->height_scale; tm_param.output_height = p->output_height; tm_param.output_width = p->output_width; tm_param.resize_type = p->resize_type; tm_param.width_scale = p->width_scale; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_INTERP, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_InterpParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmSeluOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct selu_param* p = (struct selu_param*)node->op.param_mem; TM2_SeluParam tm_param; tm_param.alpha = p->alpha; tm_param.lambda = p->lambda; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_SELU, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_SeluParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmEluOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct elu_param* p = (struct elu_param*)node->op.param_mem; TM2_EluParam tm_param; tm_param.alpha = p->alpha; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_ELU, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_EluParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmBroadMulOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_BROADMUL, TM2_NOT_SET); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmLogicalOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct logical_param* p = (struct logical_param*)node->op.param_mem; TM2_LogicalParam tm_param; tm_param.type = p->type; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_LOGICAL, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_LogicalParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmGatherOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct gather_param* p = (struct gather_param*)node->op.param_mem; TM2_GatherParam tm_param; tm_param.axis = p->axis; tm_param.indices_num = p->indices_num; tm_param.is_onnx = p->is_onnx; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_GATHER, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_GatherParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmTransposeOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct transpose_param* p = (struct transpose_param*)node->op.param_mem; TM2_TransposeParam tm_param; if (p->tr_shape_size) { size_t vector_size = sizeof(tm_size_t) + sizeof(int32_t) * p->tr_shape_size; TM2_Vector_dims* v_re_shape = (TM2_Vector_dims*)malloc(vector_size); v_re_shape->v_num = p->tr_shape_size; for (unsigned int i = 0; i < p->tr_shape_size; i++) { v_re_shape->dims[i] = p->tr_shape[i]; } tm_param.offset_tr_shape = WriteTmObject(start_ptr, cur_pos, v_re_shape, vector_size); free(v_re_shape); } else { tm_param.offset_tr_shape = TM2_NOT_SET; } TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_TRANSPOSE, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_TransposeParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmComparisonOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct comparison_param* p = (struct comparison_param*)node->op.param_mem; TM2_ComparisonParam tm_param; tm_param.type = p->type; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_COMPARISON, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_ComparisonParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmReverseOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_REVERSE, TM2_NOT_SET); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmSpaceToDepthOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct spacetodepth_param* p = (struct spacetodepth_param*)node->op.param_mem; TM2_SpaceToDepthParam tm_param; tm_param.block_size = p->block_size; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_SPACETODEPTH, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_SpaceToDepthParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmDepthToSpaceOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct depthtospace_param* p = (struct depthtospace_param*)node->op.param_mem; TM2_DepthToSpaceParam tm_param; tm_param.block_size = p->block_size; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_DEPTHTOSPACE, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_DepthToSpaceParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmSquaredDifferenceOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_SQUAREDDIFFERENCE, TM2_NOT_SET); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmSparseToDenseOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct sparsetodense_param* p = (struct sparsetodense_param*)node->op.param_mem; TM2_SparseToDenseParam tm_param; tm_param.output_shape_size0 = p->output_shape_size0; tm_param.output_shape_size1 = p->output_shape_size1; tm_param.default_value = p->default_value; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_SPARSETODENSE, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_SparseToDenseParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmCeilOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_CEIL, TM2_NOT_SET); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmRoundOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_ROUND, TM2_NOT_SET); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmZerosLikeOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_ZEROSLIKE, TM2_NOT_SET); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmClipOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct clip_param* p = (struct clip_param*)node->op.param_mem; TM2_ClipParam tm_param; tm_param.max = p->max; tm_param.min = p->min; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_CLIP, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_ClipParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmUnsqueezeOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct unsqueeze_param* p = (struct unsqueeze_param*)node->op.param_mem; TM2_UnsqueezeParam tm_param; if (p->axises_size) { size_t vector_size = sizeof(tm_size_t) + sizeof(int32_t) * p->axises_size; TM2_Vector_dims* v_axises = (TM2_Vector_dims*)malloc(vector_size); v_axises->v_num = p->axises_size; for (unsigned int i = 0; i < p->axises_size; i++) { v_axises->dims[i] = p->axises[i]; } tm_param.offset_vi_axises = WriteTmObject(start_ptr, cur_pos, v_axises, vector_size); free(v_axises); } else tm_param.offset_vi_axises = TM2_NOT_SET; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_UNSQUEEZE, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_UnsqueezeParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmReduceL2Op(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct reducel2_param* p = (struct reducel2_param*)node->op.param_mem; TM2_ReduceL2Param tm_param; tm_param.axis = p->axis; tm_param.keepdim = p->keepdim; TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_REDUCEL2, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_ReduceL2Param))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmMeanOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_MEAN, TM2_NOT_SET); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmMatMulOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_MATMUL, TM2_NOT_SET); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmExpandOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct expand_param* p = (struct expand_param*)node->op.param_mem; TM2_ExpandParam tm_param; memset(&tm_param, 0, sizeof(TM2_ExpandParam)); if (p->dim_num) { size_t vector_size = sizeof(tm_size_t) + sizeof(int32_t) * p->dim_num; TM2_Vector_dims* v_axises = (TM2_Vector_dims*)malloc(vector_size); v_axises->v_num = p->dim_num; for (unsigned int i = 0; i < p->dim_num; i++) { v_axises->dims[i] = p->ex_shape[i]; } tm_param.offset_ex_shape = WriteTmObject(start_ptr, cur_pos, v_axises, vector_size); free(v_axises); } else tm_param.offset_ex_shape = TM2_NOT_SET; tm_param.dim_num = p->dim_num; TM2_Operator tm_op; memset(&tm_op, 0, sizeof(TM2_Operator)); SetTmOperator(&tm_op, TM2_OPTYPE_EXPAND, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_ExpandParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmSpatialTransformerOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { struct spatialtransformer_param* p = (struct spatialtransformer_param*)node->op.param_mem; TM2_SpatialTransformerParam tm_param; memset(&tm_param, 0, sizeof(TM2_SpatialTransformerParam)); tm_param.sampler_type = p->sampler_type; tm_param.transformer_type = p->transformer_type; tm_param.shape_size = sizeof(p->target_shape) / sizeof(p->target_shape[0]); if (tm_param.shape_size) { size_t vector_size = sizeof(tm_size_t) + sizeof(int32_t) * tm_param.shape_size; TM2_Vector_dims* v_ta_shape = (TM2_Vector_dims*)malloc(vector_size); v_ta_shape->v_num = tm_param.shape_size; for (unsigned int i = 0; i < tm_param.shape_size; i++) { v_ta_shape->dims[i] = p->target_shape[i]; } tm_param.offset_ta_shape = WriteTmObject(start_ptr, cur_pos, v_ta_shape, vector_size); free(v_ta_shape); } else { tm_param.offset_ta_shape = TM2_NOT_SET; } TM2_Operator tm_op; memset(&tm_op, 0, sizeof(TM2_Operator)); SetTmOperator(&tm_op, TM2_OPTYPE_SPATIALTRANSFORMER, WriteTmObject(start_ptr, cur_pos, &tm_param, sizeof(TM2_SpatialTransformerParam))); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmSoftplusOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_SOFTPLUS, TM2_NOT_SET); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } tm_uoffset_t SaveTmReciprocalOp(void* const start_ptr, tm_uoffset_t* cur_pos, ir_node_t* node) { TM2_Operator tm_op; SetTmOperator(&tm_op, TM2_OPTYPE_RECIPROCAL, TM2_NOT_SET); return WriteTmObject(start_ptr, cur_pos, &tm_op, sizeof(TM2_Operator)); } op_save_t SaveTmOpFunc(uint32_t op_type) { switch (op_type) { case OP_BATCHNORM: return SaveTmBatchNormOp; case OP_CONCAT: return SaveTmConcatOp; case OP_CONST: return SaveTmConstOp; case OP_CONV: return SaveTmConvOp; case OP_DECONV: return SaveTmDeconvOp; case OP_DETECTION_OUTPUT: return SaveTmDetectionOutputOp; case OP_DROPOUT: return SaveTmDropoutOp; case OP_ELTWISE: return SaveTmEltwiseOp; case OP_FLATTEN: return SaveTmFlattenOp; case OP_FC: return SaveTmFCOp; case OP_INPUT: return SaveTmInputOp; case OP_LRN: return SaveTmLRNOp; case OP_NORMALIZE: return SaveTmNormalizeOp; case OP_PERMUTE: return SaveTmPermuteOp; case OP_POOL: return SaveTmPoolingOp; case OP_PRELU: return SaveTmPreluOp; case OP_PRIORBOX: return SaveTmPriorBoxOp; case OP_REGION: return SaveTmRegionOp; case OP_RELU: return SaveTmReLuOp; case OP_RELU6: return SaveTmRelu6Op; case OP_REORG: return SaveTmReorgOp; case OP_RESHAPE: return SaveTmReshapeOp; case OP_ROIPOOLING: return SaveTmROIPoolingOp; case OP_RPN: return SaveTmRPNOp; case OP_SCALE: return SaveTmScaleOp; case OP_SLICE: return SaveTmSliceOp; case OP_SOFTMAX: return SaveTmSoftmaxOp; case OP_SPLIT: return SaveTmSplitOp; case OP_DETECTION_POSTPROCESS: return SaveTmDetectionPostProcessOp; case OP_GEMM: return SaveTmGemmOp; case OP_LOGISTIC: return SaveTmLogisticOp; case OP_LSTM: return SaveTmLstmOp; case OP_RNN: return SaveTmRnnOp; case OP_TANH: return SaveTmTanhOp; case OP_SIGMOID: return SaveTmSigmoidOp; case OP_SQUEEZE: return SaveTmSqueezeOp; case OP_SWAP_AXIS: return SaveTmSwapAxisOp; case OP_GRU: return SaveTmGruOp; case OP_ARGMAX: return SaveTmArgMaxOp; case OP_ARGMIN: return SaveTmArgMinOp; case OP_TOPKV2: return SaveTmTopKV2Op; case OP_PAD: return SaveTmPadOp; case OP_STRIDED_SLICE: return SaveTmStridedSliceOp; case OP_REDUCTION: return SaveTmReductionOp; case OP_UPSAMPLE: return SaveTmUpsampleOp; case OP_SHUFFLECHANNEL: return SaveTmShuffleChannelOp; case OP_SPACETOBATCHND: return SaveTmSpaceToBatchNDOp; case OP_BATCHTOSPACEND: return SaveTmBatchToSpaceNDOp; case OP_RESIZE: return SaveTmResizeOp; case OP_CROP: return SaveTmCropOp; case OP_ROIALIGN: return SaveTmRoialignOp; case OP_PSROIPOOLING: return SaveTmPsroipoolingOp; case OP_EXPANDDIMS: return SaveTmExpanddimsOp; case OP_UNARY: return SaveTmUnaryOp; case OP_NOOP: return SaveTmNoopOp; case OP_THRESHOLD: return SaveTmThresholdOp; case OP_HARDSIGMOID: return SaveTmHardsigmoidOp; case OP_EMBEDDING: return SaveTmEmbedOp; case OP_INSTANCENORM: return SaveTmInstanceNormOp; case OP_MVN: return SaveTmMVNOp; case OP_CAST: return SaveTmCastOp; case OP_HARDSWISH: return SaveTmHardSwishOp; case OP_INTERP: return SaveTmInterpOp; case OP_SELU: return SaveTmSeluOp; case OP_ELU: return SaveTmEluOp; case OP_BROADMUL: return SaveTmBroadMulOp; case OP_LOGICAL: return SaveTmLogicalOp; case OP_GATHER: return SaveTmGatherOp; case OP_TRANSPOSE: return SaveTmTransposeOp; case OP_COMPARISON: return SaveTmComparisonOp; case OP_REVERSE: return SaveTmReverseOp; case OP_SPACETODEPTH: return SaveTmSpaceToDepthOp; case OP_DEPTHTOSPACE: return SaveTmDepthToSpaceOp; case OP_SQUAREDDIFFERENCE: return SaveTmSquaredDifferenceOp; case OP_SPARSETODENSE: return SaveTmSparseToDenseOp; case OP_CEIL: return SaveTmCeilOp; case OP_ROUND: return SaveTmRoundOp; case OP_ZEROSLIKE: return SaveTmZerosLikeOp; case OP_CLIP: return SaveTmClipOp; case OP_REDUCEL2: return SaveTmReduceL2Op; case OP_UNSQUEEZE: return SaveTmUnsqueezeOp; case OP_MEAN: return SaveTmMeanOp; case OP_MATMUL: return SaveTmMatMulOp; case OP_MISH: return SaveTmMishOp; case OP_SPATIALTRANSFORMER: return SaveTmSpatialTransformerOp; case OP_EXPAND: return SaveTmExpandOp; case OP_SOFTPLUS: return SaveTmSoftplusOp; case OP_RECIPROCAL: return SaveTmReciprocalOp; case OP_MAXIMUM: return SaveTmMaximumOp; case OP_MINIMUM: return SaveTmMinimumOp; default: fprintf(stderr, "Operator #%d not supported in tengine model yet\n", op_type); return nullptr; } }