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-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-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)
|
|
|
|
|
job.extraBsubArgs ++= List("-w", dependencyExpression(previous, function.jobRunOnlyIfPreviousSucceed))
|
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.
|
|
|
|
|
* @return The dependency expression for the prior jobs.
|
|
|
|
|
*/
|
|
|
|
|
private def dependencyExpression(jobs: Iterable[LsfJob], runOnSuccess: Boolean) = {
|
2010-08-20 07:42:06 +08:00
|
|
|
val jobIds = 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
|
|
|
}
|
|
|
|
|
}
|