Logo AND Algorithmique Numérique Distribuée

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