Ignore:
Timestamp:
06/04/21 11:54:38 (3 years ago)
Author:
yushan
Message:

Big commit on graph functionality. Add buildWorkflowGraph function for filters

Location:
XIOS/dev/dev_ym/XIOS_COUPLING/src/filter
Files:
23 edited

Legend:

Unmodified
Added
Removed
  • XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/client_from_client_source_filter.cpp

    r2022 r2143  
    66#include "grid.hpp" 
    77#include <limits>  
     8#include "workflow_graph.hpp" 
    89 
    910namespace xios 
     
    3940          
    4041    grid_->getClientFromClientConnector()->transfer(event,packet->data) ; 
     42 
     43    if(this->graphEnabled) 
     44    { 
     45      this->graphPackage->filterId = CWorkflowGraph::getNodeSize(); 
     46      CWorkflowGraph::addNode("Client to Client Source filter", 1, false, 0, packet); 
     47    } 
    4148    onOutputReady(packet); 
    4249  } 
  • XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/client_from_server_source_filter.cpp

    r1988 r2143  
    1010#include "tracer.hpp" 
    1111#include <limits>  
     12#include "workflow_graph.hpp" 
    1213 
    1314namespace xios 
     
    5657      info(20)<<"lastDateReceived_ "<<lastDateReceived_<< "  date "<<packet->date<<endl;                                                                                    // make a registration at initialization once 
    5758      packet->status = CDataPacket::NO_ERROR; 
     59    } 
     60 
     61    if(this->graphEnabled) 
     62    { 
     63      this->graphPackage->filterId = CWorkflowGraph::getNodeSize(); 
     64      CWorkflowGraph::addNode("Client from Server Source filter", 1, false, 0, packet); 
    5865    } 
    5966    onOutputReady(packet); 
  • XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/client_to_model_store_filter.cpp

    r1930 r2143  
    44#include "timer.hpp" 
    55#include "tracer.hpp" 
     6#include "workflow_graph.hpp" 
    67 
    78namespace xios 
     
    910  CClientToModelStoreFilter::CClientToModelStoreFilter(CGarbageCollector& gc, CField* field) 
    1011    : CInputPin(gc, 1) 
    11     , gc_(gc) 
     12    , gc_(gc), graphEnabled(false) 
    1213  { 
    1314    context_ = CContext::getCurrent() ; 
     
    107108    } 
    108109 
     110    if(this->graphEnabled) 
     111    { 
     112      this->graphPackage->filterId = CWorkflowGraph::getNodeSize(); 
     113      CWorkflowGraph::addNode("Client to Model Store filter", 5, true, 1, packet); 
     114    } 
     115 
     116 
    109117    packets_.insert(std::make_pair(packet->timestamp, packet)); 
    110118    // The packet is always destroyed by the garbage collector 
  • XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/client_to_model_store_filter.hpp

    r1930 r2143  
    33 
    44#include "input_pin.hpp" 
     5#include "graph_package.hpp" 
    56 
    67namespace xios 
     
    7374      void virtual invalidate(Time timestamp); 
    7475 
     76      CGraphPackage * graphPackage; 
     77      bool graphEnabled; 
     78 
    7579    protected: 
    7680      /*! 
  • XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/client_to_server_store_filter.cpp

    r2130 r2143  
    77#include "field.hpp" 
    88#include "grid.hpp" 
     9#include "workflow_graph.hpp" 
    910 
    1011namespace xios 
     
    1213  CClientToServerStoreFilter::CClientToServerStoreFilter(CGarbageCollector& gc, CField* field, CContextClient* client) 
    1314    : CInputPin(gc, 1) 
    14     , field_(field), client_(client) 
     15    , field_(field), client_(client), graphEnabled(false) 
    1516  { 
    1617    if (!field) 
     
    2122  void CClientToServerStoreFilter::onInputReady(std::vector<CDataPacketPtr> data) 
    2223  { 
     24    buildWorkflowGraph(data); 
     25 
    2326    CTimer::get("Field : send data").resume(); 
    2427    CEventClient event(field_->getType(), CField::EVENT_ID_UPDATE_DATA); 
     
    2730    field_->getSentGrid()->getClientToServerConnector(client_)->transfer(data[0]->data, client_, event, message) ; 
    2831    CTimer::get("Field : send data").suspend(); 
     32  } 
     33 
     34  void CClientToServerStoreFilter::buildWorkflowGraph(std::vector<CDataPacketPtr> data) 
     35  { 
     36    if(this->graphEnabled) 
     37    { 
     38      this->graphPackage->filterId = CWorkflowGraph::getNodeSize(); 
     39      if(!data[0]->graphPackage) data[0]->graphPackage = new CGraphDataPackage; 
     40       
     41      std::rotate(this->graphPackage->inFields.begin(), this->graphPackage->inFields.begin() + 1, this->graphPackage->inFields.end()); 
     42       
     43      CWorkflowGraph::addNode("Client to Server Store filter", 6, true, 1, data[0]); 
     44      
     45      CWorkflowGraph::addEdge(data[0]->graphPackage->fromFilter, this->graphPackage->filterId, data[0]); 
     46      // flux can be redirected to other filters. So don't change the 'from' parameter 
     47      data[0]->graphPackage->currentField = this->graphPackage->inFields[0]; 
     48    } 
    2949  } 
    3050   
  • XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/client_to_server_store_filter.hpp

    r2130 r2143  
    33 
    44#include "input_pin.hpp" 
     5#include "graph_package.hpp" 
    56 
    67namespace xios 
     
    3738       */ 
    3839      bool virtual mustAutoTrigger() const; 
     40       
     41      void buildWorkflowGraph(std::vector<CDataPacketPtr> data); 
    3942 
    4043      /*! 
     
    4447       */ 
    4548      bool virtual isDataExpected(const CDate& date) const; 
     49      CGraphPackage * graphPackage; 
     50      bool graphEnabled; 
    4651 
    4752    protected: 
  • XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/data_packet.hpp

    r1930 r2143  
    66#include "array_new.hpp" 
    77#include "date.hpp" 
     8#include "graph_package.hpp" 
    89 
    910namespace xios 
     
    2122      END_OF_STREAM //!< Last packet of the stream, does not have data 
    2223    }; 
     24 
     25    CGraphDataPackage * graphPackage; 
    2326 
    2427    CArray<double, 1> data; //!< Array containing the data 
     
    4043      p->timestamp = timestamp; 
    4144      p->status = status; 
     45      p->graphPackage = graphPackage; 
    4246      return p; 
    4347    }; 
     48 
     49 
     50    CDataPacket() : graphPackage(nullptr) {} 
     51 
    4452  }; // struct CDataPacket 
    4553 
  • XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/file_reader_source_filter.cpp

    r1962 r2143  
    77#include "file.hpp" 
    88#include "context.hpp" 
    9  
     9#include "workflow_graph.hpp" 
    1010 
    1111namespace xios 
     
    4545     
    4646    info(20)<<"Read data from file : FieldId "<<field_->getId()<<"  nStep "<<nStep_<<"  date : "<<packet->date<<endl ; 
     47   
     48    if(this->graphEnabled) 
     49    { 
     50      this->graphPackage->filterId = CWorkflowGraph::getNodeSize(); 
     51      CWorkflowGraph::addNode("File Reader Source filter", 1, false, 0, packet); 
     52    } 
    4753            
    4854    onOutputReady(packet); 
  • XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/file_writer_store_filter.cpp

    r1962 r2143  
    44#include "file.hpp" 
    55#include "context.hpp" 
     6#include "workflow_graph.hpp" 
    67 
    78namespace xios 
     
    910  CFileWriterStoreFilter::CFileWriterStoreFilter(CGarbageCollector& gc, CField* field) 
    1011    : CInputPin(gc, 1) 
    11     , field_(field) 
     12    , field_(field), graphEnabled(false) 
    1213 
    1314  { 
     
    6768      }   
    6869      nstep_ = file_->getDataOutput()->writeFieldData(field_, fieldData, lastWrite_,currentWrite, nstep_); 
     70      if(this->graphEnabled) 
     71      { 
     72         
     73        this->graphPackage->filterId = CWorkflowGraph::getNodeSize(); 
     74        if(!data[0]->graphPackage) data[0]->graphPackage = new CGraphDataPackage; 
     75        data[0]->graphPackage->currentField = this->graphPackage->inFields[0]; 
     76        std::rotate(this->graphPackage->inFields.begin(), this->graphPackage->inFields.begin() + 1, this->graphPackage->inFields.end()); 
     77       
     78        CWorkflowGraph::addNode("File Writer Store filter", 5, true, 1, data[0]); 
     79       
     80        CWorkflowGraph::addEdge(data[0]->graphPackage->fromFilter, this->graphPackage->filterId, data[0]); 
     81        data[0]->graphPackage->fromFilter = this->graphPackage->filterId; 
     82 
     83 
     84      } 
    6985    } 
    7086 
  • XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/file_writer_store_filter.hpp

    r1961 r2143  
    33 
    44#include "input_pin.hpp" 
     5#include "graph_package.hpp" 
    56 
    67namespace xios 
     
    3940      bool virtual isDataExpected(const CDate& date) const; 
    4041 
     42      CGraphPackage *graphPackage; 
     43      bool graphEnabled; 
     44 
    4145    protected: 
    4246      /*! 
  • XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/model_to_client_source_filter.cpp

    r1930 r2143  
    44#include "calendar_util.hpp" 
    55#include <limits>  
     6#include "workflow_graph.hpp" 
    67 
    78namespace xios 
     
    4546    } 
    4647     
     48    buildWorkflowGraph(packet); 
    4749    onOutputReady(packet); 
    4850  } 
     51   
     52  void CModelToClientSourceFilter::buildWorkflowGraph(CDataPacketPtr packet) 
     53  { 
     54    if(this->graphEnabled) 
     55    { 
     56      this->graphPackage->filterId = CWorkflowGraph::getNodeSize(); 
     57      if(!packet->graphPackage) 
     58      { 
     59        packet->graphPackage = new CGraphDataPackage; 
     60      } 
     61      packet->graphPackage->fromFilter = this->graphPackage->filterId; 
     62      packet->graphPackage->currentField = this->graphPackage->inFields[0]; 
     63      CWorkflowGraph::addNode("Model to Client Source filter", 1, false, 0, packet); 
     64    } 
     65  } 
     66 
     67 
     68 
    4969 
    5070  template void CModelToClientSourceFilter::streamData<1>(CDate date, const CArray<double, 1>& data); 
  • XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/model_to_client_source_filter.hpp

    r1930 r2143  
    3737      void streamData(CDate date, const CArray<double, N>& data); 
    3838 
     39      void buildWorkflowGraph(CDataPacketPtr packet); 
     40 
     41 
    3942      /*! 
    4043       * Transforms the data received from the server into a packet and send it 
  • XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/output_pin.cpp

    r1542 r2143  
    66  COutputPin::COutputPin(CGarbageCollector& gc, bool manualTrigger /*= false*/) 
    77    : gc(gc) 
    8     , manualTrigger(manualTrigger) 
     8    , manualTrigger(manualTrigger), graphEnabled(false) 
    99  { /* Nothing to do */ } 
    1010 
  • XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/output_pin.hpp

    r1542 r2143  
    44#include "garbage_collector.hpp" 
    55#include "input_pin.hpp" 
     6#include "graph_package.hpp" 
    67 
    78namespace xios 
     
    6566       */ 
    6667      void virtual invalidate(Time timestamp); 
     68      CGraphPackage *graphPackage; 
     69      bool graphEnabled; 
    6770 
    6871    protected: 
  • XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/pass_through_filter.cpp

    r641 r2143  
    11#include "pass_through_filter.hpp" 
     2#include "workflow_graph.hpp" 
     3#include <algorithm> 
    24 
    35namespace xios 
     
    911  CDataPacketPtr CPassThroughFilter::apply(std::vector<CDataPacketPtr> data) 
    1012  { 
     13    buildWorkflowGraph(data); 
    1114    return data[0]; 
    1215  } 
     16 
     17  void CPassThroughFilter::buildWorkflowGraph(std::vector<CDataPacketPtr> data) 
     18  { 
     19    if(this->graphEnabled) 
     20    { 
     21      if(data[0]->graphPackage && data[0]->graphPackage->currentField->getId() == this->graphPackage->inFields[0]->getId()) 
     22      { 
     23        std::cout<<"PASS THROUGH FILTER OMITTED "<<this<<std::endl; 
     24        return; 
     25      } 
     26      this->graphPackage->filterId = CWorkflowGraph::getNodeSize(); 
     27       
     28      if(!data[0]->graphPackage)  
     29      { 
     30        data[0]->graphPackage = new CGraphDataPackage; 
     31        data[0]->graphPackage->fromFilter = -1; 
     32        data[0]->graphPackage->currentField = this->graphPackage->inFields[0]; 
     33      } 
     34 
     35      for(int i=0; i<this->graphPackage->filterId; i++) 
     36      { 
     37        if(CXios::isClient  
     38          &&  (*CWorkflowGraph::vectorOfNodes_)[i].label_field_id == this->label_field_id   
     39          && (*CWorkflowGraph::vectorOfNodes_)[i].timestamp == data[0]->timestamp 
     40          && (*CWorkflowGraph::vectorOfNodes_)[i].filter_name == "Pass through filter" ) 
     41        { 
     42          data[0]->graphPackage->fromFilter = i; 
     43          return; 
     44        }   
     45      } 
     46       
     47      CWorkflowGraph::addNode("Pass through filter", 2, false, 1, data[0]); 
     48      if(CXios::isClient) (*CWorkflowGraph::vectorOfNodes_)[this->graphPackage->filterId].label_field_id = this->label_field_id; 
     49      CWorkflowGraph::addEdge(data[0]->graphPackage->fromFilter, this->graphPackage->filterId, data[0]); 
     50       
     51      data[0]->graphPackage->currentField = this->graphPackage->inFields[0]; 
     52      std::rotate(this->graphPackage->inFields.begin(), this->graphPackage->inFields.begin() + 1, this->graphPackage->inFields.end()); 
     53       
     54      data[0]->graphPackage->fromFilter = this->graphPackage->filterId; 
     55         
     56    }  
     57  } 
     58 
     59 
    1360} // namespace xios 
  • XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/pass_through_filter.hpp

    r641 r2143  
    2020      CPassThroughFilter(CGarbageCollector& gc); 
    2121 
     22      StdString label_field_id; //used for omitting redundant pass through filter in graph 
     23 
    2224    protected: 
    2325      /*! 
     
    2830       */ 
    2931      CDataPacketPtr virtual apply(std::vector<CDataPacketPtr> data); 
     32      void buildWorkflowGraph(std::vector<CDataPacketPtr> data); 
     33   
    3034  }; // class CPassThroughFilter 
    3135} // namespace xios 
  • XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/server_from_client_source_filter.cpp

    r1930 r2143  
    44#include "calendar_util.hpp" 
    55#include "context.hpp" 
    6  
     6#include "workflow_graph.hpp" 
    77 
    88namespace xios 
     
    2727    grid_->getServerFromClientConnector()->transfer(event,packet->data) ; 
    2828 
     29    if(this->graphEnabled) 
     30    { 
     31      this->graphPackage->filterId = CWorkflowGraph::getNodeSize(); 
     32      packet->graphPackage = new CGraphDataPackage; 
     33      packet->graphPackage->fromFilter = this->graphPackage->filterId; 
     34      packet->graphPackage->currentField = this->graphPackage->inFields[0]; 
     35      CWorkflowGraph::addNode("Server from Client Source filter", 1, false, 0, packet); 
     36    } 
    2937    onOutputReady(packet); 
    3038  } 
  • XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/server_to_client_store_filter.cpp

    r2130 r2143  
    55#include "utils.hpp" 
    66#include "context_client.hpp" 
     7#include "workflow_graph.hpp" 
    78 
    89namespace xios 
     
    1011  CServerToClientStoreFilter::CServerToClientStoreFilter(CGarbageCollector& gc, CField* field, CContextClient* client) 
    1112    : CInputPin(gc, 1) 
    12     , field_(field), client_(client) 
     13    , field_(field), client_(client), graphEnabled(false) 
    1314  { 
    1415    if (!field) ERROR("CServerToClientFilter::CServerToClientFilter(CField* field)", "The field cannot be null."); 
     
    2728    CMessage msg ; 
    2829    msg<<field_->getId() ; 
     30 
     31    if(this->graphEnabled) 
     32    { 
     33      CWorkflowGraph::addNode("Server to Client Store filter", 5, true, 1, packets[0]); 
     34    } 
    2935 
    3036    if (isEOF)  
  • XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/server_to_client_store_filter.hpp

    r2130 r2143  
    33 
    44#include "input_pin.hpp" 
     5#include "graph_package.hpp" 
    56 
    67namespace xios 
     
    4647       */ 
    4748      bool virtual isDataExpected(const CDate& date) const; 
     49      CGraphPackage * graphPackage; 
     50      bool graphEnabled; 
    4851 
    4952    protected: 
  • XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/temporal_filter.cpp

    r1523 r2143  
    22#include "functor_type.hpp" 
    33#include "calendar_util.hpp" 
     4#include "workflow_graph.hpp" 
    45 
    56namespace xios 
     
    2829//    , nextOperationDate(initDate + opFreq + this->samplingOffset) 
    2930    , isFirstOperation(true) 
     31    , graphCycleCompleted(true) 
    3032  { 
    3133  } 
    3234 
     35  void CTemporalFilter::buildWorkflowGraph(std::vector<CDataPacketPtr> data) 
     36  { 
     37    if(this->graphEnabled ) 
     38    { 
     39      if(!data[0]->graphPackage) 
     40      { 
     41        data[0]->graphPackage = new CGraphDataPackage; 
     42      } 
     43       
     44      if(graphCycleCompleted) 
     45      {   
     46        this->graphPackage->filterId = CWorkflowGraph::getNodeSize(); 
     47        CWorkflowGraph::addNode("Temporal filter", 3, false, 0, data[0]); 
     48        graphCycleCompleted = false; 
     49      } 
     50       
     51      data[0]->graphPackage->currentField = this->graphPackage->inFields[0]; 
     52      std::rotate(this->graphPackage->inFields.begin(), this->graphPackage->inFields.begin() + 1, this->graphPackage->inFields.end()); 
     53       
     54      CWorkflowGraph::addEdge(data[0]->graphPackage->fromFilter, this->graphPackage->filterId, data[0]); 
     55      data[0]->graphPackage->fromFilter = this->graphPackage->filterId; 
     56      this->graphPackage->sourceFilterIds.push_back(data[0]->graphPackage->fromFilter);  
     57      data[0]->graphPackage->currentField = this->graphPackage->inFields[0]; 
     58      std::rotate(this->graphPackage->inFields.begin(), this->graphPackage->inFields.begin() + 1, this->graphPackage->inFields.end()); 
     59    } 
     60 
     61  } 
    3362  CDataPacketPtr CTemporalFilter::apply(std::vector<CDataPacketPtr> data) 
    3463  { 
     64    buildWorkflowGraph(data); 
     65   
    3566    CDataPacketPtr packet; 
    3667 
     
    4374      { 
    4475        usePacket = (data[0]->date >= nextSamplingDate); 
    45 //        outputResult = (data[0]->date + samplingFreq > nextOperationDate); 
    4676        outputResult = (data[0]->date  > initDate + nbOperationDates*opFreq - samplingFreq + offsetMonth + offsetAllButMonth); 
    4777        copyLess = (isInstantOperation && usePacket && outputResult); 
     
    75105          packet->data.resize(tmpData.numElements()); 
    76106          packet->data = tmpData; 
     107          packet->graphPackage = data[0]->graphPackage; 
    77108        } 
    78109        else 
     
    80111 
    81112        isFirstOperation = false; 
    82 //        nextOperationDate = initDate + samplingFreq + nbOperationDates*opFreq - samplingFreq + offsetMonth + offsetAllButMonth; 
    83       } 
     113        graphCycleCompleted = true; 
     114     } 
    84115    } 
    85116 
  • XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/temporal_filter.hpp

    r1473 r2143  
    3939      CDataPacketPtr virtual apply(std::vector<CDataPacketPtr> data); 
    4040 
     41      void buildWorkflowGraph(std::vector<CDataPacketPtr> data); 
     42 
    4143      /*! 
    4244       * Tests if the filter must auto-trigger. 
     
    5254       */ 
    5355      bool virtual isDataExpected(const CDate& date) const; 
     56      bool graphCycleCompleted; 
    5457 
    5558    private: 
  • XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/transform_filter.cpp

    r2011 r2143  
    11#include "transform_filter.hpp" 
    22#include "grid_algorithm.hpp" 
    3  
     3#include "workflow_graph.hpp" 
    44namespace xios 
    55{ 
     
    2222    if (packet->status == CDataPacket::NO_ERROR)  
    2323    { 
     24      buildWorkflowGraph(data, packet, algorithm_); 
     25       
    2426      if (data.size()>1) 
    2527      { 
     
    3335  } 
    3436 
    35  
     37  void CTransformFilter::buildWorkflowGraph(std::vector<CDataPacketPtr> data, CDataPacketPtr packet, CGridAlgorithm* algorithm) 
     38  { 
     39    if(this->graphEnabled) 
     40    { 
     41      this->graphPackage->filterId = CWorkflowGraph::getNodeSize(); 
     42     
     43      packet->graphPackage = new CGraphDataPackage; 
     44      if(data[0]->graphPackage) 
     45      { 
     46        packet->graphPackage->fromFilter = data[0]->graphPackage->fromFilter; 
     47      } 
     48      packet->graphPackage->toFilter = data[0]->graphPackage->toFilter; 
     49      packet->graphPackage->current_filter_name = data[0]->graphPackage->current_filter_name; 
     50      packet->graphPackage->contextId = data[0]->graphPackage->contextId;           
     51     
     52      int tmp_from = packet->graphPackage->fromFilter; 
     53      if(this->graphPackage->show) 
     54      { 
     55        packet->graphPackage->currentField = this->graphPackage->inFields[0]; 
     56        CWorkflowGraph::addNode("Spatial transform filter "+algorithm->getAlgoName(), 4, false, 1, packet); 
     57        CWorkflowGraph::addEdge(packet->graphPackage->fromFilter, this->graphPackage->filterId, packet); 
     58        packet->graphPackage->fromFilter = this->graphPackage->filterId; 
     59        packet->graphPackage->currentField = this->graphPackage->inFields[0]; 
     60        std::rotate(this->graphPackage->inFields.begin(), this->graphPackage->inFields.begin() + 1, this->graphPackage->inFields.end()); 
     61      } 
     62      else 
     63      { 
     64        packet->graphPackage->currentField = this->graphPackage->inFields[0]; 
     65        if(CXios::isClient) CWorkflowGraph::vectorOfNodes_->at(tmp_from).filter_name += algorithm->getAlgoName(); 
     66        else                CWorkflowGraph::vectorOfNodes_srv_->at(tmp_from).filter_name += algorithm->getAlgoName(); 
     67         
     68      }      
     69    } 
     70  } 
    3671 
    3772} 
  • XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/transform_filter.hpp

    r2011 r2143  
    2222      */ 
    2323      CDataPacketPtr virtual apply(std::vector<CDataPacketPtr> data) ; 
     24      void buildWorkflowGraph(std::vector<CDataPacketPtr> data, CDataPacketPtr packet, CGridAlgorithm* algorithm); 
     25       
    2426//      void apply(const CArray<double, 1>& dataSrc, CArray<double,1>& dataDest); 
    2527      
Note: See TracChangeset for help on using the changeset viewer.