1 /////////////////////////////////////////////////////////////////////////////// 2 // Copyright (c) 2016 Thomas Heller 3 // 4 // Distributed under the Boost Software License, Version 1.0. (See accompanying 5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 /////////////////////////////////////////////////////////////////////////////// 7 8 #include <hpx/compute/host/numa_domains.hpp> 9 #include <hpx/compute/host/target.hpp> 10 #include <hpx/runtime.hpp> 11 #include <hpx/runtime/get_os_thread_count.hpp> 12 #include <hpx/runtime/resource/detail/partitioner.hpp> 13 #include <hpx/runtime/threads/threadmanager.hpp> 14 #include <hpx/runtime/threads/topology.hpp> 15 16 #include <cstddef> 17 #include <vector> 18 19 namespace hpx { namespace compute { namespace host 20 { numa_domains()21 std::vector<target> numa_domains() 22 { 23 auto const& topo = hpx::threads::get_topology(); 24 25 std::size_t numa_nodes = topo.get_number_of_numa_nodes(); 26 if (numa_nodes == 0) 27 numa_nodes = topo.get_number_of_sockets(); 28 std::vector<hpx::threads::mask_type> node_masks(numa_nodes); 29 30 auto& rp = hpx::resource::get_partitioner(); 31 32 std::size_t num_os_threads = hpx::get_os_thread_count(); 33 for (std::size_t num_thread = 0; num_thread != num_os_threads; 34 ++num_thread) 35 { 36 std::size_t pu_num = rp.get_pu_num(num_thread); 37 std::size_t numa_node = topo.get_numa_node_number(pu_num); 38 39 auto const& mask = topo.get_thread_affinity_mask(pu_num); 40 41 std::size_t mask_size = hpx::threads::mask_size(mask); 42 for (std::size_t idx = 0; idx != mask_size; ++idx) 43 { 44 if (hpx::threads::test(mask, idx)) 45 { 46 hpx::threads::set(node_masks[numa_node], idx); 47 } 48 } 49 } 50 51 // Sort out the masks which don't have any bits set 52 std::vector<target> res; 53 res.reserve(numa_nodes); 54 55 for (auto& mask : node_masks) 56 { 57 if (hpx::threads::any(mask)) 58 { 59 res.push_back(target(mask)); 60 } 61 } 62 63 return res; 64 } 65 }}} 66