|
24 | 24 | #include <dmlc/thread_local.h> |
25 | 25 | #include <tvm/runtime/c_backend_api.h> |
26 | 26 | #include <tvm/runtime/c_runtime_api.h> |
| 27 | +#include <tvm/runtime/container/array.h> |
27 | 28 | #include <tvm/runtime/logging.h> |
28 | 29 | #include <tvm/runtime/packed_func.h> |
29 | 30 | #include <tvm/runtime/registry.h> |
|
42 | 43 | #include <thread> |
43 | 44 | #include <vector> |
44 | 45 |
|
| 46 | +#include "../support/utils.h" |
45 | 47 | const constexpr int kL1CacheBytes = 64; |
46 | 48 |
|
47 | 49 | namespace tvm { |
48 | 50 | namespace runtime { |
49 | 51 | namespace { |
50 | | - |
| 52 | +using support::IsNumber; |
51 | 53 | constexpr uint32_t kDefaultSpinCount = 300000; |
52 | 54 |
|
53 | 55 | uint32_t GetSpinCount() { |
@@ -317,10 +319,11 @@ class ThreadPool { |
317 | 319 |
|
318 | 320 | static ThreadPool* ThreadLocal() { return dmlc::ThreadLocalStore<ThreadPool>::Get(); } |
319 | 321 |
|
320 | | - void UpdateWorkerConfiguration(threading::ThreadGroup::AffinityMode mode, int nthreads) { |
| 322 | + void UpdateWorkerConfiguration(threading::ThreadGroup::AffinityMode mode, int nthreads, |
| 323 | + const std::vector<unsigned int>& cpus) { |
321 | 324 | // this will also reset the affinity of the ThreadGroup |
322 | 325 | // may use less than the MaxConcurrency number of workers |
323 | | - num_workers_used_ = threads_->Configure(mode, nthreads, exclude_worker0_); |
| 326 | + num_workers_used_ = threads_->Configure(mode, nthreads, exclude_worker0_, cpus); |
324 | 327 | // if MaxConcurrency restricted the number of workers (e.g., due to |
325 | 328 | // hyperthreading), respect the restriction |
326 | 329 | num_workers_used_ = std::min(num_workers_, num_workers_used_); |
@@ -369,17 +372,42 @@ class ThreadPool { |
369 | 372 | std::unique_ptr<tvm::runtime::threading::ThreadGroup> threads_; |
370 | 373 | }; |
371 | 374 |
|
| 375 | +/*! |
| 376 | + * \brief args[0] is the AffinityMode, args[1] is the number of threads. |
| 377 | + * args2 is a list of CPUs which is used to set the CPU affinity. |
| 378 | + */ |
372 | 379 | TVM_REGISTER_GLOBAL("runtime.config_threadpool").set_body([](TVMArgs args, TVMRetValue* rv) { |
373 | 380 | threading::ThreadGroup::AffinityMode mode = |
374 | 381 | static_cast<threading::ThreadGroup::AffinityMode>(static_cast<int>(args[0])); |
375 | 382 | int nthreads = args[1]; |
376 | | - ThreadPool::ThreadLocal()->UpdateWorkerConfiguration(mode, nthreads); |
| 383 | + std::vector<unsigned int> cpus; |
| 384 | + if (args.num_args >= 3) { |
| 385 | + Array<String> cpu_array = args[2]; |
| 386 | + for (auto cpu : cpu_array) { |
| 387 | + ICHECK(IsNumber(cpu)) << "The CPU core information '" << cpu << "' is not a number."; |
| 388 | + cpus.push_back(std::stoi(cpu)); |
| 389 | + std::cout << "cpu is " << cpu << std::endl; |
| 390 | + } |
| 391 | + } |
| 392 | + threading::Configure(mode, nthreads, cpus); |
377 | 393 | }); |
378 | 394 |
|
379 | 395 | namespace threading { |
380 | 396 | void ResetThreadPool() { tvm::runtime::ThreadPool::ThreadLocal()->Reset(); } |
| 397 | +/*! |
| 398 | + * \brief configure the CPU id affinity |
| 399 | + * \param mode The preferred CPU type (1 = big, -1 = little, -2 = specify , |
| 400 | + * -3 = kSpecifyOneCorePerThread, -3 = kSpecifyThreadShareAllCore). |
| 401 | + * \param nthreads The number of threads to use (0 = use all). |
| 402 | + * \param cpus cpus A list of CPUs is used to set the 'cpu affinity' for the worker threads. |
| 403 | + * |
| 404 | + */ |
| 405 | +void Configure(tvm::runtime::threading::ThreadGroup::AffinityMode mode, int nthreads, |
| 406 | + std::vector<unsigned int> cpus) { |
| 407 | + tvm::runtime::threading::SetMaxConcurrency(cpus.size()); |
| 408 | + tvm::runtime::ThreadPool::ThreadLocal()->UpdateWorkerConfiguration(mode, nthreads, cpus); |
| 409 | +} |
381 | 410 | } // namespace threading |
382 | | - |
383 | 411 | } // namespace runtime |
384 | 412 | } // namespace tvm |
385 | 413 |
|
|
0 commit comments