Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
leaks --
[simgrid.git] / src / smpi / colls / allgather-mvapich-smp.c
1 /* Copyright (c) 2013-2014. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 /*
8  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
9  *                         University Research and Technology
10  *                         Corporation.  All rights reserved.
11  * Copyright (c) 2004-2009 The University of Tennessee and The University
12  *                         of Tennessee Research Foundation.  All rights
13  *                         reserved.
14  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
15  *                         University of Stuttgart.  All rights reserved.
16  * Copyright (c) 2004-2005 The Regents of the University of California.
17  *                         All rights reserved.
18  *
19  * Additional copyrights may follow
20  */
21  /* -*- Mode: C; c-basic-offset:4 ; -*- */
22 /* Copyright (c) 2001-2014, The Ohio State University. All rights
23  * reserved.
24  *
25  * This file is part of the MVAPICH2 software package developed by the
26  * team members of The Ohio State University's Network-Based Computing
27  * Laboratory (NBCL), headed by Professor Dhabaleswar K. (DK) Panda.
28  *
29  * For detailed copyright and licensing information, please refer to the
30  * copyright file COPYRIGHT in the top level MVAPICH2 directory.
31  */
32 /*
33  *
34  *  (C) 2001 by Argonne National Laboratory.
35  *      See COPYRIGHT in top-level directory.
36  */
37  #include "colls_private.h"
38
39
40
41 int smpi_coll_tuned_allgather_mvapich2_smp(void *sendbuf,int sendcnt, MPI_Datatype sendtype,
42                             void *recvbuf, int recvcnt,MPI_Datatype recvtype,
43                             MPI_Comm  comm)
44 {
45     int rank, size;
46     int local_rank, local_size;
47     int leader_comm_size = 0; 
48     int mpi_errno = MPI_SUCCESS;
49     MPI_Aint recvtype_extent = 0;  /* Datatype extent */
50     MPI_Comm shmem_comm, leader_comm;
51
52   if(smpi_comm_get_leaders_comm(comm)==MPI_COMM_NULL){
53     smpi_comm_init_smp(comm);
54   }
55   
56     if(!smpi_comm_is_uniform(comm) || !smpi_comm_is_blocked(comm))
57     THROWF(arg_error,0, "allgather MVAPICH2 smp algorithm can't be used with irregular deployment. Please insure that processes deployed on the same node are contiguous and that each node has the same number of processes");
58   
59     if (recvcnt == 0) {
60         return MPI_SUCCESS;
61     }
62
63     rank = smpi_comm_rank(comm);
64     size = smpi_comm_size(comm);
65
66     /* extract the rank,size information for the intra-node
67      * communicator */
68     recvtype_extent=smpi_datatype_get_extent(recvtype);
69     
70     shmem_comm = smpi_comm_get_intra_comm(comm);
71     local_rank = smpi_comm_rank(shmem_comm);
72     local_size = smpi_comm_size(shmem_comm);
73
74     if (local_rank == 0) {
75         /* Node leader. Extract the rank, size information for the leader
76          * communicator */
77         leader_comm = smpi_comm_get_leaders_comm(comm);
78         if(leader_comm==MPI_COMM_NULL){
79           leader_comm = MPI_COMM_WORLD;
80         }
81         leader_comm_size = smpi_comm_size(leader_comm);
82     }
83
84     /*If there is just one node, after gather itself,
85      * root has all the data and it can do bcast*/
86     if(local_rank == 0) {
87         mpi_errno = mpi_coll_gather_fun(sendbuf, sendcnt,sendtype, 
88                                     (void*)((char*)recvbuf + (rank * recvcnt * recvtype_extent)), 
89                                      recvcnt, recvtype,
90                                      0, shmem_comm);
91     } else {
92         /*Since in allgather all the processes could have 
93          * its own data in place*/
94         if(sendbuf == MPI_IN_PLACE) {
95             mpi_errno = mpi_coll_gather_fun((void*)((char*)recvbuf + (rank * recvcnt * recvtype_extent)), 
96                                          recvcnt , recvtype, 
97                                          recvbuf, recvcnt, recvtype,
98                                          0, shmem_comm);
99         } else {
100             mpi_errno = mpi_coll_gather_fun(sendbuf, sendcnt,sendtype, 
101                                          recvbuf, recvcnt, recvtype,
102                                          0, shmem_comm);
103         }
104     }
105     /* Exchange the data between the node leaders*/
106     if (local_rank == 0 && (leader_comm_size > 1)) {
107         /*When data in each socket is different*/
108         if (smpi_comm_is_uniform(comm) != 1) {
109
110             int *displs = NULL;
111             int *recvcnts = NULL;
112             int *node_sizes = NULL;
113             int i = 0;
114
115             node_sizes = smpi_comm_get_non_uniform_map(comm);
116
117             displs = xbt_malloc(sizeof (int) * leader_comm_size);
118             recvcnts = xbt_malloc(sizeof (int) * leader_comm_size);
119             if (!displs || !recvcnts) {
120                 return MPI_ERR_OTHER;
121             }
122             recvcnts[0] = node_sizes[0] * recvcnt;
123             displs[0] = 0;
124
125             for (i = 1; i < leader_comm_size; i++) {
126                 displs[i] = displs[i - 1] + node_sizes[i - 1] * recvcnt;
127                 recvcnts[i] = node_sizes[i] * recvcnt;
128             }
129
130
131             void* sendbuf=((char*)recvbuf)+smpi_datatype_get_extent(recvtype)*displs[smpi_comm_rank(leader_comm)];
132
133             mpi_errno = mpi_coll_allgatherv_fun(sendbuf,
134                                        (recvcnt*local_size),
135                                        recvtype, 
136                                        recvbuf, recvcnts,
137                                        displs, recvtype,
138                                        leader_comm);
139             xbt_free(displs);
140             xbt_free(recvcnts);
141         } else {
142         void* sendtmpbuf=((char*)recvbuf)+smpi_datatype_get_extent(recvtype)*(recvcnt*local_size)*smpi_comm_rank(leader_comm);
143         
144           
145
146             mpi_errno = smpi_coll_tuned_allgather_mpich(sendtmpbuf, 
147                                                (recvcnt*local_size),
148                                                recvtype,
149                                                recvbuf, (recvcnt*local_size), recvtype,
150                                              leader_comm);
151
152         }
153     }
154
155     /*Bcast the entire data from node leaders to all other cores*/
156     mpi_errno = mpi_coll_bcast_fun (recvbuf, recvcnt * size, recvtype, 0, shmem_comm);
157     return mpi_errno;
158 }