@@ -94,6 +94,201 @@ 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
+ size_t ret_len = strlen (ret );
210
+ snprintf (ret + ret_len , BUFSIZ - ret_len , "%s" , tmp );
211
+
212
+ range_start = -999 ;
213
+ }
214
+ }
215
+
216
+ /* No running range */
217
+ else {
218
+ if (isset ) {
219
+ range_start = i ;
220
+ }
221
+ }
222
+ }
223
+
224
+ /* If we ended the bitmap with a range open, output it */
225
+ if (range_start >= 0 ) {
226
+ if (!first ) {
227
+ strncat (ret , "," , sizeof (ret ) - strlen (ret ) - 1 );
228
+ first = false;
229
+ }
230
+
231
+ range_end = i - 1 ;
232
+ if (range_start == range_end ) {
233
+ snprintf (tmp , stmp , "%d" , range_start );
234
+ } else {
235
+ snprintf (tmp , stmp , "%d-%d" , range_start , range_end );
236
+ }
237
+ size_t ret_len = strlen (ret );
238
+ snprintf (ret + ret_len , BUFSIZ - ret_len , "%s" , tmp );
239
+ }
240
+
241
+ return ret ;
242
+ }
243
+
244
+ /*
245
+ * Make a prettyprint string for a hwloc_cpuset_t
246
+ */
247
+ static int cset2str (char * str , int len , hwloc_topology_t topo , hwloc_cpuset_t cpuset )
248
+ {
249
+ bool first ;
250
+ int num_sockets , num_cores ;
251
+ int ret , socket_index , core_index ;
252
+ char tmp [BUFSIZ ];
253
+ const int stmp = sizeof (tmp ) - 1 ;
254
+ int * * map = NULL ;
255
+
256
+ str [0 ] = tmp [stmp ] = '\0' ;
257
+
258
+ /* if the cpuset is all zero, then not bound */
259
+ if (hwloc_bitmap_iszero (cpuset )) {
260
+ return OMPI_ERR_NOT_BOUND ;
261
+ }
262
+
263
+ if (OMPI_SUCCESS != (ret = build_map (& num_sockets , & num_cores , cpuset , & map , topo ))) {
264
+ return ret ;
265
+ }
266
+ /* Iterate over the data matrix and build up the string */
267
+ first = true;
268
+ for (socket_index = 0 ; socket_index < num_sockets ; ++ socket_index ) {
269
+ for (core_index = 0 ; core_index < num_cores ; ++ core_index ) {
270
+ if (map [socket_index ][core_index ] > 0 ) {
271
+ if (!first ) {
272
+ strncat (str , ", " , len - strlen (str ) - 1 );
273
+ }
274
+ first = false;
275
+
276
+ snprintf (tmp , stmp , "socket %d[core %d[hwt %s]]" , socket_index , core_index ,
277
+ bitmap2rangestr (map [socket_index ][core_index ]));
278
+ strncat (str , tmp , len - strlen (str ) - 1 );
279
+ }
280
+ }
281
+ }
282
+ if (NULL != map ) {
283
+ if (NULL != map [0 ]) {
284
+ free (map [0 ]);
285
+ }
286
+ free (map );
287
+ }
288
+
289
+ return OMPI_SUCCESS ;
290
+ }
291
+
97
292
/*
98
293
* Where did OMPI bind this process? (prettyprint)
99
294
*/
@@ -107,10 +302,10 @@ static int get_rsrc_ompi_bound(char str[OMPI_AFFINITY_STRING_MAX])
107
302
108
303
hwloc_bitmap_t cpuset = hwloc_bitmap_alloc ();
109
304
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 ))
305
+ if (OMPI_ERR_NOT_BOUND == cset2str (str ,
306
+ OMPI_AFFINITY_STRING_MAX ,
307
+ opal_hwloc_topology ,
308
+ cpuset ))
114
309
{
115
310
opal_string_copy (str , not_bound_str , OMPI_AFFINITY_STRING_MAX );
116
311
}
@@ -119,6 +314,90 @@ static int get_rsrc_ompi_bound(char str[OMPI_AFFINITY_STRING_MAX])
119
314
return OMPI_SUCCESS ;
120
315
}
121
316
317
+ /* determine if there is a single cpu in a bitmap */
318
+ static bool is_single_cpu (hwloc_cpuset_t cpuset )
319
+ {
320
+ int i ;
321
+ bool one = false;
322
+
323
+ /* count the number of bits that are set - there is
324
+ * one bit for each available pu. We could just
325
+ * subtract the first and last indices, but there
326
+ * may be "holes" in the bitmap corresponding to
327
+ * offline or unallowed cpus - so we have to
328
+ * search for them. Return false if we anything
329
+ * other than one
330
+ */
331
+ for (i = hwloc_bitmap_first (cpuset ); i <= hwloc_bitmap_last (cpuset ); i ++ ) {
332
+ if (hwloc_bitmap_isset (cpuset , i )) {
333
+ if (one ) {
334
+ return false;
335
+ }
336
+ one = true;
337
+ }
338
+ }
339
+
340
+ return one ;
341
+ }
342
+
343
+ /*
344
+ * Make a prettyprint string for a cset in a map format.
345
+ * Example: [B./..]
346
+ * Key: [] - signifies socket
347
+ * / - divider between cores
348
+ * . - signifies PU a process not bound to
349
+ * B - signifies PU a process is bound to
350
+ */
351
+ static int cset2mapstr (char * str , int len , hwloc_topology_t topo , hwloc_cpuset_t cpuset )
352
+ {
353
+ char tmp [BUFSIZ ];
354
+ int core_index , pu_index ;
355
+ const int stmp = sizeof (tmp ) - 1 ;
356
+ hwloc_obj_t socket , core , pu ;
357
+
358
+ str [0 ] = tmp [stmp ] = '\0' ;
359
+
360
+ /* if the cpuset is all zero, then not bound */
361
+ if (hwloc_bitmap_iszero (cpuset )) {
362
+ return OMPI_ERR_NOT_BOUND ;
363
+ }
364
+
365
+ /* Iterate over all existing sockets */
366
+ for (socket = hwloc_get_obj_by_type (topo , HWLOC_OBJ_SOCKET , 0 ); NULL != socket ;
367
+ socket = socket -> next_cousin ) {
368
+ strncat (str , "[" , len - strlen (str ) - 1 );
369
+
370
+ /* Iterate over all existing cores in this socket */
371
+ core_index = 0 ;
372
+ for (core = hwloc_get_obj_inside_cpuset_by_type (topo , socket -> cpuset , HWLOC_OBJ_CORE ,
373
+ core_index );
374
+ NULL != core ;
375
+ core = hwloc_get_obj_inside_cpuset_by_type (topo , socket -> cpuset , HWLOC_OBJ_CORE ,
376
+ ++ core_index )) {
377
+ if (core_index > 0 ) {
378
+ strncat (str , "/" , len - strlen (str ) - 1 );
379
+ }
380
+
381
+ /* Iterate over all existing PUs in this core */
382
+ pu_index = 0 ;
383
+ for (pu = hwloc_get_obj_inside_cpuset_by_type (topo , core -> cpuset , HWLOC_OBJ_PU ,
384
+ pu_index );
385
+ NULL != pu ; pu = hwloc_get_obj_inside_cpuset_by_type (topo , core -> cpuset ,
386
+ HWLOC_OBJ_PU , ++ pu_index )) {
387
+
388
+ /* Is this PU in the cpuset? */
389
+ if (hwloc_bitmap_isset (cpuset , pu -> os_index )) {
390
+ strncat (str , "B" , len - strlen (str ) - 1 );
391
+ } else {
392
+ strncat (str , "." , len - strlen (str ) - 1 );
393
+ }
394
+ }
395
+ }
396
+ strncat (str , "]" , len - strlen (str ) - 1 );
397
+ }
398
+
399
+ return OMPI_SUCCESS ;
400
+ }
122
401
123
402
/*
124
403
* Where is this process currently bound? (prettyprint)
@@ -145,8 +424,8 @@ static int get_rsrc_current_binding(char str[OMPI_AFFINITY_STRING_MAX])
145
424
/* we are bound if the two cpusets are not equal, or if there
146
425
is only ONE PU available to us */
147
426
if (0 != hwloc_bitmap_compare (boundset , rootset ) ||
148
- opal_hwloc_base_single_cpu (rootset ) ||
149
- opal_hwloc_base_single_cpu (boundset )) {
427
+ is_single_cpu (rootset ) ||
428
+ is_single_cpu (boundset )) {
150
429
bound = true;
151
430
}
152
431
}
@@ -159,10 +438,10 @@ static int get_rsrc_current_binding(char str[OMPI_AFFINITY_STRING_MAX])
159
438
160
439
/* If we are bound, print it out */
161
440
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 ) {
441
+ ret = cset2str (str , OMPI_AFFINITY_STRING_MAX ,
442
+ opal_hwloc_topology ,
443
+ boundset );
444
+ if (OMPI_ERR_NOT_BOUND == ret ) {
166
445
opal_string_copy (str , not_bound_str , OMPI_AFFINITY_STRING_MAX );
167
446
ret = OMPI_SUCCESS ;
168
447
}
@@ -297,10 +576,10 @@ static int get_layout_ompi_bound(char str[OMPI_AFFINITY_STRING_MAX])
297
576
298
577
hwloc_bitmap_t cpuset = hwloc_bitmap_alloc ();
299
578
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 ))
579
+ if (OMPI_ERR_NOT_BOUND == cset2mapstr (str ,
580
+ OMPI_AFFINITY_STRING_MAX ,
581
+ opal_hwloc_topology ,
582
+ cpuset ))
304
583
{
305
584
opal_string_copy (str , not_bound_str , OMPI_AFFINITY_STRING_MAX );
306
585
}
@@ -333,8 +612,8 @@ static int get_layout_current_binding(char str[OMPI_AFFINITY_STRING_MAX])
333
612
/* we are bound if the two cpusets are not equal, or if there
334
613
is only ONE PU available to us */
335
614
if (0 != hwloc_bitmap_compare (boundset , rootset ) ||
336
- opal_hwloc_base_single_cpu (rootset ) ||
337
- opal_hwloc_base_single_cpu (boundset )) {
615
+ is_single_cpu (rootset ) ||
616
+ is_single_cpu (boundset )) {
338
617
bound = true;
339
618
}
340
619
}
@@ -347,10 +626,10 @@ static int get_layout_current_binding(char str[OMPI_AFFINITY_STRING_MAX])
347
626
348
627
/* If we are bound, print it out */
349
628
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 ) {
629
+ ret = cset2mapstr (str , OMPI_AFFINITY_STRING_MAX ,
630
+ opal_hwloc_topology ,
631
+ boundset );
632
+ if (OMPI_ERR_NOT_BOUND == ret ) {
354
633
opal_string_copy (str , not_bound_str , OMPI_AFFINITY_STRING_MAX );
355
634
ret = OMPI_SUCCESS ;
356
635
}
0 commit comments