@@ -94,6 +94,199 @@ int OMPI_Affinity_str(ompi_affinity_fmt_t fmt_type,
94
94
95
95
/*---------------------------------------------------------------------------*/
96
96
97
+ /*
98
+ * Make a map of socket/core/hwthread tuples
99
+ */
100
+ static int build_map (int * num_sockets_arg , int * num_cores_arg , hwloc_cpuset_t cpuset , int * * * map ,
101
+ hwloc_topology_t topo )
102
+ {
103
+ int num_sockets , num_cores ;
104
+ int socket_index , core_index , pu_index ;
105
+ hwloc_obj_t socket , core , pu ;
106
+ int * * data ;
107
+
108
+ /* Find out how many sockets we have */
109
+ num_sockets = hwloc_get_nbobjs_by_type (topo , HWLOC_OBJ_SOCKET );
110
+ /* some systems (like the iMac) only have one
111
+ * socket and so don't report a socket
112
+ */
113
+ if (0 == num_sockets ) {
114
+ num_sockets = 1 ;
115
+ }
116
+ /* Lazy: take the total number of cores that we have in the
117
+ topology; that'll be more than the max number of cores
118
+ under any given socket */
119
+ num_cores = hwloc_get_nbobjs_by_type (topo , HWLOC_OBJ_CORE );
120
+ * num_sockets_arg = num_sockets ;
121
+ * num_cores_arg = num_cores ;
122
+
123
+ /* Alloc a 2D array: sockets x cores. */
124
+ data = malloc (num_sockets * sizeof (int * ));
125
+ if (NULL == data ) {
126
+ return OMPI_ERR_OUT_OF_RESOURCE ;
127
+ }
128
+ data [0 ] = calloc (num_sockets * num_cores , sizeof (int ));
129
+ if (NULL == data [0 ]) {
130
+ free (data );
131
+ return MPI_ERR_NO_MEM ;
132
+ }
133
+ for (socket_index = 1 ; socket_index < num_sockets ; ++ socket_index ) {
134
+ data [socket_index ] = data [socket_index - 1 ] + num_cores ;
135
+ }
136
+
137
+ /* Iterate the PUs in this cpuset; fill in the data[][] array with
138
+ the socket/core/pu triples */
139
+ for (pu_index = 0 ,
140
+ pu = hwloc_get_obj_inside_cpuset_by_type (topo , cpuset , HWLOC_OBJ_PU , pu_index );
141
+ NULL != pu ;
142
+ pu = hwloc_get_obj_inside_cpuset_by_type (topo , cpuset , HWLOC_OBJ_PU , ++ pu_index )) {
143
+ /* Go upward and find the core this PU belongs to */
144
+ core = pu ;
145
+ while (NULL != core && core -> type != HWLOC_OBJ_CORE ) {
146
+ core = core -> parent ;
147
+ }
148
+ core_index = 0 ;
149
+ if (NULL != core ) {
150
+ core_index = core -> logical_index ;
151
+ }
152
+
153
+ /* Go upward and find the socket this PU belongs to */
154
+ socket = pu ;
155
+ while (NULL != socket && socket -> type != HWLOC_OBJ_SOCKET ) {
156
+ socket = socket -> parent ;
157
+ }
158
+ socket_index = 0 ;
159
+ if (NULL != socket ) {
160
+ socket_index = socket -> logical_index ;
161
+ }
162
+
163
+ /* Save this socket/core/pu combo. LAZY: Assuming that we
164
+ won't have more PU's per core than (sizeof(int)*8). */
165
+ data [socket_index ][core_index ] |= (1 << pu -> sibling_rank );
166
+ }
167
+
168
+ * map = data ;
169
+ return OMPI_SUCCESS ;
170
+ }
171
+
172
+ /*
173
+ * Turn an int bitmap to a "a-b,c" range kind of string
174
+ */
175
+ static char * bitmap2rangestr (int bitmap )
176
+ {
177
+ size_t i ;
178
+ int range_start , range_end ;
179
+ bool first , isset ;
180
+ char tmp [BUFSIZ ];
181
+ const int stmp = sizeof (tmp ) - 1 ;
182
+ static char ret [BUFSIZ ];
183
+
184
+ memset (ret , 0 , sizeof (ret ));
185
+
186
+ first = true;
187
+ range_start = -999 ;
188
+ for (i = 0 ; i < sizeof (int ) * 8 ; ++ i ) {
189
+ isset = (bitmap & (1 << i ));
190
+
191
+ /* Do we have a running range? */
192
+ if (range_start >= 0 ) {
193
+ if (isset ) {
194
+ continue ;
195
+ } else {
196
+ /* A range just ended; output it */
197
+ if (!first ) {
198
+ strncat (ret , "," , sizeof (ret ) - strlen (ret ) - 1 );
199
+ } else {
200
+ first = false;
201
+ }
202
+
203
+ range_end = i - 1 ;
204
+ if (range_start == range_end ) {
205
+ snprintf (tmp , stmp , "%d" , range_start );
206
+ } else {
207
+ snprintf (tmp , stmp , "%d-%d" , range_start , range_end );
208
+ }
209
+ snprintf (ret + strlen (ret ), BUFSIZ , "%s" , tmp );
210
+
211
+ range_start = -999 ;
212
+ }
213
+ }
214
+
215
+ /* No running range */
216
+ else {
217
+ if (isset ) {
218
+ range_start = i ;
219
+ }
220
+ }
221
+ }
222
+
223
+ /* If we ended the bitmap with a range open, output it */
224
+ if (range_start >= 0 ) {
225
+ if (!first ) {
226
+ strncat (ret , "," , sizeof (ret ) - strlen (ret ) - 1 );
227
+ first = false;
228
+ }
229
+
230
+ range_end = i - 1 ;
231
+ if (range_start == range_end ) {
232
+ snprintf (tmp , stmp , "%d" , range_start );
233
+ } else {
234
+ snprintf (tmp , stmp , "%d-%d" , range_start , range_end );
235
+ }
236
+ snprintf (ret + strlen (ret ), BUFSIZ , "%s" , tmp );
237
+ }
238
+
239
+ return ret ;
240
+ }
241
+
242
+ /*
243
+ * Make a prettyprint string for a hwloc_cpuset_t
244
+ */
245
+ static int cset2str (char * str , int len , hwloc_topology_t topo , hwloc_cpuset_t cpuset )
246
+ {
247
+ bool first ;
248
+ int num_sockets , num_cores ;
249
+ int ret , socket_index , core_index ;
250
+ char tmp [BUFSIZ ];
251
+ const int stmp = sizeof (tmp ) - 1 ;
252
+ int * * map = NULL ;
253
+
254
+ str [0 ] = tmp [stmp ] = '\0' ;
255
+
256
+ /* if the cpuset is all zero, then not bound */
257
+ if (hwloc_bitmap_iszero (cpuset )) {
258
+ return OMPI_ERR_NOT_BOUND ;
259
+ }
260
+
261
+ if (OMPI_SUCCESS != (ret = build_map (& num_sockets , & num_cores , cpuset , & map , topo ))) {
262
+ return ret ;
263
+ }
264
+ /* Iterate over the data matrix and build up the string */
265
+ first = true;
266
+ for (socket_index = 0 ; socket_index < num_sockets ; ++ socket_index ) {
267
+ for (core_index = 0 ; core_index < num_cores ; ++ core_index ) {
268
+ if (map [socket_index ][core_index ] > 0 ) {
269
+ if (!first ) {
270
+ strncat (str , ", " , len - strlen (str ) - 1 );
271
+ }
272
+ first = false;
273
+
274
+ snprintf (tmp , stmp , "socket %d[core %d[hwt %s]]" , socket_index , core_index ,
275
+ bitmap2rangestr (map [socket_index ][core_index ]));
276
+ strncat (str , tmp , len - strlen (str ) - 1 );
277
+ }
278
+ }
279
+ }
280
+ if (NULL != map ) {
281
+ if (NULL != map [0 ]) {
282
+ free (map [0 ]);
283
+ }
284
+ free (map );
285
+ }
286
+
287
+ return OMPI_SUCCESS ;
288
+ }
289
+
97
290
/*
98
291
* Where did OMPI bind this process? (prettyprint)
99
292
*/
@@ -107,10 +300,10 @@ static int get_rsrc_ompi_bound(char str[OMPI_AFFINITY_STRING_MAX])
107
300
108
301
hwloc_bitmap_t cpuset = hwloc_bitmap_alloc ();
109
302
hwloc_bitmap_list_sscanf (cpuset , opal_process_info .cpuset );
110
- if (OPAL_ERR_NOT_BOUND == opal_hwloc_base_cset2str (str ,
111
- OMPI_AFFINITY_STRING_MAX ,
112
- opal_hwloc_topology ,
113
- cpuset ))
303
+ if (OMPI_ERR_NOT_BOUND == cset2str (str ,
304
+ OMPI_AFFINITY_STRING_MAX ,
305
+ opal_hwloc_topology ,
306
+ cpuset ))
114
307
{
115
308
opal_string_copy (str , not_bound_str , OMPI_AFFINITY_STRING_MAX );
116
309
}
@@ -119,6 +312,90 @@ static int get_rsrc_ompi_bound(char str[OMPI_AFFINITY_STRING_MAX])
119
312
return OMPI_SUCCESS ;
120
313
}
121
314
315
+ /* determine if there is a single cpu in a bitmap */
316
+ static bool is_single_cpu (hwloc_cpuset_t cpuset )
317
+ {
318
+ int i ;
319
+ bool one = false;
320
+
321
+ /* count the number of bits that are set - there is
322
+ * one bit for each available pu. We could just
323
+ * subtract the first and last indices, but there
324
+ * may be "holes" in the bitmap corresponding to
325
+ * offline or unallowed cpus - so we have to
326
+ * search for them. Return false if we anything
327
+ * other than one
328
+ */
329
+ for (i = hwloc_bitmap_first (cpuset ); i <= hwloc_bitmap_last (cpuset ); i ++ ) {
330
+ if (hwloc_bitmap_isset (cpuset , i )) {
331
+ if (one ) {
332
+ return false;
333
+ }
334
+ one = true;
335
+ }
336
+ }
337
+
338
+ return one ;
339
+ }
340
+
341
+ /*
342
+ * Make a prettyprint string for a cset in a map format.
343
+ * Example: [B./..]
344
+ * Key: [] - signifies socket
345
+ * / - divider between cores
346
+ * . - signifies PU a process not bound to
347
+ * B - signifies PU a process is bound to
348
+ */
349
+ static int cset2mapstr (char * str , int len , hwloc_topology_t topo , hwloc_cpuset_t cpuset )
350
+ {
351
+ char tmp [BUFSIZ ];
352
+ int core_index , pu_index ;
353
+ const int stmp = sizeof (tmp ) - 1 ;
354
+ hwloc_obj_t socket , core , pu ;
355
+
356
+ str [0 ] = tmp [stmp ] = '\0' ;
357
+
358
+ /* if the cpuset is all zero, then not bound */
359
+ if (hwloc_bitmap_iszero (cpuset )) {
360
+ return OMPI_ERR_NOT_BOUND ;
361
+ }
362
+
363
+ /* Iterate over all existing sockets */
364
+ for (socket = hwloc_get_obj_by_type (topo , HWLOC_OBJ_SOCKET , 0 ); NULL != socket ;
365
+ socket = socket -> next_cousin ) {
366
+ strncat (str , "[" , len - strlen (str ) - 1 );
367
+
368
+ /* Iterate over all existing cores in this socket */
369
+ core_index = 0 ;
370
+ for (core = hwloc_get_obj_inside_cpuset_by_type (topo , socket -> cpuset , HWLOC_OBJ_CORE ,
371
+ core_index );
372
+ NULL != core ;
373
+ core = hwloc_get_obj_inside_cpuset_by_type (topo , socket -> cpuset , HWLOC_OBJ_CORE ,
374
+ ++ core_index )) {
375
+ if (core_index > 0 ) {
376
+ strncat (str , "/" , len - strlen (str ) - 1 );
377
+ }
378
+
379
+ /* Iterate over all existing PUs in this core */
380
+ pu_index = 0 ;
381
+ for (pu = hwloc_get_obj_inside_cpuset_by_type (topo , core -> cpuset , HWLOC_OBJ_PU ,
382
+ pu_index );
383
+ NULL != pu ; pu = hwloc_get_obj_inside_cpuset_by_type (topo , core -> cpuset ,
384
+ HWLOC_OBJ_PU , ++ pu_index )) {
385
+
386
+ /* Is this PU in the cpuset? */
387
+ if (hwloc_bitmap_isset (cpuset , pu -> os_index )) {
388
+ strncat (str , "B" , len - strlen (str ) - 1 );
389
+ } else {
390
+ strncat (str , "." , len - strlen (str ) - 1 );
391
+ }
392
+ }
393
+ }
394
+ strncat (str , "]" , len - strlen (str ) - 1 );
395
+ }
396
+
397
+ return OMPI_SUCCESS ;
398
+ }
122
399
123
400
/*
124
401
* Where is this process currently bound? (prettyprint)
@@ -145,8 +422,8 @@ static int get_rsrc_current_binding(char str[OMPI_AFFINITY_STRING_MAX])
145
422
/* we are bound if the two cpusets are not equal, or if there
146
423
is only ONE PU available to us */
147
424
if (0 != hwloc_bitmap_compare (boundset , rootset ) ||
148
- opal_hwloc_base_single_cpu (rootset ) ||
149
- opal_hwloc_base_single_cpu (boundset )) {
425
+ is_single_cpu (rootset ) ||
426
+ is_single_cpu (boundset )) {
150
427
bound = true;
151
428
}
152
429
}
@@ -159,10 +436,10 @@ static int get_rsrc_current_binding(char str[OMPI_AFFINITY_STRING_MAX])
159
436
160
437
/* If we are bound, print it out */
161
438
else {
162
- ret = opal_hwloc_base_cset2str (str , OMPI_AFFINITY_STRING_MAX ,
163
- opal_hwloc_topology ,
164
- boundset );
165
- if (OPAL_ERR_NOT_BOUND == ret ) {
439
+ ret = cset2str (str , OMPI_AFFINITY_STRING_MAX ,
440
+ opal_hwloc_topology ,
441
+ boundset );
442
+ if (OMPI_ERR_NOT_BOUND == ret ) {
166
443
opal_string_copy (str , not_bound_str , OMPI_AFFINITY_STRING_MAX );
167
444
ret = OMPI_SUCCESS ;
168
445
}
@@ -297,10 +574,10 @@ static int get_layout_ompi_bound(char str[OMPI_AFFINITY_STRING_MAX])
297
574
298
575
hwloc_bitmap_t cpuset = hwloc_bitmap_alloc ();
299
576
hwloc_bitmap_list_sscanf (cpuset , opal_process_info .cpuset );
300
- if (OPAL_ERR_NOT_BOUND == opal_hwloc_base_cset2mapstr (str ,
301
- OMPI_AFFINITY_STRING_MAX ,
302
- opal_hwloc_topology ,
303
- cpuset ))
577
+ if (OMPI_ERR_NOT_BOUND == cset2mapstr (str ,
578
+ OMPI_AFFINITY_STRING_MAX ,
579
+ opal_hwloc_topology ,
580
+ cpuset ))
304
581
{
305
582
opal_string_copy (str , not_bound_str , OMPI_AFFINITY_STRING_MAX );
306
583
}
@@ -333,8 +610,8 @@ static int get_layout_current_binding(char str[OMPI_AFFINITY_STRING_MAX])
333
610
/* we are bound if the two cpusets are not equal, or if there
334
611
is only ONE PU available to us */
335
612
if (0 != hwloc_bitmap_compare (boundset , rootset ) ||
336
- opal_hwloc_base_single_cpu (rootset ) ||
337
- opal_hwloc_base_single_cpu (boundset )) {
613
+ is_single_cpu (rootset ) ||
614
+ is_single_cpu (boundset )) {
338
615
bound = true;
339
616
}
340
617
}
@@ -347,10 +624,10 @@ static int get_layout_current_binding(char str[OMPI_AFFINITY_STRING_MAX])
347
624
348
625
/* If we are bound, print it out */
349
626
else {
350
- ret = opal_hwloc_base_cset2mapstr (str , OMPI_AFFINITY_STRING_MAX ,
351
- opal_hwloc_topology ,
352
- boundset );
353
- if (OPAL_ERR_NOT_BOUND == ret ) {
627
+ ret = cset2mapstr (str , OMPI_AFFINITY_STRING_MAX ,
628
+ opal_hwloc_topology ,
629
+ boundset );
630
+ if (OMPI_ERR_NOT_BOUND == ret ) {
354
631
opal_string_copy (str , not_bound_str , OMPI_AFFINITY_STRING_MAX );
355
632
ret = OMPI_SUCCESS ;
356
633
}
0 commit comments