diff --git a/mindspore/lite/cmake/mix210.toolchain.cmake b/mindspore/lite/cmake/mix210.toolchain.cmake new file mode 100644 index 0000000000..c73e576cba --- /dev/null +++ b/mindspore/lite/cmake/mix210.toolchain.cmake @@ -0,0 +1,24 @@ +# set cross-compiled system type, it's better not use the type which cmake cannot recognized. +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR arm) +# when hislicon SDK was installed, toolchain was installed in the path as below: +set(CMAKE_C_COMPILER /opt/linux/x86-arm/aarch64-mix210-linux/bin/aarch64-mix210-linux-gcc) +set(CMAKE_CXX_COMPILER /opt/linux/x86-arm/aarch64-mix210-linux/bin/aarch64-mix210-linux-g++) + +find_path(GCC_PATH gcc) +find_path(GXX_PATH g++) +if(NOT ${GCC_PATH} STREQUAL "GCC_PATH-NOTFOUND" AND NOT ${GXX_PATH} STREQUAL "GXX_PATH-NOTFOUND") + set(FLATC_GCC_COMPILER ${GCC_PATH}/gcc) + set(FLATC_GXX_COMPILER ${GXX_PATH}/g++) +endif() + +# set searching rules for cross-compiler +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +#set(CMAKE_CXX_FLAGS "-march= -mfloat-abi=softfp -mfpu=neon-vfpv4 ${CMAKE_CXX_FLAGS}") + +# cache flags +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}" CACHE STRING "c flags") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" CACHE STRING "c++ flags") diff --git a/mindspore/lite/test/st/scripts/dpico/run_benchmark_3403.sh b/mindspore/lite/test/st/scripts/dpico/run_benchmark_3403.sh new file mode 100644 index 0000000000..33ab415c20 --- /dev/null +++ b/mindspore/lite/test/st/scripts/dpico/run_benchmark_3403.sh @@ -0,0 +1,174 @@ +#!/bin/bash + +function Run_3403() { + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${basepath} + Run_3403_Samples + if [ $? -eq 1 ]; then + echo "samples failed" + return 1 + fi + Run_3403_Gate 'models_onnx_3403.cfg' + if [ $? -eq 1 ]; then + echo "onnx failed" + return 1 + fi + Run_3403_Gate 'models_tf_3403.cfg' + if [ $? -eq 1 ]; then + echo "tensorflow failed" + return 1 + fi +} +# Run on 3403 platform: +function Run_3403_Samples() { + + # Run dpico converted models: + while read line; do + model_pass=${line:0:1} + if [[ $model_pass == \# ]]; then + continue + fi + dpico_line_info=${line} + model_info=`echo ${dpico_line_info}|awk -F ' ' '{print $2}'` + input_num=`echo ${dpico_line_info}|awk -F ' ' '{print $3}'` + env_max_roi_num=`echo ${dpico_line_info}|awk -F ' ' '{print $5}'` + accuracy_limit=`echo ${dpico_line_info}|awk -F ' ' '{print $6}'` + cosine_distance_limit=`echo ${dpico_line_info}|awk -F ' ' '{print $7}'` + nms_thr=`echo ${dpico_line_info}|awk -F ' ' '{print $8}'` + score_thr=`echo ${dpico_line_info}|awk -F ' ' '{print $9}'` + min_height=`echo ${dpico_line_info}|awk -F ' ' '{print $10}'` + min_width=`echo ${dpico_line_info}|awk -F ' ' '{print $11}'` + detection_all_net_out=`echo ${dpico_line_info}|awk -F ' ' '{print $12}'` + model_name=${model_info%%;*} + length=`expr ${#model_name} + 1` + input_shapes=${model_info:${length}} + input_files='' + if [[ $input_num != 1 ]]; then + for i in $(seq 1 $input_num) + do + input_files=$input_files${basepath}'/../../input_output/input/'${model_name}'.ms.bin_'$i',' + done + else + input_files=${basepath}/../../input_output/input/${model_name}.ms.bin + fi + + DPICO_CONFIG_FILE=tmp.txt + echo [dpico] > ${DPICO_CONFIG_FILE} + echo MaxRoiNum=${env_max_roi_num} >> ${DPICO_CONFIG_FILE} + echo NmsThreshold=${nms_thr} >> ${DPICO_CONFIG_FILE} + echo ScoreThreshold=${score_thr} >> ${DPICO_CONFIG_FILE} + echo MinHeight=${min_height} >> ${DPICO_CONFIG_FILE} + echo MinWidth=${min_width} >> ${DPICO_CONFIG_FILE} + if [ ${detection_all_net_out} == 1 ]; then + echo DetectionPostProcess=on >> ${DPICO_CONFIG_FILE} + else + echo DetectionPostProcess=off >> ${DPICO_CONFIG_FILE} + fi + + echo './benchmark --modelFile='${basepath}'/'${model_name}'.ms --inDataFile='${input_files}' --inputShapes='${input_shapes}' --benchmarkDataFile='${basepath}'/../../input_output/output_commercial/'${model_name}'.ms.out --accuracyThreshold='${accuracy_limit} >> "${run_3403_log_file}" + ./benchmark --modelFile=${basepath}/${model_name}.ms --inDataFile=${input_files} --inputShapes=${input_shapes} --benchmarkDataFile=${basepath}/../../input_output/output_commercial/${model_name}.ms.out --accuracyThreshold=${accuracy_limit} --cosineDistanceThreshold=${cosine_distance_limit} --configFile=${DPICO_CONFIG_FILE} + if [ $? = 0 ]; then + run_result='benchmark: '${model_name}' pass'; echo ${run_result} >> ${run_benchmark_result_file} + else + run_result='benchmark: '${model_name}' failed'; echo ${run_result} >> ${run_benchmark_result_file}; return 1 + fi + done < ${models_dpico_config} +} + +# Run on 3403 platform: +function Run_3403_Gate() { + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${basepath} + cfg_file=$1 + # Run dpico converted models: + while read line; do + model_pass=${line:0:1} + if [[ $model_pass == \# ]]; then + continue + fi + dpico_line_info=${line} + model_info=`echo ${dpico_line_info}|awk -F ' ' '{print $1}'` + input_num=`echo ${dpico_line_info}|awk -F ' ' '{print $2}'` + env_max_roi_num=`echo ${dpico_line_info}|awk -F ' ' '{print $4}'` + accuracy_limit=`echo ${dpico_line_info}|awk -F ' ' '{print $5}'` + cosine_distance_limit=`echo ${dpico_line_info}|awk -F ' ' '{print $6}'` + nms_thr=`echo ${dpico_line_info}|awk -F ' ' '{print $7}'` + score_thr=`echo ${dpico_line_info}|awk -F ' ' '{print $8}'` + min_height=`echo ${dpico_line_info}|awk -F ' ' '{print $9}'` + min_width=`echo ${dpico_line_info}|awk -F ' ' '{print $10}'` + detection_all_net_out=`echo ${dpico_line_info}|awk -F ' ' '{print $11}'` + model_name=${model_info%%;*} + length=`expr ${#model_name} + 1` + input_shapes=${model_info:${length}} + input_files='' + if [[ $input_num != 1 ]]; then + for i in $(seq 1 $input_num) + do + input_files=$input_files${basepath}'/../../input_output/input/'${model_name}'.ms.bin_'$i'.nchw,' + done + else + input_files=${basepath}/../../input_output/input/${model_name}.ms.bin.nchw + fi + + DPICO_CONFIG_FILE=tmp.txt + echo [dpico] > ${DPICO_CONFIG_FILE} + echo MaxRoiNum=${env_max_roi_num} >> ${DPICO_CONFIG_FILE} + echo NmsThreshold=${nms_thr} >> ${DPICO_CONFIG_FILE} + echo ScoreThreshold=${score_thr} >> ${DPICO_CONFIG_FILE} + echo MinHeight=${min_height} >> ${DPICO_CONFIG_FILE} + echo MinWidth=${min_width} >> ${DPICO_CONFIG_FILE} + if [ ${detection_all_net_out} == "1" ]; then + echo DetectionPostProcess=on >> ${DPICO_CONFIG_FILE} + else + echo DetectionPostProcess=off >> ${DPICO_CONFIG_FILE} + fi + + echo './benchmark --modelFile='${basepath}'/'${model_name}'.ms --inDataFile='${input_files}' --benchmarkDataFile='${basepath}'/../../input_output/output/'${model_name}'.ms.out --accuracyThreshold='${accuracy_limit} >> "${run_3403_log_file}" + ./benchmark --modelFile=${basepath}/${model_name}.ms --inDataFile=${input_files} --benchmarkDataFile=${basepath}/../../input_output/output_commercial/${model_name}.ms.out --accuracyThreshold=${accuracy_limit} --cosineDistanceThreshold=${cosine_distance_limit} --configFile=${DPICO_CONFIG_FILE} + if [ $? = 0 ]; then + run_result='benchmark: '${model_name}' pass'; echo ${run_result} >> ${run_benchmark_result_file} + else + run_result='benchmark: '${model_name}' failed'; echo ${run_result} >> ${run_benchmark_result_file}; return 1 + fi + done < ${cfg_file} +} + +# Print start msg after run testcase +function MS_PRINT_TESTCASE_END_MSG() { + echo -e "-----------------------------------------------------------------------------------------------------------------------------------" +} + +basepath=$(pwd) +echo "on 3403, bashpath is ${basepath}" + +# Set models config filepath +models_dpico_config=${basepath}/models_caffe_3403.cfg +echo ${models_dpico_config} + +# Write benchmark result to temp file +run_benchmark_result_file=${basepath}/run_benchmark_result.txt +echo ' ' > ${run_benchmark_result_file} + +run_3403_log_file=${basepath}/run_3403_log.txt +echo 'run 3403 logs: ' > ${run_3403_log_file} + +echo "Running in 3403 ..." +Run_3403 & +Run_3403_PID=$! +sleep 1 + +wait ${Run_3403_PID} +Run_benchmark_status=$? + +# Check converter result and return value +if [[ ${Run_benchmark_status} = 0 ]];then + echo "Run benchmark success" + MS_PRINT_TESTCASE_END_MSG + cat ${run_benchmark_result_file} + MS_PRINT_TESTCASE_END_MSG + exit 0 +else + echo "Run benchmark failed" + MS_PRINT_TESTCASE_END_MSG + cat ${run_benchmark_result_file} + MS_PRINT_TESTCASE_END_MSG + exit 1 +fi diff --git a/mindspore/lite/test/st/scripts/dpico/run_converter_3403.sh b/mindspore/lite/test/st/scripts/dpico/run_converter_3403.sh new file mode 100644 index 0000000000..1fbad940f3 --- /dev/null +++ b/mindspore/lite/test/st/scripts/dpico/run_converter_3403.sh @@ -0,0 +1,315 @@ +#!/bin/bash + +# Build x86 tar.gz file for dpico +function Run_Build_x86() { + export MSLITE_REGISTRY_DEVICE=sd3403 + unset JAVA_HOME + bash ${mindspore_top_dir}/build.sh -I x86_64 -j 80 + if [ $? = 0 ]; then + echo "build x86 for dpico success" + cp ${mindspore_top_dir}/output/*linux-x64.tar.gz ${x86_path} + mkdir -p ${x86_path}/lib + cp ${mindspore_top_dir}/mindspore/lite/build/_deps/opencv-4.2-for-dpico-src/lib/* ${x86_path}/lib + cp ${mindspore_top_dir}/mindspore/lite/build/_deps/protobuf-3.9-for-dpico-src/lib/* ${x86_path}/lib + cp ${mindspore_top_dir}/mindspore/lite/build/_deps/pico_mapper-src/lib/* ${x86_path}/lib + else + echo "build x86 for dpico failed"; return 1 + fi +} + +# Build arm32 tar.gz file for dpico +function Run_Build_arm64() { + export MSLITE_REGISTRY_DEVICE=sd3403 + unset JAVA_HOME + bash ${mindspore_top_dir}/build.sh -I arm64 -j 80 + if [ $? = 0 ]; then + echo "build arm64 for dpico success" + cp ${mindspore_top_dir}/output/*linux-aarch64.tar.gz ${arm64_path} + else + echo "build arm64 for dpico failed"; return 1 + fi +} + +function Run_Converter_CI_MODELS() { + framework=$1 + if [[ ${framework} == 'TF' ]]; then + model_location='tf' + elif [[ ${framework} == 'ONNX' ]]; then + model_location='onnx' + else + echo "unsupported framework"; return 1 + fi + models_3403_cfg=$2 + while read line; do + dpico_line_info=${line} + if [[ $dpico_line_info == \#* ]]; then + continue + fi + model_info=`echo ${dpico_line_info}|awk -F ' ' '{print $1}'` + model_name=${model_info%%;*} + length=`expr ${#model_name} + 1` + input_shape=${model_info:${length}} + cfg_path_name=${models_path}/${model_location}/cfg_8bit/${model_name}.cfg + cp ${cfg_path_name} ./ || exit 1 + ms_config_file=./converter_for_dpico.cfg + echo '[registry]' > ${ms_config_file} + echo 'plugin_path=./tools/converter/providers/SD3403/libdpico_atc_adapter.so' >> ${ms_config_file} + echo -e 'disable_fusion=on\n' >> ${ms_config_file} + echo '[dpico]' >> ${ms_config_file} + echo 'dpico_config_path='./${model_name}.cfg >> ${ms_config_file} + echo -e 'benchmark_path=./tools/benchmark/benchmark' >> ${ms_config_file} + echo ${model_name} >> "${run_converter_log_file}" + echo './converter_lite --inputDataFormat=NCHW --fmk='${framework}' --inputShape='${input_shape} '--modelFile='${models_path}'/'${model_location}'/models/'${model_name}' --configFile='${ms_config_file}' --outputFile='${ms_models_path}'/'${model_name}'' >> "${run_converter_log_file}" + ./converter_lite --inputDataFormat=NCHW --inputShape=${input_shape} --fmk=${framework} --modelFile=${models_path}/${model_location}/models/${model_name} --configFile=${ms_config_file} --outputFile=${ms_models_path}/${model_name} + if [ $? = 0 ]; then + converter_result='converter '${framework}' '${model_name}' pass';echo ${converter_result} >> ${run_converter_result_file} + else + converter_result='converter '${framework}' '${model_name}' failed';echo ${converter_result} >> ${run_converter_result_file}; exit 1 + fi + done < ${models_3403_cfg} +} + +# Run converter for DPICO models on x86 platform: +function Run_Converter() { + cd ${x86_path} || exit 1 + tar -zxf mindspore-enterprise-lite-${version}-linux-x64.tar.gz || exit 1 + cd ${x86_path}/mindspore-enterprise-lite-${version}-linux-x64/ || exit 1 + + cp tools/converter/converter/converter_lite ./ || exit 1 + export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:./tools/converter/lib/:./runtime/lib/:./tools/converter/third_party/glog/lib:./tools/converter/providers/SD3403/:${x86_path}/lib + chmod +x ./tools/benchmark/benchmark + + echo ' ' > ${run_converter_log_file} + rm -rf ${ms_models_path} + mkdir -p ${ms_models_path} + chmod +x converter_lite + # Convert dpico models: + while read line; do + dpico_line_info=${line} + if [[ $dpico_line_info == \#* ]]; then + continue + fi + model_location=`echo ${dpico_line_info}|awk -F ' ' '{print $1}'` + model_info=`echo ${dpico_line_info}|awk -F ' ' '{print $2}'` + model_name=${model_info%%;*} + echo ${model_name} >> "${run_converter_log_file}" + # generate converter_lite config file + cp ${models_path}/${model_location}/${model_name}.cfg ./ || exit 1 + ms_config_file=./converter_for_dpico.cfg + echo '[registry]' > ${ms_config_file} + echo 'plugin_path=./tools/converter/providers/SD3403/libdpico_atc_adapter.so' >> ${ms_config_file} + echo -e 'disable_fusion=on\n' >> ${ms_config_file} + echo '[dpico]' >> ${ms_config_file} + echo 'dpico_config_path='./${model_name}.cfg >> ${ms_config_file} + echo -e 'benchmark_path=./tools/benchmark/benchmark' >> ${ms_config_file} + + echo './converter_lite --inputDataFormat=NCHW --fmk=CAFFE --modelFile='${models_path}'/'${model_location}'/model/'${model_name}'.prototxt --weightFile='${models_path}'/'${model_location}'/model/'${model_name}'.caffemodel --configFile='${ms_config_file}' --outputFile='${ms_models_path}'/'${model_name}'' >> "${run_converter_log_file}" + ./converter_lite --inputDataFormat=NCHW --fmk=CAFFE --modelFile=${models_path}/${model_location}/model/${model_name}.prototxt --weightFile=${models_path}/${model_location}/model/${model_name}.caffemodel --configFile=${ms_config_file} --outputFile=${ms_models_path}/${model_name} + if [ $? = 0 ]; then + converter_result='converter CAFFE '${model_name}' pass';echo ${converter_result} >> ${run_converter_result_file} + else + converter_result='converter CAFFE '${model_name}' failed';echo ${converter_result} >> ${run_converter_result_file};return 1 + fi + done < ${models_caffe_3403_config} + + Run_Converter_CI_MODELS 'TF' ${models_tf_3403_config} + Run_convert_tf_status=$? + if [[ ${Run_convert_tf_status} = 0 ]];then + echo "Run convert tf success" + else + echo "Run convert tf failed" + exit 1 + fi + Run_Converter_CI_MODELS 'ONNX' ${models_onnx_3403_config} + Run_convert_onnx_status=$? + if [[ ${Run_convert_onnx_status} = 0 ]];then + echo "Run convert onnx success" + else + echo "Run convert onnx failed" + exit 1 + fi +} + +# Run benchmark on 3403: +function Run_Benchmark() { + if [[ "${CI_3403_USERNAME}" && "${CI_3403_PASSWORD}" ]]; then + username=${CI_3403_USERNAME} + password=${CI_3403_PASSWORD} + else + echo "ERROR: ENV CI_3403_USERNAME or CI_3403_PASSWORD not found." + exit 1 + fi + sshpass -p "${password}" ssh ${username}@${device_ip} "cd /mnt/dpico/gate/benchmark_test/${cur_timestamp}; sh run_benchmark_3403.sh" + if [ $? = 0 ]; then + run_result='benchmark_3403: '${model_name}' pass'; echo ${run_result} >> ${run_benchmark_result_file}; + else + run_result='benchmark_3403: '${model_name}' failed'; echo ${run_result} >> ${run_benchmark_result_file}; exit 1 + fi +} + +mindspore_top_dir=$(pwd) +echo ${mindspore_top_dir} +x86_path=${mindspore_top_dir}/x86_release/ +rm -rf ${x86_path} +mkdir -p ${x86_path} +arm64_path=${mindspore_top_dir}/arm64_release/ +rm -rf ${arm64_path} +mkdir -p ${arm64_path} +#set -e +st_dir=${mindspore_top_dir}/mindspore/lite/test/st + +# Example:sh run_dpico_nets.sh r /home/temp_test -m /home/temp_test/models -e arm32_3403D -d 192.168.1.1 +while getopts "m:d:e:" opt; do + case ${opt} in + m) + models_path=${OPTARG} + echo "models_path is ${OPTARG}" + ;; + d) + device_ip=${OPTARG} + echo "device_ip is ${OPTARG}" + ;; + e) + backend=${OPTARG} + echo "backend is ${OPTARG}" + ;; + ?) + echo "unknown para" + exit 1;; + esac +done + +# Print start msg after run testcase +function MS_PRINT_TESTCASE_END_MSG() { + echo -e "-----------------------------------------------------------------------------------------------------------------------------------" +} + +function Print_Converter_Result() { + MS_PRINT_TESTCASE_END_MSG + while read line; do + arr=("${line}") + printf "%-15s %-20s %-90s %-7s\n" ${arr[0]} ${arr[1]} ${arr[2]} ${arr[3]} + done < ${run_converter_result_file} + MS_PRINT_TESTCASE_END_MSG +} + +# build x86 +echo "start building x86..." +Run_Build_x86 & +Run_build_x86_PID=$! +sleep 1 + +wait ${Run_build_x86_PID} +Run_build_x86_status=$? +if [[ ${Run_build_x86_status} = 0 ]];then + echo "Run build x86 success" +else + echo "Run build x86 failed" + exit 1 +fi + +# build arm64 +echo "start building arm64..." +Run_Build_arm64 & +Run_build_arm64_PID=$! +sleep 1 + +wait ${Run_build_arm64_PID} +Run_build_arm64_status=$? +if [[ ${Run_build_arm64_status} = 0 ]];then + echo "Run build arm64 success" +else + echo "Run build arm64 failed" + exit 1 +fi + +# Set filepath +models_caffe_3403_config=${st_dir}/../config/models_caffe_3403.cfg +models_onnx_3403_config=${st_dir}/../config/models_onnx_3403.cfg +models_tf_3403_config=${st_dir}/../config/models_tf_3403.cfg +run_benchmark_script=${st_dir}/scripts/dpico/run_benchmark_3403.sh + +# Set version +file_name=$(ls ${x86_path}/*linux-x64.tar.gz) +IFS="-" read -r -a file_name_array <<< "$file_name" +version=${file_name_array[3]} + +# Set ms models output path +ms_models_path=${st_dir}/ms_models + +# Write converter result to temp file +run_converter_log_file=${st_dir}/run_converter_log.txt +#rm ${run_converter_log_file} +echo ' ' > ${run_converter_log_file} + +run_converter_result_file=${st_dir}/run_converter_result.txt +#rm ${run_converter_result_file} +echo ' ' > ${run_converter_result_file} + +# Run converter +echo "start Run converter for dpico models..." +Run_Converter & +Run_converter_PID=$! +sleep 1 + +wait ${Run_converter_PID} +Run_converter_status=$? +if [[ ${Run_converter_status} = 0 ]];then + echo "Run converter for dpico models success" + Print_Converter_Result +else + echo "Run converter for dpico models failed" + cat ${run_converter_log_file} + Print_Converter_Result + exit 1 +fi + +# Write benchmark result to temp file +run_benchmark_result_file=${st_dir}/run_benchmark_result.txt +echo ' ' > ${run_benchmark_result_file} + +# Copy the MindSpore models: +cur_timestamp=$((`date '+%s'`*1000+10#`date '+%N'`/1000000)) +benchmark_test_path=/home/dpico/gate/benchmark_test/${cur_timestamp} +rm -rf ${benchmark_test_path} +mkdir -p ${benchmark_test_path} +cp -a ${ms_models_path}/*.ms ${benchmark_test_path} || exit 1 +cp -a ${models_caffe_3403_config} ${benchmark_test_path} || exit 1 +cp -a ${models_onnx_3403_config} ${benchmark_test_path} || exit 1 +cp -a ${models_tf_3403_config} ${benchmark_test_path} || exit 1 +cp -a ${run_benchmark_script} ${benchmark_test_path} || exit 1 + +#copy related so file to shared folder +cd ${arm64_path} || exit 1 +tar -zxf mindspore-enterprise-lite-${version}-linux-aarch64.tar.gz || exit 1 +cd ${arm64_path}/mindspore-enterprise-lite-${version}-linux-aarch64/ || exit 1 +chmod +x ${mindspore_top_dir}/mindspore/lite/build/tools/benchmark/benchmark +cp -a ${mindspore_top_dir}/mindspore/lite/build/tools/benchmark/benchmark ${benchmark_test_path}/benchmark || exit 1 +cp -a ${arm64_path}/mindspore-enterprise-lite-${version}-linux-aarch64/providers/SD3403/libdpico_acl_adapter.so ${benchmark_test_path}/libdpico_acl_adapter.so || exit 1 +cp -a ${arm64_path}/mindspore-enterprise-lite-${version}-linux-aarch64/runtime/lib/libmindspore-lite.so ${benchmark_test_path}/libmindspore-lite.so || exit 1 +cp -a ${mindspore_top_dir}/mindspore/lite/build/_deps/34xx_sdk-src/lib/*so* ${benchmark_test_path} || exit 1 + +if [[ $backend == "all" || $backend == "arm64_3403" ]]; then + # Run on 34xx + Run_Benchmark & + Run_benchmark_PID=$! + sleep 1 +fi + +if [[ $backend == "all" || $backend == "arm64_3403" ]]; then + wait ${Run_benchmark_PID} + Run_benchmark_status=$? + if [[ ${Run_benchmark_status} != 0 ]];then + echo "Run_benchmark_3403 failed" + isFailed=1 + else + echo "Run_benchmark_3403 success" + isFailed=0 + fi + rm -rf ${benchmark_test_path} || exit 1 +fi + +if [[ $isFailed == 1 ]]; then + exit 1 +fi +exit 0 diff --git a/mindspore/lite/test/st/scripts/dpico/run_simulation_3403.sh b/mindspore/lite/test/st/scripts/dpico/run_simulation_3403.sh new file mode 100644 index 0000000000..54d82d39d1 --- /dev/null +++ b/mindspore/lite/test/st/scripts/dpico/run_simulation_3403.sh @@ -0,0 +1,295 @@ +#!/bin/bash + +function Run_Convert_MODELS() { + framework=$1 + models_3403_cfg=$2 + while read line; do + dpico_line_info=${line} + if [[ $dpico_line_info == \#* ]]; then + continue + fi + model_location=`echo ${dpico_line_info}|awk -F ' ' '{print $1}'` + model_info=`echo ${dpico_line_info}|awk -F ' ' '{print $2}'` + model_name=${model_info%%;*} + length=`expr ${#model_name} + 1` + input_shape=${model_info:${length}} + + # converter_lite convert model + cp ${models_path}/${model_location}/${model_name}.cfg ./ || exit 1 + cp ${model_name}.cfg ${model_name}_atc.cfg + sed -i '$a \[instruction_name] '${om_generated_path}/${model_name}_lib ./${model_name}.cfg + + ms_config_file=./converter_for_dpico.cfg + echo '[registry]' > ${ms_config_file} + echo 'plugin_path=./tools/converter/providers/SD3403/libdpico_atc_adapter.so' >> ${ms_config_file} + echo -e 'disable_fusion=on\n' >> ${ms_config_file} + echo '[dpico]' >> ${ms_config_file} + echo 'dpico_config_path='./${model_name}.cfg >> ${ms_config_file} + echo -e 'benchmark_path=./tools/benchmark/benchmark' >> ${ms_config_file} + echo ${model_name} >> "${run_converter_log_file}" + if [[ ${framework} == 'CAFFE' ]]; then + echo './converter_lite --inputDataFormat=NCHW --fmk='${framework}' --inputShape='${input_shape} '--modelFile='${models_path}'/'${model_location}'/model/'${model_name}.prototxt' --weightFile='${models_path}'/'${model_location}'/model/'${model_name}.caffemodel' --configFile='${ms_config_file}' --outputFile='${om_generated_path}'/'${model_name}'' >> "${run_converter_log_file}" + ./converter_lite --inputDataFormat=NCHW --inputShape=${input_shape} --fmk=${framework} --modelFile=${models_path}/${model_location}/model/${model_name}.prototxt --weightFile=${models_path}/${model_location}/model/${model_name}.caffemodel --configFile=${ms_config_file} --outputFile=${om_generated_path}/${model_name} + if [ $? = 0 ]; then + converter_result='converter CAFFE '${model_name}' pass';echo ${converter_result} >> ${run_converter_result_file} + else + converter_result='converter CAFFE '${model_name}' failed';echo ${converter_result} >> ${run_converter_result_file};exit 1 + fi + elif [[ ${framework} == 'ONNX' ]]; then + echo './converter_lite --inputDataFormat=NCHW --fmk='${framework}' --inputShape='${input_shape} '--modelFile='${models_path}'/'${model_location}'/models/'${model_name}' --configFile='${ms_config_file}' --outputFile='${om_generated_path}'/'${model_name}'' >> "${run_converter_log_file}" + ./converter_lite --inputDataFormat=NCHW --inputShape=${input_shape} --fmk=${framework} --modelFile=${models_path}/${model_location}/models/${model_name} --configFile=${ms_config_file} --outputFile=${om_generated_path}/${model_name} + if [ $? = 0 ]; then + converter_result='converter ONNX '${model_name}' pass';echo ${converter_result} >> ${run_converter_result_file} + else + converter_result='converter ONNX '${model_name}' failed';echo ${converter_result} >> ${run_converter_result_file};exit 1 + fi + else + echo "unsupported framework"; return 1 + fi + + # atc convert model + if [[ ${framework} == 'CAFFE' ]]; then + sed -i 's/\[framework\] 6/\[framework\] 0/g' ./${model_name}_atc.cfg + sed -i '1 i\[weight] '${models_path}/${model_location}/model/${model_name}'.caffemodel' ./${model_name}_atc.cfg + sed -i '1 i\[model] '${models_path}/${model_location}/model/${model_name}'.prototxt' ./${model_name}_atc.cfg + elif [[ ${framework} == 'ONNX' ]]; then + sed -i 's/\[framework\] 6/\[framework\] 5/g' ./${model_name}_atc.cfg + sed -i '1 i\[model] '${models_path}/${model_location}/models/${model_name} ./${model_name}_atc.cfg + fi + sed -i '$a \[instruction_name] '${om_generated_path}/${model_name}_atc ./${model_name}_atc.cfg + ./atc ./${model_name}_atc.cfg + if [ $? = 0 ]; then + converter_result='atc '${framework}' '${model_name}' pass';echo ${converter_result} >> ${run_converter_result_file} + else + converter_result='atc '${framework}' '${model_name}' failed';echo ${converter_result} >> ${run_converter_result_file}; exit 1 + fi + done < ${models_3403_cfg} +} + +# Run converter for DPICO models on x86 platform: +function Run_Converter() { + cd ${x86_path} || exit 1 + tar -zxf mindspore-enterprise-lite-${version}-linux-x64.tar.gz || exit 1 + cd ${x86_path}/mindspore-enterprise-lite-${version}-linux-x64/ || exit 1 + + # atc tool + cp tools/converter/providers/SD3403/third_party/pico_mapper/bin/atc ./ || exit 1 + chmod +x atc + + cp tools/converter/converter/converter_lite ./ || exit 1 + export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:./tools/converter/lib/:./runtime/lib/:./tools/converter/providers/SD3403/third_party/pico_mapper/lib:./tools/converter/providers/SD3403/third_party/protobuf-3.9.0/lib:./tools/converter/providers/SD3403/third_party/opencv-4.2.0/lib + chmod +x ./tools/benchmark/benchmark + + echo ' ' > ${run_converter_log_file} + rm -rf ${om_generated_path} + mkdir -p ${om_generated_path} + chmod +x converter_lite + + Run_Convert_MODELS 'ONNX' ${models_onnx_3403_config} + Run_convert_onnx_status=$? + if [[ ${Run_convert_onnx_status} = 0 ]];then + echo "Run convert onnx success" + else + echo "Run convert onnx failed" + exit 1 + fi + + Run_Convert_MODELS 'CAFFE' ${models_caffe_3403_config} + Run_convert_caffe_status=$? + if [[ ${Run_convert_caffe_status} = 0 ]];then + echo "Run convert caffe success" + else + echo "Run convert caffe failed" + exit 1 + fi +} + +function Run_Func_Sim() { + models_3403_cfg=$1 + while read line; do + dpico_line_info=${line} + if [[ $dpico_line_info == \#* ]]; then + continue + fi + model_info=`echo ${dpico_line_info}|awk -F ' ' '{print $2}'` + model_name=${model_info%%;*} + input_num=`echo ${dpico_line_info}|awk -F ' ' '{print $3}'` + input_files='' + if [[ $input_num != 1 ]]; then + for i in $(seq 1 $input_num) + do + cp ${models_path}'/input_output/input/'${model_name}'.ms.bin_'${i}* ${model_name}'_'${i}'.ms.bin' || exit 1 + input_files=$input_files${model_name}'_'${i}'.ms.bin,' + done + else + cp ${models_path}/input_output/input/${model_name}.ms.bin* ${model_name}'.ms.bin' || exit 1 + input_files=${model_name}'.ms.bin' + fi + # generate dump files + rm -rf ${om_generated_path}/dump_output + ./func_sim -m ./${model_name}_lib_original.om -i ${input_files} -a + if [ $? -ne 0 ]; then + simulation_3403_result='func_sim '${model_name}' failed';echo ${simulation_3403_result} >> ${run_simulation_result_file}; exit 1 + fi + ./func_sim -m ./${model_name}_atc_original.om -i ${input_files} -a + if [ $? -ne 0 ]; then + simulation_3403_result='func_sim '${model_name}' failed';echo ${simulation_3403_result} >> ${run_simulation_result_file}; exit 1 + fi + + # compare dump files + ls ./dump_output/*lib*/batch_0/layer/*report* || exit 1 + ls ./dump_output/*atc*/batch_0/layer/*report* || exit 1 + lib_files_cnt=$(ls ./dump_output/*lib*/batch_0/layer/*report* | wc -l) + atc_files_cnt=$(ls ./dump_output/*atc*/batch_0/layer/*report* | wc -l) + if [[ $lib_files_cnt -ne $atc_files_cnt ]]; then + echo "generated report files is not equal"; exit 1 + fi + is_file_equal=1 + for i in $(seq 0 $input_num) + do + cmp -s ./dump_output/*lib*/batch_0/layer/*report_0_${i}_*.float ./dump_output/*atc*/batch_0/layer/*report_0_${i}_*.float || is_file_equal=0 && break + done + if [[ ${is_file_equal} == 1 ]]; then + simulation_3403_result='simulation '${model_name}' pass';echo ${simulation_3403_result} >> ${run_simulation_result_file} + else + simulation_3403_result='simulation '${model_name}' failed';echo ${simulation_3403_result} >> ${run_simulation_result_file}; exit 1 + fi + done < ${models_3403_cfg} +} + +# Run benchmark on 3403: +function Run_Simulation() { + cd ${om_generated_path} || exit 1 + wget http://mindspore-repo.csi.rnd.huawei.com/mindspore/enterprise/dpico/func_sim || exit 1 + chmod +x func_sim + + Run_Func_Sim ${models_onnx_3403_config} + Run_func_sim_status=$? + if [[ ${Run_func_sim_status} = 0 ]];then + echo "Run func_sim onnx success" + else + echo "Run func_sim onnx failed" + exit 1 + fi + + Run_Func_Sim ${models_caffe_3403_config} + Run_func_sim_status=$? + if [[ ${Run_func_sim_status} = 0 ]];then + echo "Run func_sim caffe success" + else + echo "Run func_sim caffe failed" + exit 1 + fi + +} + +basepath=$(pwd) +echo ${basepath} + +# Example:sh run_dpico_nets.sh r /home/temp_test -m /home/temp_test/models -e arm32_3403D -d 192.168.1.1 +while getopts "r:m:e:" opt; do + case ${opt} in + r) + release_path=${OPTARG} + echo "release_path is ${OPTARG}" + ;; + m) + models_path=${OPTARG} + echo "models_path is ${OPTARG}" + ;; + e) + backend=${OPTARG} + echo "backend is ${OPTARG}" + ;; + ?) + echo "unknown para" + exit 1;; + esac +done + +# Print start msg after run testcase +function MS_PRINT_TESTCASE_END_MSG() { + echo -e "-----------------------------------------------------------------------------------------------------------------------------------" +} + +function Print_Converter_Result() { + MS_PRINT_TESTCASE_END_MSG + while read line; do + arr=("${line}") + printf "%-15s %-20s %-90s %-7s\n" ${arr[0]} ${arr[1]} ${arr[2]} ${arr[3]} + done < ${run_converter_result_file} + MS_PRINT_TESTCASE_END_MSG +} + +x86_path=${release_path}/ubuntu_x86 + +# Set version +file_name=$(ls ${x86_path}/*linux-x64.tar.gz) +IFS="-" read -r -a file_name_array <<< "$file_name" +version=${file_name_array[3]} + +# Set filepath +models_caffe_3403_config=${basepath}/../config/models_caffe_3403_simulation.cfg +models_onnx_3403_config=${basepath}/../config/models_onnx_3403_simulation.cfg + +# Set om generated path +om_generated_path=${basepath}/om_generated + +# Write converter result to temp file +run_converter_log_file=${basepath}/run_converter_log.txt +rm ${run_converter_log_file} +echo ' ' > ${run_converter_log_file} + +run_converter_result_file=${basepath}/run_converter_result.txt +rm ${run_converter_result_file} +echo ' ' > ${run_converter_result_file} + +# Run converter +echo "start Run converter for dpico models..." +Run_Converter & +Run_converter_PID=$! +sleep 1 + +wait ${Run_converter_PID} +Run_converter_status=$? +if [[ ${Run_converter_status} = 0 ]];then + echo "Run converter for dpico models success" + Print_Converter_Result +else + echo "Run converter for dpico models failed" + cat ${run_converter_log_file} + Print_Converter_Result + exit 1 +fi + +# Write benchmark result to temp file +run_simulation_result_file=${basepath}/run_simulation_3403_result.txt +rm ${run_simulation_result_file} +echo ' ' > ${run_simulation_result_file} + +if [[ $backend == "all" || $backend == "simulation_3403" ]]; then + # Run funcsim + Run_Simulation & + Run_Simulation_PID=$! + sleep 1 +fi + +if [[ $backend == "all" || $backend == "simulation_3403" ]]; then + wait ${Run_Simulation_PID} + Run_Simulation_status=$? + if [[ ${Run_Simulation_status} != 0 ]];then + echo "Run_simulation_3403 failed" + isFailed=1 + else + echo "Run_simulation_3403 success" + isFailed=0 + fi + MS_PRINT_TESTCASE_END_MSG + cat ${run_simulation_result_file} + MS_PRINT_TESTCASE_END_MSG +fi + +if [[ $isFailed == 1 ]]; then + exit 1 +fi +exit 0 diff --git a/mindspore/lite/tools/benchmark/dpico/CMakeLists.txt b/mindspore/lite/tools/benchmark/dpico/CMakeLists.txt new file mode 100644 index 0000000000..e4ba71f5cf --- /dev/null +++ b/mindspore/lite/tools/benchmark/dpico/CMakeLists.txt @@ -0,0 +1,23 @@ +cmake_minimum_required(VERSION 3.14) +project(DPICO_Custom) +include(${CMAKE_CURRENT_SOURCE_DIR}/../../../../../cmake/utils.cmake) +__download_pkg(34xx_sdk + http://mindspore-repo.csi.rnd.huawei.com/mindspore/enterprise/dpico/34xx_sdk.tar.gz + f64a9129615b3b41b63debe17c6785af) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(${34xx_sdk_SOURCE_DIR}) +include_directories(${34xx_sdk_SOURCE_DIR}/include) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/third_party/runtime) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/third_party/runtime/include) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/third_party/runtime/include/third_party) +link_directories(${34xx_sdk_SOURCE_DIR}/lib) + +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src COMMON_SRC3) + +set(LINK_LOCAT_LIB ${34xx_sdk_SOURCE_DIR}/lib/libsvp_acl.so + pthread ${34xx_sdk_SOURCE_DIR}/lib/libsecurec.so dl + ${34xx_sdk_SOURCE_DIR}/lib/libprotobuf-c.so.1 stdc++) + +add_library(dpico_acl_adapter SHARED + ${COMMON_SRC3}) +target_link_libraries(dpico_acl_adapter ${LINK_LOCAT_LIB} securec) \ No newline at end of file diff --git a/mindspore/lite/tools/benchmark/dpico/src/common_utils.cc b/mindspore/lite/tools/benchmark/dpico/src/common_utils.cc new file mode 100644 index 0000000000..e4f629209b --- /dev/null +++ b/mindspore/lite/tools/benchmark/dpico/src/common_utils.cc @@ -0,0 +1,329 @@ +/** + * 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 "src/common_utils.h" +#include +#include +#include +#include +#include +#include +#include +#include "include/svp_acl_rt.h" +#include "include/svp_acl.h" +#include "include/svp_acl_ext.h" + +namespace mindspore { +namespace lite { +namespace { +constexpr int32_t kDeviceId = 0; +constexpr size_t kMaxSize = 1024; +bool kThreadRunning = false; + +bool IsValidDoubleNum(const std::string &num_str) { + if (num_str.empty()) { + return false; + } + std::istringstream iss(num_str); + double d; + iss >> std::noskipws >> d; + return iss.eof() && !iss.fail(); +} + +void AicpuThread() { + MS_LOG(INFO) << "create aicpu thread success"; + while (kThreadRunning) { + svp_acl_error ret = svp_acl_ext_process_aicpu_task(1000); // 1000 ms + if (ret != SVP_ACL_SUCCESS && ret != SVP_ACL_ERROR_RT_REPORT_TIMEOUT) { + MS_LOG(ERROR) << "create aicpu thread failed!"; + break; + } + } + MS_LOG(INFO) << "end to destroy aicpu thread"; + return; +} +} // namespace + +bool InferDone(const std::vector &tensors) { + for (auto &tensor : tensors) { + auto shape = tensor.Shape(); + if (std::find(shape.begin(), shape.end(), -1) != shape.end()) { + return false; + } + } + return true; +} + +void ExtractAttrsFromPrimitive(const mindspore::schema::Primitive *primitive, + std::map *attrs) { + if (primitive == nullptr || attrs == nullptr) { + return; + } + auto custom_holder = primitive->value_as_Custom(); + if (custom_holder == nullptr) { + return; + } + auto attrs_holder = custom_holder->attr(); + if (attrs_holder == nullptr) { + return; + } + + for (size_t i = 0; i < attrs_holder->size(); i++) { + if (attrs_holder->Get(i) == nullptr || attrs_holder->Get(i)->name() == nullptr) { + continue; + } + auto attr_name = attrs_holder->Get(i)->name()->str(); + std::string attr; + auto attr_data = attrs_holder->Get(i)->data(); + if (attr_data != nullptr) { + if (attr_data->size() >= kMaxSize) { + MS_LOG(WARNING) << "attr size too big, which is out of 1024 character. Obtain " << attr_name.c_str() + << " failed."; + } else { + for (size_t j = 0; j < attr_data->size(); j++) { + attr.push_back(static_cast(attr_data->Get(j))); + } + } + } + attrs->emplace(attr_name, attr); + } +} + +void *ReadBinFile(const std::string &fileName, uint32_t *fileSize) { + if (fileSize == nullptr) { + return nullptr; + } + struct stat sBuf; + int fileStatus = stat(fileName.data(), &sBuf); + if (fileStatus == -1) { + MS_LOG(ERROR) << "failed to get file " << fileName.c_str(); + return nullptr; + } + if (S_ISREG(sBuf.st_mode) == 0) { + MS_LOG(ERROR) << fileName.c_str() << " is not a file, please enter a file"; + return nullptr; + } + std::ifstream binFile(fileName, std::ifstream::binary); + if (!binFile.is_open()) { + MS_LOG(ERROR) << "open file " << fileName.c_str() << " failed"; + return nullptr; + } + binFile.seekg(0, binFile.end); + uint32_t binFileBufferLen = binFile.tellg(); + if (binFileBufferLen == 0) { + MS_LOG(ERROR) << "binfile is empty, filename is " << fileName.c_str(); + binFile.close(); + return nullptr; + } + binFile.seekg(0, binFile.beg); + void *binFileBufferData = nullptr; + svp_acl_error ret = SVP_ACL_SUCCESS; + ret = svp_acl_rt_malloc(&binFileBufferData, binFileBufferLen, SVP_ACL_MEM_MALLOC_NORMAL_ONLY); + if (ret != SVP_ACL_SUCCESS) { + MS_LOG(ERROR) << "malloc device buffer failed. size is " << binFileBufferLen; + binFile.close(); + return nullptr; + } + binFile.read(static_cast(binFileBufferData), binFileBufferLen); + binFile.close(); + *fileSize = binFileBufferLen; + return binFileBufferData; +} + +Result JudgeOmNetType(const schema::Primitive &primitive, OmNetType *net_type) { + auto op = primitive.value_as_Custom(); + if (op == nullptr) { + return FAILED; + } + if (op->attr() == nullptr) { + MS_LOG(ERROR) << "op attr is nullptr."; + return FAILED; + } + if (op->attr()->size() < 1) { + MS_LOG(ERROR) << "There are at least 1 attribute of Custom"; + return FAILED; + } + std::string net_type_str = ""; + for (size_t i = 0; i < op->attr()->size(); i++) { + if (op->attr()->Get(i) == nullptr || op->attr()->Get(i)->name() == nullptr) { + return FAILED; + } + if (op->attr()->Get(i)->name()->str() == kNetType) { + auto output_info = op->attr()->Get(i)->data(); + if (output_info == nullptr) { + return FAILED; + } + int attr_size = static_cast(output_info->size()); + for (int j = 0; j < attr_size; j++) { + net_type_str.push_back(static_cast(output_info->Get(j))); + } + break; + } + } + if (net_type_str.empty()) { + *net_type = OmNetType_CNN; + return SUCCESS; + } + if (!IsValidUnsignedNum(net_type_str)) { + MS_LOG(ERROR) << "net_type attr data is invalid."; + return FAILED; + } + int net_type_val = stoi(net_type_str); + if (net_type_val == OmNetType_ROI) { + *net_type = OmNetType_ROI; + } else if (net_type_val == OmNetType_RECURRENT) { + *net_type = OmNetType_RECURRENT; + } + return SUCCESS; +} + +void DpicoConfigParamExtractor::InitDpicoConfigParam(const kernel::Kernel &kernel) { + if (has_init_) { + return; + } + has_init_ = true; + UpdateDpicoConfigParam(kernel); +} + +void DpicoConfigParamExtractor::UpdateDpicoConfigParam(const kernel::Kernel &kernel) { + auto dpico_arg = kernel.GetConfig("dpico"); + if (dpico_arg.find("MaxRoiNum") != dpico_arg.end()) { + if (IsValidUnsignedNum(dpico_arg.at("MaxRoiNum"))) { + max_roi_num_ = stoi(dpico_arg.at("MaxRoiNum")); + } + } + + if (dpico_arg.find("NmsThreshold") != dpico_arg.end()) { + if (IsValidDoubleNum(dpico_arg.at("NmsThreshold"))) { + nms_threshold_ = stof(dpico_arg.at("NmsThreshold")); + } + } + + if (dpico_arg.find("ScoreThreshold") != dpico_arg.end()) { + if (IsValidDoubleNum(dpico_arg.at("ScoreThreshold"))) { + score_threshold_ = stof(dpico_arg.at("ScoreThreshold")); + } + } + + if (dpico_arg.find("MinHeight") != dpico_arg.end()) { + if (IsValidDoubleNum(dpico_arg.at("MinHeight"))) { + min_height_ = stof(dpico_arg.at("MinHeight")); + } + } + + if (dpico_arg.find("MinWidth") != dpico_arg.end()) { + if (IsValidDoubleNum(dpico_arg.at("MinWidth"))) { + min_width_ = stof(dpico_arg.at("MinWidth")); + } + } + + if (dpico_arg.find("GTotalT") != dpico_arg.end()) { + if (IsValidUnsignedNum(dpico_arg.at("GTotalT"))) { + g_total_t_ = stoi(dpico_arg.at("GTotalT")); + } + } + + if (dpico_arg.find("DetectionPostProcess") != dpico_arg.end()) { + if (dpico_arg.at("DetectionPostProcess") == "on") { + dpico_detection_post_process_ = 1; + } + } + if (dpico_arg.find("ConfigPath") != dpico_arg.end()) { + dpico_dump_config_file_ = dpico_arg.at("ConfigPath"); + } +} + +Result DpicoContextManager::InitContext(std::string dpico_dump_config_file) { + if (svp_context_ != nullptr) { + return SUCCESS; + } + int ret = SUCCESS; + if (dpico_dump_config_file == "") { + ret = svp_acl_init(NULL); + } else { + MS_LOG(INFO) + << "dump according to dump config file " << dpico_dump_config_file.c_str() + << ", if not dump data, please check weather the path exists, or whether add [online_model_type] 4, or model " + "name is not the same with instruction_name in converter cfg, default inst, muti seg custom_i"; + ret = svp_acl_init(dpico_dump_config_file.c_str()); + } + if (ret != SUCCESS) { + MS_LOG(ERROR) << "acl init failed"; + return FAILED; + } + MS_LOG(INFO) << "acl init success"; + // open device + ret = svp_acl_rt_set_device(kDeviceId); + if (ret != SUCCESS) { + MS_LOG(ERROR) << "acl open device " << kDeviceId << " failed"; + return FAILED; + } + MS_LOG(INFO) << "open device " << kDeviceId << " success"; + + // create context (set current) + ret = svp_acl_rt_create_context(&svp_context_, kDeviceId); + if (ret != SUCCESS || svp_context_ == nullptr) { + MS_LOG(ERROR) << "acl create context failed"; + return FAILED; + } + MS_LOG(INFO) << "create context success"; + return SUCCESS; +} + +void DpicoContextManager::DestroyContext() { + if (svp_context_ != nullptr) { + auto ret = svp_acl_rt_destroy_context(svp_context_); + if (ret != SVP_ACL_SUCCESS) { + MS_LOG(ERROR) << "destroy context failed"; + } + svp_context_ = nullptr; + } + + MS_LOG(INFO) << "end to destroy context"; + auto ret = svp_acl_rt_reset_device(kDeviceId); + if (ret != SVP_ACL_SUCCESS) { + MS_LOG(ERROR) << "reset device failed"; + } + MS_LOG(INFO) << "end to reset device is " << kDeviceId; + + ret = svp_acl_finalize(); + if (ret != SVP_ACL_SUCCESS) { + MS_LOG(ERROR) << "finalize acl failed"; + } + MS_LOG(INFO) << "end to finalize acl"; +} + +void DpicoAicpuThreadManager::CreateAicpuThread(uint32_t model_id) { + uint32_t aicpu_task_num = 0; + svp_acl_ext_get_mdl_aicpu_task_num(model_id, &aicpu_task_num); + all_aicpu_task_num_ += aicpu_task_num; + if (all_aicpu_task_num_ > 0 && !is_aicpu_thread_activity_) { + kThreadRunning = true; + aicpu_thread_ = std::thread(AicpuThread); + is_aicpu_thread_activity_ = true; + } +} + +void DpicoAicpuThreadManager::DestroyAicpuThread() { + if (all_aicpu_task_num_ > 0 && is_aicpu_thread_activity_) { + kThreadRunning = false; + aicpu_thread_.join(); + all_aicpu_task_num_ = 0; + is_aicpu_thread_activity_ = false; + } +} +} // namespace lite +} // namespace mindspore diff --git a/mindspore/lite/tools/benchmark/dpico/src/common_utils.h b/mindspore/lite/tools/benchmark/dpico/src/common_utils.h new file mode 100644 index 0000000000..776d2991ff --- /dev/null +++ b/mindspore/lite/tools/benchmark/dpico/src/common_utils.h @@ -0,0 +1,113 @@ +/** + * 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_RUNTIME_KERNEL_ARM_FP32_COMMON_UTILS_H_ +#define MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_FP32_COMMON_UTILS_H_ + +#include +#include +#include +#include +#include "include/api/context.h" +#include "include/api/kernel.h" +#include "include/svp_acl_base.h" +#include "schema/model_generated.h" +#include "src/custom_log.h" + +namespace mindspore { +namespace lite { +inline constexpr size_t kMinInputSize = 2; +inline constexpr auto kNetType = "net_type"; + +typedef enum Result : int { SUCCESS = 0, FAILED = 1 } Result; +typedef enum OmNetType : int { OmNetType_CNN = 0, OmNetType_ROI = 1, OmNetType_RECURRENT = 2 } OmNetType; + +#define MS_CHECK_FALSE_MSG(value, errcode, msg) \ + do { \ + if ((value)) { \ + MS_LOG(ERROR) << #msg; \ + return errcode; \ + } \ + } while (0) + +inline bool IsValidUnsignedNum(const std::string &num_str) { + return !num_str.empty() && std::all_of(num_str.begin(), num_str.end(), ::isdigit); +} + +bool InferDone(const std::vector &tensors); + +void ExtractAttrsFromPrimitive(const mindspore::schema::Primitive *primitive, + std::map *attrs); + +void *ReadBinFile(const std::string &fileName, uint32_t *fileSize); + +Result JudgeOmNetType(const schema::Primitive &primitive, OmNetType *net_type); + +class DpicoConfigParamExtractor { + public: + DpicoConfigParamExtractor() = default; + ~DpicoConfigParamExtractor() = default; + void InitDpicoConfigParam(const kernel::Kernel &kernel); + void UpdateDpicoConfigParam(const kernel::Kernel &kernel); + size_t GetMaxRoiNum() { return max_roi_num_; } + float GetNmsThreshold() { return nms_threshold_; } + float GetScoreThreshold() { return score_threshold_; } + float GetMinHeight() { return min_height_; } + float GetMinWidth() { return min_width_; } + int GetGTotalT() { return g_total_t_; } + int GetDpicoDetectionPostProcess() { return dpico_detection_post_process_; } + std::string GetDpicoDumpConfigFile() { return dpico_dump_config_file_; } + + private: + size_t max_roi_num_{400}; + float nms_threshold_{0.9f}; + float score_threshold_{0.08f}; + float min_height_{1.0f}; + float min_width_{1.0f}; + int g_total_t_{0}; + int dpico_detection_post_process_{0}; + bool has_init_{false}; + std::string dpico_dump_config_file_{""}; +}; + +class DpicoContextManager { + public: + DpicoContextManager() = default; + ~DpicoContextManager() = default; + Result InitContext(std::string dpico_dump_config_file); + void DestroyContext(); + svp_acl_rt_context GetSvpContext() { return svp_context_; } + + private: + svp_acl_rt_context svp_context_{nullptr}; +}; + +class DpicoAicpuThreadManager { + public: + DpicoAicpuThreadManager() = default; + ~DpicoAicpuThreadManager() = default; + void CreateAicpuThread(uint32_t model_id); + void DestroyAicpuThread(); + + private: + uint32_t all_aicpu_task_num_{0}; + bool is_aicpu_thread_activity_{false}; + std::thread aicpu_thread_; +}; +} // namespace lite +} // namespace mindspore + +#endif // LITE_COMMON_UTILS_H diff --git a/mindspore/lite/tools/benchmark/dpico/src/custom_fp32.cc b/mindspore/lite/tools/benchmark/dpico/src/custom_fp32.cc new file mode 100644 index 0000000000..acfd72d2cd --- /dev/null +++ b/mindspore/lite/tools/benchmark/dpico/src/custom_fp32.cc @@ -0,0 +1,1021 @@ +/** + * 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 "src/custom_fp32.h" +#include +#include +#include +#include +#include "schema/model_generated.h" +#include "include/registry/register_kernel.h" +#include "include/api/context.h" + +using mindspore::schema::PrimitiveType_Custom; +constexpr int RET_OK = 0; /**< No error occurs. */ +constexpr int RET_ERROR = -1; /**< Common error code. */ +constexpr int RET_NULL_PTR = -2; /**< NULL pointer returned.*/ + +namespace mindspore { +namespace lite { +namespace { +constexpr size_t kBitNumOfOneByte = 8; + +constexpr size_t TOP_LEFT_X = 0; +constexpr size_t TOP_LEFT_Y = 1; +constexpr size_t BOTTOM_RIGHT_X = 2; +constexpr size_t BOTTOM_RIGHT_Y = 3; +constexpr size_t SCORE = 4; +constexpr size_t CLASS_ID = 5; +constexpr size_t BBOX_SIZE = 6; + +constexpr size_t NMS_THR = 0; +constexpr size_t SCORE_THR = 1; +constexpr size_t MIN_HEIGHT = 2; +constexpr size_t MIN_WIDTH = 3; + +int DetermineInputIndexInOm(const svp_acl_mdl_desc *model_desc, const std::string &tensor_name, size_t *input_index) { + MS_CHECK_FALSE_MSG(model_desc == nullptr || input_index == nullptr, SVP_ACL_ERROR_INVALID_PARAM, + "The function's parameter is nullptr."); + std::string om_tensor_name = tensor_name; + + // post match + std::vector patterns{"_nh2nc", "_nh2nc", "_post"}; + bool has_matched = false; + for (const auto &pattern : patterns) { + if (tensor_name.size() >= pattern.size() && tensor_name.rfind(pattern) == tensor_name.size() - pattern.size()) { + om_tensor_name = tensor_name.substr(0, tensor_name.size() - pattern.size()); + has_matched = true; + break; + } + } + + // pre match + if (!has_matched) { + std::string pattern = "duplicate_"; + auto find_index = tensor_name.find(pattern); + if (find_index != std::string::npos) { // todo return size_t + om_tensor_name = tensor_name.substr(find_index + pattern.size()); + } + } + return svp_acl_mdl_get_input_index_by_name(model_desc, om_tensor_name.c_str(), input_index); +} +} // namespace + +size_t CustomCPUKernel::num_of_om_model_ = 0; +dpico::CustomInterface CustomCPUKernel::custom_infershape_ = dpico::CustomInterface(); +DpicoConfigParamExtractor CustomCPUKernel::dpico_config_param_extractor_ = DpicoConfigParamExtractor(); +DpicoContextManager CustomCPUKernel::dpico_context_manager_ = DpicoContextManager(); +DpicoAicpuThreadManager CustomCPUKernel::dpico_aicpu_thread_manager_ = DpicoAicpuThreadManager(); + +Result CustomCPUKernel::DetermineBatchSize() { + MS_CHECK_FALSE_MSG(model_desc_ == nullptr, FAILED, "the om hasn't been loaded."); + if (inputs_.size() < kMinInputSize) { + MS_LOG(ERROR) << "inputs' num is invalid, which now is less than 2"; + return FAILED; + } + std::vector batch_sizes; + for (size_t index = 0; index < inputs_.size() - 1; ++index) { + auto lite_shape = inputs_[index].Shape(); + if (lite_shape.empty() || std::any_of(lite_shape.begin(), lite_shape.end(), [](int64_t val) { return val <= 0; })) { + MS_LOG(ERROR) << "lite shape is invalid, which contains negative."; + return FAILED; + } + svp_acl_mdl_io_dims om_input_info; + auto ret = GetInputDims(index, &om_input_info); + if (ret != SUCCESS) { + MS_LOG(ERROR) << "get input shape from om failed"; + return FAILED; + } + auto om_shape = om_input_info.dims; + if (lite_shape.size() != om_input_info.dim_count) { + MS_LOG(ERROR) << "lite shape size is different that of om."; + return FAILED; + } + if (std::any_of(om_shape, om_shape + om_input_info.dim_count, [](int64_t val) { return val <= 0; })) { + MS_LOG(ERROR) << "lite shape is invalid, which contains negative."; + return FAILED; + } + for (size_t dim = 1; dim < lite_shape.size(); ++dim) { + if (lite_shape[dim] != om_shape[dim]) { + MS_LOG(ERROR) << "lite shape cannot match om shape."; + return FAILED; + } + } + if (lite_shape.front() % om_shape[0] != 0) { + MS_LOG(ERROR) << "lite shape cannot match om shape."; + return FAILED; + } + auto batch_size = lite_shape.front() / om_shape[0]; + if (batch_size > static_cast(INT_MAX)) { + MS_LOG(ERROR) << "batch size is out of range INT_MAX."; + return FAILED; + } + batch_sizes.push_back(static_cast(batch_size)); + } + batch_size_ = batch_sizes.front(); + if (std::any_of(batch_sizes.begin(), batch_sizes.end(), + [this](int val) { return static_cast(val) != batch_size_; })) { + MS_LOG(ERROR) << "all inputs's batch size is different."; + return FAILED; + } + return SUCCESS; +} + +int CustomCPUKernel::LoadModelAndInitResource() { + OmNetType net_type{OmNetType_CNN}; + int ret = JudgeOmNetType(*primitive_, &net_type); + if (ret != SUCCESS) { + MS_LOG(ERROR) << "get model attr failed"; + return FAILED; + } + is_detection_net_ = net_type == OmNetType_ROI; + is_recurrent_net_ = net_type == OmNetType_RECURRENT; + ret = PrepareDevice(); + if (ret != SUCCESS) { + MS_LOG(ERROR) << "sample init resource failed"; + return FAILED; + } + ret = LoadModel(); + if (ret != SUCCESS) { + MS_LOG(ERROR) << "execute LoadModel failed"; + return FAILED; + } + dpico_aicpu_thread_manager_.CreateAicpuThread(model_id_); + return SUCCESS; +} + +int CustomCPUKernel::Prepare() { + if (prepared_) { + return RET_OK; + } + MS_CHECK_FALSE_MSG(primitive_ == nullptr, RET_NULL_PTR, "primitive is nullptr"); + if (inputs_.size() < kMinInputSize || outputs_.size() < 1) { + return RET_ERROR; + } + dpico_config_param_extractor_.InitDpicoConfigParam(*this); + if (!load_flag_) { + LoadModelAndInitResource(); + } + if (!InferDone(outputs_)) { + return RET_OK; + } + + if (inputs_[0].Shape().size() < 1) { + return RET_ERROR; + } + + if (!is_recurrent_net_) { + if (DetermineBatchSize() != SUCCESS) { + MS_LOG(ERROR) << "cannot determine batch size."; + return RET_ERROR; + } + } else { + auto g_total_t = dpico_config_param_extractor_.GetGTotalT(); + if (g_total_t != 0) { + recurrent_total_t = g_total_t; + if (recurrent_total_t > (size_t)inputs_[0].Shape().at(0)) { + MS_LOG(ERROR) << "recurrent_total_t " << recurrent_total_t << " is bigger than batch " + << inputs_[0].Shape().at(0) << ", now this condition is not supported"; + return RET_ERROR; + } + } else { + recurrent_total_t = inputs_[0].Shape().at(0); + } + } + + int ret = CreateOutputs(); + if (ret != SUCCESS) { + MS_LOG(ERROR) << "execute CreateOutputs failed"; + return FAILED; + } + + ret = CreateInputs(); + if (ret != SUCCESS) { + MS_LOG(ERROR) << "create inputs failed, may memory not enough, please run it without dpico"; + MS_LOG(ERROR) << "use cmd: cat /proc/umap/media-mem when program running to see memory"; + return RET_ERROR; + } + prepared_ = true; + return RET_OK; +} + +int CustomCPUKernel::ReSize() { + if (prepared_) { + DestroyInput(); + DestroyOutput(); + inputs_data_in_npu_.clear(); + prepared_ = false; + } + Prepare(); + return RET_OK; +} + +Result CustomCPUKernel::PreExecute() { + if (!InferDone(outputs_)) { + if (custom_infershape_.Infer(&inputs_, &outputs_, primitive_, this) != kSuccess) { + MS_LOG(ERROR) << "infershape failed when running."; + return FAILED; + } + auto ret = ReSize(); + if (ret != RET_OK) { + MS_LOG(ERROR) << "reSize fail."; + return FAILED; + } + for (auto output : outputs_) { + auto output_data = output.MutableData(); + MS_CHECK_FALSE_MSG(output_data == nullptr, FAILED, "malloc data failed."); + } + } + return SUCCESS; +} + +int CustomCPUKernel::Execute() { + enum { TENSOR_FIRST_INDEX = 0, OM_FIRST_INDEX = 0 }; + if (PreExecute() != SUCCESS) { + MS_LOG(ERROR) << "pre-execute failed."; + return RET_ERROR; + } + int ret = CopyTensorsToNpuWithStride(); + if (ret != SUCCESS) { + MS_LOG(ERROR) << "CopyTensorsToNpuWithStride failed"; + return RET_ERROR; + } + if (is_detection_net_) { + UpdateDetParas(); + } + svp_acl_rt_set_current_context(dpico_context_manager_.GetSvpContext()); + ret = DeviceExecute(); + if (ret != SUCCESS) { + MS_LOG(ERROR) << "execute inference failed"; + return RET_ERROR; + } + + if (is_detection_net_) { + if (dpico_config_param_extractor_.GetDpicoDetectionPostProcess() == 1) { + OutputModelResult(); + WriteOutputToTensor(TENSOR_FIRST_INDEX, OM_FIRST_INDEX); + } else { + DumpModelOutputResultToTensor(); + } + } else { + DumpModelOutputResultToTensor(); + } + return RET_OK; +} + +CustomCPUKernel::~CustomCPUKernel() { + num_of_om_model_--; + dpico_aicpu_thread_manager_.DestroyAicpuThread(); + UnloadModel(); + DestroyInput(); + DestroyOutput(); + TerminateDevice(); +} + +std::shared_ptr CustomCreateKernel(const std::vector &inputs, + const std::vector &outputs, + const mindspore::schema::Primitive *primitive, + const mindspore::Context *ctx) { + MS_CHECK_FALSE_MSG(primitive == nullptr, nullptr, "primitive is nullptr"); + MS_CHECK_FALSE_MSG(ctx == nullptr, nullptr, "ctx is nullptr"); + + if (primitive->value_type() != mindspore::schema::PrimitiveType_Custom) { + MS_LOG(ERROR) << "Primitive type is not PrimitiveType_Custom"; + return nullptr; + } + + auto op = primitive->value_as_Custom(); + MS_CHECK_FALSE_MSG(op == nullptr, nullptr, "op is nullptr"); + MS_CHECK_FALSE_MSG(op->attr() == nullptr, nullptr, "op atrr is nullptr"); + if (op->attr()->size() < 1) { + MS_LOG(ERROR) << "There are at least 1 attribute of Custom"; + return nullptr; + } + + auto kernel = std::make_shared(inputs, outputs, primitive, ctx); + MS_CHECK_FALSE_MSG(kernel == nullptr, nullptr, "new custom kernel is nullptr"); + return kernel; +} + +Result CustomCPUKernel::LoadModel() { + auto model_buf = reinterpret_cast(inputs_[inputs_.size() - 1].MutableData()); + auto model_size = inputs_[inputs_.size() - 1].DataSize(); + svp_acl_error ret = SVP_ACL_SUCCESS; + ret = svp_acl_rt_malloc(&model_mem_ptr_, model_size, SVP_ACL_MEM_MALLOC_NORMAL_ONLY); + if (ret != SVP_ACL_SUCCESS) { + MS_LOG(ERROR) << "malloc device buffer failed. size is " << model_size; + return FAILED; + } + memcpy(model_mem_ptr_, model_buf, model_size); + ret = svp_acl_mdl_load_from_mem(static_cast(model_mem_ptr_), model_size, &model_id_); + if (ret != SVP_ACL_SUCCESS) { + svp_acl_rt_free(model_mem_ptr_); + MS_LOG(ERROR) << "load model from file failed, model file"; + return FAILED; + } + load_flag_ = true; + MS_LOG(INFO) << "load model success"; + + // obtain om's desc. + model_desc_ = svp_acl_mdl_create_desc(); + if (model_desc_ == nullptr) { + svp_acl_rt_free(model_mem_ptr_); + MS_LOG(ERROR) << "create model description failed"; + return FAILED; + } + auto status = svp_acl_mdl_get_desc(model_desc_, model_id_); + if (status != SVP_ACL_SUCCESS) { + svp_acl_rt_free(model_mem_ptr_); + MS_LOG(ERROR) << "get model description failed"; + return FAILED; + } + MS_LOG(INFO) << "create model description success"; + return SUCCESS; +} + +Result CustomCPUKernel::CreateInput(void *inputDataBuffer, size_t bufferSize, int stride) { + MS_CHECK_FALSE_MSG(inputDataBuffer == nullptr, FAILED, "inputdatabuffer is nullptr"); + svp_acl_data_buffer *inputData = svp_acl_create_data_buffer(inputDataBuffer, bufferSize, stride); + MS_CHECK_FALSE_MSG(inputData == nullptr, FAILED, "can't create data buffer, create input failed"); + + svp_acl_error ret = svp_acl_mdl_add_dataset_buffer(input_, inputData); + if (ret != SVP_ACL_SUCCESS) { + MS_LOG(ERROR) << "add input dataset buffer failed"; + svp_acl_destroy_data_buffer(inputData); + inputData = nullptr; + return FAILED; + } + + return SUCCESS; +} + +Result CustomCPUKernel::GetInputDims(int index, svp_acl_mdl_io_dims *dims) { + if (dims == nullptr) { + return FAILED; + } + svp_acl_error ret = svp_acl_mdl_get_input_dims(model_desc_, index, dims); + if (ret != SVP_ACL_SUCCESS) { + MS_LOG(ERROR) << "svp_acl_mdl_get_input_dims error!"; + return FAILED; + } + return SUCCESS; +} + +size_t CustomCPUKernel::GetInputDataSize(int index) { + svp_acl_data_type dataType = svp_acl_mdl_get_input_data_type(model_desc_, index); + return svp_acl_data_type_size(dataType) / kBitNumOfOneByte; +} + +Result CustomCPUKernel::GetStrideParam(size_t *devSize, int index, size_t *stride, svp_acl_mdl_io_dims *dims) { + MS_CHECK_FALSE_MSG(devSize == nullptr || stride == nullptr || dims == nullptr, FAILED, "nullptr found"); + Result ret = GetInputDims(index, dims); + if (ret != SUCCESS) { + MS_LOG(ERROR) << "GetModelInputDims error!"; + return FAILED; + } + *stride = svp_acl_mdl_get_input_default_stride(model_desc_, index); + if (*stride == 0) { + MS_LOG(ERROR) << "svp_acl_mdl_get_input_default_stride error!"; + return FAILED; + } + *devSize = svp_acl_mdl_get_input_size_by_index(model_desc_, index); + if (*devSize == 0) { + MS_LOG(ERROR) << "svp_acl_mdl_get_input_size_by_index error!"; + return FAILED; + } + return SUCCESS; +} + +void CustomCPUKernel::DestroyInput() { + if (input_ == nullptr) { + return; + } + for (size_t i = 0; i < svp_acl_mdl_get_dataset_num_buffers(input_); ++i) { + svp_acl_data_buffer *dataBuffer = svp_acl_mdl_get_dataset_buffer(input_, i); + void *tmp = svp_acl_get_data_buffer_addr(dataBuffer); + svp_acl_rt_free(tmp); + svp_acl_destroy_data_buffer(dataBuffer); + } + svp_acl_mdl_destroy_dataset(input_); + input_ = nullptr; +} + +void CustomCPUKernel::DestroyOutput() { + if (output_ == nullptr) { + return; + } + for (size_t i = 0; i < svp_acl_mdl_get_dataset_num_buffers(output_); ++i) { + svp_acl_data_buffer *dataBuffer = svp_acl_mdl_get_dataset_buffer(output_, i); + void *data = svp_acl_get_data_buffer_addr(dataBuffer); + (void)svp_acl_rt_free(data); + (void)svp_acl_destroy_data_buffer(dataBuffer); + } + + (void)svp_acl_mdl_destroy_dataset(output_); + output_ = nullptr; +} + +Result CustomCPUKernel::CreateOutputs() { + MS_CHECK_FALSE_MSG(model_desc_ == nullptr, FAILED, "no model description, create output failed"); + + output_ = svp_acl_mdl_create_dataset(); + if (output_ == nullptr) { + MS_LOG(ERROR) << "can't create dataset, create output failed"; + return FAILED; + } + size_t outputSize = svp_acl_mdl_get_num_outputs(model_desc_); + for (size_t i = 0; i < outputSize; ++i) { + size_t stride = svp_acl_mdl_get_output_default_stride(model_desc_, i); + if (stride == 0) { + MS_LOG(ERROR) << "output default stride is " << stride; + return FAILED; + } + size_t buffer_size = svp_acl_mdl_get_output_size_by_index(model_desc_, i); + if (buffer_size == 0) { + MS_LOG(ERROR) << "output size is " << buffer_size; + return FAILED; + } + + void *outputBuffer = nullptr; + svp_acl_error ret = + svp_acl_rt_malloc_cached(&outputBuffer, buffer_size * batch_size_, SVP_ACL_MEM_MALLOC_NORMAL_ONLY); + if (ret != SVP_ACL_SUCCESS) { + MS_LOG(ERROR) << "can't malloc buffer, size is " << buffer_size << ", create output failed"; + return FAILED; + } + + svp_acl_data_buffer *outputData = svp_acl_create_data_buffer(outputBuffer, buffer_size * batch_size_, stride); + if (ret != SVP_ACL_SUCCESS) { + MS_LOG(ERROR) << "can't create data buffer, create output failed"; + svp_acl_rt_free(outputBuffer); + return FAILED; + } + ret = svp_acl_mdl_add_dataset_buffer(output_, outputData); + if (ret != SVP_ACL_SUCCESS) { + MS_LOG(ERROR) << "can't add data buffer, create output failed"; + svp_acl_rt_free(outputBuffer); + svp_acl_destroy_data_buffer(outputData); + return FAILED; + } + } + + MS_LOG(INFO) << "create model output success"; + return SUCCESS; +} + +bool Cmp(const std::vector &veci, const std::vector &vecj) { + if (veci[CLASS_ID] < vecj[CLASS_ID]) { + return true; + } else if (veci[CLASS_ID] == vecj[CLASS_ID]) { + return veci[SCORE] > vecj[SCORE]; + } + return false; +} + +void CustomCPUKernel::PrintResultToTensor(const std::vector> &boxValue) { + std::vector clsNum; + float cId = boxValue[0][CLASS_ID]; + int validNum = 0; + for (size_t loop = 0; loop < boxValue.size(); loop++) { + if (boxValue[loop][CLASS_ID] == cId) { + validNum++; + } else { + clsNum.push_back(validNum); + cId = boxValue[loop][CLASS_ID]; + validNum = 1; + } + } + clsNum.push_back(validNum); + int idx = 0; + int sumNum = 0; + MS_LOG(INFO) << "current class valid box number is: " << clsNum[idx]; + sumNum += clsNum[idx]; + int totalBoxNum = boxValue.size(); + const size_t min_detect_output_size = 2; + if (outputs_.size() < min_detect_output_size) { + return; + } + float *box_value_in_tensor = reinterpret_cast(outputs_[1].MutableData()); + if (box_value_in_tensor == nullptr) { + return; + } + if (outputs_[1].ElementNum() < totalBoxNum * BBOX_SIZE) { + return; + } + for (int loop = 0; loop < totalBoxNum; loop++) { + if (loop == sumNum) { + idx++; + MS_LOG(INFO) << "current class valid box number is: " << clsNum[idx]; + sumNum += clsNum[idx]; + } + MS_LOG(INFO) << "lx: " << boxValue[loop][TOP_LEFT_X] << ", ly: " << boxValue[loop][TOP_LEFT_Y] + << ", rx: " << boxValue[loop][BOTTOM_RIGHT_X] << ", ry: " << boxValue[loop][BOTTOM_RIGHT_Y] + << ", score: " << boxValue[loop][SCORE] << "; class id: " << boxValue[loop][CLASS_ID]; + box_value_in_tensor[loop] = boxValue[loop][TOP_LEFT_X]; + box_value_in_tensor[totalBoxNum + loop] = boxValue[loop][TOP_LEFT_Y]; + box_value_in_tensor[2 * totalBoxNum + loop] = boxValue[loop][BOTTOM_RIGHT_X]; + box_value_in_tensor[3 * totalBoxNum + loop] = boxValue[loop][BOTTOM_RIGHT_Y]; + box_value_in_tensor[4 * totalBoxNum + loop] = boxValue[loop][SCORE]; + box_value_in_tensor[5 * totalBoxNum + loop] = boxValue[loop][CLASS_ID]; + } + outputs_[1].SetShape({1, totalBoxNum * BBOX_SIZE}); +} + +void CustomCPUKernel::OutputModelResult() { + // yolo/ssd output 0 is num, output 1 is bbox + enum InputOutputId { INPUT_IMG_ID = 0, OUTPUT_NUM_ID = 0, OUTPUT_BBOX_ID = 1 }; + // get valid box number + svp_acl_mdl_io_dims aclDims; + std::vector validBoxNum; + svp_acl_mdl_get_output_dims(model_desc_, OUTPUT_NUM_ID, &aclDims); + svp_acl_data_buffer *dataBuffer = svp_acl_mdl_get_dataset_buffer(output_, OUTPUT_NUM_ID); + auto outData = reinterpret_cast(svp_acl_get_data_buffer_addr(dataBuffer)); + for (uint32_t loop = 0; loop < static_cast(aclDims.dims[aclDims.dim_count - 1]); loop++) { + validBoxNum.push_back(*(outData + loop)); + } + int totalValidNum = 0; + for (size_t loop = 0; loop < validBoxNum.size(); loop++) { + totalValidNum += validBoxNum[loop]; + } + if (totalValidNum == 0) { + MS_LOG(INFO) << "total valid num is zero"; + return; + } + + // get x y score + svp_acl_data_buffer *dataBufferValue = svp_acl_mdl_get_dataset_buffer(output_, OUTPUT_BBOX_ID); + auto outDataValue = reinterpret_cast(svp_acl_get_data_buffer_addr(dataBufferValue)); + svp_acl_mdl_get_output_dims(model_desc_, OUTPUT_BBOX_ID, &aclDims); + if (aclDims.dim_count <= 0) { + MS_LOG(ERROR) << "aclrtOutputDims error"; + return; + } + + svp_acl_error ret = svp_acl_mdl_get_input_dims(model_desc_, INPUT_IMG_ID, &aclDims); + if (ret != SVP_ACL_SUCCESS || aclDims.dim_count <= 2) { + MS_LOG(ERROR) << "svp_acl_mdl_get_input_dims error!"; + return; + } + // input data shape is nchw, 2 is stand h + int imgHeight = aclDims.dims[aclDims.dim_count - 2]; + int imgWidth = aclDims.dims[aclDims.dim_count - 1]; + MS_LOG(INFO) << "input image width[" << imgWidth << "]; height[" << imgHeight << "]"; + + size_t wStrideOffset = svp_acl_mdl_get_output_default_stride(model_desc_, OUTPUT_BBOX_ID) / sizeof(float); + // box include 6 part which is lx, ly, rx, ry, score, class idq + std::vector> bboxes; + for (int inx = 0; inx < totalValidNum; inx++) { + float classId = (*(outDataValue + inx + CLASS_ID * wStrideOffset)); + if (classId == 0.0f) { + continue; // skip class 0 back ground + } + std::vector bbox(BBOX_SIZE, 0.0f); + for (size_t loop = 0; loop < BBOX_SIZE; loop++) { + bbox[loop] = (*(outDataValue + inx + loop * wStrideOffset)); + } + bboxes.push_back(bbox); + } + std::sort(bboxes.begin(), bboxes.end(), Cmp); + PrintResultToTensor(bboxes); + MS_LOG(INFO) << "output data success"; + return; +} + +void CustomCPUKernel::WriteOutputToTensor(size_t index, size_t output_tensor_index) { + svp_acl_data_buffer *dataBuffer = svp_acl_mdl_get_dataset_buffer(output_, index); + void *data = svp_acl_get_data_buffer_addr(dataBuffer); + size_t stride = svp_acl_get_data_buffer_stride(dataBuffer); + svp_acl_data_type dataType = svp_acl_mdl_get_output_data_type(model_desc_, index); + size_t dataSize = svp_acl_data_type_size(dataType); + svp_acl_mdl_io_dims dims; + int ret = svp_acl_mdl_get_output_dims(model_desc_, index, &dims); + if (ret != SUCCESS) { + MS_LOG(ERROR) << "get output dims fail"; + return; + } + int outNum = 1 * batch_size_; + for (size_t i = 0; i < dims.dim_count - 1; ++i) { + outNum *= dims.dims[i]; + } + if (is_recurrent_net_) { + if (index == 0) { + if (dims.dims[0] == 0) { + return; + } + outNum = outNum / dims.dims[0] * recurrent_total_t; + } + } + if (dims.dim_count < 1) { + return; + } + uint32_t w = dims.dims[dims.dim_count - 1]; + auto outTensorData = reinterpret_cast(outputs_[output_tensor_index].MutableData()); + if (outTensorData == nullptr) { + return; + } + int valid_size_per_stride = ceil(w * dataSize / kBitNumOfOneByte); + size_t om_valid_data_size = static_cast(outNum * valid_size_per_stride); + if (om_valid_data_size != outputs_[output_tensor_index].DataSize()) { + MS_LOG(ERROR) << "outnum * valid_size_per_stride in om is not equal to corresponding output tensor"; + return; + } + size_t out_data_buffer_size = svp_acl_get_data_buffer_size(dataBuffer); + ret = svp_acl_rt_mem_flush(data, out_data_buffer_size); + if (ret != SUCCESS) { + MS_LOG(ERROR) << "flush error"; + return; + } + for (int n = 0; n < outNum; n++) { + auto outData = reinterpret_cast(data) + n * stride; + memcpy(outTensorData + n * valid_size_per_stride, outData, valid_size_per_stride); + } + return; +} + +void CustomCPUKernel::DumpModelOutputResultToTensor() { + size_t outputNum = svp_acl_mdl_get_dataset_num_buffers(output_); + std::map output_tensor_name; + for (size_t i = 0; i < outputs_.size(); i++) { + output_tensor_name[outputs_[i].Name()] = i; + } + bool link_om_top_and_tensor_index = false; + for (size_t i = 0; i < outputNum; ++i) { + std::string om_index_name = svp_acl_mdl_get_output_name_by_index(model_desc_, i); + std::string om_index_name_duplicate = om_index_name + "_duplicate"; + if (output_tensor_name.find(om_index_name_duplicate) != output_tensor_name.end()) { + WriteOutputToTensor(i, output_tensor_name[om_index_name_duplicate]); + link_om_top_and_tensor_index = true; + } else if (output_tensor_name.find(om_index_name) != output_tensor_name.end()) { + WriteOutputToTensor(i, output_tensor_name[om_index_name]); + link_om_top_and_tensor_index = true; + } + } + if (!link_om_top_and_tensor_index) { + MS_LOG(ERROR) << "the om top index and tensor index is not linked"; + MS_LOG(INFO) << "the tensor value maybe nan or random value"; + MS_LOG(INFO) << "the mindspore tensor name is:"; + for (size_t i = 0; i < outputs_.size(); i++) { + std::string tensor_name = outputs_[i].Name(); + MS_LOG(INFO) << "tensor index: " << i << ", tensor name: " << tensor_name.c_str(); + } + MS_LOG(INFO) << "the om top name is below after adding duplicate to keep similar with tensor:"; + for (size_t i = 0; i < outputNum; ++i) { + std::string om_top_name = svp_acl_mdl_get_output_name_by_index(model_desc_, i); + std::string om_top_name_add_duplicate = om_top_name + "_duplicate"; + MS_LOG(INFO) << "om top index: " << i << ", om top name: " << om_top_name_add_duplicate.c_str(); + } + return; + } + MS_LOG(INFO) << "dump data success"; +} + +Result CustomCPUKernel::DeviceExecute() { + int ret = svp_acl_mdl_execute(model_id_, input_, output_); + if (ret != SVP_ACL_SUCCESS) { + MS_LOG(ERROR) << "execute model failed, modelId is " << model_id_; + return FAILED; + } + + MS_LOG(INFO) << "model execute success"; + return SUCCESS; +} + +Result CustomCPUKernel::CreateBuf(int index) { + void *bufPtr = nullptr; + size_t bufSize = 0; + size_t bufStride = 0; + svp_acl_mdl_io_dims inDims; + svp_acl_error ret = GetStrideParam(&bufSize, index, &bufStride, &inDims); + if (ret != SUCCESS) { + MS_LOG(ERROR) << "get stride param fialed"; + return FAILED; + } + + ret = svp_acl_rt_malloc(&bufPtr, bufSize, SVP_ACL_MEM_MALLOC_NORMAL_ONLY); + if (ret != SVP_ACL_SUCCESS) { + MS_LOG(ERROR) << "malloc device buffer failed. size is " << bufSize; + return FAILED; + } + ret = CreateInput(bufPtr, bufSize, bufStride); + if (ret != SUCCESS) { + MS_LOG(ERROR) << "execute CreateInput failed"; + svp_acl_rt_free(bufPtr); + return FAILED; + } + return SUCCESS; +} + +Result CustomCPUKernel::CreateTaskBufAndWorkBuf() { + // 2 is stand taskbuf and workbuf + if (svp_acl_mdl_get_num_inputs(model_desc_) <= 2) { + MS_LOG(ERROR) << "input dataset Num is error."; + return FAILED; + } + int datasetSize = svp_acl_mdl_get_dataset_num_buffers(input_); + if (datasetSize == 0) { + MS_LOG(ERROR) << "input dataset Num is 0."; + return FAILED; + } + for (size_t loop = datasetSize; loop < svp_acl_mdl_get_num_inputs(model_desc_); loop++) { + Result ret = CreateBuf(loop); + if (ret != SUCCESS) { + MS_LOG(ERROR) << "execute Create taskBuffer and workBuffer failed"; + return FAILED; + } + } + return SUCCESS; +} + +void CustomCPUKernel::UnloadModel() { + if (load_flag_) { + svp_acl_error ret = svp_acl_mdl_unload(model_id_); + if (ret != SVP_ACL_SUCCESS) { + MS_LOG(ERROR) << "unload model failed, modelId is " << model_id_; + } else { + MS_LOG(INFO) << "unload model success, modelId is " << model_id_; + } + load_flag_ = false; + } + + if (model_desc_ != nullptr) { + (void)svp_acl_mdl_destroy_desc(model_desc_); + model_desc_ = nullptr; + } + + if (model_mem_ptr_ != nullptr) { + svp_acl_rt_free(model_mem_ptr_); + model_mem_ptr_ = nullptr; + } +} + +Result CustomCPUKernel::CopyTensorsToNpuWithStride() { + for (size_t index = 0; index < inputs_.size() - 1; ++index) { + auto tensor = inputs_[index]; + size_t devSize; + size_t stride; + svp_acl_mdl_io_dims dims; + Result ret = GetStrideParam(&devSize, index, &stride, &dims); + if (ret != SUCCESS) { + MS_LOG(ERROR) << "get stride param erro"; + return ret; + } + size_t dataSize = GetInputDataSize(index); + auto tensor_data = tensor.MutableData(); + if (tensor_data == nullptr) { + return FAILED; + } + uint32_t loopTimes = dims.dims[0] * batch_size_; + if (is_recurrent_net_ && index == 0) { + loopTimes = recurrent_total_t; + if (dims.dim_count < 3) { + MS_LOG(ERROR) << "recurrent first input must be not less than 3"; + return FAILED; + } + MS_LOG(INFO) << "lstm net, the index 0 real dims in om is " << dims.dims[0] << ", " << dims.dims[1] << ", " + << dims.dims[2]; + MS_LOG(INFO) << "lstm net, the index 0 valid dims in om is " << recurrent_total_t << ", " << dims.dims[1] << ", " + << dims.dims[2]; + } + for (size_t loop = 1; loop < dims.dim_count - 1; loop++) { + loopTimes *= dims.dims[loop]; + } + devSize = loopTimes * stride; + int dimValue = dims.dims[dims.dim_count - 1]; + if (is_recurrent_net_ && index == 1) { + dimValue = recurrent_total_t; + if (dims.dim_count == 2) { + MS_LOG(INFO) << "lstm net, the index 1 real dims in om is " << dims.dims[0] << "," << dims.dims[1]; + MS_LOG(INFO) << "lstm net, the index 1 valid dims in om is " << dims.dims[0] << ", " << dimValue; + } else if (dims.dim_count == 3) { + MS_LOG(INFO) << "lstm net, the index 1 real dims in om is " << dims.dims[0] << ", " << dims.dims[1] << ", " + << dims.dims[2]; + MS_LOG(INFO) << "lstm net, the index 1 valid dims in om is " << dims.dims[0] << ", " << dims.dims[1] << ", " + << dimValue; + } else { + MS_LOG(ERROR) << "unsupported dims count"; + return FAILED; + } + } + for (uint32_t loop = 0; loop < loopTimes; loop++) { + memcpy((static_cast(inputs_data_in_npu_[index]) + loop * stride), + (static_cast(tensor_data) + loop * dimValue * dataSize), dimValue * dataSize); + } + } + return SUCCESS; +} + +void *CustomCPUKernel::GetDeviceBufferOfTensor(const svp_acl_mdl_io_dims &dims, const size_t &stride, size_t dataSize) { + void *input_buff = nullptr; + svp_acl_error ret = SVP_ACL_SUCCESS; + uint32_t loopTimes = dims.dims[0] * batch_size_; + for (size_t loop = 1; loop < dims.dim_count - 1; loop++) { + loopTimes *= dims.dims[loop]; + } + uint32_t devSize = loopTimes * stride; + ret = svp_acl_rt_malloc(&input_buff, devSize, SVP_ACL_MEM_MALLOC_NORMAL_ONLY); + if (ret != SVP_ACL_SUCCESS) { + MS_LOG(ERROR) << "malloc device buffer failed. size is " << devSize; + return nullptr; + } + return input_buff; +} + +Result CustomCPUKernel::PrepareDevice() { + if (dpico_context_manager_.InitContext(dpico_config_param_extractor_.GetDpicoDumpConfigFile()) != SUCCESS) { + MS_LOG(ERROR) << "dpico init resource failed."; + return FAILED; + } + + // create stream + auto ret = svp_acl_rt_create_stream(&stream_); + if (ret != SUCCESS) { + MS_LOG(ERROR) << "acl create stream failed"; + return FAILED; + } + MS_LOG(INFO) << "create stream success"; + + // get run mode + svp_acl_rt_run_mode runMode; + ret = svp_acl_rt_get_run_mode(&runMode); + if (ret != SUCCESS) { + MS_LOG(ERROR) << "acl get run mode failed"; + return FAILED; + } + bool is_acl_device = (runMode == SVP_ACL_DEVICE); + if (!is_acl_device) { + MS_LOG(ERROR) << "acl run mode failed"; + return FAILED; + } + MS_LOG(INFO) << "get run mode success"; + return SUCCESS; +} + +Result CustomCPUKernel::CreateInputs() { + input_ = svp_acl_mdl_create_dataset(); + MS_CHECK_FALSE_MSG(input_ == nullptr, FAILED, "can't create dataset, create input failed"); + for (size_t loop = 0; loop < inputs_.size() - 1; ++loop) { + std::string tensor_name = inputs_[loop].Name(); + size_t index; + auto status = DetermineInputIndexInOm(model_desc_, tensor_name, &index); + if (status != SVP_ACL_SUCCESS) { + MS_LOG(WARNING) << "svp_acl_mdl_get_input_index_by_name fail! ret = " << status + << "\ninput num except the last input om model is " << (inputs_.size() - 1) + << "\ntensor name is below:"; + for (size_t tensor_index = 0; tensor_index < inputs_.size() - 1; tensor_index++) { + std::string tensor_name_inner = inputs_[tensor_index].Name(); + MS_LOG(INFO) << " tensor index: " << tensor_index << ", tensor name: " << tensor_name_inner.c_str(); + } + MS_LOG(INFO) << "om bottom name is below:"; + auto om_inputs_num = svp_acl_mdl_get_num_inputs(model_desc_); + for (size_t i = 0; i < om_inputs_num; i++) { + std::string om_bottom_name = svp_acl_mdl_get_input_name_by_index(model_desc_, i); + MS_LOG(INFO) << " om bottom index: " << static_cast(i) + << ", om bottom name: " << om_bottom_name.c_str(); + } + index = loop; + MS_LOG(WARNING) << " can't find same node, use tensor index " << loop; + } + MS_LOG(INFO) << "start to process inputs: " << loop; + size_t devSize; + size_t stride; + svp_acl_mdl_io_dims inputDims; + Result ret = GetStrideParam(&devSize, index, &stride, &inputDims); + if (ret != SUCCESS) { + MS_LOG(ERROR) << "get stride param erro"; + return ret; + } + size_t dataSize = GetInputDataSize(index); + if (dataSize == 0) { + MS_LOG(ERROR) << "the input index" << index << " data type is not support"; + return FAILED; + } + + void *picDevBuffer = GetDeviceBufferOfTensor(inputDims, stride, dataSize); + if (picDevBuffer == nullptr) { + MS_LOG(ERROR) << "get pic device buffer failed,index is " << loop; + return FAILED; + } + inputs_data_in_npu_.push_back(picDevBuffer); + ret = CreateInput(reinterpret_cast(picDevBuffer), devSize * batch_size_, stride); + if (ret != SUCCESS) { + MS_LOG(ERROR) << "execute CreateInput failed"; + svp_acl_rt_free(picDevBuffer); + return FAILED; + } + } + if (is_detection_net_) { + int ret = SetDetParas(); + if (ret != SUCCESS) { + MS_LOG(ERROR) << "SetDetParas failed"; + return FAILED; + } + } + auto ret = CreateTaskBufAndWorkBuf(); + if (ret != SUCCESS) { + MS_LOG(ERROR) << "CreateTaskBufAndWorkBuf inference failed"; + return FAILED; + } + + if (is_recurrent_net_) { + auto status = svp_acl_mdl_set_total_t(model_id_, input_, recurrent_total_t); + if (status != SVP_ACL_SUCCESS) { + MS_LOG(ERROR) << "svp_acl_mdl_set_total_t failed"; + return FAILED; + } + } + if (batch_size_ > 1) { + size_t index; + auto status = svp_acl_mdl_get_input_index_by_name(model_desc_, SVP_ACL_DYNAMIC_TENSOR_NAME, &index); + if (status != SVP_ACL_SUCCESS) { + MS_LOG(ERROR) << "svp_acl_mdl_get_input_index_by_name fail! ret = " << ret; + return FAILED; + } + status = svp_acl_mdl_set_dynamic_batch_size(model_id_, input_, index, batch_size_); + if (status != SVP_ACL_SUCCESS) { + MS_LOG(ERROR) << "svp_acl_mdl_set_dynamic_batch_size fail! ret = " << ret; + return FAILED; + } + } + return SUCCESS; +} + +void CustomCPUKernel::TerminateDevice() { + svp_acl_error ret; + if (stream_ != nullptr) { + ret = svp_acl_rt_destroy_stream(stream_); + if (ret != SVP_ACL_SUCCESS) { + MS_LOG(ERROR) << "destroy stream failed"; + } + stream_ = nullptr; + } + MS_LOG(INFO) << "end to destroy stream"; + + if (num_of_om_model_ == 0) { + dpico_context_manager_.DestroyContext(); + } +} + +void CustomCPUKernel::UpdateDetParas() { + dpico_config_param_extractor_.UpdateDpicoConfigParam(*this); + det_param_buf_float_[NMS_THR] = dpico_config_param_extractor_.GetNmsThreshold(); + det_param_buf_float_[SCORE_THR] = dpico_config_param_extractor_.GetScoreThreshold(); + det_param_buf_float_[MIN_HEIGHT] = dpico_config_param_extractor_.GetMinHeight(); + det_param_buf_float_[MIN_WIDTH] = dpico_config_param_extractor_.GetMinWidth(); +} + +Result CustomCPUKernel::SetDetParas() { + void *bufPtr = nullptr; + size_t bufferSize = 4u * sizeof(float); + svp_acl_error ret = svp_acl_rt_malloc(&bufPtr, bufferSize, SVP_ACL_MEM_MALLOC_NORMAL_ONLY); + if (ret != SVP_ACL_SUCCESS) { + MS_LOG(ERROR) << "malloc device buffer failed"; + return FAILED; + } + det_param_buf_float_ = reinterpret_cast(bufPtr); + det_param_buf_float_[NMS_THR] = dpico_config_param_extractor_.GetNmsThreshold(); + det_param_buf_float_[SCORE_THR] = dpico_config_param_extractor_.GetScoreThreshold(); + det_param_buf_float_[MIN_HEIGHT] = dpico_config_param_extractor_.GetMinHeight(); + det_param_buf_float_[MIN_WIDTH] = dpico_config_param_extractor_.GetMinWidth(); + + // det para is 4 * sizeof(float) = 16 = default stride + svp_acl_data_buffer *inputData = svp_acl_create_data_buffer(bufPtr, bufferSize, bufferSize); + if (inputData == nullptr) { + (void)svp_acl_rt_free(bufPtr); + MS_LOG(ERROR) << "can't create data buffer, create input failed"; + return FAILED; + } + + ret = svp_acl_mdl_add_dataset_buffer(input_, inputData); + if (ret != SVP_ACL_SUCCESS) { + MS_LOG(ERROR) << "add input dataset buffer failed"; + (void)svp_acl_rt_free(bufPtr); + (void)svp_acl_destroy_data_buffer(inputData); + inputData = nullptr; + return FAILED; + } + return SUCCESS; +} + +namespace { +const auto kFloat32 = DataType::kNumberTypeFloat32; +const auto kInt8 = DataType::kNumberTypeInt8; +const auto kUInt8 = DataType::kNumberTypeUInt8; +} // namespace +REGISTER_CUSTOM_KERNEL(CPU, DPICO, kFloat32, DPICO, CustomCreateKernel) +REGISTER_CUSTOM_KERNEL(CPU, DPICO, kInt8, DPICO, CustomCreateKernel) +REGISTER_CUSTOM_KERNEL(CPU, DPICO, kUInt8, DPICO, CustomCreateKernel) +} // namespace lite +} // namespace mindspore diff --git a/mindspore/lite/tools/benchmark/dpico/src/custom_fp32.h b/mindspore/lite/tools/benchmark/dpico/src/custom_fp32.h new file mode 100644 index 0000000000..f06b1060a7 --- /dev/null +++ b/mindspore/lite/tools/benchmark/dpico/src/custom_fp32.h @@ -0,0 +1,116 @@ +/** + * 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_RUNTIME_KERNEL_ARM_FP32_CUSTOM_H_ +#define MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_FP32_CUSTOM_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "include/api/kernel.h" +#include "include/svp_acl.h" +#include "include/svp_acl_mdl.h" +#include "include/svp_acl_ext.h" +#include "src/common_utils.h" +#include "src/custom_infer.h" + +using mindspore::kernel::Kernel; + +namespace mindspore { +namespace lite { +class CustomCPUKernel : public Kernel { + public: + CustomCPUKernel(const std::vector &inputs, const std::vector &outputs, + const mindspore::schema::Primitive *primitive, const mindspore::Context *ctx) + : Kernel(inputs, outputs, primitive, ctx) { + std::map attrs; + ExtractAttrsFromPrimitive(primitive, &attrs); + for (auto &item : attrs) { + SetAttr(item.first, item.second); + } + num_of_om_model_++; + } + + ~CustomCPUKernel() override; + + int Prepare() override; + int ReSize() override; + int Execute() override; + + private: + Result DetermineBatchSize(); + int LoadModelAndInitResource(); + Result LoadModel(); + Result PrepareDevice(); + Result CreateInputs(); + Result CreateOutputs(); + Result SetDetParas(); + + Result GetStrideParam(size_t *devSize, int index, size_t *stride, svp_acl_mdl_io_dims *dims); + Result CreateInput(void *inputDataBuffer, size_t bufferSize, int stride); + void *GetDeviceBufferOfTensor(const svp_acl_mdl_io_dims &dims, const size_t &stride, size_t dataSize); + Result CreateTaskBufAndWorkBuf(); + Result CreateBuf(int index); + Result GetInputDims(int index, svp_acl_mdl_io_dims *dims); + size_t GetInputDataSize(int index); + + Result PreExecute(); + Result DeviceExecute(); + Result CopyTensorsToNpuWithStride(); + void DumpModelOutputResultToTensor(); + void WriteOutputToTensor(size_t index, size_t output_tensor_index); + void OutputModelResult(); + void PrintResultToTensor(const std::vector> &boxValue); + void UpdateDetParas(); + + void UnloadModel(); + void DestroyInput(); + void DestroyOutput(); + void TerminateDevice(); + + private: + uint32_t model_id_ = 0; + void *model_mem_ptr_ = nullptr; + bool load_flag_ = false; // model load flag + svp_acl_mdl_desc *model_desc_ = nullptr; + svp_acl_mdl_dataset *input_ = nullptr; + svp_acl_mdl_dataset *output_ = nullptr; + + svp_acl_rt_stream stream_; + + std::vector inputs_data_in_npu_; + size_t recurrent_total_t = 1; + bool is_recurrent_net_ = false; // true: batch is 1, false: not support Total_t + bool is_detection_net_ = false; + size_t batch_size_ = 1; + bool prepared_ = false; + float *det_param_buf_float_ = nullptr; + static size_t num_of_om_model_; + static dpico::CustomInterface custom_infershape_; + static DpicoConfigParamExtractor dpico_config_param_extractor_; + static DpicoContextManager dpico_context_manager_; + static DpicoAicpuThreadManager dpico_aicpu_thread_manager_; +}; +} // namespace lite +} // namespace mindspore +#endif // MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_FP32_CUSTOM_H_ diff --git a/mindspore/lite/tools/benchmark/dpico/src/custom_infer.cc b/mindspore/lite/tools/benchmark/dpico/src/custom_infer.cc new file mode 100644 index 0000000000..52bb1d22e3 --- /dev/null +++ b/mindspore/lite/tools/benchmark/dpico/src/custom_infer.cc @@ -0,0 +1,280 @@ +/** + * 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 "src/custom_infer.h" +#include +#include +#include "include/api/format.h" +#include "include/registry/register_kernel_interface.h" +#include "src/common_utils.h" + +using mindspore::kernel::KernelInterface; +using mindspore::schema::PrimitiveType_Custom; + +namespace mindspore { +namespace dpico { +namespace { +constexpr int kBaseValue = 10; +constexpr auto kInputShape = "inputs_shape"; +constexpr auto kOutputShape = "outputs_shape"; +constexpr auto kOutputsFormat = "outputs_format"; +std::vector SplitString(const std::string &raw_str, char delimiter) { + if (raw_str.empty()) { + return {}; + } + std::vector res; + std::string::size_type last_pos = 0; + auto cur_pos = raw_str.find(delimiter); + while (cur_pos != std::string::npos) { + res.push_back(raw_str.substr(last_pos, cur_pos - last_pos)); + cur_pos++; + last_pos = cur_pos; + cur_pos = raw_str.find(delimiter, cur_pos); + } + if (last_pos < raw_str.size()) { + res.push_back(raw_str.substr(last_pos, raw_str.size() - last_pos + 1)); + } + return res; +} + +Status GetCustomShape(const std::map &attrs, const std::string &attr_name, + std::vector> *shapes) { + if (shapes == nullptr) { + MS_LOG(ERROR) << "the function input parameter is nullptr."; + return kLiteError; + } + auto attr = attrs.at(attr_name); + if (attr.empty()) { + MS_LOG(ERROR) << attr_name.c_str() << " data is empty."; + return kLiteError; + } + char delims[] = ","; + char *res = nullptr; + char *save_ptr = nullptr; + res = strtok_r(attr.data(), delims, &save_ptr); + while (res != nullptr) { + int64_t ndims = strtol(res, &res, kBaseValue); + int j = 0; + std::vector shape; + shape.resize(ndims); + for (; j < ndims; j++) { + res = strtok_r(NULL, delims, &save_ptr); + shape[j] = static_cast(strtol(res, &res, kBaseValue)); + } + shapes->push_back(shape); + + res = strtok_r(NULL, delims, &save_ptr); + } + return kSuccess; +} + +Status DetermineBatchSize(const std::vector &input_shape_lite, const std::vector &input_shape_dpico, + int *resize_num, bool *is_resize) { + if (resize_num == nullptr || is_resize == nullptr) { + MS_LOG(ERROR) << "the function input parameter is nullptr."; + return kLiteError; + } + if (input_shape_lite.size() != input_shape_dpico.size()) { + MS_LOG(ERROR) << "both input shape from lite and dpico cannot match."; + return kLiteError; + } + for (size_t i = 0; i < input_shape_dpico.size(); i++) { + if (input_shape_dpico[i] != input_shape_lite[i]) { + if (i == 0) { + *is_resize = true; + *resize_num = input_shape_lite[i]; + } else { + MS_LOG(ERROR) << "Custom of DPICO only support batch_num resize."; + return kLiteError; + } + } + } + return kSuccess; +} + +Status SetOutputFormat(const std::map &attrs, std::vector *outputs) { + if (outputs == nullptr) { + MS_LOG(ERROR) << "the function input parameter is nullptr."; + return kLiteError; + } + if (attrs.find(kOutputsFormat) == attrs.end()) { + MS_LOG(ERROR) << "custom node should have " << kOutputsFormat << " attr."; + return kLiteError; + } + auto output_format_str = attrs.at(kOutputsFormat); + auto output_format = SplitString(output_format_str, ','); + if (output_format.size() > outputs->size()) { + MS_LOG(ERROR) << "output format attr is invalid, the number of which is out of range."; + return kLiteError; + } + for (size_t i = 0; i < output_format.size(); ++i) { + if (!lite::IsValidUnsignedNum(output_format[i])) { + MS_LOG(ERROR) << "output format must be an unsigned int."; + return kLiteError; + } + auto format = std::stoi(output_format[i]); + if (format != NHWC && format != NCHW) { + MS_LOG(ERROR) << "output format is invalid, which should be NHWC or NCHW."; + return kLiteError; + } + outputs->at(i).SetFormat(static_cast(format)); + } + return kSuccess; +} +} // namespace + +std::shared_ptr CustomInferCreater() { + auto infer = new (std::nothrow) CustomInterface(); + if (infer == nullptr) { + MS_LOG(ERROR) << "new custom infer is nullptr"; + return nullptr; + } + return std::shared_ptr(infer); +} + +Status CustomInterface::InferShapeJudge(std::vector *inputs, + const std::vector> &inputs_shape) const { + size_t inputs_size_without_om_model = inputs->size() - 1; + if (inputs_shape.size() != inputs_size_without_om_model) { + MS_LOG(ERROR) << "inputs num diff inputs_shape num."; + return kLiteError; + } + if (inputs_shape[0].size() != (*inputs)[0].Shape().size()) { + MS_LOG(ERROR) << "shape size err. " << inputs_shape[0].size() << ", " << (*inputs)[0].Shape().size(); + return kLiteError; + } + return kSuccess; +} + +Status CustomInterface::InferRecurrentTwoOutputProcess(const mindspore::schema::Primitive *primitive, + const kernel::Kernel *kernel, + std::vector> *outputs_shape) const { + if (primitive == nullptr || outputs_shape == nullptr) { + return kLiteError; + } + lite::OmNetType net_type{lite::OmNetType_CNN}; + if (kernel != nullptr) { + auto net_type_str = kernel->GetAttr(lite::kNetType); + if (!net_type_str.empty()) { + if (!lite::IsValidUnsignedNum(net_type_str)) { + MS_LOG(ERROR) << "net_type must be an unsigned int."; + return kLiteError; + } + auto net_type_int = std::stoi(net_type_str); + if (net_type_int < lite::OmNetType_CNN || net_type_int > lite::OmNetType_RECURRENT) { + MS_LOG(ERROR) << "net_type attr is invalid, value is " << net_type_int; + return kLiteError; + } + net_type = static_cast(net_type_int); + } + } else { + auto ret = JudgeOmNetType(*primitive, &net_type); + if (ret != lite::SUCCESS) { + MS_LOG(ERROR) << "get model attr failed"; + return kLiteError; + } + } + if (net_type == lite::OmNetType_RECURRENT && outputs_shape->size() > 1) { + if ((*outputs_shape)[1].empty()) { + return kLiteError; + } + (*outputs_shape)[1][0] = 1; + } + return kSuccess; +} + +Status CustomInterface::Infer(std::vector *inputs, std::vector *outputs, + const mindspore::schema::Primitive *primitive, const kernel::Kernel *kernel) { + if (inputs->size() < lite::kMinInputSize) { + MS_LOG(ERROR) << "Inputs size is less than 2"; + return kLiteError; + } + if (outputs->empty()) { + MS_LOG(ERROR) << "Outputs size 0"; + return kLiteError; + } + std::map attrs; + schema::PrimitiveType type; + if (kernel != nullptr) { + attrs.emplace(kInputShape, kernel->GetAttr(kInputShape)); + attrs.emplace(kOutputShape, kernel->GetAttr(kOutputShape)); + attrs.emplace(kOutputsFormat, kernel->GetAttr(kOutputsFormat)); + type = kernel->type(); + } else { + if (primitive == nullptr) { + MS_LOG(ERROR) << "primitive is nullptr."; + return kLiteError; + } + lite::ExtractAttrsFromPrimitive(primitive, &attrs); + type = primitive->value_type(); + } + if (type != mindspore::schema::PrimitiveType_Custom) { + MS_LOG(ERROR) << "Primitive type is not PrimitiveType_Custom"; + return kLiteError; + } + for (size_t i = 0; i < outputs->size(); i++) { + (*outputs)[i].SetDataType(DataType::kNumberTypeFloat32); + (*outputs)[i].SetFormat(Format::NCHW); + } + if (SetOutputFormat(attrs, outputs) != kSuccess) { + MS_LOG(ERROR) << "set output format failed."; + return kLiteError; + } + if (!lite::InferDone(*inputs)) { + return kLiteInferInvalid; + } + std::vector> inputs_shape; + if (GetCustomShape(attrs, "inputs_shape", &inputs_shape) != kSuccess) { + MS_LOG(ERROR) << "parser inputs_shape attribute err."; + return kLiteError; + } + std::vector> outputs_shape; + if (GetCustomShape(attrs, "outputs_shape", &outputs_shape) != kSuccess) { + MS_LOG(ERROR) << "parser outputs_shape attribute err."; + return kLiteError; + } + if (InferShapeJudge(inputs, inputs_shape) != kSuccess) { + MS_LOG(ERROR) << "input shape err."; + return kLiteError; + } + bool resize_flag = false; + int resize_num = 1; + if (DetermineBatchSize((*inputs)[0].Shape(), inputs_shape[0], &resize_num, &resize_flag) != kSuccess) { + MS_LOG(ERROR) << "determine batch size failed."; + return kLiteError; + } + if (resize_flag) { + for (auto &output_shape : outputs_shape) { + output_shape[0] = resize_num; + } + } + if (InferRecurrentTwoOutputProcess(primitive, kernel, &outputs_shape) != kSuccess) { + MS_LOG(ERROR) << "Infer Recurrent Two Output Process err."; + return kLiteError; + } + + for (size_t i = 0; i < outputs->size(); i++) { + (*outputs)[i].SetShape(outputs_shape[i]); + } + return kSuccess; +} +} // namespace dpico +} // namespace mindspore +namespace mindspore { +namespace kernel { +REGISTER_CUSTOM_KERNEL_INTERFACE(DPICO, DPICO, dpico::CustomInferCreater); +} // namespace kernel +} // namespace mindspore diff --git a/mindspore/lite/tools/benchmark/dpico/src/custom_infer.h b/mindspore/lite/tools/benchmark/dpico/src/custom_infer.h new file mode 100644 index 0000000000..e7056ca2dc --- /dev/null +++ b/mindspore/lite/tools/benchmark/dpico/src/custom_infer.h @@ -0,0 +1,42 @@ +/** + * 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_NNACL_CUSTOM_PARAMETER_H_ +#define MINDSPORE_LITE_NNACL_CUSTOM_PARAMETER_H_ +#include +#include +#include +#include "include/kernel_interface.h" + +namespace mindspore { +namespace dpico { +class CustomInterface : public mindspore::kernel::KernelInterface { + public: + CustomInterface() {} + + ~CustomInterface() = default; + + Status Infer(std::vector *inputs, std::vector *outputs, + const mindspore::schema::Primitive *primitive, const kernel::Kernel *kernel) override; + + private: + Status InferShapeJudge(std::vector *inputs, + const std::vector> &inputs_shape) const; + Status InferRecurrentTwoOutputProcess(const mindspore::schema::Primitive *primitive, const kernel::Kernel *kernel, + std::vector> *outputs_shape) const; +}; +} // namespace dpico +} // namespace mindspore +#endif // MINDSPORE_LITE_NNACL_CUSTOM_PARAMETER_H_ diff --git a/mindspore/lite/tools/benchmark/dpico/src/custom_log.cc b/mindspore/lite/tools/benchmark/dpico/src/custom_log.cc new file mode 100644 index 0000000000..31a52eb76f --- /dev/null +++ b/mindspore/lite/tools/benchmark/dpico/src/custom_log.cc @@ -0,0 +1,74 @@ +/** + * 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 "src/custom_log.h" +#include +#include +namespace mindspore { +int StrToInt(const char *env) { + if (env == nullptr) { + return static_cast(mindspore::DpicoLogLevel::WARNING); + } + if (strcmp(env, "0") == 0) { + return static_cast(mindspore::DpicoLogLevel::DEBUG); + } + if (strcmp(env, "1") == 0) { + return static_cast(mindspore::DpicoLogLevel::INFO); + } + if (strcmp(env, "2") == 0) { + return static_cast(mindspore::DpicoLogLevel::WARNING); + } + if (strcmp(env, "3") == 0) { + return static_cast(mindspore::DpicoLogLevel::ERROR); + } + return static_cast(mindspore::DpicoLogLevel::WARNING); +} + +bool IsPrint(int level) { + static const char *const env = std::getenv("GLOG_v"); + static const int ms_level = StrToInt(env); + if (level < 0) { + level = static_cast(mindspore::DpicoLogLevel::WARNING); + } + return level >= ms_level; +} + +const char *EnumStrForMsLogLevel(DpicoLogLevel level) { + if (level == DpicoLogLevel::DEBUG) { + return "DEBUG"; + } else if (level == DpicoLogLevel::INFO) { + return "INFO"; + } else if (level == DpicoLogLevel::WARNING) { + return "WARNING"; + } else if (level == DpicoLogLevel::ERROR) { + return "ERROR"; + } else { + return "NO_LEVEL"; + } +} + +void DpicoLogWriter::OutputLog(const std::ostringstream &msg) const { + if (IsPrint(static_cast(log_level_))) { + printf("%s [%s:%d] %s] %s\n", EnumStrForMsLogLevel(log_level_), location_.file_, location_.line_, location_.func_, + msg.str().c_str()); + } +} + +void DpicoLogWriter::operator<(const DpicoLogStream &stream) const noexcept { + std::ostringstream msg; + msg << stream.sstream_->rdbuf(); + OutputLog(msg); +} +} // namespace mindspore diff --git a/mindspore/lite/tools/benchmark/dpico/src/custom_log.h b/mindspore/lite/tools/benchmark/dpico/src/custom_log.h new file mode 100644 index 0000000000..ab08f860da --- /dev/null +++ b/mindspore/lite/tools/benchmark/dpico/src/custom_log.h @@ -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. + */ +#ifndef MINDSPORE_LITE_TOOLS_BENCHMARK_DPICO_SRC_CUSTOM_LOG_H_ +#define MINDSPORE_LITE_TOOLS_BENCHMARK_DPICO_SRC_CUSTOM_LOG_H_ + +#include +#include + +// NOTICE: when relative path of 'log.h' changed, macro 'DPICO_LOG_HEAR_FILE_REL_PATH' must be changed +#define DPICO_LOG_HEAR_FILE_REL_PATH "mindspore/lite/tools/benchmark/dpico/src/custom_log.h" + +// Get start index of file relative path in __FILE__ +static constexpr size_t GetRealPathPos() noexcept { + return sizeof(__FILE__) > sizeof(DPICO_LOG_HEAR_FILE_REL_PATH) + ? sizeof(__FILE__) - sizeof(DPICO_LOG_HEAR_FILE_REL_PATH) + : 0; +} + +namespace mindspore { +#define DPICO_FILE_NAME \ + (sizeof(__FILE__) > GetRealPathPos() ? static_cast(__FILE__) + GetRealPathPos() \ + : static_cast(__FILE__)) + +struct DpicoLocationInfo { + DpicoLocationInfo(const char *file, int line, const char *func) : file_(file), line_(line), func_(func) {} + + ~DpicoLocationInfo() = default; + + const char *file_; + int line_; + const char *func_; +}; + +class DpicoLogStream { + public: + DpicoLogStream() { sstream_ = std::make_shared(); } + + ~DpicoLogStream() = default; + + template + DpicoLogStream &operator<<(const T &val) noexcept { + (*sstream_) << val; + return *this; + } + + DpicoLogStream &operator<<(std::ostream &func(std::ostream &os)) noexcept { + (*sstream_) << func; + return *this; + } + friend class DpicoLogWriter; + + private: + std::shared_ptr sstream_; +}; + +enum class DpicoLogLevel : int { DEBUG = 0, INFO, WARNING, ERROR }; + +class DpicoLogWriter { + public: + DpicoLogWriter(const DpicoLocationInfo &location, mindspore::DpicoLogLevel log_level) + : location_(location), log_level_(log_level) {} + + ~DpicoLogWriter() = default; + + __attribute__((visibility("default"))) void operator<(const DpicoLogStream &stream) const noexcept; + + private: + void OutputLog(const std::ostringstream &msg) const; + + DpicoLocationInfo location_; + DpicoLogLevel log_level_; +}; + +#define MSLOG_IF(level) \ + mindspore::DpicoLogWriter(mindspore::DpicoLocationInfo(DPICO_FILE_NAME, __LINE__, __FUNCTION__), level) < \ + mindspore::DpicoLogStream() + +#define MS_LOG(level) MS_LOG_##level + +#define MS_LOG_DEBUG MSLOG_IF(mindspore::DpicoLogLevel::DEBUG) +#define MS_LOG_INFO MSLOG_IF(mindspore::DpicoLogLevel::INFO) +#define MS_LOG_WARNING MSLOG_IF(mindspore::DpicoLogLevel::WARNING) +#define MS_LOG_ERROR MSLOG_IF(mindspore::DpicoLogLevel::ERROR) +} // namespace mindspore + +#endif // MINDSPORE_LITE_TOOLS_BENCHMARK_DPICO_SRC_CUSTOM_LOG_H_ diff --git a/mindspore/lite/tools/providers/dpico/sd3403/compile_3403.sh b/mindspore/lite/tools/providers/dpico/sd3403/compile_3403.sh new file mode 100644 index 0000000000..5c69722d34 --- /dev/null +++ b/mindspore/lite/tools/providers/dpico/sd3403/compile_3403.sh @@ -0,0 +1,81 @@ +#!/bin/bash +# 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. +# ============================================================================ + +prepare_third_party() { + dpico_third_party=${mindspore_lite_top_dir}/tools/benchmark/dpico/third_party + rm -rf ${dpico_third_party} || exit 1 + mkdir -p ${dpico_third_party} || exit 1 + cd ${mindspore_top_dir}/output || exit 1 + file_name=$(ls *tar.gz) + tar_name=${file_name%%.tar.gz} + tar xzvf ${tar_name}.tar.gz || exit 1 + cd .. + cp -rf ${mindspore_top_dir}/output/${tar_name}/runtime/ ${dpico_third_party} || exit 1 +} + +# Build arm64 for dpico +make_dpico_benchmark_package() { + cd ${mindspore_top_dir}/output || exit 1 + file_name=$(ls *tar.gz) + tar_name=${file_name%%.tar.gz} + dpico_sd3403_release_path=${mindspore_top_dir}/output/${tar_name}/providers/SD3403/ + mkdir -p ${dpico_sd3403_release_path} + dpico_benchmark_path=${mindspore_top_dir}/mindspore/lite/build/tools/benchmark + cp ${dpico_benchmark_path}/dpico/libdpico_acl_adapter.so ${dpico_sd3403_release_path} || exit 1 + echo "install dpico adapter so success." + rm ${tar_name}.tar.gz || exit 1 + tar -zcf ${tar_name}.tar.gz ${tar_name} || exit 1 + rm -rf ${tar_name} || exit 1 + sha256sum ${tar_name}.tar.gz > ${tar_name}.tar.gz.sha256 || exit 1 + echo "generate dpico package success!" + cd ${basepath} + rm -rf ${dpico_third_party} || exit 1 +} + +basepath=$(pwd) +echo "basepath is ${basepath}" +#set -e +mindspore_top_dir=${basepath} +mindspore_lite_top_dir=${mindspore_top_dir}/mindspore/lite + +while getopts "t:" opt; do + case ${opt} in + t) + task=${OPTARG} + echo "compile task is ${OPTARG}" + ;; + ?) + echo "unknown para" + exit 1;; + esac +done + +if [[ ${task} == "prepare_third_party" ]]; then + prepare_third_party + if [ $? -eq 1 ]; then + echo "prepare third party failed" + return 1 + fi +else + echo "start make package for dpico..." + make_dpico_benchmark_package & + make_dpico_benchmark_package_pid=$! + sleep 1 + + wait ${make_dpico_benchmark_package_pid} + make_dpico_benchmark_package_status=$? + exit ${make_dpico_benchmark_package_status} +fi