/****************************************************************************** * * AMDiS - Adaptive multidimensional simulations * * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis * * Authors: * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. * * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * * This file is part of AMDiS * * See also license.opensource.txt in the distribution. * ******************************************************************************/ #include "StdMpi.h" namespace AMDiS { namespace Parallel { MPI_Datatype StdMpiHelper::mpiDataType = MPI_INT; MPI_Datatype StdMpiHelper >::mpiDataType = MPI_INT; MPI_Datatype StdMpiHelper >::mpiDataType = MPI_INT; MPI_Datatype StdMpiHelper > >::mpiDataType = MPI_INT; MPI_Datatype StdMpiHelper >::mpiDataType = MPI_DOUBLE; MPI_Datatype StdMpiHelper > >::mpiDataType = MPI_DOUBLE; MPI_Datatype StdMpiHelper >::mpiDataType = MPI_UNSIGNED_LONG_LONG; MPI_Datatype StdMpiHelper >::mpiDataType = MPI_INT; MPI_Datatype StdMpiHelper > >::mpiDataType = MPI_INT; MPI_Datatype StdMpiHelper > >::mpiDataType = MPI_INT; MPI_Datatype StdMpiHelper > >::mpiDataType = MPI_DOUBLE; MPI_Datatype StdMpiHelper, int> >::mpiDataType = MPI_DOUBLE; MPI_Datatype StdMpiHelper > >::mpiDataType = MPI_DOUBLE; MPI_Datatype StdMpiHelper > > >::mpiDataType = MPI_DOUBLE; // T = int int StdMpiHelper::getBufferSize(int &data) { return 1; } void StdMpiHelper::createBuffer(int &data, int *buf) { buf[0] = data; } void StdMpiHelper::makeFromBuffer(int &data, int *buf, int bufSize) { data = buf[0]; } // T = vector int StdMpiHelper >::getBufferSize(vector &data) { return data.size(); } int StdMpiHelper >::getBufferSize(vector &data) { return data.size(); } void StdMpiHelper >::createBuffer(vector &data, int *buf) { for (unsigned int i = 0; i < data.size(); i++) buf[i] = data[i]; } void StdMpiHelper >::makeFromBuffer(vector &data, int *buf, int bufSize) { data.resize(bufSize); for (int i = 0; i < bufSize; i++) data[i] = buf[i]; } // T = std::set int StdMpiHelper >::getBufferSize(std::set &data) { return data.size(); } void StdMpiHelper >::createBuffer(std::set &data, int *buf) { int i = 0; for (std::set::iterator it = data.begin(); it != data.end(); ++it) buf[i++] = *it; } void StdMpiHelper >::makeFromBuffer(std::set &data, int *buf, int bufSize) { data.clear(); for (int i = 0; i < bufSize; i++) data.insert(buf[i]); } // T = vector > int StdMpiHelper > >::getBufferSize(vector > &data) { int dataSize = 1; for (unsigned int i = 0; i < data.size(); i++) dataSize += data[i].size() + 1; return dataSize; } void StdMpiHelper > >::createBuffer(vector > &data, int *buf) { int counter = 1; buf[0] = data.size(); for (unsigned int i = 0; i < data.size(); i++) { buf[counter++] = data[i].size(); for (std::set::iterator it = data[i].begin(); it != data[i].end(); ++it) buf[counter++] = *it; } } void StdMpiHelper > >::makeFromBuffer(vector > &data, int *buf, int bufSize) { FUNCNAME("StdMpiHelper > >::makeFromBuffer()"); int counter = 1; data.resize(buf[0]); for (int i = 0; i < buf[0]; i++) { data[i].clear(); int setSize = buf[counter++]; TEST_EXIT_DBG(setSize <= bufSize - counter) ("Should not happen: %d %d %d\n", setSize, bufSize, counter); for (int j = 0; j < setSize; j++) data[i].insert(buf[counter++]); } TEST_EXIT(counter == bufSize)("Counter is %d, but buffer size is %d!\n", counter, bufSize); } // T = vector int StdMpiHelper >::getBufferSize(vector &data) { return data.size(); } void StdMpiHelper >::createBuffer(vector &data, double *buf) { for (unsigned int i = 0; i < data.size(); i++) buf[i] = data[i]; } void StdMpiHelper >::makeFromBuffer(vector &data, double *buf, int bufSize) { data.resize(bufSize); for (int i = 0; i < bufSize; i++) data[i] = buf[i]; } // T = vector > int StdMpiHelper > >::getBufferSize(vector > &data) { int size = 1; for (unsigned int i = 0; i < data.size(); i++) size += data[i].size() + 1; return size; } void StdMpiHelper > >::createBuffer(vector > &data, double *buf) { buf[0] = data.size(); int counter = 1; for (unsigned int i = 0; i < data.size(); i++) { buf[counter++] = data[i].size(); for (unsigned int j = 0; j < data[i].size(); j++) buf[counter++] = data[i][j]; } } void StdMpiHelper > >::makeFromBuffer(vector > &data, double *buf, int bufSize) { data.resize(static_cast(buf[0])); int counter = 1; for (unsigned int i = 0; i < data.size(); i++) { data[i].resize(static_cast(buf[counter++])); for (unsigned int j = 0; j < data[i].size(); j++) data[i][j] = buf[counter++]; } } // T = vector int StdMpiHelper >::getBufferSize(vector &data) { FUNCNAME("StdMpiHelper >::getBufferSize()"); int size = 0; for (unsigned int i = 0; i < data.size(); i++) size += data[i].getCode().size() + 2; return size; } void StdMpiHelper >::createBuffer(vector &data, uint64_t *buf) { FUNCNAME("StdMpiHelper >::createBuffer()"); int pos = 0; for (unsigned int i = 0; i < data.size(); i++) { buf[pos++] = data[i].getCode().size(); buf[pos++] = data[i].getNumElements(); for (unsigned int j = 0; j < data[i].getCode().size(); j++) buf[pos++] = data[i].getCode()[j]; } } void StdMpiHelper >::makeFromBuffer(vector &data, uint64_t *buf, int bufSize) { FUNCNAME("StdMpiHelper >::makeFromBuffer()"); int pos = 0; while (pos < bufSize) { int codeSize = buf[pos++]; int nElements = buf[pos++]; vector code; code.resize(codeSize); for (int i = 0; i < codeSize; i++) code[i] = buf[pos++]; MeshStructure meshCode; meshCode.init(code, nElements); data.push_back(meshCode); } } // T = vector int StdMpiHelper >::getBufferSize(vector &data) { return data.size() * 6; } void StdMpiHelper >::createBuffer(vector &data, int *buf) { for (unsigned int i = 0; i < data.size(); i++) { buf[i * 6] = data[i].rankObj.elIndex; buf[i * 6 + 1] = data[i].rankObj.subObj; buf[i * 6 + 2] = data[i].rankObj.ithObj; buf[i * 6 + 3] = data[i].neighObj.elIndex; buf[i * 6 + 4] = data[i].neighObj.subObj; buf[i * 6 + 5] = data[i].neighObj.ithObj; } } void StdMpiHelper >::makeFromBuffer(vector &data, int *buf, int bufSize) { if (bufSize == 0) return; TEST_EXIT(bufSize % 6 == 0)("This should not happen!\n"); data.resize(bufSize / 6); for (int i = 0; i < bufSize / 6; i++) { data[i].rankObj.elIndex = buf[i * 6]; data[i].rankObj.subObj = static_cast(buf[i * 6 + 1]); data[i].rankObj.ithObj = buf[i * 6 + 2]; data[i].neighObj.elIndex = buf[i * 6 + 3]; data[i].neighObj.subObj = static_cast(buf[i * 6 + 4]); data[i].neighObj.ithObj = buf[i * 6 + 5]; } } // T = map > int StdMpiHelper > >::getBufferSize(map > &data) { int size = 1; for (map >::iterator it = data.begin(); it != data.end(); ++it) { size += 2 + it->second.size() * 2; } return size; } void StdMpiHelper > >::createBuffer(map > &data, int *buf) { buf[0] = data.size(); int counter = 1; for (map >::iterator it = data.begin(); it != data.end(); ++it) { buf[counter++] = it->first; buf[counter++] = it->second.size(); for (map::iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2) { buf[counter++] = it2->first; buf[counter++] = it2->second; } } } void StdMpiHelper > >::makeFromBuffer(map > &data, int *buf, int bufSize) { data.clear(); if (bufSize == 0) return; int counter = 1; for (int i = 0; i < buf[0]; i++) { BoundaryType bound = buf[counter++]; map dofs; int nDofs = buf[counter++]; for (int j = 0; j < nDofs; j++) { DegreeOfFreedom dof0, dof1; dof0 = buf[counter++]; dof1 = buf[counter++]; dofs[dof0] = dof1; } data[bound] = dofs; } TEST_EXIT(bufSize == counter)("Should not happen!\n"); } // T = vector > int StdMpiHelper > >::getBufferSize(vector > &data) { return data.size() * 2; } void StdMpiHelper > >::createBuffer(vector > &data, int *buf) { for (unsigned int i = 0; i < data.size(); i++) { buf[i * 2] = data[i].first; buf[i * 2 + 1] = data[i].second; } } void StdMpiHelper > >::makeFromBuffer(vector > &data, int *buf, int bufSize) { if (bufSize == 0) return; TEST_EXIT(bufSize % 2 == 0)("This should not happen!\n"); data.clear(); data.reserve(bufSize / 2); for (int i = 0; i < (bufSize / 2); i++) data.push_back(std::make_pair(buf[i * 2], buf[i * 2 + 1])); } // T = vector > int StdMpiHelper > >::getBufferSize(vector > &data) { return data.size() * Global::getGeo(WORLD); } void StdMpiHelper > >::createBuffer(vector > &data, double *buf) { int dimOfWorld = Global::getGeo(WORLD); int pos = 0; for (unsigned int i = 0; i < data.size(); i++) for (int j = 0; j < dimOfWorld; j++) buf[pos++] = data[i][j]; } void StdMpiHelper > >::makeFromBuffer(vector > &data, double *buf, int bufSize) { int dimOfWorld = Global::getGeo(WORLD); TEST_EXIT(bufSize % Global::getGeo(WORLD) == 0)("This should not happen!\n"); int pos = 0; data.resize(bufSize / Global::getGeo(WORLD)); for (unsigned int i = 0; i < data.size(); i++) for (int j = 0; j < dimOfWorld; j++) data[i][j] = buf[pos++]; } // T = map, int> int StdMpiHelper, int> >::getBufferSize(map, int> &data) { return data.size() * (Global::getGeo(WORLD) + 1); } void StdMpiHelper, int> >::createBuffer(map, int> &data, double* buf) { int i = 0; for (map, int>::iterator it = data.begin(); it != data.end(); ++it) { for (int j = 0; j < Global::getGeo(WORLD); j++) buf[i++] = it->first[j]; buf[i++] = static_cast(it->second); } } void StdMpiHelper, int> >::makeFromBuffer(map, int> &data, double* buf, int bufSize) { if (bufSize == 0) return; int oneEntrySize = Global::getGeo(WORLD) + 1; int nEntry = bufSize / oneEntrySize; TEST_EXIT(bufSize % oneEntrySize == 0)("This should not happen!\n"); data.clear(); int i = 0; WorldVector coords; for (int j = 0; j < nEntry; j++) { for (int k = 0; k < Global::getGeo(WORLD); k++) coords[k] = buf[i++]; data[coords] = static_cast(buf[i++]); } } // T = map, int> int StdMpiHelper > >::getBufferSize(map > &data) { return data.size() * (Global::getGeo(WORLD) + 1); } void StdMpiHelper > >::createBuffer(map > &data, double* buf) { int i = 0; for (map >::iterator it = data.begin(); it != data.end(); ++it) { for (int j = 0; j < Global::getGeo(WORLD); j++) buf[i++] = it->second[j]; buf[i++] = static_cast(it->first); } } void StdMpiHelper > >::makeFromBuffer(map > &data, double* buf, int bufSize) { if (bufSize == 0) return; int oneEntrySize = Global::getGeo(WORLD) + 1; int nEntry = bufSize / oneEntrySize; TEST_EXIT(bufSize % oneEntrySize == 0)("This should not happen!\n"); data.clear(); int i = 0; WorldVector coords; for (int j = 0; j < nEntry; j++) { for (int k = 0; k < Global::getGeo(WORLD); k++) coords[k] = buf[i++]; data[static_cast(buf[i++])] = coords; } } // T = vector > > int StdMpiHelper > > >::getBufferSize(vector > > &data) { int result = 1; for (unsigned int i = 0; i < data.size(); i++) result += 1 + (data[i].size() * Global::getGeo(WORLD)); return result; } void StdMpiHelper > > >::createBuffer(vector > > &data, double* buf) { int counter = 0; buf[counter++] = static_cast(data.size()); for (unsigned int i = 0; i < data.size(); i++) { buf[counter++] = data[i].size(); for (unsigned int j = 0; j < data[i].size(); j++) for (int k = 0; k < Global::getGeo(WORLD); k++) buf[counter++] = data[i][j][k]; } } void StdMpiHelper > > >::makeFromBuffer(vector > > &data, double* buf, int bufSize) { int counter = 0; data.resize(static_cast(buf[counter++])); for (unsigned int i = 0; i < data.size(); i++) { data[i].resize(static_cast(buf[counter++])); for (unsigned int j = 0; j < data[i].size(); j++) for (int k = 0; k < Global::getGeo(WORLD); k++) data[i][j][k] = buf[counter++]; } TEST_EXIT_DBG(counter == bufSize)("There is something very wrong!\n"); } } }