| /******************************************************************************* |
| * Copyright (c) 2010 University of Illinois All rights reserved. This program |
| * and the accompanying materials are made available under the terms of the |
| * Eclipse Public License v1.0 which accompanies this distribution, and is |
| * available at http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Albert L. Rossi - design and implementation |
| ******************************************************************************/ |
| package org.eclipse.ptp.rm.pbs.core.templates; |
| |
| import java.util.Arrays; |
| import java.util.Comparator; |
| import java.util.Map; |
| import java.util.Properties; |
| |
| import org.eclipse.ptp.core.attributes.IAttributeDefinition; |
| import org.eclipse.ptp.core.attributes.StringAttributeDefinition; |
| import org.eclipse.ptp.rm.pbs.core.IPBSNonNLSConstants; |
| import org.eclipse.ptp.rm.pbs.core.attributes.IPBSJobAttributeData; |
| |
| /** |
| * Provides the method for taking attribute definitions and qsub flags and |
| * turning them into the full base template. |
| * |
| * @author arossi |
| * @since 5.0 |
| * |
| */ |
| public abstract class PBSBaseAttributeToTemplateConverter implements IPBSAttributeToTemplateConverter, IPBSNonNLSConstants { |
| |
| private static class AttributeNameSorter<T> implements Comparator<String> { |
| public int compare(String s1, String s2) { |
| if (TAG_QUEUE.equals(s1)) |
| return -1; |
| if (TAG_QUEUE.equals(s2)) |
| return 1; |
| return s1.compareTo(s2); |
| } |
| } |
| |
| private static final String[] HEADER = { "#!/bin/bash", //$NON-NLS-1$ |
| ZEROSTR, "#####################################################################", //$NON-NLS-1$ |
| "## Template for PBS Batch Script Generated by PBS Resource Manager",//$NON-NLS-1$ |
| "## ",//$NON-NLS-1$ |
| "## This template contains all the Job Attributes recognized as valid",//$NON-NLS-1$ |
| "## by a given PBS proxy instance.",//$NON-NLS-1$ |
| "## ",//$NON-NLS-1$ |
| "## Placeholders (@NAME@) are included for the PBS Job Attribute ",//$NON-NLS-1$ |
| "## names as specified by qsub, plus the following internal variables:",//$NON-NLS-1$ |
| "##",//$NON-NLS-1$ |
| "## - env : place for defining extra environment",//$NON-NLS-1$ |
| "## variables (NB: should not be removed)",//$NON-NLS-1$ |
| "## - prependedBash : dynamically change arbitrary bash ",//$NON-NLS-1$ |
| "## commands which should precede the ",//$NON-NLS-1$ |
| "## execution of the main application code",//$NON-NLS-1$ |
| "## - mpiCommand mpiOptions : run under MPI",//$NON-NLS-1$ |
| "## - executablePath progArgs : the actual application",//$NON-NLS-1$ |
| "## - postpendedBash : dynamically change arbitrary bash ",//$NON-NLS-1$ |
| "## commands which should follow the ",//$NON-NLS-1$ |
| "## execution of the main application code",//$NON-NLS-1$ |
| "##",//$NON-NLS-1$ |
| "## A template can also directly contain arbitrary shell scripting (not ",//$NON-NLS-1$ |
| "## to be replaced via the 'prepended' and 'postpended' placeholders);",//$NON-NLS-1$ |
| "## these lines will remain fixed and will not be exposed through",//$NON-NLS-1$ |
| "## the Launch Tab for modification (they can however be altered by ",//$NON-NLS-1$ |
| "## using the Resource Manager Properties \"Edit\" Tab).",//$NON-NLS-1$ |
| "##",//$NON-NLS-1$ |
| "## NOTE: We advise removing either the ncpus or the nodes resource,",//$NON-NLS-1$ |
| "## depending on the PBS configuration (nodes is more common);",//$NON-NLS-1$ |
| "## otherwise, the correct value must be set on both redundantly",//$NON-NLS-1$ |
| "## in order for the MPI computation to be correct (and ",//$NON-NLS-1$ |
| "## some systems might reject a script with both set).",//$NON-NLS-1$ |
| "#####################################################################"//$NON-NLS-1$ |
| }; |
| |
| private static final String[] FOOTER = { ENV_PLACEHOLDER, PRECMD_PLACEHOLDER, CHGDIR_CMD, |
| MPICMD_PLACEHOLDER + SP + MPIOPT_PLACEHOLDER + SP + EXECMD_PLACEHOLDER + SP + PRARGS_PLACEHOLDER, PSTCMD_PLACEHOLDER }; |
| |
| private static AttributeNameSorter<String> sorter = new AttributeNameSorter<String>(); |
| |
| protected IPBSJobAttributeData data; |
| protected IAttributeDefinition<?, ?, ?>[] defs; |
| |
| public String generateFullBatchScriptTemplate() throws Throwable { |
| return generateBaseTemplate(false); |
| } |
| |
| public String generateMinBatchScriptTemplate() throws Throwable { |
| return generateBaseTemplate(true); |
| } |
| |
| public IPBSJobAttributeData getData() { |
| return data; |
| } |
| |
| public void initialize() throws Throwable { |
| initializeInternal(); |
| addInternalDefinitions(); |
| } |
| |
| public void setAttributeDefinitions(IAttributeDefinition<?, ?, ?>[] defs) { |
| this.defs = defs; |
| } |
| |
| protected abstract void initializeInternal() throws Throwable; |
| |
| /* |
| * Non-standard attribute definitions used for internal processing of the |
| * batch template. |
| */ |
| private void addInternalDefinitions() throws Throwable { |
| Map<String, IAttributeDefinition<?, ?, ?>> definitions = data.getAttributeDefinitionMap(); |
| Properties ttips = data.getToolTips(); |
| if (definitions == null || ttips == null) |
| return; |
| definitions.put(TAG_MPIOPT, new StringAttributeDefinition(TAG_MPIOPT, TAG_MPIOPT, ZEROSTR, true, MPIOPT_DEFAULT)); |
| ttips.setProperty(TAG_MPIOPT, TAG_INTERNAL); |
| definitions.put(TAG_SCRIPT, new StringAttributeDefinition(TAG_SCRIPT, TAG_SCRIPT, ZEROSTR, true, null)); |
| ttips.setProperty(TAG_SCRIPT, TAG_INTERNAL); |
| definitions.put(TAG_MPICMD, new StringAttributeDefinition(TAG_MPICMD, TAG_MPICMD, ZEROSTR, true, MPICMD_DEFAULT)); |
| ttips.setProperty(TAG_MPICMD, TAG_INTERNAL); |
| definitions.put(TAG_PRECMD, new StringAttributeDefinition(TAG_PRECMD, TAG_PRECMD, ZEROSTR, true, null)); |
| ttips.setProperty(TAG_PRECMD, TAG_INTERNAL); |
| definitions.put(TAG_PSTCMD, new StringAttributeDefinition(TAG_PSTCMD, TAG_PSTCMD, ZEROSTR, true, null)); |
| ttips.setProperty(TAG_PSTCMD, TAG_INTERNAL); |
| } |
| |
| /* |
| * Composes the flag translations into the space between the header and |
| * footer of the template file. |
| * |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ptp.rm.pbs.ui.IPBSAttributeToTemplateConverter# |
| * generateFullBatchScriptTemplate() |
| */ |
| private String generateBaseTemplate(boolean minimal) throws Throwable { |
| Properties flags = data.getPBSQsubFlags(); |
| if (flags == null) |
| return null; |
| |
| Map<String, String> minSet = data.getMinSet(); |
| |
| String[] sorted = flags.keySet().toArray(new String[0]); |
| Arrays.sort(sorted, sorter); |
| |
| StringBuffer template = new StringBuffer(); |
| |
| for (int i = 0; i < HEADER.length; i++) |
| template.append(HEADER[i]).append(REMOTE_LINE_SEP); |
| |
| for (int i = 0; i < sorted.length; i++) |
| if (!minimal || minSet.containsKey(sorted[i])) { |
| String flag = flags.getProperty(sorted[i]); |
| template.append(PBSDIRECTIVE).append(flag).append(MARKER).append(sorted[i]).append(MARKER).append(REMOTE_LINE_SEP); |
| } |
| |
| for (int i = 0; i < FOOTER.length; i++) |
| template.append(FOOTER[i]).append(REMOTE_LINE_SEP); |
| |
| return template.toString(); |
| } |
| |
| public static Comparator<String> getSorter() { |
| return sorter; |
| } |
| } |