1*523fa7a6SAndroid Build Coastguard Worker /* 2*523fa7a6SAndroid Build Coastguard Worker * Copyright (c) Meta Platforms, Inc. and affiliates. 3*523fa7a6SAndroid Build Coastguard Worker * All rights reserved. 4*523fa7a6SAndroid Build Coastguard Worker * 5*523fa7a6SAndroid Build Coastguard Worker * This source code is licensed under the BSD-style license found in the 6*523fa7a6SAndroid Build Coastguard Worker * LICENSE file in the root directory of this source tree. 7*523fa7a6SAndroid Build Coastguard Worker */ 8*523fa7a6SAndroid Build Coastguard Worker 9*523fa7a6SAndroid Build Coastguard Worker #pragma once 10*523fa7a6SAndroid Build Coastguard Worker 11*523fa7a6SAndroid Build Coastguard Worker #include <functional> 12*523fa7a6SAndroid Build Coastguard Worker #include <memory> 13*523fa7a6SAndroid Build Coastguard Worker #include <mutex> 14*523fa7a6SAndroid Build Coastguard Worker 15*523fa7a6SAndroid Build Coastguard Worker #include <pthreadpool.h> 16*523fa7a6SAndroid Build Coastguard Worker 17*523fa7a6SAndroid Build Coastguard Worker namespace executorch::extension::threadpool { 18*523fa7a6SAndroid Build Coastguard Worker 19*523fa7a6SAndroid Build Coastguard Worker class ThreadPool final { 20*523fa7a6SAndroid Build Coastguard Worker public: 21*523fa7a6SAndroid Build Coastguard Worker explicit ThreadPool(size_t thread_count = 0); 22*523fa7a6SAndroid Build Coastguard Worker ~ThreadPool() = default; 23*523fa7a6SAndroid Build Coastguard Worker 24*523fa7a6SAndroid Build Coastguard Worker // Make threadpool non copyable 25*523fa7a6SAndroid Build Coastguard Worker // Non-copyable: threadpool cannot be copied because it will 26*523fa7a6SAndroid Build Coastguard Worker // effectively require cloning of threadpool. 27*523fa7a6SAndroid Build Coastguard Worker // Cloning can be done by just calling create_thread_pool. 28*523fa7a6SAndroid Build Coastguard Worker ThreadPool(const ThreadPool&) = delete; 29*523fa7a6SAndroid Build Coastguard Worker ThreadPool& operator=(const ThreadPool&) = delete; 30*523fa7a6SAndroid Build Coastguard Worker 31*523fa7a6SAndroid Build Coastguard Worker // Make threadpool non-movable. 32*523fa7a6SAndroid Build Coastguard Worker ThreadPool(ThreadPool&&) = delete; 33*523fa7a6SAndroid Build Coastguard Worker ThreadPool& operator=(ThreadPool&&) = delete; 34*523fa7a6SAndroid Build Coastguard Worker 35*523fa7a6SAndroid Build Coastguard Worker size_t get_thread_count() const; 36*523fa7a6SAndroid Build Coastguard Worker 37*523fa7a6SAndroid Build Coastguard Worker /** 38*523fa7a6SAndroid Build Coastguard Worker * INTERNAL: Resets the threadpool by creating a new threadpool with requested 39*523fa7a6SAndroid Build Coastguard Worker * # of threads. This is not a thread safe call. When calling this method, 40*523fa7a6SAndroid Build Coastguard Worker * threads of the threadpool might be doing some work. Some other code may 41*523fa7a6SAndroid Build Coastguard Worker * also be holding on to the threadpool pointer, that is no longer valid. This 42*523fa7a6SAndroid Build Coastguard Worker * is a private API, which will later be replaced by something that allows 43*523fa7a6SAndroid Build Coastguard Worker * creating of threadpool with requested size and use such a threadpool with 44*523fa7a6SAndroid Build Coastguard Worker * backend delegates, custom ops or optimized lib. 45*523fa7a6SAndroid Build Coastguard Worker */ 46*523fa7a6SAndroid Build Coastguard Worker [[deprecated("This API is experimental and may change without notice.")]] 47*523fa7a6SAndroid Build Coastguard Worker bool _unsafe_reset_threadpool(uint32_t num_threads); 48*523fa7a6SAndroid Build Coastguard Worker 49*523fa7a6SAndroid Build Coastguard Worker /** 50*523fa7a6SAndroid Build Coastguard Worker * Run, in parallel, function fn(task_id) over task_id in range [0, range). 51*523fa7a6SAndroid Build Coastguard Worker * This function is blocking. All input is processed by the time it returns. 52*523fa7a6SAndroid Build Coastguard Worker * NoThreadPoolGuard (see threadpool_guard.h) can used to disable use of 53*523fa7a6SAndroid Build Coastguard Worker * multiple threads with the scope of the guard When NoThreadPoolGuard is not 54*523fa7a6SAndroid Build Coastguard Worker * used all calls to run method are serialized. 55*523fa7a6SAndroid Build Coastguard Worker */ 56*523fa7a6SAndroid Build Coastguard Worker void run(const std::function<void(size_t)>& fn, size_t range); 57*523fa7a6SAndroid Build Coastguard Worker 58*523fa7a6SAndroid Build Coastguard Worker private: 59*523fa7a6SAndroid Build Coastguard Worker friend pthreadpool_t get_pthreadpool(); 60*523fa7a6SAndroid Build Coastguard Worker 61*523fa7a6SAndroid Build Coastguard Worker private: 62*523fa7a6SAndroid Build Coastguard Worker // This mutex is used inside get_thread_count API but it is not really needed 63*523fa7a6SAndroid Build Coastguard Worker // since data members of ThreadPool objects are not really mutable. 64*523fa7a6SAndroid Build Coastguard Worker // TODO(kimishpatel): Figure out if we will allow set_num_threads API, in 65*523fa7a6SAndroid Build Coastguard Worker // which case this mutex will be useful. Otherwise remove it. 66*523fa7a6SAndroid Build Coastguard Worker mutable std::mutex mutex_; 67*523fa7a6SAndroid Build Coastguard Worker std::unique_ptr<pthreadpool, decltype(&pthreadpool_destroy)> threadpool_; 68*523fa7a6SAndroid Build Coastguard Worker }; 69*523fa7a6SAndroid Build Coastguard Worker 70*523fa7a6SAndroid Build Coastguard Worker /** 71*523fa7a6SAndroid Build Coastguard Worker * Returns the singleton instance of ThreadPool for ATen/TH multithreading. 72*523fa7a6SAndroid Build Coastguard Worker */ 73*523fa7a6SAndroid Build Coastguard Worker ThreadPool* get_threadpool(); 74*523fa7a6SAndroid Build Coastguard Worker 75*523fa7a6SAndroid Build Coastguard Worker /** 76*523fa7a6SAndroid Build Coastguard Worker * Returns the underlying pthreadpool instance used by the implementation of 77*523fa7a6SAndroid Build Coastguard Worker * ThreadPool returned by `get_threadpool()`. Only for use in external libraries 78*523fa7a6SAndroid Build Coastguard Worker * so as to unify threading across internal (i.e. ATen, etc.) and external (e.g. 79*523fa7a6SAndroid Build Coastguard Worker * NNPACK, QNNPACK, XNNPACK) use cases. 80*523fa7a6SAndroid Build Coastguard Worker */ 81*523fa7a6SAndroid Build Coastguard Worker pthreadpool_t get_pthreadpool(); 82*523fa7a6SAndroid Build Coastguard Worker 83*523fa7a6SAndroid Build Coastguard Worker } // namespace executorch::extension::threadpool 84*523fa7a6SAndroid Build Coastguard Worker 85*523fa7a6SAndroid Build Coastguard Worker namespace torch::executorch::threadpool { // DEPRECATED 86*523fa7a6SAndroid Build Coastguard Worker // TODO(T197294990): Remove these deprecated aliases once all users have moved 87*523fa7a6SAndroid Build Coastguard Worker // to the new `::executorch` namespaces. Note that threadpool incorrectly used 88*523fa7a6SAndroid Build Coastguard Worker // the namespace `torch::executorch` instead of `torch::executor`. 89*523fa7a6SAndroid Build Coastguard Worker using ::executorch::extension::threadpool::get_pthreadpool; // DEPRECATED 90*523fa7a6SAndroid Build Coastguard Worker using ::executorch::extension::threadpool::get_threadpool; // DEPRECATED 91*523fa7a6SAndroid Build Coastguard Worker using ::executorch::extension::threadpool::ThreadPool; // DEPRECATED 92*523fa7a6SAndroid Build Coastguard Worker } // namespace torch::executorch::threadpool 93