SampleWriter.C 4.81 KB
Newer Older
1 2
////////////////////////////////////////////////////////////////////////////////
//
Francois Gygi committed
3 4 5 6
// Copyright (c) 2008 The Regents of the University of California
//
// This file is part of Qbox
//
Francois Gygi committed
7 8
// Qbox is distributed under the terms of the GNU General Public License
// as published by the Free Software Foundation, either version 2 of
Francois Gygi committed
9 10 11 12 13 14
// the License, or (at your option) any later version.
// See the file COPYING in the root directory of this distribution
// or <http://www.gnu.org/licenses/>.
//
////////////////////////////////////////////////////////////////////////////////
//
15 16 17
// SampleWriter.C:
//
////////////////////////////////////////////////////////////////////////////////
Francois Gygi committed
18
// $Id: SampleWriter.C,v 1.9 2008-09-08 15:56:19 fgygi Exp $
19 20 21 22 23 24


#include "SampleWriter.h"
#include "Sample.h"
#include "fstream"
#include "qbox_xmlns.h"
25
#include "Timer.h"
26
#include "SharedFilePtr.h"
27
#include <sstream>
28 29
#include <iomanip>

30 31 32 33 34 35 36 37
using namespace std;

////////////////////////////////////////////////////////////////////////////////
SampleWriter::SampleWriter(const Context& ctxt) : ctxt_(ctxt) {}

////////////////////////////////////////////////////////////////////////////////
void SampleWriter::writeSample(const Sample& s, const string filename,
                              string description,
38
                              bool base64, bool atomsonly, bool serial)
39
{
40 41
  Timer tm;
  tm.start();
42 43 44
  // set default encoding
  string encoding =  base64 ? "base64" : "text";
  const char* filename_cstr = filename.c_str();
45

46
  long long file_size;
47

48
  if ( serial )
49
  {
50 51 52 53
    ofstream os;
    if ( ctxt_.onpe0() )
    {
      os.open(filename_cstr);
54 55
      cout << "  SaveCmd: saving to file " << filename
           << ", encoding=" << encoding << endl;
56

57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
      os <<"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
         <<"<fpmd:sample xmlns:fpmd=\""
         << qbox_xmlns()
         << "\"\n"
         <<" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
         <<" xsi:schemaLocation=\""
         << qbox_xmlns() << " sample.xsd\">"
         << endl;

      os << "<description> " << description
         << " </description>" << endl;
      os << s.atoms;
    }

    if ( !atomsonly )
    {
      s.wf.print(os,encoding,"wavefunction");
      if ( s.wfv != 0 )
        s.wfv->print(os,encoding,"wavefunction_velocity");
    }

    if ( ctxt_.onpe0() )
      os << "</fpmd:sample>" << endl;

    os.close();
82
  }
83
  else
84
  {
85 86 87 88
    MPI_File fh;
    MPI_Info info;
    MPI_Info_create(&info);
    MPI_Offset fsize;
89
    SharedFilePtr sfp(ctxt_.comm(),fh);
90

91 92 93 94 95
    int err;
    err = MPI_File_open(ctxt_.comm(),(char*) filename_cstr,
                        MPI_MODE_WRONLY|MPI_MODE_CREATE,info,&fh);
    if ( err != 0 )
      cout << s.ctxt_.mype() << ": error in MPI_File_open: " << err << endl;
96

97
    MPI_File_set_size(fh,0);
98
    ctxt_.barrier();
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121

    MPI_Status status;
    if ( ctxt_.onpe0() )
    {
      string header("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
      "<fpmd:sample xmlns:fpmd=\"");
      header += qbox_xmlns();
      header += string("\"\n");
      header += string(
      " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n");
      header += string(" xsi:schemaLocation=\"");
      header += qbox_xmlns();
      header += string(" sample.xsd\">\n");

      string desc = string("<description> ") +
        description +
        string(" </description>\n");

      header += desc;

      ostringstream ss("");
      ss << s.atoms;
      header += ss.str();
122
      int len = header.size();
123 124
      err = MPI_File_write_at(sfp.file(),sfp.mpi_offset(),(void*)header.c_str(),
            len,MPI_CHAR,&status);
125
      if ( err != 0 )
126
        cout << ctxt_.mype() << ": error in MPI_File_write: header "
127
             << err << endl;
128
      sfp.advance(len);
129
    }
130
    sfp.sync();
131 132 133

    if ( !atomsonly )
    {
134
      s.wf.write(sfp,encoding,"wavefunction");
135
      if ( s.wfv != 0 )
136
        s.wfv->write(sfp,encoding,"wavefunction_velocity");
137 138
    }

139
    sfp.sync();
140

141 142 143 144
    if ( ctxt_.onpe0() )
    {
      char *trailer = "</fpmd:sample>\n";
      int len = strlen(trailer);
145 146
      err = MPI_File_write_at(sfp.file(),sfp.mpi_offset(),(void*)trailer,
              len,MPI_CHAR,&status);
147
      if ( err != 0 )
148
        cout << ctxt_.mype() << ": error in MPI_File_write: trailer "
149
             << err << endl;
150
      sfp.advance(len);
151
    }
152

153
    sfp.sync();
154

155
    file_size = sfp.offset();
156 157 158 159 160

    err = MPI_File_close(&fh);
    if ( err != 0 )
      cout << ctxt_.mype() << ": error in MPI_File_close: " << err << endl;
  }
161

162 163
  tm.stop();
  if ( ctxt_.onpe0() )
164
  {
165 166
    cout << " SampleWriter: write time: "
         << setprecision(3) << tm.real() << " s"
167
         << endl;
168 169
    if ( !serial )
    {
170
      cout << " SampleWriter: file size: " << file_size << endl;
171
      cout << " SampleWriter: aggregate write rate: "
172 173 174 175
           << setprecision(2) << file_size/(tm.real()*1024*1024)
           << " MB/s" << endl;
    }
  }
176
}