/*! \file generic_algorithm_transformation.hpp \author Ha NGUYEN \since 14 May 2015 \date 29 June 2015 \brief Interface for all transformation algorithms. */ #ifndef __XIOS_GENERIC_ALGORITHM_TRANSFORMATION_HPP__ #define __XIOS_GENERIC_ALGORITHM_TRANSFORMATION_HPP__ #include #include #include "array_new.hpp" #include "client_client_dht_template.hpp" namespace xios { class CGrid; class CDomain; class CAxis; class CScalar; /*! \class CGenericAlgorithmTransformation This class defines the interface for all other inherited algorithms class */ class CGenericAlgorithmTransformation { public: enum AlgoTransType { ELEMENT_GENERATION = 0, ELEMENT_MODIFICATION_WITHOUT_DATA = 1, ELEMENT_MODIFICATION_WITH_DATA = 2, ELEMENT_NO_MODIFICATION_WITH_DATA = 3, ELEMENT_NO_MODIFICATION_WITHOUT_DATA = 4 } ; public: // Mapping between global index map of DESTINATION and its local index with pair of global index of SOURCE and weights typedef std::unordered_map > > > SourceDestinationIndexMap; protected: typedef std::unordered_map GlobalLocalMap; protected: typedef std::unordered_map > TransformationIndexMap; typedef std::unordered_map > TransformationWeightMap; typedef std::unordered_map > TransformationPositionMap; public: CGenericAlgorithmTransformation(); virtual ~CGenericAlgorithmTransformation() {} bool isDistributedTransformation(int elementPositionInGrid, CGrid* gridSrc, CGrid* gridDst) ; void computeGlobalSourceIndex(int elementPositionInGrid, CGrid* gridSrc, CGrid* gridDst, SourceDestinationIndexMap& globaIndexWeightFromSrcToDst); /*! Apply a operation on local data. \param [in] localIndex vector contains local index of local data output and the corresponding weight \param [in] dataInput Pointer to the first element of data input array (in form of buffer) \param [in/out] dataOut Array contains local data \param [in/out] flagInitial vector of boolean to mark the local index already initialized. True means there is a need for initalization \param [in] ignoreMissingValue don't count missing value in operation if this flag is true \param [in] firstPass indicate if it is the first time the apply funtion is called for a same transformation, in order to make a clean initialization */ virtual void apply(const std::vector >& localIndex, const double* dataInput, CArray& dataOut, std::vector& flagInitial, bool ignoreMissingValue, bool firstPass); /*! * Update whole dataOut (on necessary). * (Example: Impose a weight, whose value is only known after being applied an operation, on dataOut) * \param [in/out] dataOut dataOut */ virtual void updateData(CArray& dataOut); std::vector getIdAuxInputs(); AlgoTransType type(); /*! Compute global index mapping from one element of destination grid to the corresponding element of source grid */ void computeIndexSourceMapping(const std::vector* >& dataAuxInputs = std::vector* >()); // void computeTransformationMappingNonDistributed(int elementPositionInGrid, CGrid* gridSrc, CGrid* gridDst, // vector& localSrc, vector& localDst, vector& weight, vector& localMaskOnGridDest); void computeTransformationMappingNonDistributed(int elementPositionInGrid, CGrid* gridSrc, CGrid* gridDst, vector& localSrc, vector& localDst, vector& weight, int nbLocalIndexOnGridDest); void nonDistributedrecursiveFunct(int currentPos, bool masked, int elementPositionInGrid, vector< CArray* >& maskSrc, vector< CArray* >& maskDst, int& srcInd, int& srcIndCompressed, vector& nIndexSrc, int& t, vector > > >& dstIndWeight, int currentInd, vector& localSrc, vector& localDst, vector& weight) ; protected: virtual void computeIndexSourceMapping_(const std::vector* >&) = 0; /*! Compute proc which contains global index of an element \param[in] globalElementIndex demanding global index of an element of source grid \param[in] elementType type of source element, 2: domain, 1: axis and 0: scalar \param[out] globalElementIndexOnProc Proc contains the demanding global index */ virtual void computeExchangeGlobalIndex(const CArray& globalElementIndex, int elementType, CClientClientDHTInt::Index2VectorInfoTypeMap& globalElementIndexOnProc) = 0; protected: void computeGlobalGridIndexMapping(int elementPositionInGrid, const std::vector& srcRank, std::unordered_map > >& src2DstMap, CGrid* gridDst, CGrid* gridSrc, std::vector > >& globalElementIndexOnProc, SourceDestinationIndexMap& globaIndexWeightFromSrcToDst); void computeExchangeDomainIndex(CDomain* domainDst, CDomain* domainSrc, CArray& destGlobalIndexPositionInGrid, std::unordered_map >& globalDomainIndexOnProc); void computeExchangeAxisIndex(CAxis* axisDst, CAxis* axisSrc, CArray& destGlobalIndexPositionInGrid, std::unordered_map >& globalAxisIndexOnProc); void computeExchangeScalarIndex(CScalar* scalarDst, CScalar* scalarSrc, CArray& destGlobalIndexPositionInGrid, std::unordered_map >& globalScalarIndexOnProc); void computePositionElements(CGrid* dst, CGrid* src); protected: //! indicate if the transformation is performed on a distributed element bool isDistributed_ ; //! indicate if the method isDistributedTransformation has been called before bool isDistributedComputed_ ; //! Map between global index of destination element and source element std::vector transformationMapping_; //! Weight corresponding of source to destination std::vector transformationWeight_; //! Map of global index of destination element and corresponding global index of other elements in the same grid //! By default, one index of an element corresponds to all index of remaining element in the grid. So it's empty std::vector transformationPosition_; //! Id of auxillary inputs which helps doing transformation dynamically std::vector idAuxInputs_; AlgoTransType type_; std::set indexElementSrc_; std::vector > > globalElementIndexOnProc_; std::vector procContainSrcElementIdx_; // List of processes containing source index of transformed elements // std::set procOfNonTransformedElements_; // Processes contain the source index of non-transformed elements std::set commonProc_; std::vector< set > procElementList_ ; // List of processes containing source index of elements CClientClientDHTInt::Index2VectorInfoTypeMap globalIndexOfTransformedElementOnProc_; bool computedProcSrcNonTransformedElement_; // Flag to indicate whether we computed proc containing non transformed elements std::map elementPositionInGridSrc2AxisPosition_, elementPositionInGridSrc2DomainPosition_, elementPositionInGridSrc2ScalarPosition_; std::map elementPositionInGridDst2AxisPosition_, elementPositionInGridDst2DomainPosition_, elementPositionInGridDst2ScalarPosition_; bool eliminateRedondantSrc_ ; // flag to indicate if the transformation must select only one global source point for all proc. // In this case it will choose preferentially the current process }; } #endif // __XIOS_GENERIC_ALGORITHM_TRANSFORMATION_HPP__