ADIOSReader.cxx 6.75 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    ADIOSReader.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/

16
#include <adios_read.h>
17 18 19

#include "ADIOSReader.h"

20 21
namespace ADIOS
{
22 23

//----------------------------------------------------------------------------
24
struct Reader::InitContext
25 26
{
  static int RefCount;
27 28 29 30 31 32 33
  static MPI_Comm GlobalComm;
  static ADIOS_READ_METHOD Method;
  static std::string MethodArgs;

  MPI_Comm Comm;
  int Rank;
  int CommSize;
34

35 36
  InitContext()
  : Comm(GlobalComm)
37 38 39
  {
    if(this->RefCount == 0)
      {
40 41 42 43 44 45
      int init = 0;
      MPI_Initialized(&init);
      ReadError::TestEq(1, init, "InitContext: MPI is not yet initialized");

      int err = adios_read_init_method(Method, this->Comm, MethodArgs.c_str());
      ReadError::TestEq(0, err);
46 47
      }
    ++this->RefCount;
48 49 50

    MPI_Comm_size(this->Comm, &this->CommSize);
    MPI_Comm_rank(this->Comm, &this->Rank);
51 52
  }

53
  ~InitContext()
54 55 56 57
  {
    --this->RefCount;
    if(this->RefCount == 0)
      {
58 59 60 61
      // If we've gotten this far then we know that MPI has been initialized
      //already
      MPI_Barrier(this->Comm);
      adios_read_finalize_method(Method);
62 63 64 65
      }
  }
};

66 67 68 69 70 71
// Default communicator is invalid
//MPI_Comm Reader::InitContext::GlobalComm = MPI_COMM_NULL;
MPI_Comm Reader::InitContext::GlobalComm = MPI_COMM_WORLD;
ADIOS_READ_METHOD Reader::InitContext::Method = ADIOS_READ_METHOD_BP;
std::string Reader::InitContext::MethodArgs = "";
int Reader::InitContext::RefCount = 0;
72 73

//----------------------------------------------------------------------------
74
struct Reader::ReaderImpl
75
{
76 77
  ReaderImpl()
  : File(NULL), StepBegin(0), StepEnd(0)
78 79
  { }

80
  ~ReaderImpl()
81
  {
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
    for(std::vector<const Attribute*>::iterator a = this->Attributes.begin();
        a != this->Attributes.end();
        ++a)
      {
      delete *a;
      }
    for(std::vector<const Scalar*>::iterator s = this->Scalars.begin();
        s != this->Scalars.end();
        ++s)
      {
      delete *s;
      }
    for(std::vector<const VarInfo*>::iterator v = this->Arrays.begin();
        v != this->Arrays.end();
        ++v)
97
      {
98
      delete *v;
99 100 101
      }
  }

102 103 104 105 106 107
  ADIOS_FILE *File;
  size_t StepBegin;
  size_t StepEnd;
  std::vector<const Attribute*> Attributes;
  std::vector<const Scalar*> Scalars;
  std::vector<const VarInfo*> Arrays;
108 109
};

110 111
//-------------------:---------------------------------------------------------
bool Reader::SetCommunicator(MPI_Comm comm)
112
{
113 114
  // The communicator can only be set if ADIOS has not yet been initialized
  if(Reader::InitContext::RefCount == 0)
115
    {
116 117
    Reader::InitContext::GlobalComm = comm;
    return true;
118
    }
119
  return false;
120 121
}

122 123
//-------------------:---------------------------------------------------------
bool Reader::SetReadMethod(ReadMethod method, const std::string& methodArgs)
124
{
125 126
  // The communicator can only be set if ADIOS has not yet been initialized
  if(Reader::InitContext::RefCount == 0)
127
    {
128 129 130
    Reader::InitContext::Method = static_cast<ADIOS_READ_METHOD>(method);
    Reader::InitContext::MethodArgs = methodArgs;
    return true;
131
    }
132
  return false;
133 134 135
}

//----------------------------------------------------------------------------
136 137
Reader::Reader()
: Ctx(new InitContext), Impl(new ReaderImpl)
138 139 140 141
{
}

//----------------------------------------------------------------------------
142
Reader::~Reader()
143
{
144 145
  this->Close();

146 147 148
  delete this->Impl;
  delete this->Ctx;
}
149

150 151 152 153
//----------------------------------------------------------------------------
bool Reader::IsOpen() const
{
  return this->Impl->File != NULL;
154 155 156
}

//----------------------------------------------------------------------------
157
const std::vector<const Attribute*>& Reader::GetAttributes() const
158
{
159
  return this->Impl->Attributes;
160 161 162
}

//----------------------------------------------------------------------------
163
const std::vector<const Scalar*>& Reader::GetScalars() const
164
{
165
  return this->Impl->Scalars;
166 167 168
}

//----------------------------------------------------------------------------
169
const std::vector<const VarInfo*>& Reader::GetArrays() const
170
{
171 172
  return this->Impl->Arrays;
}
173

174 175 176 177 178
//----------------------------------------------------------------------------
void Reader::Open(const std::string &fileName)
{
  ReadError::TestEq<ADIOS_FILE*>(NULL, this->Impl->File,
    "Open: An existing file is already open");
179 180 181

  // Open the file
  this->Impl->File = adios_read_open_file(fileName.c_str(),
182 183
    this->Ctx->Method, this->Ctx->Comm);
  ReadError::TestNe<ADIOS_FILE*>(NULL, this->Impl->File);
184 185

  // Poplulate step information
186 187
  this->Impl->StepBegin = this->Impl->File->current_step;
  this->Impl->StepEnd = this->Impl->File->last_step;
188

189 190
  // Polulate attributes
  for(int i = 0; i < this->Impl->File->nattrs; ++i)
191
    {
192
    this->Impl->Attributes.push_back(new Attribute(this->Impl->File, i));
193 194 195 196 197 198
    }

  // Preload the scalar data and cache the array metadata
  for(int i = 0; i < this->Impl->File->nvars; ++i)
    {
      ADIOS_VARINFO *v = adios_inq_var_byid(this->Impl->File, i);
199
      ReadError::TestNe<ADIOS_VARINFO*>(NULL, v);
200 201 202

      if(v->ndim == 0)
        {
203
        this->Impl->Scalars.push_back(new Scalar(this->Impl->File, v));
204 205 206
        }
      else
        {
207
        this->Impl->Arrays.push_back(new VarInfo(this->Impl->File, v));
208
        }
209
      adios_free_varinfo(v);
210 211 212
    }
}

213 214 215 216 217 218 219 220 221 222
//----------------------------------------------------------------------------
void Reader::Close()
{
  if(this->Impl->File)
    {
    adios_read_close(this->Impl->File);
    this->Impl->File = NULL;
    }
}

223
//----------------------------------------------------------------------------
224
void Reader::GetStepRange(int &tStart, int &tEnd) const
225
{
226 227
  ReadError::TestNe<ADIOS_FILE*>(NULL, this->Impl->File,
    "GetStepRange: File not open");
228

229 230
  tStart = this->Impl->StepBegin;
  tEnd = this->Impl->StepEnd;
231 232 233
}

//----------------------------------------------------------------------------
234
void Reader::ScheduleReadArray(int id, void *data, int step, int block)
235
{
236 237
  ADIOS_SELECTION *sel = adios_selection_writeblock(block);
  ReadError::TestNe<ADIOS_SELECTION*>(NULL, sel);
238

239
  int err = adios_schedule_read_byid(this->Impl->File, sel, id,
240
    step, 1, data);
241
  ReadError::TestEq(0, err);
242 243

  adios_selection_delete(sel);
244 245 246
}

//----------------------------------------------------------------------------
247
void Reader::ReadArrays(void)
248
{
249 250
  int err = adios_perform_reads(this->Impl->File, 1);
  ReadError::TestEq(0, err);
251
}
252 253

} // End namespace ADIOS