Parallel-inl.h 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. #pragma once
  2. #include <c10/util/Exception.h>
  3. #include <c10/util/SmallVector.h>
  4. namespace at {
  5. template <class F>
  6. inline void parallel_for(
  7. const int64_t begin,
  8. const int64_t end,
  9. const int64_t grain_size,
  10. const F& f) {
  11. TORCH_INTERNAL_ASSERT_DEBUG_ONLY(grain_size >= 0);
  12. if (begin >= end) {
  13. return;
  14. }
  15. #ifdef INTRA_OP_PARALLEL
  16. at::internal::lazy_init_num_threads();
  17. const auto numiter = end - begin;
  18. const bool use_parallel = (
  19. numiter > grain_size && numiter > 1 &&
  20. !at::in_parallel_region() &&
  21. at::get_num_threads() > 1);
  22. if (!use_parallel) {
  23. internal::ThreadIdGuard tid_guard(0);
  24. f(begin, end);
  25. return;
  26. }
  27. internal::invoke_parallel(begin, end, grain_size, f);
  28. #else
  29. internal::ThreadIdGuard tid_guard(0);
  30. f(begin, end);
  31. #endif
  32. }
  33. template <class scalar_t, class F, class SF>
  34. inline scalar_t parallel_reduce(
  35. const int64_t begin,
  36. const int64_t end,
  37. const int64_t grain_size,
  38. const scalar_t ident,
  39. const F& f,
  40. const SF& sf) {
  41. TORCH_CHECK(grain_size >= 0);
  42. if (begin >= end) {
  43. return ident;
  44. }
  45. #ifdef INTRA_OP_PARALLEL
  46. at::internal::lazy_init_num_threads();
  47. const auto max_threads = at::get_num_threads();
  48. const bool use_parallel = (
  49. (end - begin) > grain_size &&
  50. !at::in_parallel_region() &&
  51. max_threads > 1);
  52. if (!use_parallel) {
  53. internal::ThreadIdGuard tid_guard(0);
  54. return f(begin, end, ident);
  55. }
  56. c10::SmallVector<scalar_t, 64> results(max_threads, ident);
  57. internal::invoke_parallel(begin, end, grain_size,
  58. [&](const int64_t my_begin, const int64_t my_end) {
  59. const auto tid = at::get_thread_num();
  60. results[tid] = f(my_begin, my_end, ident);
  61. }
  62. );
  63. scalar_t result = ident;
  64. for (auto partial_result : results) {
  65. result = sf(result, partial_result);
  66. }
  67. return result;
  68. #else
  69. internal::ThreadIdGuard tid_guard(0);
  70. return f(begin, end, ident);
  71. #endif
  72. }
  73. } // namespace at