PLASMA  2.4.5
PLASMA - Parallel Linear Algebra for Scalable Multi-core Architectures
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
plasmaos-hwloc.c
Go to the documentation of this file.
1 
16 #include <stdlib.h>
17 
18 #ifdef __cplusplus
19 extern "C" {
20 #endif
21 
22 #ifdef PLASMA_HWLOC
23 
24 #include <hwloc.h>
25 
26 static hwloc_topology_t plasma_topology = NULL; /* Topology object */
27 static volatile int plasma_nbr = 0;
28 
30 
31  pthread_mutex_lock(&mutextopo);
32  if (!topo_initialized) {
33 
34  /* Allocate and initialize topology object. */
35  hwloc_topology_init(&plasma_topology);
36 
37  /* Perform the topology detection. */
38  hwloc_topology_load(plasma_topology);
39 
40  /* Get the number of cores (We don't want to use HyperThreading */
41  sys_corenbr = hwloc_get_nbobjs_by_type(plasma_topology, HWLOC_OBJ_CORE);
42 
43  topo_initialized = 1;
44  }
45  plasma_nbr++;
46  pthread_mutex_unlock(&mutextopo);
47 }
48 
50 
52 
53  pthread_mutex_lock(&mutextopo);
54  plasma_nbr--;
55  if ((topo_initialized ==1) && (plasma_nbr == 0)) {
56  /* Destroy tpology */
57  hwloc_topology_destroy(plasma_topology);
58 
59  topo_initialized = 0;
60  }
61  pthread_mutex_unlock(&mutextopo);
62 }
63 
73 int plasma_setaffinity(int rank) {
74  hwloc_obj_t obj; /* Hwloc object */
75  hwloc_cpuset_t cpuset; /* HwLoc cpuset */
76 
77  if (!topo_initialized) {
78  plasma_error("plasma_setaffinity", "Topology not initialized");
79  return PLASMA_ERR_UNEXPECTED;
80  }
81 
82  /* Get last one. */
83  obj = hwloc_get_obj_by_type(plasma_topology, HWLOC_OBJ_CORE, rank);
84  if (!obj)
85  return PLASMA_ERR_UNEXPECTED;
86 
87  /* Get a copy of its cpuset that we may modify. */
88  /* Get only one logical processor (in case the core is SMT/hyperthreaded). */
89 #if !defined(HWLOC_BITMAP_H)
90  cpuset = hwloc_cpuset_dup(obj->cpuset);
91  hwloc_cpuset_singlify(cpuset);
92 #else
93  cpuset = hwloc_bitmap_dup(obj->cpuset);
94  hwloc_bitmap_singlify(cpuset);
95 #endif
96 
97  /* And try to bind ourself there. */
98  if (hwloc_set_cpubind(plasma_topology, cpuset, HWLOC_CPUBIND_THREAD)) {
99  char *str = NULL;
100 #if !defined(HWLOC_BITMAP_H)
101  hwloc_cpuset_asprintf(&str, obj->cpuset);
102 #else
103  hwloc_bitmap_asprintf(&str, obj->cpuset);
104 #endif
105  printf("Couldn't bind to cpuset %s\n", str);
106  free(str);
107  return PLASMA_ERR_UNEXPECTED;
108  }
109 
110  /* Get the number at Proc level ( We don't want to use HyperThreading ) */
111  rank = obj->children[0]->os_index;
112 
113  /* Free our cpuset copy */
114 #if !defined(HWLOC_BITMAP_H)
115  hwloc_cpuset_free(cpuset);
116 #else
117  hwloc_bitmap_free(cpuset);
118 #endif
119  return PLASMA_SUCCESS;
120 }
121 
126 int plasma_unsetaffinity() {
127  hwloc_obj_t obj; /* Hwloc object */
128  hwloc_cpuset_t cpuset; /* HwLoc cpuset */
129 
130  if (!topo_initialized) {
131  plasma_error("plasma_unsetaffinity", "Topology not initialized");
132  return PLASMA_ERR_UNEXPECTED;
133  }
134 
135  /* Get last one. */
136  obj = hwloc_get_obj_by_type(plasma_topology, HWLOC_OBJ_MACHINE, 0);
137  if (!obj) {
138  plasma_warning("plasma_unsetaffinity", "Could not get object");
139  return PLASMA_ERR_UNEXPECTED;
140  }
141 
142  /* Get a copy of its cpuset that we may modify. */
143  /* Get only one logical processor (in case the core is SMT/hyperthreaded). */
144 #if !defined(HWLOC_BITMAP_H)
145  cpuset = hwloc_cpuset_dup(obj->cpuset);
146 #else
147  cpuset = hwloc_bitmap_dup(obj->cpuset);
148 #endif
149 
150  /* And try to bind ourself there. */
151  if (hwloc_set_cpubind(plasma_topology, cpuset, HWLOC_CPUBIND_THREAD)) {
152  char *str = NULL;
153 #if !defined(HWLOC_BITMAP_H)
154  hwloc_cpuset_asprintf(&str, obj->cpuset);
155 #else
156  hwloc_bitmap_asprintf(&str, obj->cpuset);
157 #endif
158  plasma_warning("plasma_unsetaffinity", "Could not bind to the whole machine");
159  printf("Couldn't bind to cpuset %s\n", str);
160  free(str);
161  return PLASMA_ERR_UNEXPECTED;
162  }
163 
164  /* Free our cpuset copy */
165 #if !defined(HWLOC_BITMAP_H)
166  hwloc_cpuset_free(cpuset);
167 #else
168  hwloc_bitmap_free(cpuset);
169 #endif
170  return PLASMA_SUCCESS;
171 }
172 
173 int plasma_getnuma_size() {
174  hwloc_cpuset_t cpuset; /* HwLoc cpuset */
175  hwloc_obj_t obj;
176  int thrdnbr = 1;
177 
178  obj = hwloc_get_obj_by_type(plasma_topology, HWLOC_OBJ_NODE, 0);
179 
180  /* Get a copy of its cpuset that we may modify. */
181  if (obj != NULL) {
182 #if !defined(HWLOC_BITMAP_H)
183  cpuset = hwloc_cpuset_dup(obj->cpuset);
184 #else
185  cpuset = hwloc_bitmap_dup(obj->cpuset);
186 #endif
187  thrdnbr = hwloc_get_nbobjs_inside_cpuset_by_type(plasma_topology, cpuset, HWLOC_OBJ_CORE);
188 
189  /* Free our cpuset copy */
190 #if !defined(HWLOC_BITMAP_H)
191  hwloc_cpuset_free(cpuset);
192 #else
193  hwloc_bitmap_free(cpuset);
194 #endif
195  }
196 
197  return thrdnbr;
198 }
199 #ifdef __cplusplus
200 }
201 #endif
202 
203 #endif /* PLASMA_HAS_COMPLEX */