From a26696fb0e3b3d7f911dc60d037cf06df98674ed Mon Sep 17 00:00:00 2001 From: Changming Sun Date: Thu, 21 Mar 2019 15:53:06 -0700 Subject: [PATCH] Enable LTO on Linux --- cmake/CMakeLists.txt | 22 +++++++++++++++++++ cmake/onnxruntime_unittests.cmake | 3 +++ .../core/session/onnxruntime_cxx_api.h | 4 ++-- onnxruntime/core/framework/cblas.h | 3 +-- .../framework/session_state_initializer.cc | 2 +- onnxruntime/core/platform/posix/ort_mutex.cc | 8 +++---- .../cuda/math/binary_elementwise_ops.h | 2 +- onnxruntime/core/session/onnxruntime_c_api.cc | 5 ++++- onnxruntime/test/onnx/TestCase.cc | 4 ++-- .../test/providers/cpu/controlflow/if_test.cc | 2 ++ .../providers/cpu/controlflow/loop_test.cc | 3 ++- onnxruntime/test/util/compare_mlvalue.cc | 2 +- .../linux/docker/scripts/install_deps.sh | 2 ++ tools/ci_build/github/linux/run_build.sh | 8 +++---- .../ci_build/github/linux/run_dockerbuild.sh | 10 +++++---- 15 files changed, 56 insertions(+), 24 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index a684f3909c..b423aa956c 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -6,6 +6,9 @@ cmake_minimum_required(VERSION 3.11) # Project project(onnxruntime C CXX) +cmake_policy(SET CMP0069 NEW) +set(CMAKE_POLICY_DEFAULT_CMP0069 NEW) + include(CheckCXXCompilerFlag) include(CheckLanguage) @@ -65,6 +68,7 @@ option(onnxruntime_ENABLE_MICROSOFT_INTERNAL "Use this option to enable/disable option(onnxruntime_USE_NUPHAR "Build with Nupha" OFF) option(onnxruntime_USE_BRAINSLICE "Build with BrainSlice" OFF) option(onnxruntime_USE_TENSORRT "Build with TensorRT support" OFF) +option(onnxruntime_ENABLE_LTO "Enable link time optimization, which is not stable on older GCCs" OFF) option(onnxruntime_CROSS_COMPILING "Cross compiling onnx runtime" OFF) option(onnxruntime_USE_FULL_PROTOBUF "Use full protobuf" OFF) @@ -73,6 +77,24 @@ set(protobuf_BUILD_TESTS OFF CACHE BOOL "Build protobuf tests" FORCE) set(NSYNC_ENABLE_TESTS OFF CACHE BOOL "Build protobuf tests" FORCE) set(ONNX_ML 1) +if(onnxruntime_ENABLE_LTO) + #LTO(or LTCG) is great, in our case it can reduce binary size by 1/3. + #cmake can only help us check if the compiler support LTO or not, it can't tell us if the feature works well + #Don't enable this option in Ubuntu 16.04, protoc will crash + include(CheckIPOSupported) + check_ipo_supported(RESULT ipo_enabled OUTPUT ipo_output) + #TODO: figure out why nsync doesn't work + if(NOT onnxruntime_USE_NSYNC) + if(ipo_enabled) + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE ON) + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO ON) + else() + message(WARNING "IPO is not supported: ${ipo_output}") + endif() + endif() +endif() + + set(REPO_ROOT ${PROJECT_SOURCE_DIR}/..) set(ONNXRUNTIME_ROOT ${PROJECT_SOURCE_DIR}/../onnxruntime) file (STRINGS "${REPO_ROOT}/VERSION_NUMBER" VERSION_NUMBER) diff --git a/cmake/onnxruntime_unittests.cmake b/cmake/onnxruntime_unittests.cmake index 6fece97154..8f01aa6840 100644 --- a/cmake/onnxruntime_unittests.cmake +++ b/cmake/onnxruntime_unittests.cmake @@ -315,12 +315,15 @@ endif() # SingleUnitTestProject # standalone test for inference session without environment # the normal test executables set up a default runtime environment, which we don't want here +if(NOT ipo_enabled) + #TODO: figure out why this test doesn't work with gcc LTO AddTest( TARGET onnxruntime_test_framework_session_without_environment_standalone SOURCES "${TEST_SRC_DIR}/framework/inference_session_without_environment/inference_session_without_environment_standalone_test.cc" "${TEST_SRC_DIR}/framework/test_main.cc" LIBS onnxruntime_test_utils ${ONNXRUNTIME_TEST_LIBS} DEPENDS ${onnxruntime_EXTERNAL_DEPENDENCIES} ) +endif() # # onnxruntime_ir_graph test data diff --git a/include/onnxruntime/core/session/onnxruntime_cxx_api.h b/include/onnxruntime/core/session/onnxruntime_cxx_api.h index 14cfc7d599..dffd51e764 100644 --- a/include/onnxruntime/core/session/onnxruntime_cxx_api.h +++ b/include/onnxruntime/core/session/onnxruntime_cxx_api.h @@ -117,13 +117,13 @@ class SessionOptionsWrapper { } #ifdef _WIN32 OrtSession* OrtCreateSession(_In_ const wchar_t* model_path) { - OrtSession* ret; + OrtSession* ret = nullptr; ORT_THROW_ON_ERROR(::OrtCreateSession(env_, model_path, value.get(), &ret)); return ret; } #else OrtSession* OrtCreateSession(_In_ const char* model_path) { - OrtSession* ret; + OrtSession* ret = nullptr; ORT_THROW_ON_ERROR(::OrtCreateSession(env_, model_path, value.get(), &ret)); return ret; } diff --git a/onnxruntime/core/framework/cblas.h b/onnxruntime/core/framework/cblas.h index c3752807bc..1df6fa3329 100644 --- a/onnxruntime/core/framework/cblas.h +++ b/onnxruntime/core/framework/cblas.h @@ -13,8 +13,7 @@ enum CBLAS_ORDER { CblasRowMajor = 101, enum CBLAS_TRANSPOSE { CblasNoTrans = 111, CblasTrans = 112, - CblasConjTrans = 113, - AtlasConj = 114 + CblasConjTrans = 113 }; enum CBLAS_UPLO { CblasUpper = 121, CblasLower = 122 }; diff --git a/onnxruntime/core/framework/session_state_initializer.cc b/onnxruntime/core/framework/session_state_initializer.cc index a4020d3399..ab72323c49 100644 --- a/onnxruntime/core/framework/session_state_initializer.cc +++ b/onnxruntime/core/framework/session_state_initializer.cc @@ -327,7 +327,7 @@ common::Status SaveInitializedTensors(const Env& env, const std::basic_string(*entry.second, &len)); ORT_RETURN_IF_ERROR(planner.TraceAllocation(entry.first, len)); } diff --git a/onnxruntime/core/platform/posix/ort_mutex.cc b/onnxruntime/core/platform/posix/ort_mutex.cc index e98ed7bd9d..23a195145c 100644 --- a/onnxruntime/core/platform/posix/ort_mutex.cc +++ b/onnxruntime/core/platform/posix/ort_mutex.cc @@ -57,7 +57,7 @@ OrtCondVar::~OrtCondVar() { void OrtCondVar::notify_one() noexcept { #ifdef USE_NSYNC - nsync_cv_signal(&native_cv_object); + nsync::nsync_cv_signal(&native_cv_object); #else pthread_cond_signal(&native_cv_object); #endif @@ -65,7 +65,7 @@ void OrtCondVar::notify_one() noexcept { void OrtCondVar::notify_all() noexcept { #ifdef USE_NSYNC - nsync_cv_broadcast(&native_cv_object); + nsync::nsync_cv_broadcast(&native_cv_object); #else pthread_cond_broadcast(&native_cv_object); #endif @@ -75,7 +75,7 @@ void OrtCondVar::wait(std::unique_lock& lk) { if (!lk.owns_lock()) throw std::runtime_error("OrtCondVar wait failed: mutex not locked"); #ifdef USE_NSYNC - nsync_cv_wait(&native_cv_object, lk.mutex()->native_handle()); + nsync::nsync_cv_wait(&native_cv_object, lk.mutex()->native_handle()); #else int ec = pthread_cond_wait(&native_cv_object, lk.mutex()->native_handle()); if (ec) { @@ -106,7 +106,7 @@ void OrtCondVar::timed_wait_impl(std::unique_lock& lk, abs_deadline.tv_nsec = 999999999; } #ifdef USE_NSYNC - nsync_cv_wait_with_deadline(&native_cv_object, lk.mutex()->native_handle(), abs_deadline, nullptr); + nsync::nsync_cv_wait_with_deadline(&native_cv_object, lk.mutex()->native_handle(), abs_deadline, nullptr); #else int ec = pthread_cond_timedwait(&native_cv_object, lk.mutex()->native_handle(), &abs_deadline); if (ec != 0 && ec != ETIMEDOUT) { diff --git a/onnxruntime/core/providers/cuda/math/binary_elementwise_ops.h b/onnxruntime/core/providers/cuda/math/binary_elementwise_ops.h index 347e1261b7..f595797ee0 100644 --- a/onnxruntime/core/providers/cuda/math/binary_elementwise_ops.h +++ b/onnxruntime/core/providers/cuda/math/binary_elementwise_ops.h @@ -58,7 +58,7 @@ struct BinaryElementwisePreparation { // When N > 1: out[id] = op(lhs[id], rhs[id / H % C]) if (lhs_shape == output_shape) { const auto& rhs_dims = rhs_shape.GetDims(); - int64_t C; + int64_t C = 0; if (1 == std::count_if(rhs_dims.begin(), rhs_dims.end(), [&C](int64_t dim) { if (dim > 1) C = dim; return (dim > 1); })) { auto dim_C = std::find(rhs_dims.begin(), rhs_dims.end(), C) - rhs_dims.begin() + output_shape.NumDimensions() - rhs_shape.NumDimensions(); int64_t N = output_shape.SizeToDimension(dim_C); diff --git a/onnxruntime/core/session/onnxruntime_c_api.cc b/onnxruntime/core/session/onnxruntime_c_api.cc index 01264fd010..4f881da3c6 100644 --- a/onnxruntime/core/session/onnxruntime_c_api.cc +++ b/onnxruntime/core/session/onnxruntime_c_api.cc @@ -126,8 +126,11 @@ ORT_API_STATUS_IMPL(OrtCreateEnv, OrtLoggingLevel default_warning_level, &name); std::unique_ptr env; Status status = Environment::Create(env); - if (status.IsOK()) + if (status.IsOK()) { *out = new OrtEnv(env.release(), default_logging_manager.release()); + return nullptr; + } + *out = nullptr; return ToOrtStatus(status); API_IMPL_END } diff --git a/onnxruntime/test/onnx/TestCase.cc b/onnxruntime/test/onnx/TestCase.cc index 69841d71f0..2911a7c880 100644 --- a/onnxruntime/test/onnx/TestCase.cc +++ b/onnxruntime/test/onnx/TestCase.cc @@ -458,9 +458,9 @@ Status OnnxTestCase::ParseModel() { Status st = Status::OK(); std::call_once(model_parsed_, [this, &st]() { //parse model - ONNX_NAMESPACE::ModelProto* model_pb; + ONNX_NAMESPACE::ModelProto* model_pb = nullptr; st = loadModelFile(model_url_.c_str(), &model_pb); - if (!st.IsOK()) return; + if (!st.IsOK() || model_pb == nullptr) return; const ONNX_NAMESPACE::GraphProto& graph = model_pb->graph(); if (graph.node().size() == 1) { node_name_ = graph.node()[0].op_type(); diff --git a/onnxruntime/test/providers/cpu/controlflow/if_test.cc b/onnxruntime/test/providers/cpu/controlflow/if_test.cc index b2a1386c2e..db1b60a316 100644 --- a/onnxruntime/test/providers/cpu/controlflow/if_test.cc +++ b/onnxruntime/test/providers/cpu/controlflow/if_test.cc @@ -16,12 +16,14 @@ using namespace ONNX_NAMESPACE; namespace onnxruntime { namespace test { +namespace { struct RunOptions { bool include_dim_values_in_main_graph = false; int symbolic_dim_value_in_main_graph = -1; bool include_dim_values_in_subgraph = true; bool mixed_execution_providers = false; }; +} static const ONNX_NAMESPACE::GraphProto CreateSubgraph(bool then_branch, const RunOptions& options); diff --git a/onnxruntime/test/providers/cpu/controlflow/loop_test.cc b/onnxruntime/test/providers/cpu/controlflow/loop_test.cc index 2ce588944f..adbe4099fc 100644 --- a/onnxruntime/test/providers/cpu/controlflow/loop_test.cc +++ b/onnxruntime/test/providers/cpu/controlflow/loop_test.cc @@ -17,13 +17,14 @@ using namespace ONNX_NAMESPACE; namespace onnxruntime { namespace test { +namespace { struct RunOptions { bool include_dim_values_in_main_graph = true; bool include_dim_values_in_subgraph = false; bool include_types_in_subgraph = false; bool mixed_execution_providers = false; }; - +} static const ONNX_NAMESPACE::GraphProto CreateSubgraph(const RunOptions& options); static const float kOuterNodeAddValue = 3.f; diff --git a/onnxruntime/test/util/compare_mlvalue.cc b/onnxruntime/test/util/compare_mlvalue.cc index bc5a348b52..001c037637 100644 --- a/onnxruntime/test/util/compare_mlvalue.cc +++ b/onnxruntime/test/util/compare_mlvalue.cc @@ -355,7 +355,7 @@ std::pair VerifyValueInfo(const ONNX_NAMESPACE::Val //} std::unique_ptr info; { - OrtTensorTypeAndShapeInfo* t1; + OrtTensorTypeAndShapeInfo* t1 = nullptr; ORT_THROW_ON_ERROR(OrtGetTensorShapeAndType(o, &t1)); info.reset(t1); } diff --git a/tools/ci_build/github/linux/docker/scripts/install_deps.sh b/tools/ci_build/github/linux/docker/scripts/install_deps.sh index 0a0ce75df4..9e13d559ca 100755 --- a/tools/ci_build/github/linux/docker/scripts/install_deps.sh +++ b/tools/ci_build/github/linux/docker/scripts/install_deps.sh @@ -65,5 +65,7 @@ tar -jxf /tmp/src/eigen-eigen-323c052e1731.tar.bz2 -C /usr/include mv /usr/include/eigen-eigen-323c052e1731 /usr/include/eigen3 rm -rf /tmp/src +rm -rf /usr/include/google +rm -rf /usr/lib/libproto* diff --git a/tools/ci_build/github/linux/run_build.sh b/tools/ci_build/github/linux/run_build.sh index 497187e2e8..c948d90d33 100755 --- a/tools/ci_build/github/linux/run_build.sh +++ b/tools/ci_build/github/linux/run_build.sh @@ -15,17 +15,16 @@ done if [ $BUILD_DEVICE = "gpu" ]; then _CUDNN_VERSION=$(echo $CUDNN_VERSION | cut -d. -f1-2) - python3 $SCRIPT_DIR/../../build.py --build_dir /home/onnxruntimedev \ + python3 $SCRIPT_DIR/../../build.py --build_dir /build \ --config Debug Release \ --skip_submodule_sync --enable_onnx_tests \ --parallel --build_shared_lib \ --use_cuda --use_openmp \ --cuda_home /usr/local/cuda \ --cudnn_home /usr/local/cudnn-$_CUDNN_VERSION/cuda --build_shared_lib $BUILD_EXTR_PAR - /home/onnxruntimedev/Release/onnx_test_runner -e cuda /data/onnx elif [ $BUILD_DEVICE = "tensorrt" ]; then _CUDNN_VERSION=$(echo $CUDNN_VERSION | cut -d. -f1-2) - python3 $SCRIPT_DIR/../../build.py --build_dir /home/onnxruntimedev \ + python3 $SCRIPT_DIR/../../build.py --build_dir /build \ --config Release \ --enable_onnx_tests \ --parallel --build_shared_lib \ @@ -34,10 +33,9 @@ elif [ $BUILD_DEVICE = "tensorrt" ]; then --cuda_home /usr/local/cuda \ --cudnn_home /usr/local/cuda --build_shared_lib $BUILD_EXTR_PAR else - python3 $SCRIPT_DIR/../../build.py --build_dir /home/onnxruntimedev \ + python3 $SCRIPT_DIR/../../build.py --build_dir /build \ --config Debug Release --build_shared_lib \ --skip_submodule_sync --enable_onnx_tests \ --build_wheel \ --parallel --use_openmp --build_shared_lib $BUILD_EXTR_PAR - /home/onnxruntimedev/Release/onnx_test_runner /data/onnx fi diff --git a/tools/ci_build/github/linux/run_dockerbuild.sh b/tools/ci_build/github/linux/run_dockerbuild.sh index fe94183310..629eeb78a2 100755 --- a/tools/ci_build/github/linux/run_dockerbuild.sh +++ b/tools/ci_build/github/linux/run_dockerbuild.sh @@ -49,15 +49,16 @@ else fi set +e - +mkdir -p ~/.cache/onnxruntime +mkdir -p ~/.onnx if [ $BUILD_DEVICE = "cpu" ]; then docker rm -f "onnxruntime-$BUILD_DEVICE" || true docker run -h $HOSTNAME \ - --rm \ --name "onnxruntime-$BUILD_DEVICE" \ --volume "$SOURCE_ROOT:/onnxruntime_src" \ - --volume "$BUILD_DIR:/home/onnxruntimedev" \ + --volume "$BUILD_DIR:/build" \ --volume "$HOME/.cache/onnxruntime:/home/onnxruntimedev/.cache/onnxruntime" \ + --volume "$HOME/.onnx:/home/onnxruntimedev/.onnx" \ "onnxruntime-$IMAGE" \ /bin/bash /onnxruntime_src/tools/ci_build/github/linux/run_build.sh \ -d $BUILD_DEVICE -x "$BUILD_EXTR_PAR" & @@ -67,8 +68,9 @@ else --rm \ --name "onnxruntime-$BUILD_DEVICE" \ --volume "$SOURCE_ROOT:/onnxruntime_src" \ - --volume "$BUILD_DIR:/home/onnxruntimedev" \ + --volume "$BUILD_DIR:/build" \ --volume "$HOME/.cache/onnxruntime:/home/onnxruntimedev/.cache/onnxruntime" \ + --volume "$HOME/.onnx:/home/onnxruntimedev/.onnx" \ "onnxruntime-$IMAGE" \ /bin/bash /onnxruntime_src/tools/ci_build/github/linux/run_build.sh \ -d $BUILD_DEVICE -x "$BUILD_EXTR_PAR" &