2010-06-15 12:43:46 +08:00
|
|
|
package org.broadinstitute.sting.queue.engine
|
|
|
|
|
|
2010-08-10 00:42:48 +08:00
|
|
|
import org.broadinstitute.sting.queue.function.{CommandLineFunction, DispatchWaitFunction}
|
|
|
|
|
import org.broadinstitute.sting.queue.util.{IOUtils, LsfJob, Logging}
|
2010-06-15 12:43:46 +08:00
|
|
|
|
2010-08-10 00:42:48 +08:00
|
|
|
/**
|
|
|
|
|
* Runs jobs on an LSF compute cluster.
|
|
|
|
|
*/
|
2010-08-12 05:58:26 +08:00
|
|
|
class LsfJobRunner extends DispatchJobRunner with Logging {
|
2010-08-10 00:42:48 +08:00
|
|
|
type DispatchJobType = LsfJob
|
2010-06-15 12:43:46 +08:00
|
|
|
|
2010-08-10 00:42:48 +08:00
|
|
|
/**
|
|
|
|
|
* Dispatches the function on the LSF cluster.
|
|
|
|
|
* @param function Command to run.
|
|
|
|
|
* @param qGraph graph that holds the job, and if this is a dry run.
|
|
|
|
|
*/
|
2010-08-12 05:58:26 +08:00
|
|
|
def run(function: CommandLineFunction, qGraph: QGraph) = {
|
2010-08-10 00:42:48 +08:00
|
|
|
val job = new LsfJob
|
|
|
|
|
job.name = function.jobName
|
|
|
|
|
job.outputFile = function.jobOutputFile
|
|
|
|
|
job.errorFile = function.jobErrorFile
|
|
|
|
|
job.project = function.jobProject
|
|
|
|
|
job.queue = function.jobQueue
|
|
|
|
|
job.command = function.commandLine
|
2010-06-15 12:43:46 +08:00
|
|
|
|
2010-08-10 00:42:48 +08:00
|
|
|
if (!IOUtils.CURRENT_DIR.getCanonicalFile.equals(function.commandDirectory))
|
|
|
|
|
job.workingDir = function.commandDirectory
|
|
|
|
|
|
|
|
|
|
if (function.jobRestartable)
|
|
|
|
|
job.extraBsubArgs :+= "-r"
|
2010-06-15 12:43:46 +08:00
|
|
|
|
|
|
|
|
if (function.memoryLimit.isDefined)
|
2010-08-10 00:42:48 +08:00
|
|
|
job.extraBsubArgs ++= List("-R", "rusage[mem=" + function.memoryLimit.get + "]")
|
2010-06-15 12:43:46 +08:00
|
|
|
|
2010-09-20 08:16:53 +08:00
|
|
|
if ( ! function.commandLine.contains("mkdir")) // wild hack -- ignore mkdirs ??
|
|
|
|
|
job.postExecCommand = function.doneOutputs.foldLeft("python /humgen/gsa-scr1/chartl/sting/python/lsf_post_touch.py ")((b,a) => b + a.getAbsolutePath+" ")
|
|
|
|
|
// hacky trailing space, so sue me -- CH
|
|
|
|
|
|
2010-08-10 00:42:48 +08:00
|
|
|
val previous: Iterable[LsfJob] =
|
2010-06-29 03:52:17 +08:00
|
|
|
if (function.isInstanceOf[DispatchWaitFunction]) {
|
2010-08-10 00:42:48 +08:00
|
|
|
job.waitForCompletion = true
|
|
|
|
|
getWaitJobs(qGraph)
|
2010-06-29 03:52:17 +08:00
|
|
|
} else {
|
|
|
|
|
previousJobs(function, qGraph)
|
|
|
|
|
}
|
2010-09-20 08:16:53 +08:00
|
|
|
|
2010-08-10 00:42:48 +08:00
|
|
|
mountCommand(function) match {
|
|
|
|
|
case Some(command) => job.preExecCommand = command
|
|
|
|
|
case None => /* ignore */
|
|
|
|
|
}
|
2010-06-15 12:43:46 +08:00
|
|
|
|
2010-08-10 00:42:48 +08:00
|
|
|
if (previous.size > 0)
|
2010-08-25 23:18:02 +08:00
|
|
|
job.extraBsubArgs ++= List("-w", dependencyExpression(previous,
|
|
|
|
|
function.jobRunOnlyIfPreviousSucceed, qGraph.dryRun))
|
2010-06-15 12:43:46 +08:00
|
|
|
|
2010-06-29 03:52:17 +08:00
|
|
|
addJob(function, qGraph, job, previous)
|
2010-06-15 12:43:46 +08:00
|
|
|
|
2010-06-23 02:39:20 +08:00
|
|
|
if (logger.isDebugEnabled) {
|
2010-08-10 00:42:48 +08:00
|
|
|
logger.debug(function.commandDirectory + " > " + job.bsubCommand.mkString(" "))
|
2010-06-23 02:39:20 +08:00
|
|
|
} else {
|
2010-08-10 00:42:48 +08:00
|
|
|
logger.info(job.bsubCommand.mkString(" "))
|
2010-06-23 02:39:20 +08:00
|
|
|
}
|
2010-06-15 12:43:46 +08:00
|
|
|
|
|
|
|
|
if (!qGraph.dryRun)
|
2010-08-10 00:42:48 +08:00
|
|
|
job.run
|
2010-06-15 12:43:46 +08:00
|
|
|
}
|
|
|
|
|
|
2010-08-10 00:42:48 +08:00
|
|
|
/**
|
|
|
|
|
* Returns the dependency expression for the prior jobs.
|
|
|
|
|
* @param jobs Previous jobs this job is dependent on.
|
|
|
|
|
* @param runOnSuccess Run the job only if the previous jobs succeed.
|
2010-08-25 23:18:02 +08:00
|
|
|
* @param dryRun If the current run is a dry run.
|
2010-08-10 00:42:48 +08:00
|
|
|
* @return The dependency expression for the prior jobs.
|
|
|
|
|
*/
|
2010-08-25 23:18:02 +08:00
|
|
|
private def dependencyExpression(jobs: Iterable[LsfJob],
|
|
|
|
|
runOnSuccess: Boolean, dryRun: Boolean) = {
|
|
|
|
|
val jobIds = if (dryRun)
|
|
|
|
|
jobs.toSet[LsfJob].map("\"" + _.name + "\"")
|
|
|
|
|
else
|
|
|
|
|
jobs.toSet[LsfJob].map(_.bsubJobId)
|
|
|
|
|
|
2010-08-10 00:42:48 +08:00
|
|
|
if (runOnSuccess)
|
2010-08-20 07:42:06 +08:00
|
|
|
jobIds.mkString("done(", ") && done(", ")")
|
2010-08-10 00:42:48 +08:00
|
|
|
else
|
2010-08-20 07:42:06 +08:00
|
|
|
jobIds.mkString("ended(", ") && ended(", ")")
|
2010-06-15 12:43:46 +08:00
|
|
|
}
|
|
|
|
|
}
|