Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
123de2ce44fb6a3eb9b6ced870697be1d6b65baf
[simgrid.git] / src / smpi / colls / allreduce / allreduce-mvapich-two-level.cpp
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
38 #include "../colls_private.h"
39
40 #define MPIR_Allreduce_pt2pt_rd_MV2 Coll_allreduce_rdb::allreduce
41 #define MPIR_Allreduce_pt2pt_rs_MV2 Coll_allreduce_mvapich2_rs::allreduce
42
43 extern int (*MV2_Allreducection)(void *sendbuf,
44     void *recvbuf,
45     int count,
46     MPI_Datatype datatype,
47     MPI_Op op, MPI_Comm comm);
48
49
50 extern int (*MV2_Allreduce_intra_function)( void *sendbuf,
51     void *recvbuf,
52     int count,
53     MPI_Datatype datatype,
54     MPI_Op op, MPI_Comm comm);
55     
56 static  int MPIR_Allreduce_reduce_p2p_MV2( void *sendbuf,
57     void *recvbuf,
58     int count,
59     MPI_Datatype datatype,
60     MPI_Op op, MPI_Comm  comm)
61 {
62   Colls::reduce(sendbuf,recvbuf,count,datatype,op,0,comm);
63   return MPI_SUCCESS;
64 }
65
66 static  int MPIR_Allreduce_reduce_shmem_MV2( void *sendbuf,
67     void *recvbuf,
68     int count,
69     MPI_Datatype datatype,
70     MPI_Op op, MPI_Comm  comm)
71 {
72   Colls::reduce(sendbuf,recvbuf,count,datatype,op,0,comm);
73   return MPI_SUCCESS;
74 }
75     
76     
77 /* general two level allreduce helper function */
78 int Coll_allreduce_mvapich2_two_level::allreduce(void *sendbuf,
79                              void *recvbuf,
80                              int count,
81                              MPI_Datatype datatype,
82                              MPI_Op op, MPI_Comm comm)
83 {
84     int mpi_errno = MPI_SUCCESS;
85     int total_size = 0;
86     MPI_Aint true_lb, true_extent;
87     MPI_Comm shmem_comm = MPI_COMM_NULL, leader_comm = MPI_COMM_NULL;
88     int local_rank = -1, local_size = 0;
89
90     //if not set (use of the algo directly, without mvapich2 selector)
91     if(MV2_Allreduce_intra_function==NULL)
92       MV2_Allreduce_intra_function = Coll_allreduce_mpich::allreduce;
93     if(MV2_Allreducection==NULL)
94       MV2_Allreducection = Coll_allreduce_rdb::allreduce;
95     
96     if(comm->get_leaders_comm()==MPI_COMM_NULL){
97       comm->init_smp();
98     }
99   
100     if (count == 0) {
101         return MPI_SUCCESS;
102     }
103     datatype->extent(&true_lb,
104                                        &true_extent);
105
106     total_size = comm->size();
107     shmem_comm = comm->get_intra_comm();
108     local_rank = shmem_comm->rank();
109     local_size = shmem_comm->size();
110
111     leader_comm = comm->get_leaders_comm();
112
113     if (local_rank == 0) {
114         if (sendbuf != MPI_IN_PLACE) {
115             Datatype::copy(sendbuf, count, datatype, recvbuf,
116                                        count, datatype);
117         }
118     }
119
120     /* Doing the shared memory gather and reduction by the leader */
121     if (local_rank == 0) {
122         if ((MV2_Allreduce_intra_function == &MPIR_Allreduce_reduce_shmem_MV2) || 
123               (MV2_Allreduce_intra_function == &MPIR_Allreduce_reduce_p2p_MV2) ) {
124         mpi_errno =
125         MV2_Allreduce_intra_function(sendbuf, recvbuf, count, datatype,
126                                      op, comm);
127         }
128         else {
129         mpi_errno =
130         MV2_Allreduce_intra_function(sendbuf, recvbuf, count, datatype,
131                                      op, shmem_comm);
132         }
133
134         if (local_size != total_size) {
135           void* sendtmpbuf = (char *)smpi_get_tmp_sendbuffer(count*datatype->get_extent());
136           Datatype::copy(recvbuf, count, datatype,sendtmpbuf, count, datatype);
137             /* inter-node allreduce */
138             if(MV2_Allreducection == &MPIR_Allreduce_pt2pt_rd_MV2){
139                 mpi_errno =
140                     MPIR_Allreduce_pt2pt_rd_MV2(sendtmpbuf, recvbuf, count, datatype, op,
141                                       leader_comm);
142             } else {
143                 mpi_errno =
144                     MPIR_Allreduce_pt2pt_rs_MV2(sendtmpbuf, recvbuf, count, datatype, op,
145                                       leader_comm);
146             }
147             smpi_free_tmp_buffer(sendtmpbuf);
148         }
149     } else {
150         /* insert the first reduce here */
151         if ((MV2_Allreduce_intra_function == &MPIR_Allreduce_reduce_shmem_MV2) || 
152               (MV2_Allreduce_intra_function == &MPIR_Allreduce_reduce_p2p_MV2) ) {
153         mpi_errno =
154         MV2_Allreduce_intra_function(sendbuf, recvbuf, count, datatype,
155                                      op, comm);
156         }
157         else {
158         mpi_errno =
159         MV2_Allreduce_intra_function(sendbuf, recvbuf, count, datatype,
160                                      op, shmem_comm);
161         }
162     }
163
164     /* Broadcasting the mesage from leader to the rest */
165     /* Note: shared memory broadcast could improve the performance */
166     mpi_errno = Colls::bcast(recvbuf, count, datatype, 0, shmem_comm);
167
168     return (mpi_errno);
169
170 }