Commit e782467a by Francois Gygi

rel1_63_7

git-svn-id: http://qboxcode.org/svn/qb/branches/rel1_63@1924 cba15fb0-1239-40c8-b417-11db7ca47a34
parents 0c77dcad 66b16485
......@@ -21,16 +21,18 @@
#include <string>
#include <list>
#include <fstream>
#include <unistd.h> // sync()
#include <sstream>
#include <unistd.h> // fsync()
#include <stdio.h> // fopen(), fclose(), fprintf()
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/stat.h> // stat()
#include <mpi.h>
using namespace std;
////////////////////////////////////////////////////////////////////////////////
void wait_for_no_file(const string& lockfilename)
{
cerr << " waiting for no " << lockfilename << endl;
//cerr << " waiting for no " << lockfilename << endl;
struct stat statbuf;
int status;
do
......@@ -293,23 +295,21 @@ void UserInterface::processCmdsServer ( string inputfilename,
string lockfilename = inputfilename + ".lock";
// in server mode, redirect output to stream qbout
streambuf *qbout_buf;
streambuf *cout_buf;
ofstream qbout;
ifstream qbin;
ofstream tstfile;
ostringstream os;
while ( !done )
{
if ( onpe0_ )
{
// create file to signal that Qbox is waiting for a command on qbin
tstfile.open(lockfilename.c_str());
tstfile << "1" << endl;
tstfile.close();
sync();
// wait for tstfile to be removed by the driver
FILE *lockfile = fopen(lockfilename.c_str(),"w");
fprintf(lockfile,"1");
fclose(lockfile);
fsync(fileno(lockfile));
usleep(100000);
wait_for_no_file(lockfilename.c_str());
......@@ -317,13 +317,14 @@ void UserInterface::processCmdsServer ( string inputfilename,
qbin.sync();
qbin.clear();
// clear os
os.str("");
// save copy of cout streambuf
cout_buf = cout.rdbuf();
qbout.open(outputfilename.c_str(),ios_base::trunc);
qbout_buf = qbout.rdbuf();
// redirect cout
cout.rdbuf(qbout_buf);
cerr << " processCmdsServer: cout streambuf redirected" << endl;
// redirect cout to os
cout.rdbuf(os.rdbuf());
// cerr << " processCmdsServer: cout streambuf redirected" << endl;
cout << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl;
cout << "<fpmd:simulation xmlns:fpmd=\"" << qbox_xmlns() << "\">" << endl;
......@@ -480,13 +481,19 @@ void UserInterface::processCmdsServer ( string inputfilename,
cout << " End of command stream " << endl;
cout << "</fpmd:simulation>" << endl;
cout.flush();
qbout.close();
// write ostringstream contents to output file
FILE *qboutfile = fopen(outputfilename.c_str(),"w");
fprintf(qboutfile,"%s",os.str().c_str());
fclose(qboutfile);
fsync(fileno(qboutfile));
// restore cout streambuf
cout.rdbuf(cout_buf);
cerr << " processCmdsServer: cout streambuf reassigned" << endl;
// cerr << " processCmdsServer: cout streambuf reassigned" << endl;
}
// wait before retrying
sync();
usleep(200000);
} // while !done
......@@ -495,6 +502,5 @@ void UserInterface::processCmdsServer ( string inputfilename,
{
// remove lock file
remove(lockfilename.c_str());
sync();
}
}
--------------------------------------------------------------------------------
rel1_63_7
--------------------------------------------------------------------------------
r1920: Modified UserInterface.C to use C library, fsync()
to ensure synchronization.
r1912-1919: improvements in util/qbdriver files, twin.C
Added test programs in util/qbdriver
Added runtwin.sh script for interactive test of client-server mode
--------------------------------------------------------------------------------
rel1_63_6
--------------------------------------------------------------------------------
r1907: add sync in UserInterface.C
--------------------------------------------------------------------------------
rel1_63_5
--------------------------------------------------------------------------------
r1886: fix coeff of divergence correction for nspin=2 and multiple k-points
......
......@@ -19,5 +19,5 @@
#include "release.h"
std::string release(void)
{
return std::string("1.63.6");
return std::string("1.63.7");
}
This source diff could not be displayed because it is too large. You can view the blob instead.
../../test/potentials/C_HSCV_PBE-1.0.xml
\ No newline at end of file
../../test/potentials/H_HSCV_PBE-1.0.xml
\ No newline at end of file
set cell 8 0 0 0 8 0 0 0 8
species carbon C_HSCV_LDA-1.0.xml
species hydrogen H_HSCV_LDA-1.0.xml
species carbon C_HSCV_PBE-1.0.xml
species hydrogen H_HSCV_PBE-1.0.xml
atom C carbon 0.00000000 0.00000000 0.00000000
atom H1 hydrogen 1.20000000 1.20000000 1.20000000
atom H2 hydrogen 1.20000000 -1.20000000 -1.20000000
atom H3 hydrogen -1.20000000 1.20000000 -1.20000000
atom H4 hydrogen -1.20000000 -1.20000000 1.20000000
set ecut 35
set xc PBE
randomize_wf
set wf_dyn PSDA
set ecutprec 5
......
#!/bin/bash
exe=../../src/qb
rm -f qbin_[01] qbout_[01] qblog_[01] twin.out
mpirun -np 1 $exe -server qbin_0 qbout_0 > qblog_0 &
mpirun -np 1 $exe -server qbin_1 qbout_1 > qblog_1 &
./twin qbin qbout > twin.out &
wait
//
// testlock.C
//
// test the creation and removal of a lock file using the C library
//
#include <stdio.h> // fopen, fclose, fprintf
#include <sys/stat.h> // stat()
#include <unistd.h> // fsync()
int main()
{
// create a lock file "lock.dat"
FILE *lockfile = fopen("lock.dat","w");
fprintf(lockfile,"1");
fclose(lockfile);
fsync(fileno(lockfile));
// test for the presence of the lock file
struct stat statbuf;
int status;
do
{
// stat returns 0 if the file exists
status = stat("lock.dat",&statbuf);
usleep(100000);
}
while ( status != 0 );
// remove the lock file
remove("lock.dat");
usleep(100000);
// test for the absence of the file
do
{
// stat returns 0 if the file exists
status = stat("lock.dat",&statbuf);
usleep(100000);
}
while ( status == 0 );
}
//
// testreassign.C
//
// test the functionality of:
// - reassign the streambuf of std::cout to an ostringstream
// - write and sync using C library functions
//
// This program tests the functionality needed in UserInterface when
// operating in server mode. In that case, the std::cout stream is redirected
// to an ostringstream. The contents of the ostringstream are written at the
// end using C library functions, which allow for the use of the fsync() call.
//
#include <unistd.h>
#include <iostream>
#include <fstream>
#include <sstream>
int main()
{
// write something to std::cout before reassign
std::cout << "initial write on std::cout" << std::endl;
// streambuf pointers
std::streambuf *qbout_buf;
std::streambuf *cout_buf;
// save copy of cout streambuf
cout_buf = std::cout.rdbuf();
// create an ostringstream
std::ostringstream os;
qbout_buf = os.rdbuf();
// redirect std::cout to os
std::cout.rdbuf(qbout_buf);
// the following output should go to the ostringstream
std::cout << " output written to cout after redirect" << std::endl;
std::cout.flush();
// write contents of os to file "out.txt"
FILE *qboutfile = fopen("out.txt","w");
fprintf(qboutfile,"%s",os.str().c_str());
fclose(qboutfile);
fsync(fileno(qboutfile));
// restore cout streambuf
std::cout.rdbuf(cout_buf);
// write more output to std::cout
std::cout << "more output on std::cout" << std::endl;
}
////////////////////////////////////////////////////////////////////////////////
//
// qb_driver_twin.C
// twin.C
//
////////////////////////////////////////////////////////////////////////////////
//
// use: qb_driver qb_input qb_output
// use: twin qbin qbout
//
// qb_driver sends commands to the server, via the file qb_input_1, qb_input_2
// It checks for the presence of a link named "qb_input_<n>.lock"
// twin sends commands to two Qbox servers, via the files qbin_0, qbin_1
// It checks for the presence of a link named "qbin_<n>.lock"
// before writing additional commands
// compile with: g++ -o qb_driver qb_driver.C
// compile with: g++ -o twin twin.C
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <cstdlib>
#include <unistd.h> // stat()
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
using namespace std;
void wait_for_file(string& lockfilename);
void wait_for_nofile(string& lockfilename);
void sendCmd(const string filename, const string cmd);
void wait_for_file(const string& lockfilename);
void wait_for_nofile(const string& lockfilename);
int main(int argc, char** argv)
{
......@@ -47,22 +50,16 @@ int main(int argc, char** argv)
cout << " qb lock file: " << lockfilename[i] << endl;
}
ofstream qb_infile[2];
ifstream qb_outfile[2];
// send commands to servers to execute the init.i script
for ( int i = 0; i < ns; i++ )
{
wait_for_file(lockfilename[i]);
qb_infile[i].open(qb_infilename[i].c_str(),ios_base::trunc);
qb_infile[i] << "init.i" << endl;
cout << " sent init.i cmd to server " << i << endl;
qb_infile[i].close();
sync();
sendCmd(qb_infilename[i],string("init.i\n"));
remove(lockfilename[i].c_str());
cout << " lock file of server " << i << " removed" << endl;
}
usleep(500000);
usleep(100000);
// extract element <etotal> from output
string element_name("etotal");
......@@ -70,8 +67,7 @@ int main(int argc, char** argv)
for ( int iter = 0; iter < 5; iter++ )
{
cout << " loop start" << endl;
// loop over servers
for ( int i = 0; i < ns; i++ )
{
wait_for_file(lockfilename[i]);
......@@ -127,61 +123,62 @@ int main(int argc, char** argv)
double dz = amplitude * (2.0*drand48()-1.0);
// prepare next commands
// send next command to server
// send next commands to server
// write all commands into ostringstream os
ostringstream os;
os << "move C by " << dx << " " << dy << " " << dz << endl;
os << "run 0 30" << endl;
qb_infile[i].open(qb_infilename[i].c_str(),ios_base::trunc);
qb_infile[i] << "move C by " << dx << " " << dy << " " << dz << endl;
qb_infile[i] << "run 0 30" << endl;
qb_infile[i].close();
sync();
// write ostringstream to file
sendCmd(qb_infilename[i],os.str());
remove(lockfilename[i].c_str());
cout << " lock file " << i << " removed" << endl;
}
usleep(100000);
}
// send quit command to all servers
for ( int i = 0; i < ns; i++ )
{
wait_for_file(lockfilename[i]);
qb_infile[i].open(qb_infilename[i].c_str(),ios_base::trunc);
qb_infile[i] << "quit" << endl;
qb_infile[i].close();
sync();
cout << " sent quit cmd to server " << i << endl;
sendCmd(qb_infilename[i],string("quit\n"));
remove(lockfilename[i].c_str());
cout << " lock file " << i << " removed" << endl;
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////
void sendCmd(const string filename, const string str)
{
FILE *fp = fopen(filename.c_str(),"w");
fprintf(fp,"%s",str.c_str());
fclose(fp);
fsync(fileno(fp));
}
////////////////////////////////////////////////////////////////////////////////
void wait_for_file(string& lockfilename)
void wait_for_file(const string& lockfilename)
{
cerr << " waiting for " << lockfilename << endl;
struct stat statbuf;
int status;
do
{
// stat returns 0 if the file exists
status = stat(lockfilename.c_str(),&statbuf);
// cout << " status = " << status << endl;
usleep(100000);
}
while ( status != 0 );
}
////////////////////////////////////////////////////////////////////////////////
void wait_for_nofile(string& lockfilename)
void wait_for_nofile(const string& lockfilename)
{
cerr << " waiting for no " << lockfilename << endl;
struct stat statbuf;
int status;
do
{
// stat returns 0 if the file exists
status = stat(lockfilename.c_str(),&statbuf);
// cout << " status = " << status << endl;
usleep(100000);
}
while ( status == 0 );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment