//////////////////////////////////////////////////////////////////////////////// // // Copyright (c) 2008 The Regents of the University of California // // This file is part of Qbox // // Qbox is distributed under the terms of the GNU General Public License // as published by the Free Software Foundation, either version 2 of // the License, or (at your option) any later version. // See the file COPYING in the root directory of this distribution // or . // //////////////////////////////////////////////////////////////////////////////// // // SampleWriter.C: // //////////////////////////////////////////////////////////////////////////////// #include "SampleWriter.h" #include "Sample.h" #include "fstream" #include "qbox_xmlns.h" #include "Timer.h" #include "SharedFilePtr.h" #include #include #include #include using namespace std; //////////////////////////////////////////////////////////////////////////////// SampleWriter::SampleWriter(const Context& ctxt) : ctxt_(ctxt) {} //////////////////////////////////////////////////////////////////////////////// void SampleWriter::writeSample(const Sample& s, const string filename, string description, bool base64, bool atomsonly, bool serial, bool save_wfv) { Timer tm; tm.start(); // set default encoding string encoding = base64 ? "base64" : "text"; const char* filename_cstr = filename.c_str(); long long file_size; if ( serial ) { ofstream os; if ( ctxt_.onpe0() ) { os.open(filename_cstr); cout << " SaveCmd: saving to file " << filename << ", encoding=" << encoding << endl; os <<"\n" <<"" << endl; os << " " << description << " " << endl; os << s.atoms; } if ( !atomsonly ) { s.wf.print(os,encoding,"wavefunction"); if ( save_wfv && s.wfv != 0 ) s.wfv->print(os,encoding,"wavefunction_velocity"); } if ( ctxt_.onpe0() ) os << "" << endl; os.close(); } else { #if USE_MPI MPI_File fh; MPI_Info info; MPI_Info_create(&info); 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; MPI_File_set_size(fh,0); ctxt_.barrier(); MPI_Status status; #else ofstream fh(filename_cstr); #endif SharedFilePtr sfp(ctxt_.comm(),fh); if ( ctxt_.onpe0() ) { string header("\n" "\n"); string desc = string(" ") + description + string(" \n"); header += desc; ostringstream ss(""); ss << s.atoms; header += ss.str(); int len = header.size(); #if USE_MPI err = MPI_File_write_at(sfp.file(),sfp.mpi_offset(),(void*)header.c_str(), len,MPI_CHAR,&status); if ( err != 0 ) cout << ctxt_.mype() << ": error in MPI_File_write: header " << err << endl; sfp.advance(len); #else fh.write(header.c_str(),len); #endif } sfp.sync(); if ( !atomsonly ) { s.wf.write(sfp,encoding,"wavefunction"); if ( save_wfv && s.wfv != 0 ) s.wfv->write(sfp,encoding,"wavefunction_velocity"); } sfp.sync(); if ( ctxt_.onpe0() ) { const char *trailer = "\n"; int len = strlen(trailer); #if USE_MPI err = MPI_File_write_at(sfp.file(),sfp.mpi_offset(),(void*)trailer, len,MPI_CHAR,&status); if ( err != 0 ) cout << ctxt_.mype() << ": error in MPI_File_write: trailer " << err << endl; sfp.advance(len); #else fh.write(trailer,len); #endif } sfp.sync(); #if USE_MPI file_size = sfp.offset(); err = MPI_File_close(&fh); if ( err != 0 ) cout << ctxt_.mype() << ": error in MPI_File_close: " << err << endl; #else fh.close(); struct stat statbuf; stat(filename_cstr,&statbuf); file_size = statbuf.st_size; #endif } tm.stop(); if ( ctxt_.onpe0() ) { cout << " SampleWriter: write time: " << setprecision(3) << tm.real() << " s" << endl; if ( !serial ) { cout << " SampleWriter: file size: " << file_size << endl; cout << " SampleWriter: aggregate write rate: " << setprecision(2) << file_size/(tm.real()*1024*1024) << " MB/s" << endl; } } }