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