Below is a sample for emulating a lottery. To compile GenerateDraws.C issue:
g++ -o GenerateDraws -0 3 GenerateDraws.C
#include <cstdlib> #include <unistd.h> #include <list> #include <algorithm> #include <fstream> int GetARandomNumberBetween1And60() { returnrandom()/(RAND_MAX/60)+1; }; void initrandom(unsigned seed){ #define RANDSIZE 256 static char randstate[RANDSIZE]; initstate(seed, randstate, RANDSIZE); } main(int argc,char ** argv) { initrandom(getpid()); // seeding for a new sequence of pseudo-random integers // let generate 8 number between 1 and 60 list<long int> Series; long int n; long long DrawNumber,InitialDrawNumber; ofstream OutputFileMonitor; OutputFileMonitor.open("Monitor"); DrawNumber=atoll(argv[1]); InitialDrawNumber=DrawNumber; do { int i; Series.clear(); for(i=8;i;i--) { //find 8 different number between 1 and 60 do n=GetARandomNumberBetween1And60(); while (find(Series.begin(),Series.end(),n)!=Series.end()); Series.push_front(n); }; //let display the result Series.sort(); list<long int>::iterator j; for(j=Series.begin();j!=Series.end();++j) cout << *j << " "; cout << endl; OutputFileMonitor.seekp(1,ios::beg); OutputFileMonitor << 100*(InitialDrawNumber-DrawNumber)/InitialDrawNumber; } while (--DrawNumber); OutputFileMonitor.seekp(1,ios::beg); OutputFileMonitor << "100"; OutputFileMonitor.close(); }
#the script takes the tested draw as parameter #example: ./Submit 3 4 5 32 34 43 n=1000000 NodesNumber=12 #temporary working directory on the execution nodes TMP=.$HOSTNAME i=0 #the loop variable is used is all the "for" loops #the format is 1 2 3 4 .... n loop="" # use here the broker developped for the redbook # see chapter 8 (mds executable) for node in $(mds $NodesNumber | xargs) do Nodes[$i]=$node loop=${loop}" "${i} i=$(( $i + 1 )) done echo The number of draws tested is $n a=$* #sort the numbers in the specified draw # 2 45 23 12 32 43 becomes 2 12 23 32 43 45 so that we could use # grep to test this draw and the ouput of the draw programs. param=$(echo $a | tr " " " " | sort -n | xargs ) # parrarell transfer of the draw executable # we submit jobs in the background, get their process id # and uses the wait command to wait for their completion # this method is also used for the jobs submission echo Transferring executable files for i in $loop do gsissh -p 24 ${Nodes[$i]} "[ -d $TMP ] || mkdir $TMP" & ProcessID[$i]=$! done for i in $loop do wait ${ProcessID[$i]} gsiscp -P 24 GenerateDraws ${Nodes[$i]}:$TMP & ProcessID[$i]=$! done for i in $loop do wait ${ProcessID[$i]} gsissh -p 24 ${Nodes[$i]} "chmod +x ./$TMP/GenerateDraws" & ProcessID[$i]=$! done #file should be made executable #on all the execution nodes echo Jobs submission to the grid for i in $loop do wait ${ProcessID[$i]} echo ${Nodes[$i]} EXE="cd $TMP;./GenerateDraws $n | grep "'"'$param'" && echo GOT IT on $HOSTNAME' gsissh -p 24 ${Nodes[$i]} "$EXE" & ProcessID[$i]=$! done #for monitoring, we copy locally the Monitor files # created on each compute nodes. This file content the # percentage of tested draws. Each files is suffixes by # the nodes number. $statusnum is actually the sum of all # the percentage (Monitor files) devided by 100. When it # equals the number of nodes, that means that we have finished echo Monitoring statussum=0 while (( $statussum != $NodesNumber )) do echo sleep 5 #we poll every 5 seconds statussum=0 for i in $loop do gsiscp -q -P 24 ${Nodes[$i]}:$TMP/Monitor Monitor.$i status=$(cat Monitor.$i) statussum=$(( $status + $statussum )) echo ${Nodes[$i]}:Monitor $(cat Monitor.$i) % done statussum=$(( $statussum / 100 )) done #cleanup the tmp directory for i in $loop do wait ${ProcessID[$i]} gsissh -p 24 ${Nodes[$i]} "rm -fr ./.$TMP" & ProcessID[$i]=$! done
To compile this program, just issue:
g++ -o GenerateDrawsGlobus GenerateDrawsGlobus.C #include <cstdlib> #include <unistd.h> #include <list> #include <algorithm> #include <string> #include <fstream> int GetARandomNumberBetween1And60() { returnrandom()/(RAND_MAX/60)+1; }; void initrandom(unsigned seed){ #define RANDSIZE 256 static char randstate[RANDSIZE]; initstate(seed, randstate, RANDSIZE); } // the first argument is the hostname provided by SubmitGlobus script // the second argument is the number of draws that must be generated main(int argc,char ** argv) { initrandom(getpid()); // seeding for a new sequence of pseudo-random integers // let generate 8 number between 1 and 60 list<long int> Series; long int n; long long DrawNumber,InitialDrawNumber; ofstream OutputFileMonitor; string filename; filename="Monitor."; filename.append(argv[1]); OutputFileMonitor.open(filename.c_str()); DrawNumber=atoll(argv[2]); InitialDrawNumber=DrawNumber; do { int i; Series.clear(); for(i=8;i;i--) { //find 8 different number between 1 and 60 do n=GetARandomNumberBetween1And60(); while (find(Series.begin(),Series.end(),n)!=Series.end()); Series.push_front(n); }; //let display the result Series.sort(); list<long int>::iterator j; for(j=Series.begin();j!=Series.end();++j) cout << *j << " "; cout << endl; OutputFileMonitor.seekp(1,ios::beg); OutputFileMonitor << 100*(InitialDrawNumber-DrawNumber)/InitialDrawNumber; } while (--DrawNumber); OutputFileMonitor.seekp(1,ios::beg); OutputFileMonitor << "100"; OutputFileMonitor.close(); }
#the script takes the tested draw as parameter #example: ./Submit 3 4 5 32 34 43 n=10000000 NodesNumber=8 #temporary filename used by by GenerateDrawsGlobus #to monitor the job #we can also use the process id to increase the granularity TMP=$HOSTNAME i=0 #the loop variable is used is all the "for" loops #the format is 1 2 3 4 .... n loop="" # use here the broker developped for the redbook # see chapter 8 (mds executable) for node in $(mds $NodesNumber | xargs) do Nodes[$i]=$node loop=${loop}" "${i} i=$(( $i + 1 )) done echo The number of draws tested is $n a=$* #sort the numbers in the specified draw # 2 45 23 12 32 43 becomes 2 12 23 32 43 45 so that we could use # grep to test this draw and the ouput of the draw programs. param=$(echo $a | tr " " " " | sort -n | xargs ) #Start the gass server on each nodes # clean up the Monitoring file when leaving for i in $loop do rsl='&(executable=$(GLOBUS_LOCATION)/bin/globus-gass-server)(arguments=-c -t -r)(environment=(LD_LIBRARY_PATH $(GLOBUS_LOCATION)/lib))(file_clean_up=Monitor.'"$TMP)" globusrun -o -r ${Nodes[$i]} "$rsl" > gass-server.$i & done #file should be made executable #on all the execution nodes echo Jobs submission to the grid rsl="+" for i in $loop do echo ${Nodes[$i]} rsl=${rsl}"(&(resourceManagerContact="${Nodes[$i]}")" rsl=${rsl}"(executable=$(GLOBUSRUN_GASS_URL)$PWD/GenerateDrawsGlobus.sh)(argum ents=$TMP $n "$param")(subjobStartType=loose-barrier)(file_stage_in=($(GLOBUSRUN_GASS_URL )$PWD/GenerateDrawsGlobus GenerateDrawsGlobus.$TMP))(file_clean_up=GenerateDrawsGlobus.$TMP)(environment= (LD_LIBRARY_PATH $(GLOBUS_LOCATION)/lib)) )" done echo $rsl globusrun -s -o "$rsl" & #for monitoring, we copy locally the Monitor files # created on each compute nodes. This file content the # percentage of tested draws. Each files is suffixes by # the nodes number. $statusnum is actually the sum of all # the percentage (Monitor files) devided by 100. When it # equals the number of nodes, that means that we have finished echo Monitoring rm -f Monitor.* statussum=0 while (( $statussum != $NodesNumber )) do echo sleep 5 #we poll every 5 seconds statussum=0 for i in $loop do if [ -s gass-server.$i] then contact=$(cat gass-server.$i) globus-url-copy $contact/~/Monitor.$TMP file://$PWD/Monitor.$i status=$(cat Monitor.$i) statussum=$(( $status + $statussum )) echo ${Nodes[$i]}:Monitor $(cat Monitor.$i) % fi done statussum=$(( $statussum / 100 )) done #Stop the gassserver for i in $loop do contact=$(cat gass-server.$i) globus-gass-server-shutdown $contact done
18.191.235.8