TABLE OF CONTENTS
53-tpool
DESCRIPTION
This example shows how to use a thread-pool with PWTK. A thread-pool is a mechanism for achieving concurrency of execution, consisting of multiple threads waiting for jobs to be allocated for concurrent execution.
This example is analogous to the 51-bg example (file: bg.pwtk), but uses thread-pool (::pwtk::tpool) instead of ::pwtk::bg. In particular, a lateral position of O adatom on a two-layer Al(111)-1x1 slab is scanned using a 6x6 lateral XY-grid, implying 36 pw.x calculations. A thread-pool with 4 workers is created, implying that initially 4 jobs are distributed to 4 workers. When the first job finishes, thread-pool submits the next job to a free worker, and so on until all jobs are completed.
BEWARE
- ::pwtk::thread requires the tcl-thread Tcl extension (which can be installed on e.g. Debian based distros as: sudo apt install tcl-thread)
EXAMPLE SOURCE FILE
SOURCE
# jobs submitted to thread-pool are child processes born in an empty state; # ::pwtk::propagate is used to inform PWTK what to propagate to the child processes propagate { # we will run 4 jobs in parallel; the number of processors used # for each job depends on the number of available cores; # edit according to your preference prefix mpirun -np 2 # load the pw.x input data with ::pwtk::pwi::load_fromPWI load_fromPWI relax.OAl111-1x1-2L.in # Make some simple structure modification: # 1. fix the O adatom and the top Al layer laterally with ::pwtk::pwi::fixAtoms1st # 2. fix the bottom layer of Al-slab with ::pwtk::pwi::fixAtomsLast fixAtoms1st 2 "0 0 1" fixAtomsLast 1 } # create a thread-pool ::pwtk::tpool object with 4 concurrent thread-workers set tp [tpool new -t 4] set seq [seq 0.0 0.2 1.0]; # this sequence will be used multiple times foreach dx $seq { foreach dy $seq { # jobs are submitted to thread-pool with the "job" method (see ::pwtk::tpool::job) $tp job { # each job should have its own prefix or else jobs will # write to the same temporary files CONTROL " prefix = 'O-$dx,$dy.Al111' " # shift the O adatom to a new position with ::pwtk::pwi::displaceAtoms displaceAtoms "$dx $dy 0.0" 1 # run pw.x calculation with ::pwtk::runPW runPW relax-z.O-$dx,$dy.Al111-1x1-2L } } } # wait for all tpool jobs to finish (see ::pwtk::tpool::wait) $tp wait # extract all total energies foreach dx $seq { foreach dy $seq { # get the total energy with pwo_totene, a shortcut to ::pwtk::pwo::totene set E($dx,$dy) [pwo_totene relax-z.O-$dx,$dy.Al111-1x1-2L.out] # get the minimum total energy ifset Emin $E($dx,$dy); # ::pwtk::ifset assigns the variable only if it is not yet assigned if { $E($dx,$dy) < $Emin } { set Emin $E($dx,$dy) } } } # calculate ΔE(x,y) = E(x,y) - Emin, and write a datafile foreach dx $seq { foreach dy $seq { # calculate ΔE(x,y) in eV units set dE [expr $ry2ev*($E($dx,$dy) - $Emin)] # lateral Cartesian position of the O atom in alat units set x [expr $dx - 0.5*$dy] set y [expr sqrt(3)/2*$dy] # write data to a file with ::pwtk::write write ene.OAl.dat "$x $y $dE" } write ene.OAl.dat "" } # plot the heatmap with ::pwtk::heatmap heatmap -pal dark -i 10,10 -contour -cc black \ -xr -0.5:1 -yr 0:sqrt(3)/2 \ -xl "Δx (alat)" -yl "Δy (alat)" \ -xf %.1f -yf %.1f -cbf %.1f ene.OAl.dat # plot the surface plot with ::pwtk::splot splot -pal dark -i 10,10 -contour -cc black \ -xr -0.5:1 -yr 0:sqrt(3)/2 \ -xl "Δx (alat)" -yl "Δy (alat)" -zl "ΔE (eV)" \ -xf %.1f -yf %.1f -zf %.1f -cbf %.1f \ -x {set zlabel rotate by 90} ene.OAl.dat