From 86afa56a4a2cc2c5bd44ca2eb19cf3ef45b23e35 Mon Sep 17 00:00:00 2001 From: ling Date: Thu, 10 Mar 2022 18:40:51 +0800 Subject: [PATCH] experiment kernel nc4 conv1x1 --- .../device/cpu/kernel/nnacl/CMakeLists.txt | 10 +- .../kernel/nnacl/experimental/base_matmul.c | 102 ++++++++++++++++ .../kernel/nnacl/experimental/base_matmul.h | 31 +++++ .../cpu/kernel/nnacl/experimental/conv.c | 13 ++- .../cpu/kernel/nnacl/experimental/conv1x1.c | 94 +++++++++++++++ .../cpu/kernel/nnacl/experimental/conv1x1.h | 32 +++++ .../experimental/conv_fp32_nchwx_avx512.c | 21 ++-- .../experimental/conv_fp32_nchwx_avx512.h | 2 +- .../kernel/nnacl/experimental/core_funcs.h | 33 ++++++ .../kernel/nnacl/experimental/fp16_funcs.c | 24 ++++ .../kernel/nnacl/experimental/fp16_funcs.h | 30 +++++ .../kernel/nnacl/experimental/fp32_funcs.c | 110 ++++++++++++++++++ .../kernel/nnacl/experimental/fp32_funcs.h | 32 +++++ .../device/cpu/kernel/nnacl/fp32/pack_fp32.c | 58 ++++----- .../device/cpu/kernel/nnacl/fp32/pack_fp32.h | 3 +- .../plugin/device/cpu/kernel/nnacl/kernel.c | 29 ++++- .../plugin/device/cpu/kernel/nnacl/kernel.h | 34 ++++-- .../core/mindrt/src/thread/threadpool.cc | 4 +- mindspore/core/mindrt/src/thread/threadpool.h | 5 +- mindspore/lite/CMakeLists.txt | 80 +++++++------ .../experimental/kernel/convolution_1x1.cc | 77 ++++++++++++ .../experimental/kernel/convolution_1x1.h | 43 +++++++ .../experimental/kernel/convolution_fp32.cc | 26 +++-- .../lite/experimental/src/exec_env_utils.cc | 46 ++++++++ .../lite/experimental/src/exec_env_utils.h | 37 ++++++ mindspore/lite/src/CMakeLists.txt | 6 +- mindspore/lite/src/inner_context.cc | 15 +++ mindspore/lite/src/inner_context.h | 2 + mindspore/lite/tools/converter/CMakeLists.txt | 6 + 29 files changed, 892 insertions(+), 113 deletions(-) create mode 100644 mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/base_matmul.c create mode 100644 mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/base_matmul.h create mode 100644 mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/conv1x1.c create mode 100644 mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/conv1x1.h create mode 100644 mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/core_funcs.h create mode 100644 mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/fp16_funcs.c create mode 100644 mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/fp16_funcs.h create mode 100644 mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/fp32_funcs.c create mode 100644 mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/fp32_funcs.h create mode 100644 mindspore/lite/experimental/kernel/convolution_1x1.cc create mode 100644 mindspore/lite/experimental/kernel/convolution_1x1.h create mode 100644 mindspore/lite/experimental/src/exec_env_utils.cc create mode 100644 mindspore/lite/experimental/src/exec_env_utils.h diff --git a/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/CMakeLists.txt b/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/CMakeLists.txt index d99f7d0b237..39112b78356 100644 --- a/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/CMakeLists.txt +++ b/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/CMakeLists.txt @@ -37,8 +37,16 @@ file(GLOB KERNEL_SRC ${NNACL_DIR}/infer/*.c ${NNACL_DIR}/base/*.c ${NNACL_DIR}/fp32_grad/*.c - #${NNACL_DIR}/experimental/HPC-generator/*.c ) +list(REMOVE_ITEM KERNEL_SRC ${NNACL_DIR}/kernel.c) + +if(MSLITE_ENABLE_EXPERIMENT_KERNEL) + file(GLOB EXPERIMENT_SRC + ${NNACL_DIR}/experimental/*.c + ${NNACL_DIR}/kernel.c) + set(KERNEL_SRC ${KERNEL_SRC} ${EXPERIMENT_SRC}) +endif() + if(NOT MSLITE_ENABLE_RUNTIME_PASS) list(REMOVE_ITEM KERNEL_SRC ${NNACL_DIR}/infer/shape_fusion_infer.c) endif() diff --git a/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/base_matmul.c b/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/base_matmul.c new file mode 100644 index 00000000000..9f8efc3a74a --- /dev/null +++ b/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/base_matmul.c @@ -0,0 +1,102 @@ +/** + * Copyright 2022 Huawei Technologies Co., Ltd + * + * Licensed 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. + */ + +#include "nnacl/experimental/base_matmul.h" +#include "nnacl/experimental/fp32_funcs.h" + +typedef struct BaseMatmulStru { + KernelBase *base; + size_t deep; + size_t row; + size_t col; + size_t thread_num; + uint8_t *a_ptr; + uint8_t *b_ptr; + uint8_t *c_ptr; + uint8_t *bias; + uint8_t *tmp_ptr; + float min; + float max; + size_t row_unit; + size_t row_tile; +} BaseMatmulStru; + +int BaseMatmulRun(void *param, int task_id, float lhs_scale, float rhs_scale) { + BaseMatmulStru *mm = (BaseMatmulStru *)param; + if (mm == NULL) { + return -1; + } + + size_t pack_uint = mm->base->funcs->pack * mm->base->funcs->byte; + + for (size_t i = task_id; i < mm->row_unit; i += mm->thread_num) { + int xStart = i * mm->row_tile; + uint8_t *a = mm->a_ptr + xStart * pack_uint; + uint8_t *tmp = mm->tmp_ptr + mm->row_tile * mm->deep * task_id * mm->base->funcs->byte; + mm->base->funcs->PackLeft(tmp, a, mm->row_tile, mm->deep, mm->row); + mm->base->funcs->Matmul(mm->c_ptr + xStart * pack_uint, tmp, mm->b_ptr, mm->bias, mm->row_tile, mm->deep, mm->col, + mm->row * mm->base->funcs->pack, mm->min, mm->max); + } + return 0; +} + +void BaseMatmul(uint8_t *a_ptr, uint8_t *b_ptr, uint8_t *bias, uint8_t *c_ptr, int row, int deep, int col, + ActType act_type, int thread_num, KernelBase *base) { + BaseMatmulStru basemm; + if (a_ptr == NULL || b_ptr == NULL || c_ptr == NULL) { + return; + } + basemm.base = base; + basemm.deep = deep; + basemm.col = col; + basemm.row = row; + basemm.a_ptr = a_ptr; + basemm.b_ptr = b_ptr; + basemm.c_ptr = c_ptr; + basemm.bias = bias; + basemm.thread_num = thread_num; + + int byte = basemm.base->funcs->byte; + int pack = basemm.base->funcs->pack; + int row_tile, deep_tile, col_tile; + basemm.base->funcs->InitMatmulTileCount(&row_tile, &deep_tile, &col_tile); + + basemm.row_tile = row_tile; + if (row_tile == 0) { + return; + } + basemm.row_unit = row / row_tile; + + if (bias != NULL || act_type != ActType_No) { + GetPostParameters(act_type, &basemm.min, &basemm.max); + } + + basemm.tmp_ptr = (uint8_t *)basemm.base->env->alloc(basemm.base->env->allocator, + thread_num * UP_ROUND(deep, deep_tile) * row_tile * byte); + basemm.base->env->parallelLaunch(basemm.base->env->threadPool, BaseMatmulRun, &basemm, thread_num); + + size_t row_remain = row - basemm.row_unit * row_tile; + if (row_remain != 0) { + int32_t start_row = basemm.row_unit * row_tile; + uint8_t *a_remain_ptr = a_ptr + start_row * pack * byte; + basemm.base->funcs->PackLeft(basemm.tmp_ptr, a_remain_ptr, row_remain, deep, row); + basemm.base->funcs->MatMulRes(c_ptr + start_row * pack * byte, basemm.tmp_ptr, b_ptr, bias, row_remain, basemm.deep, + basemm.col, basemm.row * basemm.base->funcs->pack, basemm.min, basemm.max); + } + + basemm.base->env->free(basemm.base->env->allocator, basemm.tmp_ptr); + return; +} diff --git a/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/base_matmul.h b/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/base_matmul.h new file mode 100644 index 00000000000..8c75bdce4f2 --- /dev/null +++ b/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/base_matmul.h @@ -0,0 +1,31 @@ +/** + * Copyright 2022 Huawei Technologies Co., Ltd + * + * Licensed 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. + */ +#ifndef MINDSPORE_NNACL_EXPERIMENT_BASE_MATMUL_H_ +#define MINDSPORE_NNACL_EXPERIMENT_BASE_MATMUL_H_ + +#include "nnacl/kernel.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void BaseMatmul(uint8_t *a_ptr, uint8_t *b_ptr, uint8_t *bias, uint8_t *c_ptr, int row, int deep, int col, + ActType act_type, int thread_num, KernelBase *base); + +#ifdef __cplusplus +} +#endif +#endif // MINDSPORE_NNACL_EXPERIMENT_BASE_MATMUL_H_ diff --git a/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/conv.c b/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/conv.c index 44c4489e9de..17b03d96060 100644 --- a/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/conv.c +++ b/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/conv.c @@ -13,14 +13,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #include "nnacl/experimental/conv.h" #include "nnacl/experimental/conv_fp32_nchwx_avx512.h" +#include "mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/conv_parameter.h" +#include "nnacl/tensor_c.h" +#include "nnacl/op_base.h" +#include "nnacl/kernel.h" static KernelBase *CreateConv(OpParameter *param, TensorC *in[], size_t insize, TensorC *out[], size_t outsize) { if (in[0]->format_ == Format_NHWC) { return NULL; } else if (in[0]->format_ == Format_NCHW) { - if (in[0]->data_format_ != Format_NC16HW16) { + if (in[0]->format_ != Format_NC16HW16) { return NULL; } KConv2d *conv = (KConv2d *)malloc(sizeof(KConv2d)); @@ -38,6 +43,9 @@ static KernelBase *CreateConv(OpParameter *param, TensorC *in[], size_t insize, conv->base.release = conv2d_release_fp32_nchwx_avx512; conv->base.resize = conv2d_resize_fp32_nchwx_avx512; conv->base.inferShape = conv2d_infershape_fp32_nchwx_avx512; + + conv->base.funcs = GetCoreFuncs(in[0]->data_type_ == kNumberTypeFloat16); + return (KernelBase *)conv; } else { return NULL; @@ -45,4 +53,5 @@ static KernelBase *CreateConv(OpParameter *param, TensorC *in[], size_t insize, return NULL; } -REG_KERNEL_CREATOR(PrimType_Conv2DFusion, PrimType_Conv2DFusion, DT_Float16, CreateConv); +REG_KERNEL_CREATOR(PrimType_Conv2DFusion, kNumberTypeFloat32, CreateConv); +REG_KERNEL_CREATOR(PrimType_Conv2DFusion, kNumberTypeFloat16, CreateConv); diff --git a/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/conv1x1.c b/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/conv1x1.c new file mode 100644 index 00000000000..f5ac77e8b82 --- /dev/null +++ b/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/conv1x1.c @@ -0,0 +1,94 @@ +/** + * Copyright 2022 Huawei Technologies Co., Ltd + * + * Licensed 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. + */ + +#include "nnacl/experimental/conv1x1.h" +#include +#include "nnacl/conv_parameter.h" +#include "nnacl/tensor_c.h" +#include "nnacl/op_base.h" +#include "nnacl/experimental/base_matmul.h" + +typedef struct Conv1x1Stru { + KernelBase base; + uint8_t *bias_; + uint8_t *weight_; +} Conv1x1Stru; + +int conv1x1_resize(struct KernelBase *self, TensorC *in[], size_t insize, TensorC *out[], size_t outsize) { return 0; } + +int conv1x1_prepare(struct KernelBase *self) { + Conv1x1Stru *conv = (Conv1x1Stru *)self; + ConvParameter *param = (ConvParameter *)conv->base.param; + + conv->base.funcs = GetCoreFuncs(conv->base.in[0]->data_type_ == kNumberTypeFloat16); + + int row_tile, deep_tile, col_tile; + conv->base.funcs->InitMatmulTileCount(&row_tile, &deep_tile, &col_tile); + + conv->weight_ = (uint8_t *)(conv->base.env->alloc( + conv->base.env->allocator, + UP_ROUND(param->output_channel_, col_tile) * UP_ROUND(param->input_channel_, deep_tile) * row_tile)); + conv->base.funcs->PackRight(conv->base.in[1]->data_, conv->weight_, 1, param->input_channel_, param->output_channel_); + + if (conv->base.insize < kInputSize2) { + conv->bias_ = NULL; + return 0; + } + + size_t bias_size = UP_ROUND(param->output_channel_, conv->base.funcs->pack) * conv->base.funcs->byte; + conv->bias_ = (uint8_t *)(conv->base.env->alloc(conv->base.env->allocator, bias_size)); + + memset(conv->bias_, 0, bias_size); + memcpy(conv->bias_, conv->base.in[kBiasIndex]->data_, param->output_channel_); + + return 0; +} + +int conv1x1_release(struct KernelBase *self) { + Conv1x1Stru *conv = (Conv1x1Stru *)self; + conv->base.env->free(conv->base.env->allocator, conv->bias_); + conv->base.env->free(conv->base.env->allocator, conv->weight_); + return 0; +} + +int conv1x1_compute(struct KernelBase *self) { + Conv1x1Stru *conv = (Conv1x1Stru *)self; + ConvParameter *param = (ConvParameter *)conv->base.param; + + BaseMatmul(conv->base.in[0]->data_, conv->weight_, conv->bias_, conv->base.out[0]->data_, + param->input_h_ * param->input_w_, param->input_channel_, param->output_channel_, param->act_type_, + param->op_parameter_.thread_num_, &conv->base); + return 0; +} + +KernelBase *CreateConv1x1(OpParameter *param, TensorC **in, size_t insize, TensorC **out, size_t outsize) { + if (in[0]->format_ != Format_NC4HW4) { + return NULL; + } + Conv1x1Stru *conv1x1 = (Conv1x1Stru *)malloc(sizeof(Conv1x1Stru)); + conv1x1->base.param = param; + conv1x1->base.in = in; + conv1x1->base.insize = insize; + conv1x1->base.out = out; + conv1x1->base.outsize = outsize; + conv1x1->base.env = GetExecEnv(); + conv1x1->base.prepare = conv1x1_prepare; + conv1x1->base.resize = conv1x1_resize; + conv1x1->base.release = conv1x1_release; + conv1x1->base.compute = conv1x1_compute; + + return (KernelBase *)conv1x1; +} diff --git a/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/conv1x1.h b/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/conv1x1.h new file mode 100644 index 00000000000..f32fb6d2d35 --- /dev/null +++ b/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/conv1x1.h @@ -0,0 +1,32 @@ +/** + * Copyright 2022 Huawei Technologies Co., Ltd + * + * Licensed 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. + */ +#ifndef MINDSPORE_NNACL_EXPERIMENT_CONV1X1_H_ +#define MINDSPORE_NNACL_EXPERIMENT_CONV1X1_H_ + +#include "nnacl/op_base.h" +#include "nnacl/tensor_c.h" +#include "nnacl/kernel.h" + +#ifdef __cplusplus +extern "C" { +#endif + +KernelBase *CreateConv1x1(OpParameter *param, TensorC *in[], size_t insize, TensorC *out[], size_t outsize); + +#ifdef __cplusplus +} +#endif +#endif // MINDSPORE_NNACL_EXPERIMENT_CONV1X1_H_ diff --git a/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/conv_fp32_nchwx_avx512.c b/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/conv_fp32_nchwx_avx512.c index f93924dc6ec..a2c91372513 100644 --- a/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/conv_fp32_nchwx_avx512.c +++ b/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/conv_fp32_nchwx_avx512.c @@ -23,9 +23,9 @@ static const int UNIT_LEN = 512; // register length static const int UNIT_NR = 512 / sizeof(float); static const int TILE_ROW; -int conv2d_prepare_fp32_nchwx_avx512(struct KernelBase *self, ExecEnv *env) { +int conv2d_prepare_fp32_nchwx_avx512(struct KernelBase *self) { KConv2d *conv = (KConv2d *)self; - self->env = env; + self->env = GetExecEnv(); int rowIndex = 0; TensorC *weight = self->in[kWeightIndex]; @@ -113,8 +113,8 @@ int conv2d_compute_fp32_nchwx_avx512(struct KernelBase *self) { // im2col + pack to z-N-Z order int unitOffset = 0; - int unitChNr = in->data_shape_[1]; - int interval = in->data_shape_[1] * UNIT_LEN; + int unitChNr = in->shape_[1]; + int interval = in->shape_[1] * UNIT_LEN; #ifdef VECTORIZE_OPTIMIZE // use AVX2 instruction to optimize matrix transpose #else @@ -219,18 +219,15 @@ int conv2d_resize_fp32_nchwx_avx512(struct KernelBase *self, TensorC *inputs[], int kw = weight->shape_[kNCHW_W]; self->inferShape(self); - out->data_format_ = Format_NC16HW16; - out->data_shape_[0] = out->shape_[0]; - out->data_shape_[1] = UP_ROUND_DIV(out->shape_[1], 16); - out->data_shape_[2] = out->shape_[2]; - out->data_shape_[3] = out->shape_[3]; - out->data_shape_[4] = 16; - out->data_shape_size_ = 5; + out->format_ = Format_NC16HW16; + out->shape_[1] = UP_ROUND_DIV(out->shape_[1], C16NUM); + out->shape_[4] = 16; + out->shape_size_ = 5; if (conv->im2colBuf) { free(conv->im2colBuf); } - int ci = in->data_shape_[1] * in->data_shape_[4]; + int ci = in->shape_[1] * in->shape_[4]; int lmw = ci * kw * kh; // left matrix width int lmh = out->shape_[kNCHW_H] * out->shape_[kNCHW_W]; // left matrix height diff --git a/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/conv_fp32_nchwx_avx512.h b/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/conv_fp32_nchwx_avx512.h index d01ce2f7c80..74ba85db413 100644 --- a/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/conv_fp32_nchwx_avx512.h +++ b/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/conv_fp32_nchwx_avx512.h @@ -17,7 +17,7 @@ #define MINDSPORE_NNACL_EXPERIMENT_CONV_FP32_AVX512_H_ #include "nnacl/kernel.h" -int conv2d_prepare_fp32_nchwx_avx512(struct KernelBase *self, ExecEnv *env); +int conv2d_prepare_fp32_nchwx_avx512(struct KernelBase *self); int conv2d_release_fp32_nchwx_avx512(struct KernelBase *self); int conv2d_compute_fp32_nchwx_avx512(struct KernelBase *self); int conv2d_infershape_fp32_nchwx_avx512(struct KernelBase *self); diff --git a/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/core_funcs.h b/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/core_funcs.h new file mode 100644 index 00000000000..6d316c8729b --- /dev/null +++ b/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/core_funcs.h @@ -0,0 +1,33 @@ +/** + * Copyright 2022 Huawei Technologies Co., Ltd + * + * Licensed 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. + */ +#ifndef MINDSPORE_NNACL_EXPERIMENT_CORE_FUNCS_H_ +#define MINDSPORE_NNACL_EXPERIMENT_CORE_FUNCS_H_ + +typedef struct CoreFuncs { + int pack; + int byte; + void (*InitMatmulTileCount)(int *row_tile, int *deep_tile, int *col_tile); + void (*PackNcX)(const void *src, void *dst, int batch, int plane, int channel); + void (*UnPackNcX)(const void *src, void *dst, int batch, int plane, int channel); + void (*PackLeft)(void *dst, void *src, size_t row, size_t deep, size_t src_stride); + void (*PackRight)(const void *src, void *dst, int batch, int plane, int channel); + void (*Matmul)(void *c_ptr, void *a_ptr, void *b_ptr, void *bias, size_t row, size_t deep, size_t col, + size_t dst_stride, float min, float max); + void (*MatMulRes)(void *c_ptr, void *a_ptr, void *b_ptr, void *bias, size_t row, size_t deep, size_t col, + size_t dst_stride, float min, float max); +} CoreFuncs; + +#endif // MINDSPORE_NNACL_EXPERIMENT_CORE_FUNCS_H_ diff --git a/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/fp16_funcs.c b/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/fp16_funcs.c new file mode 100644 index 00000000000..93dbc6b8686 --- /dev/null +++ b/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/fp16_funcs.c @@ -0,0 +1,24 @@ +/** + * Copyright 2022 Huawei Technologies Co., Ltd + * + * Licensed 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. + */ + +#include "nnacl/experimental/fp16_funcs.h" + +void InitFp16Funcs(CoreFuncs *funcs_) { +#ifdef ENABLE_ARM64 + funcs_->pack = C8NUM; + funcs_->byte = sizeof(float16_t); +#endif +} diff --git a/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/fp16_funcs.h b/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/fp16_funcs.h new file mode 100644 index 00000000000..6d69328692e --- /dev/null +++ b/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/fp16_funcs.h @@ -0,0 +1,30 @@ +/** + * Copyright 2022 Huawei Technologies Co., Ltd + * + * Licensed 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. + */ +#ifndef MINDSPORE_NNACL_EXPERIMENT_FP16_FUNCS_H_ +#define MINDSPORE_NNACL_EXPERIMENT_FP16_FUNCS_H_ + +#include "nnacl/kernel.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void InitFp16Funcs(CoreFuncs *funcs_); + +#ifdef __cplusplus +} +#endif +#endif // MINDSPORE_NNACL_EXPERIMENT_FP32_FUNCS_H_ diff --git a/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/fp32_funcs.c b/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/fp32_funcs.c new file mode 100644 index 00000000000..69a7219f529 --- /dev/null +++ b/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/fp32_funcs.c @@ -0,0 +1,110 @@ +/** + * Copyright 2022 Huawei Technologies Co., Ltd + * + * Licensed 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. + */ + +#include "nnacl/experimental/fp32_funcs.h" +#include +#include "nnacl/op_base.h" +#include "nnacl/fp32/pack_fp32.h" + +void GetPostParameters(ActType act, float *min, float *max) { +#define RELU6_VALUE 6.0f +#define RELU_VALUE 0.0f + *min = -FLT_MAX; + *max = FLT_MAX; + + if (act == ActType_Relu) { + *min = RELU_VALUE; + } + if (act == ActType_Relu6) { + *min = RELU_VALUE; + *max = RELU6_VALUE; + } + return; +} + +void InitBaseMMFp32TileCount(int *row_tile, int *deep_tile, int *col_tile) { + *row_tile = C16NUM; + *col_tile = C4NUM; + *deep_tile = 1; +} + +void PackMatmulA(void *dst_ptr, void *src_ptr, size_t row, size_t deep, size_t src_stride) { + /* src_stride : total row */ + float *dst = (float *)dst_ptr; + float *src = (float *)src_ptr; + for (int d = 0; d < deep; d++) { + int deep_mod4 = d % C4NUM; + int deep_div4 = d / C4NUM; + for (int r = 0; r < row; r++) { + dst[d * row + r] = src[deep_div4 * src_stride * C4NUM + r * C4NUM + deep_mod4]; + } + } +} + +static void DoBaseMatmul(float *c_ptr, const float *a_ptr, const float *b_ptr, const float *bias, size_t row, + size_t deep, size_t col, size_t dst_stride, float min, float max) { + /* dst_stride : total_row * pack */ + for (size_t r = 0; r < row; r++) { + for (size_t c = 0; c < col; c++) { + float dst = 0; + size_t c_div4 = c / C4NUM; + size_t c_mod4 = c % C4NUM; + for (size_t d = 0; d < deep; d++) { + size_t a_index = d * row + r; + size_t b_index = c_div4 * deep * C4NUM + d * C4NUM + c_mod4; + dst += a_ptr[a_index] * b_ptr[b_index]; + } + + if (bias != NULL) { + dst += bias[c]; + } + dst = MSMIN(dst, max); + dst = MSMAX(dst, min); + size_t dst_index = c_div4 * dst_stride + r * C4NUM + c_mod4; + c_ptr[dst_index] = dst; + } + } +} + +void BaseMatMul(void *c_ptr, void *a_ptr, void *b_ptr, void *bias_ptr, size_t row, size_t deep, size_t col, + size_t dst_stride, float min, float max) { + float *c = (float *)c_ptr; + float *a = (float *)a_ptr; + float *b = (float *)b_ptr; + float *bias = (float *)bias_ptr; + return DoBaseMatmul(c, a, b, bias, row, deep, col, dst_stride, min, max); +} + +void BaseMatMulRes(void *c_ptr, void *a_ptr, void *b_ptr, void *bias_ptr, size_t row, size_t deep, size_t col, + size_t dst_stride, float min, float max) { + float *c = (float *)c_ptr; + float *a = (float *)a_ptr; + float *b = (float *)b_ptr; + float *bias = (float *)bias_ptr; + return DoBaseMatmul(c, a, b, bias, row, deep, col, dst_stride, min, max); +} + +void InitFp32Funcs(CoreFuncs *funcs_) { + funcs_->pack = C4NUM; + funcs_->byte = sizeof(float); + funcs_->InitMatmulTileCount = InitBaseMMFp32TileCount; + funcs_->PackNcX = PackNCHWToNC4HW4Fp32; + funcs_->UnPackNcX = PackNC4HW4ToNCHWFp32; + funcs_->PackLeft = PackMatmulA; + funcs_->PackRight = PackNCHWToNC4HW4Fp32; + funcs_->Matmul = BaseMatMul; + funcs_->MatMulRes = BaseMatMulRes; +} diff --git a/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/fp32_funcs.h b/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/fp32_funcs.h new file mode 100644 index 00000000000..dbbbd4c58e7 --- /dev/null +++ b/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/experimental/fp32_funcs.h @@ -0,0 +1,32 @@ +/** + * Copyright 2022 Huawei Technologies Co., Ltd + * + * Licensed 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. + */ +#ifndef MINDSPORE_NNACL_EXPERIMENT_FP32_FUNCS_H_ +#define MINDSPORE_NNACL_EXPERIMENT_FP32_FUNCS_H_ + +#include "nnacl/kernel.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void InitFp32Funcs(CoreFuncs *funcs_); + +void GetPostParameters(ActType act, float *min, float *max); + +#ifdef __cplusplus +} +#endif +#endif // MINDSPORE_NNACL_EXPERIMENT_FP32_FUNCS_H_ diff --git a/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/fp32/pack_fp32.c b/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/fp32/pack_fp32.c index 769fe533eae..3dca71776ce 100644 --- a/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/fp32/pack_fp32.c +++ b/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/fp32/pack_fp32.c @@ -384,6 +384,29 @@ void PackNC4HW4ToNHWC4Fp32(const void *src, void *dst, int batch, int plane, int } } +void UnPackC4Uint(const void *src, void *dst, size_t plane, size_t channel) { + const float *fp32_src = (const float *)src; + float *fp32_dst = (float *)dst; + for (size_t c = 0; c < channel; c++) { + size_t c_div = c / C4NUM; + size_t c_mod = c % C4NUM; + for (size_t p = 0; p < plane; p++) { + int src_offset = c_div * plane * C4NUM + plane * C4NUM + c_mod; + int dst_offset = p * channel + c; + fp32_dst[dst_offset] = fp32_src[src_offset]; + } + } +} + +void PackNC4HW4ToNCHWFp32(const void *src, void *dst, int batch, int plane, int channel) { + int c4 = UP_ROUND(channel, C4NUM); + for (int b = 0; b < batch; b++) { + int src_offset = b * plane * c4; + int dst_offset = b * plane * channel; + UnPackC4Uint((const float *)src + src_offset, (float *)dst + dst_offset, plane, channel); + } +} + void PackNC4HW4ToNHWCFp32(const void *src, void *dst, int batch, int plane, int channel) { int c4 = UP_DIV(channel, C4NUM); for (int b = 0; b < batch; b++) { @@ -415,41 +438,6 @@ void PackNC4HW4ToNHWCFp32(const void *src, void *dst, int batch, int plane, int } } -void PackNC8HW8ToNHWCFp32(const void *src, void *dst, int batch, int plane, int channel) { - int c8 = UP_DIV(channel, C8NUM); - for (int b = 0; b < batch; b++) { - int src_offset = b * plane * c8 * C8NUM; - int dst_offset = b * plane * channel; - for (int k = 0; k < plane; k++) { - int src_kernel_offset = src_offset + k * C8NUM; - int dst_kernel_offset = dst_offset + k * channel; - for (int c = 0; c < c8 - 1; c++) { - int src_c_offset = src_kernel_offset + c * plane * C8NUM; - int dst_c_offset = dst_kernel_offset + c * C8NUM; -#ifdef ENABLE_AVX - MS_ST256_F32((float *)dst + dst_c_offset, MS_LD256_F32((float *)src + src_c_offset)); -#else - ((float *)dst + dst_c_offset)[0] = ((float *)src + src_c_offset)[0]; - ((float *)dst + dst_c_offset)[1] = ((float *)src + src_c_offset)[1]; - ((float *)dst + dst_c_offset)[2] = ((float *)src + src_c_offset)[2]; - ((float *)dst + dst_c_offset)[3] = ((float *)src + src_c_offset)[3]; - ((float *)dst + dst_c_offset)[4] = ((float *)src + src_c_offset)[4]; - ((float *)dst + dst_c_offset)[5] = ((float *)src + src_c_offset)[5]; - ((float *)dst + dst_c_offset)[6] = ((float *)src + src_c_offset)[6]; - ((float *)dst + dst_c_offset)[7] = ((float *)src + src_c_offset)[7]; -#endif - } - // res part - int res_c = channel - (c8 - 1) * C8NUM; - for (int i = 0; i < res_c; i++) { - int src_res_c_offset = src_kernel_offset + (c8 - 1) * C8NUM * plane + i; - int dst_res_c_offset = dst_kernel_offset + (c8 - 1) * C8NUM + i; - ((float *)dst + dst_res_c_offset)[0] = ((float *)src + src_res_c_offset)[0]; - } - } - } -} - void PackNC8HW8AlignedToNC8HW8NotAlignedFp32(const void *src, void *dst, const int batch, const int plane, const int channel) { int down_channel_8 = DOWN_ROUND(channel, C8NUM); diff --git a/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/fp32/pack_fp32.h b/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/fp32/pack_fp32.h index 979ab568806..2845336e1ba 100644 --- a/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/fp32/pack_fp32.h +++ b/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/fp32/pack_fp32.h @@ -37,7 +37,8 @@ void PackNCHWToNHWCFp32(const void *src, void *dst, int batch, int plane, int ch void PackNHWCXToNHWCFp32(const void *src, void *dst, int batch, int plane, int channel, int cx_num); void PackNC4HW4ToNHWC4Fp32(const void *src, void *dst, int batch, int plane, int channel); void PackNC4HW4ToNHWCFp32(const void *src, void *dst, int batch, int plane, int channel); -void PackNC8HW8ToNHWCFp32(const void *src, void *dst, int batch, int plane, int channel); +void PackNC4HW4ToNCHWFp32(const void *src, void *dst, int batch, int plane, int channel); +void UnPackC4Uint(const void *src, void *dst, size_t plane, size_t channel); void PackNC8HW8AlignedToNC8HW8NotAlignedFp32(const void *src, void *dst, int batch, int plane, int channel); void PackNHWCToC8HWN8Fp32(const void *src, void *dst, int batch, int plane, int channel); void PackNHWCToCXHWNXFp32(const float *src, float *dst, int batch, int plane, int channel); diff --git a/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/kernel.c b/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/kernel.c index 58b7416f2b5..59cba23494f 100644 --- a/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/kernel.c +++ b/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/kernel.c @@ -14,6 +14,11 @@ * limitations under the License. */ #include "nnacl/kernel.h" +#include "nnacl/tensor_c.h" +#include "nnacl/op_base.h" +#include "nnacl/experimental/fp32_funcs.h" +#include "nnacl/experimental/fp16_funcs.h" + static KernelCreator g_kernelCreatorRegistry[PrimType_MAX][16]; void RegKernelCreator(int opType, int dataType, KernelCreator creator) { @@ -22,5 +27,27 @@ void RegKernelCreator(int opType, int dataType, KernelCreator creator) { KernelBase *CreateKernel(OpParameter *param, TensorC *in[], size_t insize, TensorC *out[], size_t outsize) { int dtype = in[kInputIndex]->data_type_; - return g_kernelCreatorRegistry[param->type_][dtype - kNumberTypeBegin - 1](param, in, insize, out, outsize); + KernelCreator creator = g_kernelCreatorRegistry[param->type_][dtype - kNumberTypeBegin - 1]; + if (creator == NULL) { + return NULL; + } + return creator(param, in, insize, out, outsize); +} + +ExecEnv *GetExecEnv() { + static ExecEnv kc; + return &kc; +} + +CoreFuncs *GetCoreFuncs(bool use_fp16) { + static CoreFuncs fp23funcs; + InitFp32Funcs(&fp23funcs); + static CoreFuncs fp16funcs; + InitFp16Funcs(&fp16funcs); + + if (use_fp16) { + return &fp16funcs; + } + + return &fp23funcs; } diff --git a/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/kernel.h b/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/kernel.h index 84bbde18222..6eb85593e69 100644 --- a/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/kernel.h +++ b/mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/kernel.h @@ -17,16 +17,19 @@ #define MINDSPORE_NNACL_KERNEL_H_ #include "nnacl/op_base.h" #include "nnacl/infer/common_infer.h" +#include "nnacl/experimental/core_funcs.h" typedef struct ExecEnv { - void *(*alloc)(size_t sz); - void (*free)(void *ptr); + void *allocator; + void *threadPool; + void *(*alloc)(void *allocator, size_t sz); + void (*free)(void *allocator, void *ptr); int threadNum; - void (*parallelLaunch)(void *task, void *param, int taskNr); + int (*parallelLaunch)(void *threadPool, void *task, void *param, int taskNr); } ExecEnv; typedef struct KernelBase { - int (*prepare)(struct KernelBase *self, ExecEnv *env); // prepare, e.g. pack weight + int (*prepare)(struct KernelBase *self); // prepare, e.g. pack weight int (*release)(struct KernelBase *self); int (*compute)(struct KernelBase *self); int (*inferShape)(struct KernelBase *self); @@ -40,17 +43,26 @@ typedef struct KernelBase { size_t outsize; ExecEnv *env; bool inferShape_; + CoreFuncs *funcs; } KernelBase; -KernelBase *CreateKernel(OpParameter *param, TensorC *in[], size_t insize, TensorC *out[], size_t outsize); +#ifdef _MSC_VER +#define REG_KERNEL_CREATOR(op_type, data_type, func) +#else +#define REG_KERNEL_CREATOR(op, data_type, func) \ + __attribute__((constructor(102))) void Reg##op##data_type##Creator() { RegKernelCreator(op, data_type, func); } +#endif + typedef KernelBase *(*KernelCreator)(OpParameter *param, TensorC *in[], size_t insize, TensorC *out[], size_t outsize); void RegKernelCreator(int opType, int dataType, KernelCreator func); +CoreFuncs *GetCoreFuncs(bool use_fp16); -#ifdef _MSC_VER -#define REG_KERNEL_CREATOR(op, op_type, data_type, func) -#else -#define REG_KERNEL_CREATOR(op, op_type, data_type, func) \ - __attribute__((constructor(102))) void Reg##op##Creator() { RegKernelCreator(op_type, data_type, func); } +#ifdef __cplusplus +extern "C" { +#endif +KernelBase *CreateKernel(OpParameter *param, TensorC *in[], size_t insize, TensorC *out[], size_t outsize); +ExecEnv *GetExecEnv(void); +#ifdef __cplusplus +} #endif - #endif diff --git a/mindspore/core/mindrt/src/thread/threadpool.cc b/mindspore/core/mindrt/src/thread/threadpool.cc index fb0992e1b9d..69f1294d2e4 100644 --- a/mindspore/core/mindrt/src/thread/threadpool.cc +++ b/mindspore/core/mindrt/src/thread/threadpool.cc @@ -227,11 +227,11 @@ int ThreadPool::CreateThreads(size_t thread_num, const std::vector &core_li return THREAD_OK; } -int ThreadPool::ParallelLaunch(const TaskFunc &func, Content content, int task_num) const { +int ThreadPool::ParallelLaunch(const TaskFunc &func, Content content, int task_num) { return ParallelLaunch(std::function(func), content, task_num); } -int ThreadPool::ParallelLaunch(const Func &func, Content content, int task_num) const { +int ThreadPool::ParallelLaunch(const Func &func, Content content, int task_num) { // if single thread, run master thread if (task_num <= 1) { for (int i = 0; i < task_num; ++i) { diff --git a/mindspore/core/mindrt/src/thread/threadpool.h b/mindspore/core/mindrt/src/thread/threadpool.h index 713e14a5e8c..ebc70e3efa7 100644 --- a/mindspore/core/mindrt/src/thread/threadpool.h +++ b/mindspore/core/mindrt/src/thread/threadpool.h @@ -60,6 +60,7 @@ constexpr int kThreadIdle = 2; // idle, the thread is waiting typedef int (*TaskFunc)(void *param, int task_id, float l, float r); using Func = std::function; + using Content = void *; typedef struct Task { @@ -162,8 +163,8 @@ class MS_CORE_API ThreadPool { int SetCpuAffinity(BindMode bind_mode); int SetProcessAffinity(BindMode bind_mode) const; - int ParallelLaunch(const TaskFunc &func, Content content, int task_num) const; - int ParallelLaunch(const Func &func, Content content, int task_num) const; + int ParallelLaunch(const TaskFunc &func, Content content, int task_num); + int ParallelLaunch(const Func &func, Content content, int task_num); void DisableOccupiedActorThread() { occupied_actor_thread_ = false; } void SetActorThreadNum(size_t actor_thread_num) { actor_thread_num_ = actor_thread_num; } void SetKernelThreadNum(size_t kernel_thread_num) { kernel_thread_num_ = kernel_thread_num; } diff --git a/mindspore/lite/CMakeLists.txt b/mindspore/lite/CMakeLists.txt index 646811beadf..48fd514df5d 100644 --- a/mindspore/lite/CMakeLists.txt +++ b/mindspore/lite/CMakeLists.txt @@ -54,6 +54,7 @@ option(MSLITE_ENABLE_DYNAMIC_THREAD_DISTRIBUTE "enable distribute thread dynamic option(MSLITE_ENABLE_BFC_MEMORY "enable distribute BFC memory" off) option(MSLITE_ENABLE_PARALLEL_INFERENCE "enable parallel inference interface" off) option(MSLITE_ENABLE_SHARING_MODEL_WEIGHT "enable sharing model weight" off) +option(MSLITE_ENABLE_EXPERIMENTAL_KERNEL "enable experimental kernel" off) #Option that can be configured through manually option(ENABLE_VERBOSE "" off) @@ -67,6 +68,10 @@ if(MACHINE_LINUX_ARM64) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv8-a+fp16") endif() +if(DEFINED ENV{MSLITE_ENABLE_EXPERIMENTAL_KERNEL}) + set(MSLITE_ENABLE_EXPERIMENTAL_KERNEL $ENV{MSLITE_ENABLE_EXPERIMENTAL_KERNEL}) +endif() + if(DEFINED ENV{MSLITE_GPU_BACKEND}) set(MSLITE_GPU_BACKEND $ENV{MSLITE_GPU_BACKEND}) endif() @@ -245,7 +250,7 @@ if(PLATFORM_ARM64 OR PLATFORM_ARM32) endif() set(MSLITE_ENABLE_RUNTIME_GLOG off) set(MSLITE_ENABLE_RUNTIME_CONVERT off) - #set for cross - compiling toolchain +#set for cross - compiling toolchain set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH) @@ -351,41 +356,42 @@ if(MSLITE_ENABLE_FP16 AND PLATFORM_ARM32 AND CMAKE_CXX_COMPILER_ID STREQUAL "Cla endif() message(STATUS "************MindSpore Lite Build Option:************") -message(STATUS "\tMSLITE_GPU_BACKEND = \t${MSLITE_GPU_BACKEND}") -message(STATUS "\tMSLITE_REGISTRY_DEVICE = \t${MSLITE_REGISTRY_DEVICE}") -message(STATUS "\tMSLITE_ENABLE_NPU = \t${MSLITE_ENABLE_NPU}") -message(STATUS "\tMSLITE_ENABLE_TRAIN = \t${MSLITE_ENABLE_TRAIN}") -message(STATUS "\tMSLITE_ENABLE_SSE = \t${MSLITE_ENABLE_SSE}") -message(STATUS "\tMSLITE_ENABLE_AVX = \t${MSLITE_ENABLE_AVX}") -message(STATUS "\tMSLITE_ENABLE_AVX512 = \t${MSLITE_ENABLE_AVX512}") -message(STATUS "\tMSLITE_ENABLE_CONVERTER = \t${MSLITE_ENABLE_CONVERTER}") -message(STATUS "\tMSLITE_ENABLE_TOOLS = \t${MSLITE_ENABLE_TOOLS}") -message(STATUS "\tMSLITE_ENABLE_TESTCASES = \t${MSLITE_ENABLE_TESTCASES}") -message(STATUS "\tMSLITE_ENABLE_HIGH_PERFORMANCE = \t${MSLITE_ENABLE_HIGH_PERFORMANCE}") -message(STATUS "\tMSLITE_ENABLE_RUNTIME_PASS = \t${MSLITE_ENABLE_RUNTIME_PASS}") -message(STATUS "\tMSLITE_ENABLE_STRING_KERNEL = \t${MSLITE_ENABLE_STRING_KERNEL}") -message(STATUS "\tMSLITE_ENABLE_CONTROLFLOW = \t${MSLITE_ENABLE_CONTROLFLOW}") -message(STATUS "\tMSLITE_ENABLE_AUTO_PARALLEL = \t${MSLITE_ENABLE_AUTO_PARALLEL}") -message(STATUS "\tMSLITE_ENABLE_WEIGHT_DECODE = \t${MSLITE_ENABLE_WEIGHT_DECODE}") -message(STATUS "\tMSLITE_ENABLE_CUSTOM_KERNEL = \t${MSLITE_ENABLE_CUSTOM_KERNEL}") -message(STATUS "\tMSLITE_ENABLE_MINDRT = \t${MSLITE_ENABLE_MINDRT}") -message(STATUS "\tMSLITE_ENABLE_V0 = \t${MSLITE_ENABLE_V0}") -message(STATUS "\tMSLITE_MINDDATA_IMPLEMENT = \t${MSLITE_MINDDATA_IMPLEMENT}") -message(STATUS "\tMSLITE_ENABLE_DELEGATE = \t${MSLITE_ENABLE_DELEGATE}") -message(STATUS "\tMSLITE_ENABLE_ACL = \t${MSLITE_ENABLE_ACL}") -message(STATUS "\tMSLITE_ENABLE_FP16 = \t${MSLITE_ENABLE_FP16}") -message(STATUS "\tMSLITE_ENABLE_INT8 = \t${MSLITE_ENABLE_INT8}") -message(STATUS "\tMSLITE_ENABLE_MODEL_ENCRYPTION = \t${MSLITE_ENABLE_MODEL_ENCRYPTION}") -message(STATUS "\tMSLITE_ENABLE_SPARSE_COMPUTE = \t${MSLITE_ENABLE_SPARSE_COMPUTE}") -message(STATUS "\tMSLITE_ENABLE_RUNTIME_CONVERT = \t${MSLITE_ENABLE_RUNTIME_CONVERT}") -message(STATUS "\tMSLITE_ENABLE_RUNTIME_GLOG = \t${MSLITE_ENABLE_RUNTIME_GLOG}") -message(STATUS "\tMSLITE_ENABLE_COVERAGE = \t${MSLITE_ENABLE_COVERAGE}") +message(STATUS "\tMSLITE_GPU_BACKEND = \t${MSLITE_GPU_BACKEND}") +message(STATUS "\tMSLITE_REGISTRY_DEVICE = \t${MSLITE_REGISTRY_DEVICE}") +message(STATUS "\tMSLITE_ENABLE_NPU = \t${MSLITE_ENABLE_NPU}") +message(STATUS "\tMSLITE_ENABLE_TRAIN = \t${MSLITE_ENABLE_TRAIN}") +message(STATUS "\tMSLITE_ENABLE_SSE = \t${MSLITE_ENABLE_SSE}") +message(STATUS "\tMSLITE_ENABLE_AVX = \t${MSLITE_ENABLE_AVX}") +message(STATUS "\tMSLITE_ENABLE_AVX512 = \t${MSLITE_ENABLE_AVX512}") +message(STATUS "\tMSLITE_ENABLE_CONVERTER = \t${MSLITE_ENABLE_CONVERTER}") +message(STATUS "\tMSLITE_ENABLE_TOOLS = \t${MSLITE_ENABLE_TOOLS}") +message(STATUS "\tMSLITE_ENABLE_TESTCASES = \t${MSLITE_ENABLE_TESTCASES}") +message(STATUS "\tMSLITE_ENABLE_HIGH_PERFORMANCE = \t${MSLITE_ENABLE_HIGH_PERFORMANCE}") +message(STATUS "\tMSLITE_ENABLE_RUNTIME_PASS = \t${MSLITE_ENABLE_RUNTIME_PASS}") +message(STATUS "\tMSLITE_ENABLE_STRING_KERNEL = \t${MSLITE_ENABLE_STRING_KERNEL}") +message(STATUS "\tMSLITE_ENABLE_CONTROLFLOW = \t${MSLITE_ENABLE_CONTROLFLOW}") +message(STATUS "\tMSLITE_ENABLE_AUTO_PARALLEL = \t${MSLITE_ENABLE_AUTO_PARALLEL}") +message(STATUS "\tMSLITE_ENABLE_WEIGHT_DECODE = \t${MSLITE_ENABLE_WEIGHT_DECODE}") +message(STATUS "\tMSLITE_ENABLE_CUSTOM_KERNEL = \t${MSLITE_ENABLE_CUSTOM_KERNEL}") +message(STATUS "\tMSLITE_ENABLE_MINDRT = \t${MSLITE_ENABLE_MINDRT}") +message(STATUS "\tMSLITE_ENABLE_V0 = \t${MSLITE_ENABLE_V0}") +message(STATUS "\tMSLITE_MINDDATA_IMPLEMENT = \t${MSLITE_MINDDATA_IMPLEMENT}") +message(STATUS "\tMSLITE_ENABLE_DELEGATE = \t${MSLITE_ENABLE_DELEGATE}") +message(STATUS "\tMSLITE_ENABLE_ACL = \t${MSLITE_ENABLE_ACL}") +message(STATUS "\tMSLITE_ENABLE_FP16 = \t${MSLITE_ENABLE_FP16}") +message(STATUS "\tMSLITE_ENABLE_INT8 = \t${MSLITE_ENABLE_INT8}") +message(STATUS "\tMSLITE_ENABLE_MODEL_ENCRYPTION = \t${MSLITE_ENABLE_MODEL_ENCRYPTION}") +message(STATUS "\tMSLITE_ENABLE_SPARSE_COMPUTE = \t${MSLITE_ENABLE_SPARSE_COMPUTE}") +message(STATUS "\tMSLITE_ENABLE_RUNTIME_CONVERT = \t${MSLITE_ENABLE_RUNTIME_CONVERT}") +message(STATUS "\tMSLITE_ENABLE_RUNTIME_GLOG = \t${MSLITE_ENABLE_RUNTIME_GLOG}") +message(STATUS "\tMSLITE_ENABLE_COVERAGE = \t${MSLITE_ENABLE_COVERAGE}") message(STATUS "\tMSLITE_ENABLE_SHARING_MEM_WITH_OPENGL = \t${MSLITE_ENABLE_SHARING_MEM_WITH_OPENGL}") -message(STATUS "\tMSLITE_ENABLE_SERVER_INFERENCE = \t${MSLITE_ENABLE_SERVER_INFERENCE}") -message(STATUS "\tMSLITE_ENABLE_DYNAMIC_THREAD_DISTRIBUTE = \t${MSLITE_ENABLE_DYNAMIC_THREAD_DISTRIBUTE}") -message(STATUS "\tMSLITE_ENABLE_BFC_MEMORY = \t${MSLITE_ENABLE_BFC_MEMORY}") -message(STATUS "\tMSLITE_ENABLE_PARALLEL_INFERENCE = \t${MSLITE_ENABLE_PARALLEL_INFERENCE}") -message(STATUS "\tMSLITE_ENABLE_SHARING_MODEL_WEIGHT = \t${MSLITE_ENABLE_SHARING_MODEL_WEIGHT}") +message(STATUS "\tMSLITE_ENABLE_SERVER_INFERENCE = \t${MSLITE_ENABLE_SERVER_INFERENCE}") +message(STATUS "\tMSLITE_ENABLE_DYNAMIC_THREAD_DISTRIBUTE = \t${MSLITE_ENABLE_DYNAMIC_THREAD_DISTRIBUTE}") +message(STATUS "\tMSLITE_ENABLE_BFC_MEMORY = \t${MSLITE_ENABLE_BFC_MEMORY}") +message(STATUS "\tMSLITE_ENABLE_PARALLEL_INFERENCE = \t${MSLITE_ENABLE_PARALLEL_INFERENCE}") +message(STATUS "\tMSLITE_ENABLE_SHARING_MODEL_WEIGHT = \t${MSLITE_ENABLE_SHARING_MODEL_WEIGHT}") +message(STATUS "\tMSLITE_ENABLE_EXPERIMENT_KERNEL = \t${MSLITE_ENABLE_EXPERIMENT_KERNEL}") if((MSLITE_ENABLE_CONVERTER OR MSLITE_ENABLE_TESTCASES) AND ( NOT MSLITE_ENABLE_MINDRT @@ -398,6 +404,10 @@ if((MSLITE_ENABLE_CONVERTER OR MSLITE_ENABLE_TESTCASES) AND ( "is configured as off, MSLITE_ENABLE_CONVERTER and MSLITE_ENABLE_TESTCASES must also be configured as off") endif() +if(MSLITE_ENABLE_EXPERIMENTAL_KERNEL) + add_compile_definitions(MSLITE_ENABLE_EXPERIMENTAL_KERNEL) +endif() + if(((MSLITE_GPU_BACKEND STREQUAL tensorrt) OR MSLITE_ENABLE_NPU) AND ( NOT MSLITE_ENABLE_DELEGATE)) message(FATAL_ERROR "If MSLITE_ENABLE_DELEGATE use is configured as off, MSLITE_ENABLE_NPU must also be configured diff --git a/mindspore/lite/experimental/kernel/convolution_1x1.cc b/mindspore/lite/experimental/kernel/convolution_1x1.cc new file mode 100644 index 00000000000..58b6af2ad0a --- /dev/null +++ b/mindspore/lite/experimental/kernel/convolution_1x1.cc @@ -0,0 +1,77 @@ +/** + * Copyright 2022 Huawei Technologies Co., Ltd + * + * Licensed 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. + */ + +#include "experimental/kernel/convolution_1x1.h" +#include "nnacl/tensor_c.h" +#include "src/common/tensor_util.h" +#include "nnacl/kernel.h" + +namespace mindspore::kernel::experimental { +Convolution1x1CPU::Convolution1x1CPU(OpParameter *parameter, std::vector in_tensors, + std::vector out_tensors, const lite::Context *ctx) + : LiteKernel(parameter, in_tensors, out_tensors, ctx) { + for (size_t i = 0; i < in_tensors.size(); i++) { + in[i] = reinterpret_cast(malloc(sizeof(TensorC))); + Tensor2TensorC(in_tensors[i], in[i]); + } + out[0] = reinterpret_cast(malloc(sizeof(TensorC))); + Tensor2TensorC(out_tensors[0], out[0]); +} + +Convolution1x1CPU::~Convolution1x1CPU() { + if (kernel == nullptr) { + return; + } + kernel->release(kernel); + + free(kernel); + kernel = nullptr; + + for (size_t i = 0; i < in_tensors().size(); i++) { + free(in[i]); + in[i] = nullptr; + } + free(out[0]); + out[0] = nullptr; +} + +int Convolution1x1CPU::Prepare() { + kernel = CreateKernel(op_parameter_, in, in_tensors().size(), out, 1); + if (kernel == nullptr) { + return -1; + } + return kernel->prepare(kernel); +} + +int Convolution1x1CPU::ReSize() { + if (kernel == nullptr) { + return -1; + } + return kernel->resize(kernel, in, in_tensors().size(), out, 1); +} + +int Convolution1x1CPU::Run() { + if (kernel == nullptr) { + return -1; + } + + kernel->in[0]->data_ = in_tensors().front()->data(); + kernel->out[0]->data_ = out_tensors().front()->data(); + + kernel->compute(kernel); + return 0; +} +} // namespace mindspore::kernel::experimental diff --git a/mindspore/lite/experimental/kernel/convolution_1x1.h b/mindspore/lite/experimental/kernel/convolution_1x1.h new file mode 100644 index 00000000000..b15fcc2ae49 --- /dev/null +++ b/mindspore/lite/experimental/kernel/convolution_1x1.h @@ -0,0 +1,43 @@ +/** + * Copyright 2022 Huawei Technologies Co., Ltd + * + * Licensed 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. + */ + +#ifndef MINDSPORE_LITE_EXPERIMENTAL_CONVOLUTION_1x1_H_ +#define MINDSPORE_LITE_EXPERIMENTAL_CONVOLUTION_1x1_H_ + +#include +#include "nnacl/op_base.h" +#include "src/lite_kernel.h" +#include "nnacl/kernel.h" + +namespace mindspore::kernel::experimental { +class Convolution1x1CPU : public LiteKernel { + public: + Convolution1x1CPU(OpParameter *parameter, std::vector in_tensors, + std::vector out_tensors, const lite::Context *ctx); + virtual ~Convolution1x1CPU(); + + int Run() override; + int ReSize() override; + int Prepare() override; + + private: + KernelBase *kernel = nullptr; + TensorC *in[3] = {nullptr}; + TensorC *out[1] = {nullptr}; +}; +} // namespace mindspore::kernel::experimental + +#endif // MINDSPORE_LITE_EXPERIMENTAL_CONVOLUTION_1x1_H_ diff --git a/mindspore/lite/experimental/kernel/convolution_fp32.cc b/mindspore/lite/experimental/kernel/convolution_fp32.cc index ce55a4d2610..84da4db58f0 100644 --- a/mindspore/lite/experimental/kernel/convolution_fp32.cc +++ b/mindspore/lite/experimental/kernel/convolution_fp32.cc @@ -15,34 +15,46 @@ */ #include "nnacl/op_base.h" #include "experimental/kernel/convolution_fp32.h" +#include "src/common/tensor_util.h" namespace mindspore::kernel { ConvolutionCPUFp32::ConvolutionCPUFp32(OpParameter *parameter, std::vector in_tensors, std::vector out_tensors, const lite::Context *ctx) : LiteKernel(parameter, in_tensors, out_tensors, ctx) { - in[0] = &in_tensors[0]->TensorC(); - in[1] = &in_tensors[1]->TensorC(); - out[0] = &out_tensors[0]->TensorC(); + for (size_t i = 0; i < in_tensors.size(); i++) { + in[i] = reinterpret_cast(malloc(sizeof(TensorC))); + Tensor2TensorC(in_tensors[i], in[i]); + } + out[0] = reinterpret_cast(malloc(sizeof(TensorC))); + Tensor2TensorC(out_tensors[0], out[0]); } ConvolutionCPUFp32::~ConvolutionCPUFp32() { + if (kernel == nullptr) { + return; + } kernel->release(kernel); free(kernel); + for (size_t i = 0; i < in_tensors_.size(); i++) { + free(in[i]); + } + free(out[0]); } int ConvolutionCPUFp32::Prepare() { - kernel = CreateKernel(parameter, in, 2, out, 1); + kernel = CreateKernel(op_parameter_, in, in_tensors_.size(), out, 1); if (kernel == nullptr) { return -1; } - if (kernel->resize(kernel, in, 2, out, 1) != NNACL_OK) { + auto ret = kernel->resize(kernel, in, in_tensors_.size(), out, 1); + if (ret != NNACL_OK) { return ret; } - return kernel->prepare(kernel, NULL); + return kernel->prepare(kernel); } int ConvolutionCPUFp32::Run() { return kernel->compute(kernel); } -int ConvolutionCPUFp32::Resize() { return kernel->resize(kernel, in, 2, out, 1); } +int ConvolutionCPUFp32::ReSize() { return kernel->resize(kernel, in, in_tensors_.size(), out, 1); } } // namespace mindspore::kernel diff --git a/mindspore/lite/experimental/src/exec_env_utils.cc b/mindspore/lite/experimental/src/exec_env_utils.cc new file mode 100644 index 00000000000..ae716af4ea3 --- /dev/null +++ b/mindspore/lite/experimental/src/exec_env_utils.cc @@ -0,0 +1,46 @@ +/** + * Copyright 2022 Huawei Technologies Co., Ltd + * + * Licensed 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. + */ + +#include "experimental/src/exec_env_utils.h" + +namespace mindspore::lite::experimental { +void *DefaultAllocatorMalloc(void *allocator, size_t sz) { + if (allocator == nullptr || sz == 0) { + MS_LOG(ERROR) << "in param invalid"; + return nullptr; + } + auto default_allocator = static_cast(allocator); + return default_allocator->Malloc(sz); +} + +void DefaultAllocatorFree(void *allocator, void *ptr) { + if (allocator == nullptr || ptr == nullptr) { + MS_LOG(ERROR) << "in param invalid"; + return; + } + auto default_allocator = static_cast(allocator); + return default_allocator->Free(ptr); +} + +int DefaultThreadPoolParallelLunch(void *threadPool, void *task, void *param, int taskNr) { + ThreadPool *pool = static_cast(threadPool); + if (pool == nullptr) { + MS_LOG(ERROR) << "thread pool is nullptr"; + return RET_NULL_PTR; + } + return pool->ParallelLaunch((TaskFunc)task, param, taskNr); +} +} // namespace mindspore::lite::experimental diff --git a/mindspore/lite/experimental/src/exec_env_utils.h b/mindspore/lite/experimental/src/exec_env_utils.h new file mode 100644 index 00000000000..c7784042dc7 --- /dev/null +++ b/mindspore/lite/experimental/src/exec_env_utils.h @@ -0,0 +1,37 @@ +/** + * Copyright 2022 Huawei Technologies Co., Ltd + * + * Licensed 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. + */ + +#ifndef MINDSPORE_LITE_EXPERIMENTAL_SRC_EXEC_ENV_UTILS_H_ +#define MINDSPORE_LITE_EXPERIMENTAL_SRC_EXEC_ENV_UTILS_H_ + +#include "thread/threadpool.h" +#include "src/runtime/inner_allocator.h" +#include "src/common/log_adapter.h" +#include "src/common/log_util.h" + +namespace mindspore::lite::experimental { +#ifdef __cplusplus +extern "C" { +#endif +void *DefaultAllocatorMalloc(void *allocator, size_t sz); +void DefaultAllocatorFree(void *allocator, void *ptr); +int DefaultThreadPoolParallelLunch(void *threadPool, void *task, void *param, int taskNr); +#ifdef __cplusplus +} +#endif +} // namespace mindspore::lite::experimental + +#endif // MINDSPORE_LITE_EXPERIMENTAL_SRC_EXEC_ENV_UTILS_H_ diff --git a/mindspore/lite/src/CMakeLists.txt b/mindspore/lite/src/CMakeLists.txt index 88469f2af9a..6a2dfa448ef 100644 --- a/mindspore/lite/src/CMakeLists.txt +++ b/mindspore/lite/src/CMakeLists.txt @@ -172,10 +172,10 @@ if(MSLITE_ENABLE_CONTROLFLOW) set(LITE_SRC ${LITE_SRC} ${CONTROL_FLOW_SRC}) endif() -if(BUILD_EXPERIMENT) +if(MSLITE_ENABLE_EXPERIMENT_KERNEL) file(GLOB EXPERIMENT_SRC - ${CMAKE_CURRENT_SOURCE_DIR}/../experimental/kernel/*.cc - ) + ${CMAKE_CURRENT_SOURCE_DIR}/../experimental/src/exec_env_utils.cc + ${CMAKE_CURRENT_SOURCE_DIR}/../experimental/kernel/*.cc) set(LITE_SRC ${LITE_SRC} ${EXPERIMENT_SRC}) endif() diff --git a/mindspore/lite/src/inner_context.cc b/mindspore/lite/src/inner_context.cc index 1a9816e7002..5bcdeb6b769 100644 --- a/mindspore/lite/src/inner_context.cc +++ b/mindspore/lite/src/inner_context.cc @@ -28,6 +28,9 @@ #ifdef GPU_OPENCL #include "src/runtime/gpu/opencl/opencl_runtime.h" #endif +#include "nnacl/kernel.h" +#include "src/runtime/inner_allocator.h" +#include "experimental/src/exec_env_utils.h" namespace mindspore::lite { namespace { @@ -108,6 +111,16 @@ void InnerContext::SetContextDevice(const Context *context) { return; } +void InnerContext::InitExperimentExecEnv() { +#ifdef MSLITE_ENABLE_EXPERIMENT_KERNEL + GetExecEnv()->allocator = this->allocator.get(); + GetExecEnv()->threadPool = this->thread_pool_; + GetExecEnv()->alloc = experimental::DefaultAllocatorMalloc; + GetExecEnv()->free = experimental::DefaultAllocatorFree; + GetExecEnv()->parallelLaunch = experimental::DefaultThreadPoolParallelLunch; +#endif +} + int InnerContext::CreateThreadPool() { if (this->thread_pool_ == nullptr) { BindMode bind_mode = Power_NoBind; @@ -170,6 +183,8 @@ int InnerContext::Init() { if (IsGpuEnabled()) { MS_LOG(DEBUG) << "GPU enabled."; } + + InitExperimentExecEnv(); return RET_OK; } diff --git a/mindspore/lite/src/inner_context.h b/mindspore/lite/src/inner_context.h index e1547d812c0..3adbe3994f9 100644 --- a/mindspore/lite/src/inner_context.h +++ b/mindspore/lite/src/inner_context.h @@ -115,6 +115,8 @@ struct InnerContext : public Context { int CreateThreadPool(); + void InitExperimentExecEnv(); + bool device_and_pkg_support_fp16_ = false; #ifdef BFC_MEMORY diff --git a/mindspore/lite/tools/converter/CMakeLists.txt b/mindspore/lite/tools/converter/CMakeLists.txt index f9fbb8375f3..b441908f370 100644 --- a/mindspore/lite/tools/converter/CMakeLists.txt +++ b/mindspore/lite/tools/converter/CMakeLists.txt @@ -138,6 +138,12 @@ if(MSLITE_ENABLE_BFC_MEMORY) ) endif() +if(MSLITE_ENABLE_EXPERIMENT_KERNEL) + set(LITE_SRC ${LITE_SRC} + ${SRC_DIR}/../experimental/src/exec_env_utils.cc) +endif() + + if(MSLITE_ENABLE_SHARING_MODEL_WEIGHT) set(LITE_SRC ${LITE_SRC}