diff --git a/toolflow/src/main/scala/com/minres/tgc/hammer/Main.scala b/toolflow/src/main/scala/com/minres/tgc/hammer/Main.scala index 0381f0c..3007fa4 100644 --- a/toolflow/src/main/scala/com/minres/tgc/hammer/Main.scala +++ b/toolflow/src/main/scala/com/minres/tgc/hammer/Main.scala @@ -32,10 +32,12 @@ object Main { logger.info(s"Executing subcommand ${c.name}") val tasks = c.getRequiredTasks logger.debug(s"Subcommand requires ${tasks.size} tasks") - logger.info(s"Validating tasks") - tasks.foreach(_.validate()) - logger.info(s"Executing tasks") - tasks.foreach(_.execute()) + try { + tasks.foreach(_.run()) + } catch { + case e: Exception => + logger.error(s"Error during task execution, see above!") + } case _ => logger.error(s"Found no subcommand, see help below") conf.printHelp() diff --git a/toolflow/src/main/scala/com/minres/tgc/hammer/options/BaseOption.scala b/toolflow/src/main/scala/com/minres/tgc/hammer/options/BaseOption.scala index 5414631..cc64743 100644 --- a/toolflow/src/main/scala/com/minres/tgc/hammer/options/BaseOption.scala +++ b/toolflow/src/main/scala/com/minres/tgc/hammer/options/BaseOption.scala @@ -7,7 +7,9 @@ import scala.compiletime.uninitialized trait BaseOption[T](using conv: ValueConverter[T]) extends ConfigElement { protected def createScallop(conf: ScallopConf, group: ScallopOptionGroup): ScallopOption[T] + protected[options] var scallop: ScallopOption[T] = uninitialized + def init(scallopConf: ScallopConf, group: ScallopOptionGroup): Unit = { scallop = createScallop(scallopConf, group) } @@ -15,10 +17,10 @@ trait BaseOption[T](using conv: ValueConverter[T]) extends ConfigElement { def default: () => Option[T] def get: Option[T] = scallop.toOption.orElse(default()) + def apply(): T = get.get - def getToolParameters: Seq[Shellable] = if (get.isDefined) Seq(s"$toolName", getToolArg) else Seq() + def getToolParameters: Seq[Shellable] = if (get.isDefined) Seq(s"$toolName", get.get.toString) else Seq() def toolName: String - def getToolArg: String = get.toString -} +} \ No newline at end of file diff --git a/toolflow/src/main/scala/com/minres/tgc/hammer/tasks/CopyTask.scala b/toolflow/src/main/scala/com/minres/tgc/hammer/tasks/CopyTask.scala index c74852b..311ecb4 100644 --- a/toolflow/src/main/scala/com/minres/tgc/hammer/tasks/CopyTask.scala +++ b/toolflow/src/main/scala/com/minres/tgc/hammer/tasks/CopyTask.scala @@ -2,7 +2,7 @@ package com.minres.tgc.hammer.tasks import os.* -case class CopyTask(from: Path, to: Path) extends Task { +case class CopyTask(from: Path, to: Path) extends TaskImpl[CopyTask] { override def validate(): Unit = { assert(isFile(from), "Input file does not exist") } diff --git a/toolflow/src/main/scala/com/minres/tgc/hammer/tasks/Task.scala b/toolflow/src/main/scala/com/minres/tgc/hammer/tasks/Task.scala index f6b1136..bef368b 100644 --- a/toolflow/src/main/scala/com/minres/tgc/hammer/tasks/Task.scala +++ b/toolflow/src/main/scala/com/minres/tgc/hammer/tasks/Task.scala @@ -3,10 +3,20 @@ package com.minres.tgc.hammer.tasks import com.minres.tgc.hammer.util.Logging import os.{Path, Shellable} -trait Task extends Logging[Task] { +import scala.reflect.ClassTag + +trait Task { def validate(): Unit def execute(): Unit + def run(): Unit = { + validate() + execute() + } +} + +trait TaskImpl[T <: Task : ClassTag] extends Task with Logging[T] { + def runExecutable(execPath: Path, args: Shellable*): os.CommandResult = { val command = s"$execPath ${args.flatMap(_.value).mkString(" ")}" os.proc("bash", "-c", command).call(stdout = os.Inherit) diff --git a/toolflow/src/main/scala/com/minres/tgc/hammer/tasks/TreenailTask.scala b/toolflow/src/main/scala/com/minres/tgc/hammer/tasks/TreenailTask.scala index e3c14fd..688c1a9 100644 --- a/toolflow/src/main/scala/com/minres/tgc/hammer/tasks/TreenailTask.scala +++ b/toolflow/src/main/scala/com/minres/tgc/hammer/tasks/TreenailTask.scala @@ -4,7 +4,7 @@ import com.minres.tgc.hammer.Global import com.minres.tgc.hammer.util.FileUtils.* import os.* -case class TreenailTask(coreDSLInput: Path, output: Path) extends Task { +case class TreenailTask(coreDSLInput: Path, output: Path) extends TaskImpl[TreenailTask] { private val EXECUTABLE = Global.TREENAIL / "app" / "build" / "install" / "app" / "bin" / "app" override def validate(): Unit = { diff --git a/toolflow/src/main/scala/com/minres/tgc/hammer/tasks/longnail/LongnailBaseTask.scala b/toolflow/src/main/scala/com/minres/tgc/hammer/tasks/longnail/LongnailBaseTask.scala index 936c9ab..e5f7c4a 100644 --- a/toolflow/src/main/scala/com/minres/tgc/hammer/tasks/longnail/LongnailBaseTask.scala +++ b/toolflow/src/main/scala/com/minres/tgc/hammer/tasks/longnail/LongnailBaseTask.scala @@ -2,10 +2,10 @@ package com.minres.tgc.hammer.tasks.longnail import com.minres.tgc.hammer.Global import com.minres.tgc.hammer.options.* -import com.minres.tgc.hammer.tasks.Task +import com.minres.tgc.hammer.tasks.{Task, TaskImpl} import os.{Path, isFile} -trait LongnailBaseTask extends Task { +trait LongnailBaseTask[T <: LongnailBaseTask[T]] extends TaskImpl[T] { protected val EXECUTABLE: os.Path = Global.LONGNAIL / "build" / "bin" / "longnail-opt" override def validate(): Unit = { diff --git a/toolflow/src/main/scala/com/minres/tgc/hammer/tasks/longnail/LongnailHLSTask.scala b/toolflow/src/main/scala/com/minres/tgc/hammer/tasks/longnail/LongnailHLSTask.scala index 92063a0..cdc5355 100644 --- a/toolflow/src/main/scala/com/minres/tgc/hammer/tasks/longnail/LongnailHLSTask.scala +++ b/toolflow/src/main/scala/com/minres/tgc/hammer/tasks/longnail/LongnailHLSTask.scala @@ -3,7 +3,7 @@ package com.minres.tgc.hammer.tasks.longnail import com.minres.tgc.hammer.util.FileUtils.* import os.* -class LongnailHLSTask(schedulingSolutionFile: Path, schedulingSelectionFile: Option[Path], outDirectory: Path) extends LongnailBaseTask { +class LongnailHLSTask(schedulingSolutionFile: Path, schedulingSelectionFile: Option[Path], outDirectory: Path) extends LongnailBaseTask[LongnailHLSTask] { override def validate(): Unit = { super.validate() assert(isMLIRFile(schedulingSolutionFile), "Scheduling solution file does not exist") diff --git a/toolflow/src/main/scala/com/minres/tgc/hammer/tasks/longnail/LongnailMergeTask.scala b/toolflow/src/main/scala/com/minres/tgc/hammer/tasks/longnail/LongnailMergeTask.scala index f1fb963..22c3887 100644 --- a/toolflow/src/main/scala/com/minres/tgc/hammer/tasks/longnail/LongnailMergeTask.scala +++ b/toolflow/src/main/scala/com/minres/tgc/hammer/tasks/longnail/LongnailMergeTask.scala @@ -3,7 +3,7 @@ package com.minres.tgc.hammer.tasks.longnail import com.minres.tgc.hammer.util.FileUtils.* import os.* -class LongnailMergeTask(mlirFiles: Seq[Path], concatMLIR: Path, mergedMLIR: Path) extends LongnailBaseTask { +class LongnailMergeTask(mlirFiles: Seq[Path], concatMLIR: Path, mergedMLIR: Path) extends LongnailBaseTask[LongnailMergeTask] { override def validate(): Unit = { super.validate() mlirFiles.foreach(f => assert(f.isMLIRFile, s"Input file $f does not exist or is not an MLIR file")) diff --git a/toolflow/src/main/scala/com/minres/tgc/hammer/tasks/longnail/LongnailScheduleTask.scala b/toolflow/src/main/scala/com/minres/tgc/hammer/tasks/longnail/LongnailScheduleTask.scala index 836f60b..eee382d 100644 --- a/toolflow/src/main/scala/com/minres/tgc/hammer/tasks/longnail/LongnailScheduleTask.scala +++ b/toolflow/src/main/scala/com/minres/tgc/hammer/tasks/longnail/LongnailScheduleTask.scala @@ -4,7 +4,7 @@ import com.minres.tgc.hammer.tasks.longnail.LongnailBaseTask import com.minres.tgc.hammer.util.FileUtils.isMLIRFile import os.* -class LongnailScheduleTask(isaxMLIR: Path, coreDatasheet: Path, params: SchedulingParameters) extends LongnailBaseTask { +class LongnailScheduleTask(isaxMLIR: Path, coreDatasheet: Path, params: SchedulingParameters) extends LongnailBaseTask[LongnailScheduleTask] { override def validate(): Unit = { super.validate() diff --git a/toolflow/src/main/scala/com/minres/tgc/hammer/util/Logging.scala b/toolflow/src/main/scala/com/minres/tgc/hammer/util/Logging.scala index f48f770..283fbb6 100644 --- a/toolflow/src/main/scala/com/minres/tgc/hammer/util/Logging.scala +++ b/toolflow/src/main/scala/com/minres/tgc/hammer/util/Logging.scala @@ -8,6 +8,9 @@ trait Logging[T: ClassTag] { protected val log: Logger = Logger[T] protected def assert(boolean: Boolean, msg: String): Unit = { - if (!boolean) log.error(msg) + if (!boolean) { + log.error(msg) + throw new Exception() + } } } diff --git a/toolflow/src/main/scala/com/minres/tgc/hammer/util/ValidationBase.scala b/toolflow/src/main/scala/com/minres/tgc/hammer/util/ValidationBase.scala index da566fa..58cfb94 100644 --- a/toolflow/src/main/scala/com/minres/tgc/hammer/util/ValidationBase.scala +++ b/toolflow/src/main/scala/com/minres/tgc/hammer/util/ValidationBase.scala @@ -1,7 +1,5 @@ package com.minres.tgc.hammer.util -import org.rogach.scallop.ScallopOption - trait ValidationBase[O[_]] { def check[T](option: O[T])(check: Checker[T]): Unit def checkPred[T, U](condOpt: O[U], cond: U => Boolean)(option: O[T])(check: Checker[T]): Unit