Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
7e453a866b7fdc629ff70868b50ffaf2236f3303
[simgrid.git] / src / smpi / colls / alltoall / alltoall-pair.cpp
1 /* Copyright (c) 2013-2020. 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 #include "../colls_private.hpp"
8 #include "smpi_win.hpp"
9
10 /*****************************************************************************
11
12  * Function: alltoall_pair
13
14  * Return: int
15
16  * Inputs:
17     send_buff: send input buffer
18     send_count: number of elements to send
19     send_type: data type of elements being sent
20     recv_buff: receive output buffer
21     recv_count: number of elements to received
22     recv_type: data type of elements being received
23     comm: communicator
24
25  * Descrp: Function works when P is power of two. In each phase of P - 1
26            phases, nodes in pair communicate their data.
27
28  * Author: Ahmad Faraj
29
30  ****************************************************************************/
31 namespace simgrid{
32 namespace smpi{
33 int alltoall__pair_rma(const void *send_buff, int send_count, MPI_Datatype send_type,
34                        void *recv_buff, int recv_count, MPI_Datatype recv_type,
35                        MPI_Comm comm)
36 {
37
38   MPI_Aint send_chunk, recv_chunk;
39   MPI_Win win;
40   int assert = 0;
41   int i, dst, rank, num_procs;
42
43   char *send_ptr = (char *) send_buff;
44
45   rank = comm->rank();
46   num_procs = comm->size();
47   send_chunk = send_type->get_extent();
48   recv_chunk = recv_type->get_extent();
49
50   win = new Win(recv_buff, num_procs * recv_chunk * send_count, recv_chunk, nullptr, comm);
51   send_chunk *= send_count;
52   recv_chunk *= recv_count;
53
54   win->fence(assert);
55   for (i = 0; i < num_procs; i++) {
56     dst = rank ^ i;
57     win->put(send_ptr + dst * send_chunk, send_count, send_type, dst,
58             rank /* send_chunk*/, send_count, send_type);
59   }
60   win->fence(assert);
61   delete win;
62   return 0;
63 }
64
65
66 int alltoall__pair(const void *send_buff, int send_count,
67                    MPI_Datatype send_type,
68                    void *recv_buff, int recv_count,
69                    MPI_Datatype recv_type, MPI_Comm comm)
70 {
71
72   MPI_Aint send_chunk, recv_chunk;
73   MPI_Status s;
74   int i, src, dst, rank, num_procs;
75   int tag = COLL_TAG_ALLTOALL;
76   char *send_ptr = (char *) send_buff;
77   char *recv_ptr = (char *) recv_buff;
78
79   rank = comm->rank();
80   num_procs = comm->size();
81
82   if((num_procs&(num_procs-1)))
83     throw std::invalid_argument("alltoall pair algorithm can't be used with non power of two number of processes!");
84
85   send_chunk = send_type->get_extent();
86   recv_chunk = recv_type->get_extent();
87
88   send_chunk *= send_count;
89   recv_chunk *= recv_count;
90
91   for (i = 0; i < num_procs; i++) {
92     src = dst = rank ^ i;
93     Request::sendrecv(send_ptr + dst * send_chunk, send_count, send_type, dst, tag, recv_ptr + src * recv_chunk,
94                       recv_count, recv_type, src, tag, comm, &s);
95   }
96
97   return MPI_SUCCESS;
98 }
99 }
100 }