diff --git a/benchmark-driver/benchmark-run-kind.cc b/benchmark-driver/benchmark-run-kind.cc index 6897f9ca8d720483d59f784f8d8bae4cac62f97d..50885af700eec0d08889fef58503e84a3c32c2f8 100644 --- a/benchmark-driver/benchmark-run-kind.cc +++ b/benchmark-driver/benchmark-run-kind.cc @@ -2,7 +2,7 @@ // Copyright © 2021 Florian Schmaus #include "benchmark-run-kind.hpp" -#include <ios> +#include <string> namespace mazstab { auto operator<<(std::ostream& out, const BenchmarkRunKind& benchmark_run_kind) -> std::ostream& { diff --git a/benchmark-driver/benchmark-run-kind.hpp b/benchmark-driver/benchmark-run-kind.hpp index b3c8b36eb76f258d8d4b6e04e55ce54f6c06ef3f..05d4a63953563da69af604f92590a08f6d5141f1 100644 --- a/benchmark-driver/benchmark-run-kind.hpp +++ b/benchmark-driver/benchmark-run-kind.hpp @@ -3,7 +3,6 @@ #pragma once #include <istream> -#include <ostream> namespace mazstab { enum class BenchmarkRunKind { diff --git a/benchmark-runner/main/src/de/fau/cs/mazstab/Mazstab.scala b/benchmark-runner/main/src/de/fau/cs/mazstab/Mazstab.scala index d6419b5fbe1f57634e6779d88994eda1c905a13d..2ce27d3c4a4a3757eb94b4e7b3a86fb001642549 100644 --- a/benchmark-runner/main/src/de/fau/cs/mazstab/Mazstab.scala +++ b/benchmark-runner/main/src/de/fau/cs/mazstab/Mazstab.scala @@ -2,57 +2,63 @@ // Copyright © 2021 Florian Schmaus package de.fau.cs.mazstab -import java.nio.file.Path - import scala.collection._ import scala.jdk.CollectionConverters._ import net.jcazevedo.moultingyaml._ +import os._ -class MazstabContext(conf: MazstabConf) { +class MazstabContext(val conf: MazstabConf) { private val postProcessedDirectory = conf - .experimentDirectory() - .resolve("post-processed") - .resolve(Mazstab.getTimestamp) + .experimentDirectory() / "post-processed" / Mazstab.getTimestamp - def getPostProcessedDirectory() = mkdirIfRequired(postProcessedDirectory) + def getPostProcessedDirectory() = { + os.makeDir(postProcessedDirectory) + postProcessedDirectory + } private val rawDataDirectory = conf - .experimentDirectory() - .resolve("raw-data") + .experimentDirectory() / "raw-data" + + def getRawDataDirectory() = { + os.makeDir.all(rawDataDirectory) + rawDataDirectory + } + + def getExperimentDescriptionYaml(): Path = conf + .experimentDirectory() / "description.yaml" + + lazy val experimentDescription = { + import ExperimentDescriptionYamlProtocol._ + os.read(getExperimentDescriptionYaml()) + .parseYaml + .convertTo[ExperimentDescription] + } - def getRawDataDirectory() = mkdirIfRequired(rawDataDirectory) } object Mazstab { - implicit def nioPathToOsPath(nioPath: Path) = os.Path(nioPath) - def main(args: Array[String]): Unit = { val conf = new MazstabConf(args) + val context = new MazstabContext(conf) if (conf.subcommand != Some(conf.postProcess)) { val mazstabRepository = org.eclipse.jgit.storage.file.FileRepositoryBuilder - .create(conf.rootDirectory().toFile) + .create(conf.rootDirectory().toIO) val startupMessage = s"""MazStab starting" Experiment directory: ${conf.experimentDirectory()} MazStab root: ${conf.rootDirectory()} (${mazstabRepository.getBranch})""" println(startupMessage) - val experimentDirectory = conf.experimentDirectory().toFile - if (!experimentDirectory.isDirectory) { - val mkdirExperimentDirectoryCreated = experimentDirectory.mkdirs - if (!mkdirExperimentDirectoryCreated) - throw new Exception("Could not create " + experimentDirectory) - } + os.makeDir(conf.experimentDirectory()) val buildDir = buildMazstab(conf) - performBenchmark(buildDir, conf) + performBenchmark(buildDir, context) } - val context = new MazstabContext(conf) val processedResults = MazstabPostProcess(context) MazstabPgfPlots(context, processedResults) @@ -71,11 +77,10 @@ MazStab root: ${conf.rootDirectory()} (${mazstabRepository.getBranch})""" def buildMazstab(conf: MazstabConf): Path = { val buildDir = - conf.buildDirectory.getOrElse(conf.experimentDirectory().resolve("build")) + conf.buildDirectory.getOrElse(conf.experimentDirectory() / "build") val buildDirString = buildDir.toString - val buildDirFile = buildDir.toFile - val buildDirIsDirectory = buildDirFile.isDirectory - val buildDirContainsNinja = buildDir.resolve("build.ninja").toFile.isFile + val buildDirIsDirectory = buildDir.toIO.isDirectory + val buildDirContainsNinja = (buildDir / "build.ninja").toIO.isFile if (!buildDirIsDirectory || !buildDirContainsNinja) { // "meson setup" will also create the build directory if it does @@ -96,8 +101,8 @@ MazStab root: ${conf.rootDirectory()} (${mazstabRepository.getBranch})""" buildDir } - def performBenchmark(buildDir: Path, conf: MazstabConf): Unit = { - val benchmarkBinaries = buildDir.toFile.listFiles + def performBenchmark(buildDir: Path, context: MazstabContext): Unit = { + val benchmarkBinaries = buildDir.toIO.listFiles .filter(_.canExecute) .filterNot(_.isDirectory) // ammonite.Main().run( "benchmarks" -> benchmarks ) @@ -113,36 +118,34 @@ MazStab root: ${conf.rootDirectory()} (${mazstabRepository.getBranch})""" runtimeSystems += rts } - val experimentDirectory = conf.experimentDirectory() - + val conf = context.conf val threads = conf.threads() val experimentDescription = ExperimentDescription( benchmarks.to(collection.immutable.Set), runtimeSystems.to(collection.immutable.Set), threads ) - val experimentDescriptionYamlFile = - experimentDirectory.resolve("description.yaml") { + val experimentDescriptionYamlFile = context.getExperimentDescriptionYaml() + import ExperimentDescriptionYamlProtocol._ os.write( - os.Path(experimentDescriptionYamlFile), + experimentDescriptionYamlFile, experimentDescription.toYaml.prettyPrint ) } - val rawDataDir = experimentDirectory.resolve("raw-data") - rawDataDir.toFile.mkdir() + val rawDataDir = context.getRawDataDirectory() for (nthreads <- threads) { for (benchmark <- benchmarkBinaries) { val benchmarkName = benchmark.getName val outfileBasename = benchmarkName + "--" + nthreads - val outfileCsv = rawDataDir.resolve(outfileBasename + ".csv") - val outfileStdout = rawDataDir.resolve(outfileBasename + ".stdout") - val outfileStderr = rawDataDir.resolve(outfileBasename + ".stderr") + val outfileCsv = rawDataDir / (outfileBasename + ".csv") + val outfileStdout = rawDataDir / (outfileBasename + ".stdout") + val outfileStderr = rawDataDir / (outfileBasename + ".stderr") // format: off val benchmarkCommand = immutable.Seq( @@ -158,8 +161,8 @@ MazStab root: ${conf.rootDirectory()} (${mazstabRepository.getBranch})""" ) val benchmarkProcess = new java.lang.ProcessBuilder(benchmarkCommand: _*) - .redirectOutput(outfileStdout.toFile) - .redirectError(outfileStderr.toFile) + .redirectOutput(outfileStdout.toIO) + .redirectError(outfileStderr.toIO) .start benchmarkProcess.waitFor diff --git a/benchmark-runner/main/src/de/fau/cs/mazstab/MazstabConf.scala b/benchmark-runner/main/src/de/fau/cs/mazstab/MazstabConf.scala index b2074e47af500429c1c7fd793a3e358059bdc740..da3c4faf72aa24c28d21ddb027376329ae73afec 100644 --- a/benchmark-runner/main/src/de/fau/cs/mazstab/MazstabConf.scala +++ b/benchmark-runner/main/src/de/fau/cs/mazstab/MazstabConf.scala @@ -2,7 +2,7 @@ // Copyright © 2021 Florian Schmaus package de.fau.cs.mazstab -import java.nio.file.Path +import os._ import org.rogach.scallop._ @@ -33,33 +33,29 @@ object MazstabConf { case _ => throw new Exception(s"Invalid problem size: ${s}") } ) + + val osPathConverter = singleArgConverter[Path](s => toPath(s)) } class MazstabConf(arguments: Seq[String]) extends ScallopConf(arguments) { val rootDirectory = opt[Path]( name = "mazstab-root", required = true, - default = sys.env.get("MAZSTAB_ROOT").map(s => Path.of(s)) - ) + default = sys.env.get("MAZSTAB_ROOT").map(s => toPath(s)) + )(MazstabConf.osPathConverter) val experimentDirectory = opt[Path]( default = Some( - rootDirectory().resolve( - Path - .of( - "out", - Mazstab.getTimestamp - ) - ) + rootDirectory() / "out" / Mazstab.getTimestamp() ), name = "experiment-dir" - ) + )(MazstabConf.osPathConverter) val buildDirectory = opt[Path]( name = "build-dir", descr = "The MazStab build directory to use. If this directory already exists and if it contains a configured MazStab build, then it will be re-used" - ) + )(MazstabConf.osPathConverter) val problemSize = opt[ProblemSize.Value]( default = diff --git a/benchmark-runner/main/src/de/fau/cs/mazstab/MazstabPgfPlots.scala b/benchmark-runner/main/src/de/fau/cs/mazstab/MazstabPgfPlots.scala index 4230ffa18626aeed04cf74055ba12cac0992cf94..681fb69b5c5c724b6f601998d98cb0bfabffc633 100644 --- a/benchmark-runner/main/src/de/fau/cs/mazstab/MazstabPgfPlots.scala +++ b/benchmark-runner/main/src/de/fau/cs/mazstab/MazstabPgfPlots.scala @@ -3,6 +3,19 @@ package de.fau.cs.mazstab object MazstabPgfPlots { + val pgfPlotHeader = """ +\documentclass{standalone} +\input{common.tex} + +\begin{document} +\begin{tikzpicture} +""" + + val pgfPlotFooter = """ +\end{tikzpicture} +\end{document} +""" + def apply( context: MazstabContext, processedResults: Map[BenchmarkRunDescriptor, BenchmarkRunResult] diff --git a/benchmark-runner/main/src/de/fau/cs/mazstab/MazstabPostProcess.scala b/benchmark-runner/main/src/de/fau/cs/mazstab/MazstabPostProcess.scala index d95b244bb4d8228ee9100661f86927b9cac18532..a7970cba305cadec0a26c3f89a2d7cf7a3b30f52 100644 --- a/benchmark-runner/main/src/de/fau/cs/mazstab/MazstabPostProcess.scala +++ b/benchmark-runner/main/src/de/fau/cs/mazstab/MazstabPostProcess.scala @@ -31,8 +31,7 @@ object MazstabPostProcess { val processedResults = mutable.Map[BenchmarkRunDescriptor, BenchmarkRunResult]() - val rawDataDir = context.getRawDataDirectory - val csvFiles = rawDataDir.toFile.listFiles + val csvFiles = context.getRawDataDirectory.toIO.listFiles .filter(_.isFile) .filter(_.getName.endsWith(".csv")) @@ -68,6 +67,7 @@ object MazstabPostProcess { if (!previous.isEmpty) throw new Exception() } + // Convert mutable map to immutable using 'toMap'. processedResults.toMap } diff --git a/benchmark-runner/main/src/de/fau/cs/mazstab/package.scala b/benchmark-runner/main/src/de/fau/cs/mazstab/package.scala index a7d04eff52b714c7accdf780f84c55b340720605..577aecb51f3164e56e0e85614745491f2d386d90 100644 --- a/benchmark-runner/main/src/de/fau/cs/mazstab/package.scala +++ b/benchmark-runner/main/src/de/fau/cs/mazstab/package.scala @@ -2,15 +2,13 @@ // Copyright © 2021 Florian Schmaus package de.fau.cs -import java.nio.file.Path - package object mazstab { - def mkdirIfRequired(dir: Path): Path = { - val dirAsFile = dir.toFile - if (!dirAsFile.isDirectory) { - val created = dirAsFile.mkdirs - if (created) throw new Exception() + def toPath(path: String): os.Path = { + val nioPath = java.nio.file.Path.of(path) + if (nioPath.isAbsolute) { + os.Path(nioPath) + } else { + os.Path(nioPath, os.pwd) } - dir } }