#ifndef __GRID_TRANSFORM_CONNECTOR_HPP__ #define __GRID_TRANSFORM_CONNECTOR_HPP__ #include "xios_spl.hpp" #include "array_new.hpp" #include "distributed_view.hpp" #include "local_view.hpp" #include "grid_scatterer_connector.hpp" #include "grid_gatherer_connector.hpp" #include "reduction_types.hpp" #include "mpi.hpp" namespace xios { class CGridTransformConnector { public: CGridTransformConnector(vector> srcViews, vector> remoteViews, MPI_Comm localComm) : srcViews_(srcViews), remoteViews_(remoteViews), localComm_(localComm) { } void computeConnector(bool eliminateRedundant=true) ; protected: MPI_Comm localComm_ ; vector> srcViews_ ; vector> remoteViews_ ; map recvRankSize_ ; vector> scattererConnector_ ; vector> gathererConnector_ ; shared_ptr gridScattererConnector_ ; shared_ptr gridGathererConnector_ ; public: template void transfer(const CArray& dataIn, CArray& dataOut, EReduction op = EReduction::none) { map> tmpArrayIn ; gridScattererConnector_->transfer(dataIn, tmpArrayIn) ; vector requests ; MPI_Request request ; for(auto it : tmpArrayIn) { auto& array = it.second ; MPI_Issend(array.dataFirst(), array.numElements(), MPI_GetType(), it.first, 0, localComm_, &request) ; requests.push_back(request) ; } map> tmpArrayOut ; for(auto it : recvRankSize_) { auto& array = tmpArrayOut[it.first] ; array.resize(it.second) ; MPI_Irecv(array.dataFirst(), array.numElements(), MPI_GetType(), it.first, 0, localComm_, &request) ; requests.push_back(request) ; } vector status(requests.size()) ; MPI_Waitall(requests.size(), requests.data(),status.data()) ; const double nanValue = std::numeric_limits::quiet_NaN(); if (op == EReduction::none) gridGathererConnector_->transfer(tmpArrayOut, dataOut, nanValue) ; else gridGathererConnector_->transfer(tmpArrayOut, dataOut, op) ; } }; } #endif