def command(self, job): ret = ['srun'] if job.name: ret += ['--job-name=%s' % job.name] if job.time_limit: h, m, s = seconds_to_hms(job.time_limit.total_seconds()) ret += ['--time=%d:%d:%d' % (h, m, s)] if job.stdout: ret += ['--output=%s' % job.stdout] if job.stderr: ret += ['--error=%s' % job.stderr] if job.num_tasks: ret += ['--ntasks=%s' % str(job.num_tasks)] if job.num_tasks_per_node: ret += ['--ntasks-per-node=%s' % str(job.num_tasks_per_node)] if job.num_tasks_per_core: ret += ['--ntasks-per-core=%s' % str(job.num_tasks_per_core)] if job.num_tasks_per_socket: ret += ['--ntasks-per-socket=%s' % str(job.num_tasks_per_socket)] if job.num_cpus_per_task: ret += ['--cpus-per-task=%s' % str(job.num_cpus_per_task)] if job.sched_partition: ret += ['--partition=%s' % str(job.sched_partition)] if job.sched_exclusive_access: ret += ['--exclusive'] if job.use_smt is not None: hint = 'multithread' if job.use_smt else 'nomultithread' ret += ['--hint=%s' % hint] if job.sched_partition: ret += ['--partition=%s' % str(job.sched_partition)] if job.sched_account: ret += ['--account=%s' % str(job.sched_account)] if job.sched_nodelist: ret += ['--nodelist=%s' % str(job.sched_nodelist)] if job.sched_exclude_nodelist: ret += ['--exclude=%s' % str(job.sched_exclude_nodelist)] for opt in job.options: if opt.startswith('#'): continue ret.append(opt) return ret
def emit_preamble(self, job): preamble = [ self._format_option(job.name, '--job-name="{0}"'), self._format_option(job.num_tasks, '--ntasks={0}'), self._format_option(job.num_tasks_per_node, '--ntasks-per-node={0}'), self._format_option(job.num_tasks_per_core, '--ntasks-per-core={0}'), self._format_option(job.num_tasks_per_socket, '--ntasks-per-socket={0}'), self._format_option(job.num_cpus_per_task, '--cpus-per-task={0}'), self._format_option(job.sched_partition, '--partition={0}'), self._format_option(job.sched_account, '--account={0}'), self._format_option(job.sched_nodelist, '--nodelist={0}'), self._format_option(job.sched_exclude_nodelist, '--exclude={0}'), self._format_option(job.sched_reservation, '--reservation={0}') ] # Slurm replaces '%a' by the corresponding SLURM_ARRAY_TASK_ID outfile_fmt = '--output={0}' + ('_%a' if self.is_array(job) else '') errfile_fmt = '--error={0}' + ('_%a' if self.is_array(job) else '') preamble += [self._format_option(job.stdout, outfile_fmt), self._format_option(job.stderr, errfile_fmt)] if job.time_limit is not None: h, m, s = seconds_to_hms(job.time_limit.total_seconds()) preamble.append( self._format_option('%d:%d:%d' % (h, m, s), '--time={0}') ) if job.sched_exclusive_access: preamble.append( self._format_option(job.sched_exclusive_access, '--exclusive') ) if job.use_smt is None: hint = None else: hint = 'multithread' if job.use_smt else 'nomultithread' for opt in job.sched_access: preamble.append('%s %s' % (self._prefix, opt)) preamble.append(self._format_option(hint, '--hint={0}')) prefix_patt = re.compile(r'(#\w+)') for opt in job.options: if not prefix_patt.match(opt): preamble.append('%s %s' % (self._prefix, opt)) else: preamble.append(opt) # Filter out empty statements before returning return list(filter(None, preamble))
def emit_preamble(self, job): preamble = [ self._format_option('-N "%s"' % job.name), self._format_option('-o %s' % job.stdout), self._format_option('-e %s' % job.stderr), ] if job.time_limit is not None: h, m, s = seconds_to_hms(job.time_limit) preamble.append( self._format_option('-l walltime=%d:%d:%d' % (h, m, s))) preamble += self._emit_lselect_option(job) # PBS starts the job in the home directory by default preamble.append('cd %s' % job.workdir) return preamble
def emit_preamble(self, job): # The job name is a string of up to 15 alphanumeric characters # where the first character is alphabetic job_name = toalphanum(job.name)[:15] preamble = [ self._format_option(f'-N {job_name}'), self._format_option(f'-o {job.stdout}'), self._format_option(f'-e {job.stderr}'), ] if job.time_limit is not None: h, m, s = seconds_to_hms(job.time_limit) preamble.append( self._format_option('-l walltime=%d:%d:%d' % (h, m, s))) preamble += self._emit_lselect_option(job) # PBS starts the job in the home directory by default preamble.append(f'cd {job.workdir}') return preamble
def emit_preamble(self, job): preamble = [ self._format_option(f'-N "{job.name}"'), self._format_option(f'-o {job.stdout}'), self._format_option(f'-e {job.stderr}'), self._format_option(f'-wd {job.workdir}') ] if job.time_limit is not None: h, m, s = seconds_to_hms(job.time_limit) preamble.append( self._format_option(f'-l h_rt=%d:%d:%d' % (h, m, s))) # Emit the rest of the options options = job.options + job.cli_options for opt in options: if opt.startswith('#'): preamble.append(opt) else: preamble.append(self._format_option(opt)) return preamble
def emit_preamble(self, job): # host is de-facto nodes and core is number of cores requested per node # number of sockets can also be specified using cpu={num_sockets} tasks_opt = '-l /host={num_nodes}/core={num_tasks_per_node}' # Same reason as oarsub, we give full path to output and error files to # avoid writing them in the working dir preamble = [ self._format_option(f'-n "{job.name}"'), self._format_option(f'-O {job.stdout}'), self._format_option(f'-E {job.stderr}'), ] if job.time_limit is not None: h, m, s = seconds_to_hms(job.time_limit) tasks_opt += ',walltime=%d:%d:%d' % (h, m, s) # Get number of nodes in the reservation num_tasks_per_node = job.num_tasks_per_node or 1 num_nodes = job.num_tasks // num_tasks_per_node # Emit main resource reservation option options = [ tasks_opt.format( num_nodes=num_nodes, num_tasks_per_node=num_tasks_per_node, ) ] # Emit the rest of the options options += job.sched_access + job.options + job.cli_options for opt in options: if opt.startswith('#'): preamble.append(opt) else: preamble.append(self._format_option(opt)) return preamble
def emit_preamble(self, job): preamble = [ self._format_option(job.name, '--job-name="{0}"'), self._format_option(job.num_tasks, '--ntasks={0}'), self._format_option(job.num_tasks_per_node, '--ntasks-per-node={0}'), self._format_option(job.num_tasks_per_core, '--ntasks-per-core={0}'), self._format_option(job.num_tasks_per_socket, '--ntasks-per-socket={0}'), self._format_option(job.num_cpus_per_task, '--cpus-per-task={0}'), ] # Determine if job refers to a Slurm job array, by looking into the # job.options and job.cli_options jobarr_parser = ArgumentParser() jobarr_parser.add_argument('-a', '--array') parsed_args, _ = jobarr_parser.parse_known_args(job.options + job.cli_options) if parsed_args.array: job._is_array = True self.log('Slurm job is a job array') # Slurm replaces '%a' by the corresponding SLURM_ARRAY_TASK_ID outfile_fmt = '--output={0}' + ('_%a' if job.is_array else '') errfile_fmt = '--error={0}' + ('_%a' if job.is_array else '') preamble += [ self._format_option(job.stdout, outfile_fmt), self._format_option(job.stderr, errfile_fmt) ] if job.time_limit is not None: h, m, s = seconds_to_hms(job.time_limit) preamble.append( self._format_option('%d:%d:%d' % (h, m, s), '--time={0}')) if job.exclusive_access: preamble.append( self._format_option(job.exclusive_access, '--exclusive')) if self._use_nodes_opt: num_nodes = job.num_tasks // job.num_tasks_per_node preamble.append(self._format_option(num_nodes, '--nodes={0}')) if job.use_smt is None: hint = None else: hint = 'multithread' if job.use_smt else 'nomultithread' for opt in job.sched_access: if not opt.strip().startswith(('-C', '--constraint')): preamble.append('%s %s' % (self._prefix, opt)) constraints = [] constraint_parser = ArgumentParser() constraint_parser.add_argument('-C', '--constraint') parsed_options, _ = constraint_parser.parse_known_args( job.sched_access) if parsed_options.constraint: constraints.append(parsed_options.constraint.strip()) # NOTE: Here last of the passed --constraint job options is taken # into account in order to respect the behavior of slurm. parsed_options, _ = constraint_parser.parse_known_args(job.options + job.cli_options) if parsed_options.constraint: constraints.append(parsed_options.constraint.strip()) if constraints: preamble.append( self._format_option('&'.join(constraints), '--constraint={0}')) preamble.append(self._format_option(hint, '--hint={0}')) prefix_patt = re.compile(r'(#\w+)') for opt in job.options + job.cli_options: if opt.strip().startswith(('-C', '--constraint')): # Constraints are already processed continue if not prefix_patt.match(opt): preamble.append('%s %s' % (self._prefix, opt)) else: preamble.append(opt) # Filter out empty statements before returning return list(filter(None, preamble))