41 #ifndef VALUELAYERND_H_
42 #define VALUELAYERND_H_
49 #include "GridDimensions.h"
50 #include "RepastProcess.h"
67 MPI_Datatype datatype;
101 int globalCoordinateMin, globalCoordinateMax;
102 int localBoundariesMin, localBoundariesMax;
103 int simplifiedBoundariesMin, simplifiedBoundariesMax;
104 int leftBufferSize, rightBufferSize;
105 int matchingCoordinateMin, matchingCoordinateMax;
107 bool atLeftBound, atRightBound;
108 bool spaceContinuesLeft, spaceContinuesRight;
119 int getSendReceiveSize(
int relativeLocation);
136 int getTransformedCoord(
int originalCoord);
154 int getIndexedCoord(
int originalCoord,
bool isSimplified =
false);
164 bool isInLocalBounds(
int originalCoord);
175 "global (" << globalCoordinateMin <<
", " << globalCoordinateMax <<
") " <<
176 "local (" << localBoundariesMin <<
", " << localBoundariesMax <<
") " <<
177 "simple (" << simplifiedBoundariesMin <<
", " << simplifiedBoundariesMax <<
") " <<
178 "match (" << matchingCoordinateMin <<
", " << matchingCoordinateMax <<
") " <<
179 "globalWidth = " << globalWidth <<
" localWidth = " << localWidth <<
" width = " << width <<
" bytes = " << widthInBytes << std::endl;
185 leftBufferSize(buffer), rightBufferSize(buffer), periodic(isPeriodic){
186 globalCoordinateMin = globalBoundaries.
origin(indx);
187 globalCoordinateMax = globalBoundaries.
origin(indx) + globalBoundaries.
extents(indx);
188 localBoundariesMin = localBoundaries.
origin(indx);
189 localBoundariesMax = localBoundaries.
origin(indx) + localBoundaries.
extents(indx);
191 atLeftBound = localBoundariesMin == globalCoordinateMin;
192 atRightBound = localBoundariesMax == globalCoordinateMax;
194 spaceContinuesLeft = !atLeftBound || periodic;
195 spaceContinuesRight = !atRightBound || periodic;
197 simplifiedBoundariesMin = localBoundariesMin - leftBufferSize;
198 simplifiedBoundariesMax = localBoundariesMax + rightBufferSize;
200 matchingCoordinateMin = localBoundariesMin;
201 if(spaceContinuesLeft && !atLeftBound ) matchingCoordinateMin -= leftBufferSize;
203 matchingCoordinateMax = localBoundariesMax;
204 if(spaceContinuesRight && !atRightBound) matchingCoordinateMax += rightBufferSize;
206 globalWidth = globalCoordinateMax - globalCoordinateMin;
207 localWidth = localBoundariesMax - localBoundariesMin;
208 width = leftBufferSize + localWidth + rightBufferSize;
209 widthInBytes = width * (
sizeof(T));
215 switch(relativeLocation){
216 case -1:
return leftBufferSize;
217 case 1:
return rightBufferSize;
226 if(originalCoord < matchingCoordinateMin){
227 return matchingCoordinateMax + (originalCoord - globalCoordinateMin);
229 else if(originalCoord > matchingCoordinateMax){
230 return matchingCoordinateMin - (globalCoordinateMax - originalCoord);
232 else return originalCoord;
238 return (isSimplified ? originalCoord : getTransformedCoord(originalCoord)) - simplifiedBoundariesMin;
243 return originalCoord >= localBoundariesMin && originalCoord < localBoundariesMax;
264 bool globalSpaceIsPeriodic;
268 vector<DimensionDatum<T> > dimensionData;
271 MPI_Request* requests;
290 static int instanceCount;
315 return localBoundaries;
331 vector<int>
getIndexes(vector<int> location,
bool isSimplified =
false);
346 int getIndex(vector<int> location,
bool isSimplified =
false);
382 virtual void initialize(T initialValue,
bool fillBufferZone =
false,
bool fillLocal =
true) = 0;
391 virtual void initialize(T initialLocalValue, T initialBufferZoneValue) = 0;
417 virtual T
addValueAt(T val, vector<int> location,
bool& errFlag) = 0;
443 virtual T
setValueAt(T val, vector<int> location,
bool& errFlag) = 0;
465 virtual T
getValueAt(vector<int> location,
bool& errFlag) = 0;
501 void getMPIDataType(
int radius, MPI_Datatype &datatype);
511 void getMPIDataType(vector<int> sideLengths, MPI_Datatype &datatype,
int dimensionIndex);
517 MPI_Datatype getRawMPIDataType();
559 int AbstractValueLayerND<T>::instanceCount = 0;
567 numDims = processesPerDim.size();
570 localBoundaries = cartTopology->
getDimensions(rank, globalBoundaries);
575 for(
int i = 0; i < numDims; i++){
576 DimensionDatum<T> datum(i, globalBoundaries, localBoundaries, bufferSize, periodic);
577 length *= datum.width;
578 dimensionData.push_back(datum);
579 places.push_back(val);
580 strides.push_back(val *
sizeof(T));
581 val *= dimensionData[i].width;
588 vector<int> myCoordinates;
596 datum = &neighborData[neighborCount];
598 getMPIDataType(relLoc, datum->datatype);
599 datum->sendPtrOffset = getSendPointerOffset(relLoc);
600 datum->receivePtrOffset = getReceivePointerOffset(relLoc);
602 datum->rank = cartTopology->
getRank(myCoordinates, current);
608 }
while(relLoc.increment());
611 requests =
new MPI_Request[neighborCount * 2];
616 delete[] neighborData;
622 for(
int i = 0; i < numDims; i++){
631 return isInLocalBounds(location.
coords());
637 ret.assign(numDims, 0);
638 for(
int i = 0; i < numDims; i++) ret[i] = dimensionData[i].getIndexedCoord(location[i], isSimplified);
644 vector<int> indexed = getIndexes(location, isSimplified);
646 for(
int i = numDims - 1; i >= 0; i--) val += indexed[i] * places[i];
647 if(val < 0 || val > length) val = -1;
653 return getIndex(location.
coords());
659 vector<int> sideLengths;
660 for(
int i = 0; i < numDims; i++) sideLengths.push_back(dimensionData[i].getSendReceiveSize(relLoc[i]));
661 getMPIDataType(sideLengths, datatype, numDims - 1);
665 void AbstractValueLayerND<T>::getMPIDataType(
int radius, MPI_Datatype &datatype){
666 vector<int> sideLengths;
667 sideLengths.assign(numDims, 2 * radius + 1);
668 getMPIDataType(sideLengths, datatype, numDims - 1);
672 void AbstractValueLayerND<T>::getMPIDataType(vector<int> sideLengths, MPI_Datatype &datatype,
int dimensionIndex){
673 if(dimensionIndex == 0){
674 MPI_Type_contiguous(sideLengths[dimensionIndex], getRawMPIDataType(), &datatype);
677 MPI_Datatype innerType;
678 getMPIDataType(sideLengths, innerType, dimensionIndex - 1);
679 MPI_Type_create_hvector(sideLengths[dimensionIndex],
681 strides[dimensionIndex],
686 MPI_Type_commit(&datatype);
691 int AbstractValueLayerND<T>::getSendPointerOffset(RelativeLocation relLoc){
693 for(
int i = 0; i < numDims; i++){
694 DimensionDatum<T>* datum = &dimensionData[i];
695 ret += (relLoc[i] <= 0 ? datum->leftBufferSize : datum->width - (2 * datum->rightBufferSize)) * places[i];
701 int AbstractValueLayerND<T>::getReceivePointerOffset(RelativeLocation relLoc){
703 for(
int i = 0; i < numDims; i++){
704 DimensionDatum<T>* datum = &dimensionData[i];
705 ret += (relLoc[i] < 0 ? 0 : (relLoc[i] == 0 ? datum->leftBufferSize : datum->width - datum->rightBufferSize)) * places[i];
778 bool periodic, T initialValue = 0, T initialBufferZoneValue = 0);
784 virtual void initialize(T initialValue,
bool fillBufferZone =
false,
bool fillLocal =
true);
789 virtual void initialize(T initialLocalValue, T initialBufferZoneValue);
799 virtual T
addValueAt(T val, vector<int> location,
bool& errFlag);
809 virtual T
setValueAt(T val, vector<int> location,
bool& errFlag);
819 virtual T
getValueAt(vector<int> location,
bool& errFlag);
848 void write(
string fileLocation,
string filetag,
bool writeSharedBoundaryAreas =
false);
865 void fillDimension(T localValue, T bufferZoneValue,
bool doBufferZone,
bool doLocal, T* dataSpacePointer,
int dimIndex);
876 void writeDimension(std::ofstream& outfile, T* dataSpacePointer,
int* currentPosition,
int dimIndex,
bool writeSharedBoundaryAreas =
false);
903 ValueLayerNDSU(vector<int> processesPerDim,
GridDimensions globalBoundaries,
int bufferSize,
bool periodic, T initialValue = 0, T initialBufferZoneValue = 0);
909 virtual void initialize(T initialValue,
bool fillBufferZone =
false,
bool fillLocal =
true);
914 virtual void initialize(T initialLocalValue, T initialBufferZoneValue);
924 virtual T
addValueAt(T val, vector<int> location,
bool& errFlag);
934 virtual T
setValueAt(T val, vector<int> location,
bool& errFlag);
944 virtual T
getValueAt(vector<int> location,
bool& errFlag);
954 virtual void write(
string fileLocation,
string filetag,
bool writeSharedBoundaryAreas =
false);
1086 void fillDimension(T localValue, T bufferZoneValue,
bool doBufferZone,
bool doLocal, T* dataSpace1Pointer, T* dataSpace2Pointer,
int dimIndex);
1097 void writeDimension(std::ofstream& outfile, T* dataSpacePointer,
int* currentPosition,
int dimIndex,
bool writeSharedBoundaryAreas =
false);
1104 void sumInto(T* dataSpace1Pointer, T* dataSpace2Pointer,
int dimIndex);
1110 template<
typename T>
1112 T initialValue, T initialBufferZoneValue):
AbstractValueLayerND<T>(processesPerDim, globalBoundaries, bufferSize, periodic){
1118 initialize(initialValue, initialBufferZoneValue);
1125 template<
typename T>
1126 ValueLayerND<T>::~ValueLayerND(){
1130 template<
typename T>
1135 template<
typename T>
1140 template<
typename T>
1143 int indx = this->getIndex(location);
1148 T* pt = &dataSpace[indx];
1149 return (*pt = *pt + val);
1152 template<
typename T>
1155 int indx = this->getIndex(location);
1161 T* pt = &dataSpace[indx];
1162 return (*pt = *pt + val);
1165 template<
typename T>
1168 int indx = this->getIndex(location);
1173 T* pt = &dataSpace[indx];
1177 template<
typename T>
1180 int indx = this->getIndex(location);
1185 T* pt = &dataSpace[indx];
1189 template<
typename T>
1192 int indx = this->getIndex(location);
1197 return dataSpace[indx];
1200 template<
typename T>
1203 int indx = this->getIndex(location);
1208 return dataSpace[indx];
1211 template<
typename T>
1226 for(
int i = 0; i < AbstractValueLayerND<T>::neighborCount; i++){
1236 template<
typename T>
1238 std::ofstream outfile;
1239 std::ostringstream stream;
1241 stream << fileLocation <<
"ValueLayer_" << fileTag <<
"_" << rank <<
".csv";
1242 std::string filename = stream.str();
1244 const char * c = filename.c_str();
1245 outfile.open(c, std::ios_base::trunc | std::ios_base::out);
1248 for(
int i = 0; i < AbstractValueLayerND<T>::numDims; i++) outfile <<
"DIM_" << i <<
",";
1249 outfile <<
"VALUE" << endl;
1252 for(
int i = 0; i < AbstractValueLayerND<T>::numDims; i++) positions[i] = 0;
1260 template<
typename T>
1262 if(!doBufferZone && !doLocal)
return;
1271 for(; i < bufferEdge; i++){
1274 *dataSpacePointer = bufferValue;
1277 fillDimension(bufferValue, bufferValue, doBufferZone, doLocal, dataSpacePointer, dimIndex - 1);
1281 dataSpacePointer += pointerIncrement;
1283 for(; i < localEdge; i++){
1286 *dataSpacePointer = localValue;
1289 fillDimension(localValue, bufferValue, doBufferZone, doLocal, dataSpacePointer, dimIndex - 1);
1293 dataSpacePointer += pointerIncrement;
1296 for(; i < upperBound; i++){
1298 *dataSpacePointer = bufferValue;
1301 fillDimension(bufferValue, bufferValue, doBufferZone, doLocal, dataSpacePointer, dimIndex - 1);
1304 dataSpacePointer += pointerIncrement;
1309 template<
typename T>
1310 void ValueLayerND<T>::writeDimension(std::ofstream& outfile, T* dataSpacePointer,
int* currentPosition,
int dimIndex,
bool writeSharedBoundaryAreas){
1311 int bufferEdge = AbstractValueLayerND<T>::dimensionData[dimIndex].leftBufferSize;
1312 int localEdge = bufferEdge + AbstractValueLayerND<T>::dimensionData[dimIndex].localWidth;
1313 int upperBound = localEdge + AbstractValueLayerND<T>::dimensionData[dimIndex].rightBufferSize;
1315 int pointerIncrement = AbstractValueLayerND<T>::places[dimIndex];
1317 for(; i < bufferEdge; i++){
1318 currentPosition[dimIndex] = i;
1319 if(writeSharedBoundaryAreas){
1321 T val = *dataSpacePointer;
1323 for(
int j = 0; j < AbstractValueLayerND<T>::numDims; j++) outfile << (currentPosition[j] - AbstractValueLayerND<T>::dimensionData[j].leftBufferSize + AbstractValueLayerND<T>::dimensionData[j].localBoundariesMin) <<
",";
1324 outfile << val << endl;
1328 writeDimension(outfile, dataSpacePointer, currentPosition, dimIndex - 1, writeSharedBoundaryAreas);
1332 dataSpacePointer += pointerIncrement;
1334 for(; i < localEdge; i++){
1335 currentPosition[dimIndex] = i;
1337 T val = *dataSpacePointer;
1339 for(
int j = 0; j < AbstractValueLayerND<T>::numDims; j++) outfile << (currentPosition[j] - AbstractValueLayerND<T>::dimensionData[j].leftBufferSize + AbstractValueLayerND<T>::dimensionData[j].localBoundariesMin) <<
",";
1340 outfile << val << endl;
1344 writeDimension(outfile, dataSpacePointer, currentPosition, dimIndex - 1, writeSharedBoundaryAreas);
1347 dataSpacePointer += pointerIncrement;
1349 if(writeSharedBoundaryAreas){
1350 for(; i < upperBound; i++){
1351 currentPosition[dimIndex] = i;
1353 T val = *dataSpacePointer;
1355 for(
int j = 0; j < AbstractValueLayerND<T>::numDims; j++) outfile << (currentPosition[j] - AbstractValueLayerND<T>::dimensionData[j].leftBufferSize + AbstractValueLayerND<T>::dimensionData[j].localBoundariesMin) <<
",";
1356 outfile << *dataSpacePointer << endl;
1360 writeDimension(outfile, dataSpacePointer, currentPosition, dimIndex - 1, writeSharedBoundaryAreas);
1363 dataSpacePointer += pointerIncrement;
1371 template<
typename T>
1372 ValueLayerNDSU<T>::ValueLayerNDSU(vector<int> processesPerDim, GridDimensions globalBoundaries,
int bufferSize,
bool periodic,
1373 T initialValue, T initialBufferZoneValue): AbstractValueLayerND<T>(processesPerDim, globalBoundaries, bufferSize, periodic){
1376 dataSpace1 =
new T[AbstractValueLayerND<T>::length];
1377 dataSpace2 =
new T[AbstractValueLayerND<T>::length];
1378 currentDataSpace = dataSpace1;
1379 otherDataSpace = dataSpace2;
1382 initialize(initialValue, initialBufferZoneValue);
1389 template<
typename T>
1390 ValueLayerNDSU<T>::~ValueLayerNDSU(){
1391 delete[] currentDataSpace;
1392 delete[] otherDataSpace;
1395 template<
typename T>
1400 template<
typename T>
1405 template<
typename T>
1407 int indx = this->getIndex(location);
1408 if(indx == -1)
return nan(
"");
1409 T* pt = ¤tDataSpace[indx];
1410 return (*pt = *pt + val);
1413 template<
typename T>
1415 int indx = this->getIndex(location);
1416 if(indx == -1)
return nan(
"");
1417 T* pt = ¤tDataSpace[indx];
1418 return (*pt = *pt + val);
1421 template<
typename T>
1423 int indx = this->getIndex(location);
1424 if(indx == -1)
return nan(
"");
1425 T* pt = ¤tDataSpace[indx];
1429 template<
typename T>
1431 int indx = this->getIndex(location);
1432 if(indx == -1)
return nan(
"");
1433 T* pt = ¤tDataSpace[indx];
1437 template<
typename T>
1439 int indx = this->getIndex(location);
1440 if(indx == -1)
return nan(
"");
1441 return currentDataSpace[indx];
1444 template<
typename T>
1446 int indx = this->getIndex(location);
1447 if(indx == -1)
return nan(
"");
1448 return currentDataSpace[indx];
1452 template<
typename T>
1467 for(
int i = 0; i < AbstractValueLayerND<T>::neighborCount; i++){
1476 template<
typename T>
1478 std::ofstream outfile;
1479 std::ostringstream stream;
1481 stream << fileLocation <<
"ValueLayer_" << fileTag <<
"_" << rank <<
".csv";
1482 std::string filename = stream.str();
1484 const char * c = filename.c_str();
1485 outfile.open(c, std::ios_base::trunc | std::ios_base::out);
1488 for(
int i = 0; i < AbstractValueLayerND<T>::numDims; i++) outfile <<
"DIM_" << i <<
",";
1489 outfile <<
"VALUE" << endl;
1492 for(
int i = 0; i < AbstractValueLayerND<T>::numDims; i++) positions[i] = 0;
1499 template<
typename T>
1502 T* tempDataSpace = currentDataSpace;
1503 currentDataSpace = otherDataSpace;
1504 otherDataSpace = tempDataSpace;
1507 template<
typename T>
1510 int indx = this->getIndex(location);
1515 T* pt = &otherDataSpace[indx];
1516 return (*pt = *pt + val);
1519 template<
typename T>
1522 int indx = this->getIndex(location);
1527 T* pt = &otherDataSpace[indx];
1528 return (*pt = *pt + val);
1531 template<
typename T>
1534 int indx = this->getIndex(location);
1539 T* pt = &otherDataSpace[indx];
1543 template<
typename T>
1546 int indx = this->getIndex(location);
1551 T* pt = &otherDataSpace[indx];
1555 template<
typename T>
1558 int indx = this->getIndex(location);
1563 return otherDataSpace[indx];
1566 template<
typename T>
1569 int indx = this->getIndex(location);
1574 return otherDataSpace[indx];
1577 template<
typename T>
1583 template<
typename T>
1589 template<
typename T>
1605 MPI_Request* flowbackRequests =
new MPI_Request[4];
1615 int countOfRequests = 0;
1616 for(
int i = 0; i < listSize; i++){
1619 if(datum->sendDir == LDir){
1620 MPI_Isend(¤tDataSpace[datum->receivePtrOffset], 1, datum->datatype,
1624 else if(datum->sendDir == RDir){
1625 MPI_Isend(¤tDataSpace[datum->receivePtrOffset], 1, datum->datatype,
1629 if(datum->recvDir == LDir){
1630 MPI_Irecv(&otherDataSpace[datum->sendPtrOffset], 1, datum->datatype,
1634 else if(datum->recvDir == RDir){
1635 MPI_Irecv(&otherDataSpace[datum->sendPtrOffset], 1, datum->datatype,
1640 MPI_Status statuses[countOfRequests];
1643 MPI_Waitall(countOfRequests, flowbackRequests, statuses);
1653 delete[] flowbackRequests;
1657 template<
typename T>
1658 void ValueLayerNDSU<T>::fillDimension(T localValue, T bufferValue,
bool doBufferZone,
bool doLocal, T* dataSpace1Pointer, T* dataSpace2Pointer,
int dimIndex){
1659 if(!doBufferZone && !doLocal)
return;
1668 for(; i < bufferEdge; i++){
1671 *dataSpace1Pointer = bufferValue;
1672 *dataSpace2Pointer = bufferValue;
1675 fillDimension(bufferValue, bufferValue, doBufferZone, doLocal, dataSpace1Pointer, dataSpace2Pointer, dimIndex - 1);
1679 dataSpace1Pointer += pointerIncrement;
1680 dataSpace2Pointer += pointerIncrement;
1682 for(; i < localEdge; i++){
1685 *dataSpace1Pointer = localValue;
1686 *dataSpace2Pointer = localValue;
1689 fillDimension(localValue, bufferValue, doBufferZone, doLocal, dataSpace1Pointer, dataSpace2Pointer, dimIndex - 1);
1693 dataSpace1Pointer += pointerIncrement;
1694 dataSpace2Pointer += pointerIncrement;
1697 for(; i < upperBound; i++){
1699 *dataSpace1Pointer = bufferValue;
1700 *dataSpace2Pointer = bufferValue;
1703 fillDimension(bufferValue, bufferValue, doBufferZone, doLocal, dataSpace1Pointer, dataSpace2Pointer, dimIndex - 1);
1706 dataSpace1Pointer += pointerIncrement;
1707 dataSpace2Pointer += pointerIncrement;
1712 template<
typename T>
1713 void ValueLayerNDSU<T>::writeDimension(std::ofstream& outfile, T* dataSpacePointer,
int* currentPosition,
int dimIndex,
bool writeSharedBoundaryAreas){
1714 int bufferEdge = AbstractValueLayerND<T>::dimensionData[dimIndex].leftBufferSize;
1715 int localEdge = bufferEdge + AbstractValueLayerND<T>::dimensionData[dimIndex].localWidth;
1716 int upperBound = localEdge + AbstractValueLayerND<T>::dimensionData[dimIndex].rightBufferSize;
1718 int pointerIncrement = AbstractValueLayerND<T>::places[dimIndex];
1720 for(; i < bufferEdge; i++){
1721 currentPosition[dimIndex] = i;
1722 if(writeSharedBoundaryAreas){
1724 T val = *dataSpacePointer;
1726 for(
int j = 0; j < AbstractValueLayerND<T>::numDims; j++) outfile << (currentPosition[j] - AbstractValueLayerND<T>::dimensionData[j].leftBufferSize + AbstractValueLayerND<T>::dimensionData[j].localBoundariesMin) <<
",";
1727 outfile << val << endl;
1731 writeDimension(outfile, dataSpacePointer, currentPosition, dimIndex - 1, writeSharedBoundaryAreas);
1735 dataSpacePointer += pointerIncrement;
1737 for(; i < localEdge; i++){
1738 currentPosition[dimIndex] = i;
1740 T val = *dataSpacePointer;
1742 for(
int j = 0; j < AbstractValueLayerND<T>::numDims; j++) outfile << (currentPosition[j] - AbstractValueLayerND<T>::dimensionData[j].leftBufferSize + AbstractValueLayerND<T>::dimensionData[j].localBoundariesMin) <<
",";
1743 outfile << val << endl;
1747 writeDimension(outfile, dataSpacePointer, currentPosition, dimIndex - 1, writeSharedBoundaryAreas);
1750 dataSpacePointer += pointerIncrement;
1752 if(writeSharedBoundaryAreas){
1753 for(; i < upperBound; i++){
1754 currentPosition[dimIndex] = i;
1756 T val = *dataSpacePointer;
1758 for(
int j = 0; j < AbstractValueLayerND<T>::numDims; j++) outfile << (currentPosition[j] - AbstractValueLayerND<T>::dimensionData[j].leftBufferSize + AbstractValueLayerND<T>::dimensionData[j].localBoundariesMin) <<
",";
1759 outfile << *dataSpacePointer << endl;
1763 writeDimension(outfile, dataSpacePointer, currentPosition, dimIndex - 1, writeSharedBoundaryAreas);
1766 dataSpacePointer += pointerIncrement;
1772 template<
typename T>
1773 void ValueLayerNDSU<T>::sumInto(T* dataSpace1Pointer, T* dataSpace2Pointer,
int dimIndex){
1775 int bufferEdge = AbstractValueLayerND<T>::dimensionData[dimIndex].leftBufferSize;
1776 int localEdge = bufferEdge + AbstractValueLayerND<T>::dimensionData[dimIndex].localWidth;
1779 int pointerIncrement = AbstractValueLayerND<T>::places[dimIndex];
1780 int leftPointerSkip = pointerIncrement * AbstractValueLayerND<T>::dimensionData[dimIndex].leftBufferSize;
1784 dataSpace1Pointer += leftPointerSkip;
1785 dataSpace2Pointer += leftPointerSkip;
1788 for(
int i = bufferEdge; i < localEdge; i++){
1791 *dataSpace1Pointer += *dataSpace2Pointer;
1792 *dataSpace2Pointer = 0;
1794 else sumInto(dataSpace1Pointer, dataSpace2Pointer, dimIndex - 1);
1795 dataSpace1Pointer += pointerIncrement;
1796 dataSpace2Pointer += pointerIncrement;