/usr/bin/gpaw-mpisim is in gpaw 1.1.0-1+b2.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | #! /usr/bin/python
import sys
import numpy as np
class DummyCommunicator:
def __init__(self, rank, size, ranks=None):
self.rank = rank
self.size = size
self.ranks = ranks
self.txt = ''
def new_communicator(self, ranks):
# The process with rank i in new group is the
# process with rank ranks[i] in the old group
my_subcomm_rank = np.argwhere(ranks==self.rank).ravel()
return DummyCommunicator(rank=my_subcomm_rank.item(),
size=len(ranks), ranks=ranks)
def simulate_kpt_comm(self, nspins, nibzkpts):
# From gpaw/wavefunctions.py lines 76-83 rev. 3893
mynks = nspins*nibzkpts // self.size
self.txt += ', mynks=%d' % mynks
ks0 = self.rank * mynks
kpt_u = []
for ks in range(ks0, ks0 + mynks):
s, k = divmod(ks, nibzkpts)
kpt_u.append('%d%s' % (k, s==0 and '^' or 'v'))
self.txt += ', kpt_u=[' + ','.join(kpt_u) + ']'
self.output('kpt_comm')
def simulate_band_comm(self, bd):
self.txt += ', mynbands=%d' % bd.mynbands
self.txt += ', mybands=%s' % bd.get_band_indices()
self.output('band_comm')
def output(self, name='world'):
if name is not 'world':
name = ' ' + name.ljust(12)
print '%s: rank=%d, ranks=%s' % (name, self.rank, self.ranks) + self.txt
# -------------------------------------------------------------------
def simulate(world_size, parsize_c, parsize_bands, parstride_bands, nspins,
nibzkpts, nbands, show_kpt=True, show_band=True, show_domain=True):
# We haven't imported GPAW until now because it messes with sys.argv
from gpaw import mpi
print ''
print 'Simulating: world.size = %d' % world_size
print ' parsize_c =', parsize_c
print ' parsize_bands =', parsize_bands
print ' parstride_bands =', parstride_bands
print ' nspins =', nspins
print ' nibzkpts =', nibzkpts
print ' nbands =', nbands
print ''
for rank in range(world_size):
world = DummyCommunicator(rank, world_size)
world.output()
(domain_comm, kpt_comm, band_comm) = mpi.distribute_cpus(parsize_c, \
parsize_bands, nspins, nibzkpts, world)
if show_kpt:
kpt_comm.simulate_kpt_comm(nspins, nibzkpts)
if show_band:
from gpaw.band_descriptor import BandDescriptor
bd = BandDescriptor(nbands, band_comm, parstride_bands)
band_comm.simulate_band_comm(bd)
if show_domain:
domain_comm.output('domain_comm') #TODO N_c parts!
# -------------------------------------------------------------------
from optparse import Option, OptionValueError
def check_int3(option, opt, value):
try:
x,y,z = value.split(',')
return (int(x), int(y), int(z),)
except ValueError:
raise OptionValueError('option %s: invalid int3 value: %r' \
% (opt, value))
class CustomOption(Option):
TYPES = Option.TYPES + ('int3',)
TYPE_CHECKER = Option.TYPE_CHECKER.copy()
TYPE_CHECKER['int3'] = check_int3
if __name__ in ['__main__', '__builtin__']:
from optparse import OptionParser, OptionGroup
usage = '%prog [options]'
version = '%prog 0.1'
description = 'Simulate MPI parallelization of a GPAW calculation.'
parser = OptionParser(usage=usage, version=version,
description=description, option_class=CustomOption)
output_options = OptionGroup(parser, 'Output-specific options')
output_options.add_option('-v', '--verbose', action='store_true', \
default=None, dest='show_all', help='Simulate all communicators')
output_options.add_option('-0', '--kpoint-communicators',
action='store_true', \
default=False, dest='show_kpoint', help='Simulate kpoint communicators')
output_options.add_option('-1', '--band-communicators', action='store_true', \
default=False, dest='show_band', help='Simulate band communicators')
output_options.add_option('-2', '--domain-communicators',
action='store_true', \
default=False, dest='show_domain', help='Simulate domain communicators')
parser.add_option_group(output_options)
mpi_options = OptionGroup(parser, 'MPI-specific options')
mpi_options.add_option('-w', '--dry-run', default=0, type='int',
dest='world_size', metavar='<N>', \
help='Number of processes in parallelization [default: %default]')
mpi_options.add_option('-c', '--domain-decomposition', default=None, \
type='int3', dest='parsize_c', metavar='<X,Y,Z>', \
help='Domain decomposition along three axes [default: %default]')
mpi_options.add_option('-b', '--state-parallelization', default=1,
type='int', \
dest='parsize_bands', metavar='<B>', \
help='Divide bands into this many blocks [default: %default]')
mpi_options.add_option('-x', '--strided-bandgroups', action='store_true', \
default=None, dest='parstride_bands',\
help='Simulate strided band grouping (instead of blocked)')
parser.add_option_group(mpi_options)
gpaw_options = OptionGroup(parser, 'GPAW-specific options')
gpaw_options.add_option('-s', '--spins', default=1, type='int',
dest='nspins', \
metavar='<nspins>', help='Number of spins [default: %default]')
gpaw_options.add_option('-k', '--kpoints', default=1, type='int', \
dest='nibzkpts', metavar='<nibzkpts>', \
help='Number of irreducible k-points [default: %default]')
gpaw_options.add_option('-n', '--bands', default=1, type='int',
dest='nbands', \
metavar='<nbands>', help='Number of bands [default: %default]')
parser.add_option_group(gpaw_options)
#parser.add_option('-g', '--grid-size', default=None, type='int3', \
# dest='N_c', metavar='<X,Y,Z>', \
# help='Size of the grid along three axes [default: %default]')
opts, args = parser.parse_args()
if opts.show_all is not None:
opts.show_kpoint = True
opts.show_band = True
opts.show_domain = True
if not opts.world_size > 0:
sys.stderr.write('ERROR: MPI world size is unspecified or invalid.\n')
parser.print_help()
raise SystemExit(-1)
if opts.parsize_c is not None and (len(opts.parsize_c) != 3 or
(np.array(opts.parsize_c)<1).any()):
sys.stderr.write('ERROR: Domain decomposition is invalid.\n')
parser.print_help()
raise SystemExit(-1)
if not opts.parsize_bands > 0:
sys.stderr.write('ERROR: State-parallelization size is invalid.\n')
parser.print_help()
raise SystemExit(-1)
if not opts.nspins in [1,2]:
sys.stderr.write('ERROR: Invalid number of spins.\n')
parser.print_help()
raise SystemExit(-1)
if not opts.nibzkpts > 0:
sys.stderr.write('ERROR: Invalid number of irreducible k-points.\n')
parser.print_help()
raise SystemExit(-1)
if not opts.nbands > 0:
sys.stderr.write('ERROR: Invalid number of bands.\n')
parser.print_help()
raise SystemExit(-1)
simulate(opts.world_size, opts.parsize_c, opts.parsize_bands,
opts.parstride_bands, opts.nspins, opts.nibzkpts, opts.nbands,
opts.show_kpoint, opts.show_band, opts.show_domain)
|