FEI Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
snl_fei_RecordMsgHandler.cpp
Go to the documentation of this file.
1/*--------------------------------------------------------------------*/
2/* Copyright 2005 Sandia Corporation. */
3/* Under the terms of Contract DE-AC04-94AL85000, there is a */
4/* non-exclusive license for use of this work by or on behalf */
5/* of the U.S. Government. Export of this program may require */
6/* a license from the United States Government. */
7/*--------------------------------------------------------------------*/
8
9#include "fei_sstream.hpp"
10
14#include "fei_FieldMask.hpp"
15#include "fei_TemplateUtils.hpp"
16
17#undef fei_file
18#define fei_file "snl_fei_RecordMsgHandler.cpp"
19#include "fei_ErrMacros.hpp"
20
22 RecordCollection* recordCollection,
23 snl_fei::PointBlockMap& ptBlkMap,
24 std::vector<fei::FieldMask*>& fieldMasks,
25 std::vector<int>& eqnNumbers)
26 :sendPattern_(NULL),
27 recvPattern_(NULL),
28 recordCollection_(recordCollection),
29 ptBlkMap_(ptBlkMap),
30 fieldMasks_(fieldMasks),
31 whichTask_(_FieldMasks_),
32 sendProcs_(0, 32),
33 recvProcs_(0, 32),
34 eqnNumbers_(eqnNumbers),
35 localProc_(localProc)
36{
37}
38
40{
41}
42
44{
45 fei::copyKeysToVector(sendPattern_->getMap(), sendProcs_);
46 return(sendProcs_);
47}
48
50{
51 fei::copyKeysToVector(recvPattern_->getMap(), recvProcs_);
52 return(recvProcs_);
53}
54
56 int& messageLength)
57{
58 if (sendPattern_ == NULL || recvPattern_ == NULL) ERReturn(-1);
59
60 switch(whichTask_) {
61 case _FieldMasks_:
62 messageLength = localFieldMaskMessageSize(fieldMasks_); break;
63 case _MaskIDs_:
64 messageLength = sendPattern_->getRow(destProc)->size(); break;
65 case _EqnNumbers_:
66 messageLength = eqnNumbersMsgLength(destProc); break;
67 default:
68 std::abort();
69 }
70
71 return(0);
72}
73
75 std::vector<int>& message)
76{
77 switch(whichTask_) {
78 case _FieldMasks_:
79 CHK_ERR( packLocalFieldMasks(fieldMasks_, message) ); break;
80 case _MaskIDs_:
81 CHK_ERR( packMaskIDs(destProc, message) ); break;
82 case _EqnNumbers_:
83 CHK_ERR( packEqnNumbersMsg(destProc, message) ); break;
84 default:
85 std::abort();
86 }
87
88 return(0);
89}
90
92 std::vector<int>& message)
93{
94 switch(whichTask_) {
95 case _FieldMasks_:
96 CHK_ERR( addFieldMasks(message, fieldMasks_) ); break;
97 case _MaskIDs_:
98 CHK_ERR( mergeMaskIDs(srcProc, message) ); break;
99 case _EqnNumbers_:
100 CHK_ERR( storeEqnNumbers(srcProc, message) ); break;
101 default:
102 std::abort();
103 }
104
105 return(0);
106}
107
109localFieldMaskMessageSize(std::vector<fei::FieldMask*>& fieldMasks)
110{
111 //msg-size will be 1+sum(numFields*3+2)
112 int numLocalMasks = fieldMasks.size();
113 int i, msgSize = 1;
114 for(i=0; i<numLocalMasks; ++i) {
115 msgSize += (fieldMasks[i]->getNumFields())*3+2;
116 }
117
118 return( msgSize );
119}
120
122packLocalFieldMasks(std::vector<fei::FieldMask*>& fieldMasks,
123 std::vector<int>& localFieldMasks)
124{
125 int numLocalMasks = fieldMasks.size();
126 int msgSize = 1;
127 for(int ii=0; ii<numLocalMasks; ++ii) {
128 msgSize += fieldMasks[ii]->getNumFields()*3+2;
129 }
130
131 localFieldMasks.resize(msgSize);
132
133 int offset = 0;
134 localFieldMasks[offset++] = fieldMasks.size();
135 for(unsigned i=0; i<fieldMasks.size(); ++i) {
136 int numFields = fieldMasks[i]->getNumFields();
137 int numIndices = fieldMasks[i]->getNumIndices();
138 localFieldMasks[offset++] = numFields;
139 localFieldMasks[offset++] = numIndices;
140
141 std::vector<int>& fieldIDs = fieldMasks[i]->getFieldIDs();
142 std::vector<int>& fieldSizes = fieldMasks[i]->getFieldSizes();
143
144 for(int j=0; j<numFields; ++j) {
145 localFieldMasks[offset+j] = fieldIDs[j];
146 localFieldMasks[offset+numFields+j] = fieldSizes[j];
147 }
148 offset += numFields*3;
149 }
150
151 return(0);
152}
153
155addFieldMasks(std::vector<int>& msg, std::vector<fei::FieldMask*>& fieldMasks)
156{
157 int offset = 0;
158 int* msgPtr = &msg[0];
159 int numMasks = msgPtr[offset++];
160 for(int i=0; i<numMasks; ++i) {
161 int numFields = msgPtr[offset++];
162 int numIndices = msgPtr[offset++];
163 int* fieldIDs = NULL;
164 int* fieldSizes = NULL;
165 if (numFields > 0) {
166 fieldIDs = &(msgPtr[offset]);
167 fieldSizes = &(msgPtr[offset+numFields]);
168 }
169
170 int maskID = fei::FieldMask::calculateMaskID(numFields, fieldIDs);
171
172 bool maskAlreadyExists = false;
173 for(unsigned j=0; j<fieldMasks.size(); ++j) {
174 int existingMaskID = fieldMasks[j]->getMaskID();
175 if (maskID == existingMaskID) {
176 maskAlreadyExists = true; break;
177 }
178 }
179
180 if (!maskAlreadyExists) {
181 fei::FieldMask* newmask = new fei::FieldMask(numFields,
182 fieldIDs, fieldSizes);
183 if (numFields < 1) {
184 newmask->setNumIndices(numIndices);
185 }
186 fieldMasks.push_back(newmask);
187 }
188
189 offset += 3*numFields;
190 }
191
192 return(0);
193}
194
195int snl_fei::RecordMsgHandler::packMaskIDs(int destProc, std::vector<int>& msg)
196{
197 fei::comm_map::row_type* ids = sendPattern_->getRow(destProc);
198 int len = ids->size();
199
200 msg.resize(len);
201
202 fei::comm_map::row_type::const_iterator
203 id_iter = ids->begin(),
204 id_end = ids->end();
205
206 int offset = 0;
207 int* msgPtr = &msg[0];
208
209 for(; id_iter != id_end; ++id_iter) {
210 fei::Record<int>* rec = recordCollection_->getRecordWithID(*id_iter);
211 if (rec == NULL) {
212 FEI_OSTRINGSTREAM osstr;
213 osstr << "RecordMsgHandler::packMaskIDs: proc " << localProc_
214 << " failed to find ID " << *id_iter;
215 throw std::runtime_error(osstr.str());
216 }
217
218 msgPtr[offset++] = rec->getFieldMask()->getMaskID();
219 }
220
221 return(0);
222}
223
224int snl_fei::RecordMsgHandler::mergeMaskIDs(int srcProc, std::vector<int>& msg)
225{
226 fei::comm_map::row_type* ids = recvPattern_->getRow(srcProc);
227
228 fei::comm_map::row_type::const_iterator
229 id_iter = ids->begin(),
230 id_end = ids->end();
231
232 int offset = 0;
233 int* msgPtr = &msg[0];
234
235 for(; id_iter != id_end; ++id_iter) {
236 int ID = *id_iter;
237 fei::Record<int>* rec = recordCollection_->getRecordWithID(ID);
238 if (rec == NULL) {
239 ERReturn(-1);
240 }
241
242 int maskID = msgPtr[offset++];
243
244 if (maskID != rec->getFieldMask()->getMaskID()) {
245 //if the masks don't match, we need to add the fields from the
246 //incoming-field-mask-id to our record's field-mask.
247
248 //first, find the field-mask for 'maskID'
249 fei::FieldMask* mask = NULL;
250 for(unsigned fm=0; fm<fieldMasks_.size(); ++fm) {
251 if (fieldMasks_[fm]->getMaskID() == maskID) mask = fieldMasks_[fm];
252 }
253 if (mask == NULL) {
254 fei::console_out() << "mergeMaskIDs didn't find mask for maskID="
255 << maskID<<FEI_ENDL;
256 ERReturn(-1);
257 }
258
259 int numFields = mask->getNumFields();
260 std::vector<int>& fieldIDs = mask->getFieldIDs();
261 std::vector<int>& fieldSizes = mask->getFieldSizes();
262
263 for(int nf=0; nf<numFields; ++nf) {
264 recordCollection_->initRecords(fieldIDs[nf], fieldSizes[nf],
265 1, &ID, fieldMasks_);
266 }
267 }
268 }
269
270 return(0);
271}
272
274{
275 fei::comm_map::row_type* ids = sendPattern_->getRow(destProc);
276 fei::comm_map::row_type::const_iterator
277 id_iter = ids->begin(),
278 id_end = ids->end();
279 int len = ids->size();
280
281 len *= 3;
282
283 for(; id_iter != id_end; ++id_iter) {
284 int ID = *id_iter;
285 fei::Record<int>* rec = recordCollection_->getRecordWithID(ID);
286 if (rec == NULL) {
287 ERReturn(-1);
288 }
289
290 len += rec->getFieldMask()->getNumIndices();
291 }
292
293 return(len);
294}
295
297 std::vector<int>& msg)
298{
299 fei::comm_map::row_type* ids = sendPattern_->getRow(destProc);
300 int len = ids->size()*3;
301 msg.resize(len);
302 const int* eqnNumPtr = &eqnNumbers_[0];
303
304 fei::comm_map::row_type::const_iterator
305 id_iter = ids->begin(),
306 id_end = ids->end();
307 int offset = 0;
308 for(; id_iter != id_end; ++id_iter) {
309 int ID = *id_iter;
310 fei::Record<int>* rec = recordCollection_->getRecordWithID(ID);
311 if (rec == NULL) {
312 ERReturn(-1);
313 }
314
315 len = rec->getFieldMask()->getNumIndices();
316
317 msg[offset++] = ID;
318 msg[offset++] = rec->getNumber();
319 msg[offset++] = len;
320
321 const int* eqnNumbers = eqnNumPtr+rec->getOffsetIntoEqnNumbers();
322 for(int i=0; i<len; ++i) {
323 msg.push_back(eqnNumbers[i]);
324 }
325 }
326
327 return(0);
328}
329
330int snl_fei::RecordMsgHandler::storeEqnNumbers(int srcProc, std::vector<int>& msg)
331{
332 int numIDs = recvPattern_->getRow(srcProc)->size();
333 int offset = numIDs*3;
334 int* msgPtr = &msg[0];
335 int* eqnNumPtr = &eqnNumbers_[0];
336 for(int i=0; i<numIDs; ++i) {
337 int ID = msgPtr[i*3];
338 int recNumber = msgPtr[i*3+1];
339 int numEqns = msgPtr[i*3+2];
340 fei::Record<int>* rec = recordCollection_->getRecordWithID(ID);
341 if (rec == NULL) {
342 ERReturn(-1);
343 }
344
345 rec->setNumber(recNumber);
346 int* eqnNumbers = eqnNumPtr+rec->getOffsetIntoEqnNumbers();
347 for(int eq=0; eq<numEqns; ++eq) {
348 eqnNumbers[eq] = msgPtr[offset++];
349 ptBlkMap_.setEqn(eqnNumbers[eq], recNumber, numEqns);
350 }
351 }
352
353 return(0);
354}
355
std::vector< int > & getFieldSizes()
std::vector< int > & getFieldIDs()
void setNumIndices(int numInd)
size_t getNumFields() const
int getNumIndices() const
fei::FieldMask * getFieldMask()
Definition: fei_Record.hpp:106
int getOffsetIntoEqnNumbers() const
Definition: fei_Record.hpp:126
void setNumber(const GlobalIDType &num)
Definition: fei_Record.hpp:52
GlobalIDType getNumber() const
Definition: fei_Record.hpp:58
int packMaskIDs(int destProc, std::vector< int > &msg)
std::vector< int > & getRecvProcs()
int addFieldMasks(std::vector< int > &msg, std::vector< fei::FieldMask * > &fieldMasks)
int mergeMaskIDs(int srcProc, std::vector< int > &msg)
int getSendMessageLength(int destProc, int &messageLength)
int localFieldMaskMessageSize(std::vector< fei::FieldMask * > &fieldMasks)
int getSendMessage(int destProc, std::vector< int > &message)
int processRecvMessage(int srcProc, std::vector< int > &message)
int packEqnNumbersMsg(int destProc, std::vector< int > &msg)
int storeEqnNumbers(int srcProc, std::vector< int > &msg)
RecordMsgHandler(int localProc, RecordCollection *recordCollection, snl_fei::PointBlockMap &ptBlkMap, std::vector< fei::FieldMask * > &fieldMasks, std::vector< int > &eqnNumbers)
std::vector< int > & getSendProcs()
int packLocalFieldMasks(std::vector< fei::FieldMask * > &fieldMasks, std::vector< int > &localFieldMasks)
#define ERReturn(a)
#define CHK_ERR(a)
#define FEI_ENDL
#define FEI_OSTRINGSTREAM
Definition: fei_sstream.hpp:32
void copyKeysToVector(const MAP_TYPE &map_obj, std::vector< int > &keyvector)
std::ostream & console_out()