Changeset 5653

Show
Ignore:
Timestamp:
11/01/09 05:08:30 (3 weeks ago)
Author:
balaji
Message:

Update the HYDT_bind_info structure to make it more flexible and
future proof. Also, extend the UI to allow users to make binding
requests more intelligently.

The HYDT_bind_info structure itself should provide enough flexibility
for hwloc (barring any comments from Guillaume). The user still cannot
specify arbitrarily complex binding requests. Not sure how this can be
done without overly complicating the command line interface.

This should fix ticket #911.

Location:
mpich2/trunk/src/pm/hydra
Files:
10 modified

Legend:

Unmodified
Added
Removed
  • mpich2/trunk/src/pm/hydra/include/hydra_tools.h

    r5630 r5653  
    1313HYD_status HYDT_bind_init(char *binding, char *bindlib); 
    1414void HYDT_bind_finalize(void); 
    15 HYD_status HYDT_bind_process(int proc_unit_id); 
    16 int HYDT_bind_get_proc_unit_id(int process_id); 
     15HYD_status HYDT_bind_process(int os_index); 
     16int HYDT_bind_get_os_index(int process_id); 
    1717 
    1818/* checkpointing */ 
  • mpich2/trunk/src/pm/hydra/include/hydra_utils.h

    r5630 r5653  
    161161 
    162162HYD_status HYDU_create_process(char **client_arg, HYD_env_t * env_list, 
    163                                int *in, int *out, int *err, int *pid, int proc_unit_id); 
    164 HYD_status HYDU_fork_and_exit(int proc_unit_id); 
     163                               int *in, int *out, int *err, int *pid, int os_index); 
     164HYD_status HYDU_fork_and_exit(int os_index); 
    165165#if defined HAVE_THREAD_SUPPORT 
    166166HYD_status HYDU_create_thread(void *(*func) (void *), void *args, 
  • mpich2/trunk/src/pm/hydra/pm/pmiserv/pmi_proxy_utils.c

    r5641 r5653  
    490490HYD_status HYD_pmcd_pmi_proxy_launch_procs(void) 
    491491{ 
    492     int i, j, arg, stdin_fd, process_id, proc_unit_id, pmi_id; 
     492    int i, j, arg, stdin_fd, process_id, os_index, pmi_id; 
    493493    char *str, *envstr, *list; 
    494494    char *client_args[HYD_NUM_TMP_STRINGS]; 
     
    651651            client_args[arg++] = NULL; 
    652652 
    653             proc_unit_id = HYDT_bind_get_proc_unit_id(process_id); 
     653            os_index = HYDT_bind_get_os_index(process_id); 
    654654            if (pmi_id == 0) { 
    655655                status = HYDU_create_process(client_args, prop_env, 
     
    658658                                             &HYD_pmcd_pmip.downstream.err[process_id], 
    659659                                             &HYD_pmcd_pmip.downstream.pid[process_id], 
    660                                              proc_unit_id); 
     660                                             os_index); 
    661661 
    662662                HYD_pmcd_pmip.local.stdin_buf_offset = 0; 
     
    676676                                             &HYD_pmcd_pmip.downstream.err[process_id], 
    677677                                             &HYD_pmcd_pmip.downstream.pid[process_id], 
    678                                              proc_unit_id); 
     678                                             os_index); 
    679679            } 
    680680            HYDU_ERR_POP(status, "create process returned error\n"); 
  • mpich2/trunk/src/pm/hydra/tools/bind/bind.c

    r5630 r5653  
    2121HYD_status HYDT_bind_init(char *binding, char *bindlib) 
    2222{ 
    23     char *bindstr, *bindentry; 
    24     int sock, core, thread, i, j; 
     23    char *bindstr, *bindentry, *obj; 
     24    int i, j, k, use_topo_obj[HYDT_TOPO_END] = { 0 }, child_id, found_obj; 
     25    HYDT_topo_obj_type_t topo_end; 
     26    struct HYDT_topo_obj *topo_obj[HYDT_TOPO_END]; 
    2527    HYD_status status = HYD_SUCCESS; 
    2628 
     
    2830 
    2931    HYDT_bind_info.support_level = HYDT_BIND_NONE; 
    30     HYDT_bind_info.topology = NULL; 
    3132    HYDT_bind_info.bindlib = HYDU_strdup(bindlib); 
    32  
     33    HYDT_bind_info.bindmap = NULL; 
     34 
     35    /***************************** NONE *****************************/ 
    3336    if (!binding || !strcmp(binding, "none")) { 
    3437        /* If no binding is given, we just set all mappings to -1 */ 
    3538        HYDU_MALLOC(HYDT_bind_info.bindmap, int *, sizeof(int), status); 
    36         HYDT_bind_info.num_procs = 1; 
     39        HYDT_bind_info.total_proc_units = 1; 
    3740        HYDT_bind_info.bindmap[0] = -1; 
    3841 
     
    5962    if (HYDT_bind_info.support_level == HYDT_BIND_NONE) { 
    6063        HYDU_MALLOC(HYDT_bind_info.bindmap, int *, sizeof(int), status); 
    61         HYDT_bind_info.num_procs = 1; 
     64        HYDT_bind_info.total_proc_units = 1; 
    6265        HYDT_bind_info.bindmap[0] = -1; 
    6366 
     
    6568    } 
    6669 
     70 
     71    /***************************** USER *****************************/ 
    6772    if (!strncmp(binding, "user:", strlen("user:"))) { 
    68         /* If the user specified the binding, we don't need to 
    69          * initialize anything */ 
    70  
    7173        /* Find the number of processing elements */ 
    7274        bindstr = HYDU_strdup(binding + strlen("user:")); 
    73         HYDT_bind_info.num_procs = 0; 
     75        HYDT_bind_info.total_proc_units = 0; 
    7476        bindentry = strtok(bindstr, ","); 
    7577        while (bindentry) { 
    76             HYDT_bind_info.num_procs++; 
     78            HYDT_bind_info.total_proc_units++; 
    7779            bindentry = strtok(NULL, ","); 
    7880        } 
    7981 
    8082        /* Find the actual processing elements */ 
    81         HYDU_MALLOC(HYDT_bind_info.bindmap, int *, HYDT_bind_info.num_procs * sizeof(int), 
    82                     status); 
     83        HYDU_MALLOC(HYDT_bind_info.bindmap, int *, 
     84                    HYDT_bind_info.total_proc_units * sizeof(int), status); 
    8385        i = 0; 
    8486        bindstr = HYDU_strdup(binding + strlen("user:")); 
     
    9294    } 
    9395 
    94     HYDU_MALLOC(HYDT_bind_info.bindmap, int *, HYDT_bind_info.num_procs * sizeof(int), 
    95                 status); 
    96  
    97     for (i = 0; i < HYDT_bind_info.num_procs; i++) { 
    98  
    99         /* RR is supported at the basic binding level */ 
    100         if (!strcmp(binding, "rr")) { 
     96 
     97    /***************************** RR *****************************/ 
     98    HYDU_MALLOC(HYDT_bind_info.bindmap, int *, 
     99                HYDT_bind_info.total_proc_units * sizeof(int), status); 
     100 
     101    /* RR is supported at the basic binding level */ 
     102    if (!strcmp(binding, "rr")) { 
     103        for (i = 0; i < HYDT_bind_info.total_proc_units; i++) 
    101104            HYDT_bind_info.bindmap[i] = i; 
    102             continue; 
    103         } 
    104  
    105         /* If we reached here, the user requested for topology aware 
    106          * binding. */ 
    107         if (HYDT_bind_info.support_level != HYDT_BIND_TOPO) 
    108             HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, 
    109                                 "topology binding not supported on this platform\n"); 
    110  
    111         if (!strcmp(binding, "buddy")) { 
    112             thread = i / (HYDT_bind_info.num_sockets * HYDT_bind_info.num_cores); 
    113  
    114             core = i % (HYDT_bind_info.num_sockets * HYDT_bind_info.num_cores); 
    115             core /= HYDT_bind_info.num_sockets; 
    116  
    117             sock = i % HYDT_bind_info.num_sockets; 
    118         } 
    119         else if (!strcmp(binding, "pack")) { 
    120             sock = i / (HYDT_bind_info.num_cores * HYDT_bind_info.num_threads); 
    121  
    122             core = i % (HYDT_bind_info.num_cores * HYDT_bind_info.num_threads); 
    123             core /= HYDT_bind_info.num_threads; 
    124  
    125             thread = i % HYDT_bind_info.num_threads; 
     105 
     106        goto fn_exit; 
     107    } 
     108 
     109 
     110    /* If we reached here, the user requested for topology aware 
     111     * binding. */ 
     112    if (HYDT_bind_info.support_level != HYDT_BIND_TOPO) 
     113        HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, 
     114                            "topology binding not supported on this platform\n"); 
     115 
     116 
     117    /***************************** TOPO *****************************/ 
     118    if (!strncmp(binding, "topo", strlen("topo"))) { 
     119        bindstr = HYDU_strdup(binding); 
     120        bindentry = strtok(bindstr, ":"); 
     121        bindentry = strtok(NULL, ":"); 
     122 
     123        if (bindentry == NULL) { 
     124            /* No extension option specified; use all resources */ 
     125            for (i = HYDT_TOPO_MACHINE; i < HYDT_TOPO_END; i++) 
     126                use_topo_obj[i] = 1; 
    126127        } 
    127128        else { 
    128             HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "unknown binding option\n"); 
    129         } 
    130  
    131         for (j = 0; j < HYDT_bind_info.num_procs; j++) { 
    132             if (HYDT_bind_info.topology[j].socket_rank == sock && 
    133                 HYDT_bind_info.topology[j].core_rank == core && 
    134                 HYDT_bind_info.topology[j].thread_rank == thread) { 
    135                 HYDT_bind_info.bindmap[i] = HYDT_bind_info.topology[j].processor_id; 
     129            obj = strtok(bindentry, ","); 
     130            do { 
     131                if (!strcmp(obj, "node")) 
     132                    use_topo_obj[HYDT_TOPO_NODE] = 1; 
     133                else if (!strcmp(obj, "socket") || !strcmp(obj, "sockets")) 
     134                    use_topo_obj[HYDT_TOPO_SOCKET] = 1; 
     135                else if (!strcmp(obj, "core") || !strcmp(obj, "cores")) 
     136                    use_topo_obj[HYDT_TOPO_CORE] = 1; 
     137                else if (!strcmp(obj, "thread") || !strcmp(obj, "threads")) 
     138                    use_topo_obj[HYDT_TOPO_THREAD] = 1; 
     139                else 
     140                    HYDU_ERR_POP(status, "unrecognized binding option\n"); 
     141 
     142                obj = strtok(NULL, ","); 
     143            } while (obj); 
     144        } 
     145 
     146        for (i = HYDT_TOPO_END - 1; i > HYDT_TOPO_MACHINE; i--) { 
     147            if (use_topo_obj[i]) 
     148                use_topo_obj[i - 1] = 1; 
     149        } 
     150 
     151        topo_end = HYDT_TOPO_END; 
     152        for (i = HYDT_TOPO_MACHINE; i < HYDT_TOPO_END; i++) { 
     153            if (use_topo_obj[i] == 0) { 
     154                topo_end = i; 
    136155                break; 
    137156            } 
    138157        } 
    139     } 
     158 
     159        /* Initialize indices and topology objects */ 
     160        topo_obj[HYDT_TOPO_MACHINE] = &HYDT_bind_info.machine; 
     161        for (j = HYDT_TOPO_MACHINE; j < HYDT_TOPO_END; j++) { 
     162            if (j) 
     163                topo_obj[j] = topo_obj[j - 1]->children; 
     164        } 
     165 
     166        for (i = 0; i < HYDT_bind_info.total_proc_units; i++) { 
     167            HYDT_bind_info.bindmap[i] = topo_obj[HYDT_TOPO_END - 1]->os_index; 
     168 
     169            /* If we are done, break out */ 
     170            if (i == HYDT_bind_info.total_proc_units - 1) 
     171                break; 
     172 
     173            /* If not, increment the object structure */ 
     174            found_obj = 0; 
     175 
     176            for (j = HYDT_TOPO_END - 1; j > HYDT_TOPO_MACHINE; j--) { 
     177 
     178                /* If our topology depth is greater than what the user 
     179                 * requested, don't try to find any more siblings */ 
     180                if (j >= topo_end) 
     181                    continue; 
     182 
     183                child_id = HYDT_TOPO_CHILD_ID(topo_obj[j]); 
     184                if (child_id < topo_obj[j]->parent->num_children - 1) { 
     185                    /* This object is not the last of the siblings; 
     186                     * move to the next sibling */ 
     187                    topo_obj[j] = &topo_obj[j]->parent->children[child_id + 1]; 
     188                    for (k = j + 1; k < HYDT_TOPO_END; k++) 
     189                        topo_obj[k] = topo_obj[k - 1]->children; 
     190 
     191                    found_obj = 1; 
     192                    break; 
     193                } 
     194            } 
     195 
     196            if (!found_obj) { 
     197                /* Initialize indices and topology objects */ 
     198                topo_obj[HYDT_TOPO_MACHINE] = &HYDT_bind_info.machine; 
     199                for (j = HYDT_TOPO_MACHINE; j < HYDT_TOPO_END; j++) { 
     200                    if (j) 
     201                        topo_obj[j] = topo_obj[j - 1]->children; 
     202                } 
     203            } 
     204        } 
     205 
     206        goto fn_exit; 
     207    } 
     208 
     209 
     210    /* If we reached here, the user requested for topology aware 
     211     * binding. */ 
     212    if (HYDT_bind_info.support_level != HYDT_BIND_MEMTOPO) 
     213        HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, 
     214                            "memory topology binding not supported on this platform\n"); 
     215 
     216    /***************************** TOPOMEM *****************************/ 
     217    if (!strncmp(binding, "topomem", strlen("topomem"))) { 
     218        HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, 
     219                            "memory-aware topology binding is not implemented yet\n"); 
     220    } 
     221 
    140222 
    141223  fn_exit: 
     
    147229} 
    148230 
     231static void cleanup_topo_level(struct HYDT_topo_obj level) 
     232{ 
     233    int i; 
     234 
     235    level.parent = NULL; 
     236 
     237    if (level.shared_memory_depth) 
     238        HYDU_FREE(level.shared_memory_depth); 
     239 
     240    if (level.children) 
     241        for (i = 0; i < level.num_children; i++) 
     242            cleanup_topo_level(level.children[i]); 
     243} 
     244 
    149245void HYDT_bind_finalize(void) 
    150246{ 
     
    155251        HYDU_FREE(HYDT_bind_info.bindlib); 
    156252 
    157     if (HYDT_bind_info.topology) 
    158         HYDU_FREE(HYDT_bind_info.topology); 
    159 } 
    160  
    161 HYD_status HYDT_bind_process(int core) 
     253    cleanup_topo_level(HYDT_bind_info.machine); 
     254} 
     255 
     256HYD_status HYDT_bind_process(int os_index) 
    162257{ 
    163258    HYD_status status = HYD_SUCCESS; 
     
    167262#if defined HAVE_PLPA 
    168263    if (!strcmp(HYDT_bind_info.bindlib, "plpa")) { 
    169         status = HYDT_bind_plpa_process(core); 
     264        status = HYDT_bind_plpa_process(os_index); 
    170265        HYDU_ERR_POP(status, "PLPA failure binding process to core\n"); 
    171266    } 
     
    174269#if defined HAVE_HWLOC 
    175270    if (!strcmp(HYDT_bind_info.bindlib, "hwloc")) { 
    176         status = HYDT_bind_hwloc_process(core); 
     271        status = HYDT_bind_hwloc_process(os_index); 
    177272        HYDU_ERR_POP(status, "HWLOC failure binding process to core\n"); 
    178273    } 
     
    187282} 
    188283 
    189  
    190 int HYDT_bind_get_proc_unit_id(int id) 
    191 { 
    192     return HYDT_bind_info.bindmap[id % HYDT_bind_info.num_procs]; 
    193 } 
     284int HYDT_bind_get_os_index(int process_id) 
     285{ 
     286    /* TODO: Allow the binding layer to export CPU sets instead of 
     287     * single units */ 
     288 
     289    return HYDT_bind_info.bindmap[process_id % HYDT_bind_info.total_proc_units]; 
     290} 
  • mpich2/trunk/src/pm/hydra/tools/bind/bind.h

    r5472 r5653  
    1010#include "hydra_utils.h" 
    1111 
     12#define HYDT_TOPO_CHILD_ID(obj) \ 
     13    ((((char *) obj) - ((char *) obj->parent->children)) / sizeof(struct HYDT_topo_obj)) 
     14 
    1215typedef enum { 
    1316    HYDT_BIND_NONE = 0, 
    1417    HYDT_BIND_BASIC, 
    15     HYDT_BIND_TOPO 
     18    HYDT_BIND_TOPO, 
     19    HYDT_BIND_MEMTOPO 
    1620} HYDT_bind_support_level_t; 
     21 
     22typedef enum { 
     23    HYDT_TOPO_MACHINE = 0, /* Cache-coherent set of processors */ 
     24    HYDT_TOPO_NODE, /* Sockets sharing memory dimms */ 
     25    HYDT_TOPO_SOCKET, 
     26    HYDT_TOPO_CORE, 
     27    HYDT_TOPO_THREAD, 
     28    HYDT_TOPO_END /* The last element */ 
     29} HYDT_topo_obj_type_t; 
     30 
     31struct HYDT_topo_obj { 
     32    HYDT_topo_obj_type_t type; 
     33 
     34    int os_index; /* OS index */ 
     35 
     36    struct HYDT_topo_obj *parent; 
     37 
     38    int num_children; 
     39    struct HYDT_topo_obj *children; 
     40 
     41    /* Depth of the shared memory regions. This is a pointer to 
     42     * accomodate multiple levels of memory shared by this set of 
     43     * processing units. */ 
     44    int *shared_memory_depth; 
     45}; 
    1746 
    1847struct HYDT_bind_info { 
    1948    HYDT_bind_support_level_t support_level; 
    2049 
    21     int num_procs; 
    22     int num_sockets; 
    23     int num_cores; 
    24     int num_threads; 
     50    char *bindlib; 
     51    int *bindmap; 
    2552 
    26     int *bindmap; 
    27     char *bindlib; 
     53    /* This is needed for all binding levels, except "NONE" */ 
     54    int total_proc_units; 
    2855 
    29     struct HYDT_topology { 
    30         int processor_id; 
    31  
    32         int socket_rank; 
    33         int socket_id; 
    34  
    35         int core_rank; 
    36         int core_id; 
    37  
    38         int thread_rank; 
    39         int thread_id; 
    40     } *topology; 
     56    struct HYDT_topo_obj machine; 
    4157}; 
    4258 
  • mpich2/trunk/src/pm/hydra/tools/bind/hwloc/bind_hwloc.h

    r5576 r5653  
    1212 
    1313HYD_status HYDT_bind_hwloc_init(HYDT_bind_support_level_t * support_level); 
    14 HYD_status HYDT_bind_hwloc_process(int core); 
     14HYD_status HYDT_bind_hwloc_process(int os_index); 
    1515 
    1616#endif /* BIND_PLPA_H_INCLUDED */ 
  • mpich2/trunk/src/pm/hydra/tools/bind/plpa/bind_plpa.c

    r5472 r5653  
    1717{ 
    1818    PLPA_NAME(api_type_t) p; 
    19     int ret, i, j, max, id; 
    20     int processor, sock, core, thread; 
     19    int ret, i, j, k, proc_id, socket_id, core_id, max, total_cores; 
     20    struct HYDT_topo_obj *node, *sock, *core, *thread; 
    2121    HYD_status status = HYD_SUCCESS; 
    2222 
     
    3131    /* Find the maximum number of processing elements */ 
    3232    ret = PLPA_NAME(get_processor_data) (PLPA_NAME_CAPS(COUNT_ONLINE), 
    33                                          &HYDT_bind_info.num_procs, &max); 
     33                                         &HYDT_bind_info.total_proc_units, &max); 
    3434    if (ret) { 
    3535        /* Unable to get number of processors */ 
     
    3838    } 
    3939 
    40     HYDU_MALLOC(HYDT_bind_info.topology, struct HYDT_topology *, 
    41                 HYDT_bind_info.num_procs * sizeof(struct HYDT_topology), status); 
    42     for (i = 0; i < HYDT_bind_info.num_procs; i++) { 
    43         HYDT_bind_info.topology[i].processor_id = -1; 
    44         HYDT_bind_info.topology[i].socket_rank = -1; 
    45         HYDT_bind_info.topology[i].socket_id = -1; 
    46         HYDT_bind_info.topology[i].core_rank = -1; 
    47         HYDT_bind_info.topology[i].core_id = -1; 
    48         HYDT_bind_info.topology[i].thread_rank = -1; 
    49         HYDT_bind_info.topology[i].thread_id = -1; 
    50     } 
    51  
    52     for (i = 0; i < HYDT_bind_info.num_procs; i++) { 
    53         ret = PLPA_NAME(get_processor_id) (i, PLPA_NAME_CAPS(COUNT_ALL), &processor); 
    54         if (ret) { 
    55             /* Unable to get processor ID */ 
    56             HYDU_warn_printf("plpa get processor id failed\n"); 
    57             if (HYDT_bind_info.topology) 
    58                 HYDU_FREE(HYDT_bind_info.topology); 
    59             goto fn_fail; 
    60         } 
    61         HYDT_bind_info.topology[i].processor_id = processor; 
    62     } 
    63  
    6440    /* We have qualified for basic binding support level */ 
    6541    *support_level = HYDT_BIND_BASIC; 
    6642 
    67     /* PLPA only gives information about sockets and cores */ 
    68     ret = PLPA_NAME(get_socket_info) (&HYDT_bind_info.num_sockets, &max); 
     43    /* Setup the machine level */ 
     44    HYDT_bind_info.machine.type = HYDT_TOPO_MACHINE; 
     45    HYDT_bind_info.machine.os_index = -1; /* This is a set, not a single unit */ 
     46    HYDT_bind_info.machine.parent = NULL; 
     47    HYDT_bind_info.machine.num_children = 1; 
     48    HYDU_MALLOC(HYDT_bind_info.machine.children, struct HYDT_topo_obj *, 
     49                sizeof(struct HYDT_topo_obj), status); 
     50    HYDT_bind_info.machine.shared_memory_depth = NULL; 
     51 
     52    /* Setup the node level */ 
     53    node = &HYDT_bind_info.machine.children[0]; 
     54    node->type = HYDT_TOPO_NODE; 
     55    node->os_index = -1; 
     56    node->parent =  &HYDT_bind_info.machine; 
     57    ret = PLPA_NAME(get_socket_info) (&node->num_children, &max); 
    6958    if (ret) { 
    70         /* Unable to get number of sockets */ 
    7159        HYDU_warn_printf("plpa get socket info failed\n"); 
    7260        goto fn_fail; 
    7361    } 
     62    HYDU_MALLOC(node->children, struct HYDT_topo_obj *, 
     63                sizeof(struct HYDT_topo_obj) * node->num_children, status); 
     64    node->shared_memory_depth = NULL; 
    7465 
    75     ret = PLPA_NAME(get_core_info) (0, &HYDT_bind_info.num_cores, &max); 
    76     if (ret) { 
    77         /* Unable to get number of cores */ 
    78         HYDU_warn_printf("plpa get core info failed\n"); 
     66    /* Setup the socket level */ 
     67    total_cores = 0; 
     68    for (i = 0; i < node->num_children; i++) { 
     69        sock = &node->children[i]; 
     70        sock->type = HYDT_TOPO_SOCKET; 
     71        sock->os_index = -1; 
     72        sock->parent = node; 
     73 
     74        ret = PLPA_NAME(get_socket_id) (i, &socket_id); 
     75        if (ret) { 
     76            HYDU_warn_printf("plpa get socket id failed\n"); 
     77            goto fn_fail; 
     78        } 
     79 
     80        ret = PLPA_NAME(get_core_info) (socket_id, &sock->num_children, &max); 
     81        if (ret) { 
     82            HYDU_warn_printf("plpa get core info failed\n"); 
     83            goto fn_fail; 
     84        } 
     85        HYDU_MALLOC(sock->children, struct HYDT_topo_obj *, 
     86                    sizeof(struct HYDT_topo_obj) * sock->num_children, status); 
     87        sock->shared_memory_depth = NULL; 
     88 
     89        total_cores += sock->num_children; 
     90    } 
     91 
     92    if (HYDT_bind_info.total_proc_units % total_cores) { 
     93        HYDU_warn_printf("total processing units is not a multiple of total cores\n"); 
    7994        goto fn_fail; 
    8095    } 
    8196 
    82     HYDT_bind_info.num_threads = HYDT_bind_info.num_procs / 
    83         (HYDT_bind_info.num_sockets * HYDT_bind_info.num_cores); 
     97    /* Core level objects */ 
     98    for (i = 0; i < node->num_children; i++) { 
     99        sock = &node->children[i]; 
    84100 
    85     /* Find the socket and core IDs for all processor IDs */ 
    86     for (i = 0; i < HYDT_bind_info.num_procs; i++) { 
    87         ret = PLPA_NAME(map_to_socket_core) (HYDT_bind_info.topology[i].processor_id, 
    88                                              &sock, &core); 
     101        for (j = 0; j < sock->num_children; j++) { 
     102            core = &sock->children[j]; 
     103            core->type = HYDT_TOPO_CORE; 
     104            core->os_index = -1; 
     105            core->parent = sock; 
     106            core->num_children = HYDT_bind_info.total_proc_units / total_cores; 
     107            HYDU_MALLOC(core->children, struct HYDT_topo_obj *, 
     108                        sizeof(struct HYDT_topo_obj) * sock->num_children, status); 
     109            core->shared_memory_depth = NULL; 
     110 
     111            for (k = 0; k < core->num_children; k++) { 
     112                thread = &core->children[k]; 
     113                thread->type = HYDT_TOPO_THREAD; 
     114                thread->os_index = -1; 
     115                thread->parent = core; 
     116                thread->num_children = 0; 
     117                thread->children = NULL; 
     118                thread->shared_memory_depth = NULL; 
     119            } 
     120        } 
     121    } 
     122 
     123    for (i = 0; i < HYDT_bind_info.total_proc_units; i++) { 
     124        ret = PLPA_NAME(get_processor_id) (i, PLPA_NAME_CAPS(COUNT_ONLINE), &proc_id); 
    89125        if (ret) { 
    90             /* Unable to get number of cores */ 
     126            HYDU_warn_printf("plpa unable to get processor id\n"); 
     127            goto fn_fail; 
     128        } 
     129 
     130        ret = PLPA_NAME(map_to_socket_core) (proc_id, &socket_id, &core_id); 
     131        if (ret) { 
    91132            HYDU_warn_printf("plpa unable to map socket to core\n"); 
    92133            goto fn_fail; 
    93134        } 
    94135 
    95         HYDT_bind_info.topology[i].socket_id = sock; 
    96         HYDT_bind_info.topology[i].core_id = core; 
    97  
    98         thread = -1; 
    99         for (j = 0; j < i; j++) 
    100             if (HYDT_bind_info.topology[j].socket_id == sock && 
    101                 HYDT_bind_info.topology[j].core_id == core) 
    102                 thread = HYDT_bind_info.topology[j].thread_id; 
    103         thread++; 
    104  
    105         HYDT_bind_info.topology[i].thread_id = thread; 
    106         HYDT_bind_info.topology[i].thread_rank = thread; 
    107     } 
    108  
    109     /* Find the rank of each socket ID */ 
    110     for (i = 0; i < HYDT_bind_info.num_sockets; i++) { 
    111         ret = PLPA_NAME(get_socket_id) (i, &id); 
    112         if (ret) { 
    113             /* Unable to get socket id */ 
    114             HYDU_warn_printf("plpa unable to get socket id\n"); 
    115             goto fn_fail; 
     136        for (j = 0; j < HYDT_bind_info.total_proc_units / total_cores; j++) { 
     137            thread = &node->children[socket_id].children[core_id].children[j]; 
     138            if (thread->os_index == -1) { 
     139                thread->os_index = i; 
     140                break; 
     141            } 
    116142        } 
    117         for (j = 0; j < HYDT_bind_info.num_procs; j++) 
    118             if (HYDT_bind_info.topology[j].socket_id == id) 
    119                 HYDT_bind_info.topology[j].socket_rank = i; 
    120     } 
    121  
    122     /* Find the rank of each core ID */ 
    123     for (i = 0; i < HYDT_bind_info.num_cores; i++) { 
    124         ret = PLPA_NAME(get_core_id) (HYDT_bind_info.topology[0].socket_id, i, &id); 
    125         if (ret) { 
    126             /* Unable to get socket id */ 
    127             HYDU_warn_printf("plpa unable to get socket id\n"); 
    128             goto fn_fail; 
    129         } 
    130         for (j = 0; j < HYDT_bind_info.num_procs; j++) 
    131             if (HYDT_bind_info.topology[j].core_id == id) 
    132                 HYDT_bind_info.topology[j].core_rank = i; 
    133143    } 
    134144 
     
    144154} 
    145155 
    146 HYD_status HYDT_bind_plpa_process(int core) 
     156HYD_status HYDT_bind_plpa_process(int os_index) 
    147157{ 
    148158    int ret; 
     
    152162    HYDU_FUNC_ENTER(); 
    153163 
    154     /* If the specified core is negative, we just ignore it */ 
    155     if (core < 0) 
     164    /* If the specified os_index is negative, we just ignore it */ 
     165    if (os_index < 0) 
    156166        goto fn_exit; 
    157167 
    158168    PLPA_NAME_CAPS(CPU_ZERO) (&cpuset); 
    159     PLPA_NAME_CAPS(CPU_SET) (core % HYDT_bind_info.num_procs, &cpuset); 
     169    PLPA_NAME_CAPS(CPU_SET) (os_index % HYDT_bind_info.total_proc_units, &cpuset); 
    160170    ret = PLPA_NAME(sched_setaffinity) (0, 1, &cpuset); 
    161171    if (ret) 
  • mpich2/trunk/src/pm/hydra/tools/bind/plpa/bind_plpa.h

    r5472 r5653  
    99 
    1010HYD_status HYDT_bind_plpa_init(HYDT_bind_support_level_t * support_level); 
    11 HYD_status HYDT_bind_plpa_process(int core); 
     11HYD_status HYDT_bind_plpa_process(int os_index); 
    1212 
    1313#endif /* BIND_PLPA_H_INCLUDED */ 
  • mpich2/trunk/src/pm/hydra/ui/mpiexec/utils.c

    r5589 r5653  
    685685        printf("        none -- no binding\n"); 
    686686        printf("        rr   -- round-robin as OS assigned processor IDs\n"); 
    687         printf("        buddy -- order of least shared resources\n"); 
    688         printf("        pack  -- order of most shared resources\n\n"); 
    689687        printf("        user:0,1,3,2 -- user specified binding\n"); 
     688        printf("        topo -- CPU topology-aware binding\n"); 
     689        printf("        topomem -- memory topology-aware binding\n\n"); 
     690 
     691        printf("    CPU options (supported on topology-capable binding libs):\n"); 
     692        printf("        topo (with no options) -- use all CPU resources\n"); 
     693        printf("        topo:sockets,cores,threads -- use all CPU resources\n"); 
     694        printf("        topo:sockets,cores -- avoid using multiple threads on a core\n"); 
     695        printf("        topo:sockets -- avoid using multiple cores on a socket\n"); 
     696 
     697        printf("    Memory options (supported on memory topology aware binding libs):\n"); 
     698        printf("        topomem:l1,l2,l3,mem -- use all memory resources\n"); 
     699        printf("        topomem:l2,l3,mem -- avoid sharing l1 cache\n"); 
     700        printf("        topomem:l3,mem -- avoid using l2 cache\n"); 
     701        printf("        topomem:mem -- avoid using l3 cache\n"); 
    690702        HYDU_ERR_SETANDJUMP(status, HYD_GRACEFUL_ABORT, ""); 
    691703    } 
  • mpich2/trunk/src/pm/hydra/utils/launch/launch.c

    r5630 r5653  
    99 
    1010HYD_status HYDU_create_process(char **client_arg, HYD_env_t * env_list, 
    11                                int *in, int *out, int *err, int *pid, int proc_unit_id) 
     11                               int *in, int *out, int *err, int *pid, int os_index) 
    1212{ 
    1313    int inpipe[2], outpipe[2], errpipe[2], tpid; 
     
    6060        } 
    6161 
    62         if (proc_unit_id >= 0) { 
    63             status = HYDT_bind_process(proc_unit_id); 
     62        if (os_index >= 0) { 
     63            status = HYDT_bind_process(os_index); 
    6464            HYDU_ERR_POP(status, "bind process failed\n"); 
    6565        } 
     
    101101 
    102102 
    103 HYD_status HYDU_fork_and_exit(int proc_unit_id) 
     103HYD_status HYDU_fork_and_exit(int os_index) 
    104104{ 
    105105    pid_t tpid; 
     
    115115        close(2); 
    116116 
    117         if (proc_unit_id >= 0) { 
    118             status = HYDT_bind_process(proc_unit_id); 
     117        if (os_index >= 0) { 
     118            status = HYDT_bind_process(os_index); 
    119119            HYDU_ERR_POP(status, "bind process failed\n"); 
    120120        }