[Runtime] Enable option to use OpenMP thread pool (#4089)
This commit is contained in:
Родитель
9b3a424a91
Коммит
740f61f2c1
|
@ -32,6 +32,7 @@ tvm_option(USE_LLVM "Build with LLVM, can be set to specific llvm-config path" O
|
|||
tvm_option(USE_STACKVM_RUNTIME "Include stackvm into the runtime" OFF)
|
||||
tvm_option(USE_GRAPH_RUNTIME "Build with tiny graph runtime" ON)
|
||||
tvm_option(USE_GRAPH_RUNTIME_DEBUG "Build with tiny graph runtime debug mode" OFF)
|
||||
tvm_option(USE_OPENMP "Build with OpenMP thread pool implementation" OFF)
|
||||
tvm_option(USE_SGX "Build with SGX" OFF)
|
||||
tvm_option(USE_RTTI "Build with RTTI" ON)
|
||||
tvm_option(USE_MSVC_MT "Build with MT" OFF)
|
||||
|
@ -187,6 +188,7 @@ include(cmake/modules/VTA.cmake)
|
|||
include(cmake/modules/CUDA.cmake)
|
||||
include(cmake/modules/OpenCL.cmake)
|
||||
include(cmake/modules/OpenGL.cmake)
|
||||
include(cmake/modules/OpenMP.cmake)
|
||||
include(cmake/modules/Vulkan.cmake)
|
||||
include(cmake/modules/Metal.cmake)
|
||||
include(cmake/modules/ROCM.cmake)
|
||||
|
|
|
@ -105,6 +105,10 @@ set(USE_BLAS none)
|
|||
# set(USE_MKL_PATH ../IntelSWTools/compilers_and_libraries_2018/windows/mkl) for WIN32
|
||||
set(USE_MKL_PATH none)
|
||||
|
||||
# Whether use OpenMP thread pool, choices: gnu, intel
|
||||
# Note: "gnu" uses gomp library, "intel" uses iomp5 library
|
||||
set(USE_OPENMP none)
|
||||
|
||||
# Whether use contrib.random in runtime
|
||||
set(USE_RANDOM OFF)
|
||||
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you 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.
|
||||
|
||||
# OpenMP Module
|
||||
if(USE_OPENMP STREQUAL "gnu")
|
||||
find_package(OpenMP)
|
||||
if(OPENMP_FOUND)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
|
||||
list(APPEND TVM_RUNTIME_LINKER_LIBS ${OpenMP_CXX_LIBRARIES})
|
||||
add_definitions(-DTVM_THREADPOOL_USE_OPENMP=1)
|
||||
message(STATUS "Build with OpenMP ${OpenMP_CXX_LIBRARIES}")
|
||||
else()
|
||||
add_definitions(-DTVM_THREADPOOL_USE_OPENMP=0)
|
||||
message(WARNING "OpenMP cannot be found, use TVM threadpool instead.")
|
||||
endif()
|
||||
elseif(USE_OPENMP STREQUAL "intel")
|
||||
find_package(OpenMP)
|
||||
if(OPENMP_FOUND)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
|
||||
if (MSVC)
|
||||
find_library(OMP_LIBRARY NAMES libiomp5md)
|
||||
else()
|
||||
find_library(OMP_LIBRARY NAMES iomp5)
|
||||
endif()
|
||||
list(APPEND TVM_RUNTIME_LINKER_LIBS ${OMP_LIBRARY})
|
||||
add_definitions(-DTVM_THREADPOOL_USE_OPENMP=1)
|
||||
message(STATUS "Build with OpenMP " ${OMP_LIBRARY})
|
||||
else()
|
||||
add_definitions(-DTVM_THREADPOOL_USE_OPENMP=0)
|
||||
message(WARNING "OpenMP cannot be found, use TVM threadpool instead.")
|
||||
endif()
|
||||
else()
|
||||
add_definitions(-DTVM_THREADPOOL_USE_OPENMP=0)
|
||||
endif()
|
|
@ -10,6 +10,9 @@
|
|||
#include <tvm/runtime/threading_backend.h>
|
||||
#include <dmlc/thread_local.h>
|
||||
#include <dmlc/logging.h>
|
||||
#if TVM_THREADPOOL_USE_OPENMP
|
||||
#include <omp.h>
|
||||
#endif
|
||||
#include <thread>
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
|
@ -358,12 +361,34 @@ int TVMBackendParallelLaunch(
|
|||
FTVMParallelLambda flambda,
|
||||
void* cdata,
|
||||
int num_task) {
|
||||
#if !TVM_THREADPOOL_USE_OPENMP
|
||||
int res = tvm::runtime::ThreadPool::ThreadLocal()->Launch(
|
||||
flambda, cdata, num_task, 1);
|
||||
return res;
|
||||
#else
|
||||
int num_workers = tvm::runtime::threading::MaxConcurrency();
|
||||
if (num_task == 0) num_task = num_workers;
|
||||
omp_set_num_threads(num_workers);
|
||||
#pragma omp parallel num_threads(num_workers)
|
||||
{
|
||||
TVMParallelGroupEnv env;
|
||||
env.num_task = num_task;
|
||||
std::atomic<int32_t>* sync_counter = new std::atomic<int>[num_task * tvm::runtime::kSyncStride];
|
||||
for (int i = 0; i < num_task; ++i) {
|
||||
sync_counter[i * tvm::runtime::kSyncStride].store(
|
||||
0, std::memory_order_relaxed);
|
||||
}
|
||||
env.sync_handle = sync_counter;
|
||||
(*flambda)(omp_get_thread_num(), &env, cdata);
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int TVMBackendParallelBarrier(int task_id, TVMParallelGroupEnv* penv) {
|
||||
#if TVM_THREADPOOL_USE_OPENMP
|
||||
#pragma omp barrier
|
||||
#else
|
||||
using tvm::runtime::kSyncStride;
|
||||
int num_task = penv->num_task;
|
||||
std::atomic<int>* sync_counter =
|
||||
|
@ -379,5 +404,6 @@ int TVMBackendParallelBarrier(int task_id, TVMParallelGroupEnv* penv) {
|
|||
}
|
||||
}
|
||||
std::atomic_thread_fence(std::memory_order_acquire);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче