chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 12:40:42 +08:00
commit e25996e7db
15472 changed files with 3536181 additions and 0 deletions
+353
View File
@@ -0,0 +1,353 @@
cmake_minimum_required(VERSION 3.5)
project(cpp_inference_demo CXX C)
option(WITH_MKL "Compile demo with MKL/OpenBlas support, default use MKL." ON)
option(WITH_GPU "Compile demo with GPU/CPU, default use CPU." OFF)
option(WITH_STATIC_LIB
"Compile demo with static/shared library, default use static." OFF)
option(USE_TENSORRT "Compile demo with TensorRT." OFF)
option(WITH_GTEST "Compile demo with GTEST" OFF)
option(WITH_ONNXRUNTIME "Compile demo with ONNXRuntime" OFF)
if(NOT WITH_STATIC_LIB)
add_definitions("-DPADDLE_WITH_SHARED_LIB")
else()
# PD_INFER_DECL is mainly used to set the dllimport/dllexport attribute in dynamic library mode.
# Set it to empty in static library mode to avoid compilation issues.
add_definitions("/DPD_INFER_DECL=")
endif()
macro(safe_set_static_flag)
foreach(flag_var
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
if(${flag_var} MATCHES "/MD")
string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
endif()
endforeach()
endmacro()
if(NOT DEFINED PADDLE_LIB)
message(
FATAL_ERROR "please set PADDLE_LIB with -DPADDLE_LIB=/path/paddle/lib")
endif()
if(NOT DEFINED DEMO_NAME)
message(FATAL_ERROR "please set DEMO_NAME with -DDEMO_NAME=demo_name")
endif()
include_directories("${PADDLE_LIB}/")
set(PADDLE_LIB_THIRD_PARTY_PATH "${PADDLE_LIB}/third_party/install/")
include_directories("${PADDLE_LIB_THIRD_PARTY_PATH}protobuf/include")
include_directories("${PADDLE_LIB_THIRD_PARTY_PATH}glog/include")
include_directories("${PADDLE_LIB_THIRD_PARTY_PATH}gflags/include")
include_directories("${PADDLE_LIB_THIRD_PARTY_PATH}xxhash/include")
include_directories("${PADDLE_LIB_THIRD_PARTY_PATH}cryptopp/include")
link_directories("${PADDLE_LIB_THIRD_PARTY_PATH}protobuf/lib")
link_directories("${PADDLE_LIB_THIRD_PARTY_PATH}glog/lib")
link_directories("${PADDLE_LIB_THIRD_PARTY_PATH}gflags/lib")
link_directories("${PADDLE_LIB_THIRD_PARTY_PATH}xxhash/lib")
link_directories("${PADDLE_LIB_THIRD_PARTY_PATH}cryptopp/lib")
link_directories("${PADDLE_LIB}/paddle/lib")
if(WITH_ONNXRUNTIME)
include_directories("${PADDLE_LIB_THIRD_PARTY_PATH}onnxruntime/include")
include_directories("${PADDLE_LIB_THIRD_PARTY_PATH}paddle2onnx/include")
link_directories("${PADDLE_LIB_THIRD_PARTY_PATH}onnxruntime/lib")
link_directories("${PADDLE_LIB_THIRD_PARTY_PATH}paddle2onnx/lib")
endif()
if(WIN32)
add_definitions("/DGOOGLE_GLOG_DLL_DECL=")
option(MSVC_STATIC_CRT "use static C Runtime library by default" ON)
if(MSVC_STATIC_CRT)
if(WITH_MKL)
set(FLAG_OPENMP "/openmp")
endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4244 /wd4530")
set(CMAKE_C_FLAGS_DEBUG
"${CMAKE_C_FLAGS_DEBUG} /bigobj /MTd ${FLAG_OPENMP}")
set(CMAKE_C_FLAGS_RELEASE
"${CMAKE_C_FLAGS_RELEASE} /bigobj /MT ${FLAG_OPENMP}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4244 /wd4530")
set(CMAKE_CXX_FLAGS_DEBUG
"${CMAKE_CXX_FLAGS_DEBUG} /bigobj /MTd ${FLAG_OPENMP}")
set(CMAKE_CXX_FLAGS_RELEASE
"${CMAKE_CXX_FLAGS_RELEASE} /bigobj /MT ${FLAG_OPENMP}")
safe_set_static_flag()
if(WITH_STATIC_LIB)
add_definitions(-DSTATIC_LIB)
endif()
endif()
else()
if(WITH_MKL)
set(FLAG_OPENMP "-fopenmp")
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 ${FLAG_OPENMP}")
endif()
if(WITH_GPU)
if(NOT WIN32)
add_definitions("-DPADDLE_WITH_GPU")
set(CUDA_LIB
"/usr/local/cuda/lib64/"
CACHE STRING "CUDA Library")
include_directories("${CUDA_LIB}/../include")
else()
set(CUDA_LIB
""
CACHE STRING "CUDA_LIB")
if("${CUDA_LIB}" STREQUAL "")
set(CUDA_LIB "$ENV{CUDA_PATH}\\lib\\x64")
endif()
message(STATUS "Current CUDA lib path: ${CUDA_LIB}")
endif()
endif()
if(USE_TENSORRT AND WITH_GPU)
set(TENSORRT_ROOT
""
CACHE STRING "The root directory of TensorRT library")
if("${TENSORRT_ROOT}" STREQUAL "")
message(
FATAL_ERROR
"The TENSORRT_ROOT is empty, you must assign it a value with CMake command. Such as: -DTENSORRT_ROOT=TENSORRT_ROOT_PATH "
)
endif()
set(TENSORRT_INCLUDE_DIR ${TENSORRT_ROOT}/include)
set(TENSORRT_LIB_DIR ${TENSORRT_ROOT}/lib)
file(READ ${TENSORRT_INCLUDE_DIR}/NvInfer.h TENSORRT_VERSION_FILE_CONTENTS)
string(REGEX MATCH "define NV_TENSORRT_MAJOR +([0-9]+)"
TENSORRT_MAJOR_VERSION "${TENSORRT_VERSION_FILE_CONTENTS}")
string(REGEX MATCH "define NV_TENSORRT_MINOR +([0-9]+)"
TENSORRT_MINOR_VERSION "${TENSORRT_VERSION_FILE_CONTENTS}")
string(REGEX MATCH "define NV_TENSORRT_PATCH +([0-9]+)"
TENSORRT_PATCH_VERSION "${TENSORRT_VERSION_FILE_CONTENTS}")
string(REGEX MATCH "define NV_TENSORRT_BUILD +([0-9]+)"
TENSORRT_BUILD_VERSION "${TENSORRT_VERSION_FILE_CONTENTS}")
if("${TENSORRT_MAJOR_VERSION}" STREQUAL "")
file(READ ${TENSORRT_INCLUDE_DIR}/NvInferVersion.h
TENSORRT_VERSION_FILE_CONTENTS)
string(REGEX MATCH "define NV_TENSORRT_MAJOR +([0-9]+)"
TENSORRT_MAJOR_VERSION "${TENSORRT_VERSION_FILE_CONTENTS}")
string(REGEX MATCH "define NV_TENSORRT_MINOR +([0-9]+)"
TENSORRT_MINOR_VERSION "${TENSORRT_VERSION_FILE_CONTENTS}")
string(REGEX MATCH "define NV_TENSORRT_PATCH +([0-9]+)"
TENSORRT_PATCH_VERSION "${TENSORRT_VERSION_FILE_CONTENTS}")
string(REGEX MATCH "define NV_TENSORRT_BUILD +([0-9]+)"
TENSORRT_BUILD_VERSION "${TENSORRT_VERSION_FILE_CONTENTS}")
endif()
if("${TENSORRT_MAJOR_VERSION}" STREQUAL "")
message(SEND_ERROR "Failed to detect TensorRT version.")
endif()
string(REGEX REPLACE "define NV_TENSORRT_MAJOR +([0-9]+)" "\\1"
TENSORRT_MAJOR_VERSION "${TENSORRT_MAJOR_VERSION}")
string(REGEX REPLACE "define NV_TENSORRT_MINOR +([0-9]+)" "\\1"
TENSORRT_MINOR_VERSION "${TENSORRT_MINOR_VERSION}")
string(REGEX REPLACE "define NV_TENSORRT_PATCH +([0-9]+)" "\\1"
TENSORRT_PATCH_VERSION "${TENSORRT_PATCH_VERSION}")
string(REGEX REPLACE "define NV_TENSORRT_BUILD +([0-9]+)" "\\1"
TENSORRT_BUILD_VERSION "${TENSORRT_BUILD_VERSION}")
message(
STATUS
"Current TensorRT header is ${TENSORRT_INCLUDE_DIR}/NvInfer.h. "
"Current TensorRT version is v${TENSORRT_MAJOR_VERSION}.${TENSORRT_MINOR_VERSION}.${TENSORRT_PATCH_VERSION}.${TENSORRT_BUILD_VERSION} "
)
include_directories("${TENSORRT_INCLUDE_DIR}")
link_directories("${TENSORRT_LIB_DIR}")
add_compile_definitions(NV_TENSORRT_MAJOR=${TENSORRT_MAJOR_VERSION})
add_compile_definitions(NV_TENSORRT_MINOR=${TENSORRT_MINOR_VERSION})
add_compile_definitions(NV_TENSORRT_PATCH=${TENSORRT_PATCH_VERSION})
add_compile_definitions(NV_TENSORRT_BUILD=${TENSORRT_BUILD_VERSION})
endif()
if(WITH_MKL)
set(MATH_LIB_PATH "${PADDLE_LIB_THIRD_PARTY_PATH}mklml")
include_directories("${MATH_LIB_PATH}/include")
if(WIN32)
set(MATH_LIB ${MATH_LIB_PATH}/lib/mklml${CMAKE_STATIC_LIBRARY_SUFFIX}
${MATH_LIB_PATH}/lib/libiomp5md${CMAKE_STATIC_LIBRARY_SUFFIX})
else()
set(MATH_LIB
${MATH_LIB_PATH}/lib/libmklml_intel${CMAKE_SHARED_LIBRARY_SUFFIX}
${MATH_LIB_PATH}/lib/libiomp5${CMAKE_SHARED_LIBRARY_SUFFIX})
endif()
set(ONEDNN_PATH "${PADDLE_LIB_THIRD_PARTY_PATH}onednn")
if(EXISTS ${ONEDNN_PATH})
include_directories("${ONEDNN_PATH}/include")
if(WIN32)
set(ONEDNN_LIB ${ONEDNN_PATH}/lib/mkldnn.lib)
else()
set(ONEDNN_LIB ${ONEDNN_PATH}/lib/libdnnl.so.3)
endif()
endif()
else()
set(OPENBLAS_LIB_PATH "${PADDLE_LIB_THIRD_PARTY_PATH}openblas")
include_directories("${OPENBLAS_LIB_PATH}/include/openblas")
if(WIN32)
set(MATH_LIB
${OPENBLAS_LIB_PATH}/lib/openblas${CMAKE_STATIC_LIBRARY_SUFFIX})
else()
set(MATH_LIB
${OPENBLAS_LIB_PATH}/lib/libopenblas${CMAKE_STATIC_LIBRARY_SUFFIX})
endif()
endif()
if(WITH_STATIC_LIB)
set(DEPS
${PADDLE_LIB}/paddle/lib/libpaddle_inference${CMAKE_STATIC_LIBRARY_SUFFIX}
)
else()
if(WIN32)
set(DEPS
${PADDLE_LIB}/paddle/lib/paddle_inference${CMAKE_STATIC_LIBRARY_SUFFIX})
else()
set(DEPS
${PADDLE_LIB}/paddle/lib/libpaddle_inference${CMAKE_SHARED_LIBRARY_SUFFIX}
)
endif()
endif()
if(WITH_ONNXRUNTIME)
set(DEPS ${DEPS} onnxruntime paddle2onnx)
endif()
if(NOT WIN32)
set(EXTERNAL_LIB "-lrt -ldl -lpthread")
set(DEPS
${DEPS}
${MATH_LIB}
${ONEDNN_LIB}
glog
gflags
protobuf
xxhash
cryptopp
${EXTERNAL_LIB})
else()
set(DEPS
${DEPS}
${MATH_LIB}
${ONEDNN_LIB}
glog
gflags_static
libprotobuf
xxhash
cryptopp-static
${EXTERNAL_LIB})
set(DEPS ${DEPS} shlwapi.lib)
endif()
if(WITH_GPU)
if(NOT WIN32)
if(USE_TENSORRT)
set(DEPS ${DEPS}
${TENSORRT_LIB_DIR}/libnvinfer${CMAKE_SHARED_LIBRARY_SUFFIX})
set(DEPS
${DEPS}
${TENSORRT_LIB_DIR}/libnvinfer_plugin${CMAKE_SHARED_LIBRARY_SUFFIX})
endif()
set(DEPS ${DEPS} ${CUDA_LIB}/libcudart${CMAKE_SHARED_LIBRARY_SUFFIX})
else()
if(USE_TENSORRT)
set(DEPS ${DEPS}
${TENSORRT_LIB_DIR}/nvinfer${CMAKE_STATIC_LIBRARY_SUFFIX})
set(DEPS ${DEPS}
${TENSORRT_LIB_DIR}/nvinfer_plugin${CMAKE_STATIC_LIBRARY_SUFFIX})
if(${TENSORRT_MAJOR_VERSION} EQUAL 7)
set(DEPS ${DEPS}
${TENSORRT_LIB_DIR}/myelin64_1${CMAKE_STATIC_LIBRARY_SUFFIX})
endif()
endif()
set(DEPS ${DEPS} ${CUDA_LIB}/cudart${CMAKE_STATIC_LIBRARY_SUFFIX})
set(DEPS ${DEPS} ${CUDA_LIB}/cublas${CMAKE_STATIC_LIBRARY_SUFFIX})
set(DEPS ${DEPS} ${CUDA_LIB}/cudnn${CMAKE_STATIC_LIBRARY_SUFFIX})
endif()
endif()
if(WITH_GTEST)
include(ExternalProject)
include(external-cmake/gtest-cpp.cmake)
endif()
add_executable(${DEMO_NAME} ${DEMO_NAME}.cc)
target_link_libraries(${DEMO_NAME} ${DEPS})
if(WITH_GTEST)
include(GNUInstallDirs)
include_directories(${GTEST_INSTALL_DIR}/include)
add_dependencies(${DEMO_NAME} thirdparty_gtest)
if(WIN32)
target_link_libraries(${DEMO_NAME} ${GTEST_LIBRARIES})
else()
target_link_libraries(
${DEMO_NAME}
${GTEST_INSTALL_DIR}/${CMAKE_INSTALL_LIBDIR}/libgtest${CMAKE_STATIC_LIBRARY_SUFFIX}
)
endif()
endif()
if(WIN32)
if("${CMAKE_GENERATOR}" MATCHES "Ninja")
set(LIB_PATH ${CMAKE_BINARY_DIR})
else()
set(LIB_PATH ${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE})
endif()
if(USE_TENSORRT)
add_custom_command(
TARGET ${DEMO_NAME}
POST_BUILD
COMMAND
${CMAKE_COMMAND} -E copy
${TENSORRT_LIB_DIR}/nvinfer${CMAKE_SHARED_LIBRARY_SUFFIX} ${LIB_PATH}
COMMAND
${CMAKE_COMMAND} -E copy
${TENSORRT_LIB_DIR}/nvinfer_plugin${CMAKE_SHARED_LIBRARY_SUFFIX}
${LIB_PATH})
if(${TENSORRT_MAJOR_VERSION} EQUAL 7)
add_custom_command(
TARGET ${DEMO_NAME}
POST_BUILD
COMMAND
${CMAKE_COMMAND} -E copy
${TENSORRT_LIB_DIR}/myelin64_1${CMAKE_SHARED_LIBRARY_SUFFIX}
${LIB_PATH})
endif()
endif()
if(WITH_MKL)
message("LIB_PATH IS ${LIB_PATH}")
add_custom_command(
TARGET ${DEMO_NAME}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy ${MATH_LIB_PATH}/lib/mklml.dll
${LIB_PATH}
COMMAND ${CMAKE_COMMAND} -E copy ${MATH_LIB_PATH}/lib/libiomp5md.dll
${LIB_PATH}
COMMAND ${CMAKE_COMMAND} -E copy ${ONEDNN_PATH}/lib/mkldnn.dll
${LIB_PATH})
else()
add_custom_command(
TARGET ${DEMO_NAME}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy ${OPENBLAS_LIB_PATH}/lib/openblas.dll
${LIB_PATH})
endif()
if(WITH_ONNXRUNTIME)
add_custom_command(
TARGET ${DEMO_NAME}
POST_BUILD
COMMAND
${CMAKE_COMMAND} -E copy
${PADDLE_LIB_THIRD_PARTY_PATH}onnxruntime/lib/onnxruntime.dll
${LIB_PATH}
COMMAND
${CMAKE_COMMAND} -E copy
${PADDLE_LIB_THIRD_PARTY_PATH}paddle2onnx/lib/paddle2onnx.dll
${LIB_PATH})
endif()
if(NOT WITH_STATIC_LIB)
add_custom_command(
TARGET ${DEMO_NAME}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
"${PADDLE_LIB}/paddle/lib/paddle_inference.dll" ${LIB_PATH})
endif()
endif()
+37
View File
@@ -0,0 +1,37 @@
# Inference Model UT
There are several model tests currently:
- test_ernie_text_cls.cc
- test_LeViT.cc
- test_ppyolo_mbv3.cc
- test_ppyolov2_r50vd.cc
- test_resnet50.cc
- test_resnet50_quant.cc
- test_yolov3.cc
To build and execute tests on Linux, simply run
```
./run.sh $PADDLE_ROOT $TURN_ON_MKL $TEST_GPU_CPU $DATA_DIR
```
To build on windows, run command with busybox
```
busybox bash ./run.sh $PADDLE_ROOT $TURN_ON_MKL $TEST_GPU_CPU $DATA_DIR
```
- After run command, it will build and execute tests and download to ${DATA_DIR} automatically.
- `$PADDLE_ROOT`: paddle library path
- `$TURN_ON_MKL`: use MKL or Openblas
- `$TEST_GPU_CPU`: test both GPU/CPU mode or only CPU mode
- `$DATA_DIR`: download data path
now only support 4 kinds of tests which controlled by `--gtest_filter` argument, test suite name should be same as following.
- `TEST(gpu_tester_*, test_name)`
- `TEST(cpu_tester_*, test_name)`
- `TEST(onednn_tester_*, test_name)`
- `TEST(tensorrt_tester_*, test_name)`
skpied test suite name.
- `TEST(DISABLED_gpu_tester_*, test_name)`
- `TEST(DISABLED_cpu_tester_*, test_name)`
- `TEST(DISABLED_onednn_tester_*, test_name)`
- `TEST(DISABLED_tensorrt_tester_*, test_name)`
@@ -0,0 +1,59 @@
find_package(Git REQUIRED)
message("${CMAKE_BUILD_TYPE}")
set(GTEST_PREFIX_DIR ${CMAKE_CURRENT_BINARY_DIR}/gtest)
set(PADDLE_SOURCE_DIR $ENV{PADDLE_SOURCE_DIR})
set(GTEST_SOURCE_DIR ${PADDLE_SOURCE_DIR}/third_party/gtest)
set(GTEST_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/install/gtest)
set(GTEST_INCLUDE_DIR
"${GTEST_INSTALL_DIR}/include"
CACHE PATH "gtest include directory." FORCE)
set(GTEST_TAG release-1.8.1)
if(CMAKE_VERSION VERSION_GREATER_EQUAL "4.0.0")
message(
WARNING
"gtest-cpp: forcing CMake policy compatibility for CMake >= 4.0 (CMAKE_POLICY_VERSION_MINIMUM=3.5)"
)
set(GTEST_POLICY_ARGS -DCMAKE_POLICY_VERSION_MINIMUM=3.5)
endif()
include_directories(${GTEST_INCLUDE_DIR})
if(WIN32)
# if use CMAKE_INSTALL_LIBDIR, the path of lib actually is \
# install/gtest/lib/gtest.lib but GTEST_LIBRARIES
# is install/gtest/gtest.lib
set(GTEST_LIBRARIES
"${GTEST_INSTALL_DIR}/lib/gtest.lib"
CACHE FILEPATH "gtest libraries." FORCE)
set(GTEST_MAIN_LIBRARIES
"${GTEST_INSTALL_DIR}/lib/gtest_main.lib"
CACHE FILEPATH "gtest main libraries." FORCE)
else()
set(GTEST_LIBRARIES
"${GTEST_INSTALL_DIR}/${CMAKE_INSTALL_LIBDIR}/libgtest.a"
CACHE FILEPATH "gtest libraries." FORCE)
set(GTEST_MAIN_LIBRARIES
"${GTEST_INSTALL_DIR}/${CMAKE_INSTALL_LIBDIR}/libgtest_main.a"
CACHE FILEPATH "gtest main libraries." FORCE)
endif()
ExternalProject_Add(
extern_gtest
PREFIX gtest
SOURCE_DIR ${GTEST_SOURCE_DIR}
DOWNLOAD_DIR "${DOWNLOAD_LOCATION}"
UPDATE_COMMAND ""
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${GTEST_INSTALL_DIR}
-DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=ON
-DCMAKE_BUILD_TYPE:STRING=Release ${GTEST_POLICY_ARGS}
BUILD_BYPRODUCTS ${GTEST_LIBRARIES}
BUILD_BYPRODUCTS ${GTEST_MAIN_LIBRARIES})
add_library(thirdparty_gtest STATIC IMPORTED GLOBAL)
set_property(TARGET thirdparty_gtest PROPERTY IMPORTED_LOCATION
${GTEST_LIBRARIES})
add_dependencies(thirdparty_gtest extern_gtest)
add_library(thirdparty_gtest_main STATIC IMPORTED GLOBAL)
set_property(TARGET thirdparty_gtest_main PROPERTY IMPORTED_LOCATION
${GTEST_MAIN_LIBRARIES})
add_dependencies(thirdparty_gtest_main extern_gtest)
+326
View File
@@ -0,0 +1,326 @@
#!/bin/bash
# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
#
# 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.
set -x
PADDLE_ROOT=$1
export PADDLE_SOURCE_DIR=$1
TURN_ON_MKL=$2 # use MKL or Openblas
TEST_GPU_CPU=$3 # test both GPU/CPU mode or only CPU mode
DATA_DIR=$4 # dataset
TENSORRT_ROOT_DIR=$5 # TensorRT ROOT dir, default to /usr/local/TensorRT
WITH_ONNXRUNTIME=$6
MSVC_STATIC_CRT=$7
CUDA_LIB=$8/lib/x64
inference_install_dir=${PADDLE_ROOT}/build/paddle_inference_install_dir
EXIT_CODE=0 # init default exit code
WIN_DETECT=$(echo `uname` | grep "Win") # detect current platform
test_suite_list="cpu_tester*" # init test suite list, pass to --gtest_filter
export RED='\033[0;31m' # red color
export NC='\033[0m' # no color
export YELLOW='\033[33m' # yellow color
cd `dirname $0`
current_dir=`pwd`
build_dir=${current_dir}/build
log_dir=${current_dir}/log
# check onednn installation
if [ $2 == ON ]; then
# You can export yourself if move the install path
MKL_LIB=${inference_install_dir}/third_party/install/mklml/lib
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${MKL_LIB}
test_suite_list="${test_suite_list}:onednn_tester*"
fi
if [ $3 == ON ]; then
use_gpu_list='true false'
test_suite_list="${test_suite_list}:gpu_tester*"
else
use_gpu_list='false'
fi
# check tensorrt installation
TENSORRT_COMPILED=$(cat "${inference_install_dir}/version.txt" | grep "WITH_TENSORRT")
USE_TENSORRT=OFF
if [ -d "$TENSORRT_ROOT_DIR" ] && [ ! -z "$TENSORRT_COMPILED" ] ; then
USE_TENSORRT=ON
test_suite_list="${test_suite_list}:tensorrt_tester*"
fi
function download() {
url_prefix=$1
model_name=$2
mkdir -p $model_name
cd $model_name
if [[ -e "${model_name}.tgz" ]]; then
echo "${model_name}.tgz has been downloaded."
else
if [ "$WIN_DETECT" != "" ]; then
wget -q -Y off ${url_prefix}/${model_name}.tgz
tar xzf *.tgz
else
wget -q --no-proxy ${url_prefix}/${model_name}.tgz
tar xzf *.tgz
fi
fi
cd ..
}
mkdir -p $DATA_DIR
cd $DATA_DIR
download_list='resnet50'
for model_name in $download_list; do
url_prefix="https://paddle-inference-dist.bj.bcebos.com/Paddle-Inference-Demo"
download $url_prefix $model_name
done
ocr_download_list='ocr_det_mv3_db'
for model_name in $ocr_download_list; do
url_prefix="https://paddle-qa.bj.bcebos.com/inference_model/2.1.1/ocr"
download $url_prefix $model_name
done
clas_download_list='LeViT'
for model_name in $clas_download_list; do
url_prefix="https://paddle-qa.bj.bcebos.com/inference_model/2.1.1/class"
download $url_prefix $model_name
done
nlp_download_list='ernie_text_cls'
for model_name in $nlp_download_list; do
url_prefix="https://paddle-qa.bj.bcebos.com/inference_model/2.1.1/nlp"
download $url_prefix $model_name
done
det_download_list='yolov3 ppyolo_mbv3 ppyolov2_r50vd'
for model_name in $det_download_list; do
url_prefix="https://paddle-qa.bj.bcebos.com/inference_model/2.1.1/detection"
download $url_prefix $model_name
done
unknown_download_list='resnet50_quant'
for model_name in $unknown_download_list; do
url_prefix="https://paddle-qa.bj.bcebos.com/inference_model/unknown"
download $url_prefix $model_name
done
# ernie int8 quant with matmul
unknown_nlp_download_list='quant_post_model_xnli_predict_matmul'
for model_name in $unknown_nlp_download_list; do
url_prefix="https://paddle-qa.bj.bcebos.com/inference_model/unknown/nlp"
download $url_prefix $model_name
done
# mobilnetv1 with prune op attribute
dev_class_download_list='MobileNetV1'
for model_name in $dev_class_download_list; do
url_prefix="https://paddle-qa.bj.bcebos.com/inference_model/2021-09-16/class"
download $url_prefix $model_name
done
function compile_test() {
mkdir -p ${build_dir}
cd ${build_dir}
TEST_NAME=$1
if [ "$WIN_DETECT" != "" ]; then
cmake .. -GNinja -DPADDLE_LIB=${inference_install_dir} \
-DWITH_MKL=$TURN_ON_MKL \
-DDEMO_NAME=${TEST_NAME} \
-DWITH_GPU=$TEST_GPU_CPU \
-DWITH_STATIC_LIB=OFF \
-DUSE_TENSORRT=$USE_TENSORRT \
-DTENSORRT_ROOT=$TENSORRT_ROOT_DIR \
-DMSVC_STATIC_CRT=$MSVC_STATIC_CRT \
-DWITH_GTEST=ON \
-DCMAKE_CXX_FLAGS='/std:c++17' \
-DCMAKE_BUILD_TYPE=Release \
-DWITH_ONNXRUNTIME=$WITH_ONNXRUNTIME \
-DCUDA_LIB="$CUDA_LIB"
ninja
else
cmake .. -DPADDLE_LIB=${inference_install_dir} \
-DWITH_MKL=$TURN_ON_MKL \
-DDEMO_NAME=${TEST_NAME} \
-DWITH_GPU=$TEST_GPU_CPU \
-DWITH_STATIC_LIB=OFF \
-DUSE_TENSORRT=$USE_TENSORRT \
-DTENSORRT_ROOT=$TENSORRT_ROOT_DIR \
-DWITH_GTEST=ON \
-DWITH_ONNXRUNTIME=$WITH_ONNXRUNTIME
make -j$(nproc)
fi
cd -
}
# compile and run test
cd $current_dir
mkdir -p ${build_dir}
mkdir -p ${log_dir}
cd ${build_dir}
rm -rf *
exe_dir=${build_dir}
# printf "${YELLOW} start test_resnet50 ${NC} \n";
# compile_test "test_resnet50"
# ${exe_dir}/test_resnet50 \
# --modeldir=$DATA_DIR/resnet50/resnet50 \
# --gtest_filter=${test_suite_list} \
# --gtest_output=xml:${log_dir}/test_resnet50.xml
# if [ $? -ne 0 ]; then
# echo "${RED} test_resnet50 runs failed ${NC}" >> ${exe_dir}/test_summary.txt
# EXIT_CODE=8
# fi
# printf "${YELLOW} start test_det_mv3_db ${NC} \n";
# compile_test "test_det_mv3_db"
# ${exe_dir}/test_det_mv3_db \
# --modeldir=$DATA_DIR/ocr_det_mv3_db/ocr_det_mv3_db \
# --gtest_filter=${test_suite_list} \
# --gtest_output=xml:${log_dir}/test_det_mv3_db.xml
# if [ $? -ne 0 ]; then
# echo "${RED} test_det_mv3_db runs failed ${NC}" >> ${exe_dir}/test_summary.txt
# EXIT_CODE=8
# fi
# printf "${YELLOW} start test_LeViT ${NC} \n";
# compile_test "test_LeViT"
# ${exe_dir}/test_LeViT \
# --modeldir=$DATA_DIR/LeViT/LeViT \
# --gtest_filter=${test_suite_list} \
# --gtest_output=xml:${log_dir}/test_LeViT.xml
# if [ $? -ne 0 ]; then
# echo "${RED} test_LeViT runs failed ${NC}" >> ${exe_dir}/test_summary.txt
# EXIT_CODE=8
# fi
if [ "$WIN_DETECT" != "" ]; then
#TODO(OliverLPH): enable test_ernie_text_cls on windows after fix compile issue
echo " skip test_ernie_text_cls "
else
printf "${YELLOW} start test_ernie_text_cls ${NC} \n";
compile_test "test_ernie_text_cls"
${exe_dir}/test_ernie_text_cls \
--modeldir=$DATA_DIR/ernie_text_cls/ernie_text_cls \
--gtest_filter=${test_suite_list} \
--gtest_output=xml:${log_dir}/test_ernie_text_cls.xml
if [ $? -ne 0 ]; then
echo "${RED} test_ernie_text_cls runs failed ${NC}" >> ${exe_dir}/test_summary.txt
EXIT_CODE=8
fi
fi
printf "${YELLOW} start test_yolov3 ${NC} \n";
compile_test "test_yolov3"
${exe_dir}/test_yolov3 \
--modeldir=$DATA_DIR/yolov3/yolov3 \
--gtest_filter=${test_suite_list} \
--gtest_output=xml:${log_dir}/test_yolov3.xml
if [ $? -ne 0 ]; then
echo "${RED} test_yolov3 runs failed ${NC}" >> ${exe_dir}/test_summary.txt
EXIT_CODE=8
fi
# printf "${YELLOW} start test_ppyolo_mbv3 ${NC} \n";
# compile_test "test_ppyolo_mbv3"
# ${exe_dir}/test_ppyolo_mbv3 \
# --modeldir=$DATA_DIR/ppyolo_mbv3/ppyolo_mbv3 \
# --gtest_filter=${test_suite_list} \
# --gtest_output=xml:${log_dir}/test_ppyolo_mbv3.xml
# if [ $? -ne 0 ]; then
# echo "${RED} test_ppyolo_mbv3 runs failed ${NC}" >> ${exe_dir}/test_summary.txt
# EXIT_CODE=8
# fi
# printf "${YELLOW} start test_ppyolov2_r50vd ${NC} \n";
# compile_test "test_ppyolov2_r50vd"
# ${exe_dir}/test_ppyolov2_r50vd \
# --modeldir=$DATA_DIR/ppyolov2_r50vd/ppyolov2_r50vd \
# --gtest_filter=${test_suite_list} \
# --gtest_output=xml:${log_dir}/test_ppyolov2_r50vd.xml
# if [ $? -ne 0 ]; then
# echo "${RED} test_ppyolov2_r50vd runs failed ${NC}" >> ${exe_dir}/test_summary.txt
# EXIT_CODE=8
# fi
printf "${YELLOW} start test_resnet50_quant ${NC} \n";
compile_test "test_resnet50_quant"
${exe_dir}/test_resnet50_quant \
--int8dir=$DATA_DIR/resnet50_quant/resnet50_quant/resnet50_quant \
--modeldir=$DATA_DIR/resnet50/resnet50 \
--datadir=$DATA_DIR/resnet50_quant/resnet50_quant/imagenet-eval-binary/9.data \
--gtest_filter=${test_suite_list} \
--gtest_output=xml:${log_dir}/test_resnet50_quant.xml
if [ $? -ne 0 ]; then
echo "${RED} test_resnet50_quant runs failed ${NC}" >> ${exe_dir}/test_summary.txt
EXIT_CODE=8
fi
# printf "${YELLOW} start test_ernie_xnli_int8 ${NC} \n";
# compile_test "test_ernie_xnli_int8"
# ernie_qat_model="quant_post_model_xnli_predict_matmul"
# ${exe_dir}/test_ernie_xnli_int8 \
# --modeldir=$DATA_DIR/$ernie_qat_model/$ernie_qat_model \
# --datadir=$DATA_DIR/$ernie_qat_model/$ernie_qat_model/xnli_var_len \
# --truth_data=$DATA_DIR/$ernie_qat_model/$ernie_qat_model/truth_data \
# --gtest_filter=${test_suite_list} \
# --gtest_output=xml:${log_dir}/test_ernie_xnli_int8.xml
# if [ $? -ne 0 ]; then
# echo "${RED} test_ernie_xnli_int8 runs failed ${NC}" >> ${exe_dir}/test_summary.txt
# EXIT_CODE=8
# fi
printf "${YELLOW} start test_mobilnetv1 ${NC} \n";
compile_test "test_mobilnetv1"
${exe_dir}/test_mobilnetv1 \
--modeldir=$DATA_DIR/MobileNetV1/MobileNetV1 \
--gtest_filter=${test_suite_list} \
--gtest_output=xml:${log_dir}/test_mobilnetv1.xml
if [ $? -ne 0 ]; then
echo "${RED} test_mobilnetv1 runs failed ${NC}" >> ${exe_dir}/test_summary.txt
EXIT_CODE=8
fi
set +x
test_suites=$(echo ${test_suite_list} | sed 's/:/ /g')
echo " "
echo "CI Tested Following Patterns: "
echo "=====================test patterns======================"
for test_suite in ${test_suites}; do
echo " ${test_suite}"
done
echo "========================================================"
echo " "
if [[ -f ${exe_dir}/test_summary.txt ]];then
echo " "
echo "Summary infer_ut Failed Tests ..."
echo "=====================test summary======================"
echo "The following tests Failed: "
cat ${exe_dir}/test_summary.txt
echo "========================================================"
echo " "
fi
set -x
# tar Gtest output report
tar -zcvf infer_ut_log.tgz ${log_dir}
echo "infer_ut script finished"
exit ${EXIT_CODE}
+253
View File
@@ -0,0 +1,253 @@
// Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
//
// 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 "test_suite.h" // NOLINT
#ifdef PADDLE_WITH_GPU
#include <cuda_runtime.h>
#endif
DEFINE_string(modeldir, "", "Directory of the inference model.");
namespace paddle_infer {
paddle::test::Record PrepareInput(int batch_size) {
// init input data
int channel = 3;
int width = 224;
int height = 224;
paddle::test::Record image_Record;
int input_num = batch_size * channel * width * height;
std::vector<float> input_data(input_num, 1);
image_Record.data = input_data;
image_Record.shape = std::vector<int>{batch_size, channel, width, height};
image_Record.type = paddle::PaddleDType::FLOAT32;
return image_Record;
}
TEST(gpu_tester_LeViT, analysis_gpu_bz1) {
// init input data
std::map<std::string, paddle::test::Record> my_input_data_map;
my_input_data_map["x"] = PrepareInput(1);
// init output data
std::map<std::string, paddle::test::Record> infer_output_data,
truth_output_data;
// prepare ground truth config
paddle_infer::Config config, config_no_ir;
config_no_ir.SetModel(FLAGS_modeldir + "/inference.pdmodel",
FLAGS_modeldir + "/inference.pdiparams");
config_no_ir.SwitchIrOptim(false);
// prepare inference config
config.SetModel(FLAGS_modeldir + "/inference.pdmodel",
FLAGS_modeldir + "/inference.pdiparams");
// get ground truth by disable ir
paddle_infer::services::PredictorPool pred_pool_no_ir(config_no_ir, 1);
SingleThreadPrediction(
pred_pool_no_ir.Retrieve(0), &my_input_data_map, &truth_output_data, 1);
// get infer results
paddle_infer::services::PredictorPool pred_pool(config, 1);
SingleThreadPrediction(
pred_pool.Retrieve(0), &my_input_data_map, &infer_output_data);
// check outputs
CompareRecord(&truth_output_data, &infer_output_data);
std::cout << "finish test" << std::endl;
}
TEST(tensorrt_tester_LeViT, trt_fp32_bz2) {
// init input data
std::map<std::string, paddle::test::Record> my_input_data_map;
my_input_data_map["x"] = PrepareInput(2);
// init output data
std::map<std::string, paddle::test::Record> infer_output_data,
truth_output_data;
// prepare ground truth config
paddle_infer::Config config, config_no_ir;
config_no_ir.SetModel(FLAGS_modeldir + "/inference.pdmodel",
FLAGS_modeldir + "/inference.pdiparams");
config_no_ir.SwitchIrOptim(false);
// prepare inference config
config.SetModel(FLAGS_modeldir + "/inference.pdmodel",
FLAGS_modeldir + "/inference.pdiparams");
config.EnableUseGpu(100, 0);
config.EnableTensorRtEngine(
1 << 20, 2, 50, paddle_infer::PrecisionType::kFloat32, false, false);
// get ground truth by disable ir
paddle_infer::services::PredictorPool pred_pool_no_ir(config_no_ir, 1);
SingleThreadPrediction(
pred_pool_no_ir.Retrieve(0), &my_input_data_map, &truth_output_data, 1);
// get infer results
paddle_infer::services::PredictorPool pred_pool(config, 1);
SingleThreadPrediction(
pred_pool.Retrieve(0), &my_input_data_map, &infer_output_data);
// check outputs
CompareRecord(&truth_output_data, &infer_output_data);
std::cout << "finish test" << std::endl;
}
TEST(tensorrt_tester_LeViT, serial_diff_batch_trt_fp32) {
int max_batch_size = 5;
// prepare ground truth config
paddle_infer::Config config, config_no_ir;
config_no_ir.SetModel(FLAGS_modeldir + "/inference.pdmodel",
FLAGS_modeldir + "/inference.pdiparams");
config_no_ir.SwitchIrOptim(false);
paddle_infer::services::PredictorPool pred_pool_no_ir(config_no_ir, 1);
// prepare inference config
config.SetModel(FLAGS_modeldir + "/inference.pdmodel",
FLAGS_modeldir + "/inference.pdiparams");
config.EnableUseGpu(100, 0);
config.EnableTensorRtEngine(1 << 20,
max_batch_size,
50,
paddle_infer::PrecisionType::kFloat32,
false,
false);
paddle_infer::services::PredictorPool pred_pool(config, 1);
for (int i = 1; i < max_batch_size; i++) {
// init input data
std::map<std::string, paddle::test::Record> my_input_data_map;
my_input_data_map["x"] = PrepareInput(i);
// init output data
std::map<std::string, paddle::test::Record> infer_output_data,
truth_output_data;
// get ground truth by disable ir
SingleThreadPrediction(
pred_pool_no_ir.Retrieve(0), &my_input_data_map, &truth_output_data, 1);
// get infer results
SingleThreadPrediction(
pred_pool.Retrieve(0), &my_input_data_map, &infer_output_data);
// check outputs
CompareRecord(&truth_output_data, &infer_output_data);
}
std::cout << "finish test" << std::endl;
}
TEST(tensorrt_tester_LeViT, multi_thread4_trt_fp32_bz2) {
int thread_num = 4;
// init input data
std::map<std::string, paddle::test::Record> my_input_data_map;
my_input_data_map["x"] = PrepareInput(2);
// init output data
std::map<std::string, paddle::test::Record> infer_output_data,
truth_output_data;
// prepare ground truth config
paddle_infer::Config config, config_no_ir;
config_no_ir.SetModel(FLAGS_modeldir + "/inference.pdmodel",
FLAGS_modeldir + "/inference.pdiparams");
config_no_ir.SwitchIrOptim(false);
// prepare inference config
config.SetModel(FLAGS_modeldir + "/inference.pdmodel",
FLAGS_modeldir + "/inference.pdiparams");
config.EnableUseGpu(100, 0);
config.EnableTensorRtEngine(
1 << 20, 2, 50, paddle_infer::PrecisionType::kFloat32, false, false);
// get ground truth by disable ir
paddle_infer::services::PredictorPool pred_pool_no_ir(config_no_ir, 1);
SingleThreadPrediction(
pred_pool_no_ir.Retrieve(0), &my_input_data_map, &truth_output_data, 1);
// get infer results from multi threads
std::vector<std::thread> threads;
services::PredictorPool pred_pool(config, thread_num);
for (int i = 0; i < thread_num; ++i) {
threads.emplace_back(paddle::test::SingleThreadPrediction,
pred_pool.Retrieve(i),
&my_input_data_map,
&infer_output_data,
10);
}
// thread join & check outputs
for (int i = 0; i < thread_num; ++i) {
LOG(INFO) << "join tid : " << i;
threads[i].join();
CompareRecord(&truth_output_data, &infer_output_data);
}
std::cout << "finish multi-thread test" << std::endl;
}
#ifdef PADDLE_WITH_GPU
TEST(tensorrt_tester_LeViT, multi_stream_thread4_trt_fp32_bz2) {
int thread_num = 4;
// init stream
std::vector<cudaStream_t> streams(thread_num);
for (size_t i = 0; i < thread_num; ++i) {
cudaStreamCreate(&streams[i]);
}
// init input data
std::map<std::string, paddle::test::Record> my_input_data_map;
my_input_data_map["x"] = PrepareInput(2);
// init output data
std::map<std::string, paddle::test::Record> infer_output_data,
truth_output_data;
// prepare ground truth config
paddle_infer::Config config, config_no_ir;
config_no_ir.SetModel(FLAGS_modeldir + "/inference.pdmodel",
FLAGS_modeldir + "/inference.pdiparams");
config_no_ir.SwitchIrOptim(false);
// prepare inference config
config.SetModel(FLAGS_modeldir + "/inference.pdmodel",
FLAGS_modeldir + "/inference.pdiparams");
config.EnableUseGpu(100, 0);
config.EnableTensorRtEngine(
1 << 20, 2, 50, paddle_infer::PrecisionType::kFloat32, false, false);
// get ground truth by disable ir
paddle_infer::services::PredictorPool pred_pool_no_ir(config_no_ir, 1);
SingleThreadPrediction(
pred_pool_no_ir.Retrieve(0), &my_input_data_map, &truth_output_data, 1);
// get infer results from multi threads
std::vector<std::thread> threads;
config.SetExecStream(streams[0]);
config.pass_builder()->DeletePass("add_support_int8_pass");
auto main_predictor = CreatePredictor(config);
std::vector<decltype(main_predictor)> predictors;
for (size_t i = 0; i < thread_num - 1; ++i) {
predictors.push_back(std::move(main_predictor->Clone(streams[i + 1])));
LOG(INFO) << "predictors[" << i << "] stream is "
<< predictors[i]->GetExecStream();
}
predictors.push_back(std::move(main_predictor));
LOG(INFO) << "predictors[" << thread_num - 1 << "] stream is "
<< predictors[thread_num - 1]->GetExecStream();
for (int i = 0; i < thread_num; ++i) {
threads.emplace_back(paddle::test::SingleThreadPrediction,
predictors[i].get(),
&my_input_data_map,
&infer_output_data,
10);
}
// thread join & check outputs
for (int i = 0; i < thread_num; ++i) {
LOG(INFO) << "join tid : " << i;
threads[i].join();
CompareRecord(&truth_output_data, &infer_output_data);
}
std::cout << "finish multi-thread test" << std::endl;
}
#endif
} // namespace paddle_infer
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
gflags::ParseCommandLineFlags(&argc, &argv, true);
return RUN_ALL_TESTS();
}
@@ -0,0 +1,188 @@
// Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
//
// 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 "test_suite.h" // NOLINT
DEFINE_string(modeldir, "", "Directory of the inference model.");
namespace paddle_infer {
paddle::test::Record PrepareInput(int batch_size, int image_shape = 640) {
// init input data
int channel = 3;
int width = image_shape;
int height = image_shape;
paddle::test::Record image_Record;
int input_num = batch_size * channel * width * height;
std::vector<float> input_data(input_num, 1);
image_Record.data = input_data;
image_Record.shape = std::vector<int>{batch_size, channel, width, height};
image_Record.type = paddle::PaddleDType::FLOAT32;
return image_Record;
}
void PrepareDynamicShape(paddle_infer::Config* config, int max_batch_size = 4) {
// set dynamic shape range
std::map<std::string, std::vector<int>> min_input_shape = {
{"x", {1, 3, 224, 224}},
{"conv2d_124.tmp_0", {1, 256, 56, 56}},
{"nearest_interp_v2_2.tmp_0", {1, 256, 56, 56}},
{"nearest_interp_v2_3.tmp_0", {1, 64, 56, 56}},
{"nearest_interp_v2_4.tmp_0", {1, 64, 56, 56}},
{"nearest_interp_v2_5.tmp_0", {1, 64, 56, 56}}};
std::map<std::string, std::vector<int>> max_input_shape = {
{"x", {max_batch_size, 3, 448, 448}},
{"conv2d_124.tmp_0", {max_batch_size, 256, 112, 112}},
{"nearest_interp_v2_2.tmp_0", {max_batch_size, 256, 112, 112}},
{"nearest_interp_v2_3.tmp_0", {max_batch_size, 64, 112, 112}},
{"nearest_interp_v2_4.tmp_0", {max_batch_size, 64, 112, 112}},
{"nearest_interp_v2_5.tmp_0", {max_batch_size, 64, 112, 112}}};
std::map<std::string, std::vector<int>> opt_input_shape = {
{"x", {1, 3, 256, 256}},
{"conv2d_124.tmp_0", {1, 256, 64, 64}},
{"nearest_interp_v2_2.tmp_0", {1, 256, 64, 64}},
{"nearest_interp_v2_3.tmp_0", {1, 64, 64, 64}},
{"nearest_interp_v2_4.tmp_0", {1, 64, 64, 64}},
{"nearest_interp_v2_5.tmp_0", {1, 64, 64, 64}}};
config->SetTRTDynamicShapeInfo(
min_input_shape, max_input_shape, opt_input_shape);
}
TEST(gpu_tester_det_mv3_db, analysis_gpu_bz4) {
// init input data
std::map<std::string, paddle::test::Record> my_input_data_map;
my_input_data_map["x"] = PrepareInput(4, 640);
// init output data
std::map<std::string, paddle::test::Record> infer_output_data,
truth_output_data;
// prepare ground truth config
paddle_infer::Config config, config_no_ir;
config_no_ir.SetModel(FLAGS_modeldir + "/inference.pdmodel",
FLAGS_modeldir + "/inference.pdiparams");
config_no_ir.SwitchIrOptim(false);
// prepare inference config
config.SetModel(FLAGS_modeldir + "/inference.pdmodel",
FLAGS_modeldir + "/inference.pdiparams");
// get ground truth by disable ir
paddle_infer::services::PredictorPool pred_pool_no_ir(config_no_ir, 1);
SingleThreadPrediction(
pred_pool_no_ir.Retrieve(0), &my_input_data_map, &truth_output_data, 1);
// get infer results
paddle_infer::services::PredictorPool pred_pool(config, 1);
SingleThreadPrediction(
pred_pool.Retrieve(0), &my_input_data_map, &infer_output_data);
// check outputs
CompareRecord(&truth_output_data, &infer_output_data, 1e-4);
std::cout << "finish test" << std::endl;
}
TEST(tensorrt_tester_det_mv3_db, multi_thread2_trt_fp32_dynamic_shape_bz2) {
int thread_num = 2; // thread > 2 may OOM
// init input data
std::map<std::string, paddle::test::Record> my_input_data_map;
my_input_data_map["x"] = PrepareInput(2, 256);
// init output data
std::map<std::string, paddle::test::Record> infer_output_data,
truth_output_data;
// prepare ground truth config
paddle_infer::Config config, config_no_ir;
config_no_ir.SetModel(FLAGS_modeldir + "/inference.pdmodel",
FLAGS_modeldir + "/inference.pdiparams");
config_no_ir.SwitchIrOptim(false);
// prepare inference config
config.SetModel(FLAGS_modeldir + "/inference.pdmodel",
FLAGS_modeldir + "/inference.pdiparams");
config.EnableUseGpu(100, 0);
config.EnableTensorRtEngine(
1 << 20, 4, 3, paddle_infer::PrecisionType::kFloat32, false, false);
PrepareDynamicShape(&config, 4);
// get ground truth by disable ir
paddle_infer::services::PredictorPool pred_pool_no_ir(config_no_ir, 1);
SingleThreadPrediction(
pred_pool_no_ir.Retrieve(0), &my_input_data_map, &truth_output_data, 1);
// get infer results from multi threads
std::vector<std::thread> threads;
services::PredictorPool pred_pool(config, thread_num);
for (int i = 0; i < thread_num; ++i) {
threads.emplace_back(paddle::test::SingleThreadPrediction,
pred_pool.Retrieve(i),
&my_input_data_map,
&infer_output_data,
2);
}
// thread join & check outputs
for (int i = 0; i < thread_num; ++i) {
LOG(INFO) << "join tid : " << i;
threads[i].join();
CompareRecord(&truth_output_data, &infer_output_data, 1e-4);
}
std::cout << "finish multi-thread test" << std::endl;
}
TEST(onednn_tester_det_mv3_db, multi_thread2_mkl_fp32_bz2) {
int thread_num = 2; // thread > 2 may OOM
// init input data
std::map<std::string, paddle::test::Record> my_input_data_map;
my_input_data_map["x"] = PrepareInput(2, 640);
// init output data
std::map<std::string, paddle::test::Record> infer_output_data,
truth_output_data;
// prepare ground truth config
paddle_infer::Config config, config_no_ir;
config_no_ir.SetModel(FLAGS_modeldir + "/inference.pdmodel",
FLAGS_modeldir + "/inference.pdiparams");
config_no_ir.SwitchIrOptim(false);
// prepare inference config
config.SetModel(FLAGS_modeldir + "/inference.pdmodel",
FLAGS_modeldir + "/inference.pdiparams");
config.DisableGpu();
config.EnableONEDNN();
config.SetOnednnCacheCapacity(10);
config.SetCpuMathLibraryNumThreads(10);
// get ground truth by disable ir
paddle_infer::services::PredictorPool pred_pool_no_ir(config_no_ir, 1);
SingleThreadPrediction(
pred_pool_no_ir.Retrieve(0), &my_input_data_map, &truth_output_data, 1);
// get infer results from multi threads
std::vector<std::thread> threads;
services::PredictorPool pred_pool(config, thread_num);
for (int i = 0; i < thread_num; ++i) {
threads.emplace_back(paddle::test::SingleThreadPrediction,
pred_pool.Retrieve(i),
&my_input_data_map,
&infer_output_data,
2);
}
// thread join & check outputs
for (int i = 0; i < thread_num; ++i) {
LOG(INFO) << "join tid : " << i;
threads[i].join();
CompareRecord(&truth_output_data, &infer_output_data, 1e-4);
}
std::cout << "finish multi-thread test" << std::endl;
}
} // namespace paddle_infer
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
gflags::ParseCommandLineFlags(&argc, &argv, true);
return RUN_ALL_TESTS();
}
@@ -0,0 +1,139 @@
// Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
//
// 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 "test_suite.h" // NOLINT
DEFINE_string(modeldir, "", "Directory of the inference model.");
namespace paddle_infer {
template <typename T>
T cRandom(int min, int max) {
unsigned int seed = 100;
return (min +
static_cast<T>(max * rand_r(&seed) / static_cast<T>(RAND_MAX + 1)));
}
std::map<std::string, paddle::test::Record> PrepareInput(int batch_size) {
// init input data
int digit_length = 115;
paddle::test::Record input_ids, segment_ids;
int input_num = batch_size * digit_length;
std::vector<int64_t> input_data(input_num, 1);
std::vector<int64_t> segment_data(input_num, 0);
srand((unsigned)time(NULL));
for (int x = 0; x < input_data.size(); x++) {
input_data[x] = cRandom<int>(1, 100);
}
input_ids.data = std::vector<float>(input_data.begin(), input_data.end());
input_ids.shape = std::vector<int>{batch_size, digit_length};
input_ids.type = paddle::PaddleDType::INT64;
segment_ids.data =
std::vector<float>(segment_data.begin(), segment_data.end());
segment_ids.shape = std::vector<int>{batch_size, digit_length};
segment_ids.type = paddle::PaddleDType::INT64;
std::map<std::string, paddle::test::Record> my_input_data_map;
my_input_data_map.insert({"input_ids", input_ids});
my_input_data_map.insert({"token_type_ids", segment_ids});
return my_input_data_map;
}
TEST(gpu_tester_ernie_text_cls, analysis_gpu_bz2_buffer) {
// init input data
auto my_input_data_map = PrepareInput(2);
// init output data
std::map<std::string, paddle::test::Record> infer_output_data,
truth_output_data;
// prepare ground truth config
paddle_infer::Config config, config_no_ir;
config_no_ir.SetModel(FLAGS_modeldir + "/inference.pdmodel",
FLAGS_modeldir + "/inference.pdiparams");
config_no_ir.SwitchIrOptim(false);
// prepare inference config from buffer
std::string prog_file = FLAGS_modeldir + "/inference.pdmodel";
std::string params_file = FLAGS_modeldir + "/inference.pdiparams";
std::string prog_str = paddle::test::read_file(prog_file);
std::string params_str = paddle::test::read_file(params_file);
config.SetModelBuffer(
prog_str.c_str(), prog_str.size(), params_str.c_str(), params_str.size());
// get ground truth by disable ir
paddle_infer::services::PredictorPool pred_pool_no_ir(config_no_ir, 1);
SingleThreadPrediction(
pred_pool_no_ir.Retrieve(0), &my_input_data_map, &truth_output_data, 1);
// get infer results
paddle_infer::services::PredictorPool pred_pool(config, 1);
SingleThreadPrediction(
pred_pool.Retrieve(0), &my_input_data_map, &infer_output_data);
// check outputs
CompareRecord(&truth_output_data, &infer_output_data);
std::cout << "finish test" << std::endl;
}
TEST(onednn_tester_ernie_text_cls, multi_thread4_mkl_fp32_bz2) {
int thread_num = 4;
// init input data
auto my_input_data_map = PrepareInput(2);
// init output data
std::map<std::string, paddle::test::Record> infer_output_data,
truth_output_data;
// prepare ground truth config
paddle_infer::Config config, config_no_ir;
config_no_ir.SetModel(FLAGS_modeldir + "/inference.pdmodel",
FLAGS_modeldir + "/inference.pdiparams");
config.DisableGpu();
config_no_ir.SwitchIrOptim(false);
// prepare inference config
config.SetModel(FLAGS_modeldir + "/inference.pdmodel",
FLAGS_modeldir + "/inference.pdiparams");
config.DisableGpu();
config.EnableONEDNN();
config.SetOnednnCacheCapacity(10);
config.SetCpuMathLibraryNumThreads(10);
// get ground truth by disable ir
paddle_infer::services::PredictorPool pred_pool_no_ir(config_no_ir, 1);
SingleThreadPrediction(
pred_pool_no_ir.Retrieve(0), &my_input_data_map, &truth_output_data, 1);
// get infer results from multi threads
std::vector<std::thread> threads;
services::PredictorPool pred_pool(config, thread_num);
for (int i = 0; i < thread_num; ++i) {
threads.emplace_back(paddle::test::SingleThreadPrediction,
pred_pool.Retrieve(i),
&my_input_data_map,
&infer_output_data,
2);
}
// thread join & check outputs
for (int i = 0; i < thread_num; ++i) {
LOG(INFO) << "join tid : " << i;
threads[i].join();
CompareRecord(&truth_output_data, &infer_output_data);
}
std::cout << "finish multi-thread test" << std::endl;
}
} // namespace paddle_infer
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
gflags::ParseCommandLineFlags(&argc, &argv, true);
return RUN_ALL_TESTS();
}
@@ -0,0 +1,201 @@
// Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
//
// 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 "test_helper.h" // NOLINT
#include "test_suite.h" // NOLINT
DEFINE_string(modeldir, "", "Directory of the inference model.");
DEFINE_string(datadir, "", "dataset.");
DEFINE_string(truth_data, "", "Directory of the inference data truth result");
namespace paddle_infer {
std::shared_ptr<Predictor> InitPredictor() {
Config config;
config.SetModel(FLAGS_modeldir + "/__model__",
FLAGS_modeldir + "/__params__");
config.EnableUseGpu(1000, 0);
// Open the memory optim.
config.EnableMemoryOptim();
int max_batch = 32;
int max_single_seq_len = 128;
int opt_single_seq_len = 64;
int min_batch_seq_len = 1;
int max_batch_seq_len = 512;
int opt_batch_seq_len = 256;
std::string input_name0 = "eval_placeholder_0";
std::string input_name1 = "eval_placeholder_1";
std::string input_name2 = "eval_placeholder_2";
std::string input_name3 = "eval_placeholder_3";
std::vector<int> min_shape = {min_batch_seq_len};
std::vector<int> max_shape = {max_batch_seq_len};
std::vector<int> opt_shape = {opt_batch_seq_len};
// Set the input's min, max, opt shape
std::map<std::string, std::vector<int>> min_input_shape = {
{input_name0, min_shape},
{input_name1, min_shape},
{input_name2, {1}},
{input_name3, {1, min_batch_seq_len, 1}}};
std::map<std::string, std::vector<int>> max_input_shape = {
{input_name0, max_shape},
{input_name1, max_shape},
{input_name2, {max_batch + 1}},
{input_name3, {1, max_single_seq_len, 1}}};
std::map<std::string, std::vector<int>> opt_input_shape = {
{input_name0, opt_shape},
{input_name1, opt_shape},
{input_name2, {max_batch + 1}},
{input_name3, {1, opt_single_seq_len, 1}}};
// only kHalf supported
config.EnableTensorRtEngine(
1 << 30, 1, 5, Config::Precision::kInt8, false, false);
// ernie varlen must be used with dynamic shape
config.SetTRTDynamicShapeInfo(
min_input_shape, max_input_shape, opt_input_shape);
// ernie varlen must be used with oss
config.EnableVarseqlen();
paddle_infer::experimental::InternalUtils::SetTransformerPosid(&config,
input_name2);
paddle_infer::experimental::InternalUtils::SetTransformerMaskid(&config,
input_name3);
return CreatePredictor(config);
}
// Parse tensor from string
template <typename T>
std::vector<T> ParseTensor(const std::string &field) {
std::string mat_str = field;
std::vector<T> mat;
paddle::test::Split(mat_str, ' ', &mat);
return mat;
}
void run(Predictor *predictor, std::vector<float> *out_data) {
clock_t start, end;
start = clock();
CHECK(predictor->Run());
end = clock();
auto output_names = predictor->GetOutputNames();
auto output_t = predictor->GetOutputHandle(output_names[0]);
std::vector<int> output_shape = output_t->shape();
int out_num = std::accumulate(
output_shape.begin(), output_shape.end(), 1, std::multiplies<int>());
out_data->resize(out_num);
output_t->CopyToCpu(out_data->data());
return;
}
auto PrepareOutput(std::string input_file) -> std::deque<float> {
std::ifstream fin(input_file);
std::string line;
std::vector<std::string> buffer;
while (std::getline(fin, line)) {
buffer.emplace_back(line);
}
std::deque<float> resDeque(buffer.size());
std::transform(buffer.begin(),
buffer.end(),
resDeque.begin(),
[](const std::string &val) { return std::stof(val); });
return resDeque;
} // PrepareOutput
TEST(tensorrt_tester_ernie_xnli, oss_varlen_truth_data_int8) {
auto resDeque = PrepareOutput(FLAGS_truth_data);
auto predictor = InitPredictor();
ASSERT_FALSE(FLAGS_datadir.empty());
std::ifstream fin(FLAGS_datadir);
std::string line;
int lineno = 0;
const int max_seq_len = 128;
const int run_batch = 1;
int correct_num = 0;
while (std::getline(fin, line)) {
std::vector<std::string> fields;
paddle::test::Split(line, ';', &fields);
auto src_ids = ParseTensor<int32_t>(fields[0]);
auto sent_ids = ParseTensor<int32_t>(fields[1]);
auto pos_ids = ParseTensor<int64_t>(fields[2]);
int run_seq_len = src_ids.size();
int32_t i3[2] = {0, run_seq_len};
int32_t i4[max_seq_len] = {0};
auto input_names = predictor->GetInputNames();
// first input
auto input_t1 = predictor->GetInputHandle(input_names[0]);
input_t1->Reshape({run_seq_len});
input_t1->CopyFromCpu(src_ids.data());
// second input
auto input_t2 = predictor->GetInputHandle(input_names[1]);
input_t2->Reshape({run_seq_len});
input_t2->CopyFromCpu(sent_ids.data());
// third input
auto input_t3 = predictor->GetInputHandle(input_names[2]);
input_t3->Reshape({run_batch + 1});
input_t3->CopyFromCpu(i3);
// fourth input
auto input_t4 = predictor->GetInputHandle(input_names[3]);
input_t4->Reshape({1, max_seq_len, 1});
input_t4->CopyFromCpu(i4);
std::vector<float> out_data;
run(predictor.get(), &out_data);
lineno++;
int maxPosition =
max_element(out_data.begin(), out_data.end()) - out_data.begin();
if (maxPosition == resDeque[0]) {
correct_num += 1;
}
resDeque.pop_front();
VLOG(2) << "predict result: " << maxPosition;
for (auto r : out_data) {
VLOG(2) << r;
}
}
ASSERT_GT(correct_num,
3855); // total input 5010, int8 res should greater than 3855
LOG(INFO) << "=== finish oss test ===";
}
} // namespace paddle_infer
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
gflags::ParseCommandLineFlags(&argc, &argv, true);
#if IS_TRT_VERSION_GE(7200)
return RUN_ALL_TESTS();
#endif
return 0;
}
+81
View File
@@ -0,0 +1,81 @@
// Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
//
// 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.
#pragma once
#include <sstream>
#include <string>
#include <vector>
namespace paddle {
namespace test {
// split string to vector<string> by sep
static void split(const std::string &str,
char sep,
std::vector<std::string> *pieces,
bool ignore_null = true) {
pieces->clear();
if (str.empty()) {
if (!ignore_null) {
pieces->push_back(str);
}
return;
}
size_t pos = 0;
size_t next = str.find(sep, pos);
while (next != std::string::npos) {
pieces->push_back(str.substr(pos, next - pos));
pos = next + 1;
next = str.find(sep, pos);
}
if (!str.substr(pos).empty()) {
pieces->push_back(str.substr(pos));
}
}
template <typename T>
void GetValueFromStream(std::stringstream *ss, T *t) {
(*ss) >> (*t);
}
template <>
void GetValueFromStream<std::string>(std::stringstream *ss, std::string *t) {
*t = ss->str();
}
// Split string to multiple vector
template <typename T>
void Split(const std::string &line, char sep, std::vector<T> *v) {
std::stringstream ss;
T t;
for (auto c : line) {
if (c != sep) {
ss << c;
} else {
GetValueFromStream<T>(&ss, &t);
v->push_back(std::move(t));
ss.str({});
ss.clear();
}
}
if (!ss.str().empty()) {
GetValueFromStream<T>(&ss, &t);
v->push_back(std::move(t));
ss.str({});
ss.clear();
}
}
} // namespace test
} // namespace paddle
@@ -0,0 +1,86 @@
// Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
//
// 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 "test_helper.h" // NOLINT
#include "test_suite.h" // NOLINT
DEFINE_string(modeldir, "", "Directory of the inference model.");
namespace paddle_infer {
paddle::test::Record PrepareInput(int batch_size, int shape_size = 224) {
// init input data
int channel = 3;
int width = shape_size; // w = 224
int height = shape_size; // h = 224
paddle::test::Record image_Record;
int input_num = batch_size * channel * width * height;
std::vector<float> input_data(input_num, 1);
image_Record.data = input_data;
image_Record.shape = std::vector<int>{batch_size, channel, width, height};
image_Record.type = paddle::PaddleDType::FLOAT32;
return image_Record;
}
TEST(tensorrt_tester_mobilenetv1, tuned_dynamic_trt_fp32_bz2) {
bool tuned_shape = true;
std::string shape_range_info = FLAGS_modeldir + "/shape_range_info.pbtxt";
LOG(INFO) << "tensorrt tuned info saved to " << shape_range_info;
// init input data
std::map<std::string, paddle::test::Record> my_input_data_map;
my_input_data_map["x"] = PrepareInput(2, 448);
// init output data
std::map<std::string, paddle::test::Record> infer_output_data,
truth_output_data;
if (tuned_shape) {
// NOTE: shape_range_info will be saved after destructor of predictor
// function
// prepare ground truth config
paddle_infer::Config tune_config;
tune_config.SetModel(FLAGS_modeldir + "/inference.pdmodel",
FLAGS_modeldir + "/inference.pdiparams");
tune_config.SwitchIrOptim(false);
tune_config.EnableUseGpu(1000, 0);
tune_config.CollectShapeRangeInfo(shape_range_info);
auto predictor_tune = paddle_infer::CreatePredictor(tune_config);
SingleThreadPrediction(
predictor_tune.get(), &my_input_data_map, &truth_output_data, 1);
}
// prepare inference config
paddle_infer::Config config;
config.SetModel(FLAGS_modeldir + "/inference.pdmodel",
FLAGS_modeldir + "/inference.pdiparams");
config.EnableUseGpu(1000, 0);
config.EnableTensorRtEngine(
1 << 20, 2, 5, paddle_infer::PrecisionType::kFloat32, false, false);
config.EnableTunedTensorRtDynamicShape(shape_range_info, true);
LOG(INFO) << config.Summary();
paddle_infer::services::PredictorPool pred_pool(config, 1);
SingleThreadPrediction(
pred_pool.Retrieve(0), &my_input_data_map, &infer_output_data);
// check outputs
CompareRecord(&truth_output_data, &infer_output_data);
VLOG(1) << "finish test";
}
} // namespace paddle_infer
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
gflags::ParseCommandLineFlags(&argc, &argv, true);
return RUN_ALL_TESTS();
}
@@ -0,0 +1,160 @@
// Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
//
// 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 "test_suite.h" // NOLINT
DEFINE_string(modeldir, "", "Directory of the inference model.");
namespace paddle_infer {
std::map<std::string, paddle::test::Record> PrepareInput(int batch_size) {
// init input data
int channel = 3;
int width = 320;
int height = 320;
paddle::test::Record image, im_shape, scale_factor;
int input_num = batch_size * channel * width * height;
int shape_num = batch_size * 2;
std::vector<float> image_data(input_num, 1);
for (int i = 1; i < input_num + 1; ++i) {
image_data[i] = i % 10 * 0.5;
}
std::vector<float> im_shape_data(shape_num, 1);
std::vector<float> scale_factor_data(shape_num, 1);
image.data = std::vector<float>(image_data.begin(), image_data.end());
image.shape = std::vector<int>{batch_size, channel, width, height};
image.type = paddle::PaddleDType::FLOAT32;
im_shape.data =
std::vector<float>(im_shape_data.begin(), im_shape_data.end());
im_shape.shape = std::vector<int>{batch_size, 2};
im_shape.type = paddle::PaddleDType::FLOAT32;
scale_factor.data =
std::vector<float>(scale_factor_data.begin(), scale_factor_data.end());
scale_factor.shape = std::vector<int>{batch_size, 2};
scale_factor.type = paddle::PaddleDType::FLOAT32;
std::map<std::string, paddle::test::Record> input_data_map;
input_data_map.insert({"image", image});
input_data_map.insert({"im_shape", im_shape});
input_data_map.insert({"scale_factor", scale_factor});
return input_data_map;
}
TEST(tensorrt_tester_ppyolo_mbv3, multi_thread4_trt_fp32_bz2) {
int thread_num = 4;
// init input data
auto input_data_map = PrepareInput(2);
// init output data
std::map<std::string, paddle::test::Record> infer_output_data,
truth_output_data;
// prepare ground truth config
paddle_infer::Config config, config_no_ir;
config_no_ir.SetModel(FLAGS_modeldir + "/model.pdmodel",
FLAGS_modeldir + "/model.pdiparams");
config_no_ir.EnableUseGpu(100, 0);
config_no_ir.SwitchIrOptim(false);
// prepare inference config
config.SetModel(FLAGS_modeldir + "/model.pdmodel",
FLAGS_modeldir + "/model.pdiparams");
config.EnableUseGpu(100, 0);
config.EnableTensorRtEngine(
1 << 25, 2, 3, paddle_infer::PrecisionType::kFloat32, false, false);
LOG(INFO) << config.Summary();
// get ground truth by disable ir
paddle_infer::services::PredictorPool pred_pool_no_ir(config_no_ir, 1);
SingleThreadPrediction(
pred_pool_no_ir.Retrieve(0), &input_data_map, &truth_output_data, 1);
// get infer results from multi threads
std::vector<std::thread> threads;
services::PredictorPool pred_pool(config, thread_num);
for (int i = 0; i < thread_num; ++i) {
threads.emplace_back(paddle::test::SingleThreadPrediction,
pred_pool.Retrieve(i),
&input_data_map,
&infer_output_data,
2);
}
// thread join & check outputs
for (int i = 0; i < thread_num; ++i) {
LOG(INFO) << "join tid : " << i;
threads[i].join();
CompareRecord(&truth_output_data, &infer_output_data, 0.18);
// TODO(OliverLPH): precision set to 1e-2 since input is fake, change to
// real input later
}
std::cout << "finish multi-thread test" << std::endl;
}
TEST(DISABLED_onednn_tester_ppyolo_mbv3, multi_thread4_mkl_bz2) {
// TODO(OliverLPH): onednn multi thread will fail
int thread_num = 4;
// init input data
auto input_data_map = PrepareInput(2);
// init output data
std::map<std::string, paddle::test::Record> infer_output_data,
truth_output_data;
// prepare ground truth config
paddle_infer::Config config, config_no_ir;
config_no_ir.SetModel(FLAGS_modeldir + "/model.pdmodel",
FLAGS_modeldir + "/model.pdiparams");
config_no_ir.DisableGpu();
config_no_ir.SwitchIrOptim(false);
// prepare inference config
config.SetModel(FLAGS_modeldir + "/model.pdmodel",
FLAGS_modeldir + "/model.pdiparams");
config.DisableGpu();
config.EnableONEDNN();
config.SetOnednnCacheCapacity(10);
config.SetCpuMathLibraryNumThreads(10);
LOG(INFO) << config.Summary();
// get ground truth by disable ir
paddle_infer::services::PredictorPool pred_pool_no_ir(config_no_ir, 1);
SingleThreadPrediction(
pred_pool_no_ir.Retrieve(0), &input_data_map, &truth_output_data, 1);
// get infer results from multi threads
std::vector<std::thread> threads;
services::PredictorPool pred_pool(config, thread_num);
for (int i = 0; i < thread_num; ++i) {
threads.emplace_back(paddle::test::SingleThreadPrediction,
pred_pool.Retrieve(i),
&input_data_map,
&infer_output_data,
2);
}
// thread join & check outputs
for (int i = 0; i < thread_num; ++i) {
LOG(INFO) << "join tid : " << i;
threads[i].join();
CompareRecord(&truth_output_data, &infer_output_data, 1e-4);
}
std::cout << "finish multi-thread test" << std::endl;
}
} // namespace paddle_infer
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
gflags::ParseCommandLineFlags(&argc, &argv, true);
return RUN_ALL_TESTS();
}
@@ -0,0 +1,168 @@
// Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
//
// 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 "test_suite.h" // NOLINT
DEFINE_string(modeldir, "", "Directory of the inference model.");
namespace paddle_infer {
std::map<std::string, paddle::test::Record> PrepareInput(int batch_size) {
// init input data
int channel = 3;
int width = 640;
int height = 640;
paddle::test::Record image, im_shape, scale_factor;
int input_num = batch_size * channel * width * height;
int shape_num = batch_size * 2;
std::vector<float> image_data(input_num, 1);
for (int i = 1; i < input_num + 1; ++i) {
image_data[i] = i % 10 * 0.5;
}
std::vector<float> im_shape_data(shape_num, 1);
std::vector<float> scale_factor_data(shape_num, 1);
image.data = std::vector<float>(image_data.begin(), image_data.end());
image.shape = std::vector<int>{batch_size, channel, width, height};
image.type = paddle::PaddleDType::FLOAT32;
im_shape.data =
std::vector<float>(im_shape_data.begin(), im_shape_data.end());
im_shape.shape = std::vector<int>{batch_size, 2};
im_shape.type = paddle::PaddleDType::FLOAT32;
scale_factor.data =
std::vector<float>(scale_factor_data.begin(), scale_factor_data.end());
scale_factor.shape = std::vector<int>{batch_size, 2};
scale_factor.type = paddle::PaddleDType::FLOAT32;
std::map<std::string, paddle::test::Record> input_data_map;
input_data_map.insert({"image", image});
input_data_map.insert({"im_shape", im_shape});
input_data_map.insert({"scale_factor", scale_factor});
return input_data_map;
}
TEST(tensorrt_tester_ppyolov2_r50vd, multi_thread2_trt_fp32_bz1) {
int thread_num = 2; // thread > 2 may OOM
// init input data
auto input_data_map = PrepareInput(1);
// init output data
std::map<std::string, paddle::test::Record> infer_output_data,
truth_output_data;
// prepare ground truth config
paddle_infer::Config config, config_no_ir;
config_no_ir.SetModel(FLAGS_modeldir + "/model.pdmodel",
FLAGS_modeldir + "/model.pdiparams");
config_no_ir.EnableUseGpu(100, 0);
config_no_ir.SwitchIrOptim(false);
// prepare inference config
config.SetModel(FLAGS_modeldir + "/model.pdmodel",
FLAGS_modeldir + "/model.pdiparams");
config.EnableUseGpu(100, 0);
config.EnableTensorRtEngine(
1 << 28, 2, 10, paddle_infer::PrecisionType::kFloat32, false, false);
std::map<std::string, std::vector<int>> input_shape;
input_shape["image"] = {1, 3, 640, 640};
input_shape["im_shape"] = {1, 2};
input_shape["scale_factor"] = {1, 2};
config.SetTRTDynamicShapeInfo(input_shape, input_shape, input_shape, false);
LOG(INFO) << config.Summary();
// get ground truth by disable ir
paddle_infer::services::PredictorPool pred_pool_no_ir(config_no_ir, 1);
SingleThreadPrediction(
pred_pool_no_ir.Retrieve(0), &input_data_map, &truth_output_data, 1);
// get infer results from multi threads
std::vector<std::thread> threads;
services::PredictorPool pred_pool(config, thread_num);
for (int i = 0; i < thread_num; ++i) {
threads.emplace_back(paddle::test::SingleThreadPrediction,
pred_pool.Retrieve(i),
&input_data_map,
&infer_output_data,
2);
}
// thread join & check outputs
for (int i = 0; i < thread_num; ++i) {
LOG(INFO) << "join tid : " << i;
threads[i].join();
// CompareRecord(&truth_output_data, &infer_output_data, 1e-2);
// TODO(OliverLPH): disable comparison since precision is low
}
std::cout << "finish multi-thread test" << std::endl;
}
// fused_softplus is about to be removed, the test uses fused_softplus and is
// disabled
/*
TEST(onednn_tester_ppyolov2_r50vd, multi_thread2_mkl_bz2) {
int thread_num = 2;
// init input data
auto input_data_map = PrepareInput(2);
// init output data
std::map<std::string, paddle::test::Record> infer_output_data,
truth_output_data;
// prepare ground truth config
paddle_infer::Config config, config_no_ir;
config_no_ir.SetModel(FLAGS_modeldir + "/model.pdmodel",
FLAGS_modeldir + "/model.pdiparams");
config_no_ir.DisableGpu();
config_no_ir.SwitchIrOptim(false);
// prepare inference config
config.SetModel(FLAGS_modeldir + "/model.pdmodel",
FLAGS_modeldir + "/model.pdiparams");
config.DisableGpu();
config.EnableONEDNN();
config.SetOnednnCacheCapacity(10);
config.SetCpuMathLibraryNumThreads(10);
LOG(INFO) << config.Summary();
// get ground truth by disable ir
paddle_infer::services::PredictorPool pred_pool_no_ir(config_no_ir, 1);
SingleThreadPrediction(
pred_pool_no_ir.Retrieve(0), &input_data_map, &truth_output_data, 1);
// get infer results from multi threads
std::vector<std::thread> threads;
services::PredictorPool pred_pool(config, thread_num);
for (int i = 0; i < thread_num; ++i) {
threads.emplace_back(paddle::test::SingleThreadPrediction,
pred_pool.Retrieve(i),
&input_data_map,
&infer_output_data,
2);
}
// thread join & check outputs
for (int i = 0; i < thread_num; ++i) {
LOG(INFO) << "join tid : " << i;
threads[i].join();
// CompareRecord(&truth_output_data, &infer_output_data, 1e-4);
// TODO(OliverLPH): disable comparison since precision is low
}
std::cout << "finish multi-thread test" << std::endl;
}
*/
} // namespace paddle_infer
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
gflags::ParseCommandLineFlags(&argc, &argv, true);
return RUN_ALL_TESTS();
}
@@ -0,0 +1,247 @@
// Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
//
// 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 "test_suite.h" // NOLINT
DEFINE_string(modeldir, "", "Directory of the inference model.");
namespace paddle_infer {
paddle::test::Record PrepareInput(int batch_size) {
// init input data
int channel = 3;
int width = 224;
int height = 224;
paddle::test::Record image_Record;
int input_num = batch_size * channel * width * height;
std::vector<float> input_data(input_num, 1);
image_Record.data = input_data;
image_Record.shape = std::vector<int>{batch_size, channel, width, height};
image_Record.type = paddle::PaddleDType::FLOAT32;
return image_Record;
}
TEST(gpu_tester_resnet50, analysis_gpu_bz1) {
// init input data
std::map<std::string, paddle::test::Record> my_input_data_map;
my_input_data_map["inputs"] = PrepareInput(1);
// init output data
std::map<std::string, paddle::test::Record> infer_output_data,
truth_output_data;
// prepare ground truth config
paddle_infer::Config config, config_no_ir;
config_no_ir.SetModel(FLAGS_modeldir + "/inference.pdmodel",
FLAGS_modeldir + "/inference.pdiparams");
config_no_ir.SwitchIrOptim(false);
// prepare inference config
config.SetModel(FLAGS_modeldir + "/inference.pdmodel",
FLAGS_modeldir + "/inference.pdiparams");
// get ground truth by disable ir
paddle_infer::services::PredictorPool pred_pool_no_ir(config_no_ir, 1);
SingleThreadPrediction(
pred_pool_no_ir.Retrieve(0), &my_input_data_map, &truth_output_data, 1);
// get infer results
paddle_infer::services::PredictorPool pred_pool(config, 1);
SingleThreadPrediction(
pred_pool.Retrieve(0), &my_input_data_map, &infer_output_data);
// check outputs
CompareRecord(&truth_output_data, &infer_output_data);
std::cout << "finish test" << std::endl;
}
TEST(tensorrt_tester_resnet50, trt_fp32_bz2) {
// init input data
std::map<std::string, paddle::test::Record> my_input_data_map;
my_input_data_map["inputs"] = PrepareInput(2);
// init output data
std::map<std::string, paddle::test::Record> infer_output_data,
truth_output_data;
// prepare ground truth config
paddle_infer::Config config, config_no_ir;
config_no_ir.SetModel(FLAGS_modeldir + "/inference.pdmodel",
FLAGS_modeldir + "/inference.pdiparams");
config_no_ir.SwitchIrOptim(false);
// prepare inference config
config.SetModel(FLAGS_modeldir + "/inference.pdmodel",
FLAGS_modeldir + "/inference.pdiparams");
config.EnableUseGpu(100, 0);
config.EnableTensorRtEngine(
1 << 20, 2, 3, paddle_infer::PrecisionType::kFloat32, false, false);
// get ground truth by disable ir
paddle_infer::services::PredictorPool pred_pool_no_ir(config_no_ir, 1);
SingleThreadPrediction(
pred_pool_no_ir.Retrieve(0), &my_input_data_map, &truth_output_data, 1);
// get infer results
paddle_infer::services::PredictorPool pred_pool(config, 1);
SingleThreadPrediction(
pred_pool.Retrieve(0), &my_input_data_map, &infer_output_data);
// check outputs
CompareRecord(&truth_output_data, &infer_output_data, 2e-4);
std::cout << "finish test" << std::endl;
}
TEST(tensorrt_tester_resnet50, serial_diff_batch_trt_fp32) {
int max_batch_size = 5;
// prepare ground truth config
paddle_infer::Config config, config_no_ir;
config_no_ir.SetModel(FLAGS_modeldir + "/inference.pdmodel",
FLAGS_modeldir + "/inference.pdiparams");
config_no_ir.SwitchIrOptim(false);
paddle_infer::services::PredictorPool pred_pool_no_ir(config_no_ir, 1);
// prepare inference config
config.SetModel(FLAGS_modeldir + "/inference.pdmodel",
FLAGS_modeldir + "/inference.pdiparams");
config.EnableUseGpu(100, 0);
config.EnableTensorRtEngine(1 << 20,
max_batch_size,
3,
paddle_infer::PrecisionType::kFloat32,
false,
false);
paddle_infer::services::PredictorPool pred_pool(config, 1);
for (int i = 1; i < max_batch_size; i++) {
// init input data
std::map<std::string, paddle::test::Record> my_input_data_map;
my_input_data_map["inputs"] = PrepareInput(i);
// init output data
std::map<std::string, paddle::test::Record> infer_output_data,
truth_output_data;
// get ground truth by disable ir
SingleThreadPrediction(
pred_pool_no_ir.Retrieve(0), &my_input_data_map, &truth_output_data, 1);
// get infer results
SingleThreadPrediction(
pred_pool.Retrieve(0), &my_input_data_map, &infer_output_data);
// check outputs
CompareRecord(&truth_output_data, &infer_output_data, 1e-4);
}
std::cout << "finish test" << std::endl;
}
TEST(tensorrt_tester_resnet50, multi_thread4_trt_fp32_bz2) {
int thread_num = 4;
// init input data
std::map<std::string, paddle::test::Record> my_input_data_map;
my_input_data_map["inputs"] = PrepareInput(2);
// init output data
std::map<std::string, paddle::test::Record> infer_output_data,
truth_output_data;
// prepare ground truth config
paddle_infer::Config config, config_no_ir;
config_no_ir.SetModel(FLAGS_modeldir + "/inference.pdmodel",
FLAGS_modeldir + "/inference.pdiparams");
config_no_ir.SwitchIrOptim(false);
// prepare inference config
config.SetModel(FLAGS_modeldir + "/inference.pdmodel",
FLAGS_modeldir + "/inference.pdiparams");
config.EnableUseGpu(100, 0);
config.EnableTensorRtEngine(
1 << 20, 2, 3, paddle_infer::PrecisionType::kFloat32, false, false);
// get ground truth by disable ir
paddle_infer::services::PredictorPool pred_pool_no_ir(config_no_ir, 1);
SingleThreadPrediction(
pred_pool_no_ir.Retrieve(0), &my_input_data_map, &truth_output_data, 1);
// get infer results from multi threads
std::vector<std::thread> threads;
services::PredictorPool pred_pool(config, thread_num);
for (int i = 0; i < thread_num; ++i) {
threads.emplace_back(paddle::test::SingleThreadPrediction,
pred_pool.Retrieve(i),
&my_input_data_map,
&infer_output_data,
2);
}
// thread join & check outputs
for (int i = 0; i < thread_num; ++i) {
LOG(INFO) << "join tid : " << i;
threads[i].join();
CompareRecord(&truth_output_data, &infer_output_data, 2e-4);
}
std::cout << "finish multi-thread test" << std::endl;
}
TEST(tensorrt_tester_resnet50, trt_int8_bz2) {
// init input data
std::map<std::string, paddle::test::Record> my_input_data_map;
my_input_data_map["inputs"] = PrepareInput(2);
// init output data
std::map<std::string, paddle::test::Record> infer_output_data,
truth_output_data;
// prepare inference config
paddle_infer::Config config;
config.SetModel(FLAGS_modeldir + "/inference.pdmodel",
FLAGS_modeldir + "/inference.pdiparams");
config.EnableUseGpu(100, 0);
config.EnableTensorRtEngine(
1 << 20, 2, 3, paddle_infer::PrecisionType::kInt8, true, true);
// get first time prediction int8 results
paddle_infer::services::PredictorPool pred_pool(config, 1);
SingleThreadPrediction(
pred_pool.Retrieve(0), &my_input_data_map, &truth_output_data, 1);
// get repeat 5 times prediction int8 results
SingleThreadPrediction(
pred_pool.Retrieve(0), &my_input_data_map, &infer_output_data, 5);
// check outputs
CompareRecord(&truth_output_data, &infer_output_data);
std::cout << "finish test" << std::endl;
}
TEST(DISABLED_tensorrt_tester_resnet50, profile_multi_thread_trt_fp32) {
int batch_size = 2;
int thread_num = 4;
int repeat_time = 1000;
// init input data
std::map<std::string, paddle::test::Record> my_input_data_map;
my_input_data_map["inputs"] = PrepareInput(batch_size);
// init output data
std::map<std::string, paddle::test::Record> infer_output_data;
// prepare inference config
paddle_infer::Config config;
config.SetModel(FLAGS_modeldir + "/inference.pdmodel",
FLAGS_modeldir + "/inference.pdiparams");
config.EnableUseGpu(100, 0);
config.EnableTensorRtEngine(
1 << 20, 2, 3, paddle_infer::PrecisionType::kFloat32, false, false);
// get infer results from multi threads
services::PredictorPool pred_pool(config, thread_num);
std::vector<std::future<double>> calcs;
for (int i = 0; i < thread_num; ++i) {
calcs.push_back(std::async(&paddle::test::SingleThreadProfile,
pred_pool.Retrieve(i),
&my_input_data_map,
repeat_time));
}
double total_time_ = 0.0;
for (auto&& fut : calcs) {
total_time_ += fut.get();
}
std::cout << total_time_ << std::endl;
std::cout << "finish multi-thread profile" << std::endl;
}
} // namespace paddle_infer
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
gflags::ParseCommandLineFlags(&argc, &argv, true);
return RUN_ALL_TESTS();
}
@@ -0,0 +1,176 @@
// Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
//
// 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 "test_suite.h" // NOLINT
DEFINE_string(modeldir, "", "Directory of the inference model.");
DEFINE_string(int8dir, "", "Directory of the quant inference model.");
DEFINE_string(datadir, "", "Directory of the infer data.");
namespace paddle_infer {
paddle::test::Record PrepareInput(int batch_size) {
// init input data
int channel = 3;
int width = 224;
int height = 224;
paddle::test::Record image_Record;
int input_num = batch_size * channel * width * height;
// load from binary data
std::ifstream fs(FLAGS_datadir, std::ifstream::binary);
EXPECT_TRUE(fs.is_open());
CHECK(fs.is_open());
float* input = new float[input_num];
memset(input, 0, input_num * sizeof(float));
auto input_data_tmp = input;
for (int i = 0; i < input_num; ++i) {
fs.read(reinterpret_cast<char*>(input_data_tmp), sizeof(*input_data_tmp));
input_data_tmp++;
}
int label = 0;
fs.read(reinterpret_cast<char*>(&label), sizeof(label));
fs.close();
std::vector<float> input_data{input, input + input_num};
image_Record.data = input_data;
image_Record.shape = std::vector<int>{batch_size, channel, width, height};
image_Record.type = paddle::PaddleDType::FLOAT32;
image_Record.label = label;
return image_Record;
}
TEST(DISABLED_tensorrt_tester_resnet50_quant, multi_thread4_trt_int8_bz1) {
int thread_num = 4;
// init input data
std::map<std::string, paddle::test::Record> input_data_map;
input_data_map["image"] = PrepareInput(1);
// init output data
std::map<std::string, paddle::test::Record> infer_output_data;
// prepare inference config
paddle_infer::Config config;
config.SetModel(FLAGS_int8dir);
config.EnableUseGpu(1000, 0);
config.EnableTensorRtEngine(
1 << 20, 10, 3, paddle_infer::PrecisionType::kInt8, false, false);
// get infer results from multi threads
std::vector<std::thread> threads;
services::PredictorPool pred_pool(config, thread_num);
for (int i = 0; i < thread_num; ++i) {
threads.emplace_back(paddle::test::SingleThreadPrediction,
pred_pool.Retrieve(i),
&input_data_map,
&infer_output_data,
5);
}
// thread join & check outputs
for (int i = 0; i < thread_num; ++i) {
LOG(INFO) << "join tid : " << i;
threads[i].join();
// check outputs
std::vector<int> index(1000);
std::iota(index.begin(), index.end(), 0);
auto out_data =
infer_output_data["save_infer_model/scale_0.tmp_0"].data.data();
std::sort(index.begin(), index.end(), [out_data](size_t i1, size_t i2) {
return out_data[i1] > out_data[i2];
});
// compare inference & ground truth label
ASSERT_EQ(index[0], input_data_map["image"].label);
}
std::cout << "finish test" << std::endl;
}
TEST(DISABLED_tensorrt_tester_resnet50_quant, multi_thread_multi_instance) {
int thread_num = 4;
// init input data
std::map<std::string, paddle::test::Record> input_data_fp32, input_data_quant;
input_data_quant["image"] = PrepareInput(1);
input_data_fp32["inputs"] = PrepareInput(1);
// init output data
std::map<std::string, paddle::test::Record> infer_output_data;
// prepare inference config
paddle_infer::Config config_fp32, config_quant;
config_fp32.SetModel(FLAGS_modeldir + "/inference.pdmodel",
FLAGS_modeldir + "/inference.pdiparams");
config_fp32.EnableUseGpu(1000, 0);
config_fp32.EnableTensorRtEngine(
1 << 20, 10, 3, paddle_infer::PrecisionType::kFloat32, false, false);
config_quant.SetModel(FLAGS_int8dir);
config_quant.EnableUseGpu(1000, 0);
config_quant.EnableTensorRtEngine(
1 << 20, 10, 3, paddle_infer::PrecisionType::kInt8, false, false);
// get infer results from multi threads
std::vector<std::thread> threads;
services::PredictorPool pred_pool_fp32(config_fp32, thread_num);
services::PredictorPool pred_pool_quant(config_quant, thread_num);
for (int i = 0; i < thread_num; ++i) {
if (i % 2 == 0) {
threads.emplace_back(paddle::test::SingleThreadPrediction,
pred_pool_fp32.Retrieve(i),
&input_data_fp32,
&infer_output_data,
5);
} else {
threads.emplace_back(paddle::test::SingleThreadPrediction,
pred_pool_quant.Retrieve(i),
&input_data_quant,
&infer_output_data,
5);
}
}
// thread join & check outputs
for (int i = 0; i < thread_num; ++i) {
LOG(INFO) << "join tid : " << i;
std::vector<int> index(1000);
threads[i].join();
if (i % 2 == 0) {
// check outputs
std::iota(index.begin(), index.end(), 0);
auto out_data =
infer_output_data["save_infer_model/scale_0.tmp_0"].data.data();
std::sort(index.begin(), index.end(), [out_data](size_t i1, size_t i2) {
return out_data[i1] > out_data[i2];
});
// compare inference & ground truth label
ASSERT_EQ(index[0], input_data_fp32["inputs"].label);
} else {
// check outputs
std::iota(index.begin(), index.end(), 0);
auto out_data =
infer_output_data["save_infer_model/scale_0.tmp_0"].data.data();
std::sort(index.begin(), index.end(), [out_data](size_t i1, size_t i2) {
return out_data[i1] > out_data[i2];
});
// compare inference & ground truth label
ASSERT_EQ(index[0], input_data_quant["image"].label);
}
}
}
} // namespace paddle_infer
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
gflags::ParseCommandLineFlags(&argc, &argv, true);
return RUN_ALL_TESTS();
}
+260
View File
@@ -0,0 +1,260 @@
// Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
//
// 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.
#pragma once
#include <math.h>
#include <algorithm>
#include <deque>
#include <fstream>
#include <future>
#include <iostream>
#include <numeric>
#include <string>
#include <thread>
#include <vector>
#include "gflags/gflags.h"
#include "glog/logging.h"
#include "gtest/gtest.h"
#include "paddle/include/paddle_inference_api.h"
namespace paddle {
namespace test {
#define IS_TRT_VERSION_GE(version) \
((NV_TENSORRT_MAJOR * 1000 + NV_TENSORRT_MINOR * 100 + \
NV_TENSORRT_PATCH * 10 + NV_TENSORRT_BUILD) >= version)
#define IS_TRT_VERSION_LT(version) \
((NV_TENSORRT_MAJOR * 1000 + NV_TENSORRT_MINOR * 100 + \
NV_TENSORRT_PATCH * 10 + NV_TENSORRT_BUILD) < version)
#define TRT_VERSION \
NV_TENSORRT_MAJOR * 1000 + NV_TENSORRT_MINOR * 100 + \
NV_TENSORRT_PATCH * 10 + NV_TENSORRT_BUILD
class Record {
public:
std::vector<float> data;
std::vector<int32_t> shape;
paddle::PaddleDType type;
int label;
};
std::string read_file(std::string filename) {
std::ifstream file(filename);
return std::string((std::istreambuf_iterator<char>(file)),
std::istreambuf_iterator<char>());
}
void SingleThreadPrediction(paddle_infer::Predictor *predictor,
std::map<std::string, Record> *input_data_map,
std::map<std::string, Record> *output_data_map,
int repeat_times = 2) {
// prepare input tensor
auto input_names = predictor->GetInputNames();
for (const auto &[key, value] : *input_data_map) {
switch (value.type) {
case paddle::PaddleDType::INT64: {
std::vector<int64_t> input_value =
std::vector<int64_t>(value.data.begin(), value.data.end());
auto input_tensor = predictor->GetInputHandle(key);
input_tensor->Reshape(value.shape);
input_tensor->CopyFromCpu(input_value.data());
break;
}
case paddle::PaddleDType::INT32: {
std::vector<int32_t> input_value =
std::vector<int32_t>(value.data.begin(), value.data.end());
auto input_tensor = predictor->GetInputHandle(key);
input_tensor->Reshape(value.shape);
input_tensor->CopyFromCpu(input_value.data());
break;
}
case paddle::PaddleDType::FLOAT32: {
std::vector<float> input_value =
std::vector<float>(value.data.begin(), value.data.end());
auto input_tensor = predictor->GetInputHandle(key);
input_tensor->Reshape(value.shape);
input_tensor->CopyFromCpu(input_value.data());
break;
}
}
}
// inference
for (size_t i = 0; i < repeat_times; ++i) {
ASSERT_TRUE(predictor->Run());
}
// get output data to Record
auto output_names = predictor->GetOutputNames();
for (auto &output_name : output_names) {
Record output_Record;
auto output_tensor = predictor->GetOutputHandle(output_name);
std::vector<int> output_shape = output_tensor->shape();
int out_num = std::accumulate(
output_shape.begin(), output_shape.end(), 1, std::multiplies<int>());
switch (output_tensor->type()) {
case paddle::PaddleDType::INT64: {
VLOG(1) << "output_tensor dtype: int64";
std::vector<int64_t> out_data;
output_Record.type = paddle::PaddleDType::INT64;
out_data.resize(out_num);
output_tensor->CopyToCpu(out_data.data());
output_Record.shape = output_shape;
std::vector<float> floatVec(out_data.begin(), out_data.end());
output_Record.data = floatVec;
(*output_data_map)[output_name] = output_Record;
break;
}
case paddle::PaddleDType::FLOAT32: {
VLOG(1) << "output_tensor dtype: float32";
std::vector<float> out_data;
output_Record.type = paddle::PaddleDType::FLOAT32;
out_data.resize(out_num);
output_tensor->CopyToCpu(out_data.data());
output_Record.shape = output_shape;
output_Record.data = out_data;
(*output_data_map)[output_name] = output_Record;
break;
}
case paddle::PaddleDType::INT32: {
VLOG(1) << "output_tensor dtype: int32";
std::vector<int32_t> out_data;
output_Record.type = paddle::PaddleDType::INT32;
out_data.resize(out_num);
output_tensor->CopyToCpu(out_data.data());
output_Record.shape = output_shape;
std::vector<float> floatVec(out_data.begin(), out_data.end());
output_Record.data = floatVec;
(*output_data_map)[output_name] = output_Record;
break;
}
}
}
}
void CompareRecord(std::map<std::string, Record> *truth_output_data,
std::map<std::string, Record> *infer_output_data,
float epsilon = 1e-5) {
for (const auto &[key, value] : *infer_output_data) {
auto truth_record = (*truth_output_data)[key];
VLOG(1) << "output name: " << key;
size_t numel = value.data.size() / sizeof(float);
EXPECT_EQ(value.data.size(), truth_record.data.size());
for (size_t i = 0; i < numel; ++i) {
VLOG(1) << "compare: " << value.data.data()[i] << ",\t"
<< truth_record.data.data()[i];
ASSERT_LT(fabs(value.data.data()[i] - truth_record.data.data()[i]),
epsilon);
}
}
}
// Timer, count in ms
class Timer {
public:
Timer() { reset(); }
void start() { start_t = std::chrono::high_resolution_clock::now(); }
void stop() {
auto end_t = std::chrono::high_resolution_clock::now();
typedef std::chrono::microseconds ms;
auto diff = end_t - start_t;
ms counter = std::chrono::duration_cast<ms>(diff);
total_time += counter.count();
}
void reset() { total_time = 0.; }
double report() { return total_time / 1000.0; }
private:
double total_time;
std::chrono::high_resolution_clock::time_point start_t;
};
// single thread inference benchmark, return double time in ms
double SingleThreadProfile(paddle_infer::Predictor *predictor,
std::map<std::string, Record> *input_data_map,
int repeat_times = 2) {
// prepare input tensor
auto input_names = predictor->GetInputNames();
for (const auto &[key, value] : *input_data_map) {
switch (value.type) {
case paddle::PaddleDType::INT64: {
std::vector<int64_t> input_value =
std::vector<int64_t>(value.data.begin(), value.data.end());
auto input_tensor = predictor->GetInputHandle(key);
input_tensor->Reshape(value.shape);
input_tensor->CopyFromCpu(input_value.data());
break;
}
case paddle::PaddleDType::INT32: {
std::vector<int32_t> input_value =
std::vector<int32_t>(value.data.begin(), value.data.end());
auto input_tensor = predictor->GetInputHandle(key);
input_tensor->Reshape(value.shape);
input_tensor->CopyFromCpu(input_value.data());
break;
}
case paddle::PaddleDType::FLOAT32: {
std::vector<float> input_value =
std::vector<float>(value.data.begin(), value.data.end());
auto input_tensor = predictor->GetInputHandle(key);
input_tensor->Reshape(value.shape);
input_tensor->CopyFromCpu(input_value.data());
break;
}
}
}
Timer timer; // init prediction timer
timer.start();
// inference
for (size_t i = 0; i < repeat_times; ++i) {
CHECK(predictor->Run());
auto output_names = predictor->GetOutputNames();
for (auto &output_name : output_names) {
auto output_tensor = predictor->GetOutputHandle(output_name);
std::vector<int> output_shape = output_tensor->shape();
int out_num = std::accumulate(
output_shape.begin(), output_shape.end(), 1, std::multiplies<int>());
switch (output_tensor->type()) {
case paddle::PaddleDType::INT64: {
std::vector<int64_t> out_data;
out_data.resize(out_num);
output_tensor->CopyToCpu(out_data.data());
break;
}
case paddle::PaddleDType::FLOAT32: {
std::vector<float> out_data;
out_data.resize(out_num);
output_tensor->CopyToCpu(out_data.data());
break;
}
case paddle::PaddleDType::INT32: {
std::vector<int32_t> out_data;
out_data.resize(out_num);
output_tensor->CopyToCpu(out_data.data());
break;
}
}
}
}
timer.stop();
return timer.report();
}
} // namespace test
} // namespace paddle
+159
View File
@@ -0,0 +1,159 @@
// Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
//
// 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 "test_suite.h" // NOLINT
DEFINE_string(modeldir, "", "Directory of the inference model.");
namespace paddle_infer {
std::map<std::string, paddle::test::Record> PrepareInput(int batch_size) {
// init input data
int channel = 3;
int width = 608;
int height = 608;
paddle::test::Record image, im_shape, scale_factor;
int input_num = batch_size * channel * width * height;
int shape_num = batch_size * 2;
std::vector<float> image_data(input_num, 1);
for (int i = 1; i < input_num + 1; ++i) {
image_data[i] = i % 10 * 0.5;
}
std::vector<float> im_shape_data(shape_num, 1);
std::vector<float> scale_factor_data(shape_num, 1);
image.data = std::vector<float>(image_data.begin(), image_data.end());
image.shape = std::vector<int>{batch_size, channel, width, height};
image.type = paddle::PaddleDType::FLOAT32;
im_shape.data =
std::vector<float>(im_shape_data.begin(), im_shape_data.end());
im_shape.shape = std::vector<int>{batch_size, 2};
im_shape.type = paddle::PaddleDType::FLOAT32;
scale_factor.data =
std::vector<float>(scale_factor_data.begin(), scale_factor_data.end());
scale_factor.shape = std::vector<int>{batch_size, 2};
scale_factor.type = paddle::PaddleDType::FLOAT32;
std::map<std::string, paddle::test::Record> input_data_map;
input_data_map.insert({"image", image});
input_data_map.insert({"im_shape", im_shape});
input_data_map.insert({"scale_factor", scale_factor});
return input_data_map;
}
TEST(test_yolov3, multi_thread3_trt_fp32_bz2) {
int thread_num = 3;
// init input data
auto input_data_map = PrepareInput(2);
// init output data
std::map<std::string, paddle::test::Record> infer_output_data,
truth_output_data;
// prepare ground truth config
paddle_infer::Config config, config_no_ir;
config_no_ir.SetModel(FLAGS_modeldir + "/model.pdmodel",
FLAGS_modeldir + "/model.pdiparams");
config_no_ir.EnableUseGpu(100, 0);
config_no_ir.SwitchIrOptim(false);
// prepare inference config
config.SetModel(FLAGS_modeldir + "/model.pdmodel",
FLAGS_modeldir + "/model.pdiparams");
config.EnableUseGpu(100, 0);
config.EnableTensorRtEngine(
1 << 20, 2, 3, paddle_infer::PrecisionType::kFloat32, false, false);
LOG(INFO) << config.Summary();
// get ground truth by disable ir
paddle_infer::services::PredictorPool pred_pool_no_ir(config_no_ir, 1);
SingleThreadPrediction(
pred_pool_no_ir.Retrieve(0), &input_data_map, &truth_output_data, 1);
// get infer results from multi threads
std::vector<std::thread> threads;
services::PredictorPool pred_pool(config, thread_num);
for (int i = 0; i < thread_num; ++i) {
threads.emplace_back(paddle::test::SingleThreadPrediction,
pred_pool.Retrieve(i),
&input_data_map,
&infer_output_data,
2);
}
// thread join & check outputs
for (int i = 0; i < thread_num; ++i) {
LOG(INFO) << "join tid : " << i;
threads[i].join();
CompareRecord(&truth_output_data, &infer_output_data, 1e-2);
// TODO(OliverLPH): precision set to 1e-2 since input is fake, change to
// real input later
}
std::cout << "finish multi-thread test" << std::endl;
}
TEST(test_yolov3, multi_thread4_mkl_bz2) {
int thread_num = 4;
// init input data
auto input_data_map = PrepareInput(2);
// init output data
std::map<std::string, paddle::test::Record> infer_output_data,
truth_output_data;
// prepare ground truth config
paddle_infer::Config config, config_no_ir;
config_no_ir.SetModel(FLAGS_modeldir + "/model.pdmodel",
FLAGS_modeldir + "/model.pdiparams");
config_no_ir.DisableGpu();
config_no_ir.SwitchIrOptim(false);
// prepare inference config
config.SetModel(FLAGS_modeldir + "/model.pdmodel",
FLAGS_modeldir + "/model.pdiparams");
config.DisableGpu();
config.EnableONEDNN();
config.SetOnednnCacheCapacity(10);
config.SetCpuMathLibraryNumThreads(10);
LOG(INFO) << config.Summary();
// get ground truth by disable ir
paddle_infer::services::PredictorPool pred_pool_no_ir(config_no_ir, 1);
SingleThreadPrediction(
pred_pool_no_ir.Retrieve(0), &input_data_map, &truth_output_data, 1);
// get infer results from multi threads
std::vector<std::thread> threads;
services::PredictorPool pred_pool(config, thread_num);
for (int i = 0; i < thread_num; ++i) {
threads.emplace_back(paddle::test::SingleThreadPrediction,
pred_pool.Retrieve(i),
&input_data_map,
&infer_output_data,
2);
}
// thread join & check outputs
for (int i = 0; i < thread_num; ++i) {
LOG(INFO) << "join tid : " << i;
threads[i].join();
CompareRecord(&truth_output_data, &infer_output_data, 1e-4);
}
std::cout << "finish multi-thread test" << std::endl;
}
} // namespace paddle_infer
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
gflags::ParseCommandLineFlags(&argc, &argv, true);
return RUN_ALL_TESTS();
}