Changeset 1653
- Timestamp:
- 03/06/19 12:11:10 (5 years ago)
- Location:
- XIOS/dev/dev_olga/src
- Files:
-
- 4 added
- 36 edited
Legend:
- Unmodified
- Added
- Removed
-
XIOS/dev/dev_olga/src/config/field_attribute.conf
r1524 r1653 19 19 DECLARE_ATTRIBUTE(bool, indexed_output) 20 20 DECLARE_ATTRIBUTE(bool, check_if_active) 21 DECLARE_ATTRIBUTE(bool, build_workflow_graph) 21 22 22 23 DECLARE_ATTRIBUTE(StdString, domain_ref, false) -
XIOS/dev/dev_olga/src/cxios.cpp
r1612 r1653 11 11 #include "memtrack.hpp" 12 12 #include "registry.hpp" 13 #include "graphviz.hpp" 13 14 14 15 namespace xios … … 135 136 globalRegistry->toFile("xios_registry.bin") ; 136 137 delete globalRegistry ; 138 139 CGraphviz::buildStaticWorkflowGraph(); 137 140 } 138 141 -
XIOS/dev/dev_olga/src/filter/file_server_writer_filter.cpp
r1358 r1653 12 12 ERROR("CFileServerWriterFilter::CFileServerWriterFilter(CField* field)", 13 13 "The field cannot be null."); 14 filterId = InvalidableObject::count; 15 InvalidableObject::count++; 14 16 } 15 17 … … 28 30 return true; 29 31 } 32 33 int CFileServerWriterFilter::getFilterId(void) 34 { 35 return filterId; 36 } 37 30 38 } // namespace xios -
XIOS/dev/dev_olga/src/filter/file_server_writer_filter.hpp
r1358 r1653 37 37 bool virtual isDataExpected(const CDate& date) const; 38 38 39 /*! 40 * Returns filter's id needed in case of building workflow graph 41 */ 42 int getFilterId(); 43 39 44 protected: 40 45 /*! … … 46 51 47 52 private: 48 CField* field; //<! The associated field53 CField* field; //<! The associated field 49 54 std::map<Time, CDataPacketPtr> packets; //<! The stored packets 55 int filterId; //<! Filter's id needed in case of building a workflow 56 50 57 }; // class CFileServerWriterFilter 51 58 } // namespace xios -
XIOS/dev/dev_olga/src/filter/file_writer_filter.cpp
r1594 r1653 3 3 #include "field.hpp" 4 4 #include "utils.hpp" 5 #include "workflow_graph.hpp" 5 6 6 7 namespace xios … … 13 14 ERROR("CFileWriterFilter::CFileWriterFilter(CField* field)", 14 15 "The field cannot be null."); 16 filterId = InvalidableObject::count; 17 InvalidableObject::count++; 15 18 } 16 19 … … 46 49 return true; 47 50 } 51 52 int CFileWriterFilter::getFilterId(void) 53 { 54 return filterId; 55 } 56 48 57 } // namespace xios -
XIOS/dev/dev_olga/src/filter/file_writer_filter.hpp
r1358 r1653 23 23 CFileWriterFilter(CGarbageCollector& gc, CField* field); 24 24 25 inline StdString GetName(void) {return StdString("File writer filter");}; 26 25 27 /*! 26 28 * Tests if the filter must auto-trigger. … … 37 39 bool virtual isDataExpected(const CDate& date) const; 38 40 41 /*! 42 * Returns filter's id needed in case of building workflow graph 43 */ 44 int getFilterId(); 45 39 46 protected: 40 47 /*! … … 46 53 47 54 private: 48 CField* field; //<! The associated field55 CField* field; //<! The associated field 49 56 std::map<Time, CDataPacketPtr> packets; //<! The stored packets 57 int filterId; //<! Filter's id needed in case of building a workflow 58 50 59 }; // class CFileWriterFilter 51 60 } // namespace xios -
XIOS/dev/dev_olga/src/filter/filter.cpp
r1358 r1653 3 3 namespace xios 4 4 { 5 CFilter::CFilter(CGarbageCollector& gc, size_t inputSlotsCount, IFilterEngine* engine )5 CFilter::CFilter(CGarbageCollector& gc, size_t inputSlotsCount, IFilterEngine* engine, bool buildWorkflowGraph /*= false*/) 6 6 : CInputPin(gc, inputSlotsCount) 7 , COutputPin(gc )7 , COutputPin(gc, false, buildWorkflowGraph) 8 8 , engine(engine) 9 9 , inputSlotCount(inputSlotCount) 10 10 { /* Nothing to do */ } 11 12 StdString CFilter::GetName(void) { return StdString("Filter"); } 11 13 12 14 void CFilter::onInputReady(std::vector<CDataPacketPtr> data) -
XIOS/dev/dev_olga/src/filter/filter.hpp
r1358 r1653 23 23 * \param inputSlotsCount the number of input slots 24 24 * \param engine the filter engine 25 * \param buildWorkflowGraph indicates whether data will be visualized 25 26 */ 26 CFilter(CGarbageCollector& gc, size_t inputSlotsCount, IFilterEngine* engine); 27 CFilter(CGarbageCollector& gc, size_t inputSlotsCount, IFilterEngine* engine, bool buildWorkflowGraph = false); 28 29 StdString virtual GetName(void); 27 30 28 31 /*! -
XIOS/dev/dev_olga/src/filter/garbage_collector.cpp
r1021 r1653 3 3 namespace xios 4 4 { 5 6 int InvalidableObject::count = 0; 7 5 8 void CGarbageCollector::registerObject(InvalidableObject* Object, Time timestamp) 6 9 { -
XIOS/dev/dev_olga/src/filter/garbage_collector.hpp
r1021 r1653 20 20 */ 21 21 void virtual invalidate(Time timestamp) = 0; 22 23 static int count; //!< Counter used to identify a filter in case building workflow graph 24 22 25 }; // struct InvalidableObject 23 26 -
XIOS/dev/dev_olga/src/filter/input_pin.cpp
r1021 r1653 3 3 #include "garbage_collector.hpp" 4 4 #include "exception.hpp" 5 #include "workflow_graph.hpp" 5 6 6 7 namespace xios … … 11 12 , triggers(slotsCount) 12 13 , hasTriggers(false) 13 { /* Nothing to do */ } 14 { } 15 16 StdString CInputPin::GetName(void) 17 { 18 return StdString("Input pin"); 19 } 14 20 15 21 void CInputPin::setInput(size_t inputSlot, CDataPacketPtr packet) … … 77 83 inputs.erase(inputs.begin(), inputs.lower_bound(timestamp)); 78 84 } 85 86 int CInputPin::getFilterId(void) 87 { 88 return -1; 89 } 90 79 91 } // namespace xios -
XIOS/dev/dev_olga/src/filter/input_pin.hpp
r1358 r1653 26 26 */ 27 27 CInputPin(CGarbageCollector& gc, size_t slotsCount); 28 29 StdString virtual GetName(void); 28 30 29 31 /*! … … 79 81 */ 80 82 void virtual invalidate(Time timestamp); 83 84 /*! 85 * Returns filter's id needed in case of building workflow graph 86 * This function should never be called from this class, instead functions defined in derived classes or in class COutputPin should be used 87 */ 88 int virtual getFilterId(); 81 89 82 90 protected: -
XIOS/dev/dev_olga/src/filter/output_pin.cpp
r1542 r1653 1 1 #include "output_pin.hpp" 2 2 #include "exception.hpp" 3 #include "workflow_graph.hpp" 3 4 4 5 namespace xios 5 6 { 6 COutputPin::COutputPin(CGarbageCollector& gc, bool manualTrigger /*= false*/ )7 COutputPin::COutputPin(CGarbageCollector& gc, bool manualTrigger /*= false*/, bool buildWorkflowGraph /* =false */) 7 8 : gc(gc) 8 9 , manualTrigger(manualTrigger) 9 { /* Nothing to do */ } 10 , buildWorkflowGraph(buildWorkflowGraph) 11 { 12 filterId = InvalidableObject::count; 13 InvalidableObject::count++; 14 } 15 16 StdString COutputPin::GetName(void) 17 { 18 return StdString("Output pin"); 19 } 10 20 11 21 void COutputPin::connectOutput(std::shared_ptr<CInputPin> inputPin, size_t inputSlot) … … 26 36 ERROR("void COutputPin::onOutputReady(CDataPacketPtr packet)", 27 37 "The packet cannot be null."); 38 39 if (buildWorkflowGraph) 40 { 41 CWorkflowGraph::mapFilterTimestamps[this->getFilterId()].push_back(packet->timestamp); 42 CWorkflowGraph::timestamps.insert(packet->timestamp); 43 } 28 44 29 45 if (manualTrigger) // Don't use canBeTriggered here, this function is virtual and can be overriden … … 101 117 outputPackets.erase(outputPackets.begin(), outputPackets.lower_bound(timestamp)); 102 118 } 119 120 int COutputPin::getFilterId(void) 121 { 122 return filterId; 123 } 124 103 125 } // namespace xios -
XIOS/dev/dev_olga/src/filter/output_pin.hpp
r1542 r1653 19 19 * \param gc the garbage collector associated with this ouput pin 20 20 * \param slotsCount the number of slots 21 * \param buildWorkflowGraph indicates whether data will be visualized 21 22 */ 22 COutputPin(CGarbageCollector& gc, bool manualTrigger = false );23 COutputPin(CGarbageCollector& gc, bool manualTrigger = false, bool buildWorkflowGraph = false); 23 24 25 StdString virtual GetName(void); 26 24 27 /*! 25 28 * Connects to a specific slot of the input pin of a downstream filter. … … 66 69 void virtual invalidate(Time timestamp); 67 70 71 /*! 72 * Returns filter's id needed in case of building workflow graph 73 */ 74 int getFilterId(); 75 68 76 protected: 69 77 /*! … … 97 105 //! Output buffer, store the packets until the output is triggered 98 106 std::map<Time, CDataPacketPtr> outputPackets; 107 108 //! Indicates whether the workflow will be visualized 109 bool buildWorkflowGraph; 110 111 //! Filter's id needed in case of building a workflow graph 112 int filterId; 113 114 99 115 }; // class COutputPin 100 116 } // namespace xios -
XIOS/dev/dev_olga/src/filter/pass_through_filter.cpp
r641 r1653 3 3 namespace xios 4 4 { 5 CPassThroughFilter::CPassThroughFilter(CGarbageCollector& gc )6 : CFilter(gc, 1, this )5 CPassThroughFilter::CPassThroughFilter(CGarbageCollector& gc, bool buildWorkflowGraph /*= false*/) 6 : CFilter(gc, 1, this, buildWorkflowGraph) 7 7 { /* Nothing to do */ } 8 8 -
XIOS/dev/dev_olga/src/filter/pass_through_filter.hpp
r641 r1653 17 17 * 18 18 * \param gc the associated garbage collector 19 * \param buildWorkflowGraph indicates whether data will be visualized 19 20 */ 20 CPassThroughFilter(CGarbageCollector& gc); 21 CPassThroughFilter(CGarbageCollector& gc, bool buildWorkflowGraph = false); 22 23 inline StdString GetName(void) {return StdString("Pass through filter");}; 21 24 22 25 protected: -
XIOS/dev/dev_olga/src/filter/source_filter.cpp
r1568 r1653 4 4 #include "calendar_util.hpp" 5 5 #include <limits> 6 #include "workflow_graph.hpp" 6 7 7 8 namespace xios … … 11 12 const CDuration offset /*= NoneDu*/, bool manualTrigger /*= false*/, 12 13 bool hasMissingValue /*= false*/, 13 double defaultValue /*= 0.0*/) 14 : COutputPin(gc, manualTrigger) 14 double defaultValue /*= 0.0*/, 15 bool buildWorkflowGraph /*= false*/) 16 : COutputPin(gc, manualTrigger, buildWorkflowGraph) 15 17 , grid(grid) 16 18 , compression(compression) -
XIOS/dev/dev_olga/src/filter/source_filter.hpp
r1568 r1653 27 27 * \param hasMissingValue whether data has missing value 28 28 * \param defaultValue missing value to detect 29 * \param[in] buildWorkflowGraph indicates whether the workflow will be visualized 29 30 */ 30 31 CSourceFilter(CGarbageCollector& gc, CGrid* grid, … … 33 34 const CDuration offset = NoneDu, bool manualTrigger = false, 34 35 bool hasMissingValue = false, 35 double defaultValue = 0.0); 36 double defaultValue = 0.0, 37 bool buildWorkflowGraph = false); 38 39 inline StdString GetName(void) {return StdString("Source filter");}; 36 40 37 41 /*! -
XIOS/dev/dev_olga/src/filter/spatial_transform_filter.cpp
r1589 r1653 4 4 #include "context_client.hpp" 5 5 #include "timer.hpp" 6 #include "workflow_graph.hpp" 6 7 7 8 namespace xios 8 9 { 9 CSpatialTransformFilter::CSpatialTransformFilter(CGarbageCollector& gc, CSpatialTransformFilterEngine* engine, double outputValue, size_t inputSlotsCount) 10 : CFilter(gc, inputSlotsCount, engine), outputDefaultValue(outputValue) 10 CSpatialTransformFilter::CSpatialTransformFilter(CGarbageCollector& gc, CSpatialTransformFilterEngine* engine, 11 double outputValue, size_t inputSlotsCount, bool buildWorkflowGraph /*= false*/) 12 : CFilter(gc, inputSlotsCount, engine, buildWorkflowGraph), outputDefaultValue(outputValue) 11 13 { /* Nothing to do */ } 12 14 13 15 std::pair<std::shared_ptr<CSpatialTransformFilter>, std::shared_ptr<CSpatialTransformFilter> > 14 CSpatialTransformFilter::buildFilterGraph(CGarbageCollector& gc, CGrid* srcGrid, CGrid* destGrid, bool hasMissingValue, double missingValue) 16 CSpatialTransformFilter::buildFilterGraph(CGarbageCollector& gc, CGrid* srcGrid, CGrid* destGrid, bool hasMissingValue, double missingValue, 17 bool buildWorkflowGraph) 15 18 { 16 19 if (!srcGrid || !destGrid) … … 29 32 double defaultValue = (hasMissingValue) ? std::numeric_limits<double>::quiet_NaN() : 0.0; 30 33 31 32 34 const CGridTransformationSelector::ListAlgoType& algoList = gridTransformation->getAlgoList() ; 33 35 CGridTransformationSelector::ListAlgoType::const_iterator it ; … … 37 39 38 40 std::shared_ptr<CSpatialTransformFilter> filter ; 39 if( isSpatialTemporal) filter = std::shared_ptr<CSpatialTransformFilter>(new CSpatialTemporalFilter(gc, engine, gridTransformation, defaultValue, inputCount)); 40 else filter = std::shared_ptr<CSpatialTransformFilter>(new CSpatialTransformFilter(gc, engine, defaultValue, inputCount)); 41 42 41 if( isSpatialTemporal) 42 filter = std::shared_ptr<CSpatialTransformFilter>(new CSpatialTemporalFilter(gc, engine, gridTransformation, defaultValue, inputCount, buildWorkflowGraph)); 43 else 44 filter = std::shared_ptr<CSpatialTransformFilter>(new CSpatialTransformFilter(gc, engine, defaultValue, inputCount, buildWorkflowGraph)); 45 43 46 if (!lastFilter) 44 47 lastFilter = filter; 45 48 else 49 { 46 50 filter->connectOutput(firstFilter, 0); 51 if (buildWorkflowGraph) 52 { 53 int filterOut = (std::static_pointer_cast<COutputPin>(filter))->getFilterId(); 54 int filterIn = (std::static_pointer_cast<COutputPin>(firstFilter))->getFilterId(); 55 // PASS field's id here 56 CWorkflowGraph::mapFieldToFilters["XXX"].push_back(filterOut); 57 CWorkflowGraph::mapFieldToFilters["XXX"].push_back(filterIn); 58 CWorkflowGraph::mapFilters[filterOut] = "Spatial transform filter"; 59 CWorkflowGraph::mapFilters[filterIn] = "Spatial transform filter"; 60 } 61 } 47 62 48 63 firstFilter = filter; … … 69 84 } 70 85 71 CSpatialTemporalFilter::CSpatialTemporalFilter(CGarbageCollector& gc, CSpatialTransformFilterEngine* engine, CGridTransformation* gridTransformation, double outputValue, size_t inputSlotsCount) 72 : CSpatialTransformFilter(gc, engine, outputValue, inputSlotsCount), record(0) 86 CSpatialTemporalFilter::CSpatialTemporalFilter(CGarbageCollector& gc, CSpatialTransformFilterEngine* engine, 87 CGridTransformation* gridTransformation, double outputValue, 88 size_t inputSlotsCount, bool buildWorkflowGraph) 89 : CSpatialTransformFilter(gc, engine, outputValue, inputSlotsCount, buildWorkflowGraph), record(0) 73 90 { 74 91 const CGridTransformationSelector::ListAlgoType& algoList = gridTransformation->getAlgoList() ; … … 188 205 189 206 CContextClient* client = CContext::getCurrent()->client; 207 int rank; 208 MPI_Comm_rank (client->intraComm, &rank); 190 209 191 210 // Get default value for output data … … 217 236 int idxSendBuff = 0; 218 237 std::vector<double*> sendBuff(localIndexToSend.size()); 238 double* sendBuffRank; 219 239 for (itSend = itbSend; itSend != iteSend; ++itSend, ++idxSendBuff) 220 240 { 241 int destRank = itSend->first; 221 242 if (0 != itSend->second.numElements()) 222 sendBuff[idxSendBuff] = new double[itSend->second.numElements()]; 243 { 244 if (rank != itSend->first) 245 sendBuff[idxSendBuff] = new double[itSend->second.numElements()]; 246 else 247 sendBuffRank = new double[itSend->second.numElements()]; 248 } 223 249 } 224 250 … … 230 256 const CArray<int,1>& localIndex_p = itSend->second; 231 257 int countSize = localIndex_p.numElements(); 232 for (int idx = 0; idx < countSize; ++idx) 233 { 234 sendBuff[idxSendBuff][idx] = dataCurrentSrc(localIndex_p(idx)); 235 } 236 sendRecvRequest.push_back(MPI_Request()); 237 MPI_Isend(sendBuff[idxSendBuff], countSize, MPI_DOUBLE, destRank, 12, client->intraComm, &sendRecvRequest.back()); 258 if (destRank != rank) 259 { 260 for (int idx = 0; idx < countSize; ++idx) 261 { 262 sendBuff[idxSendBuff][idx] = dataCurrentSrc(localIndex_p(idx)); 263 } 264 sendRecvRequest.push_back(MPI_Request()); 265 MPI_Isend(sendBuff[idxSendBuff], countSize, MPI_DOUBLE, destRank, 12, client->intraComm, &sendRecvRequest.back()); 266 } 267 else 268 { 269 for (int idx = 0; idx < countSize; ++idx) 270 { 271 sendBuffRank[idx] = dataCurrentSrc(localIndex_p(idx)); 272 } 273 } 238 274 } 239 275 … … 243 279 iteRecv = localIndexToReceive.end(); 244 280 int recvBuffSize = 0; 245 for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv) recvBuffSize += itRecv->second.size(); //(recvBuffSize < itRecv->second.size()) 246 //? itRecv->second.size() : recvBuffSize; 281 for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv) 282 { 283 if (itRecv->first != rank ) 284 recvBuffSize += itRecv->second.size(); 285 } 286 //(recvBuffSize < itRecv->second.size()) ? itRecv->second.size() : recvBuffSize; 247 287 double* recvBuff; 288 248 289 if (0 != recvBuffSize) recvBuff = new double[recvBuffSize]; 249 290 int currentBuff = 0; … … 251 292 { 252 293 int srcRank = itRecv->first; 253 int countSize = itRecv->second.size(); 254 sendRecvRequest.push_back(MPI_Request()); 255 MPI_Irecv(recvBuff + currentBuff, countSize, MPI_DOUBLE, srcRank, 12, client->intraComm, &sendRecvRequest.back()); 256 currentBuff += countSize; 294 if (srcRank != rank) 295 { 296 int countSize = itRecv->second.size(); 297 sendRecvRequest.push_back(MPI_Request()); 298 MPI_Irecv(recvBuff + currentBuff, countSize, MPI_DOUBLE, srcRank, 12, client->intraComm, &sendRecvRequest.back()); 299 currentBuff += countSize; 300 } 257 301 } 258 302 std::vector<MPI_Status> status(sendRecvRequest.size()); … … 267 311 for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv) 268 312 { 269 int countSize = itRecv->second.size();270 313 const std::vector<std::pair<int,double> >& localIndex_p = itRecv->second; 271 (*itAlgo)->apply(localIndex_p, 272 recvBuff+currentBuff, 273 dataCurrentDest, 274 localInitFlag, 275 ignoreMissingValue,firstPass); 276 277 currentBuff += countSize; 314 int srcRank = itRecv->first; 315 if (srcRank != rank) 316 { 317 int countSize = itRecv->second.size(); 318 (*itAlgo)->apply(localIndex_p, 319 recvBuff+currentBuff, 320 dataCurrentDest, 321 localInitFlag, 322 ignoreMissingValue,firstPass); 323 currentBuff += countSize; 324 } 325 else 326 { 327 (*itAlgo)->apply(localIndex_p, 328 sendBuffRank, 329 dataCurrentDest, 330 localInitFlag, 331 ignoreMissingValue,firstPass); 332 } 333 278 334 firstPass=false ; 279 335 } … … 285 341 { 286 342 if (0 != itSend->second.numElements()) 287 delete [] sendBuff[idxSendBuff]; 343 { 344 if (rank != itSend->first) 345 delete [] sendBuff[idxSendBuff]; 346 else 347 delete [] sendBuffRank; 348 } 288 349 } 289 350 if (0 != recvBuffSize) delete [] recvBuff; -
XIOS/dev/dev_olga/src/filter/spatial_transform_filter.hpp
r1542 r1653 23 23 * \param outputValue default value of output pin 24 24 * \param [in] inputSlotsCount number of input, by default there is only one for field src 25 * \param buildWorkflowGraph indicates whether data will be visualized 25 26 */ 26 CSpatialTransformFilter(CGarbageCollector& gc, CSpatialTransformFilterEngine* engine, double outputValue, size_t inputSlotsCount = 1); 27 CSpatialTransformFilter(CGarbageCollector& gc, CSpatialTransformFilterEngine* engine, 28 double outputValue, size_t inputSlotsCount = 1, bool buildWorkflowGraph = false); 29 30 inline StdString GetName(void) {return StdString("Spatial transform filter");}; 27 31 28 32 /*! … … 34 38 * \param hasMissingValue whether field source has missing value 35 39 * \param defaultValue default value 40 * \param buildWorkflowGraph indicates whether data will be visualized 36 41 * \return the first and the last filters of the filter graph 37 42 */ 38 43 static std::pair<std::shared_ptr<CSpatialTransformFilter>, std::shared_ptr<CSpatialTransformFilter> > 39 buildFilterGraph(CGarbageCollector& gc, CGrid* srcGrid, CGrid* destGrid, bool hasMissingValue, double defaultValue );44 buildFilterGraph(CGarbageCollector& gc, CGrid* srcGrid, CGrid* destGrid, bool hasMissingValue, double defaultValue, bool buildWorkflowGraph = false); 40 45 41 46 protected: … … 67 72 * \param outputValue default value of output pin 68 73 * \param [in] inputSlotsCount number of input, by default there is only one for field src 74 * \param buildWorkflowGraph indicates whether data will be visualized 75 * 69 76 */ 70 CSpatialTemporalFilter(CGarbageCollector& gc, CSpatialTransformFilterEngine* engine, CGridTransformation* gridTransformation, double outputValue, size_t inputSlotsCount = 1); 77 CSpatialTemporalFilter(CGarbageCollector& gc, CSpatialTransformFilterEngine* engine, CGridTransformation* gridTransformation, 78 double outputValue, size_t inputSlotsCount = 1, bool buildWorkflowGraph = false); 71 79 72 80 -
XIOS/dev/dev_olga/src/filter/store_filter.cpp
r1474 r1653 21 21 ERROR("CStoreFilter::CStoreFilter(CContext* context, CGrid* grid)", 22 22 "Impossible to construct a store filter without providing a grid."); 23 filterId = InvalidableObject::count; 24 InvalidableObject::count++; 23 25 } 24 26 … … 126 128 packets.erase(packets.begin(), packets.lower_bound(timestamp)); 127 129 } 130 131 int CStoreFilter::getFilterId(void) 132 { 133 return filterId; 134 } 135 128 136 } // namespace xios -
XIOS/dev/dev_olga/src/filter/store_filter.hpp
r1358 r1653 73 73 void virtual invalidate(Time timestamp); 74 74 75 /*! 76 * Returns filter's id needed in case of building workflow graph 77 */ 78 int getFilterId(); 79 75 80 protected: 76 81 /*! … … 82 87 83 88 private: 84 CGarbageCollector& gc; //!< The garbage collector associated to the filter85 CContext* context; //!< The context to which the data belongs86 CGrid* grid; //!< The grid attached to the data the filter can accept87 const bool detectMissingValues; //!< Whether missing values should be detected88 const double missingValue; //!< The value to use to replace missing values89 CGarbageCollector& gc; //!< The garbage collector associated to the filter 90 CContext* context; //!< The context to which the data belongs 91 CGrid* grid; //!< The grid attached to the data the filter can accept 92 const bool detectMissingValues; //!< Whether missing values should be detected 93 const double missingValue; //!< The value to use to replace missing values 89 94 std::map<Time, CDataPacketPtr> packets; //<! The stored packets 95 int filterId; //!< Filter's id needed in case of building a workflow 96 90 97 }; // class CStoreFilter 91 98 } // namespace xios -
XIOS/dev/dev_olga/src/filter/temporal_filter.cpp
r1523 r1653 9 9 CTemporalFilter::CTemporalFilter(CGarbageCollector& gc, const std::string& opId, 10 10 const CDate& initDate, const CDuration samplingFreq, const CDuration samplingOffset, const CDuration opFreq, 11 bool ignoreMissingValue /*= false*/ )12 : CFilter(gc, 1, this )11 bool ignoreMissingValue /*= false*/, bool buildWorkflowGraph /*= false*/) 12 : CFilter(gc, 1, this, buildWorkflowGraph) 13 13 , functor(createFunctor(opId, ignoreMissingValue, tmpData)) 14 14 , isOnceOperation(functor->timeType() == func::CFunctor::once) … … 22 22 this->samplingOffset.second, this->samplingOffset.timestep) 23 23 , initDate(initDate) 24 // , nextSamplingDate(initDate + (this->samplingOffset + initDate.getRelCalendar().getTimeStep()))25 24 , nextSamplingDate(initDate + offsetMonth + ( offsetAllButMonth + initDate.getRelCalendar().getTimeStep())) 26 25 , nbOperationDates(1) 27 26 , nbSamplingDates(0) 28 // , nextOperationDate(initDate + opFreq + this->samplingOffset)29 27 , isFirstOperation(true) 30 28 { … … 43 41 { 44 42 usePacket = (data[0]->date >= nextSamplingDate); 45 // outputResult = (data[0]->date + samplingFreq > nextOperationDate);46 43 outputResult = (data[0]->date > initDate + nbOperationDates*opFreq - samplingFreq + offsetMonth + offsetAllButMonth); 47 44 copyLess = (isInstantOperation && usePacket && outputResult); … … 80 77 81 78 isFirstOperation = false; 82 // nextOperationDate = initDate + samplingFreq + nbOperationDates*opFreq - samplingFreq + offsetMonth + offsetAllButMonth;83 79 } 84 80 } … … 94 90 bool CTemporalFilter::isDataExpected(const CDate& date) const 95 91 { 96 // return isOnceOperation ? isFirstOperation : (date >= nextSamplingDate || date + samplingFreq > nextOperationDate);97 92 return isOnceOperation ? isFirstOperation : (date >= nextSamplingDate || date > initDate + nbOperationDates*opFreq - samplingFreq + offsetMonth + offsetAllButMonth); 98 93 } -
XIOS/dev/dev_olga/src/filter/temporal_filter.hpp
r1473 r1653 29 29 CTemporalFilter(CGarbageCollector& gc, const std::string& opId, 30 30 const CDate& initDate, const CDuration samplingFreq, const CDuration samplingOffset, const CDuration opFreq, 31 bool ignoreMissingValue = false); 31 bool ignoreMissingValue = false, bool buildWorkflowGraph = false); 32 33 inline StdString GetName(void) {return StdString("Temporal filter");}; 32 34 33 35 /*! -
XIOS/dev/dev_olga/src/io/nc4_data_output.cpp
r1612 r1653 426 426 std::vector<StdSize> start(2) ; 427 427 std::vector<StdSize> count(2) ; 428 // Comment out for a moment becauseit is not working for a hole428 // Comment out: it is not working for a hole 429 429 // if (domain->isEmpty()) 430 430 // { -
XIOS/dev/dev_olga/src/io/onetcdf4_impl.hpp
r1633 r1653 60 60 CTimer::get("CONetCDF4::writeData getWriteDataInfos").suspend(); 61 61 62 int dimArrayLen = 0;62 int dimArrayLen; 63 63 for (int i=0; i<scount.size(); i++) 64 64 if (scount[i] == stringArrayLen) … … 73 73 } 74 74 char *PtrArrayStr ; 75 PtrArrayStr=new char[stringArrayLen] ; 75 PtrArrayStr=new char[stringArrayLen*data.numElements()] ; 76 memset (PtrArrayStr,' ',stringArrayLen*data.numElements()); 77 size_t offset=0 ; 76 78 Array<StdString,1>::const_iterator it, itb=data.begin(), ite=data.end() ; 77 int lineNb = 0; 78 for(it=itb;it!=ite;it++) 79 for(it=itb;it!=ite;++it, offset+=stringArrayLen) 79 80 { 80 it->copy(PtrArrayStr,it->size()) ; 81 PtrArrayStr[it->size()]='\0' ; 82 sstart[0] = lineNb; 83 sstart[dimArrayLen] = 0; 84 scount[0] = 1; 85 scount[dimArrayLen] = it->size()+1; 86 CTimer::get("CONetCDF4::writeData writeData_").resume(); 87 this->writeData_(grpid, varid, sstart, scount, PtrArrayStr); 88 CTimer::get("CONetCDF4::writeData writeData_").suspend(); 89 ++lineNb; 81 it->copy(PtrArrayStr+offset,it->size()) ; 82 PtrArrayStr[offset+it->size()]='\0' ; 90 83 } 84 85 CTimer::get("CONetCDF4::writeData writeData_").resume(); 86 this->writeData_(grpid, varid, sstart, scount, PtrArrayStr); 87 CTimer::get("CONetCDF4::writeData writeData_").suspend(); 88 91 89 delete [] PtrArrayStr; 92 90 } -
XIOS/dev/dev_olga/src/node/axis.hpp
r1589 r1653 183 183 }; // class CAxis 184 184 185 ///-------------------------------------------------------------- 186 185 187 // Declare/Define CAxisGroup and CAxisDefinition 186 188 DECLARE_GROUP(CAxis); -
XIOS/dev/dev_olga/src/node/field.cpp
r1612 r1653 24 24 #include "spatial_transform_filter.hpp" 25 25 #include "file_server_writer_filter.hpp" 26 #include "workflow_graph.hpp" 26 27 27 28 namespace xios{ … … 1109 1110 TRY 1110 1111 { 1111 if (!isReferenceSolvedAndTransformed) solveAllEnabledFieldsAndTransform();1112 if (!isGridChecked) checkGridOfEnabledFields();1112 if (!isReferenceSolvedAndTransformed) solveAllEnabledFieldsAndTransform(); 1113 if (!isGridChecked) checkGridOfEnabledFields(); 1113 1114 1114 1115 const bool detectMissingValues = (!detect_missing_value.isEmpty() && !default_value.isEmpty() && detect_missing_value == true); 1116 const bool buildWorkflowGraph = (!build_workflow_graph.isEmpty() && build_workflow_graph == true); 1115 1117 const double defaultValue = detectMissingValues ? default_value : (!default_value.isEmpty() ? default_value : 0.0); 1116 1118 … … 1122 1124 { 1123 1125 if (!instantDataFilter) 1126 { 1124 1127 instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, false)); 1125 1128 } 1126 1129 1127 1130 // If the field data is to be read by the client or/and written to a file … … 1138 1141 { 1139 1142 if (!instantDataFilter) 1143 { 1140 1144 instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, false, false)); 1141 1145 } 1142 1146 // If the field data is to be read by the client or/and written to a file 1143 1147 if (enableOutput && !storeFilter && !fileWriterFilter) … … 1164 1168 if (!field_ref.isEmpty()) 1165 1169 { 1166 CGrid* gridRef = CField::get(field_ref)->grid; 1170 CField* fieldRef = CField::get(field_ref); 1171 fieldRef->build_workflow_graph.setValue(buildWorkflowGraph); 1172 CGrid* gridRef = fieldRef->grid; 1167 1173 1168 1174 if (grid && grid != gridRef && grid->hasTransform()) 1169 1175 { 1170 std::pair<std::shared_ptr<CFilter>, std::shared_ptr<CFilter> > filters = CSpatialTransformFilter::buildFilterGraph(gc, gridRef, grid, detectMissingValues, defaultValue); 1176 std::pair<std::shared_ptr<CFilter>, std::shared_ptr<CFilter> > filters = CSpatialTransformFilter::buildFilterGraph(gc, gridRef, grid, 1177 detectMissingValues, defaultValue, buildWorkflowGraph); 1171 1178 1172 1179 filter->connectOutput(filters.first, 0); 1180 1181 if (buildWorkflowGraph) 1182 { 1183 int filterOut = filter->getFilterId(); 1184 int filterIn = (std::static_pointer_cast<COutputPin>(filters.second))->getFilterId(); 1185 CWorkflowGraph::mapFieldToFilters[this->getId()].push_back(filterOut); 1186 CWorkflowGraph::mapFieldToFilters[this->getId()].push_back(filterIn); 1187 CWorkflowGraph::mapFilters[filterOut] = filter->GetName(); 1188 CWorkflowGraph::mapFilters[filterIn] = filters.second->GetName(); 1189 } 1173 1190 filter = filters.second; 1174 1191 } … … 1179 1196 // Check if we have a reference on another field 1180 1197 else if (!field_ref.isEmpty()) 1198 { 1199 CField::get(field_ref)->build_workflow_graph.setValue(buildWorkflowGraph); 1181 1200 instantDataFilter = getFieldReference(gc); 1201 } 1182 1202 // Check if the data is to be read from a file 1183 1203 else if (file && !file->mode.isEmpty() && file->mode == CFile::mode_attr::read) … … 1185 1205 checkTimeAttributes(); 1186 1206 instantDataFilter = serverSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, false, freq_offset, true, 1187 detectMissingValues, defaultValue ));1207 detectMissingValues, defaultValue, buildWorkflowGraph)); 1188 1208 } 1189 1209 else // The data might be passed from the model … … 1191 1211 if (check_if_active.isEmpty()) check_if_active = false; 1192 1212 instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, false, true, NoneDu, false, 1193 detectMissingValues, defaultValue));1213 detectMissingValues, defaultValue, buildWorkflowGraph)); 1194 1214 } 1195 1215 } … … 1209 1229 fileWriterFilter = std::shared_ptr<CFileWriterFilter>(new CFileWriterFilter(gc, this)); 1210 1230 getTemporalDataFilter(gc, file->output_freq)->connectOutput(fileWriterFilter, 0); 1231 if (buildWorkflowGraph) 1232 { 1233 int filterOut = getTemporalDataFilter(gc, file->output_freq)->getFilterId(); 1234 int filterIn = fileWriterFilter->getFilterId(); 1235 CWorkflowGraph::mapFieldToFilters[this->getId()].push_back(filterOut); 1236 CWorkflowGraph::mapFieldToFilters[this->getId()].push_back(filterIn); 1237 CWorkflowGraph::mapFilters[filterOut] = "Temporal filter"; 1238 CWorkflowGraph::mapFilters[filterIn] = fileWriterFilter->GetName(); 1239 } 1211 1240 } 1212 1241 } … … 1231 1260 CField* fieldRef = CField::get(field_ref); 1232 1261 fieldRef->buildFilterGraph(gc, false); 1262 bool buildWorkflowGraph = (!build_workflow_graph.isEmpty() && build_workflow_graph == true); 1233 1263 1234 1264 std::pair<std::shared_ptr<CFilter>, std::shared_ptr<CFilter> > filters; … … 1238 1268 bool hasMissingValue = (!detect_missing_value.isEmpty() && !default_value.isEmpty() && detect_missing_value == true); 1239 1269 double defaultValue = hasMissingValue ? default_value : (!default_value.isEmpty() ? default_value : 0.0); 1240 filters = CSpatialTransformFilter::buildFilterGraph(gc, fieldRef->grid, grid, hasMissingValue, defaultValue );1270 filters = CSpatialTransformFilter::buildFilterGraph(gc, fieldRef->grid, grid, hasMissingValue, defaultValue, buildWorkflowGraph); 1241 1271 } 1242 1272 else 1243 filters.first = filters.second = std::shared_ptr<CFilter>(new CPassThroughFilter(gc)); 1273 { 1274 filters.first = filters.second = std::shared_ptr<CFilter>(new CPassThroughFilter(gc, buildWorkflowGraph)); 1275 } 1244 1276 1245 1277 fieldRef->getInstantDataFilter()->connectOutput(filters.first, 0); 1246 1278 1279 if (buildWorkflowGraph) 1280 { 1281 int filterOut = fieldRef->instantDataFilter->getFilterId(); 1282 int filterIn = (std::static_pointer_cast<COutputPin>(filters.first))->getFilterId(); 1283 CWorkflowGraph::mapFieldToFilters[fieldRef->getId()].push_back(filterOut); 1284 CWorkflowGraph::mapFieldToFilters[fieldRef->getId()].push_back(filterIn); 1285 CWorkflowGraph::mapFilters[filterOut] = fieldRef->getInstantDataFilter()->GetName(); 1286 CWorkflowGraph::mapFilters[filterIn] = filters.first->GetName(); 1287 } 1247 1288 return filters.second; 1248 1289 } … … 1317 1358 { 1318 1359 std::map<CDuration, std::shared_ptr<COutputPin> >::iterator it = temporalDataFilters.find(outFreq); 1360 const bool buildWorkflowGraph = (!build_workflow_graph.isEmpty() && build_workflow_graph == true); 1319 1361 1320 1362 if (it == temporalDataFilters.end()) … … 1327 1369 1328 1370 const bool detectMissingValues = (!detect_missing_value.isEmpty() && detect_missing_value == true); 1329 std::shared_ptr<CTemporalFilter> temporalFilter(new CTemporalFilter(gc, operation, 1330 CContext::getCurrent()->getCalendar()->getInitDate(),1331 freq_op, freq_offset, outFreq, detectMissingValues));1371 std::shared_ptr<CTemporalFilter> temporalFilter(new CTemporalFilter(gc, operation, CContext::getCurrent()->getCalendar()->getInitDate(), 1372 freq_op, freq_offset, outFreq, 1373 detectMissingValues, buildWorkflowGraph)); 1332 1374 1333 1375 instantDataFilter->connectOutput(temporalFilter, 0); 1334 1376 1377 if (buildWorkflowGraph) 1378 { 1379 int filterOut = instantDataFilter->getFilterId(); 1380 int filterIn = (std::static_pointer_cast<COutputPin>(temporalFilter))->getFilterId(); 1381 CWorkflowGraph::mapFieldToFilters[this->getId()].push_back(filterOut); 1382 CWorkflowGraph::mapFieldToFilters[this->getId()].push_back(filterIn); 1383 CWorkflowGraph::mapFilters[filterOut] = getInstantDataFilter()->GetName(); 1384 CWorkflowGraph::mapFilters[filterIn] = temporalFilter->GetName(); 1385 } 1386 1335 1387 it = temporalDataFilters.insert(std::make_pair(outFreq, temporalFilter)).first; 1336 1388 } 1337 1338 1389 return it->second; 1339 1390 } … … 1367 1418 1368 1419 const bool detectMissingValues = (!detect_missing_value.isEmpty() && detect_missing_value == true); 1420 const bool buildWorkflowGraph = (!build_workflow_graph.isEmpty() && build_workflow_graph == true); 1369 1421 std::shared_ptr<CTemporalFilter> temporalFilter(new CTemporalFilter(gc, operation, 1370 CContext::getCurrent()->getCalendar()->getInitDate(), 1371 freq_op, freq_offset, outFreq, detectMissingValues)); 1422 CContext::getCurrent()->getCalendar()->getInitDate(), 1423 freq_op, freq_offset, outFreq, 1424 detectMissingValues, buildWorkflowGraph)); 1372 1425 1373 1426 selfReferenceFilter->connectOutput(temporalFilter, 0); 1427 if (buildWorkflowGraph) 1428 1429 { 1430 int filterOut = selfReferenceFilter->getFilterId(); 1431 int filterIn = (std::static_pointer_cast<COutputPin>(temporalFilter))->getFilterId(); 1432 CWorkflowGraph::mapFieldToFilters[this->getId()].push_back(filterOut); 1433 CWorkflowGraph::mapFieldToFilters[this->getId()].push_back(filterIn); 1434 CWorkflowGraph::mapFilters[filterOut] = selfReferenceFilter->GetName(); 1435 CWorkflowGraph::mapFilters[filterIn] = temporalFilter->GetName(); 1436 } 1437 1374 1438 return temporalFilter ; 1375 1439 } -
XIOS/dev/dev_olga/src/node/field.hpp
r1594 r1653 7 7 #include "functor.hpp" 8 8 #include "functor_type.hpp" 9 #include "filter.hpp" 9 10 #include "duration.hpp" 10 11 #include "date.hpp" … … 243 244 bool hasTimeCentered; 244 245 245 246 246 DECLARE_REF_FUNC(Field,field) 247 247 -
XIOS/dev/dev_olga/src/node/field_impl.hpp
r1201 r1653 17 17 template <int N> 18 18 void CField::setData(const CArray<double, N>& _data) 19 TRY 19 20 { 20 21 if (clientSourceFilter) … … 27 28 << "Impossible to receive data from the model for a field [ id = " << getId() << " ] with a reference or an arithmetic operation."); 28 29 } 30 CATCH_DUMP_ATTR 29 31 30 32 template <int N> 31 33 void CField::getData(CArray<double, N>& _data) const 34 TRY 32 35 { 33 36 if (storeFilter) … … 45 48 } 46 49 } 50 CATCH 47 51 } // namespace xios 48 52 -
XIOS/dev/dev_olga/src/node/grid.hpp
r1594 r1653 205 205 bool hasTransform(); 206 206 size_t getGlobalWrittenSize(void) ; 207 // void getLocalMask(CArray<bool,1>& localMask) ;208 // template<int N>209 // void getLocalMask(const CArray<bool,N>& gridMask, CArray<bool,1>& localMask) ;210 207 public: 211 208 CArray<int, 1> storeIndex_client; … … 377 374 template <int n> 378 375 void CGrid::inputField(const CArray<double,n>& field, CArray<double,1>& stored) const 376 TRY 379 377 { 380 378 //#ifdef __XIOS_DEBUG … … 388 386 this->storeField_arr(field.dataFirst(), stored); 389 387 } 388 CATCH 390 389 391 390 template <int n> … … 405 404 template <int n> 406 405 void CGrid::outputField(const CArray<double,1>& stored, CArray<double,n>& field) const 406 TRY 407 407 { 408 408 //#ifdef __XIOS_DEBUG … … 416 416 this->restoreField_arr(stored, field.dataFirst()); 417 417 } 418 CATCH 418 419 419 420 /*! … … 425 426 template <int N> 426 427 void CGrid::uncompressField(const CArray<double,N>& data, CArray<double,1>& outData) const 428 TRY 427 429 { 428 430 uncompressField_arr(data.dataFirst(), outData); 429 431 } 432 CATCH 430 433 431 434 template<int N> … … 435 438 const CArray<int,1>& axisDomainOrder, 436 439 bool createMask) 440 TRY 437 441 { 438 442 int idx = 0; … … 530 534 } 531 535 } 536 CATCH_DUMP_ATTR 532 537 533 538 template<int N> … … 535 540 const std::vector<int>& eachDimSize, 536 541 bool newValue) 542 TRY 537 543 { 538 544 if (N != eachDimSize.size()) … … 549 555 gridMask = newValue; 550 556 } 557 CATCH_DUMP_ATTR 551 558 552 559 … … 558 565 template<int N> 559 566 void CGrid::modifyGridMask(CArray<bool,N>& gridMask, const CArray<int,1>& indexToModify, bool valueToModify) 567 TRY 560 568 { 561 569 int num = indexToModify.numElements(); … … 565 573 } 566 574 } 575 CATCH_DUMP_ATTR 576 567 577 ///-------------------------------------------------------------- 568 578 569 579 570 /*!571 A grid can have multiple dimension, so can its mask in the form of multi-dimension array.572 It's not a good idea to store all multi-dimension arrays corresponding to each mask.573 One of the ways is to convert this array into 1-dimension one and every process is taken place on it.574 \param [in] multi-dimension array grid mask575 */576 //template<int N>577 //void CGrid::getLocalMask(const CArray<bool,N>& gridMask, CArray<bool,1>& localMask)578 //{579 // if (gridMask.isEmpty()) return ;580 // int dim = gridMask.dimensions();581 // std::vector<int> dimensionSizes(dim);582 // for (int i = 0; i < dim; ++i) dimensionSizes[i] = gridMask.extent(i);583 //584 // std::vector<int> idxLoop(dim,0);585 // int ssize = gridMask.numElements(), idx = 0;586 // localMask.resize(ssize);587 // while (idx < ssize)588 // {589 // for (int i = 0; i < dim-1; ++i)590 // {591 // if (idxLoop[i] == dimensionSizes[i])592 // {593 // idxLoop[i] = 0;594 // ++idxLoop[i+1];595 // }596 // }597 //598 // int maskIndex = idxLoop[0];599 // int mulDim = 1;600 // for (int k = 1; k < dim; ++k)601 // {602 // mulDim *= dimensionSizes[k-1];603 // maskIndex += idxLoop[k]*mulDim;604 // }605 // localMask(maskIndex) = *(gridMask.dataFirst()+maskIndex);606 //607 // ++idxLoop[0];608 // ++idx;609 // }610 //}611 580 612 581 // Declare/Define CGridGroup and CGridDefinition -
XIOS/dev/dev_olga/src/node/interpolate_domain.cpp
r1269 r1653 65 65 if (this->read_write_convention.isEmpty()) this->read_write_convention.setValue(read_write_convention_attr::fortran); 66 66 67 67 68 } 68 69 -
XIOS/dev/dev_olga/src/transformation/domain_algorithm_zoom.cpp
r1620 r1653 113 113 domainDest_->data_ni.setValue(niDest); 114 114 domainDest_->data_nj.setValue(njDest); 115 domainDest_->data_ibegin.setValue(0); // local position116 domainDest_->data_jbegin.setValue(0); // local position117 domainDest_->data_i_index.resize(niDest*njDest); // local position118 domainDest_->data_j_index.resize(niDest*njDest); // local position115 domainDest_->data_ibegin.setValue(0); 116 domainDest_->data_jbegin.setValue(0); 117 domainDest_->data_i_index.resize(niDest*njDest); 118 domainDest_->data_j_index.resize(niDest*njDest); 119 119 120 120 domainDest_->domainMask.resize(niDest*njDest); -
XIOS/dev/dev_olga/src/transformation/generic_algorithm_transformation.hpp
r1599 r1653 87 87 */ 88 88 void computeIndexSourceMapping(const std::vector<CArray<double,1>* >& dataAuxInputs = std::vector<CArray<double,1>* >()); 89 // void computeTransformationMappingNonDistributed(int elementPositionInGrid, CGrid* gridSrc, CGrid* gridDst,90 // vector<int>& localSrc, vector<int>& localDst, vector<double>& weight, vector<bool>& localMaskOnGridDest);91 89 void computeTransformationMappingNonDistributed(int elementPositionInGrid, CGrid* gridSrc, CGrid* gridDst, 92 90 vector<int>& localSrc, vector<int>& localDst, vector<double>& weight, int& nbLocalIndexOnGridDest); -
XIOS/dev/dev_olga/src/transformation/grid_transformation.cpp
r1612 r1653 413 413 int nbLocalIndexOnGridDest; 414 414 CTimer::get("computeTransformationMappingNonDistributed").resume(); 415 // algo->computeTransformationMappingNonDistributed(elementPosition, gridSource_, tmpGridDestination_,416 // localSrc, localDst, weight, localMaskOnGridDest_.back()) ;417 415 algo->computeTransformationMappingNonDistributed(elementPosition, gridSource_, tmpGridDestination_, 418 416 localSrc, localDst, weight, nbLocalIndexOnGridDest) ; -
XIOS/dev/dev_olga/src/transformation/grid_transformation_factory_impl.hpp
r1612 r1653 110 110 } 111 111 112 112 113 } 113 114 #endif // __XIOS_GRID_TRANSFORMATION_FACTORY_HPP__
Note: See TracChangeset
for help on using the changeset viewer.