summaryrefslogtreecommitdiff
path: root/opendc-experiments/opendc-experiments-greenifier/src/main/kotlin
diff options
context:
space:
mode:
authorDante Niewenhuis <d.niewenhuis@hotmail.com>2024-03-19 20:26:04 +0100
committerGitHub <noreply@github.com>2024-03-19 20:26:04 +0100
commitdff30fa60809c018101052f395b09cf17cb83ccb (patch)
tree2c5f67b9424547061aaa0c6b6b85af9a125ec263 /opendc-experiments/opendc-experiments-greenifier/src/main/kotlin
parent960b3d8a13c67ac4b7f479d5764b0b618fc9ea09 (diff)
Scenario and Portfolio update (#209)
* Initial commit * Implemented a new systems of defining and running scenarios / portfolios. Scenarios and Portfolios can now be defined using JSON files similar to topologies. This allows user to define experiments without changing any KotLin code. * Ran spotlessApply
Diffstat (limited to 'opendc-experiments/opendc-experiments-greenifier/src/main/kotlin')
-rw-r--r--opendc-experiments/opendc-experiments-greenifier/src/main/kotlin/org/opendc/experiments/greenifier/GreenifierCli.kt158
-rw-r--r--opendc-experiments/opendc-experiments-greenifier/src/main/kotlin/org/opendc/experiments/greenifier/GreenifierPortfolio.kt62
-rw-r--r--opendc-experiments/opendc-experiments-greenifier/src/main/kotlin/org/opendc/experiments/greenifier/GreenifierRunner.kt105
3 files changed, 0 insertions, 325 deletions
diff --git a/opendc-experiments/opendc-experiments-greenifier/src/main/kotlin/org/opendc/experiments/greenifier/GreenifierCli.kt b/opendc-experiments/opendc-experiments-greenifier/src/main/kotlin/org/opendc/experiments/greenifier/GreenifierCli.kt
deleted file mode 100644
index 93557500..00000000
--- a/opendc-experiments/opendc-experiments-greenifier/src/main/kotlin/org/opendc/experiments/greenifier/GreenifierCli.kt
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (c) 2022 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-@file:JvmName("GreenifierCli")
-
-package org.opendc.experiments.greenifier
-
-import com.github.ajalt.clikt.core.CliktCommand
-import com.github.ajalt.clikt.parameters.arguments.argument
-import com.github.ajalt.clikt.parameters.arguments.default
-import com.github.ajalt.clikt.parameters.options.associate
-import com.github.ajalt.clikt.parameters.options.default
-import com.github.ajalt.clikt.parameters.options.defaultLazy
-import com.github.ajalt.clikt.parameters.options.flag
-import com.github.ajalt.clikt.parameters.options.option
-import com.github.ajalt.clikt.parameters.types.choice
-import com.github.ajalt.clikt.parameters.types.file
-import com.github.ajalt.clikt.parameters.types.int
-import com.github.ajalt.clikt.parameters.types.long
-import me.tongfei.progressbar.ProgressBarBuilder
-import me.tongfei.progressbar.ProgressBarStyle
-import org.opendc.experiments.base.portfolio.model.Scenario
-import java.io.File
-import java.util.concurrent.ForkJoinPool
-import java.util.stream.LongStream
-
-/**
- * Main entrypoint of the application.
- */
-fun main(args: Array<String>): Unit = GreenifierCommand().main(args)
-
-/**
- * Represents the command for the Greenifier experiments.
- */
-internal class GreenifierCommand : CliktCommand(name = "greenifier") {
- /**
- * The path to the environment directory.
- */
- private val envPath by option("--env-path", help = "path to environment directory")
- .file(canBeDir = true, canBeFile = false)
- .defaultLazy { File("input/environments") }
-
- /**
- * The path to the trace directory.
- */
- private val tracePath by option("--trace-path", help = "path to trace directory")
- .file(canBeDir = true, canBeFile = false)
- .defaultLazy { File("input/traces") }
-
- /**
- * The path to the experiment output.
- */
- private val outputPath by option("-O", "--output", help = "path to experiment output")
- .file(canBeDir = true, canBeFile = false)
- .defaultLazy { File("output") }
-
- /**
- * Disable writing output.
- */
- private val disableOutput by option("--disable-output", help = "disable output").flag()
-
- /**
- * The number of threads to use for parallelism.
- */
- private val parallelism by option("-p", "--parallelism", help = "number of worker threads")
- .int()
- .default(Runtime.getRuntime().availableProcessors() - 1)
-
- /**
- * The number of repeats.
- */
- private val repeats by option("-r", "--repeats", help = "number of repeats")
- .int()
- .default(128)
-
- /**
- * The seed for seeding the random instances.
- */
- private val seed by option("-s", "--seed", help = "initial seed for randomness")
- .long()
- .default(0)
-
- /**
- * The portfolio to replay.
- */
- private val portfolio by argument(help = "portfolio to replay")
- .choice(
- "greenifier" to { GreenifierPortfolio() },
- )
- .default({ GreenifierPortfolio() })
-
- /**
- * The base partitions to use for the invocation
- */
- private val basePartitions: Map<String, String> by option("-P", "--base-partitions").associate()
-
- override fun run() {
- val runner = GreenifierRunner(envPath, tracePath, outputPath.takeUnless { disableOutput })
- val scenarios = portfolio().scenarios.toList()
-
- val pool = ForkJoinPool(parallelism)
-
- echo("Detected ${scenarios.size} scenarios [$repeats replications]")
-
- for (scenario in scenarios) {
- runScenario(runner, pool, scenario)
- }
-
- pool.shutdown()
- }
-
- /**
- * Run a single scenario.
- */
- private fun runScenario(
- runner: GreenifierRunner,
- pool: ForkJoinPool,
- scenario: Scenario,
- ) {
- val pb =
- ProgressBarBuilder()
- .setInitialMax(repeats.toLong())
- .setStyle(ProgressBarStyle.ASCII)
- .setTaskName("Simulating...")
- .build()
-
- pool.submit {
- LongStream.range(0, repeats.toLong())
- .parallel()
- .forEach { repeat ->
- val augmentedScenario = scenario.copy(partitions = basePartitions + scenario.partitions)
- runner.runScenario(augmentedScenario, seed + repeat)
- pb.step()
- }
-
- pb.close()
- }.join()
- }
-}
diff --git a/opendc-experiments/opendc-experiments-greenifier/src/main/kotlin/org/opendc/experiments/greenifier/GreenifierPortfolio.kt b/opendc-experiments/opendc-experiments-greenifier/src/main/kotlin/org/opendc/experiments/greenifier/GreenifierPortfolio.kt
deleted file mode 100644
index f7452be2..00000000
--- a/opendc-experiments/opendc-experiments-greenifier/src/main/kotlin/org/opendc/experiments/greenifier/GreenifierPortfolio.kt
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2022 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.experiments.greenifier
-
-import org.opendc.compute.workload.sampleByLoad
-import org.opendc.compute.workload.trace
-import org.opendc.experiments.base.portfolio.Portfolio
-import org.opendc.experiments.base.portfolio.model.OperationalPhenomena
-import org.opendc.experiments.base.portfolio.model.Scenario
-import org.opendc.experiments.base.portfolio.model.Topology
-import org.opendc.experiments.base.portfolio.model.Workload
-
-/**
- * A [Portfolio] that explores the difference between horizontal and vertical scaling.
- */
-public class GreenifierPortfolio : Portfolio {
- private val topologies =
- listOf(
- Topology("single.json"),
- Topology("multi.json"),
- )
-
- private val workloads =
- listOf(
- Workload("bitbrains-small", trace("trace").sampleByLoad(1.0)),
- )
- private val operationalPhenomena = OperationalPhenomena(0.0, false)
- private val allocationPolicy = "active-servers"
-
- override val scenarios: Iterable<Scenario> =
- topologies.flatMap { topology ->
- workloads.map { workload ->
- Scenario(
- topology,
- workload,
- operationalPhenomena,
- allocationPolicy,
- mapOf("topology" to topology.name, "workload" to workload.name),
- )
- }
- }
-}
diff --git a/opendc-experiments/opendc-experiments-greenifier/src/main/kotlin/org/opendc/experiments/greenifier/GreenifierRunner.kt b/opendc-experiments/opendc-experiments-greenifier/src/main/kotlin/org/opendc/experiments/greenifier/GreenifierRunner.kt
deleted file mode 100644
index bd855aac..00000000
--- a/opendc-experiments/opendc-experiments-greenifier/src/main/kotlin/org/opendc/experiments/greenifier/GreenifierRunner.kt
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (c) 2022 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.experiments.greenifier
-
-import org.opendc.compute.service.ComputeService
-import org.opendc.compute.service.scheduler.createComputeScheduler
-import org.opendc.compute.simulator.failure.grid5000
-import org.opendc.compute.simulator.provisioner.Provisioner
-import org.opendc.compute.simulator.provisioner.registerComputeMonitor
-import org.opendc.compute.simulator.provisioner.setupComputeService
-import org.opendc.compute.simulator.provisioner.setupHosts
-import org.opendc.compute.telemetry.export.parquet.ParquetComputeMonitor
-import org.opendc.compute.topology.clusterTopology
-import org.opendc.compute.workload.ComputeWorkloadLoader
-import org.opendc.experiments.base.portfolio.model.Scenario
-import org.opendc.experiments.base.runner.replay
-import org.opendc.simulator.kotlin.runSimulation
-import java.io.File
-import java.time.Duration
-import java.util.Random
-import kotlin.math.roundToLong
-
-/**
- * Helper class for running the Greenifier experiments.
- *
- * @param envPath The path to the directory containing the environments.
- * @param tracePath The path to the directory containing the traces.
- * @param outputPath The path to the directory where the output should be written (or `null` if no output should be generated).
- */
-public class GreenifierRunner(
- private val envPath: File,
- tracePath: File,
- private val outputPath: File?,
-) {
- /**
- * The [ComputeWorkloadLoader] to use for loading the traces.
- */
- private val workloadLoader = ComputeWorkloadLoader(tracePath)
-
- /**
- * Run a single [scenario] with the specified seed.
- */
- fun runScenario(
- scenario: Scenario,
- seed: Long,
- ) = runSimulation {
- val serviceDomain = "compute.opendc.org"
- val topology = clusterTopology(File(envPath, scenario.topology.name))
-
- Provisioner(dispatcher, seed).use { provisioner ->
- provisioner.runSteps(
- setupComputeService(serviceDomain, { createComputeScheduler(scenario.allocationPolicy, Random(it.seeder.nextLong())) }),
- setupHosts(serviceDomain, topology, optimize = true),
- )
-
- if (outputPath != null) {
- val partitions = scenario.partitions + ("seed" to seed.toString())
- val partition = partitions.map { (k, v) -> "$k=$v" }.joinToString("/")
-
- provisioner.runStep(
- registerComputeMonitor(
- serviceDomain,
- ParquetComputeMonitor(
- outputPath,
- partition,
- bufferSize = 4096,
- ),
- ),
- )
- }
-
- val service = provisioner.registry.resolve(serviceDomain, ComputeService::class.java)!!
- val vms = scenario.workload.source.resolve(workloadLoader, Random(seed))
- val operationalPhenomena = scenario.operationalPhenomena
- val failureModel =
- if (operationalPhenomena.failureFrequency > 0) {
- grid5000(Duration.ofSeconds((operationalPhenomena.failureFrequency * 60).roundToLong()))
- } else {
- null
- }
-
- service.replay(timeSource, vms, seed, failureModel = failureModel, interference = operationalPhenomena.hasInterference)
- }
- }
-}