source: ThirdParty/vmg/src/comm/mpi/datatype.cpp

Candidate_v1.6.1
Last change on this file was 7faa5c, checked in by Frederik Heber <heber@…>, 9 years ago

Merge commit 'de061d9d851257a04e924d4472df4523d33bb08b' as 'ThirdParty/vmg'

  • Property mode set to 100644
File size: 6.2 KB
Line 
1/*
2 * vmg - a versatile multigrid solver
3 * Copyright (C) 2012 Institute for Numerical Simulation, University of Bonn
4 *
5 * vmg is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * vmg is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19/**
20 * @file datatype.cpp
21 * @author Julian Iseringhausen <isering@ins.uni-bonn.de>
22 * @date Tue Apr 09 12:19:58 2013
23 *
24 * @brief Helper class to handle MPI datatypes.
25 *
26 */
27
28#ifdef HAVE_CONFIG_H
29#include <libvmg_config.h>
30#endif
31
32#ifndef HAVE_MPI
33#error MPI is needed to compile VMG::MPI::Datatype
34#endif
35
36#include <mpi.h>
37#ifdef HAVE_MARMOT
38#include <enhancempicalls.h>
39#include <sourceinfompicalls.h>
40#endif
41
42#include <cstring>
43#include <sstream>
44
45#include "comm/mpi/datatype.hpp"
46
47using namespace VMG;
48
49void VMG::MPI::Datatype::Send(Grid& grid, const int& tag, const MPI_Comm& comm) const
50{
51 if (Feasible())
52 MPI_Send(&grid(0), 1, _type, _rank, _tag_send+tag, comm);
53}
54
55void VMG::MPI::Datatype::Isend(Grid& grid, const int& tag, const MPI_Comm& comm, MPI_Request& request) const
56{
57 if (Feasible())
58 MPI_Isend(&grid(0), 1, _type, _rank, _tag_send+tag, comm, &request);
59}
60
61void VMG::MPI::Datatype::Recv(Grid& grid, const int& tag, const MPI_Comm& comm) const
62{
63 if (Feasible())
64 MPI_Recv(&grid(0), 1 ,_type, _rank, _tag_recv+tag, comm, MPI_STATUS_IGNORE);
65}
66
67void VMG::MPI::Datatype::Irecv(Grid& grid, const int& tag, const MPI_Comm& comm, MPI_Request& request) const
68{
69 if (Feasible())
70 MPI_Irecv(&grid(0), 1, _type, _rank, _tag_recv+tag, comm, &request);
71}
72
73void VMG::MPI::Datatype::SendBuffered(const Grid& grid, const int& tag, const MPI_Comm& comm)
74{
75 if (Feasible()) {
76
77 Index i;
78 int c = 0;
79 const Index end = _starts + _subsizes;
80 const size_t memcpy_size = _subsizes.Z() * sizeof(vmg_float);
81
82 for (i.X()=_starts.X(); i.X()<end.X(); ++i.X())
83 for (i.Y()=_starts.Y(); i.Y()<end.Y(); ++i.Y()) {
84 std::memcpy(&_buffer[c], &grid.GetVal(i.X(), i.Y(), _starts.Z()), memcpy_size);
85 c += _subsizes.Z();
86 }
87
88 MPI_Send(&_buffer.front(), _buffer.size(), MPI_DOUBLE, _rank, _tag_send+tag, comm);
89 }
90}
91
92void VMG::MPI::Datatype::IsendBuffered(const Grid& grid, const int& tag, const MPI_Comm& comm, MPI_Request& request)
93{
94 if (Feasible()) {
95
96 Index i;
97 unsigned int c = 0;
98 const Index end = _starts + _subsizes;
99 const size_t memcpy_size = _subsizes.Z() * sizeof(vmg_float);
100
101 for (i.X()=_starts.X(); i.X()<end.X(); ++i.X())
102 for (i.Y()=_starts.Y(); i.Y()<end.Y(); ++i.Y()) {
103 std::memcpy(&_buffer[c], &grid.GetVal(i.X(), i.Y(), _starts.Z()), memcpy_size);
104 c += _subsizes.Z();
105 }
106
107 assert(c == _buffer.size());
108
109 MPI_Isend(&_buffer.front(), _buffer.size(), MPI_DOUBLE, _rank, _tag_send+tag, comm, &request);
110 }
111}
112
113void VMG::MPI::Datatype::RecvBuffered(const int& tag, const MPI_Comm& comm)
114{
115 if (Feasible())
116 MPI_Recv(&_buffer.front(), _buffer.size(), MPI_DOUBLE, _rank, _tag_recv+tag, comm, MPI_STATUS_IGNORE);
117}
118
119void VMG::MPI::Datatype::IrecvBuffered(const int& tag, const MPI_Comm& comm, MPI_Request& request)
120{
121 if (Feasible())
122 MPI_Irecv(&_buffer.front(), _buffer.size(), MPI_DOUBLE, _rank, _tag_recv+tag, comm, &request);
123}
124
125void VMG::MPI::Datatype::GridReplace(Grid& grid) const
126{
127 if (Feasible()) {
128
129 Index i;
130 unsigned int c = 0;
131 const Index end = _starts + _subsizes;
132 const size_t memcpy_size = _subsizes.Z() * sizeof(vmg_float);
133
134 for (i.X()=_starts.X(); i.X()<end.X(); ++i.X())
135 for (i.Y()=_starts.Y(); i.Y()<end.Y(); ++i.Y()) {
136 std::memcpy(&grid(i.X(), i.Y(), _starts.Z()), &_buffer[c], memcpy_size);
137 c += _subsizes.Z();
138 }
139
140 assert(c == _buffer.size());
141 }
142}
143
144void VMG::MPI::Datatype::GridSum(Grid& grid) const
145{
146 if (Feasible()) {
147
148 Index i;
149 const Index end = _starts + _subsizes;
150 std::vector<vmg_float>::const_iterator iter = _buffer.begin();
151
152 for (i.X()=_starts.X(); i.X()<end.X(); ++i.X())
153 for (i.Y()=_starts.Y(); i.Y()<end.Y(); ++i.Y())
154 for (i.Z()=_starts.Z(); i.Z()<end.Z(); ++i.Z())
155 grid(i) += *iter++;
156
157 assert(iter == _buffer.end());
158 }
159}
160
161void VMG::MPI::Datatype::Set(const GridIteratorSet& bounds, const Grid& grid, const int& rank,
162 const int& tag_send, const int& tag_receive)
163{
164 _sizes = grid.Local().SizeTotal();
165 _subsizes = bounds.Begin().GetEnd() - bounds.Begin().GetBegin();
166 _starts = bounds.Begin().GetBegin();
167 _rank = rank;
168 _tag_send = tag_send;
169 _tag_recv = tag_receive;
170
171 if (_type != MPI_DATATYPE_NULL)
172 MPI_Type_free(&_type);
173
174 InitDatatype();
175}
176
177void VMG::MPI::Datatype::Set(const Index& sizes, const Index& subsizes, const Index& starts, const int& rank,
178 const int& tag_send, const int& tag_receive)
179{
180 _sizes = sizes;
181 _subsizes = subsizes;
182 _starts = starts;
183 _rank = rank;
184 _tag_send = tag_send;
185 _tag_recv = tag_receive;
186
187 if (_type != MPI_DATATYPE_NULL)
188 MPI_Type_free(&_type);
189
190 InitDatatype();
191}
192
193void VMG::MPI::Datatype::InitDatatype()
194{
195 if (Feasible()) {
196 MPI_Type_create_subarray(3, _sizes.vec(), _subsizes.vec(), _starts.vec(), MPI_ORDER_C, MPI_DOUBLE, &_type);
197 MPI_Type_commit(&_type);
198 if (_alloc_buffer)
199 _buffer.resize(_subsizes.Product());
200 }else {
201 _type = MPI_DATATYPE_NULL;
202 }
203}
204
205std::string VMG::MPI::Datatype::ToString() const
206{
207 std::stringstream str;
208 str << "VMG::MPI::Datatype {" << std::endl
209 << " Rank: " << _rank << std::endl
210 << " TagSend: " << _tag_send << std::endl
211 << " TagReceive: " << _tag_recv << std::endl
212 << " Sizes: " << _sizes << std::endl
213 << " Subsizes: " << _subsizes << std::endl
214 << " Starts: " << _starts << std::endl
215 << " AllocBuffer: " << _alloc_buffer << std::endl
216 << "}";
217
218 return str.str();
219}
Note: See TracBrowser for help on using the repository browser.