Skip to content

WIP: In transit data adaptor

Burlen Loring requested to merge in_transit_data_adaptor into sensei_3_development

mr for collab on sensei 3 in transit api @srizzi @wolf.m7 @lot @jgu @ewbethel

Example 1, an analysis that wants the data to land a certain way

Screen_Shot_2018-12-11_at_11.27.03_AM The FFT needs data to land a certain way. In this case column based.

Screen_Shot_2018-12-11_at_12.07.00_PM In this case row based

ConfigurableEndPoint

int main(int argc, char **argv)
{
  string xml_config = argv[1];
  string stream_id = argv[2];

  // create instances of adaptors
  ConfigurableAnalysis *aa = nullptr;
  DataAdaptor *da = nullptr;
  InTransitAdaptorFactory::Initialize(xml_config, aa, da);
  
  // open the stream
  da->OpenStream(stream_id);
  
  // process time steps
  int ok = adaptors.size();
  while (da->StreamGood())
  {
    // run the analyses
    aa->Execute(adaptor.first);

    // move to the next time step
    da->AdvanceStream();
  }

  // close the stream
  da->CloseStream();

  return 0;
}

FFTAnalysis

class FFTAnalysis : public sensei::AnalysisAdaptor
{
  int Initialize(const pugi::xml_node &node);

  bool Execute(sensei::DataAdaptor *da);

  string MeshName;
  string ArrayName;
  int RowBased;
};

bool FFTAnalysis::Execute(sensei::DataAdaptor *da)
{
  // if we are in transit set the desired view
  if (sensei::InTransitDataAdaptor *itda = dynamic_cast<sensei::InTransitDataAdaptor*>(da))
  {
    sensei::MeshMetadataPtr remote_mmd;
    itda->GetSenderMeshMetadata(this->MeshName, remote_mmd);

    // set up the desired block to process mapping
    // for how the data lands
    sensei::MeshMetadataPtr local_mmd;
    this->ComputeBlockLayout(remote_mmd, local_mmd);

    // tell the data adaptor what we need
    itda->SetReceiverMeshMetadata(this->MeshName, local_mmd);
  }

  // from here on, in transit and in situ are identical
  vtkDataObject *mesh;
  da->GetMesh(this->MeshName, false, mesh);
  da->AddArray(this->MeshName, this->ArrayName, this->ArrayCen);
  
  // process data
  // ...

  return 0;
}

int FFTAnalysis::ComputeBlockLayout(sensei::MeshMetadataPtr remote, sensei::MeshMetadataPtr &local)
{
   // analyze the remote BlockOwner & BlockIds
   // set the local BlockOwner & BlockIds such that desired blocks land on desired ranks

   // in this example...
   // remote->BlockOwner is {0, 1, ..., 8}
   // remote->BlockIds is {0, 1, ... , 8}
   
   if (this->RowBased)
   {
     // in this example...
     // local->BlockOwner = {0, 0, 0, 1, 1, 1, 2, 2, 2};
     // local->BlockIds = {0, 3, 6, 1, 4, 7, 2, 5, 8};
   }
   else
   {
     // in this example...
     // local->BlockOwner = {0, 0, 0, 1, 1, 1, 2, 2, 2};
     // local->BlockIds = {0, 1, 2, 3, 4, 5, 6, 7, 8};
   }

  return 0;
}

Histogram

This histogram does not care how blocks are distributed, but the user may want to say how they do.

All sensei::InTransitDataAdaptors support XML attribute 'partitioner' and methods 'block', 'cyclic', 'plane', 'mapped'.

Here the user has specified "block" in the XML file passed into the ConfigurableEndPoint. Screen_Shot_2018-12-11_at_12.27.09_PM

Here the user has specified "cyclic" in the XML file Screen_Shot_2018-12-11_at_12.27.23_PM

InTransitDataAdaptor partitioner defaults


int InTransitDataAdaptor::GetCyclicPartition(sensei::MeshMetadataPtr &remote, sensei::MeshMetadataPtr &local)
{

   // implement the "cyclic" partitioner decomposition

   // in this example...
   // remote->BlockOwner is {0, 1, ..., 8}
   // remote->BlockIds is {0, 1, ... , 8}
   
   // in this example...
   // local->BlockOwner = {0, 1, 0, 1, 0, 1, 0, 1, 0};
   // local->BlockIds = {0, 1, ... , 8}
}

int InTransitDataAdaptor::GetBlockPartition(sensei::MeshMetadataPtr &remote, sensei::MeshMetadataPtr &local)
{

   // implement the "block" partitioner decomposition

   // in this example...
   // remote->BlockOwner is {0, 1, ..., 8}
   // remote->BlockIds is {0, 1, ... , 8}
   
   // in this example...
   // local->BlockOwner = {0, 0, 0, 0, 0, 1, 1, 1, 1};
   // local->BlockIds = {0, 1, ... , 8}
}

int InTransitDataAdaptor::GetPlanePartition(sensei::MeshMetadataPtr &remote, sensei::MeshMetadataPtr &local)
{
    // details omitted
}

int InTransitDataAdaptor::GetMappedPartition(sensei::MeshMetadataPtr &remote, sensei::MeshMetadataPtr &local)
{
    // user passes the block to process map via XML
}
Edited by Burlen Loring

Merge request reports