Commit 5a09bfec by Francois Gygi

initial revision


git-svn-id: http://qboxcode.org/svn/qb/trunk@828 cba15fb0-1239-40c8-b417-11db7ca47a34
parent fb82c896
twin: twin.C
g++ -o $@ $^
qbd: qbd.C
g++ -o $@ $^
set cell 8 0 0 0 8 0 0 0 8
species carbon http://fpmd.ucdavis.edu/potentials/C/C_HSCV_LDA-1.0.xml
species hydrogen http://fpmd.ucdavis.edu/potentials/H/H_HSCV_LDA-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
randomize_wf
set wf_dyn PSDA
set ecutprec 5
run 1 200
--------------------------------------------------------------------------------
Using Qbox in client-server mode
--------------------------------------------------------------------------------
Qbox is used in client-server mode by invoking it with the "-server" argument:
$ mpirun -np 32 qb -server qbin qbout
Qbox starts executing the commands in qbin (if there are any)
Qbox erases the file qbout and writes output to qbout.
When Qbox is done executing commands in file qbin, it creates a file
named qbin.lock.
Qbox then waits for the file qbin.lock to disappear.
The client program:
Waits for the file qbin.lock to appear
Reads qbout
Erases qbin
Writes commands on qbin
Removes the file qbin.lock
Testing for the presence of qbin.lock:
In a C/C++ program:
- trying to open the file until the open() call is successful.
- using the stat() function (see man 2 stat).
In a shell script:
- Checking the presence of a file using
if [[ -a qbin.lock ]]
then
...
fi
Waiting for the lock file to appear:
while [[ ! -a qbin.lock ]]
do
usleep 500000
done
In interactive use:
$ cat > qbin
qbox command 1
qbox command 2
^D
$ rm qbin.lock
Using other programming languages (Fortran, etc.):
- trying to open the link and writing to it when successful.
////////////////////////////////////////////////////////////////////////////////
//
// qb_driver.C
//
////////////////////////////////////////////////////////////////////////////////
//
// use: qb_driver qb_input_file qb_output_file
//
// qb_driver sends commands to the server, via the file qb_input_file
// It checks for the presence of a link named "qb_input_file.lock"
// before writing additional commands
// compile with: g++ -o qb_driver qb_driver.C
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
using namespace std;
void wait_for_file(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)
{
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 );
}
int main(int argc, char** argv)
{
char* qb_infilename = argv[1];
char* qb_outfilename = argv[2];
string lockfilename = string(qb_infilename) + ".lock";
ofstream qb_infile;
ifstream qb_outfile;
// send command to execute init.i script
wait_for_file(lockfilename);
qb_infile.open(qb_infilename,ios_base::trunc);
qb_infile << "init.i" << endl;
cout << " sent init.i cmd" << endl;
qb_infile.close();
sync();
remove(lockfilename.c_str());
cout << " lock file removed" << endl;
usleep(500000);
// extract element <etotal> from output
string element_name("etotal");
double etotal;
bool done = false;
//while ( !done )
for ( int iter = 0; iter < 5; iter++ )
{
cout << " loop start" << endl;
wait_for_file(lockfilename);
cout << " reading output ... ";
qb_outfile.open(qb_outfilename);
// get output from server
// read output until EOF
string s, qb_output;
//qb_outfile.sync();
qb_outfile.clear();
while ( qb_outfile )
{
getline(qb_outfile,s);
qb_output += s;
qb_output += '\n';
}
cout << qb_output << endl;
cout << "done" << endl;
qb_outfile.close();
// parse output
string start_tag = "<" + element_name + ">";
string end_tag = "</" + element_name + ">";
size_t pstart = qb_output.find(start_tag);
size_t pend = qb_output.find(end_tag);
size_t len;
if ( pend != string::npos )
{
string buf;
// element was found
len = pend + end_tag.size() - pstart;
buf = qb_output.substr(pstart,len);
cout << " buf= " << buf << endl;
istringstream is(buf);
string dum;
is >> dum >> etotal;
cout << " etotal = " << etotal << endl;
}
else
{
cout << " element " << element_name << " not found in qb_output" << endl;
}
// analyze data
//
// generate a random move in a cube of side 0.04
const double amplitude = 0.02;
double dx = amplitude * (2.0*drand48()-1.0);
double dy = amplitude * (2.0*drand48()-1.0);
double dz = amplitude * (2.0*drand48()-1.0);
// prepare next commands
// send next command to server
qb_infile.open(qb_infilename,ios_base::trunc);
qb_infile << "move C by " << dx << " " << dy << " " << dz << endl;
qb_infile << "run 0 30" << endl;
qb_infile.close();
sync();
remove(lockfilename.c_str());
cout << " lock file removed" << endl;
usleep(100000);
}
wait_for_file(lockfilename);
qb_infile.open(qb_infilename,ios_base::trunc);
qb_infile << "quit" << endl;
qb_infile.close();
sync();
cout << " sent quit cmd" << endl;
remove(lockfilename.c_str());
cout << " lock file removed" << endl;
return 0;
}
#!/bin/bash
# qbox.job: qbox job script
#
# submit with: qsub -pe mpi <NSLOTS> [-v NTASKS=<NTASKS> ] -N <JOB_NAME> job
# uses: JOB_NAME.i
# produces: JOB_NAME.r JOB_NAME.o<jobid> JOB_NAME.po<jobid>
#
#$ -cwd
#$ -j y
#$ -S /bin/bash
#
exe=/home/fgygi/qb/export/rel1_45_2/qb/src/qb
MPIRUNARGS=-q 0
declare -i nslots=$NSLOTS
declare -i ntasks
if [ "$NTASKS" == "" ]
then
NTASKS=$NSLOTS
fi
if [ "$NTASKS" == "$NSLOTS" ]
then
# 4 tasks per node
NTASKS=$NSLOTS
echo "ulimit -v 850000" > mpirunrc.$JOB_ID
else
# less than 4 tasks per node
ntasks=$NTASKS
declare -i ns2=nslots*2
declare -i ns3=nslots*3
declare -i ns4=nslots*4
declare -i nt4=ntasks*4
if [ $ns2 -eq $nt4 ]
then
# 2 tasks per node
echo "ulimit -v 1700000" > mpirunrc.$JOB_ID
PPN="-ppn 2"
elif [ $ns3 -eq $nt4 ]
then
# 3 tasks per node
echo "ulimit -v 2550000" > mpirunrc.$JOB_ID
PPN="-ppn 3"
elif [ $nslots -eq $nt4 ]
then
# 1 task per node
echo "ulimit -v 3400000" > mpirunrc.$JOB_ID
PPN="-ppn 1"
else
echo "Illegal value of NTASKS: must be NSLOTS, NSLOTS/2, NSLOTS/3 or NSLOTS/4"
exit 1
fi
cat $TMPDIR/machines | uniq > $TMPDIR/machines.tmp
mv $TMPDIR/machines.tmp $TMPDIR/machines
fi
echo TMPDIR=$TMPDIR
echo NSLOTS=$NSLOTS
echo NTASKS=$NTASKS
cmd="mpirun $MPIRUNARGS -np $NTASKS $PPN -machinefile $TMPDIR/machines \
-rcfile mpirunrc.$JOB_ID $exe -server $JOB_NAME.in $JOB_NAME.out"
echo cmd=$cmd
$cmd
rm mpirunrc.$JOB_ID
#!/bin/bash
#$ -A TG-ASC090004
#$ -N qbtwin
#$ -V
#$ -q development
#$ -cwd
#$ -j y
#$ -pe 4way 16
#$ -l h_rt=00:10:00
exe=$HOME/qb/export/rel1_51_1/qb/src/qb
export OMP_NUM_THREADS=1
# ibrun -n <# of cores> -o <hostlist offset> exec <args>
ibrun -n 1 -o 0 $exe -server qbin_0 qbout_0 &
ibrun -n 1 -o 1 $exe -server qbin_1 qbout_1 &
ibrun -n 1 -o 2 ./twin qbin qbout &
wait
////////////////////////////////////////////////////////////////////////////////
//
// qb_driver_twin.C
//
////////////////////////////////////////////////////////////////////////////////
//
// use: qb_driver qb_input qb_output
//
// 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"
// before writing additional commands
// compile with: g++ -o qb_driver qb_driver.C
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#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);
int main(int argc, char** argv)
{
char* qb_infilename_root = argv[1];
char* qb_outfilename_root = argv[2];
// number of servers
const int ns = 2;
string qb_infilename[ns];
string qb_outfilename[ns];
string lockfilename[ns];
for ( int i = 0; i < ns; i++ )
{
ostringstream i_str;
i_str << i;
qb_infilename[i] = string(qb_infilename_root) + "_" + i_str.str();
qb_outfilename[i] = string(qb_outfilename_root) + "_" + i_str.str();
lockfilename[i] = string(qb_infilename[i]) + ".lock";
cout << " qb input file: " << qb_infilename[i] << endl;
cout << " qb output file: " << qb_outfilename[i] << endl;
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();
remove(lockfilename[i].c_str());
cout << " lock file of server " << i << " removed" << endl;
}
usleep(500000);
// extract element <etotal> from output
string element_name("etotal");
double etotal;
for ( int iter = 0; iter < 5; iter++ )
{
cout << " loop start" << endl;
for ( int i = 0; i < ns; i++ )
{
wait_for_file(lockfilename[i]);
cout << " reading output from server " << i << " ... " << endl;
qb_outfile[i].open(qb_outfilename[i].c_str());
// get output from server
// read output until EOF
string s, qb_output;
//qb_outfile.sync();
qb_outfile[i].clear();
while ( qb_outfile[i] )
{
getline(qb_outfile[i],s);
qb_output += s;
qb_output += '\n';
}
cout << i << ": " << qb_output << endl;
cout << i << ": " << "done" << endl;
qb_outfile[i].close();
// parse output
string start_tag = "<" + element_name + ">";
string end_tag = "</" + element_name + ">";
size_t pstart = qb_output.find(start_tag);
size_t pend = qb_output.find(end_tag);
size_t len;
if ( pend != string::npos )
{
string buf;
// element was found
len = pend + end_tag.size() - pstart;
buf = qb_output.substr(pstart,len);
cout << " buf= " << buf << endl;
istringstream is(buf);
string dum;
is >> dum >> etotal;
cout << " etotal = " << etotal << endl;
}
else
{
cout << " element " << element_name
<< " not found in qb_output[" << i << "]" << endl;
}
// analyze data
//
// generate a random move in a cube of side 0.04
const double amplitude = 0.02;
double dx = amplitude * (2.0*drand48()-1.0);
double dy = amplitude * (2.0*drand48()-1.0);
double dz = amplitude * (2.0*drand48()-1.0);
// prepare next commands
// send next command to server
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();
remove(lockfilename[i].c_str());
cout << " lock file " << i << " removed" << endl;
}
usleep(100000);
}
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;
remove(lockfilename[i].c_str());
cout << " lock file " << i << " removed" << endl;
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////
void wait_for_file(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)
{
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