mixed precision scheduler

This commit is contained in:
yoni 2021-06-14 09:16:33 +03:00
parent af16989394
commit 213a6600d1
71 changed files with 1441 additions and 296 deletions

View File

@ -55,3 +55,33 @@ void FusedBatchNormFp16(const void *input, const void *scale, const void *offset
cur_offset += param->channel_;
}
}
void FusedBatchNormFp16MeanVar(const float16_t *input, float16_t *run_mean, float16_t *run_var,
const BatchNormParameter *param, float16_t *save_mean, float16_t *save_var) {
const float N = (float)param->unit_;
const float VN = N;
const float VNUB = (N > 1.0f) ? (N - 1.0f) : 1.0f;
const float momentum = (1.0f - param->momentum_);
for (int i = 0; i < param->unit_; i++) {
for (int c = 0; c < param->channel_; c++) {
int idx = i * param->channel_ + c;
run_mean[c] += input[idx];
}
}
for (int c = 0; c < param->channel_; c++) {
run_mean[c] /= (float16_t)N;
}
for (int i = 0; i < param->unit_; i++) {
for (int c = 0; c < param->channel_; c++) {
int idx = i * param->channel_ + c;
run_var[c] += (float16_t)((float)(input[idx] - run_mean[c]) * (float)(input[idx] - run_mean[c]));
}
}
for (int c = 0; c < param->channel_; c++) {
float unbiased_var = ((float)run_var[c] / VNUB);
run_var[c] = (float16_t)((float)run_var[c] / VN);
save_mean[c] = (float16_t)(momentum * (float)save_mean[c] + (1.0f - momentum) * (float)run_mean[c]);
save_var[c] = (float16_t)(momentum * (float)save_var[c] + (1.0f - momentum) * unbiased_var);
}
}

View File

@ -13,8 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MINDSPORE_NNACL_FP16_BATCHNORM_FP16_H_
#define MINDSPORE_NNACL_FP16_BATCHNORM_FP16_H_
#ifndef MINDSPORE_CCSRC_BACKEND_KERNEL_COMPILER_CPU_NNACL_FP16_BATCHNORM_FP16_H_
#define MINDSPORE_CCSRC_BACKEND_KERNEL_COMPILER_CPU_NNACL_FP16_BATCHNORM_FP16_H_
#include "nnacl/batchnorm_parameter.h"
@ -26,9 +26,10 @@ void BatchNormFp16(const float16_t *input, const void *mean, const void *varianc
int task_id, float16_t *output);
void FusedBatchNormFp16(const void *input, const void *scale, const void *offset, const void *mean,
const void *variance, BatchNormParameter *param, int task_id, void *output);
void FusedBatchNormFp16MeanVar(const float16_t *input, float16_t *run_mean, float16_t *run_var,
const BatchNormParameter *param, float16_t *save_mean, float16_t *save_var);
#ifdef __cplusplus
}
#endif
#endif // MINDSPORE_NNACL_FP16_BATCHNORM_FP16_H_
#endif // MINDSPORE_CCSRC_BACKEND_KERNEL_COMPILER_CPU_NNACL_FP16_BATCHNORM_FP16_H_

View File

@ -47,14 +47,35 @@ inline void Float16ToInt64(const float16_t *input, int64_t *output, int number)
}
#ifdef ENABLE_ARM64
inline void Float32ToFloat16(const float *input, float16_t *output, int number) {
for (int i = 0; i < number; ++i) {
inline void Float32ToFloat16(const float *__restrict input, float16_t *__restrict output, int number) {
int count = (number & ~(C8NUM - 1));
int i = 0;
for (; i < count; i += C8NUM) {
float32x4_t in1 = vld1q_f32(input + i);
float16x4_t out1 = vcvt_f16_f32(in1);
float32x4_t in2 = vld1q_f32(input + i + 4);
float16x4_t out2 = vcvt_f16_f32(in2);
float16x8_t out = vcombine_f16(out1, out2);
vst1q_f16(output + i, out);
}
for (; i < number; ++i) {
output[i] = (float16_t)input[i];
}
}
inline void Float16ToFloat32(const float16_t *input, float *output, int number) {
for (int i = 0; i < number; ++i) {
inline void Float16ToFloat32(const float16_t *__restrict input, float *__restrict output, int number) {
int count = number & ~(C8NUM - 1);
int i = 0;
for (; i < count; i += C8NUM) {
float16x8_t in = vld1q_f16(input + i);
float16x4_t in1 = vget_low_f16(in);
float16x4_t in2 = vget_high_f16(in);
float32x4_t out1 = vcvt_f32_f16(in1);
vst1q_f32(output + i, out1);
float32x4_t out2 = vcvt_f32_f16(in2);
vst1q_f32(output + i + 4, out2);
}
for (; i < number; ++i) {
output[i] = (float)input[i];
}
}

View File

@ -27,7 +27,6 @@ void backwardAllFp16(const float16_t *restrict in, const float16_t *restrict yt,
const float16_t *restrict invar, const float16_t *restrict scale, int size, int ch,
float *restrict dxhat_sum, float *restrict dxhathat_sum, float16_t *restrict dbias,
float16_t *restrict dscale, float16_t *restrict dx) {
float16_t N = (float16_t)size;
for (int i = 0; i < size; i++) {
for (int c = 0; c < ch; c++) {
int ix = i * ch + c;
@ -41,13 +40,14 @@ void backwardAllFp16(const float16_t *restrict in, const float16_t *restrict yt,
dxhathat_sum[c] += (float)(dx_hat * x_hat);
}
}
float N = (float)size;
for (int i = 0; i < size; i++) {
for (int c = 0; c < ch; c++) {
// dx_2
int ix = i * ch + c;
float16_t x_hat = (in[ix] - mean[c]) * invar[c];
float16_t dx_hat = yt[ix] * scale[c];
dx[ix] = 1.0f / N * (float)((invar[c]) * (N * dx_hat - dxhat_sum[c] - x_hat * dxhathat_sum[c]));
dx[ix] = (float16_t)((float)((invar[c]) * (N * dx_hat - dxhat_sum[c] - x_hat * dxhathat_sum[c])) / N);
}
}
}
@ -80,7 +80,7 @@ void backwardP2Fp16(const float16_t *restrict in, const float16_t *restrict yt,
int ix = i * ch + c;
float x_hat = (float)((in[ix] - mean[c]) * invar[c]);
float dx_hat = (float)(yt[ix] * scale[c]);
dx[ix] = (float16_t)(1.0f / N * (float)(invar[c]) * (N * dx_hat - dxhat_sum[c] - x_hat * dxhathat_sum[c]));
dx[ix] = (float16_t)(((float)(invar[c]) * (N * dx_hat - dxhat_sum[c] - x_hat * dxhathat_sum[c])) / N);
}
}
}

View File

@ -16,6 +16,7 @@
#include "nnacl/fp16_grad/convolution_grad_filter.h"
#include "nnacl/intrinsics/ms_simd_instructions_fp16.h"
#include "nnacl/errorcode.h"
#ifdef ENABLE_NEON
#include <arm_neon.h>
#endif
@ -356,5 +357,5 @@ int ConvDwFilterFp16Grad(const float16_t *x, const float16_t *dy, float16_t *dw,
dw[i_c * k_spatial + k_idx] = sum;
}
}
return 0;
return NNACL_OK;
}

View File

@ -0,0 +1,100 @@
/**
* Copyright 2021 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/fp16_grad/convolution_grad_input.h"
#include "nnacl/errorcode.h"
#ifdef ENABLE_ARM
#include <arm_neon.h>
#endif
int ConvDwInputGradFp16(const float16_t *dy, const float16_t *w, float16_t *dx, int start, int count,
const ConvParameter *conv_param) {
int in_h = conv_param->input_h_;
int in_w = conv_param->input_w_;
int out_w = conv_param->output_w_;
int out_ch = conv_param->output_channel_;
int in_ch = conv_param->input_channel_;
int out_spatial = conv_param->output_h_ * conv_param->output_w_;
int k_h = conv_param->kernel_h_;
int k_w = conv_param->kernel_w_;
int k_spatial = k_h * k_w;
int end = start + count;
int j = start;
for (; j <= (end - C4NUM); j += C4NUM) {
float16_t *c = dx + j;
const float16_t *mat_b_0 = w + (j + 0) * k_spatial;
const float16_t *mat_b_1 = w + (j + 1) * k_spatial;
const float16_t *mat_b_2 = w + (j + 2) * k_spatial;
const float16_t *mat_b_3 = w + (j + 3) * k_spatial;
for (int si = 0; si < out_spatial; si++) {
const float16_t *a = dy + j + si * out_ch;
#ifdef ENABLE_ARM
float16x4_t mat_a = vld1_f16(a);
#else
float16_t mat_a[4] = {a[0], a[1], a[2], a[3]};
#endif
int output_row = (si) / out_w;
int output_col = (si) % out_w;
for (int k = 0; k < k_spatial; k++) {
int row_stride_offset = output_row * conv_param->stride_h_;
int col_stride_offset = output_col * conv_param->stride_w_;
int kernel_row = k / k_w;
int kernel_col = k % k_w;
int input_row = -conv_param->pad_u_ + kernel_row * conv_param->dilation_h_ + row_stride_offset;
int input_col = -conv_param->pad_l_ + kernel_col * conv_param->dilation_w_ + col_stride_offset;
if (((unsigned)(input_row) < (unsigned)(in_h)) && ((unsigned)(input_col) < (unsigned)(in_w))) {
int offset = (input_row * in_w + input_col) * in_ch;
#ifdef ENABLE_ARM
float16x4_t mat_b = {mat_b_0[k], mat_b_1[k], mat_b_2[k], mat_b_3[k]};
float16x4_t mat_c = vld1_f16(c + offset);
mat_c = vfma_f16(mat_c, mat_b, mat_a);
vst1_f16(c + offset, mat_c);
#else
c[offset + 0] += mat_a[0] * mat_b_0[k];
c[offset + 1] += mat_a[1] * mat_b_1[k];
c[offset + 2] += mat_a[2] * mat_b_2[k];
c[offset + 3] += mat_a[3] * mat_b_3[k];
#endif
}
}
}
}
for (; j < end; j++) {
float16_t *c = dx + j;
const float16_t *b = w + j * k_spatial;
for (int si = 0; si < out_spatial; si++) {
const float16_t *a = dy + j + si * out_ch;
int output_row = si / out_w;
int output_col = si % out_w;
int row_stride_offset = output_row * conv_param->stride_h_;
int col_stride_offset = output_col * conv_param->stride_w_;
for (int k = 0; k < k_spatial; k++) {
int kernel_row = k / k_w;
int kernel_col = k % k_w;
int input_row = -conv_param->pad_u_ + kernel_row * conv_param->dilation_h_ + row_stride_offset;
int input_col = -conv_param->pad_l_ + kernel_col * conv_param->dilation_w_ + col_stride_offset;
if (((unsigned)(input_row) < (unsigned)(in_h)) && ((unsigned)(input_col) < (unsigned)(in_w))) {
int offset = (input_row * in_w + input_col) * in_ch;
c[offset] += a[0] * b[k];
}
}
}
}
return NNACL_OK;
}

View File

@ -0,0 +1,33 @@
/**
* Copyright 2021 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_FP32_GRAD_CONVOLUTION_GRAD_INPUT_H_
#define MINDSPORE_NNACL_FP32_GRAD_CONVOLUTION_GRAD_INPUT_H_
#include <stddef.h>
#include "nnacl/conv_parameter.h"
#ifdef __cplusplus
extern "C" {
#endif
int ConvDwInputGradFp16(const float16_t *dy, const float16_t *w, float16_t *dx, int start, int count,
const ConvParameter *conv_param);
#ifdef __cplusplus
}
#endif
#endif // MINDSPORE_NNACL_FP32_GRAD_CONVOLUTION_GRAD_INPUT_H_

View File

@ -15,6 +15,7 @@
*/
#include "nnacl/fp32_grad/convolution_grad_filter.h"
#include "nnacl/errorcode.h"
#ifdef ENABLE_ARM
#include <arm_neon.h>
#endif
@ -375,5 +376,5 @@ int ConvDwFilterGrad(const float *x, const float *dy, float *dw, int start, int
dw[i_c * k_spatial + k_idx] = sum;
}
}
return 0;
return NNACL_OK;
}

View File

@ -0,0 +1,99 @@
/**
* Copyright 2021 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/fp32_grad/convolution_grad_input.h"
#include "nnacl/errorcode.h"
#ifdef ENABLE_ARM
#include <arm_neon.h>
#endif
int ConvDwInputGrad(const float *dy, const float *w, float *dx, int start, int count, const ConvParameter *conv_param) {
int in_h = conv_param->input_h_;
int in_w = conv_param->input_w_;
int out_w = conv_param->output_w_;
int out_ch = conv_param->output_channel_;
int in_ch = conv_param->input_channel_;
int out_spatial = conv_param->output_h_ * conv_param->output_w_;
int k_h = conv_param->kernel_h_;
int k_w = conv_param->kernel_w_;
int k_spatial = k_h * k_w;
int end = start + count;
int j = start;
for (; j <= (end - C4NUM); j += C4NUM) {
float *c = dx + j;
const float *mat_b_0 = w + (j + 0) * k_spatial;
const float *mat_b_1 = w + (j + 1) * k_spatial;
const float *mat_b_2 = w + (j + 2) * k_spatial;
const float *mat_b_3 = w + (j + 3) * k_spatial;
for (int si = 0; si < out_spatial; si++) {
const float *a = dy + j + si * out_ch;
#ifdef ENABLE_ARM
float32x4_t mat_a = vld1q_f32(a);
#else
float mat_a[4] = {a[0], a[1], a[2], a[3]};
#endif
int output_row = (si) / out_w;
int output_col = (si) % out_w;
for (int k = 0; k < k_spatial; k++) {
int row_stride_offset = output_row * conv_param->stride_h_;
int col_stride_offset = output_col * conv_param->stride_w_;
int kernel_row = k / k_w;
int kernel_col = k % k_w;
int input_row = -conv_param->pad_u_ + kernel_row * conv_param->dilation_h_ + row_stride_offset;
int input_col = -conv_param->pad_l_ + kernel_col * conv_param->dilation_w_ + col_stride_offset;
if (((unsigned)(input_row) < (unsigned)(in_h)) && ((unsigned)(input_col) < (unsigned)(in_w))) {
int offset = (input_row * in_w + input_col) * in_ch;
#ifdef ENABLE_ARM
float32x4_t mat_b = {mat_b_0[k], mat_b_1[k], mat_b_2[k], mat_b_3[k]};
float32x4_t mat_c = vld1q_f32(c + offset);
mat_c = vmlaq_f32(mat_c, mat_b, mat_a);
vst1q_f32(c + offset, mat_c);
#else
c[offset + 0] += mat_a[0] * mat_b_0[k];
c[offset + 1] += mat_a[1] * mat_b_1[k];
c[offset + 2] += mat_a[2] * mat_b_2[k];
c[offset + 3] += mat_a[3] * mat_b_3[k];
#endif
}
}
}
}
for (; j < end; j++) {
float *c = dx + j;
const float *b = w + j * k_spatial;
for (int si = 0; si < out_spatial; si++) {
const float *a = dy + j + si * out_ch;
int output_row = si / out_w;
int output_col = si % out_w;
int row_stride_offset = output_row * conv_param->stride_h_;
int col_stride_offset = output_col * conv_param->stride_w_;
for (int k = 0; k < k_spatial; k++) {
int kernel_row = k / k_w;
int kernel_col = k % k_w;
int input_row = -conv_param->pad_u_ + kernel_row * conv_param->dilation_h_ + row_stride_offset;
int input_col = -conv_param->pad_l_ + kernel_col * conv_param->dilation_w_ + col_stride_offset;
if (((unsigned)(input_row) < (unsigned)(in_h)) && ((unsigned)(input_col) < (unsigned)(in_w))) {
int offset = (input_row * in_w + input_col) * in_ch;
c[offset] += a[0] * b[k];
}
}
}
}
return NNACL_OK;
}

View File

@ -0,0 +1,32 @@
/**
* Copyright 2021 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_FP32_GRAD_CONVOLUTION_GRAD_INPUT_H_
#define MINDSPORE_NNACL_FP32_GRAD_CONVOLUTION_GRAD_INPUT_H_
#include <stddef.h>
#include "nnacl/conv_parameter.h"
#ifdef __cplusplus
extern "C" {
#endif
int ConvDwInputGrad(const float *dy, const float *w, float *dx, int start, int count, const ConvParameter *conv_param);
#ifdef __cplusplus
}
#endif
#endif // MINDSPORE_NNACL_FP32_GRAD_CONVOLUTION_GRAD_INPUT_H_

View File

@ -105,10 +105,11 @@ message(STATUS "\tMSLITE_ENABLE_TOOLS = \t${MSLITE_ENABLE_TOOLS}")
message(STATUS "\tMSLITE_ENABLE_TESTCASES = \t${MSLITE_ENABLE_TESTCASES}")
if(ENABLE_ASAN)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fsanitize-recover=address -fno-omit-frame-pointer")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fsanitize-recover=address -fno-omit-frame-pointer")
add_definitions(-fsanitize=address -fno-omit-frame-pointer -mllvm -asan-use-private-alias=1)
add_link_options(-fsanitize=address)
endif()
set(PKG_NAME_PREFIX mindspore-lite-${MS_VERSION_MAJOR}.${MS_VERSION_MINOR}.${MS_VERSION_REVISION})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
set(BUILD_MINDDATA "lite_cv" CACHE STRING "off, lite, lite_cv, wrapper or full")

View File

@ -23,7 +23,7 @@ from mindspore import context, Tensor, nn
from mindspore.train.serialization import export
context.set_context(mode=context.PYNATIVE_MODE, device_target="GPU", save_graphs=False)
batch = 16
batch = 8
backbone_net = MobileNetV2Backbone()
head_net = MobileNetV2Head(input_channel=backbone_net.out_channels, num_classes=10)

View File

@ -14,8 +14,8 @@ OBJ:=$(SRC:.cc=.o)
CFLAGS := -Ofast -std=c++17 \
-I . \
-I ./msl/train \
-I ./msl/train/minddata \
-I ./msl/inference \
-I ./msl/inference/minddata \
-I ./msl/tools/third_party/flatbuffers/include

View File

@ -14,6 +14,7 @@
# ============================================================================
"""lenet_export."""
import sys
import numpy as np
from mindspore import context, Tensor
import mindspore.common.dtype as mstype
@ -21,11 +22,12 @@ from mindspore.train.serialization import export
from lenet import LeNet5
from train_utils import train_wrap
n = LeNet5()
n.set_train()
context.set_context(mode=context.PYNATIVE_MODE, device_target="CPU", save_graphs=False)
BATCH_SIZE = 32
BATCH_SIZE = int(sys.argv[1])
x = Tensor(np.ones((BATCH_SIZE, 1, 32, 32)), mstype.float32)
label = Tensor(np.zeros([BATCH_SIZE]).astype(np.int32))
net = train_wrap(n)

View File

@ -1,12 +1,12 @@
#!/bin/bash
echo "============Exporting=========="
if [ -n "$1" ]; then
DOCKER_IMG=$1
docker run -w $PWD --runtime=nvidia -v /home/$USER:/home/$USER --privileged=true ${DOCKER_IMG} /bin/bash -c "PYTHONPATH=../../../../../model_zoo/official/cv/lenet/src python lenet_export.py; chmod 444 lenet_tod.mindir; rm -rf __pycache__"
if [ -n "$2" ]; then
DOCKER_IMG=$2
docker run -w $PWD --runtime=nvidia -v /home/$USER:/home/$USER --privileged=true ${DOCKER_IMG} /bin/bash -c "PYTHONPATH=../../../../../model_zoo/official/cv/lenet/src python lenet_export.py '$1'; chmod 444 lenet_tod.mindir; rm -rf __pycache__"
else
echo "MindSpore docker was not provided, attempting to run locally"
PYTHONPATH=../../../../../model_zoo/official/cv/lenet/src python lenet_export.py
PYTHONPATH=../../../../../model_zoo/official/cv/lenet/src python lenet_export.py $1
fi

View File

@ -2,7 +2,7 @@
display_usage()
{
echo -e "\nUsage: prepare_and_run.sh -D dataset_path [-d mindspore_docker] [-r release.tar.gz] [-t arm64|x86] [-q]\n"
echo -e "\nUsage: prepare_and_run.sh -D dataset_path [-d mindspore_docker] [-r release.tar.gz] [-t arm64|x86] [-q] [-o] [-b virtual_batch]\n"
}
checkopts()
@ -11,7 +11,9 @@ checkopts()
DOCKER=""
MNIST_DATA_PATH=""
QUANTIZE=""
while getopts 'D:d:r:t:q' opt
ENABLEFP16=false
VIRTUAL_BATCH=-1
while getopts 'D:d:r:t:qob:' opt
do
case "${opt}" in
D)
@ -35,6 +37,12 @@ checkopts()
q)
QUANTIZE="QUANTIZE"
;;
o)
ENABLEFP16=true
;;
b)
VIRTUAL_BATCH=$OPTARG
;;
*)
echo "Unknown option ${opt}!"
display_usage
@ -65,10 +73,18 @@ if [ "$TARBALL" == "" ]; then
fi
fi
# Prepare the model
if [[ "${VIRTUAL_BATCH}" == "-1" ]]; then
BATCH=32
else
BATCH=1
fi
cd model/ || exit 1
rm -f *.ms
QUANTIZE=${QUANTIZE} ./prepare_model.sh $DOCKER || exit 1
QUANTIZE=${QUANTIZE} ./prepare_model.sh $BATCH $DOCKER || exit 1
cd ../
# Copy the .ms model to the package folder
@ -84,11 +100,11 @@ cp scripts/*.sh ${PACKAGE}/
# Copy the shared MindSpore ToD library
tar -xzf ${TARBALL}
mv mindspore-*/train/lib ${PACKAGE}/
mv mindspore-*/train/third_party/libjpeg-turbo/lib/* ${PACKAGE}/lib/
mv mindspore-*/inference/lib ${PACKAGE}/
mv mindspore-*/inference/third_party/libjpeg-turbo/lib/* ${PACKAGE}/lib/
if [ "${TARGET}" == "arm64" ]; then
tar -xzf ${TARBALL} --wildcards --no-anchored hiai_ddk
mv mindspore-*/train/third_party/hiai_ddk/lib/* ${PACKAGE}/lib/
mv mindspore-*/inference/third_party/hiai_ddk/lib/* ${PACKAGE}/lib/
fi
rm -rf msl
@ -111,11 +127,21 @@ if [ "${TARGET}" == "arm64" ]; then
adb push ${PACKAGE} /data/local/tmp/
echo "========Training on Device====="
adb shell "cd /data/local/tmp/package-arm64 && /system/bin/sh train.sh"
if "$ENABLEFP16"; then
echo "Training fp16.."
adb shell "cd /data/local/tmp/package-arm64 && /system/bin/sh train.sh -o -b ${VIRTUAL_BATCH}"
else
adb shell "cd /data/local/tmp/package-arm64 && /system/bin/sh train.sh -b ${VIRTUAL_BATCH}"
fi
echo
echo "===Evaluating trained Model====="
adb shell "cd /data/local/tmp/package-arm64 && /system/bin/sh eval.sh"
if "$ENABLEFP16"; then
echo "Evaluating fp16 Model.."
adb shell "cd /data/local/tmp/package-arm64 && /system/bin/sh eval.sh -o"
else
adb shell "cd /data/local/tmp/package-arm64 && /system/bin/sh eval.sh"
fi
echo
else
cd ${PACKAGE} || exit 1
@ -124,6 +150,7 @@ else
echo "===Evaluating trained Model====="
./eval.sh
cd ..
fi

View File

@ -15,4 +15,4 @@
# ============================================================================
# an simple tutorial as follows, more parameters can be setting
LD_LIBRARY_PATH=./lib/ bin/net_runner -f model/lenet_tod_trained.ms -e 0 -d dataset
LD_LIBRARY_PATH=./lib/ bin/net_runner -f model/lenet_tod_trained.ms -e 0 -d dataset $1

View File

@ -15,4 +15,4 @@
# ============================================================================
# an simple tutorial as follows, more parameters can be setting
LD_LIBRARY_PATH=./lib/ bin/net_runner -f model/lenet_tod.ms -e 5 -d dataset
LD_LIBRARY_PATH=./lib/ bin/net_runner -f model/lenet_tod.ms -e 5 -d dataset $1 $2 $3

View File

@ -51,7 +51,7 @@ constexpr int kNCHWDims = 4;
constexpr int kNCHWCDim = 2;
constexpr int kPrintTimes = 100;
constexpr int kSaveSteps = 1000;
constexpr float kLearningRate = 0.7f;
constexpr float kGammaFactor = 0.7f;
class Rescaler : public mindspore::session::TrainLoopCallBack {
public:
explicit Rescaler(float scale) : scale_(scale) {
@ -70,6 +70,36 @@ class Rescaler : public mindspore::session::TrainLoopCallBack {
float scale_ = 1.0;
};
class Measurement : public mindspore::session::TrainLoopCallBack {
public:
explicit Measurement(unsigned int epochs)
: epochs_(epochs), time_avg_(std::chrono::duration<double, std::milli>(0)) {}
~Measurement() override = default;
void EpochBegin(const mindspore::session::TrainLoopCallBackData &cb_data) override {
start_time_ = std::chrono::high_resolution_clock::now();
}
int EpochEnd(const mindspore::session::TrainLoopCallBackData &cb_data) override {
end_time_ = std::chrono::high_resolution_clock::now();
auto time = std::chrono::duration<double, std::milli>(end_time_ - start_time_);
time_avg_ += time;
return mindspore::session::RET_CONTINUE;
}
void End(const mindspore::session::TrainLoopCallBackData &cb_data) override {
if (epochs_ > 0) {
std::cout << "AvgRunTime: " << time_avg_.count() / epochs_ << " ms" << std::endl;
}
struct mallinfo info = mallinfo();
std::cout << "Total allocation: " << info.arena + info.hblkhd << std::endl;
}
private:
std::chrono::time_point<std::chrono::high_resolution_clock> start_time_;
std::chrono::time_point<std::chrono::high_resolution_clock> end_time_;
std::chrono::duration<double, std::milli> time_avg_;
unsigned int epochs_;
};
// Definition of verbose callback function after forwarding operator.
bool after_callback(const std::vector<mindspore::tensor::MSTensor *> &after_inputs,
const std::vector<mindspore::tensor::MSTensor *> &after_outputs,
@ -106,12 +136,14 @@ NetRunner::~NetRunner() {
void NetRunner::InitAndFigureInputs() {
mindspore::lite::Context context;
context.device_list_[0].device_info_.cpu_device_info_.cpu_bind_mode_ = mindspore::lite::NO_BIND;
context.device_list_[0].device_info_.cpu_device_info_.enable_float16_ = false;
context.device_list_[0].device_info_.cpu_device_info_.enable_float16_ = enable_fp16_;
context.device_list_[0].device_type_ = mindspore::lite::DT_CPU;
context.thread_num_ = 2;
session_ = mindspore::session::LiteSession::CreateTrainSession(ms_file_, &context, true);
MS_ASSERT(session_ != nullptr);
session_->SetupVirtualBatch(virtual_batch_);
loop_ = mindspore::session::TrainLoop::CreateTrainLoop(session_);
if (verbose_) {
@ -143,7 +175,7 @@ float NetRunner::CalculateAccuracy(int max_tests) {
Rescaler rescale(kScalePoint);
loop_->Eval(test_ds_.get(), std::vector<TrainLoopCallBack *>{&rescale});
std::cout << "Eval Accuracy is " << acc_metrics_->Eval() << std::endl;
std::cout << "Accuracy is " << acc_metrics_->Eval() << std::endl;
return 0.0;
}
@ -171,15 +203,22 @@ int NetRunner::InitDB() {
}
int NetRunner::TrainLoop() {
struct mindspore::lite::StepLRLambda step_lr_lambda(1, kLearningRate);
mindspore::lite::LRScheduler step_lr_sched(mindspore::lite::StepLRLambda, static_cast<void *>(&step_lr_lambda), 1);
mindspore::lite::LossMonitor lm(kPrintTimes);
mindspore::lite::ClassificationTrainAccuracyMonitor am(1);
mindspore::lite::CkptSaver cs(kSaveSteps, std::string("lenet"));
Rescaler rescale(kScalePoint);
Measurement measure(epochs_);
if (virtual_batch_ > 0) {
loop_->Train(epochs_, train_ds_.get(), std::vector<TrainLoopCallBack *>{&rescale, &lm, &cs, &am, &measure});
} else {
struct mindspore::lite::StepLRLambda step_lr_lambda(1, kGammaFactor);
mindspore::lite::LRScheduler step_lr_sched(mindspore::lite::StepLRLambda, static_cast<void *>(&step_lr_lambda), 1);
loop_->Train(epochs_, train_ds_.get(),
std::vector<TrainLoopCallBack *>{&rescale, &lm, &cs, &am, &step_lr_sched, &measure});
}
loop_->Train(epochs_, train_ds_.get(), std::vector<TrainLoopCallBack *>{&rescale, &lm, &cs, &am, &step_lr_sched});
return 0;
}
@ -206,7 +245,7 @@ void NetRunner::Usage() {
bool NetRunner::ReadArgs(int argc, char *argv[]) {
int opt;
while ((opt = getopt(argc, argv, "f:e:d:s:ihc:v")) != -1) {
while ((opt = getopt(argc, argv, "f:e:d:s:ihc:vob:")) != -1) {
switch (opt) {
case 'f':
ms_file_ = std::string(optarg);
@ -223,6 +262,13 @@ bool NetRunner::ReadArgs(int argc, char *argv[]) {
case 's':
save_checkpoint_ = atoi(optarg);
break;
case 'o':
enable_fp16_ = true;
break;
case 'b':
virtual_batch_ = atoi(optarg);
std::cout << "virtual_batch_: " << virtual_batch_ << std::endl;
break;
case 'h':
default:
Usage();

View File

@ -57,6 +57,8 @@ class NetRunner {
std::string data_dir_ = "";
unsigned int epochs_ = 10;
bool verbose_ = false;
bool enable_fp16_ = false;
int virtual_batch_ = -1;
int save_checkpoint_ = 0;
int batch_size_ = 32;
int h_ = 32;

View File

@ -42,10 +42,10 @@ class MixPrecisionCfg {
this->num_of_not_nan_iter_th_ = rhs.num_of_not_nan_iter_th_;
return *this;
}
bool dynamic_loss_scale_; /**< Enable\disable dynamic loss scale during mix precision training */
float loss_scale_; /**< Initial loss scale factor */
bool keep_batchnorm_fp32_; /**< Keep batch norm in FP32 while training */
int num_of_not_nan_iter_th_; /**< a threshold for modifying loss scale when dynamic loss scale is enabled */
bool dynamic_loss_scale_ = false; /**< Enable\disable dynamic loss scale during mix precision training */
float loss_scale_; /**< Initial loss scale factor */
bool keep_batchnorm_fp32_ = true; /**< Keep batch norm in FP32 while training */
uint32_t num_of_not_nan_iter_th_; /**< a threshold for modifying loss scale when dynamic loss scale is enabled */
};
/// \brief TrainCfg defined for holding train configuration.

View File

@ -25,21 +25,21 @@ namespace mindspore::kernel {
using mindspore::lite::RET_ERROR;
using mindspore::lite::RET_OK;
void *InnerKernel::workspace_ = nullptr;
void InnerKernel::AllocWorkspace(size_t size) {
if (size == 0) {
void InnerKernel::AllocWorkspace() {
workspace_ = malloc(workspace_size());
if (workspace_ == nullptr) {
MS_LOG(ERROR) << "fail to alloc " << workspace_size() << "in kernel" << name();
return;
}
workspace_ = malloc(size);
if (workspace_ == nullptr) {
MS_LOG(ERROR) << "fail to alloc " << size;
}
ws_allocated_ = true;
}
void InnerKernel::FreeWorkspace() {
free(workspace_);
if (ws_allocated_) {
free(workspace_);
}
workspace_ = nullptr;
ws_allocated_ = false;
}
int InnerKernel::PreProcess() {

View File

@ -46,6 +46,7 @@ class InnerKernel : public Kernel {
if (op_parameter_ != nullptr) {
free(op_parameter_);
op_parameter_ = nullptr;
FreeWorkspace();
}
}
@ -77,7 +78,7 @@ class InnerKernel : public Kernel {
ret = PostProcess();
if (lite::RET_OK != ret) {
MS_LOG(ERROR) << "run kernel PreProcess failed, name: " << this->name();
MS_LOG(ERROR) << "run kernel PostProcess failed, name: " << this->name();
return ret;
}
return lite::RET_OK;
@ -192,9 +193,15 @@ class InnerKernel : public Kernel {
void set_workspace_size(size_t value) { workspace_size_ = value; }
size_t workspace_size() { return workspace_size_; }
static void AllocWorkspace(size_t size);
static void FreeWorkspace();
void AllocWorkspace();
void FreeWorkspace();
void *workspace() { return workspace_; }
void set_workspace(void *ws) {
if (ws_allocated_ == false) {
workspace_ = ws;
}
}
bool ws_allocated_ = false;
protected:
OpParameter *op_parameter_ = nullptr;
@ -205,7 +212,7 @@ class InnerKernel : public Kernel {
bool trainable_ = false; // parameters of this Kernel are trained in Train Session
TypeId registry_data_type_ = kTypeUnknown;
size_t workspace_size_ = 0;
static void *workspace_;
void *workspace_ = nullptr;
};
} // namespace mindspore::kernel

View File

@ -496,6 +496,7 @@ int LiteSession::CompileGraph(Model *model) {
#else
Scheduler scheduler(context_, model, &tensors_, is_train_session_, delegate_);
#endif
scheduler.SetupSchedulerCb(std::move(sched_cb_));
ret = scheduler.Schedule(&kernels_);
if (ret != RET_OK) {
MS_LOG(ERROR) << "Schedule kernels failed: " << ret;

View File

@ -41,6 +41,7 @@
#elif GPU_VULKAN
#include "src/runtime/gpu/vulkan/vulkan_runtime.h"
#endif
#include "src/scheduler_cb.h"
namespace mindspore {
namespace lite {
@ -151,6 +152,7 @@ class LiteSession : public session::LiteSession {
#elif GPU_VULKAN
gpu::GpuRuntimeWrapper<vulkan::VulkanRuntime> *vk_runtime_wrap_{nullptr};
#endif
std::unique_ptr<SchedulerCb> sched_cb_;
std::shared_ptr<Delegate> delegate_ = nullptr;
};
} // namespace lite

View File

@ -58,12 +58,14 @@ class ConvolutionBaseCPUKernel : public InnerKernel {
void FreeQuantParam();
protected:
bool is_repack() { return is_repack_; }
void *bias_data_ = nullptr;
const InnerContext *ctx_ = nullptr;
ConvParameter *conv_param_ = nullptr;
ConvQuantArg *conv_quant_arg_ = nullptr;
int tile_num_ = 0;
int thread_count_ = 1;
bool is_repack_ = false;
};
} // namespace mindspore::kernel

View File

@ -81,6 +81,7 @@ REG_KERNEL(kCPU, kNumberTypeFloat16, PrimitiveType_Reshape, LiteKernelCreator<Re
REG_KERNEL(kCPU, kNumberTypeBool, PrimitiveType_Reshape, LiteKernelCreator<ReshapeBaseCPUKernel>)
REG_KERNEL(kCPU, kNumberTypeFloat16, PrimitiveType_Flatten, LiteKernelCreator<ReshapeBaseCPUKernel>)
REG_KERNEL(kCPU, kNumberTypeFloat32, PrimitiveType_Flatten, LiteKernelCreator<ReshapeBaseCPUKernel>)
REG_KERNEL(kCPU, kNumberTypeFloat16, PrimitiveType_FlattenGrad, LiteKernelCreator<ReshapeBaseCPUKernel>)
REG_KERNEL(kCPU, kNumberTypeFloat32, PrimitiveType_FlattenGrad, LiteKernelCreator<ReshapeBaseCPUKernel>)
REG_KERNEL(kCPU, kNumberTypeInt32, PrimitiveType_ExpandDims, LiteKernelCreator<ReshapeBaseCPUKernel>)
REG_KERNEL(kCPU, kNumberTypeFloat16, PrimitiveType_ExpandDims, LiteKernelCreator<ReshapeBaseCPUKernel>)

View File

@ -37,7 +37,8 @@ int ActivationFp16CPUKernel::Init() {
if (type_ != schema::ActivationType_RELU && type_ != schema::ActivationType_RELU6 &&
type_ != schema::ActivationType_LEAKY_RELU && type_ != schema::ActivationType_SIGMOID &&
type_ != schema::ActivationType_TANH && type_ != schema::ActivationType_HSWISH &&
type_ != schema::ActivationType_SWISH && type_ != schema::ActivationType_HARD_TANH) {
type_ != schema::ActivationType_SWISH && type_ != schema::ActivationType_HARD_TANH &&
type_ != schema::ActivationType_GELU) {
MS_LOG(ERROR) << "Activation fp16 not support type: " << type_;
return RET_ERROR;
}

View File

@ -39,6 +39,7 @@ using mindspore::schema::PrimitiveType_Maximum;
using mindspore::schema::PrimitiveType_Minimum;
using mindspore::schema::PrimitiveType_MulFusion;
using mindspore::schema::PrimitiveType_NotEqual;
using mindspore::schema::PrimitiveType_RealDiv;
using mindspore::schema::PrimitiveType_SquaredDifference;
using mindspore::schema::PrimitiveType_SubFusion;
@ -105,6 +106,9 @@ void ArithmeticFP16CPUKernel::InitRunFunction(int primitive_type) {
{PrimitiveType_DivFusion, schema::ActivationType_RELU, ElementDivReluFp16, ElementOptDivReluFp16},
{PrimitiveType_DivFusion, schema::ActivationType_RELU6, ElementDivRelu6Fp16, ElementOptDivRelu6Fp16},
{PrimitiveType_DivFusion, schema::ActivationType_NO_ACTIVATION, ElementDivFp16, ElementOptDivFp16},
{PrimitiveType_RealDiv, schema::ActivationType_RELU, ElementDivReluFp16, ElementOptDivReluFp16},
{PrimitiveType_RealDiv, schema::ActivationType_RELU6, ElementDivRelu6Fp16, ElementOptDivRelu6Fp16},
{PrimitiveType_RealDiv, schema::ActivationType_NO_ACTIVATION, ElementDivFp16, ElementOptDivFp16},
{PrimitiveType_FloorMod, schema::ActivationType_NO_ACTIVATION, ElementFloorModFp16, ElementOptFloorModFp16},
{PrimitiveType_FloorDiv, schema::ActivationType_NO_ACTIVATION, ElementFloorDivFp16, ElementOptFloorDivFp16},
{PrimitiveType_LogicalAnd, schema::ActivationType_NO_ACTIVATION, ElementLogicalAndFp16, ElementOptLogicalAndFp16},
@ -214,5 +218,6 @@ REG_KERNEL(kCPU, kNumberTypeFloat16, PrimitiveType_LogicalOr, LiteKernelCreator<
REG_KERNEL(kCPU, kNumberTypeFloat16, PrimitiveType_Maximum, LiteKernelCreator<ArithmeticFP16CPUKernel>)
REG_KERNEL(kCPU, kNumberTypeFloat16, PrimitiveType_Minimum, LiteKernelCreator<ArithmeticFP16CPUKernel>)
REG_KERNEL(kCPU, kNumberTypeFloat16, PrimitiveType_Eltwise, LiteKernelCreator<ArithmeticFP16CPUKernel>)
REG_KERNEL(kCPU, kNumberTypeFloat16, PrimitiveType_RealDiv, LiteKernelCreator<ArithmeticFP16CPUKernel>)
REG_KERNEL(kCPU, kNumberTypeFloat16, PrimitiveType_SquaredDifference, LiteKernelCreator<ArithmeticFP16CPUKernel>)
} // namespace mindspore::kernel

View File

@ -52,6 +52,12 @@ int BiasAddCPUFp16Kernel::Run() {
return ret;
}
}
if (op_parameter_->is_train_session_) {
if ((is_trainable() && (IsTrain() || is_repack())) || (bias_data_type_ == kNumberTypeFloat16)) {
PackWeight();
is_repack_ = false;
}
}
auto in = reinterpret_cast<float16_t *>(in_tensors_.at(0)->MutableData());
auto out = reinterpret_cast<float16_t *>(out_tensors_.at(0)->MutableData());
size_t data_size = in_tensors_.at(0)->ElementsNum();
@ -80,10 +86,12 @@ BiasAddCPUFp16Kernel::~BiasAddCPUFp16Kernel() {
int BiasAddCPUFp16Kernel::GetBiasData() {
bias_data_type_ = bias_tensor_->data_type();
if (bias_data_type_ == kNumberTypeFloat || bias_data_type_ == kNumberTypeFloat32) {
bias_data_ = reinterpret_cast<float16_t *>(malloc(bias_tensor_->ElementsNum() * sizeof(float16_t)));
if (bias_data_ == nullptr) {
MS_LOG(ERROR) << "bias_data_ is nullptr";
return RET_NULL_PTR;
bias_data_ = reinterpret_cast<float16_t *>(malloc(bias_tensor_->ElementsNum() * sizeof(float16_t)));
if (bias_data_ == nullptr) {
MS_LOG(ERROR) << "bias_data_ is nullptr";
return RET_NULL_PTR;
}
}
auto bias = reinterpret_cast<float *>(bias_tensor_->MutableData());
if (bias == nullptr) {
@ -91,7 +99,7 @@ int BiasAddCPUFp16Kernel::GetBiasData() {
return RET_NULL_PTR;
}
for (int i = 0; i < bias_tensor_->ElementsNum(); ++i) {
bias_data_[i] = (float16_t)(bias[i]);
bias_data_[i] = static_cast<float16_t>(bias[i]);
}
} else {
bias_data_ = reinterpret_cast<float16_t *>(bias_tensor_->MutableData());
@ -106,18 +114,30 @@ int BiasAddCPUFp16Kernel::GetBiasData() {
int BiasAddCPUFp16Kernel::Init() {
bias_tensor_ = in_tensors_.at(1);
MS_ASSERT(bias_tensor_ != nullptr);
if (bias_tensor_->IsConst()) {
auto ret = GetBiasData();
if (ret != RET_OK) {
MS_LOG(ERROR) << "GetBiasData is error in Init()!";
return ret;
}
}
if (!InferShapeDone()) {
return RET_OK;
}
return ReSize();
}
void BiasAddCPUFp16Kernel::PackWeight() {
if (bias_data_type_ == kNumberTypeFloat || bias_data_type_ == kNumberTypeFloat32) {
auto bias = reinterpret_cast<float *>(bias_tensor_->data_c());
for (int i = 0; i < bias_tensor_->ElementsNum(); ++i) {
bias_data_[i] = static_cast<float16_t>(bias[i]);
}
} else {
bias_data_ = reinterpret_cast<float16_t *>(bias_tensor_->data_c());
}
}
int BiasAddCPUFp16Kernel::Eval() {
InnerKernel::Eval();
if (is_trainable()) {
is_repack_ = true;
}
return RET_OK;
}
REG_KERNEL(kCPU, kNumberTypeFloat16, PrimitiveType_BiasAdd, LiteKernelCreator<BiasAddCPUFp16Kernel>)
} // namespace mindspore::kernel

View File

@ -14,8 +14,8 @@
* limitations under the License.
*/
#ifndef MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_FP16_BIASADD_H_
#define MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_FP16_BIASADD_H_
#ifndef MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_FP16_BIASADD_FP16_H_
#define MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_FP16_BIASADD_FP16_H_
#include <vector>
#include "src/inner_kernel.h"
#include "nnacl/fp16/arithmetic_fp16.h"
@ -33,14 +33,18 @@ class BiasAddCPUFp16Kernel : public InnerKernel {
int Init() override;
int ReSize() override;
int Run() override;
int Eval() override;
private:
int GetBiasData();
void PackWeight();
bool is_repack() { return is_repack_; }
ArithmeticParameter *bias_param_ = nullptr;
float16_t *bias_data_ = nullptr;
lite::Tensor *bias_tensor_ = nullptr;
TypeId bias_data_type_;
bool is_repack_ = false;
};
} // namespace mindspore::kernel
#endif // MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_FP16_BIASADD_H_
#endif // MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_FP16_BIASADD_FP16_H_

View File

@ -90,24 +90,31 @@ int Convolution1x1FP16CPUKernel::InitWeightBias() {
if (in_tensors_.size() == 3) {
size_t size = UP_ROUND(output_channel, col_tile_) * sizeof(float16_t);
size_t bias_size = output_channel * sizeof(float16_t);
bias_data_ = malloc(size);
if (bias_data_ == nullptr) {
MS_LOG(ERROR) << "Conv1x1 Malloc bias_ptr_ error!";
return RET_ERROR;
bias_data_ = malloc(size);
if (bias_data_ == nullptr) {
MS_LOG(ERROR) << "Conv1x1 Malloc bias_ptr_ error!";
return RET_ERROR;
}
}
memcpy(bias_data_, origin_bias_, output_channel * sizeof(float16_t));
void *bias_origin_tmp = is_trainable() ? in_tensors_.at(2)->data_c() : origin_bias_;
memcpy(bias_data_, bias_origin_tmp, output_channel * sizeof(float16_t));
memset(reinterpret_cast<char *>(bias_data_) + bias_size, 0, size - bias_size);
}
size_t size = input_channel * UP_ROUND(output_channel, col_tile_) * sizeof(float16_t);
size_t down_size = input_channel * DOWN_DIV(output_channel, col_tile_) * col_tile_ * sizeof(float16_t);
weight_ptr_ = reinterpret_cast<float16_t *>(malloc(size));
if (weight_ptr_ == nullptr) {
MS_LOG(ERROR) << "Conv1x1 Malloc weight_ptr_ error!";
return RET_ERROR;
weight_ptr_ = reinterpret_cast<float16_t *>(malloc(size));
if (weight_ptr_ == nullptr) {
MS_LOG(ERROR) << "Conv1x1 Malloc weight_ptr_ error!";
return RET_ERROR;
}
}
void *weight_origin_tmp = is_trainable() ? weight_tensor->data_c() : origin_weight_;
memset(reinterpret_cast<char *>(weight_ptr_) + down_size, 0, size - down_size);
ColMajor2Row8MajorFp16(origin_weight_, weight_ptr_, input_channel, output_channel, true);
ColMajor2Row8MajorFp16(weight_origin_tmp, weight_ptr_, input_channel, output_channel, true);
return RET_OK;
}
@ -233,6 +240,15 @@ int Convolution1x1FP16CPUKernel::Run() {
return RET_MEMORY_FAILED;
}
if (is_trainable() && (IsTrain() || is_repack())) {
auto ret = InitWeightBias();
if (ret != 0) {
MS_LOG(ERROR) << "Convolution 1x1 fp16 repack weight failure";
return RET_ERROR;
}
is_repack_ = false;
}
for (int batch_index = 0; batch_index < conv_param_->input_batch_; batch_index++) {
output_ptr_ = output_data + batch_index * matmul_param_->row_ * matmul_param_->col_;
float16_t *batch_in =
@ -263,9 +279,16 @@ int Convolution1x1FP16CPUKernel::Run() {
return ret;
}
}
ctx_->allocator->Free(pack_input_);
pack_input_ = nullptr;
return RET_OK;
}
int Convolution1x1FP16CPUKernel::Eval() {
if (is_trainable()) {
is_repack_ = true;
}
return InnerKernel::Eval();
}
} // namespace mindspore::kernel

View File

@ -14,8 +14,8 @@
* limitations under the License.
*/
#ifndef MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_FP16_CONVOLUTION_1x1_FP16_H_
#define MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_FP16_CONVOLUTION_1x1_FP16_H_
#ifndef MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_FP16_CONVOLUTION_1X1_FP16_H_
#define MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_FP16_CONVOLUTION_1X1_FP16_H_
#include <arm_neon.h>
#include <vector>
@ -39,6 +39,7 @@ class Convolution1x1FP16CPUKernel : public ConvolutionBaseCPUKernel {
int Init() override;
int ReSize() override;
int Run() override;
int Eval() override;
public:
int RunOc(int task_id);
@ -67,4 +68,4 @@ class Convolution1x1FP16CPUKernel : public ConvolutionBaseCPUKernel {
};
} // namespace mindspore::kernel
#endif // MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_FP16_CONVOLUTION_1x1_FP16_H_
#endif // MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_FP16_CONVOLUTION_1X1_FP16_H_

View File

@ -47,6 +47,18 @@ class ConvolutionDelegateFP16CPUKernel : public InnerKernel {
fp16_conv_kernel_->set_name(name_);
return fp16_conv_kernel_->Run();
}
int Eval() override {
InnerKernel::Eval();
return fp16_conv_kernel_->Eval();
}
int Train() override {
InnerKernel::Train();
return fp16_conv_kernel_->Train();
}
void set_trainable(bool trainable) override {
InnerKernel::set_trainable(trainable);
return fp16_conv_kernel_->set_trainable(trainable);
}
void set_in_tensor(lite::Tensor *in_tensor, int index) override {
MS_ASSERT(index < in_tensors_.size());

View File

@ -37,19 +37,22 @@ int ConvolutionDepthwiseFp16CPUKernel::InitWeightBias() {
int pack_weight_size = channel * weight_tensor->Height() * weight_tensor->Width();
auto origin_weight = reinterpret_cast<float16_t *>(weight_tensor->data_c());
MS_ASSERT(origin_weight != nullptr);
packed_weight_ = reinterpret_cast<float16_t *>(malloc(pack_weight_size * sizeof(float16_t)));
if (packed_weight_ == nullptr) {
MS_LOG(ERROR) << "Malloc buffer failed.";
return RET_ERROR;
packed_weight_ = reinterpret_cast<float16_t *>(malloc(pack_weight_size * sizeof(float16_t)));
if (packed_weight_ == nullptr) {
MS_LOG(ERROR) << "Malloc buffer failed.";
return RET_ERROR;
}
}
PackNCHWToNHWCFp16(origin_weight, packed_weight_, 1, weight_tensor->Height() * weight_tensor->Width(),
weight_tensor->Batch(), 0, 0);
bias_data_ = reinterpret_cast<float16_t *>(malloc(channel * sizeof(float16_t)));
if (bias_data_ == nullptr) {
MS_LOG(ERROR) << "Malloc buffer failed.";
return RET_ERROR;
bias_data_ = reinterpret_cast<float16_t *>(malloc(channel * sizeof(float16_t)));
if (bias_data_ == nullptr) {
MS_LOG(ERROR) << "Malloc buffer failed.";
return RET_ERROR;
}
}
memset(bias_data_, 0, channel * sizeof(float16_t));
if (in_tensors_.size() == kInputSize2) {
@ -106,6 +109,14 @@ static int ConvDwFp16Run(void *cdata, int task_id, float lhs_scale, float rhs_sc
}
int ConvolutionDepthwiseFp16CPUKernel::Run() {
if (is_trainable() && (IsTrain() || is_repack())) {
auto ret = InitWeightBias();
if (ret != 0) {
MS_LOG(ERROR) << "Convolution depthwise fp16 repack weight failure";
return RET_ERROR;
}
is_repack_ = false;
}
auto ret = static_cast<const lite::InnerContext *>(this->context_)
->thread_pool_->ParallelLaunch(ConvDwFp16Run, this, conv_param_->thread_num_);
if (ret != RET_OK) {
@ -113,4 +124,11 @@ int ConvolutionDepthwiseFp16CPUKernel::Run() {
}
return ret;
}
int ConvolutionDepthwiseFp16CPUKernel::Eval() {
if (is_trainable()) {
is_repack_ = true;
}
return InnerKernel::Eval();
}
} // namespace mindspore::kernel

View File

@ -42,6 +42,7 @@ class ConvolutionDepthwiseFp16CPUKernel : public ConvolutionBaseCPUKernel {
int Init() override;
int ReSize() override;
int Run() override;
int Eval() override;
int InitWeightBias();
int Execute(int task_id);

View File

@ -64,18 +64,22 @@ int ConvolutionDepthwiseSWFp16CPUKernel::InitWeightBias() {
auto origin_weight = reinterpret_cast<float16_t *>(weight_tensor->data_c());
MS_ASSERT(origin_weight != nullptr);
packed_weight_ = reinterpret_cast<float16_t *>(malloc(pack_weight_size * sizeof(float16_t)));
if (packed_weight_ == nullptr) {
MS_LOG(ERROR) << "Malloc buffer failed.";
return RET_ERROR;
packed_weight_ = reinterpret_cast<float16_t *>(malloc(pack_weight_size * sizeof(float16_t)));
if (packed_weight_ == nullptr) {
MS_LOG(ERROR) << "Malloc buffer failed.";
return RET_ERROR;
}
}
PackNCHWFp16ToNC8HW8Fp16(origin_weight, packed_weight_, 1, weight_tensor->Height() * weight_tensor->Width(),
weight_tensor->Batch());
bias_data_ = reinterpret_cast<float16_t *>(malloc(C8NUM * OC8 * sizeof(float16_t)));
if (bias_data_ == nullptr) {
MS_LOG(ERROR) << "Malloc buffer failed.";
return RET_ERROR;
bias_data_ = reinterpret_cast<float16_t *>(malloc(C8NUM * OC8 * sizeof(float16_t)));
if (bias_data_ == nullptr) {
MS_LOG(ERROR) << "Malloc buffer failed.";
return RET_ERROR;
}
}
memset(bias_data_, 0, C8NUM * OC8 * sizeof(float16_t));
if (in_tensors_.size() == kInputSize2) {
@ -86,7 +90,7 @@ int ConvolutionDepthwiseSWFp16CPUKernel::InitWeightBias() {
conv_param_->thread_num_ = MSMIN(thread_count_, OC8);
return RET_OK;
}
} // namespace mindspore::kernel
int ConvolutionDepthwiseSWFp16CPUKernel::Init() {
sliding_ = new (std::nothrow) SlidingWindowParam;
@ -157,6 +161,14 @@ int ConvolutionDepthwiseSWFp16CPUKernel::Run() {
packed_output_ = output_ptr;
}
if (is_trainable() && (IsTrain() || is_repack())) {
ret = InitWeightBias();
if (ret != 0) {
MS_LOG(ERROR) << "Convolution depthwise fp16 repack weight failure";
return RET_ERROR;
}
is_repack_ = false;
}
ret = static_cast<const lite::InnerContext *>(this->context_)
->thread_pool_->ParallelLaunch(ConvDwSWFp16Run, this, conv_param_->thread_num_);
if (ret != RET_OK) {
@ -179,4 +191,11 @@ void ConvolutionDepthwiseSWFp16CPUKernel::FreePackedInputOutput() {
packed_output_ = nullptr;
}
}
int ConvolutionDepthwiseSWFp16CPUKernel::Eval() {
if (is_trainable()) {
is_repack_ = true;
}
return InnerKernel::Eval();
}
} // namespace mindspore::kernel

View File

@ -14,8 +14,8 @@
* limitations under the License.
*/
#ifndef MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_FP16_CONVOLUTION_DEPTHWISE_SW_FP16_H_
#define MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_FP16_CONVOLUTION_DEPTHWISE_SW_FP16_H_
#ifndef MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_FP16_CONVOLUTION_DEPTHWISE_SLIDEWINDOW_FP16_H_
#define MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_FP16_CONVOLUTION_DEPTHWISE_SLIDEWINDOW_FP16_H_
#include <vector>
#include "src/inner_kernel.h"
@ -43,6 +43,7 @@ class ConvolutionDepthwiseSWFp16CPUKernel : public ConvolutionBaseCPUKernel {
int Init() override;
int ReSize() override;
int Run() override;
int Eval() override;
int InitPackedInputOutput();
int InitWeightBias();
@ -58,4 +59,4 @@ class ConvolutionDepthwiseSWFp16CPUKernel : public ConvolutionBaseCPUKernel {
};
} // namespace mindspore::kernel
#endif // MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_FP16_CONVOLUTION_DEPTHWISE_SW_FP16_H_
#endif // MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_FP16_CONVOLUTION_DEPTHWISE_SLIDEWINDOW_FP16_H_

View File

@ -38,23 +38,30 @@ int ConvolutionFP16CPUKernel::InitWeightBias() {
int pack_weight_size = oc8 * in_channel * kernel_plane;
// init weight
packed_weight_ = reinterpret_cast<float16_t *>(malloc(pack_weight_size * sizeof(float16_t)));
if (packed_weight_ == nullptr) {
MS_LOG(ERROR) << "malloc packed_weight_ failed.";
return RET_ERROR;
packed_weight_ = reinterpret_cast<float16_t *>(malloc(pack_weight_size * sizeof(float16_t)));
if (packed_weight_ == nullptr) {
MS_LOG(ERROR) << "malloc packed_weight_ failed.";
return RET_ERROR;
}
}
memset(packed_weight_, 0, pack_weight_size * sizeof(float16_t));
RowMajor2Col8MajorFp16(origin_weight_, packed_weight_, out_channel, in_channel * kernel_plane, false);
void *weight_origin_tmp = is_trainable() ? filter_tensor->data_c() : origin_weight_;
RowMajor2Col8MajorFp16(weight_origin_tmp, packed_weight_, out_channel, in_channel * kernel_plane, false);
// init bias
bias_data_ = malloc(oc8 * sizeof(float16_t));
if (bias_data_ == nullptr) {
MS_LOG(ERROR) << "malloc bias_data_ failed.";
return RET_ERROR;
bias_data_ = malloc(oc8 * sizeof(float16_t));
if (bias_data_ == nullptr) {
MS_LOG(ERROR) << "malloc bias_data_ failed.";
return RET_ERROR;
}
}
memset(bias_data_, 0, oc8 * sizeof(float16_t));
if (in_tensors_.size() == kInputSize2) {
memcpy(bias_data_, origin_bias_, out_channel * sizeof(float16_t));
auto bias_tensor = in_tensors_.at(kBiasIndex);
void *bias_origin_tmp = is_trainable() ? bias_tensor->data_c() : origin_bias_;
memcpy(bias_data_, bias_origin_tmp, out_channel * sizeof(float16_t));
}
return RET_OK;
}
@ -145,6 +152,14 @@ int ConvolutionFP16CPUKernel::Run() {
return RET_ERROR;
}
if (is_trainable() && (IsTrain() || is_repack())) {
ret = InitWeightBias();
if (ret != 0) {
MS_LOG(ERROR) << "Convolution 1x1 fp16 repack weight failure";
return RET_ERROR;
}
is_repack_ = false;
}
ret = static_cast<const lite::InnerContext *>(this->context_)
->thread_pool_->ParallelLaunch(ConvolutionFp16Impl, this, thread_count_);
if (ret != RET_OK) {
@ -154,4 +169,11 @@ int ConvolutionFP16CPUKernel::Run() {
FreeTmpBuffer();
return ret;
}
int ConvolutionFP16CPUKernel::Eval() {
if (is_trainable()) {
is_repack_ = true;
}
return InnerKernel::Eval();
}
} // namespace mindspore::kernel

View File

@ -41,6 +41,7 @@ class ConvolutionFP16CPUKernel : public ConvolutionBaseCPUKernel {
int Init() override;
int ReSize() override;
int Run() override;
int Eval() override;
int RunImpl(int task_id);
int InitWeightBias();
int InitTmpBuffer();

View File

@ -41,10 +41,12 @@ int ConvolutionWinogradFP16CPUKernel::InitWeightBias() {
// init weight
// set data
auto trans_matrix_data_size = input_unit_ * input_unit_ * in_channel * oc_block_num * col_tile_ * sizeof(float16_t);
trans_weight_ = reinterpret_cast<float16_t *>(malloc(trans_matrix_data_size));
if (trans_weight_ == nullptr) {
MS_LOG(ERROR) << "malloc trans_weight_ failed.";
return RET_ERROR;
trans_weight_ = reinterpret_cast<float16_t *>(malloc(trans_matrix_data_size));
if (trans_weight_ == nullptr) {
MS_LOG(ERROR) << "malloc trans_weight_ failed.";
return RET_ERROR;
}
}
memset(trans_weight_, 0, trans_matrix_data_size);
@ -64,21 +66,26 @@ int ConvolutionWinogradFP16CPUKernel::InitWeightBias() {
MS_LOG(ERROR) << "get matrix g from CookToomFilter failed.";
return ret;
}
ret = WinogradFilterTransformFp16(reinterpret_cast<float16_t *>(origin_weight_), matrix_g, matrix_gt, col_tile_);
void *weight_origin_tmp = is_trainable() ? weight_tensor->data_c() : origin_weight_;
ret = WinogradFilterTransformFp16(reinterpret_cast<float16_t *>(weight_origin_tmp), matrix_g, matrix_gt, col_tile_);
if (ret != RET_OK) {
MS_LOG(ERROR) << "winograd filter transform failed.";
return ret;
}
// init bias
bias_data_ = malloc(oc_block_num * col_tile_ * sizeof(float16_t));
if (bias_data_ == nullptr) {
MS_LOG(ERROR) << "malloc bias_data_ failed.";
return RET_ERROR;
bias_data_ = malloc(oc_block_num * col_tile_ * sizeof(float16_t));
if (bias_data_ == nullptr) {
MS_LOG(ERROR) << "malloc bias_data_ failed.";
return RET_ERROR;
}
}
memset(bias_data_, 0, oc_block_num * col_tile_ * sizeof(float16_t));
if (in_tensors_.size() == kInputSize2) {
memcpy(bias_data_, origin_bias_, out_channel * sizeof(float16_t));
auto bias_tensor = in_tensors_.at(kBiasIndex);
void *bias_origin_tmp = is_trainable() ? bias_tensor->data_c() : origin_bias_;
memcpy(bias_data_, bias_origin_tmp, out_channel * sizeof(float16_t));
}
return RET_OK;
}
@ -222,14 +229,27 @@ int ConvolutionWinogradFP16CPUKernel::Run() {
FreeTmpBuffer();
return RET_ERROR;
}
if (is_trainable() && (IsTrain() || is_repack())) {
ret = InitWeightBias();
if (ret != 0) {
MS_LOG(ERROR) << "ConvolutionWinogradFP16 repack weight failure";
return RET_ERROR;
}
is_repack_ = false;
}
ret = static_cast<const lite::InnerContext *>(this->context_)
->thread_pool_->ParallelLaunch(ConvolutionWinogradFp16Impl, this, thread_count_);
if (ret != RET_OK) {
MS_LOG(ERROR) << "conv winograd error error_code[" << ret << "]";
}
FreeTmpBuffer();
return ret;
}
int ConvolutionWinogradFP16CPUKernel::Eval() {
if (is_trainable()) {
is_repack_ = true;
}
return InnerKernel::Eval();
}
} // namespace mindspore::kernel

View File

@ -46,6 +46,7 @@ class ConvolutionWinogradFP16CPUKernel : public ConvolutionBaseCPUKernel {
int Init() override;
int ReSize() override;
int Run() override;
int Eval() override;
int RunImpl(int task_id);
int InitWeightBias();
int InitTmpBuffer();

View File

@ -25,6 +25,29 @@ using mindspore::lite::RET_OK;
using mindspore::schema::PrimitiveType_FusedBatchNorm;
namespace mindspore::kernel {
void FusedBatchnormFp16CPUKernel::CalcMeanVar(float16_t *in, float16_t *scale, float16_t *offset, float16_t *save_mean,
float16_t *save_variance) {
auto param = reinterpret_cast<BatchNormParameter *>(op_parameter_);
float16_t *current_mean = static_cast<float16_t *>(mean_);
float16_t *current_var = static_cast<float16_t *>(variance_);
std::fill(current_mean, current_mean + in_tensors_.at(3)->ElementsNum(), 0.f);
std::fill(current_var, current_var + in_tensors_.at(4)->ElementsNum(), 0.f);
FusedBatchNormFp16MeanVar(in, current_mean, current_var, param, save_mean, save_variance);
memcpy(out_tensors_.at(1)->data_c(), scale, out_tensors_.at(1)->Size());
memcpy(out_tensors_.at(2)->data_c(), offset, out_tensors_.at(2)->Size());
memcpy(out_tensors_.at(3)->data_c(), current_mean, out_tensors_.at(3)->Size());
memcpy(out_tensors_.at(4)->data_c(), current_var, out_tensors_.at(4)->Size());
// Copy to local variables
memcpy(scale_, scale, in_tensors_[1]->Size());
memcpy(offset_, offset, in_tensors_[2]->Size());
trained_ = true; // trained at least once
}
int FusedBatchnormFp16CPUKernel::DoExecute(int task_id) {
auto param = reinterpret_cast<BatchNormParameter *>(op_parameter_);
MS_ASSERT(param);
@ -54,18 +77,25 @@ int FusedBatchnormFp16CPUKernel::DoExecute(int task_id) {
context_->allocator->Free(output_fp16);
return RET_ERROR;
}
Float32ToFloat16(reinterpret_cast<float *>(input->MutableData()), reinterpret_cast<float16_t *>(input_fp16),
Float32ToFloat16(reinterpret_cast<float *>(input->data_c()), reinterpret_cast<float16_t *>(input_fp16),
input->ElementsNum());
Float32ToFloat16(reinterpret_cast<float *>(scale->MutableData()), reinterpret_cast<float16_t *>(scale_fp16),
Float32ToFloat16(reinterpret_cast<float *>(scale->data_c()), reinterpret_cast<float16_t *>(scale_fp16),
scale->ElementsNum());
Float32ToFloat16(reinterpret_cast<float *>(offset->MutableData()), reinterpret_cast<float16_t *>(offset_fp16),
Float32ToFloat16(reinterpret_cast<float *>(offset->data_c()), reinterpret_cast<float16_t *>(offset_fp16),
offset->ElementsNum());
Float32ToFloat16(reinterpret_cast<float *>(mean->MutableData()), reinterpret_cast<float16_t *>(mean_fp16),
Float32ToFloat16(reinterpret_cast<float *>(mean->data_c()), reinterpret_cast<float16_t *>(mean_fp16),
mean->ElementsNum());
Float32ToFloat16(reinterpret_cast<float *>(variance->MutableData()), reinterpret_cast<float16_t *>(variance_fp16),
Float32ToFloat16(reinterpret_cast<float *>(variance->data_c()), reinterpret_cast<float16_t *>(variance_fp16),
variance->ElementsNum());
FusedBatchNormFp16(input_fp16, scale_fp16, offset_fp16, mean_fp16, variance_fp16, param, task_id, output_fp16);
if (IsTrain() && is_trainable() && in_tensors_.size() >= 5) {
CalcMeanVar(reinterpret_cast<float16_t *>(input_fp16), reinterpret_cast<float16_t *>(scale_fp16),
reinterpret_cast<float16_t *>(offset_fp16), reinterpret_cast<float16_t *>(mean_fp16),
reinterpret_cast<float16_t *>(variance_fp16));
}
FusedBatchNormFp16(reinterpret_cast<float16_t *>(input_fp16), reinterpret_cast<float16_t *>(scale_fp16),
reinterpret_cast<float16_t *>(offset_fp16), reinterpret_cast<float16_t *>(mean_fp16),
reinterpret_cast<float16_t *>(variance_fp16), param, task_id, output_fp16);
Float16ToFloat32(reinterpret_cast<float16_t *>(output_fp16), reinterpret_cast<float *>(output),
output->ElementsNum());
@ -77,8 +107,32 @@ int FusedBatchnormFp16CPUKernel::DoExecute(int task_id) {
context_->allocator->Free(output_fp16);
return RET_OK;
}
FusedBatchNormFp16(in_tensors_.at(0)->MutableData(), scale_, offset_, mean_, variance_, param, task_id,
out_tensors_.at(0)->MutableData());
if (IsTrain() && is_trainable() && in_tensors_.size() >= 5) {
CalcMeanVar(
static_cast<float16_t *>(in_tensors_.at(0)->data_c()), static_cast<float16_t *>(in_tensors_.at(1)->data_c()),
static_cast<float16_t *>(in_tensors_.at(2)->data_c()), static_cast<float16_t *>(in_tensors_.at(3)->data_c()),
static_cast<float16_t *>(in_tensors_.at(4)->data_c()));
}
FusedBatchNormFp16(in_tensors_.at(0)->data_c(), scale_, offset_, mean_, variance_, param, task_id,
out_tensors_.at(0)->data_c());
return RET_OK;
}
int FusedBatchnormFp16CPUKernel::Eval() {
InnerKernel::Eval();
if (trained_) {
float16_t *save_mean = static_cast<float16_t *>(in_tensors_.at(3)->data_c());
float16_t *save_var = static_cast<float16_t *>(in_tensors_.at(4)->data_c());
float16_t *scale = static_cast<float16_t *>(in_tensors_.at(1)->data_c());
float16_t *bias = static_cast<float16_t *>(in_tensors_.at(2)->data_c());
// Copy to local variables
memcpy(scale_, scale, in_tensors_.at(1)->Size());
memcpy(offset_, bias, in_tensors_.at(2)->Size());
memcpy(mean_, save_mean, in_tensors_.at(3)->Size());
memcpy(variance_, save_var, in_tensors_.at(4)->Size());
}
return RET_OK;
}
} // namespace mindspore::kernel

View File

@ -1,5 +1,5 @@
/**
* Copyright 2020 Huawei Technologies Co., Ltd
* Copyright 2021 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.
@ -28,7 +28,11 @@ class FusedBatchnormFp16CPUKernel : public FusedBatchnormCPUKernel {
: FusedBatchnormCPUKernel(parameter, inputs, outputs, ctx) {}
virtual ~FusedBatchnormFp16CPUKernel() {}
virtual int DoExecute(int task_id);
int DoExecute(int task_id) override;
int Eval() override;
protected:
void CalcMeanVar(float16_t *in, float16_t *scale, float16_t *offset, float16_t *save_mean, float16_t *save_variance);
};
} // namespace mindspore::kernel

View File

@ -69,10 +69,12 @@ int MatmulBaseFP16CPUKernel::InitBias() {
if (in_tensors_.size() == 3) {
auto bias_tensor = in_tensors_[2];
int max_bias_data = UP_ROUND(bias_tensor->ElementsNum(), C8NUM);
bias_ptr_ = reinterpret_cast<float16_t *>(malloc(max_bias_data * sizeof(float16_t)));
if (bias_ptr_ == nullptr) {
MS_LOG(ERROR) << "malloc bias_ptr_ failed";
return RET_ERROR;
bias_ptr_ = reinterpret_cast<float16_t *>(malloc(max_bias_data * sizeof(float16_t)));
if (bias_ptr_ == nullptr) {
MS_LOG(ERROR) << "malloc bias_ptr_ failed";
return RET_ERROR;
}
}
memset(bias_ptr_, 0, max_bias_data * sizeof(float16_t));
if (bias_tensor->data_type() == kNumberTypeFloat32) {
@ -268,18 +270,19 @@ int MatmulBaseFP16CPUKernel::RunImpl(int task_id) {
int MatmulBaseFP16CPUKernel::Run() {
auto c_ptr = reinterpret_cast<float16_t *>(out_tensors_.at(0)->data_c());
if (params_->a_const_ == false) {
if ((params_->a_const_ == false) || is_repack()) {
if (RET_OK != InitBufferA()) {
return RET_ERROR;
}
InitMatrixA(in_tensors_.at(0)->data_c());
}
if (params_->b_const_ == false) {
if ((params_->b_const_ == false) || is_repack()) {
if (RET_OK != InitBufferB()) {
FreeResizeBufA();
return RET_ERROR;
}
InitMatrixB(in_tensors_.at(1)->data_c(), in_tensors_.at(1)->data_type());
InitBias();
}
for (int i = 0; i < params_->batch; ++i) {

View File

@ -42,6 +42,8 @@ class MatmulBaseFP16CPUKernel : public InnerKernel {
protected:
void InitParameter();
bool is_repack() { return is_repack_; }
bool is_repack_ = false;
private:
int InitBias();

View File

@ -86,12 +86,24 @@ int MatmulFP16CPUKernel::ReSize() {
}
int MatmulFP16CPUKernel::Run() {
if (is_trainable() && (IsTrain())) {
is_repack_ = true;
}
auto ret = MatmulBaseFP16CPUKernel::Run();
if (ret != RET_OK) {
MS_LOG(ERROR) << "MatmulFP16CPUKernel run failed";
}
is_repack_ = false;
return ret;
}
int MatmulFP16CPUKernel::Eval() {
InnerKernel::Eval();
if (is_trainable()) {
is_repack_ = true;
}
return RET_OK;
}
REG_KERNEL(kCPU, kNumberTypeFloat16, PrimitiveType_MatMul, LiteKernelCreator<MatmulFP16CPUKernel>)
} // namespace mindspore::kernel

View File

@ -14,8 +14,8 @@
* limitations under the License.
*/
#ifndef MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_FP16_MATMUL_H_
#define MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_FP16_MATMUL_H_
#ifndef MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_FP16_MATMUL_FP16_H_
#define MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_FP16_MATMUL_FP16_H_
#include <vector>
#include "src/runtime/kernel/arm/fp16/matmul_base_fp16.h"
@ -30,6 +30,7 @@ class MatmulFP16CPUKernel : public MatmulBaseFP16CPUKernel {
int Init() override;
int ReSize() override;
int Run() override;
int Eval() override;
private:
void InitAShape();
@ -37,4 +38,4 @@ class MatmulFP16CPUKernel : public MatmulBaseFP16CPUKernel {
};
} // namespace mindspore::kernel
#endif // MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_FP16_MATMUL_H_
#endif // MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_FP16_MATMUL_FP16_H_

View File

@ -19,6 +19,7 @@
#include "nnacl/pack.h"
#include "nnacl/fp16_grad/pack_fp16_ext.h"
#include "nnacl/fp16_grad/gemm_fp16.h"
#include "nnacl/fp16_grad/convolution_grad_input.h"
#include "include/errorcode.h"
using mindspore::kernel::KERNEL_ARCH::kCPU;
@ -64,6 +65,11 @@ int ConvolutionGradInputCPUKernelFp16::ReSize() {
? false
: true;
do_dw_ = (conv_param->output_channel_ == conv_param->group_) &&
(conv_param->input_channel_ == conv_param->output_channel_) && (conv_param->dilation_h_ == 1) &&
(conv_param->dilation_w_ == 1)
? true
: false;
return RET_OK;
}
@ -103,6 +109,18 @@ int ConvolutionGradInputCPUKernelFp16::Execute(int task_id) {
int start = stride * task_id;
int end = start + count;
if (do_dw_) {
stride = UP_DIV(groups, thread_num);
count = MSMIN(stride, groups - stride * task_id);
count = (count < 0) ? 0 : count;
start = stride * task_id;
for (i = 0; i < batch; ++i) {
ConvDwInputGradFp16(dy_addr + (i * groups) * m * k, w_addr, dx_addr + (i * groups) * in_h * in_w, start, count,
conv_param);
}
return RET_OK;
}
for (i = start; i < end; ++i) {
for (j = 0; j < groups; ++j) {
GemmCbFp16 gcb;

View File

@ -37,6 +37,7 @@ class ConvolutionGradInputCPUKernelFp16 : public InnerKernel {
size_t ws_size_ = 0;
size_t mat_alloc_ = 0;
bool do_img2col_ = true;
bool do_dw_ = false;
const int chunk_ = C12NUM;
};
} // namespace mindspore::kernel

View File

@ -19,6 +19,7 @@
#include "nnacl/pack.h"
#include "nnacl/fp32_grad/pack_ext.h"
#include "nnacl/fp32_grad/gemm.h"
#include "nnacl/fp32_grad/convolution_grad_input.h"
#include "include/errorcode.h"
using mindspore::kernel::KERNEL_ARCH;
@ -56,6 +57,20 @@ int ConvolutionGradInputCPUKernel::ReSize() {
int thread_num = op_parameter_->thread_num_;
mat_alloc_ = MatSizeTotal(chunk_, n, k, 0);
set_workspace_size((ws_size_ + mat_alloc_) * sizeof(float) * thread_num);
do_img2col_ = (conv_param->kernel_h_ == 1) && (conv_param->kernel_w_ == 1) && (conv_param->pad_d_ == 0) &&
(conv_param->pad_u_ == 0) && (conv_param->pad_l_ == 0) && (conv_param->pad_r_ == 0) &&
(conv_param->dilation_h_ == 1) && (conv_param->dilation_w_ == 1) && (conv_param->stride_h_ == 1) &&
(conv_param->stride_w_ == 1) && (conv_param->group_ == 1)
? false
: true;
do_dw_ = (conv_param->output_channel_ == conv_param->group_) &&
(conv_param->input_channel_ == conv_param->output_channel_) && (conv_param->dilation_h_ == 1) &&
(conv_param->dilation_w_ == 1)
? true
: false;
return RET_OK;
}
@ -95,6 +110,18 @@ int ConvolutionGradInputCPUKernel::Execute(int task_id) {
int start = stride * task_id;
int end = start + count;
if (do_dw_) {
stride = UP_DIV(groups, thread_num);
count = MSMIN(stride, groups - stride * task_id);
count = (count < 0) ? 0 : count;
start = stride * task_id;
for (i = 0; i < batch; ++i) {
ConvDwInputGrad(dy_addr + (i * groups) * m * k, w_addr, dx_addr + (i * groups) * in_h * in_w, start, count,
conv_param);
}
return RET_OK;
}
for (i = start; i < end; ++i) {
for (j = 0; j < groups; ++j) {
GemmCb gcb;
@ -112,10 +139,16 @@ int ConvolutionGradInputCPUKernel::Execute(int task_id) {
}
int real_chunk = MSMIN(m - ci, chunk_);
float *mat_a = dy_addr + (i * groups) * m * k + j * (out_ch / groups) + ci * out_ch;
float *mat_c = workspace_temp;
GemmMatmulPlus(0, 0, real_chunk, n, k, 1, mat_a, out_ch, mat_b, n, 0, mat_c, n, mat_workspace, &gcb);
rolling_col2im_hwc(mat_c, dx_addr + (i * groups) * (in_ch / groups) * in_h * in_w + j * (in_ch / groups),
conv_param, real_chunk, ci);
if (do_img2col_) {
float *mat_c = workspace_temp;
GemmMatmulPlus(0, 0, real_chunk, n, k, 1, mat_a, out_ch, mat_b, n, 0, mat_c, n, mat_workspace, &gcb);
rolling_col2im_hwc(mat_c, dx_addr + (i * groups) * (in_ch / groups) * in_h * in_w + j * (in_ch / groups),
conv_param, real_chunk, ci);
} else {
float *mat_c =
dx_addr + (i * groups) * (in_ch / groups) * in_h * in_w + j * (in_ch / groups) + ci * (in_ch / groups);
GemmMatmulPlus(0, 0, real_chunk, n, k, 1, mat_a, out_ch, mat_b, n, 0, mat_c, n, mat_workspace, &gcb);
}
}
}
}

View File

@ -36,6 +36,8 @@ class ConvolutionGradInputCPUKernel : public InnerKernel {
private:
size_t ws_size_ = 0;
size_t mat_alloc_ = 0;
bool do_img2col_ = true;
bool do_dw_ = false;
#ifdef ENABLE_ARM32
const int chunk_ = C4NUM;
#else

View File

@ -428,12 +428,12 @@ int Scheduler::FindCpuKernel(const std::vector<Tensor *> &in_tensors, const std:
}
std::map<Tensor *, Tensor *> restored_origin_tensors;
ret = CastConstTensorsData(in_tensors, &restored_origin_tensors, kernel_data_type);
if (ret != RET_OK) {
MS_LOG(DEBUG) << "CastConstTensorsData failed: " << ret;
return RET_NOT_SUPPORT;
}
if (!is_train_session_) {
ret = CastConstTensorsData(in_tensors, &restored_origin_tensors, kernel_data_type);
if (ret != RET_OK) {
MS_LOG(DEBUG) << "CastConstTensorsData failed: " << ret;
return RET_NOT_SUPPORT;
}
// we don't need to restore tensor for copy data
ret = CopyConstTensorData(in_tensors, op_type);
if (ret != RET_OK) {
@ -444,7 +444,11 @@ int Scheduler::FindCpuKernel(const std::vector<Tensor *> &in_tensors, const std:
ret = KernelRegistry::GetInstance()->GetKernel(in_tensors, out_tensors, context_, cpu_desc, op_parameter, kernel);
if (ret == RET_OK) {
MS_LOG(DEBUG) << "Get TypeId(" << kernel_data_type << ") op success: " << PrimitiveCurVersionTypeName(op_type);
FreeRestoreTensors(&restored_origin_tensors);
if (is_train_session_) {
RestoreTensorData(&restored_origin_tensors);
} else {
FreeRestoreTensors(&restored_origin_tensors);
}
} else {
RestoreTensorData(&restored_origin_tensors);
}
@ -612,7 +616,8 @@ kernel::LiteKernel *Scheduler::FindBackendKernel(const std::vector<Tensor *> &in
}
}
#endif
if (prefer_data_type == kNumberTypeFloat16 || prefer_data_type == kTypeUnknown) {
if ((prefer_data_type == kNumberTypeFloat16 || prefer_data_type == kTypeUnknown) &&
((is_train_session_ == false) || (sched_cb_ && sched_cb_->SchedFp16Kernel(node)))) {
status = FindCpuKernel(in_tensors, out_tensors, op_parameter, desc, kNumberTypeFloat16, &kernel);
if (status == RET_OK) {
return kernel;

View File

@ -24,6 +24,8 @@
#include "src/sub_graph_kernel.h"
#include "src/inner_context.h"
#include "include/model.h"
#include "src/scheduler_cb.h"
#if SUPPORT_NPU
#include "src/runtime/agent/npu/optimizer/npu_pass_manager.h"
#endif
@ -54,6 +56,7 @@ class Scheduler {
~Scheduler() = default;
int Schedule(std::vector<kernel::LiteKernel *> *dst_kernels);
void SetupSchedulerCb(std::unique_ptr<SchedulerCb> cb) { sched_cb_ = std::move(cb); }
private:
void FindNodeInoutTensors(const lite::Model::Node &node, std::vector<Tensor *> *inputs,
@ -132,6 +135,7 @@ class Scheduler {
std::vector<size_t> graph_output_node_indexes_;
std::map<int, OpParameter *> op_parameters_;
bool is_train_session_ = false;
std::unique_ptr<SchedulerCb> sched_cb_;
std::map<kernel::Kernel *, const schema::Primitive *> primitives_;
std::shared_ptr<Delegate> delegate_ = nullptr;
};

View File

@ -0,0 +1,43 @@
/**
* Copyright 2021 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_SRC_SCHEDELER_CB_H_
#define MINDSPORE_LITE_SRC_SCHEDELER_CB_H_
#include <functional>
#include "include/model.h"
namespace mindspore::lite {
using SchedCallBack = std::function<bool(const Model::Node *node)>;
class SchedulerCb {
public:
explicit SchedulerCb(SchedCallBack fp16_cb) : fp16_cb_(fp16_cb) {}
~SchedulerCb() = default;
bool SchedFp16Kernel(const Model::Node *node) {
if (fp16_cb_) {
return fp16_cb_(node);
}
return false;
}
private:
SchedCallBack fp16_cb_;
};
} // namespace mindspore::lite
#endif // MINDSPORE_LITE_SRC_SCHEDELER_CB_H_

View File

@ -197,6 +197,27 @@ class Tensor : public mindspore::tensor::MSTensor {
void set_own_data(bool own_data) { this->own_data_ = own_data; }
template <typename T>
int Scale(float scale) {
T cast_scale = static_cast<T>(scale);
auto data = reinterpret_cast<T *>(data_c());
if (data == nullptr) {
return RET_ERROR;
}
int length = ElementsNum();
for (int i = 0; i < length; i++) {
data[i] *= cast_scale;
}
scale_ *= scale;
return RET_OK;
}
float get_scale() const { return this->scale_; }
void set_scale(float scale) { this->scale_ = scale; }
bool IsScale() const { return (std::abs(this->scale_ - 1.0f) > 1.0e-05); }
private:
template <typename T>
std::string DataToString(void *data, size_t data_number) const {
@ -225,6 +246,7 @@ class Tensor : public mindspore::tensor::MSTensor {
AllocatorPtr allocator_ = nullptr;
Tensor *root_tensor_ = nullptr;
bool own_data_{false};
float scale_ = 1.0f;
};
inline size_t DataTypeSize(const TypeId type) {

View File

@ -16,10 +16,18 @@
#ifndef MINDSPORE_LITE_SRC_TRAIN_OPTIMIZER_KERNEL_H_
#define MINDSPORE_LITE_SRC_TRAIN_OPTIMIZER_KERNEL_H_
#include <vector>
#include <cmath>
#include <cfloat>
#include "src/lite_kernel.h"
#include "include/errorcode.h"
using mindspore::lite::RET_ERROR;
using mindspore::lite::RET_OK;
using mindspore::lite::RET_OUT_OF_TENSOR_RANGE;
static __attribute__((always_inline)) inline bool MS_ISNAN(float var) {
volatile float d = var;
return d != d;
}
namespace mindspore::kernel {
@ -103,6 +111,37 @@ class OptimizerKernel : public InnerKernel {
return InnerKernel::Eval();
}
int PreProcess() override {
auto ret = InnerKernel::PreProcess();
if (ret != RET_OK) {
return ret;
}
auto ctx = static_cast<const lite::InnerContext *>(this->context_);
if (ctx->IsCpuFloat16Enabled()) {
auto t = in_tensors_.at(grad_idx_);
auto gradient = reinterpret_cast<float *>(t->data_c());
int length = in_tensors_.at(grad_idx_)->ElementsNum();
for (int i = 0; i < length; ++i) {
if (MS_ISNAN(gradient[i]) || std::isinf(gradient[i])) {
MS_LOG(INFO) << "optimizer grad is nan or inf";
return RET_OUT_OF_TENSOR_RANGE;
}
}
auto is_scale = t->IsScale();
auto scale = t->get_scale();
if (is_scale) {
t->set_scale(1.0f / scale);
for (int i = 0; i < length; ++i) {
gradient[i] *= (1.0f / scale);
}
}
}
return RET_OK;
}
protected:
float default_lr_ = 0.0f;
float lr_ = 0.0f;

View File

@ -22,6 +22,7 @@
#include <iostream>
#include <fstream>
#include <memory>
#include <map>
#include "include/errorcode.h"
#include "src/common/utils.h"
#include "src/tensor.h"
@ -38,12 +39,16 @@
#include "src/common/tensor_util.h"
#include "src/train/train_utils.h"
#include "src/train/train_export.h"
#include "src/common/prim_util.h"
namespace mindspore {
namespace lite {
const char *kGradName = "Gradients";
const char *kOptimizerName = "optimizer";
TrainSession::TrainSession() {
is_train_session_ = true;
InitCallBack();
#ifdef ENABLE_V0
if (VersionManager::GetInstance()->CheckV0Schema()) {
kernel::PopulateTrainV0Parameters();
@ -56,7 +61,7 @@ TrainSession::TrainSession() {
int TrainSession::Init(const Context *context, const TrainCfg *train_cfg) {
if (train_cfg != nullptr) {
train_cfg_ = *train_cfg;
cfg_ = *train_cfg;
}
return lite::LiteSession::Init(context);
}
@ -82,22 +87,88 @@ void TrainSession::RestoreOps(const std::vector<CreatorOp> &restore) {
}
}
void TrainSession::AllocWorkSpace() {
int TrainSession::AllocWorkSpace() {
size_t workspace_size = 0;
for (auto kernel : this->train_kernels_) {
if (workspace_size < static_cast<kernel::InnerKernel *>(kernel->kernel())->workspace_size()) {
workspace_size = static_cast<kernel::InnerKernel *>(kernel->kernel())->workspace_size();
}
}
mindspore::kernel::InnerKernel::AllocWorkspace(workspace_size);
workspace_ = malloc(workspace_size);
if (workspace_ == nullptr) {
MS_LOG(ERROR) << "cannot allocate " << workspace_size << " for workspace";
return RET_ERROR;
}
for (auto kernel : this->train_kernels_) {
static_cast<kernel::InnerKernel *>(kernel->kernel())->set_workspace(workspace_);
}
return RET_OK;
}
void TrainSession::FreeWorkSpace() {
free(workspace_);
for (auto kernel : this->train_kernels_) {
static_cast<kernel::InnerKernel *>(kernel->kernel())->FreeWorkspace();
}
}
int TrainSession::InitCallBack() {
sched_mix_precision_callback_ = [&](const Model::Node *node) {
auto node_type = GetPrimitiveType(node->primitive_);
if (node_type == schema::PrimitiveType_Cast) {
return false;
}
TensorPtrVector inputs;
auto in_size = node->input_indices_.size();
inputs.reserve(in_size);
for (size_t k = 0; k < in_size; ++k) {
inputs.emplace_back(model_->all_tensors_.at(node->input_indices_[k]));
}
bool force_fp16 = (inputs.size() > 0 && std::any_of(inputs.begin(), inputs.end(),
[&](schema::Tensor *tensor) {
return ((tensor->dataType() == kNumberTypeFloat16) &&
(tensor->nodeType() == NodeType_ValueNode));
}))
? true
: false;
inputs.clear();
auto node_name = node->name_;
bool is_fp16 = true;
if (!force_fp16) {
// optimizer runs in fp32
if (node_name.find(kOptimizerName) != std::string::npos) {
is_fp16 = false;
}
// loss function runs in fp32
if ((node_name.find(get_loss_name()) != std::string::npos)) {
is_fp16 = false;
}
// run bn according to user configuration
if ((cfg_.mix_precision_cfg_.keep_batchnorm_fp32_) &&
(node_type == schema::PrimitiveType_FusedBatchNorm || node_type == schema::PrimitiveType_BatchNorm ||
node_type == schema::PrimitiveType_BatchNormGrad)) {
is_fp16 = false;
}
}
MS_LOG(DEBUG) << "Debug: " << node_name << ((is_fp16) ? " fp16" : " fp32");
return is_fp16;
};
return RET_OK;
}
int TrainSession::CompileGraph(lite::Model *model) { return lite::RET_ERROR; }
int TrainSession::CompileTrainGraph(mindspore::lite::Model *model) {
model_ = model;
auto restore = ReplaceOps();
sched_cb_ = std::make_unique<SchedulerCb>(sched_mix_precision_callback_);
if (sched_cb_ == nullptr) {
MS_LOG(ERROR) << "Failed to create SchedulerCb node";
return RET_ERROR;
}
auto ret = lite::LiteSession::CompileGraph(model);
if (ret != RET_OK) {
MS_LOG(ERROR) << "failed to compile train model";
@ -113,26 +184,190 @@ int TrainSession::CompileTrainGraph(mindspore::lite::Model *model) {
CompileTrainOutputs(); // prepare outputs in train mode
CompileEvalOutputs(); // prepare outputs in eval mode
CompileInferenceKernels(); // Prepare a list of eval kernels
AllocWorkSpace();
ret = AllocWorkSpace();
if (ret != RET_OK) {
MS_LOG(ERROR) << "failed to allocate space";
return RET_ERROR;
}
return RET_OK;
}
TrainSession::~TrainSession() {
mindspore::kernel::InnerKernel::FreeWorkspace();
FreeWorkSpace();
if (model_ != nullptr) {
delete model_;
model_ = nullptr;
}
}
int TrainSession::ExecKernels(const KernelCallBack &before, const KernelCallBack &after,
const std::vector<kernel::LiteKernel *> &run_kernels) {
for (auto *kernel : run_kernels) {
MS_ASSERT(nullptr != kernel);
auto ret = kernel->Execute(before, after);
if (RET_OK != ret) {
MS_LOG(ERROR) << "Execute kernel failed, name: " << kernel->name();
return ret;
}
}
return RET_OK;
}
void TrainSession::RestoreTensorData() {
for (auto &restored_origin_tensor : restored_origin_tensors_) {
auto *origin_tensor = restored_origin_tensor.first;
auto *restored_tensor = restored_origin_tensor.second;
MS_ASSERT(origin_tensor != nullptr);
MS_ASSERT(restored_tensor != nullptr);
bool own_data = restored_tensor->own_data();
if (origin_tensor->data_c() == nullptr) {
restored_tensor->FreeData();
} else {
origin_tensor->FreeData();
}
origin_tensor->set_data_type(restored_tensor->data_type());
origin_tensor->set_data(restored_tensor->data_c());
origin_tensor->set_own_data(own_data);
}
}
void TrainSession::FreeRestoreTensors() {
for (auto &restored_origin_tensor : restored_origin_tensors_) {
auto *restored_tensor = restored_origin_tensor.second;
restored_tensor->set_data(nullptr);
delete (restored_tensor);
}
restored_origin_tensors_.clear();
}
bool TrainSession::IsLossTensor(Tensor *tensor) {
MS_ASSERT(tensor != nullptr);
auto t_n = tensor->tensor_name();
return (t_n.find(get_loss_name()) != std::string::npos);
}
bool TrainSession::AllInputsNeedScale(kernel::LiteKernel *kernel) {
auto type = kernel->type();
auto is_scale = false;
for (auto &tensor : kernel->in_tensors()) {
is_scale |= tensor->IsScale();
}
switch (type) {
case schema::PrimitiveType_AbsGrad:
case schema::PrimitiveType_AddFusion:
case schema::PrimitiveType_SubFusion:
case schema::PrimitiveType_AddN:
return (true && is_scale);
default:
return false;
}
return false;
}
int TrainSession::MixPrecisionPreProcess(kernel::LiteKernel *kernel, float scale) {
auto kernel_type = kernel->desc().data_type;
auto all_scale = AllInputsNeedScale(kernel);
for (auto &tensor : kernel->in_tensors()) {
if ((tensor->IsScale() == false) && ((!IsLossKernel(kernel) && IsLossTensor(tensor)) || (all_scale == true))) {
ScaleTensor(tensor, scale);
}
// adjust tensor data type
if (tensor->data_type() != kernel_type) {
auto restore_tensor = CastTensor(tensor, kernel_type);
if (restore_tensor != nullptr) {
restored_origin_tensors_[tensor] = restore_tensor;
}
}
}
return RET_OK;
}
int TrainSession::MixPrecisionPostProcess(kernel::LiteKernel *kernel) {
RestoreTensorData();
FreeRestoreTensors();
float scale = 1.0f;
auto all_scale = AllInputsNeedScale(kernel);
for (auto &tensor : kernel->in_tensors()) {
if (tensor->IsScale()) {
scale *= tensor->get_scale();
if (all_scale) {
break;
}
}
}
for (auto &tensor : kernel->out_tensors()) {
tensor->set_scale(scale);
}
for (auto &tensor : kernel->in_tensors()) {
if ((tensor->IsScale() == true) && ((!IsLossKernel(kernel) && IsLossTensor(tensor)) || (all_scale == true))) {
ScaleTensor(tensor, 1.0f / scale);
}
}
return RET_OK;
}
int TrainSession::MixPrecisionExecKernels(const KernelCallBack &before, const KernelCallBack &after,
const std::vector<kernel::LiteKernel *> &run_kernels) {
float scale = cfg_.mix_precision_cfg_.loss_scale_;
for (auto *kernel : run_kernels) {
MS_ASSERT(nullptr != kernel);
MixPrecisionPreProcess(kernel, scale);
auto ret = kernel->Execute(before, after);
if (RET_OK != ret) {
MixPrecisionPostProcess(kernel);
// decrease loss scale in case of nan or inf
if (ret == RET_OUT_OF_TENSOR_RANGE) {
bool is_dynamic_scale = cfg_.mix_precision_cfg_.dynamic_loss_scale_;
cfg_.mix_precision_cfg_.loss_scale_ = std::max(((is_dynamic_scale) ? (scale / 2.f) : scale), 1.0f);
num_of_not_nan_iter_ = 0;
return RET_OK;
}
MS_LOG(ERROR) << "Execute kernel failed, name: " << kernel->name();
return ret;
}
MixPrecisionPostProcess(kernel);
}
// increase dynamic loss scale if pass pass threshold
if (cfg_.mix_precision_cfg_.dynamic_loss_scale_) {
num_of_not_nan_iter_++;
if (num_of_not_nan_iter_ >= cfg_.mix_precision_cfg_.num_of_not_nan_iter_th_) {
cfg_.mix_precision_cfg_.loss_scale_ = std::min((cfg_.mix_precision_cfg_.loss_scale_ * 2.0f), 65536.0f);
num_of_not_nan_iter_ = 0;
}
}
// cast output to FP32
if (train_mode_ == false) {
for (auto t : this->outputs_) {
if (t->data_type() == kNumberTypeFloat16) {
auto restore = CastTensor(t, kNumberTypeFloat32);
delete restore;
}
}
}
return RET_OK;
}
int TrainSession::RunGraph(const KernelCallBack &before, const KernelCallBack &after) {
this->outputs_.clear();
// check inputs
auto ret = CheckTensorsInvalid(inputs_);
if (ret != RET_OK) {
MS_LOG(ERROR) << "CheckInputs failed";
return ret;
}
// build out tensor
for (auto ms_tensors : output_node_map_) {
for (auto ms_tensor : ms_tensors.second) {
this->outputs_.push_back((static_cast<lite::Tensor *>(ms_tensor)));
this->outputs_.clear();
for (auto &ms_tensors : output_node_map_) {
for (auto &ms_tensor : ms_tensors.second) {
auto lite_tensor = static_cast<lite::Tensor *>(ms_tensor);
this->outputs_.push_back(lite_tensor);
}
}
@ -140,21 +375,15 @@ int TrainSession::RunGraph(const KernelCallBack &before, const KernelCallBack &a
MS_LOG(ERROR) << "context is null";
return lite::RET_NULL_PTR;
}
auto run_kernel = (train_mode_) ? train_kernels_ : inference_kernels_;
auto ret = CheckTensorsInvalid(inputs_);
if (ret != RET_OK) {
MS_LOG(ERROR) << "CheckInputs failed";
return ret;
auto &run_kernels = (train_mode_) ? train_kernels_ : inference_kernels_;
if (context_->IsCpuFloat16Enabled()) {
ret = MixPrecisionExecKernels(before, after, run_kernels);
} else {
ret = ExecKernels(before, after, run_kernels);
}
for (auto *kernel : run_kernel) {
MS_ASSERT(nullptr != kernel);
ret = kernel->Execute(before, after);
if (RET_OK != ret) {
MS_LOG(ERROR) << "run kernel failed, name: " << kernel->name();
return ret;
}
if (ret != RET_OK) {
MS_LOG(ERROR) << "failed to run model kernels";
return ret;
}
if (train_mode_ && virtual_batch_multiplier_) {
@ -175,7 +404,7 @@ int TrainSession::Train() {
// shift kernels to train mode
train_mode_ = true;
virtual_batch_idx_ = 0;
for (auto kernel : this->train_kernels_) {
for (auto &kernel : this->train_kernels_) {
MS_ASSERT(nullptr != kernel);
auto ret = kernel->Train();
if (ret != RET_OK) {
@ -194,7 +423,7 @@ int TrainSession::Eval() {
// shift kernels to eval mode
train_mode_ = false;
virtual_batch_idx_ = 0;
for (auto kernel : this->train_kernels_) {
for (auto &kernel : this->train_kernels_) {
MS_ASSERT(kernel != nullptr);
auto ret = kernel->Eval();
if (ret != RET_OK) {
@ -427,11 +656,11 @@ bool TrainSession::IsLossKernel(const kernel::LiteKernel *kernel) const {
kernel->type() == schema::PrimitiveType_SmoothL1LossGrad ||
kernel->type() == schema::PrimitiveType_SigmoidCrossEntropyWithLogits ||
kernel->type() == schema::PrimitiveType_SigmoidCrossEntropyWithLogitsGrad) ||
kernel->name().find(train_cfg_.loss_name_) != std::string::npos;
kernel->name().find(cfg_.loss_name_) != std::string::npos;
}
bool TrainSession::IsGradKernel(const kernel::LiteKernel *kernel) const {
return kernel->name().find("Gradients") != std::string::npos;
return kernel->name().find(kGradName) != std::string::npos;
}
bool TrainSession::IsOptimizer(kernel::LiteKernel *kernel) const {
@ -478,12 +707,18 @@ int TrainSession::Export(const std::string &file_name, ModelType model_type, Qua
if (orig_train_state) Train();
return status;
}
} // namespace lite
session::LiteSession *session::LiteSession::CreateTrainSession(const std::string &fn, const lite::Context *context,
bool train_mode, const lite::TrainCfg *cfg) {
auto session = new (std::nothrow) lite::TrainSession();
if (cfg != nullptr) {
// test legal configuration
if (cfg->mix_precision_cfg_.loss_scale_ <= 0) {
MS_LOG(ERROR) << "illegal loss scale configuration";
return nullptr;
}
}
auto session = std::make_unique<lite::TrainSession>();
if (session == nullptr) {
MS_LOG(ERROR) << "create session failed";
return nullptr;
@ -492,7 +727,6 @@ session::LiteSession *session::LiteSession::CreateTrainSession(const std::string
auto ret = session->Init(context, cfg);
if (ret != mindspore::lite::RET_OK) {
MS_LOG(ERROR) << "init session failed";
delete session;
return nullptr;
}
@ -504,14 +738,12 @@ session::LiteSession *session::LiteSession::CreateTrainSession(const std::string
auto *model = mindspore::lite::Model::Import(filename.c_str());
if (model == nullptr) {
MS_LOG(ERROR) << "create model for train session failed " << filename;
delete session;
return nullptr;
}
ret = session->CompileTrainGraph(model);
if (ret != mindspore::lite::RET_OK) {
MS_LOG(ERROR) << "Compiling Train Graph session failed";
delete session;
return nullptr;
}
@ -522,10 +754,10 @@ session::LiteSession *session::LiteSession::CreateTrainSession(const std::string
}
if (ret != mindspore::lite::RET_OK) {
MS_LOG(ERROR) << "Could not switch to Train Modei " << train_mode;
delete session;
return nullptr;
}
return session;
return session.release();
}
} // namespace mindspore

View File

@ -92,7 +92,7 @@ class TrainSession : virtual public lite::LiteSession {
int Export(const std::string &fb_name, ModelType model_type, QuantizationType quant_type, FormatType) override;
protected:
void AllocWorkSpace();
int AllocWorkSpace();
bool IsLossKernel(const kernel::LiteKernel *kernel) const;
bool IsGradKernel(const kernel::LiteKernel *kernel) const;
bool IsOptimizer(kernel::LiteKernel *kernel) const;
@ -106,9 +106,9 @@ class TrainSession : virtual public lite::LiteSession {
virtual void CompileOptimizedKernels();
virtual void CompileTrainOutputs();
virtual void CompileEvalOutputs();
virtual int InitCallBack();
Model *model_ = nullptr;
TrainCfg train_cfg_;
// TrainCfg train_cfg_;
std::unordered_map<std::string, std::vector<mindspore::tensor::MSTensor *>> orig_output_node_map_;
std::unordered_map<std::string, mindspore::tensor::MSTensor *> orig_output_tensor_map_;
std::vector<std::string> orig_output_tensor_names_;
@ -123,21 +123,31 @@ class TrainSession : virtual public lite::LiteSession {
std::vector<kernel::LiteKernel *> inference_kernels_;
std::vector<kernel::LiteKernel *> train_kernels_;
TrainCfg cfg_;
private:
std::string get_loss_name() const { return cfg_.loss_name_; }
void BuildInferenceKernelsRecursive(kernel::LiteKernel *ker, std::vector<kernel::LiteKernel *> *req_kernels);
int AdminSetupVirtualBatch(int virtual_batch_multiplier, float lr, float momentum);
int OptimizerStep();
int ExecKernels(const KernelCallBack &before, const KernelCallBack &after,
std::vector<kernel::LiteKernel *> run_kernel);
const std::vector<kernel::LiteKernel *> &run_kernel);
int MixPrecisionExecKernels(const KernelCallBack &before, const KernelCallBack &after,
std::vector<kernel::LiteKernel *> run_kernel);
int CopyTensor(Tensor *tensor, TypeId dst_data_type);
const std::vector<kernel::LiteKernel *> &run_kernel);
int MixPrecisionPreProcess(kernel::LiteKernel *kernel, float scale);
int MixPrecisionPostProcess(kernel::LiteKernel *kernel);
bool IsLossTensor(Tensor *tensor);
void RestoreTensorData();
void FreeRestoreTensors();
bool AllInputsNeedScale(kernel::LiteKernel *kernel);
void FreeWorkSpace();
std::map<Tensor *, Tensor *> restored_origin_tensors_;
int virtual_batch_idx_ = 0;
int virtual_batch_multiplier_ = 0;
uint32_t num_of_not_nan_iter_ = 0;
void *workspace_ = nullptr;
SchedCallBack sched_mix_precision_callback_;
bool train_mode_ = false;
};

View File

@ -20,6 +20,9 @@
#include "include/ms_tensor.h"
#include "src/common/utils.h"
#include "src/lite_kernel.h"
#ifdef ENABLE_FP16
#include "src/runtime/kernel/arm/fp16/fp16_op_handler.h"
#endif
namespace mindspore {
namespace lite {
@ -50,7 +53,7 @@ kernel::LiteKernel *TSFindKernel(const std::vector<kernel::LiteKernel *> &where,
float CalculateSparseClassification(tensor::MSTensor *input, tensor::MSTensor *output) {
if ((input->shape().size() != 1) || (input->data_type() != kNumberTypeInt32) || (output->shape().size() != 2)) {
MS_LOG(WARNING) << "SparceClassification got a " << input->shape() << "-D input tensor, " << output->shape()
MS_LOG(WARNING) << "SparseClassification got a " << input->shape() << "-D input tensor, " << output->shape()
<< "-D output tensor";
return 0.0;
}
@ -106,5 +109,72 @@ float CalculateOneHotClassification(tensor::MSTensor *input, tensor::MSTensor *o
return accuracy / (static_cast<float>(batch_size));
}
Tensor *CastTensor(Tensor *tensor, TypeId dst_data_type) {
#ifdef ENABLE_FP16
MS_ASSERT(tensor != nullptr);
std::vector<TypeId> valid_type = {kNumberTypeFloat32, kNumberTypeFloat16, kNumberTypeFloat};
std::vector<TypeId> fp32_type = {kNumberTypeFloat32, kNumberTypeFloat};
if (!IsContain(valid_type, tensor->data_type())) {
MS_LOG(ERROR) << "source data type must be fp32 or fp16";
return nullptr;
}
if (!IsContain(valid_type, dst_data_type)) {
MS_LOG(ERROR) << "destination data type must be fp32 or fp16";
return nullptr;
}
auto origin_data = tensor->data_c();
MS_ASSERT(origin_data != nullptr);
auto restore_tensor = Tensor::CopyTensor(*tensor, false);
restore_tensor->set_data(origin_data);
restore_tensor->set_own_data(tensor->own_data());
restore_tensor->set_allocator(tensor->allocator());
restore_tensor->set_scale(tensor->get_scale());
if (IsContain(fp32_type, tensor->data_type()) && dst_data_type == kNumberTypeFloat16) {
tensor->set_data(nullptr);
tensor->set_data_type(kNumberTypeFloat16);
auto ret = tensor->MallocData();
auto new_tensor_data = tensor->data_c();
MS_ASSERT(new_tensor_data != nullptr);
if (RET_OK != ret) {
MS_LOG(ERROR) << "malloc data failed";
delete restore_tensor;
return nullptr;
}
MS_LOG(DEBUG) << "Convert tensor to fp16 " << tensor->tensor_name();
Float32ToFloat16_fp16_handler(origin_data, new_tensor_data, tensor->ElementsNum());
} else {
tensor->set_data(nullptr);
tensor->set_data_type(kNumberTypeFloat32);
auto ret = tensor->MallocData();
if (RET_OK != ret) {
MS_LOG(ERROR) << "malloc data failed";
delete restore_tensor;
return nullptr;
}
auto new_tensor_data = tensor->data_c();
MS_ASSERT(new_tensor_data != nullptr);
MS_LOG(DEBUG) << "Convert tensor to fp32 " << tensor->tensor_name();
Float16ToFloat32_fp16_handler(origin_data, new_tensor_data, tensor->ElementsNum());
}
return restore_tensor;
#else
return nullptr;
#endif
}
int ScaleTensor(Tensor *tensor, float scale) {
MS_ASSERT(tensor != nullptr);
std::vector<TypeId> valid_type = {kNumberTypeFloat32, kNumberTypeFloat};
if (!IsContain(valid_type, tensor->data_type())) {
MS_LOG(DEBUG) << "Tensor: " << tensor->tensor_name() << " type is " << tensor->data_type();
return RET_OK;
}
MS_LOG(DEBUG) << "Scale tensor: " << tensor->tensor_name() << " " << scale;
return tensor->Scale<float>(scale);
}
} // namespace lite
} // namespace mindspore

View File

@ -35,7 +35,8 @@ kernel::LiteKernel *TSFindKernel(const std::vector<kernel::LiteKernel *> &where,
size_t TSFindTensor(const std::vector<lite::Tensor *> &where, const lite::Tensor *searchParameter);
float CalculateSparseClassification(tensor::MSTensor *input, tensor::MSTensor *output);
float CalculateOneHotClassification(tensor::MSTensor *input, tensor::MSTensor *output);
Tensor *CastTensor(Tensor *tensor, TypeId dst_data_type);
int ScaleTensor(Tensor *tensor, float scale);
} // namespace lite
} // namespace mindspore
#endif // MINDSPORE_LITE_SRC_TRAIN_TRAIN_UTILS_H_

View File

@ -10,6 +10,7 @@ effnet_tune
googlenet
densenet
shufflenetv2
# xception
mini_alexnet weight_quant 2
nin weight_quant 9
lenet weight_quant 5
@ -22,5 +23,15 @@ effnet_tune weight_quant 7
googlenet weight_quant 10
densenet weight_quant 11
shufflenetv2 weight_quant 3
# xception
#mini_alexnet fp16 6
#nin fp16 8.0
#lenet fp16 2
mobilenetv1 fp16 2
mobilenetv2 fp16 2
#mobilenetv3 fp16 7
effnet fp16 2
#effnet_tune fp16 5.0
resnet fp16 2
#googlenet fp16 10
#xception fp16 20.0
# LAST

View File

@ -53,6 +53,13 @@ function Run_Converter() {
if [[ $model_name == \#* ]]; then
continue
fi
if [[ "${line_array[1]}" == "fp16" ]]; then
ms_file=$ms_models_path'/'$model_name'.ms'
if [ -f "$ms_file" ]; then
echo $model_name'.ms already exist, continue without convert'
continue
fi
fi
if [[ "${line_array[1]}" == "weight_quant" ]]; then
WEIGHT_QUANT="--quantType=WeightQuant --bitNum=8 --quantWeightSize=0 --quantWeightChannel=0"
model_name=${line_array[0]}'_train_quant'
@ -88,6 +95,8 @@ function Run_x86() {
if [[ "${line_array[1]}" == "weight_quant" ]]; then
model_name=${line_array[0]}'_train_quant'
accuracy_limit=${line_array[2]}
elif [[ "${line_array[1]}" == "fp16" ]]; then
continue
fi
export_file="${ms_models_path}/${model_name}_tod"
inference_file="${ms_models_path}/${model_name}_infer"
@ -171,6 +180,8 @@ function Run_arm() {
model_prefix=${line_array[0]}
model_name=${line_array[0]}'_train'
accuracy_limit=0.5
enable_fp16="false"
suffix_print=""
if [[ $model_name == \#* ]]; then
continue
fi
@ -185,6 +196,17 @@ function Run_arm() {
run_result=$1': '${model_name}' irrelevant'; echo ${run_result} >> ${run_benchmark_train_result_file}
continue
fi
if [[ "${line_array[1]}" == "fp16" ]]; then
if [[ "$1" == arm64 ]]; then
enable_fp16="true"
suffix_print="_fp16"
accuracy_limit=${line_array[2]}
else
continue
fi
fi
# run benchmark_train test without clib data
echo ${model_name} >> "${run_arm_log_file}"
adb -s ${device_id} push ${train_io_path}/${model_prefix}_input*.bin ${train_io_path}/${model_prefix}_output*.bin /data/local/tmp/benchmark_train_test >> ${adb_push_log_file}
@ -207,6 +229,7 @@ function Run_arm() {
--expectedDataFile=${tmp_dir}/${model_prefix}_output \
--numThreads=${threads} \
--accuracyThreshold=${accuracy_limit} \
--enableFp16=${enable_fp16} \
--inferenceFile=${inference_file} \
--exportFile=${export_file}
ENDM
@ -216,9 +239,9 @@ ENDM
adb -s ${device_id} shell < ${adb_cmd_run_file} >> ${run_arm_log_file}
# TODO: change to arm_type
if [ $? = 0 ]; then
run_result=$1': '${model_name}' pass'; echo ${run_result} >> ${run_benchmark_train_result_file}
run_result=$1': '${model_name}''${suffix_print}' pass'; echo ${run_result} >> ${run_benchmark_train_result_file}
else
run_result=$1': '${model_name}' failed'; echo ${run_result} >> ${run_benchmark_train_result_file};
run_result=$1': '${model_name}''${suffix_print}' failed'; echo ${run_result} >> ${run_benchmark_train_result_file};
fail=1
fi

View File

@ -86,8 +86,12 @@ TEST_F(TestFcFp32, FcTest1) {
ASSERT_EQ(lite::RET_OK, ctx->Init());
auto *fc = new kernel::FullconnectionCPUKernel(reinterpret_cast<OpParameter *>(matmul_param), inputs_, outputs_, ctx);
fc->Init();
#ifdef SUPPORT_TRAIN
fc->AllocWorkspace();
#endif
fc->Run();
ASSERT_EQ(0, CompareOutputData(reinterpret_cast<float *>(outputs_[0]->MutableData()), correct, total_size, 0.0001));
delete fc;
delete ctx;
}
@ -146,8 +150,12 @@ TEST_F(TestFcFp32, FcTest2) {
ASSERT_EQ(lite::RET_OK, ctx->Init());
auto *fc = new kernel::FullconnectionCPUKernel(reinterpret_cast<OpParameter *>(matmul_param), inputs_, outputs_, ctx);
fc->Init();
#ifdef SUPPORT_TRAIN
fc->AllocWorkspace();
#endif
fc->Run();
ASSERT_EQ(0, CompareOutputData(reinterpret_cast<float *>(outputs_[0]->MutableData()), correct, total_size, 0.0001));
delete fc;
delete ctx;
}
@ -196,11 +204,15 @@ TEST_F(TestFcFp32, FcTest3) {
ASSERT_EQ(lite::RET_OK, ctx->Init());
auto *fc = new kernel::FullconnectionCPUKernel(reinterpret_cast<OpParameter *>(matmul_param), inputs_, outputs_, ctx);
fc->Init();
#ifdef SUPPORT_TRAIN
fc->AllocWorkspace();
#endif
struct timeval start, end;
gettimeofday(&start, nullptr);
for (int i = 0; i < 100000; ++i) fc->Run();
gettimeofday(&end, nullptr);
// printf("## elapsed: %llu\n", 1000000 * (end.tv_sec - start.tv_sec) + end.tv_usec - end.tv_usec);
delete fc;
delete ctx;
}

View File

@ -86,10 +86,9 @@ TEST_F(TestBNGradFp32, BNGradFp32) {
ASSERT_NE(creator, nullptr);
auto kernel_obj = creator(inputs, outputs, reinterpret_cast<OpParameter *>(bn_param), &ctx, desc);
ASSERT_NE(kernel_obj, nullptr);
mindspore::kernel::InnerKernel::AllocWorkspace(kernel_obj->workspace_size());
auto ret = kernel_obj->Init();
EXPECT_EQ(0, ret);
kernel_obj->AllocWorkspace();
ret = kernel_obj->Run();
EXPECT_EQ(0, ret);
std::cout << "==========dx==========\n";
@ -114,7 +113,6 @@ TEST_F(TestBNGradFp32, BNGradFp32) {
v->set_data(nullptr);
delete v;
}
mindspore::kernel::InnerKernel::FreeWorkspace();
delete kernel_obj;
MS_LOG(INFO) << "BNGradFp32 passed";
}
@ -182,7 +180,7 @@ TEST_F(TestBNGradFp32, BNTtrainFp32) {
ASSERT_NE(creator, nullptr);
auto kernel_obj = creator(inputs, outputs, reinterpret_cast<OpParameter *>(bn_param), &context, desc);
ASSERT_NE(kernel_obj, nullptr);
mindspore::kernel::InnerKernel::AllocWorkspace(kernel_obj->workspace_size());
kernel_obj->AllocWorkspace();
float *save_mean = reinterpret_cast<float *>(save_mean_tensor.MutableData());
float *save_var = reinterpret_cast<float *>(save_var_tensor.MutableData());
for (int i = 0; i < channels; i++) {
@ -213,7 +211,6 @@ TEST_F(TestBNGradFp32, BNTtrainFp32) {
x_tensor->set_data(nullptr);
delete x_tensor;
mindspore::kernel::InnerKernel::FreeWorkspace();
delete kernel_obj;
}
} // namespace mindspore

View File

@ -121,8 +121,7 @@ TEST_F(TestConvolutionGradFp32, ConvFp32FilterGrad) {
ASSERT_NE(kernel, nullptr);
auto ret = kernel->Init();
EXPECT_EQ(0, ret);
mindspore::kernel::InnerKernel::AllocWorkspace(kernel->workspace_size());
kernel->AllocWorkspace();
// warm up loop
for (int i = 0; i < 3; i++) {
kernel->Run();
@ -146,7 +145,6 @@ TEST_F(TestConvolutionGradFp32, ConvFp32FilterGrad) {
delete[] input_data;
delete[] dy_data;
delete[] dw_data;
mindspore::kernel::InnerKernel::FreeWorkspace();
delete kernel;
// delete conv_param;
dw_tensor.set_data(nullptr);
@ -201,8 +199,7 @@ TEST_F(TestConvolutionGradFp32, ConvFp32InputGrad) {
ASSERT_NE(kernel, nullptr);
auto ret = kernel->Init();
EXPECT_EQ(0, ret);
mindspore::kernel::InnerKernel::AllocWorkspace(kernel->workspace_size());
kernel->AllocWorkspace();
// warm up loop
for (int i = 0; i < 3; i++) {
kernel->Run();
@ -227,7 +224,6 @@ TEST_F(TestConvolutionGradFp32, ConvFp32InputGrad) {
w_tensor.set_data(nullptr);
dy_tensor.set_data(nullptr);
dx_tensor.set_data(nullptr);
mindspore::kernel::InnerKernel::FreeWorkspace();
delete kernel;
// delete conv_param;
@ -279,7 +275,7 @@ TEST_F(TestConvolutionGradFp32, ConvFp32GroupFilterGrad) {
ASSERT_NE(kernel, nullptr);
auto ret = kernel->Init();
EXPECT_EQ(0, ret);
mindspore::kernel::InnerKernel::AllocWorkspace(kernel->workspace_size());
kernel->AllocWorkspace();
kernel->Run();
int loop_count = 100;
@ -302,7 +298,6 @@ TEST_F(TestConvolutionGradFp32, ConvFp32GroupFilterGrad) {
dw_tensor.set_data(nullptr);
x_tensor.set_data(nullptr);
dy_tensor.set_data(nullptr);
mindspore::kernel::InnerKernel::FreeWorkspace();
delete kernel;
// delete conv_param;
MS_LOG(INFO) << "TestConvolutionGradFp32 Filter Grad passed";
@ -354,7 +349,7 @@ TEST_F(TestConvolutionGradFp32, ConvFp32GroupInputGrad) {
ASSERT_NE(kernel, nullptr);
auto ret = kernel->Init();
EXPECT_EQ(0, ret);
mindspore::kernel::InnerKernel::AllocWorkspace(kernel->workspace_size());
kernel->AllocWorkspace();
// warm up loop
for (int i = 0; i < 3; i++) {
kernel->Run();
@ -379,9 +374,8 @@ TEST_F(TestConvolutionGradFp32, ConvFp32GroupInputGrad) {
dx_tensor.set_data(nullptr);
w_tensor.set_data(nullptr);
dy_tensor.set_data(nullptr);
delete kernel;
mindspore::kernel::InnerKernel::FreeWorkspace();
// delete conv_param;
MS_LOG(INFO) << "TestConvolutionGradFp32 Filter Grad passed";
}
@ -431,8 +425,7 @@ TEST_F(TestConvolutionGradFp32, ConvFp32GroupDilationFilterGrad) {
ASSERT_NE(kernel, nullptr);
auto ret = kernel->Init();
EXPECT_EQ(0, ret);
mindspore::kernel::InnerKernel::AllocWorkspace(kernel->workspace_size());
kernel->AllocWorkspace();
// warm up loop
for (int i = 0; i < 3; i++) {
kernel->Run();
@ -457,7 +450,6 @@ TEST_F(TestConvolutionGradFp32, ConvFp32GroupDilationFilterGrad) {
dw_tensor.set_data(nullptr);
dy_tensor.set_data(nullptr);
x_tensor.set_data(nullptr);
mindspore::kernel::InnerKernel::FreeWorkspace();
delete kernel;
// delete conv_param;
MS_LOG(INFO) << "TestConvolutionGradFp32 Filter Grad passed";
@ -509,8 +501,7 @@ TEST_F(TestConvolutionGradFp32, ConvFp32GroupDilationInputGrad) {
ASSERT_NE(kernel, nullptr);
auto ret = kernel->Init();
EXPECT_EQ(0, ret);
mindspore::kernel::InnerKernel::AllocWorkspace(kernel->workspace_size());
kernel->AllocWorkspace();
int loop_count = 100;
auto time_start = mindspore::lite::GetTimeUs();
for (int i = 0; i < loop_count; i++) {
@ -530,7 +521,6 @@ TEST_F(TestConvolutionGradFp32, ConvFp32GroupDilationInputGrad) {
dx_tensor.set_data(nullptr);
dy_tensor.set_data(nullptr);
w_tensor.set_data(nullptr);
mindspore::kernel::InnerKernel::FreeWorkspace();
delete kernel;
// delete conv_param;
MS_LOG(INFO) << "TestConvolutionGradFp32 Filter Grad passed";
@ -579,7 +569,7 @@ TEST_F(TestConvolutionGradFp32, ConvGroupDilation) {
outputs, &context);
ASSERT_NE(kernel, nullptr);
kernel->Init();
mindspore::kernel::InnerKernel::AllocWorkspace(kernel->workspace_size());
kernel->AllocWorkspace();
kernel->Train();
EXPECT_EQ(kernel->IsTrain(), 1);
@ -609,7 +599,6 @@ TEST_F(TestConvolutionGradFp32, ConvGroupDilation) {
x_tensor.set_data(nullptr);
y_tensor.set_data(nullptr);
w_tensor.set_data(nullptr);
mindspore::kernel::InnerKernel::FreeWorkspace();
delete kernel;
MS_LOG(INFO) << "TestConvolutionFp32 Filter Grad passed";
@ -688,8 +677,7 @@ TEST_F(TestConvolutionGradFp32, ConvFp32Dilation2Group2Stride2FilterGrad) {
ASSERT_NE(kernel, nullptr);
auto ret = kernel->Init();
EXPECT_EQ(0, ret);
mindspore::kernel::InnerKernel::AllocWorkspace(kernel->workspace_size());
kernel->AllocWorkspace();
// warm up loop
for (int i = 0; i < 3; i++) {
kernel->Run();
@ -718,7 +706,6 @@ TEST_F(TestConvolutionGradFp32, ConvFp32Dilation2Group2Stride2FilterGrad) {
dw_tensor.set_data(nullptr);
x_tensor.set_data(nullptr);
dy_tensor.set_data(nullptr);
mindspore::kernel::InnerKernel::FreeWorkspace();
MS_LOG(INFO) << "TestConvolutionGradFp32 Filter Grad passed";
}
@ -797,7 +784,7 @@ TEST_F(TestConvolutionGradFp32, ConvGroup2Dilation2Stride2) {
ASSERT_NE(kernel, nullptr);
auto ret = kernel->Init();
EXPECT_EQ(0, ret);
mindspore::kernel::InnerKernel::AllocWorkspace(kernel->workspace_size());
kernel->AllocWorkspace();
// warm up loop
for (int i = 0; i < 3; i++) {
@ -824,7 +811,6 @@ TEST_F(TestConvolutionGradFp32, ConvGroup2Dilation2Stride2) {
dy_tensor.set_data(nullptr);
w_tensor.set_data(nullptr);
delete kernel;
mindspore::kernel::InnerKernel::FreeWorkspace();
MS_LOG(INFO) << "TestConvolutionGradFp32 Filter Grad passed";
}

View File

@ -100,7 +100,7 @@ TEST_F(TestDeConvolutionGradFp32, DeConvFp32FilterGrad) {
ASSERT_NE(kernel, nullptr);
auto ret = kernel->Init();
EXPECT_EQ(0, ret);
mindspore::kernel::InnerKernel::AllocWorkspace(kernel->workspace_size());
kernel->AllocWorkspace();
// warm up loop
for (int i = 0; i < 3; i++) {
@ -133,7 +133,7 @@ TEST_F(TestDeConvolutionGradFp32, DeConvFp32FilterGrad) {
dw_tensor.set_data(nullptr);
x_tensor.set_data(nullptr);
dy_tensor.set_data(nullptr);
mindspore::kernel::InnerKernel::FreeWorkspace();
MS_LOG(INFO) << "TestDeConvolutionGradFp32 Filter Grad passed";
}
@ -208,9 +208,7 @@ TEST_F(TestDeConvolutionGradFp32, DeConvFp32Dilation2FilterGrad) {
ASSERT_NE(kernel, nullptr);
auto ret = kernel->Init();
EXPECT_EQ(0, ret);
mindspore::kernel::InnerKernel::AllocWorkspace(kernel->workspace_size());
for (int i = 0; i < 3; i++) {
}
kernel->AllocWorkspace();
// runtime part
printf("Calculating runtime cost...\n");
@ -238,7 +236,6 @@ TEST_F(TestDeConvolutionGradFp32, DeConvFp32Dilation2FilterGrad) {
dw_tensor.set_data(nullptr);
x_tensor.set_data(nullptr);
dy_tensor.set_data(nullptr);
mindspore::kernel::InnerKernel::FreeWorkspace();
MS_LOG(INFO) << "TestDeConvolutionGradFp32 Filter Grad passed";
}
@ -316,7 +313,7 @@ TEST_F(TestDeConvolutionGradFp32, DeConvFp32Dilation2Group3FilterGrad) {
ASSERT_NE(kernel, nullptr);
auto ret = kernel->Init();
EXPECT_EQ(0, ret);
mindspore::kernel::InnerKernel::AllocWorkspace(kernel->workspace_size());
kernel->AllocWorkspace();
// warm up loop
for (int i = 0; i < 3; i++) {
@ -346,7 +343,6 @@ TEST_F(TestDeConvolutionGradFp32, DeConvFp32Dilation2Group3FilterGrad) {
dw_tensor.set_data(nullptr);
x_tensor.set_data(nullptr);
dy_tensor.set_data(nullptr);
mindspore::kernel::InnerKernel::FreeWorkspace();
MS_LOG(INFO) << "TestDeConvolutionGradFp32 Filter Grad passed";
}
@ -421,7 +417,7 @@ TEST_F(TestDeConvolutionGradFp32, DeConvFp32Dilation2Group3Stride1FilterGrad) {
ASSERT_NE(kernel, nullptr);
auto ret = kernel->Init();
EXPECT_EQ(0, ret);
mindspore::kernel::InnerKernel::AllocWorkspace(kernel->workspace_size());
kernel->AllocWorkspace();
// warm up loop
for (int i = 0; i < 3; i++) {
@ -454,7 +450,6 @@ TEST_F(TestDeConvolutionGradFp32, DeConvFp32Dilation2Group3Stride1FilterGrad) {
dw_tensor.set_data(nullptr);
x_tensor.set_data(nullptr);
dy_tensor.set_data(nullptr);
mindspore::kernel::InnerKernel::FreeWorkspace();
MS_LOG(INFO) << "TestDeConvolutionGradFp32 Filter Grad passed";
}
@ -529,7 +524,7 @@ TEST_F(TestDeConvolutionGradFp32, DeConvFp32Dilation2Group2Stride2FilterGrad) {
ASSERT_NE(kernel, nullptr);
auto ret = kernel->Init();
EXPECT_EQ(0, ret);
mindspore::kernel::InnerKernel::AllocWorkspace(kernel->workspace_size());
kernel->AllocWorkspace();
// warm up loop
for (int i = 0; i < 3; i++) {
@ -562,7 +557,6 @@ TEST_F(TestDeConvolutionGradFp32, DeConvFp32Dilation2Group2Stride2FilterGrad) {
dw_tensor.set_data(nullptr);
x_tensor.set_data(nullptr);
dy_tensor.set_data(nullptr);
mindspore::kernel::InnerKernel::FreeWorkspace();
MS_LOG(INFO) << "TestDeConvolutionGradFp32 Filter Grad passed";
}
@ -640,7 +634,7 @@ TEST_F(TestDeConvolutionGradFp32, DeConvFp32Dilation2Group12Stride2FilterGrad) {
ASSERT_NE(kernel, nullptr);
auto ret = kernel->Init();
EXPECT_EQ(0, ret);
mindspore::kernel::InnerKernel::AllocWorkspace(kernel->workspace_size());
kernel->AllocWorkspace();
// warm up loop
for (int i = 0; i < 3; i++) {
@ -670,7 +664,6 @@ TEST_F(TestDeConvolutionGradFp32, DeConvFp32Dilation2Group12Stride2FilterGrad) {
dw_tensor.set_data(nullptr);
x_tensor.set_data(nullptr);
dy_tensor.set_data(nullptr);
mindspore::kernel::InnerKernel::FreeWorkspace();
MS_LOG(INFO) << "TestDeConvolutionGradFp32 Filter Grad passed";
}

View File

@ -148,9 +148,10 @@ TEST_F(NetworkTest, noname) {
context.device_list_[0].device_info_.cpu_device_info_.cpu_bind_mode_ = lite::NO_BIND;
context.thread_num_ = 1;
auto session = mindspore::session::LiteSession::CreateTrainSession(net, &context);
lite::TrainCfg cfg;
cfg.loss_name_ = "nhwc";
auto session = mindspore::session::LiteSession::CreateTrainSession(net, &context, true, &cfg);
ASSERT_NE(session, nullptr);
auto tensors_map = session->GetOutputs();
auto tensor_names = session->GetOutputTensorNames();
EXPECT_EQ(tensors_map.size(), 1);

View File

@ -76,12 +76,11 @@ TEST_F(TestSoftmaxCrossEntropyFp32, SoftmaxCrossEntropyFp32) {
ASSERT_NE(creator, nullptr);
auto kernel_obj = creator(inputs, outputs, reinterpret_cast<OpParameter *>(sce_param), &context, desc);
ASSERT_NE(kernel_obj, nullptr);
mindspore::kernel::InnerKernel::AllocWorkspace(kernel_obj->workspace_size());
auto ret = kernel_obj->Init();
EXPECT_EQ(0, ret);
kernel_obj->AllocWorkspace();
ret = kernel_obj->Run();
EXPECT_EQ(0, ret);
printf("==================total loss=================\n");
std::cout << loss[0] << " ," << std::endl;
@ -114,7 +113,6 @@ TEST_F(TestSoftmaxCrossEntropyFp32, SoftmaxCrossEntropyFp32) {
y_tensor.set_data(nullptr);
loss_tensor.set_data(nullptr);
grad_tensor.set_data(nullptr);
mindspore::kernel::InnerKernel::FreeWorkspace();
delete kernel_obj;
MS_LOG(INFO) << "SoftmaxCrossEntropyFp32 passed";
}

View File

@ -93,7 +93,7 @@ int NetTrain::GenerateInputData(std::vector<mindspore::tensor::MSTensor *> *ms_i
auto status = GenerateRandomData(tensor_byte_size, input_data);
if (status != RET_OK) {
std::cerr << "GenerateRandomData for inTensor failed: " << status << std::endl;
MS_LOG(ERROR) << "GenerateRandomData for inTensor failed:" << status;
MS_LOG(ERROR) << "GenerateRandomData for inTensor failed: " << status;
return status;
}
}
@ -111,8 +111,8 @@ int NetTrain::LoadInput(std::vector<mindspore::tensor::MSTensor *> *ms_inputs) {
} else {
auto status = ReadInputFile(ms_inputs);
if (status != RET_OK) {
std::cerr << "ReadInputFile error, " << status << std::endl;
MS_LOG(ERROR) << "ReadInputFile error, " << status;
std::cerr << "Read Input File error, " << status << std::endl;
MS_LOG(ERROR) << "Read Input File error, " << status;
return status;
}
}
@ -172,7 +172,7 @@ int NetTrain::CompareOutput(const session::LiteSession &lite_session) {
auto outputs = tensor->data();
size_t size;
std::string output_file = flags_->data_file_ + std::to_string(i) + ".bin";
auto *bin_buf = ReadFileBuf(output_file.c_str(), &size);
auto bin_buf = std::unique_ptr<float[]>(ReadFileBuf(output_file.c_str(), &size));
if (bin_buf == nullptr) {
MS_LOG(ERROR) << "ReadFile return nullptr";
return RET_ERROR;
@ -182,7 +182,7 @@ int NetTrain::CompareOutput(const session::LiteSession &lite_session) {
<< ", read size: " << size;
return RET_ERROR;
}
float bias = CompareData<float>(bin_buf, tensor->ElementsNum(), reinterpret_cast<float *>(outputs));
float bias = CompareData<float>(bin_buf.get(), tensor->ElementsNum(), reinterpret_cast<float *>(outputs));
if (bias >= 0) {
total_bias += bias;
total_size++;
@ -191,7 +191,6 @@ int NetTrain::CompareOutput(const session::LiteSession &lite_session) {
break;
}
i++;
delete[] bin_buf;
}
if (!has_error) {
@ -221,7 +220,7 @@ int NetTrain::CompareOutput(const session::LiteSession &lite_session) {
}
}
int NetTrain::MarkPerformance(session::LiteSession *session) {
int NetTrain::MarkPerformance(const std::unique_ptr<session::LiteSession> &session) {
MS_LOG(INFO) << "Running train loops...";
std::cout << "Running train loops..." << std::endl;
uint64_t time_min = 0xFFFFFFFFFFFFFFFF;
@ -266,7 +265,7 @@ int NetTrain::MarkPerformance(session::LiteSession *session) {
return RET_OK;
}
int NetTrain::MarkAccuracy(session::LiteSession *session, bool enforce_accuracy) {
int NetTrain::MarkAccuracy(const std::unique_ptr<session::LiteSession> &session, bool enforce_accuracy) {
MS_LOG(INFO) << "MarkAccuracy";
for (auto &msInput : session->GetInputs()) {
switch (msInput->data_type()) {
@ -329,18 +328,17 @@ int NetTrain::CreateAndRunNetwork(const std::string &filename, int train_session
if (flags_->loss_name_ != "") {
train_cfg.loss_name_ = flags_->loss_name_;
}
session::LiteSession *session = nullptr;
std::unique_ptr<session::LiteSession> session;
if (train_session) {
MS_LOG(INFO) << "CreateTrainSession from model file" << filename.c_str();
std::cout << "CreateTrainSession from model file " << filename.c_str() << std::endl;
session = session::LiteSession::CreateTrainSession(filename, &context, true, &train_cfg);
session = std::unique_ptr<session::LiteSession>(
session::LiteSession::CreateTrainSession(filename, &context, true, &train_cfg));
if (session == nullptr) {
MS_LOG(ERROR) << "RunNetTrain CreateTrainSession failed while running " << model_name.c_str();
std::cout << "RunNetTrain CreateTrainSession failed while running " << model_name.c_str() << std::endl;
return RET_ERROR;
}
if (epochs > 0) {
session->Train();
}
@ -350,14 +348,14 @@ int NetTrain::CreateAndRunNetwork(const std::string &filename, int train_session
filenamems = filenamems + ".ms";
}
MS_LOG(INFO) << "start reading model file" << filenamems.c_str();
MS_LOG(INFO) << "start reading model file " << filenamems.c_str();
std::cout << "start reading model file " << filenamems.c_str() << std::endl;
auto *model = mindspore::lite::Model::Import(filenamems.c_str());
if (model == nullptr) {
MS_LOG(ERROR) << "create model for train session failed";
return RET_ERROR;
}
session = session::LiteSession::CreateSession(&context);
session = std::unique_ptr<session::LiteSession>(session::LiteSession::CreateSession(&context));
if (session == nullptr) {
MS_LOG(ERROR) << "ExportedFile CreateSession failed while running " << model_name.c_str();
std::cout << "CreateSession failed while running " << model_name.c_str() << std::endl;
@ -409,8 +407,9 @@ int NetTrain::CreateAndRunNetwork(const std::string &filename, int train_session
int NetTrain::RunNetTrain() {
auto status = CreateAndRunNetwork(flags_->model_file_, true, flags_->epochs_);
if (status != RET_OK) {
MS_LOG(ERROR) << "CreateAndRunNetwork failed for model" << flags_->model_file_ << ". Status is " << status;
std::cout << "CreateAndRunNetwork failed for model" << flags_->model_file_ << ". Status is " << status << std::endl;
MS_LOG(ERROR) << "CreateAndRunNetwork failed for model " << flags_->model_file_ << ". Status is " << status;
std::cout << "CreateAndRunNetwork failed for model " << flags_->model_file_ << ". Status is " << status
<< std::endl;
return status;
}
@ -423,34 +422,34 @@ int NetTrain::RunNetTrain() {
return RET_OK;
}
int NetTrain::SaveModels(session::LiteSession *session) {
int NetTrain::SaveModels(const std::unique_ptr<session::LiteSession> &session) {
if (!flags_->export_file_.empty()) {
auto status = session->Export(flags_->export_file_ + "_qt", lite::MT_TRAIN, lite::QT_WEIGHT);
if (status != RET_OK) {
MS_LOG(ERROR) << "Export quantized model error" << flags_->export_file_ + "_qt";
std::cout << "Export quantized model error" << flags_->export_file_ + "_qt" << std::endl;
MS_LOG(ERROR) << "Export quantized model error " << flags_->export_file_ + "_qt";
std::cout << "Export quantized model error " << flags_->export_file_ + "_qt" << std::endl;
return RET_ERROR;
}
status = session->Export(flags_->export_file_, lite::MT_TRAIN, lite::QT_NONE);
if (status != RET_OK) {
MS_LOG(ERROR) << "Export non quantized model error" << flags_->export_file_;
std::cout << "Export non quantized model error" << flags_->export_file_ << std::endl;
MS_LOG(ERROR) << "Export non quantized model error " << flags_->export_file_;
std::cout << "Export non quantized model error " << flags_->export_file_ << std::endl;
return RET_ERROR;
}
}
if (!flags_->inference_file_.empty()) {
auto status = session->Export(flags_->inference_file_ + "_qt", lite::MT_INFERENCE, lite::QT_WEIGHT);
if (status != RET_OK) {
MS_LOG(ERROR) << "Export quantized inference model error" << flags_->inference_file_ + "_qt";
std::cout << "Export quantized inference model error" << flags_->inference_file_ + "_qt" << std::endl;
MS_LOG(ERROR) << "Export quantized inference model error " << flags_->inference_file_ + "_qt";
std::cout << "Export quantized inference model error " << flags_->inference_file_ + "_qt" << std::endl;
return RET_ERROR;
}
auto tick = GetTimeUs();
status = session->Export(flags_->inference_file_, lite::MT_INFERENCE, lite::QT_NONE);
if (status != RET_OK) {
MS_LOG(ERROR) << "Export non quantized inference model error" << flags_->inference_file_ + "_qt";
std::cout << "Export non quantized inference model error" << flags_->inference_file_ + "_qt" << std::endl;
MS_LOG(ERROR) << "Export non quantized inference model error " << flags_->inference_file_ + "_qt";
std::cout << "Export non quantized inference model error " << flags_->inference_file_ + "_qt" << std::endl;
return status;
}
std::cout << "ExportInference() execution time is " << GetTimeUs() - tick << "us\n";
@ -491,6 +490,29 @@ int NetTrain::CheckExecutionOfSavedModels() {
return status;
}
void NetTrain::CheckSum(mindspore::tensor::MSTensor *tensor, std::string node_type, int id, std::string in_out) {
int tensor_size = tensor->ElementsNum();
void *data = tensor->MutableData();
TypeId type = tensor->data_type();
std::cout << node_type << " " << in_out << id << " shape=" << tensor->shape() << " sum=";
switch (type) {
case kNumberTypeFloat32:
std::cout << TensorSum<float>(data, tensor_size) << std::endl;
break;
case kNumberTypeInt32:
std::cout << TensorSum<int>(data, tensor_size) << std::endl;
break;
#ifdef ENABLE_FP16
case kNumberTypeFloat16:
std::cout << TensorSum<float16_t>(data, tensor_size) << std::endl;
break;
#endif
default:
std::cout << "unsupported type:" << type;
break;
}
}
int NetTrain::InitCallbackParameter() {
// before callback
before_call_back_ = [&](const std::vector<mindspore::tensor::MSTensor *> &before_inputs,
@ -510,6 +532,12 @@ int NetTrain::InitCallbackParameter() {
}
op_call_times_total_++;
op_begin_ = GetTimeUs();
if (callParam.node_type == "Adam") {
for (auto tensor : before_outputs) {
std::fill(reinterpret_cast<int8_t *>(tensor->MutableData()),
reinterpret_cast<int8_t *>(tensor->MutableData()) + tensor->Size(), 0);
}
}
return true;
};
@ -518,14 +546,12 @@ int NetTrain::InitCallbackParameter() {
const std::vector<mindspore::tensor::MSTensor *> &after_outputs,
const mindspore::CallBackParam &call_param) {
uint64_t opEnd = GetTimeUs();
if (after_inputs.empty()) {
MS_LOG(INFO) << "The num of after inputs is empty";
}
if (after_outputs.empty()) {
MS_LOG(INFO) << "The num of after outputs is empty";
}
float cost = static_cast<float>(opEnd - op_begin_) / 1000.0f;
op_cost_total_ += cost;
op_times_by_type_[call_param.node_type].first++;
@ -533,26 +559,11 @@ int NetTrain::InitCallbackParameter() {
op_times_by_name_[call_param.node_name].first++;
op_times_by_name_[call_param.node_name].second += cost;
if (flags_->layer_checksum_) {
auto out_tensor = after_outputs.at(0);
void *output = out_tensor->MutableData();
int tensor_size = out_tensor->ElementsNum();
TypeId type = out_tensor->data_type();
std::cout << call_param.node_type << " shape=" << after_outputs.at(0)->shape() << " sum=";
switch (type) {
case kNumberTypeFloat32:
std::cout << TensorSum<float>(output, tensor_size);
break;
case kNumberTypeInt32:
std::cout << TensorSum<int>(output, tensor_size);
break;
#ifdef ENABLE_FP16
case kNumberTypeFloat16:
std::cout << TensorSum<float16_t>(output, tensor_size);
break;
#endif
default:
std::cout << "unsupported type:" << type;
break;
for (size_t i = 0; i < after_inputs.size(); i++) {
CheckSum(after_inputs.at(i), call_param.node_type, i, "in");
}
for (size_t i = 0; i < after_outputs.size(); i++) {
CheckSum(after_outputs.at(i), call_param.node_type, i, "out");
}
std::cout << std::endl;
}

View File

@ -113,7 +113,7 @@ class MS_API NetTrain {
private:
// call GenerateInputData or ReadInputFile to init inputTensors
int LoadInput(Vector<tensor::MSTensor *> *ms_inputs);
void CheckSum(mindspore::tensor::MSTensor *tensor, std::string node_type, int id, std::string in_out);
// call GenerateRandomData to fill inputTensors
int GenerateInputData(std::vector<mindspore::tensor::MSTensor *> *ms_inputs);
@ -192,11 +192,10 @@ class MS_API NetTrain {
return meanError;
}
int MarkPerformance(session::LiteSession *session);
int MarkAccuracy(session::LiteSession *lite_session, bool enforce_accuracy = true);
int MarkPerformance(const std::unique_ptr<session::LiteSession> &session);
int MarkAccuracy(const std::unique_ptr<session::LiteSession> &session, bool enforce_accuracy = true);
int CompareOutput(const session::LiteSession &lite_session);
int SaveModels(session::LiteSession *session);
int SaveModels(const std::unique_ptr<session::LiteSession> &session);
int CheckExecutionOfSavedModels();
NetTrainFlags *flags_;