XdmfMap.cpp 13.7 KB
Newer Older
Kenneth Leiter's avatar
Kenneth Leiter committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/*****************************************************************************/
/*                                    XDMF                                   */
/*                       eXtensible Data Model and Format                    */
/*                                                                           */
/*  Id : XdmfMap.cpp                                                         */
/*                                                                           */
/*  Author:                                                                  */
/*     Kenneth Leiter                                                        */
/*     kenneth.leiter@arl.army.mil                                           */
/*     US Army Research Laboratory                                           */
/*     Aberdeen Proving Ground, MD                                           */
/*                                                                           */
/*     Copyright @ 2011 US Army Research Laboratory                          */
/*     All Rights Reserved                                                   */
/*     See Copyright.txt for details                                         */
/*                                                                           */
/*     This software is distributed WITHOUT ANY WARRANTY; without            */
/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
/*     for more information.                                                 */
/*                                                                           */
/*****************************************************************************/

24
#include <utility>
25
#include "XdmfAttribute.hpp"
26
#include "XdmfError.hpp"
27 28
#include "XdmfGridCollection.hpp"
#include "XdmfGridCollectionType.hpp"
29
#include "XdmfHeavyDataController.hpp"
30 31
#include "XdmfMap.hpp"

32
shared_ptr<XdmfMap>
33
XdmfMap::New()
34
{
35
  shared_ptr<XdmfMap> p(new XdmfMap());
36
  return p;
37 38
}

39 40
std::vector<shared_ptr<XdmfMap> >
XdmfMap::New(const std::vector<shared_ptr<XdmfAttribute> > & globalNodeIds)
41
{
42
  // globalNodeId | taskId | localNodeId at taskId
43
  std::map<node_id, std::map<task_id, node_id> > globalNodeIdMap;
44

45
  // fill globalNodeIdMap using globalNodeIds
46
  for(unsigned int i=0; i<globalNodeIds.size(); ++i) {
47
    const shared_ptr<XdmfAttribute> currGlobalNodeIds = globalNodeIds[i];
48
    for(unsigned int j=0; j<currGlobalNodeIds->getSize(); ++j) {
49
      const node_id currGlobalNodeId = currGlobalNodeIds->getValue<node_id>(j);
50 51 52
      globalNodeIdMap[currGlobalNodeId][i] = j;
    }
  }
53

54
  std::vector<shared_ptr<XdmfMap> > returnValue;
55 56 57
  returnValue.resize(globalNodeIds.size());

  // fill maps for each partition
58
  for(unsigned int i=0; i<globalNodeIds.size(); ++i)  {
59
    shared_ptr<XdmfMap> map = XdmfMap::New();
60
    returnValue[i] = map;
61 62
    const shared_ptr<XdmfAttribute> currGlobalNodeIds = globalNodeIds[i];

63
    for(unsigned int j=0; j<currGlobalNodeIds->getSize(); ++j) {
64 65 66 67
      const node_id currGlobalNodeId = currGlobalNodeIds->getValue<node_id>(j);
      const std::map<task_id, node_id> & currMap = 
        globalNodeIdMap[currGlobalNodeId];
      if(currMap.size() > 1) {
68
        for(std::map<task_id, node_id>::const_iterator iter = currMap.begin();
69
            iter != currMap.end();
70
            ++iter) {
71
          if(iter->first != (int)i) {
72
            map->insert(iter->first, j, iter->second);
73 74 75 76 77
          }
        }
      }
    }
  }
78

79
  return returnValue;
80 81
}

82 83
XdmfMap::XdmfMap() :
  mName("")
84 85 86 87 88 89 90 91 92
{
}

XdmfMap::~XdmfMap()
{
}

const std::string XdmfMap::ItemTag = "Map";

93 94
std::map<std::string, std::string>
XdmfMap::getItemProperties() const
95
{
96
  std::map<std::string, std::string> mapProperties;
97
  mapProperties.insert(std::make_pair("Name", mName));
98
  return mapProperties;
99 100
}

101 102
std::string
XdmfMap::getItemTag() const
103
{
104
  return ItemTag;
105 106
}

107
std::map<XdmfMap::task_id, XdmfMap::node_id_map>
108
XdmfMap::getMap() const
109
{
110 111 112
  return mMap;
}

113 114 115 116 117 118
std::string
XdmfMap::getName() const
{
  return mName;
}

119 120 121
XdmfMap::node_id_map
XdmfMap::getRemoteNodeIds(const task_id remoteTaskId)
{
122
  std::map<task_id, node_id_map>::const_iterator iter =
123
    mMap.find(remoteTaskId);
124 125 126 127
  if(iter != mMap.end()) {
    return iter->second;
  }
  // No entry, return empty map.
128
  return node_id_map();
129 130
}

131
void
132 133 134
XdmfMap::insert(const task_id remoteTaskId,
                const node_id localNodeId,
                const node_id remoteLocalNodeId)
135
{
136
  mMap[remoteTaskId][localNodeId].insert(remoteLocalNodeId);
137 138
}

139 140
bool XdmfMap::isInitialized() const
{
141
  return mMap.size() > 0;
142 143
}

144 145
void
XdmfMap::populateItem(const std::map<std::string, std::string> & itemProperties,
146
                      const std::vector<shared_ptr<XdmfItem> > & childItems,
147
                      const XdmfCoreReader * const reader)
148
{
149
  XdmfItem::populateItem(itemProperties, childItems, reader);
150 151 152 153 154 155 156 157
  std::map<std::string, std::string>::const_iterator name =
    itemProperties.find("Name");
  if(name != itemProperties.end()) {
    mName = name->second;
  }
  else {
    mName = "";
  }
158
  std::vector<shared_ptr<XdmfArray> > arrayVector;
159
  arrayVector.reserve(3);
160
  for(std::vector<shared_ptr<XdmfItem> >::const_iterator iter =
161 162 163
        childItems.begin();
      iter != childItems.end();
      ++iter) {
164 165 166
    if(shared_ptr<XdmfArray> array = shared_dynamic_cast<XdmfArray>(*iter)) {
      arrayVector.push_back(array);
    }
167
  }
168

169 170
  if(arrayVector.size() != 0) {
    if(arrayVector.size() != 3) {
171 172 173 174 175 176 177 178
      try {
        XdmfError::message(XdmfError::FATAL,
                           "Expected 3 arrays attached to "
                           "XdmfMap::populateItem");
      }
      catch (XdmfError e) {
        throw e;
      }
179 180 181
    }
    if(!(arrayVector[0]->getSize() == arrayVector[1]->getSize() &&
         arrayVector[0]->getSize() == arrayVector[2]->getSize())) {
182 183 184 185 186 187 188 189
      try {
        XdmfError::message(XdmfError::FATAL,
                           "Arrays must be of equal size in "
                           "XdmfMap:: populateItem");
      }
      catch (XdmfError e) {
        throw e;
      }
190
    }
191

192 193 194
    // check if any arrays have values in memory - if so, they need to be
    // read into map
    bool needToRead = false;
195
    for(std::vector<shared_ptr<XdmfArray> >::const_iterator iter =
196 197 198
          arrayVector.begin();
        iter != arrayVector.end();
        ++iter) {
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
      if((*iter)->isInitialized()) {
        needToRead = true;
        break;
      }
    }

    if(needToRead) {
      for(std::vector<shared_ptr<XdmfArray> >::const_iterator iter =
            arrayVector.begin();
          iter != arrayVector.end();
          ++iter) {
        if(!(*iter)->isInitialized()) {
          (*iter)->read();
        }
      }
      for(unsigned int i=0; i<arrayVector[0]->getSize(); ++i) {
        this->insert(arrayVector[0]->getValue<task_id>(i),
                     arrayVector[1]->getValue<node_id>(i),
                     arrayVector[2]->getValue<node_id>(i));
218
      }
219
    }
220
    else {
221 222

      mRemoteTaskIdsControllers.clear();
223
      for (unsigned int i = 0; i <  arrayVector[0]->getNumberHeavyDataControllers(); ++i)
224 225 226 227
      {
        mRemoteTaskIdsControllers.push_back(arrayVector[0]->getHeavyDataController(i));
      }
      mLocalNodeIdsControllers.clear();
228
      for (unsigned int i = 0; i <  arrayVector[1]->getNumberHeavyDataControllers(); ++i)
229 230 231 232
      {
        mLocalNodeIdsControllers.push_back(arrayVector[1]->getHeavyDataController(i));
      }
      mRemoteLocalNodeIdsControllers.clear();
233
      for (unsigned int i = 0; i <  arrayVector[2]->getNumberHeavyDataControllers(); ++i)
234 235 236
      {
        mRemoteLocalNodeIdsControllers.push_back(arrayVector[2]->getHeavyDataController(i));
      }
237 238
    }
  }
239 240
}

241 242
void
XdmfMap::read()
243
{
244 245 246 247
  if(mLocalNodeIdsControllers.size() > 0 &&
     mRemoteTaskIdsControllers.size() > 0 &&
     mRemoteLocalNodeIdsControllers.size() > 0) {

248
    unsigned int localNodeCount = 0;
249
    for (unsigned int i = 0; i< mLocalNodeIdsControllers.size(); ++i)
250 251 252
    {
      localNodeCount += mLocalNodeIdsControllers[i]->getSize();
    }
253
    unsigned int remoteTaskCount = 0;
254
    for (unsigned int i = 0; i< mRemoteTaskIdsControllers.size(); ++i)
255 256 257
    {
      remoteTaskCount += mRemoteTaskIdsControllers[i]->getSize();
    }
258
    unsigned int remoteNodeCount = 0;
259
    for (unsigned int i = 0; i< mRemoteLocalNodeIdsControllers.size(); ++i)
260 261 262 263 264 265 266 267
    {
      remoteNodeCount += mRemoteLocalNodeIdsControllers[i]->getSize();
    }

    if(!(localNodeCount ==
         remoteTaskCount &&
         localNodeCount ==
         remoteNodeCount)){
268 269 270 271 272 273 274
      try {
        XdmfError::message(XdmfError::FATAL,
                           "Arrays must be of equal size in XdmfMap::read");
      }
      catch (XdmfError e) {
        throw e;
      }
275 276
    }

277 278 279
    shared_ptr<XdmfArray> remoteTaskIds = XdmfArray::New();
    shared_ptr<XdmfArray> localNodeIds = XdmfArray::New();
    shared_ptr<XdmfArray> remoteLocalNodeIds = XdmfArray::New();
280

281
    mRemoteTaskIdsControllers[0]->read(remoteTaskIds.get());
282
    for (unsigned int i = 1; i < mRemoteTaskIdsControllers.size(); ++i)
283 284 285 286 287 288
    {
      shared_ptr<XdmfArray> tempArray = XdmfArray::New();
      mRemoteTaskIdsControllers[i]->read(tempArray.get());
      remoteTaskIds->insert(remoteTaskIds->getSize(), tempArray, 0, tempArray->getSize());
    }
    mLocalNodeIdsControllers[0]->read(localNodeIds.get());
289
    for (unsigned int i = 1; i < mLocalNodeIdsControllers.size(); ++i)
290 291 292 293 294 295
    {
      shared_ptr<XdmfArray> tempArray = XdmfArray::New();
      mLocalNodeIdsControllers[i]->read(tempArray.get());
      localNodeIds->insert(localNodeIds->getSize(), tempArray, 0, tempArray->getSize());
    }
    mRemoteLocalNodeIdsControllers[0]->read(remoteLocalNodeIds.get());
296
    for (unsigned int i = 1; i < mRemoteLocalNodeIdsControllers.size(); ++i)
297 298 299 300 301
    {
      shared_ptr<XdmfArray> tempArray = XdmfArray::New();
      mRemoteLocalNodeIdsControllers[i]->read(tempArray.get());
      remoteLocalNodeIds->insert(remoteLocalNodeIds->getSize(), tempArray, 0, tempArray->getSize());
    }
302 303 304 305

    for(unsigned int i=0; i<remoteTaskIds->getSize(); ++i) {
      const unsigned int remoteTaskId = remoteTaskIds->getValue<task_id>(i);
      const unsigned int localNodeId = localNodeIds->getValue<node_id>(i);
306
      const unsigned int remoteLocalNodeId =
307 308
        remoteLocalNodeIds->getValue<node_id>(i);
      mMap[remoteTaskId][localNodeId].insert(remoteLocalNodeId);
309 310
    }
  }
311 312
}

313

314 315
void
XdmfMap::release()
316
{
317
  mMap.clear();
318 319
}

320
void
321 322 323
XdmfMap::setHeavyDataControllers(std::vector<shared_ptr<XdmfHeavyDataController> > remoteTaskIdsControllers,
                                 std::vector<shared_ptr<XdmfHeavyDataController> > localNodeIdsControllers,
                                 std::vector<shared_ptr<XdmfHeavyDataController> > remoteLocalNodeIdsControllers)
324
{
325
  unsigned int localNodeCount = 0;
326
  for (unsigned int i = 0; i< localNodeIdsControllers.size(); ++i)
327 328 329
  {
    localNodeCount += localNodeIdsControllers[i]->getSize();
  }
330
  unsigned int remoteTaskCount = 0;
331
  for (unsigned int i = 0; i< remoteTaskIdsControllers.size(); ++i)
332 333 334
  {
    remoteTaskCount += remoteTaskIdsControllers[i]->getSize();
  }
335
  unsigned int remoteNodeCount = 0;
336
  for (unsigned int i = 0; i< remoteLocalNodeIdsControllers.size(); ++i)
337 338 339 340 341 342
  {
    remoteNodeCount += remoteLocalNodeIdsControllers[i]->getSize();
  }
  if(!(localNodeCount ==
       remoteTaskCount &&
       localNodeCount ==
343 344 345 346 347 348 349 350 351 352
       remoteNodeCount)) {
    try {
      XdmfError::message(XdmfError::FATAL,
                         "Arrays must be of equal size in "
                         "XdmfMap::setHeavyDataControllers");
    }
    catch (XdmfError e) {
      throw e;
    }
  }
353 354 355
  mRemoteTaskIdsControllers = remoteTaskIdsControllers;
  mLocalNodeIdsControllers = localNodeIdsControllers;
  mRemoteLocalNodeIdsControllers = remoteLocalNodeIdsControllers;
356 357
}

358 359 360 361 362
void 
XdmfMap::setMap(std::map<task_id, node_id_map> map)
{
  mMap = map;
}
363

364 365 366 367 368 369
void
XdmfMap::setName(const std::string & name)
{
  mName = name;
}

370
void
371
XdmfMap::traverse(const shared_ptr<XdmfBaseVisitor> visitor)
372
{
373
  XdmfItem::traverse(visitor);
374

375 376 377
  shared_ptr<XdmfArray> remoteTaskIds = XdmfArray::New();
  shared_ptr<XdmfArray> localNodeIds = XdmfArray::New();
  shared_ptr<XdmfArray> remoteLocalNodeIds = XdmfArray::New();
378 379

  for(std::map<task_id, node_id_map>::const_iterator
380 381 382
        iter = mMap.begin();
      iter != mMap.end();
      ++iter) {
383
    for(node_id_map::const_iterator
384
          iter2 = iter->second.begin();
385 386
        iter2 != iter->second.end();
        ++iter2) {
387
      for(node_id_map::mapped_type::const_iterator iter3 =
388 389 390 391 392 393 394
            iter2->second.begin();
          iter3 != iter2->second.end();
          ++iter3) {
        remoteTaskIds->pushBack(iter->first);
        localNodeIds->pushBack(iter2->first);
        remoteLocalNodeIds->pushBack(*iter3);
      }
395 396
    }
  }
397

398
  for (unsigned int i = 0; i < mRemoteTaskIdsControllers.size(); ++i)
399 400 401
  {
    remoteTaskIds->insert(mRemoteTaskIdsControllers[i]);
  }
402
  for (unsigned int i = 0; i < mLocalNodeIdsControllers.size(); ++i)
403 404 405
  {
    localNodeIds->insert(mLocalNodeIdsControllers[i]);
  }
406
  for (unsigned int i = 0; i < mRemoteLocalNodeIdsControllers.size(); ++i)
407 408 409
  {
    remoteLocalNodeIds->insert(mRemoteLocalNodeIdsControllers[i]);
  }
410

411
  remoteTaskIds->accept(visitor);
412 413
  localNodeIds->accept(visitor);
  remoteLocalNodeIds->accept(visitor);
414

415 416 417 418
  mLocalNodeIdsControllers.clear();
  mRemoteTaskIdsControllers.clear();
  mRemoteLocalNodeIdsControllers.clear();

419
  for (unsigned int i = 0; i < remoteTaskIds->getNumberHeavyDataControllers(); ++i)
420 421 422
  {
    mRemoteTaskIdsControllers.push_back(remoteTaskIds->getHeavyDataController(i));
  }
423
  for (unsigned int i = 0; i < localNodeIds->getNumberHeavyDataControllers(); ++i)
424 425 426
  {
    mLocalNodeIdsControllers.push_back(localNodeIds->getHeavyDataController(i));
  }
427
  for (unsigned int i = 0; i < remoteLocalNodeIds->getNumberHeavyDataControllers(); ++i)
428 429 430
  {
    mRemoteLocalNodeIdsControllers.push_back(remoteLocalNodeIds->getHeavyDataController(i));
  }
431
}