1 #if HAVE_CONFIG_H
2 # include "config.h"
3 #endif
4
5 #include <assert.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <stdio.h>
9 #include <unistd.h>
10
11 #include <mpi.h>
12
13 #if defined(__bgp__)
14 #include <spi/kernel_interface.h>
15 #include <common/bgp_personality.h>
16 #include <common/bgp_personality_inlines.h>
17 #elif defined(__bgq__)
18 # include <mpix.h>
19 #elif defined(__CRAYXT) || defined(__CRAYXE)
20 # include <pmi.h>
21 #endif
22
23 #include "comex.h"
24 #include "comex_impl.h"
25 #include "groups.h"
26
27
28 /* world group state */
29 comex_group_world_t g_state = {
30 MPI_COMM_NULL,
31 MPI_GROUP_NULL,
32 -1,
33 -1,
34 NULL,
35 NULL,
36 MPI_COMM_NULL,
37 -1,
38 -1
39 };
40 /* the HEAD of the group linked list */
41 comex_igroup_t *group_list = NULL;
42
43 #define RANK_OR_PID (g_state.rank >= 0 ? g_state.rank : getpid())
44
45 /* static functions implemented in this file */
46 static void _create_group_and_igroup(comex_group_t *id, comex_igroup_t **igroup);
47 static void _igroup_free(comex_igroup_t *igroup);
48 static long xgethostid();
49
50
51 /**
52 * Return the comex igroup instance given the group id.
53 *
54 * The group linked list is searched sequentially until the given group
55 * is found. It is an error if this function is called before
56 * comex_group_init(). An error occurs if the given group is not found.
57 */
comex_get_igroup_from_group(comex_group_t id)58 comex_igroup_t* comex_get_igroup_from_group(comex_group_t id)
59 {
60 comex_igroup_t *current_group_list_item = group_list;
61
62 #if DEBUG
63 printf("[%d] comex_get_igroup_from_group(%d)\n", RANK_OR_PID, id);
64 #endif
65
66 COMEX_ASSERT(group_list != NULL);
67 while (current_group_list_item != NULL) {
68 if (current_group_list_item->id == id) {
69 return current_group_list_item;
70 }
71 current_group_list_item = current_group_list_item->next;
72 }
73 comex_error("comex group lookup failed", -1);
74
75 return NULL;
76 }
77
78
79 /**
80 * Creates and associates a comex group with a comex igroup.
81 *
82 * This does *not* initialize the members of the comex igroup.
83 */
_create_group_and_igroup(comex_group_t * id,comex_igroup_t ** igroup)84 static void _create_group_and_igroup(
85 comex_group_t *id, comex_igroup_t **igroup)
86 {
87 comex_igroup_t *new_group_list_item = NULL;
88 comex_igroup_t *last_group_list_item = NULL;
89
90 #if DEBUG
91 printf("[%d] _create_group_and_igroup(...)\n", RANK_OR_PID);
92 #endif
93
94 /* create, init, and insert the new node for the linked list */
95 new_group_list_item = malloc(sizeof(comex_igroup_t));
96 new_group_list_item->next = NULL;
97 new_group_list_item->id = -1;
98 new_group_list_item->comm = MPI_COMM_NULL;
99 new_group_list_item->group = MPI_GROUP_NULL;
100 new_group_list_item->size = -1;
101 new_group_list_item->rank = -1;
102 new_group_list_item->world_ranks = NULL;
103
104 /* find the last group in the group linked list and insert */
105 if (group_list) {
106 last_group_list_item = group_list;
107 while (last_group_list_item->next != NULL) {
108 last_group_list_item = last_group_list_item->next;
109 }
110 last_group_list_item->next = new_group_list_item;
111 new_group_list_item->id = last_group_list_item->id + 1;
112 }
113 else {
114 group_list = new_group_list_item;
115 new_group_list_item->id = COMEX_GROUP_WORLD;
116 }
117
118 /* return the group id and comex igroup */
119 *igroup = new_group_list_item;
120 *id = new_group_list_item->id;
121 }
122
123
comex_group_rank(comex_group_t group,int * rank)124 int comex_group_rank(comex_group_t group, int *rank)
125 {
126 comex_igroup_t *igroup = comex_get_igroup_from_group(group);
127 *rank = igroup->rank;
128
129 #if DEBUG
130 printf("[%d] comex_group_rank(group=%d, *rank=%d)\n",
131 RANK_OR_PID, group, *rank);
132 #endif
133
134 return COMEX_SUCCESS;
135 }
136
137
comex_group_size(comex_group_t group,int * size)138 int comex_group_size(comex_group_t group, int *size)
139 {
140 comex_igroup_t *igroup = comex_get_igroup_from_group(group);
141 *size = igroup->size;
142
143 #if DEBUG
144 printf("[%d] comex_group_size(group=%d, *size=%d)\n",
145 RANK_OR_PID, group, *size);
146 #endif
147
148 return COMEX_SUCCESS;
149 }
150
151
comex_group_comm(comex_group_t group,MPI_Comm * comm)152 int comex_group_comm(comex_group_t group, MPI_Comm *comm)
153 {
154 comex_igroup_t *igroup = comex_get_igroup_from_group(group);
155 *comm = igroup->comm;
156
157 #if DEBUG
158 printf("[%d] comex_group_comm(group=%d, comm)\n",
159 RANK_OR_PID, group);
160 #endif
161
162 return COMEX_SUCCESS;
163 }
164
165
comex_group_translate_world(comex_group_t group,int group_rank,int * world_rank)166 int comex_group_translate_world(
167 comex_group_t group, int group_rank, int *world_rank)
168 {
169 #if DEBUG
170 printf("[%d] comex_group_translate_world("
171 "group=%d, group_rank=%d, world_rank)\n",
172 RANK_OR_PID, group, group_rank);
173 #endif
174
175 if (COMEX_GROUP_WORLD == group) {
176 *world_rank = group_rank;
177 }
178 else {
179 int status;
180 comex_igroup_t *igroup = comex_get_igroup_from_group(group);
181
182 COMEX_ASSERT(group_list); /* first group is world worker group */
183 status = MPI_Group_translate_ranks(igroup->group, 1, &group_rank,
184 group_list->group, world_rank);
185 }
186
187 return COMEX_SUCCESS;
188 }
189
190
191 /**
192 * Destroys the given comex igroup.
193 */
_igroup_free(comex_igroup_t * igroup)194 static void _igroup_free(comex_igroup_t *igroup)
195 {
196 int status;
197
198 #if DEBUG
199 printf("[%d] _igroup_free\n",
200 RANK_OR_PID);
201 #endif
202
203 COMEX_ASSERT(igroup);
204
205 if (igroup->group != MPI_GROUP_NULL) {
206 status = MPI_Group_free(&igroup->group);
207 if (status != MPI_SUCCESS) {
208 comex_error("MPI_Group_free: Failed ", status);
209 }
210 }
211 #if DEBUG
212 printf("[%d] free'd group\n", RANK_OR_PID);
213 #endif
214
215 if (igroup->comm != MPI_COMM_NULL) {
216 status = MPI_Comm_free(&igroup->comm);
217 if (status != MPI_SUCCESS) {
218 comex_error("MPI_Comm_free: Failed ", status);
219 }
220 }
221 #if DEBUG
222 printf("[%d] free'd comm\n", RANK_OR_PID);
223 #endif
224 if (igroup->world_ranks != NULL) {
225 free(igroup->world_ranks);
226 }
227
228 free(igroup);
229 }
230
231
comex_group_free(comex_group_t id)232 int comex_group_free(comex_group_t id)
233 {
234 comex_igroup_t *current_group_list_item = group_list;
235 comex_igroup_t *previous_group_list_item = NULL;
236
237 #if DEBUG
238 printf("[%d] comex_group_free(id=%d)\n", RANK_OR_PID, id);
239 #endif
240
241 /* find the group to free */
242 while (current_group_list_item != NULL) {
243 if (current_group_list_item->id == id) {
244 break;
245 }
246 previous_group_list_item = current_group_list_item;
247 current_group_list_item = current_group_list_item->next;
248 }
249 /* make sure we found a group */
250 COMEX_ASSERT(current_group_list_item != NULL);
251 /* remove the group from the linked list */
252 if (previous_group_list_item != NULL) {
253 previous_group_list_item->next = current_group_list_item->next;
254 }
255 /* free the igroup */
256 _igroup_free(current_group_list_item);
257
258 return COMEX_SUCCESS;
259 }
260
_igroup_set_world_ranks(comex_igroup_t * igroup)261 void _igroup_set_world_ranks(comex_igroup_t *igroup)
262 {
263 int i = 0;
264 int my_world_rank = g_state.rank;
265 igroup->world_ranks = (int*)malloc(sizeof(int)*igroup->size);
266 int status;
267
268 for (i=0; i<igroup->size; ++i) {
269 igroup->world_ranks[i] = MPI_PROC_NULL;
270 }
271
272 status = MPI_Allgather(&my_world_rank,1,MPI_INT,igroup->world_ranks,
273 1,MPI_INT,igroup->comm);
274 COMEX_ASSERT(MPI_SUCCESS == status);
275
276 for (i=0; i<igroup->size; ++i) {
277 COMEX_ASSERT(MPI_PROC_NULL != igroup->world_ranks[i]);
278 }
279 }
280
comex_group_create(int n,int * pid_list,comex_group_t id_parent,comex_group_t * id_child)281 int comex_group_create(
282 int n, int *pid_list, comex_group_t id_parent, comex_group_t *id_child)
283 {
284 int status = 0;
285 int grp_me = 0;
286 comex_igroup_t *igroup_child = NULL;
287 MPI_Group *group_child = NULL;
288 MPI_Comm *comm_child = NULL;
289 comex_igroup_t *igroup_parent = NULL;
290 MPI_Group *group_parent = NULL;
291 MPI_Comm *comm_parent = NULL;
292
293 #if DEBUG
294 printf("[%d] comex_group_create("
295 "n=%d, pid_list=%p, id_parent=%d, id_child)\n",
296 RANK_OR_PID, n, pid_list, id_parent);
297 {
298 int p;
299 printf("[%d] pid_list={%d", RANK_OR_PID, pid_list[0]);
300 for (p=1; p<n; ++p) {
301 printf(",%d", pid_list[p]);
302 }
303 printf("}\n");
304 }
305 #endif
306
307 /* create the node in the linked list of groups and */
308 /* get the child's MPI_Group and MPI_Comm, to be populated shortly */
309 _create_group_and_igroup(id_child, &igroup_child);
310 group_child = &(igroup_child->group);
311 comm_child = &(igroup_child->comm);
312
313 /* get the parent's MPI_Group and MPI_Comm */
314 igroup_parent = comex_get_igroup_from_group(id_parent);
315 group_parent = &(igroup_parent->group);
316 comm_parent = &(igroup_parent->comm);
317
318 status = MPI_Group_incl(*group_parent, n, pid_list, group_child);
319 COMEX_ASSERT(MPI_SUCCESS == status);
320
321 #if DEBUG
322 printf("[%d] comex_group_create before crazy logic\n", RANK_OR_PID);
323 #endif
324 {
325 MPI_Comm comm, comm1, comm2;
326 int lvl=1, local_ldr_pos;
327 status = MPI_Group_rank(*group_child, &grp_me);
328 COMEX_ASSERT(MPI_SUCCESS == status);
329 if (grp_me == MPI_UNDEFINED) {
330 /* FIXME: keeping the group around for now */
331 #if DEBUG
332 printf("[%d] comex_group_create aborting -- not in group\n", RANK_OR_PID);
333 #endif
334 return COMEX_SUCCESS;
335 }
336 /* SK: sanity check for the following bitwise operations */
337 COMEX_ASSERT(grp_me>=0);
338 /* FIXME: can be optimized away */
339 status = MPI_Comm_dup(MPI_COMM_SELF, &comm);
340 COMEX_ASSERT(MPI_SUCCESS == status);
341 local_ldr_pos = grp_me;
342 while(n>lvl) {
343 int tag=0;
344 int remote_ldr_pos = local_ldr_pos^lvl;
345 if (remote_ldr_pos < n) {
346 int remote_leader = pid_list[remote_ldr_pos];
347 MPI_Comm peer_comm = *comm_parent;
348 int high = (local_ldr_pos<remote_ldr_pos)?0:1;
349 status = MPI_Intercomm_create(
350 comm, 0, peer_comm, remote_leader, tag, &comm1);
351 COMEX_ASSERT(MPI_SUCCESS == status);
352 status = MPI_Comm_free(&comm);
353 COMEX_ASSERT(MPI_SUCCESS == status);
354 status = MPI_Intercomm_merge(comm1, high, &comm2);
355 COMEX_ASSERT(MPI_SUCCESS == status);
356 status = MPI_Comm_free(&comm1);
357 COMEX_ASSERT(MPI_SUCCESS == status);
358 comm = comm2;
359 }
360 local_ldr_pos &= ((~0)^lvl);
361 lvl<<=1;
362 }
363 *comm_child = comm;
364 /* cleanup temporary group (from MPI_Group_incl above) */
365 status = MPI_Group_free(group_child);
366 COMEX_ASSERT(MPI_SUCCESS == status);
367 /* get the actual group associated with comm */
368 status = MPI_Comm_group(*comm_child, group_child);
369 COMEX_ASSERT(MPI_SUCCESS == status);
370 /* rank and size of new comm */
371 status = MPI_Comm_size(igroup_child->comm, &(igroup_child->size));
372 COMEX_ASSERT(MPI_SUCCESS == status);
373 status = MPI_Comm_rank(igroup_child->comm, &(igroup_child->rank));
374 COMEX_ASSERT(MPI_SUCCESS == status);
375 }
376 #if DEBUG
377 printf("[%d] comex_group_create after crazy logic\n", RANK_OR_PID);
378 #endif
379 _igroup_set_world_ranks(igroup_child);
380
381 return COMEX_SUCCESS;
382 }
383
384
cmplong(const void * p1,const void * p2)385 static int cmplong(const void *p1, const void *p2)
386 {
387 return *((long*)p1) - *((long*)p2);
388 }
389
390 /**
391 * Initialize group linked list. Prepopulate with world group.
392 */
comex_group_init()393 void comex_group_init()
394 {
395 int status = 0;
396 int i = 0;
397 int smallest_rank_with_same_hostid = 0;
398 int largest_rank_with_same_hostid = 0;
399 int size_node = 0;
400 comex_group_t group = 0;
401 comex_igroup_t *igroup = NULL;
402 long *sorted = NULL;
403 int count = 0;
404
405 /* populate g_state */
406
407 /* dup MPI_COMM_WORLD and get group, rank, and size */
408 status = MPI_Comm_dup(MPI_COMM_WORLD, &(g_state.comm));
409 COMEX_ASSERT(MPI_SUCCESS == status);
410 status = MPI_Comm_group(g_state.comm, &(g_state.group));
411 COMEX_ASSERT(MPI_SUCCESS == status);
412 status = MPI_Comm_rank(g_state.comm, &(g_state.rank));
413 COMEX_ASSERT(MPI_SUCCESS == status);
414 status = MPI_Comm_size(g_state.comm, &(g_state.size));
415 COMEX_ASSERT(MPI_SUCCESS == status);
416
417 #if DEBUG_TO_FILE
418 {
419 char pathname[80];
420 sprintf(pathname, "trace.%d.log", g_state.rank);
421 comex_trace_file = fopen(pathname, "w");
422 COMEX_ASSERT(NULL != comex_trace_file);
423
424 printf("[%d] comex_group_init()\n", RANK_OR_PID);
425 }
426 #endif
427
428 /* need to figure out which proc is master on each node */
429 g_state.hostid = (long*)malloc(sizeof(long)*g_state.size);
430 g_state.hostid[g_state.rank] = xgethostid();
431 status = MPI_Allgather(MPI_IN_PLACE, 1, MPI_LONG,
432 g_state.hostid, 1, MPI_LONG, g_state.comm);
433 COMEX_ASSERT(MPI_SUCCESS == status);
434 /* First create a temporary node communicator and then
435 * split further into number of gruoups within the node */
436 MPI_Comm temp_node_comm;
437 int temp_node_size;
438 /* create node comm */
439 /* MPI_Comm_split requires a non-negative color,
440 * so sort and sanitize */
441 sorted = (long*)malloc(sizeof(long) * g_state.size);
442 (void)memcpy(sorted, g_state.hostid, sizeof(long)*g_state.size);
443 qsort(sorted, g_state.size, sizeof(long), cmplong);
444 for (i=0; i<g_state.size-1; ++i) {
445 if (sorted[i] == g_state.hostid[g_state.rank])
446 {
447 break;
448 }
449 if (sorted[i] != sorted[i+1]) {
450 count += 1;
451 }
452 }
453 free(sorted);
454 #if DEBUG
455 printf("count: %d\n", count);
456 #endif
457 status = MPI_Comm_split(MPI_COMM_WORLD, count,
458 g_state.rank, &temp_node_comm);
459 int node_group_size, node_group_rank;
460 MPI_Comm_size(temp_node_comm, &node_group_size);
461 MPI_Comm_rank(temp_node_comm, &node_group_rank);
462 int node_rank0, num_nodes;
463 node_rank0 = (node_group_rank == 0) ? 1 : 0;
464 MPI_Allreduce(&node_rank0, &num_nodes, 1, MPI_INT, MPI_SUM,
465 g_state.comm);
466 smallest_rank_with_same_hostid = g_state.rank;
467 largest_rank_with_same_hostid = g_state.rank;
468 for (i=0; i<g_state.size; ++i) {
469 if (g_state.hostid[i] == g_state.hostid[g_state.rank]) {
470 ++size_node;
471 if (i < smallest_rank_with_same_hostid) {
472 smallest_rank_with_same_hostid = i;
473 }
474 if (i > largest_rank_with_same_hostid) {
475 largest_rank_with_same_hostid = i;
476 }
477 }
478 }
479 /* Get nuber of Progress-Ranks per node from environment variable
480 * equal to 1 by default */
481 int num_progress_ranks_per_node = get_num_progress_ranks_per_node();
482 /* Perform check on the number of Progress-Ranks */
483 if (size_node < 2 * num_progress_ranks_per_node) {
484 comex_error("ranks per node, must be at least",
485 2 * num_progress_ranks_per_node);
486 }
487 if (size_node % num_progress_ranks_per_node > 0) {
488 comex_error("number of ranks per node must be multiple of number of process groups per node", -1);
489 }
490 int is_node_ranks_packed = get_progress_rank_distribution_on_node();
491 int split_group_size;
492 split_group_size = node_group_size / num_progress_ranks_per_node;
493 MPI_Comm_free(&temp_node_comm);
494 g_state.master = (int*)malloc(sizeof(int)*g_state.size);
495 g_state.master[g_state.rank] = get_my_master_rank_with_same_hostid(g_state.rank,
496 split_group_size, smallest_rank_with_same_hostid, largest_rank_with_same_hostid,
497 num_progress_ranks_per_node, is_node_ranks_packed);
498 #if DEBUG
499 printf("[%d] rank; split_group_size: %d\n", g_state.rank, split_group_size);
500 printf("[%d] rank; largest_rank_with_same_hostid[%d]; my master is:[%d]\n",
501 g_state.rank, largest_rank_with_same_hostid, g_state.master[g_state.rank]);
502 #endif
503 status = MPI_Allgather(MPI_IN_PLACE, 1, MPI_INT,
504 g_state.master, 1, MPI_INT, g_state.comm);
505 COMEX_ASSERT(MPI_SUCCESS == status);
506
507 COMEX_ASSERT(group_list == NULL);
508
509 // put split group stamps
510 int proc_split_group_stamp;
511 int num_split_groups;
512 num_split_groups = num_nodes * num_progress_ranks_per_node;
513 int* split_group_list = (int*)malloc(sizeof(int)*num_split_groups);
514 int split_group_index = 0;
515 int j;
516 for (i=0; i<g_state.size; i++) {
517 for (j=0; j<i; j++) {
518 if (g_state.master[i] == g_state.master[j])
519 break;
520 }
521 if(i == j) {
522 split_group_list[split_group_index] = g_state.master[i];
523 split_group_index++;
524 }
525 }
526 // label each process
527 for (j=0; j<num_split_groups; j++) {
528 if (split_group_list[j] == g_state.master[g_state.rank]) {
529 proc_split_group_stamp = j;
530 }
531 }
532 #if DEBUG
533 printf("proc_split_group_stamp[%ld]: %ld\n",
534 g_state.rank, proc_split_group_stamp);
535 #endif
536 free(split_group_list);
537 /* create a comm of only the workers */
538 if (g_state.master[g_state.rank] == g_state.rank) {
539 /* I'm a master */
540 MPI_Comm delete_me;
541 status = MPI_Comm_split(g_state.comm, 0, g_state.rank, &delete_me);
542 COMEX_ASSERT(MPI_SUCCESS == status);
543 /* masters don't need their own comm */
544 if (MPI_COMM_NULL != delete_me) {
545 MPI_Comm_free(&delete_me);
546 }
547 #if DEBUG
548 printf("Creating comm: I AM MASTER[%ld]\n", g_state.rank);
549 #endif
550 }
551 else {
552 /* I'm a worker */
553 /* create the head of the group linked list */
554 _create_group_and_igroup(&group, &igroup);
555 status = MPI_Comm_split(
556 g_state.comm, 1, g_state.rank, &(igroup->comm));
557 COMEX_ASSERT(MPI_SUCCESS == status);
558 status = MPI_Comm_group(igroup->comm, &(igroup->group));
559 COMEX_ASSERT(MPI_SUCCESS == status);
560 status = MPI_Comm_rank(igroup->comm, &(igroup->rank));
561 COMEX_ASSERT(MPI_SUCCESS == status);
562 status = MPI_Comm_size(igroup->comm, &(igroup->size));
563 COMEX_ASSERT(MPI_SUCCESS == status);
564 _igroup_set_world_ranks(igroup);
565 COMEX_ASSERT(igroup->world_ranks != NULL);
566 #if DEBUG
567 printf("Creating comm: I AM WORKER[%ld]\n", g_state.rank);
568 #endif
569 }
570 status = MPI_Comm_split(MPI_COMM_WORLD, proc_split_group_stamp,
571 g_state.rank, &(g_state.node_comm));
572 COMEX_ASSERT(MPI_SUCCESS == status);
573 /* node rank */
574 status = MPI_Comm_rank(g_state.node_comm, &(g_state.node_rank));
575 COMEX_ASSERT(MPI_SUCCESS == status);
576 /* node size */
577 status = MPI_Comm_size(g_state.node_comm, &(g_state.node_size));
578 COMEX_ASSERT(MPI_SUCCESS == status);
579
580 #if DEBUG
581 printf("node_rank[%d]/ size[%d]\n", g_state.node_rank, g_state.node_size);
582 if (g_state.master[g_state.rank] == g_state.rank) {
583 printf("[%d] world %d/%d\tI'm a master\n",
584 RANK_OR_PID, g_state.rank, g_state.size);
585 }
586 else {
587 printf("[%d] world %d/%d\tI'm a worker\n",
588 RANK_OR_PID, g_state.rank, g_state.size);
589 }
590 #endif
591 }
592
593
comex_group_finalize()594 void comex_group_finalize()
595 {
596 int status;
597 comex_igroup_t *current_group_list_item = group_list;
598 comex_igroup_t *previous_group_list_item = NULL;
599
600 #if DEBUG
601 printf("[%d] comex_group_finalize()\n", RANK_OR_PID);
602 #endif
603
604 while (current_group_list_item != NULL) {
605 previous_group_list_item = current_group_list_item;
606 current_group_list_item = current_group_list_item->next;
607 _igroup_free(previous_group_list_item);
608 }
609
610 free(g_state.master);
611 free(g_state.hostid);
612 status = MPI_Comm_free(&(g_state.node_comm));
613 COMEX_ASSERT(MPI_SUCCESS == status);
614 status = MPI_Group_free(&(g_state.group));
615 COMEX_ASSERT(MPI_SUCCESS == status);
616 status = MPI_Comm_free(&(g_state.comm));
617 COMEX_ASSERT(MPI_SUCCESS == status);
618 }
619
620
xgethostid()621 static long xgethostid()
622 {
623 #if defined(__bgp__)
624 #warning BGP
625 long nodeid;
626 int matched,midplane,nodecard,computecard;
627 char rack_row,rack_col;
628 char location[128];
629 char location_clean[128];
630 (void) memset(location, '\0', 128);
631 (void) memset(location_clean, '\0', 128);
632 _BGP_Personality_t personality;
633 Kernel_GetPersonality(&personality, sizeof(personality));
634 BGP_Personality_getLocationString(&personality, location);
635 matched = sscanf(location, "R%c%c-M%1d-N%2d-J%2d",
636 &rack_row, &rack_col, &midplane, &nodecard, &computecard);
637 assert(matched == 5);
638 sprintf(location_clean, "%2d%02d%1d%02d%02d",
639 (int)rack_row, (int)rack_col, midplane, nodecard, computecard);
640 nodeid = atol(location_clean);
641 #elif defined(__bgq__)
642 #warning BGQ
643 int nodeid;
644 MPIX_Hardware_t hw;
645 MPIX_Hardware(&hw);
646
647 nodeid = hw.Coords[0] * hw.Size[1] * hw.Size[2] * hw.Size[3] * hw.Size[4]
648 + hw.Coords[1] * hw.Size[2] * hw.Size[3] * hw.Size[4]
649 + hw.Coords[2] * hw.Size[3] * hw.Size[4]
650 + hw.Coords[3] * hw.Size[4]
651 + hw.Coords[4];
652 #elif defined(__CRAYXT) || defined(__CRAYXE)
653 #warning CRAY
654 int nodeid;
655 # if defined(__CRAYXT)
656 PMI_Portals_get_nid(g_state.rank, &nodeid);
657 # elif defined(__CRAYXE)
658 PMI_Get_nid(g_state.rank, &nodeid);
659 # endif
660 #else
661 long nodeid = gethostid();
662 #endif
663
664 return nodeid;
665 }
666