KMR
kmrgenscript.in.py
Go to the documentation of this file.
1 #!/usr/bin/env python3
2 # -*-coding: utf-8;-*-
3 
4 ## Copyright (C) 2012-2018 RIKEN R-CCS
5 
6 ## \file kmrgenscript.in.py KMR-Shell Job-Script Generator.
7 
8 import sys
9 import os
10 from optparse import OptionParser
11 
12 kmrhome = '@KMRHOME@'
13 
14 ## Checks file existence.
15 # If file does not exist, it prints an error message and exit.
16 # @param path file path for check.
17 
18 def checkexist (path) :
19  if not os.path.exists(path) :
20  print('Error: file or dir "%s" is not exist.' % path)
21  sys.exit()
22 
23 ## Checks path is a directory.
24 # If path does not exist, it prints an error message and exit. Or,
25 # it creates a directory with force option.
26 
27 def checkdir (path, force) :
28  if os.path.exists(path) :
29  if not os.path.isdir(path) :
30  print('Error: "%s" is not directory.' % path)
31  sys.exit()
32  else :
33  if force :
34  try :
35  os.mkdir(path)
36  except IOError :
37  print('Error: could not create "%s".' % path)
38  sys.exit()
39  else :
40  print('Error: directory "%s" is not exist. create it or use -f option.' % path)
41  sys.exit()
42 
43 ## Generates job-script for K.
44 # @param node number of node to execute.
45 # @param infile input file pathname.
46 # @param outfile output file prefix.
47 # @param indir directory path name that has input files.
48 # @param outdir directory path name that has result output files.
49 # @param rsctime resource time limit.
50 # @param mapper pathname of mapper program.
51 # @param reducer pathname of reducer program.
52 # @param multi multiple input file for one mapper process.
53 # @param scrfile output script file name.
54 
55 def k_scheduler(node, infile, outfile, indir, outdir, rsctime, mapper, reducer, multi, scrfile) :
56 
57  # Read template file.
58  template = ''
59  if template == '' :
60  try :
61  template = open('kmrgenscript.template').read()
62  except IOError :
63  pass
64  if template == '' :
65  try :
66  dir0 = os.path.dirname(os.path.realpath(__file__))
67  dir1 = os.path.realpath(dir0 + '/../lib')
68  #template = open(dir1 + '/kmrgenscript.template').read()
69  except IOError :
70  pass
71  if template == '' :
72  try :
73  dir2 = os.path.realpath(kmrhome + '/lib')
74  template = open(dir2 + '/kmrgenscript.template').read()
75  except IOError :
76  pass
77  if template == '' :
78  print('Error: could not open job-script template.')
79  sys.exit()
80 
81  # Stage in section
82  ncol = len(str(node -1))
83  stginstr = ""
84  # Stage in reducer if specified
85  if reducer :
86  stginstr += '#PJM --stgin "rank=* %s %%r:./"' \
87  % ('./' + os.path.basename(reducer))
88  if multi :
89  files = os.listdir(indir)
90  rank = 0
91  for file in files :
92  ipath = os.path.join(indir, file)
93  if len(stginstr) :
94  stginstr += '\n'
95  stginstr += '#PJM --stgin "rank=%s %s %%r:./work/"' % (rank, ipath)
96  rank = rank +1
97  if rank >= node :
98  rank = 0
99  else :
100  if len(stginstr) :
101  stginstr += '\n'
102  ipath = os.path.join(indir, infile)
103  stginstr += '#PJM --stgin "rank=* %s%%0%sr %%r:./input"' % (ipath, ncol)
104 
105  # Stage out section
106  opath = os.path.join(outdir, outfile)
107  stgoutstr = '#PJM --stgout "rank=* %%r:./output.%%r %s.%%0%sr"' % (opath, ncol)
108 
109  # program execute section
110  if not multi :
111  if not reducer :
112  execstr = 'mpiexec -n %s -of-proc output ./kmrshell -m %s ./input'\
113  % (node, './' + os.path.basename(mapper))
114  else :
115  execstr = 'mpiexec -n %s -of-proc output ./kmrshell -m %s -r %s ./input'\
116  % (node, './' + os.path.basename(mapper), './' + os.path.basename(reducer))
117  else :
118  if not reducer :
119  execstr = 'mpiexec -n %s -of-proc output ./kmrshell -m %s ./work'\
120  % (node, './' + os.path.basename(mapper))
121  else :
122  execstr = 'mpiexec -n %s -of-proc output ./kmrshell -m %s -r %s ./work'\
123  % (node, './' + os.path.basename(mapper), './' + os.path.basename(reducer))
124 
125 
126  # replace template keyword using parameter.
127  script = template % {'NODE': node, 'RSCTIME': rsctime, 'MAPPER': mapper, 'DATASTGIN': stginstr, 'DATASTGOUT': stgoutstr, 'EXEC': execstr, 'KMRHOME': kmrhome}
128 
129  # output script
130  if scrfile is None :
131  print(script)
132  else :
133  out = open(scrfile, "w")
134  print(script, file=out)
135  out.close()
136 
137 ## Selects job-scheduler.
138 # @param node number of node to execute.
139 # @param infile input file pathname.
140 # @param outfile output file prefix.
141 # @param indir directory path name that has input files.
142 # @param outdir directory path name that has result output files.
143 # @param rsctime resource time limit.
144 # @param mapper pathname of mapper program.
145 # @param reducer pathname of reducer program.
146 # @param multi multiple input file for one mapper process.
147 # @param sched scheduler.
148 # @param scrfile output script file name.
149 
150 def selectscheduler(node, infile, outfile, indir, outdir, rsctime, mapper, reducer, multi, sched, scrfile) :
151  if sched == 'K' :
152  k_scheduler(node, infile, outfile, indir, outdir, rsctime, mapper, reducer, multi, scrfile)
153  # for other schedulers...
154 
155 ## kmrgenscript main routine.
156 # It works on Python 2.4 or later.
157 
158 if __name__ == "__main__" :
159 
160  usage = "usage: %prog [options] -m mapper [-r reducer]"
161  parser = OptionParser(usage)
162 
163  parser.add_option("-e",
164  "--number-of-exec-node",
165  dest="node",
166  type="int",
167  help="number of execute node",
168  metavar="number",
169  default=1)
170 
171  parser.add_option("-p",
172  "--input-file-prefix",
173  dest="infile",
174  type="string",
175  help="input filename prefix",
176  metavar="'string'",
177  default='part')
178 
179  parser.add_option("-o",
180  "--outputfile",
181  dest="outfile",
182  type="string",
183  help="output filename prefix",
184  metavar="'string'",
185  default='output')
186 
187  parser.add_option("-d",
188  "--inputdir",
189  dest="indir",
190  type="string",
191  help="input directory",
192  metavar="'string'",
193  default='./')
194 
195  parser.add_option("-O",
196  "--outputdir",
197  dest="outdir",
198  type="string",
199  help="output directory",
200  metavar="'string'",
201  default='./')
202 
203  parser.add_option("-t",
204  "--resource-time",
205  dest="rsctime",
206  type="string",
207  help="resource time",
208  metavar="'string'",
209  default='00:10:00')
210 
211  parser.add_option("-m",
212  "--mapper",
213  dest="mapper",
214  type="string",
215  help="mapper path",
216  metavar="'string'")
217 
218  parser.add_option("-r",
219  "--reducer",
220  dest="reducer",
221  type="string",
222  help="reducer path",
223  metavar="'string'")
224 
225  parser.add_option("-S",
226  "--scheduler",
227  dest="sched",
228  type="string",
229  help="scheduler (default is 'K')",
230  metavar="'string'",
231  default='K')
232 
233  parser.add_option("-w",
234  "--write-scriptfile",
235  dest="scrfile",
236  type="string",
237  help="script filename",
238  metavar="'string'")
239 
240  parser.add_option("-M",
241  "--multi-input",
242  dest="multi",
243  action="store_true",
244  help="multi input files to one node",
245  default=False)
246 
247  parser.add_option("-f",
248  "--force",
249  dest="force",
250  action="store_true",
251  help="force option",
252  default=False)
253 
254  (options, args) = parser.parse_args()
255 
256  # check parameters.
257 
258  if len(args) > 1 :
259  parser.error("missing parameter")
260  sys.exit()
261 
262  if not options.mapper :
263  print("mapper not specified\n")
264  sys.exit()
265 
266  checkexist(options.indir)
267  checkdir(options.outdir, options.force)
268 
269  if options.multi :
270  if options.indir == "./" :
271  print("-M option needs -d (input directory) option.\n")
272  sys.exit()
273  files = os.listdir(options.indir)
274  if len(files) < options.node :
275  print('Node number is greater than number of files in %s.\n' % options.indir)
276  sys.exit()
277 
278  selectscheduler(options.node, options.infile, options.outfile,
279  options.indir, options.outdir, options.rsctime,
280  options.mapper, options.reducer, options.multi,
281  options.sched, options.scrfile)
282 
283 # Copyright (C) 2012-2018 RIKEN R-CCS
284 # This library is distributed WITHOUT ANY WARRANTY. This library can be
285 # redistributed and/or modified under the terms of the BSD 2-Clause License.