221 lines
8.6 KiB
Bash
Executable File
221 lines
8.6 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
usage() {
|
|
echo "Usage: $0 [--sync-adb] [--pc] [--android] [--ios] [--mnn] [--torch] [--tf]"
|
|
echo -e "\t--sync-adb sync test models and benchmark tool"
|
|
echo -e "\t--pc test for pc"
|
|
echo -e "\t--android test for android"
|
|
echo -e "\t--ios test for ios"
|
|
echo -e "\t--mnn test"
|
|
echo -e "\t--torch test"
|
|
echo -e "\t--tf test"
|
|
exit 1
|
|
}
|
|
|
|
sync_adb=false
|
|
test_for_pc=false
|
|
test_for_android=false
|
|
test_for_ios=false
|
|
test_mnn=false
|
|
test_torch=false
|
|
test_tf=false
|
|
while getopts ":h-:" opt; do
|
|
case "$opt" in
|
|
-)
|
|
case "$OPTARG" in
|
|
sync-adb) sync_adb=true ;;
|
|
pc) test_for_pc=true ;;
|
|
android) test_for_android=true ;;
|
|
ios) test_for_ios=true ;;
|
|
mnn) test_mnn=true ;;
|
|
torch) test_torch=true ;;
|
|
tf) test_tf=true ;;
|
|
*) usage ;;
|
|
esac ;;
|
|
h|? ) usage ;;
|
|
esac
|
|
done
|
|
|
|
if ! command -v jq &> /dev/null; then
|
|
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
brew install jq
|
|
elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
|
apt install -y jq
|
|
fi
|
|
fi
|
|
|
|
rm -rf result && mkdir result
|
|
|
|
MNN_HOME=/data/local/tmp/MNN
|
|
TORCH_HOME=/data/local/tmp/torch
|
|
TFLITE_HOME=/data/local/tmp/tflite
|
|
if $test_for_android; then
|
|
if ! command -v adb &> /dev/null; then
|
|
echo 'adb not found'
|
|
exit 1
|
|
fi
|
|
if $sync_adb; then
|
|
adb push dist/android/* /data/local/tmp
|
|
adb shell "mkdir -p $MNN_HOME/models"
|
|
adb push models/mnn/*.mnn $MNN_HOME/models
|
|
adb shell "mkdir -p $TORCH_HOME/models"
|
|
adb push models/torch_lite/*.ptl $TORCH_HOME/models
|
|
adb shell "mkdir -p $TFLITE_HOME/models/fp16"
|
|
adb push models/tflite/*.tflite $TFLITE_HOME/models
|
|
adb push models/tflite/fp16/*.tflite $TFLITE_HOME/models/fp16
|
|
fi
|
|
fi
|
|
if $test_for_ios; then
|
|
gem install bundler xcodeproj
|
|
fi
|
|
|
|
bench_common() {
|
|
echo "$1 begin"
|
|
for i in $(seq $(cat "models/config.json" | jq "length")); do
|
|
model_meta=$(cat "models/config.json" | jq ".[$i-1]")
|
|
model_name=$(echo $model_meta | jq -r ".model")
|
|
local input_layers=() input_shapes=() input_dtypes=() bench_args
|
|
for j in $(seq $(echo $model_meta | jq ".input_layers|length")); do
|
|
input_layers+=($(echo $model_meta | jq -r ".input_layers[$j-1]"))
|
|
input_shapes+=($(echo $model_meta | jq -r ".input_shapes[$j-1]"))
|
|
input_dtypes+=($(echo $model_meta | jq -r ".input_dtypes[$j-1]"))
|
|
done
|
|
$1 "$model_name" "$bench_args"
|
|
done
|
|
echo "$1 end"
|
|
}
|
|
|
|
# mnn android
|
|
if $test_mnn; then
|
|
mnn_android_arm32_bench() {
|
|
adb shell "export LD_LIBRARY_PATH=$MNN_HOME/arm32 && $MNN_HOME/arm32/benchmark.out $MNN_HOME/models 10 5 0 1 2>&1" >> result/mnn_android_arm32.txt
|
|
}
|
|
mnn_android_arm64_bench() {
|
|
adb shell "export LD_LIBRARY_PATH=$MNN_HOME/arm64 && $MNN_HOME/arm64/benchmark.out $MNN_HOME/models 10 5 0 1 2>&1" >> result/mnn_android_arm64.txt
|
|
}
|
|
mnn_android_armv82_bench() {
|
|
adb shell "export LD_LIBRARY_PATH=$MNN_HOME/arm64 && $MNN_HOME/arm64/benchmark.out $MNN_HOME/models 10 5 0 1 2 2>&1" >> result/mnn_android_fp16.txt
|
|
}
|
|
mnn_android_opencl_bench() {
|
|
adb shell "export LD_LIBRARY_PATH=$MNN_HOME/arm64 && $MNN_HOME/arm64/benchmark.out $MNN_HOME/models 10 5 3 1 2>&1" >> result/mnn_android_opencl.txt
|
|
}
|
|
if $test_for_pc; then
|
|
./MNN/build/benchmark.out models/mnn 10 5 0 1 2>&1 >> result/mnn_pc_cpu.txt # CPU
|
|
#./MNN/build/benchmark.out models/mnn 10 5 2 2&>1 >> result/mnn_pc_cuda.txt # CUDA
|
|
#python bench_pc.py -f mnn --modeldir models --thread-num 1 --backend cpu
|
|
#python bench_pc.py -f mnn --modeldir models --thread-num 1 --backend cuda
|
|
fi
|
|
if $test_for_android; then
|
|
mnn_android_arm32_bench
|
|
mnn_android_arm64_bench
|
|
mnn_android_armv82_bench
|
|
mnn_android_opencl_bench
|
|
fi
|
|
fi
|
|
|
|
# pytorch mobile android
|
|
if $test_torch; then
|
|
torch_compatible() {
|
|
input_shapes_str=$(IFS=";" ; echo "${input_shapes[*]}")
|
|
input_dtypes_str=$(IFS=";" ; echo "${input_dtypes[*]}")
|
|
input_dtypes_str=$(python -c "print('$input_dtypes_str'.replace('int', 'int64'))")
|
|
input_memory_format_str=$(python -c "print(';'.join(['contiguous_format'] * ${#input_shapes[@]}))")
|
|
bench_args="--input_dims='$input_shapes_str' --input_type='$input_dtypes_str' --input_memory_format='$input_memory_format_str'"
|
|
}
|
|
torch_android_arm32() {
|
|
torch_compatible
|
|
adb shell "$TORCH_HOME/arm32/speed_benchmark_torch --model=$TORCH_HOME/models/$1.ptl $bench_args 2>&1" >> result/torch_android_arm32.txt
|
|
}
|
|
torch_android_arm64() {
|
|
torch_compatible
|
|
adb shell "$TORCH_HOME/arm64/speed_benchmark_torch --model=$TORCH_HOME/models/$1.ptl $bench_args 2>&1" >> result/torch_android_arm64.txt
|
|
}
|
|
if $test_for_pc; then
|
|
python -m pip uninstall -y torch # May be custom torch wheel (build for metal optimize), uninstall it
|
|
python -m pip install torch==1.11.0
|
|
python bench_pc.py -f torch --modeldir models --thread-num 1 --backend cpu
|
|
python bench_pc.py -f torch --modeldir models --thread-num 1 --backend cuda
|
|
fi
|
|
# torch android arm32
|
|
if $test_for_android; then
|
|
bench_common torch_android_arm32
|
|
bench_common torch_android_arm64
|
|
fi
|
|
|
|
# iOS app generated by ios/TestApp/benchmark/setup.rb be failed even a empty test case, say: Unknown custom class type quantized.Conv2dPackedParamsBase
|
|
#if $test_for_ios; then
|
|
# pushd pytorch
|
|
# rm -rf build_ios && cp -r build_ios_arm64 build_ios # ios/TestApp/benchmark/setup.rb hardcode build_ios
|
|
# cp -r ../models/torch_lite ios/TestApp/models
|
|
# pushd ios/TestApp/benchmark && ruby setup.rb -lite && popd
|
|
# popd
|
|
#fi
|
|
fi
|
|
|
|
# tflite android
|
|
if $test_tf; then
|
|
tflite_compatible() {
|
|
local i j input_num=${#input_layers[@]}
|
|
local origin_input_layers=("${input_layers[@]}") origin_input_shapes=("${input_shapes[@]}")
|
|
local model_meta=$(cat models/tflite/config.json | jq "map(select(.model == \"$model_name\"))|.[0]")
|
|
input_shapes=()
|
|
input_layers=()
|
|
for i in $(seq $input_num); do
|
|
for j in $(seq $input_num); do
|
|
if [[ $(echo $model_meta | jq -r ".inputs[$i-1]") == ${origin_input_layers[$j-1]} ]]; then
|
|
input_shapes+=(${origin_input_shapes[$j-1]})
|
|
break
|
|
fi
|
|
done
|
|
input_layers+=($(echo $model_meta | jq -r ".inner_inputs[$i-1]"))
|
|
done
|
|
input_layers_str=$(IFS="," ; echo "${input_layers[*]}")
|
|
input_shapes_str=$(IFS=":" ; echo "${input_shapes[*]}")
|
|
bench_args="--input_layer='$input_layers_str' --input_layer_shape='$input_shapes_str' --warmup_runs=1 --num_runs=20"
|
|
}
|
|
tflite_android_arm32() {
|
|
tflite_compatible
|
|
adb shell "$TFLITE_HOME/arm32/benchmark_model_plus_flex --graph=$TFLITE_HOME/models/$1.tflite $bench_args --num_threads=1 2>&1" >> result/tflite_android_arm32.txt
|
|
}
|
|
tflite_android_arm64() {
|
|
tflite_compatible
|
|
adb shell "$TFLITE_HOME/arm64/benchmark_model_plus_flex --graph=$TFLITE_HOME/models/$1.tflite $bench_args --num_threads=1 2>&1" >> result/tflite_android_arm64.txt
|
|
}
|
|
tflite_android_fp16() {
|
|
tflite_compatible
|
|
adb shell "$TFLITE_HOME/arm64/benchmark_model_plus_flex --graph=$TFLITE_HOME/models/fp16/$1.tflite $bench_args --num_threads=1 2>&1" >> result/tflite_android_fp16.txt
|
|
}
|
|
tflite_android_gpu() {
|
|
tflite_compatible
|
|
adb shell "$TFLITE_HOME/arm64/benchmark_model_plus_flex --use_gpu=true --graph=$TFLITE_HOME/models/$1.tflite $bench_args --num_threads=1 2>&1" >> result/tflite_android_gpu.txt
|
|
}
|
|
if $test_for_pc; then
|
|
python -m pip install tensorflow==2.7.0
|
|
python bench_pc.py -f tf --modeldir models --thread-num 1 --backend cpu
|
|
python bench_pc.py -f tf --modeldir models --thread-num 1 --backend cuda
|
|
fi
|
|
if $test_for_android; then
|
|
bench_common tflite_android_arm32
|
|
bench_common tflite_android_arm64
|
|
bench_common tflite_android_fp16
|
|
bench_common tflite_android_gpu
|
|
fi
|
|
if $test_for_ios; then
|
|
tflite_gen_params() {
|
|
tflite_compatible
|
|
echo \
|
|
"""{
|
|
\"benchmark_name\": \"${model_name}_benchmark\",
|
|
\"num_threads\" : \"1\",
|
|
\"num_runs\" : \"20\",
|
|
\"warmup_runs\" : \"1\",
|
|
\"graph\" : \"${model_name}.tflite\",
|
|
\"input_layer\" : \"${input_layers}\",
|
|
\"input_layer_shape\" : \"${input_shapes}\",
|
|
\"run_delay\" : \"-1\"
|
|
}""" > models/tflite/${model_name}_benchmark_params.json
|
|
}
|
|
bench_common tflite_gen_params
|
|
fi
|
|
fi
|