FlashGraph-ng
A new frontier in large-scale graph analysis and data mining
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Pages
NUMA_mapper.h
1 #ifndef __NUMA_MAPPER_H__
2 #define __NUMA_MAPPER_H__
3 
4 /*
5  * Copyright 2014 Open Connectome Project (http://openconnecto.me)
6  * Written by Da Zheng (zhengda1936@gmail.com)
7  *
8  * This file is part of FlashMatrix.
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  */
22 
23 #include <stdlib.h>
24 #include <math.h>
25 #include <assert.h>
26 
27 #include <vector>
28 
29 /*
30  * This class maps elements in a container to multiple physical containers.
31  * The number of physical containers has to be 2^n.
32  * It's mainly used for distributing data to multiple NUMA nodes.
33  */
34 class NUMA_mapper
35 {
36  const size_t range_size_log;
37  const size_t range_size;
38  const size_t range_mask;
39 
40  const size_t numa_log;
41  const size_t numa_mask;
42 public:
43  NUMA_mapper(size_t num_nodes, size_t range_size_log);
44 
45  size_t get_num_nodes() const {
46  return 1 << numa_log;
47  }
48 
49  size_t get_range_size() const {
50  return range_size;
51  }
52 
53  size_t get_logical_range_id(size_t idx) const {
54  return idx >> range_size_log;
55  }
56 
57  /*
58  * This function maps the logical location in the vector to the physical
59  * location of the data. This function is a little expensive if it's
60  * invoked for every element.
61  */
62  std::pair<int, size_t> map2physical(size_t idx) const {
63  size_t tmp_idx = idx >> range_size_log;
64  size_t range_idx = idx & range_mask;
65  int node_id = tmp_idx & numa_mask;
66  tmp_idx = tmp_idx >> numa_log;
67  return std::pair<int, size_t>(node_id,
68  (tmp_idx << range_size_log) + range_idx);
69  }
70 
71  /*
72  * This method maps the offset in a raw array to the logical location
73  * in the vector.
74  */
75  size_t map2logical(int node_id, size_t local_off) const {
76  size_t off_in_range = local_off & range_mask;
77  size_t range_id = local_off >> range_size_log;
78  // The number of elements in the previous ranges on all NUMA nodes.
79  return range_id * range_size * get_num_nodes()
80  // The number of elements in the same range but on the NUMA nodes
81  // in front of the current node.
82  + range_size * node_id
83  // The number of elements in this range on the same NUMA node.
84  + off_in_range;
85  }
86 
87  /*
88  * Given the number of elements, this method calculates the number of
89  * elements assigned to each NUMA node.
90  */
91  std::vector<size_t> cal_local_lengths(size_t len) const;
92 
93  bool operator!=(const NUMA_mapper &map) const {
94  return this->numa_log != map.numa_log;
95  }
96 };
97 
98 #endif