From 0f835d57b0e989e25aa0b71fe374a0fb1a94e86f Mon Sep 17 00:00:00 2001 From: Dante Niewenhuis Date: Tue, 5 Nov 2024 14:17:08 +0100 Subject: Documentation update (#261) * Updated a lot of documentation, added a new get-started tutorial. * Applied Spotless * Applied Spotless Java * Added bitbrains workload to site --- .../org/opendc/compute/carbon/CarbonTraceLoader.kt | 16 +- .../org/opendc/compute/carbon/CarbonTraceReader.kt | 6 +- .../opendc-experiments-base/build.gradle.kts | 6 +- .../base/experiment/ExperimentFactories.kt | 115 ++++++++ .../base/experiment/ExperimentReader.kt | 53 ++++ .../base/experiment/ExperimentWriter.kt | 67 +++++ .../opendc/experiments/base/experiment/Scenario.kt | 61 ++++ .../base/experiment/specs/AllocationPolicySpec.kt | 40 +++ .../base/experiment/specs/CheckpointModelSpec.kt | 32 +++ .../base/experiment/specs/ExperimentSpec.kt | 116 ++++++++ .../base/experiment/specs/ExportModelSpec.kt | 39 +++ .../base/experiment/specs/FailureModelSpec.kt | 320 +++++++++++++++++++++ .../base/experiment/specs/PowerModelSpec.kt | 32 +++ .../base/experiment/specs/ScenarioSpec.kt | 41 +++ .../base/experiment/specs/ScenarioTopologySpec.kt | 42 +++ .../base/experiment/specs/WorkloadSpec.kt | 72 +++++ .../experiments/base/runner/ExperimentCli.kt | 2 +- .../experiments/base/runner/ExperimentRunner.kt | 2 +- .../experiments/base/runner/ScenarioReplayer.kt | 4 +- .../experiments/base/runner/ScenarioRunner.kt | 4 +- .../base/scenario/ExperimentFactories.kt | 115 -------- .../experiments/base/scenario/ExperimentReader.kt | 53 ---- .../experiments/base/scenario/ExperimentWriter.kt | 67 ----- .../opendc/experiments/base/scenario/Scenario.kt | 61 ---- .../base/scenario/specs/AllocationPolicySpec.kt | 40 --- .../base/scenario/specs/CheckpointModelSpec.kt | 32 --- .../base/scenario/specs/ExperimentSpec.kt | 116 -------- .../base/scenario/specs/ExportModelSpec.kt | 39 --- .../base/scenario/specs/FailureModelSpec.kt | 320 --------------------- .../base/scenario/specs/PowerModelSpec.kt | 32 --- .../base/scenario/specs/ScenarioSpec.kt | 41 --- .../base/scenario/specs/ScenarioTopologySpec.kt | 42 --- .../base/scenario/specs/WorkloadSpec.kt | 72 ----- .../experiments/base/ScenarioIntegrationTest.kt | 2 +- .../org/opendc/experiments/m3sa/runner/M3SACli.kt | 2 +- .../opendc/experiments/m3sa/runner/M3SARunner.kt | 2 +- .../experiments/m3sa/scenario/M3SAFactories.kt | 2 +- .../simulator/compute/power/CarbonFragment.java | 63 ++++ .../simulator/compute/power/CarbonFragmentNew.java | 59 ---- .../simulator/compute/power/CarbonModel.java | 38 ++- .../simulator/compute/power/SimPowerSource.java | 3 +- site/docs/documentation/Input/Experiment.md | 175 +++++++++++ site/docs/documentation/Input/ExperimentSchema.md | 81 ++++++ site/docs/documentation/Input/FailureModel.md | 218 ++++++++++++++ site/docs/documentation/Input/FailureModels.md | 202 ------------- site/docs/documentation/Input/Scenario.md | 125 -------- site/docs/documentation/Input/ScenarioSchema.md | 81 ------ site/docs/documentation/Input/Topology.md | 61 ++-- site/docs/documentation/Input/Traces.md | 26 -- site/docs/documentation/Input/Workload.md | 24 ++ site/docs/documentation/Output.md | 73 +++-- site/docs/getting-started/0-installation.md | 40 +-- site/docs/getting-started/1-design.mdx | 154 ---------- site/docs/getting-started/1-first-experiment.md | 200 +++++++++++++ site/docs/getting-started/2-experiment.mdx | 74 ----- .../documents/experiments/simple_experiment.json | 13 + .../getting-started/documents/topologies/big.json | 59 ++++ .../documents/topologies/small.json | 22 ++ .../documents/workloads/bitbrains-small.zip | Bin 0 -> 573038 bytes site/old_tutorials/0-installation.md | 31 ++ site/old_tutorials/1-design.mdx | 154 ++++++++++ site/old_tutorials/2-experiment.mdx | 74 +++++ site/old_tutorials/3-whats-next.md | 12 + site/old_tutorials/_category_.json | 8 + 64 files changed, 2302 insertions(+), 1876 deletions(-) create mode 100644 opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/ExperimentFactories.kt create mode 100644 opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/ExperimentReader.kt create mode 100644 opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/ExperimentWriter.kt create mode 100644 opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/Scenario.kt create mode 100644 opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/AllocationPolicySpec.kt create mode 100644 opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/CheckpointModelSpec.kt create mode 100644 opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/ExperimentSpec.kt create mode 100644 opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/ExportModelSpec.kt create mode 100644 opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/FailureModelSpec.kt create mode 100644 opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/PowerModelSpec.kt create mode 100644 opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/ScenarioSpec.kt create mode 100644 opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/ScenarioTopologySpec.kt create mode 100644 opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/WorkloadSpec.kt delete mode 100644 opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/ExperimentFactories.kt delete mode 100644 opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/ExperimentReader.kt delete mode 100644 opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/ExperimentWriter.kt delete mode 100644 opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/Scenario.kt delete mode 100644 opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/AllocationPolicySpec.kt delete mode 100644 opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/CheckpointModelSpec.kt delete mode 100644 opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/ExperimentSpec.kt delete mode 100644 opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/ExportModelSpec.kt delete mode 100644 opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/FailureModelSpec.kt delete mode 100644 opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/PowerModelSpec.kt delete mode 100644 opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/ScenarioSpec.kt delete mode 100644 opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/ScenarioTopologySpec.kt delete mode 100644 opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/WorkloadSpec.kt create mode 100644 opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/CarbonFragment.java delete mode 100644 opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/CarbonFragmentNew.java create mode 100644 site/docs/documentation/Input/Experiment.md create mode 100644 site/docs/documentation/Input/ExperimentSchema.md create mode 100644 site/docs/documentation/Input/FailureModel.md delete mode 100644 site/docs/documentation/Input/FailureModels.md delete mode 100644 site/docs/documentation/Input/Scenario.md delete mode 100644 site/docs/documentation/Input/ScenarioSchema.md delete mode 100644 site/docs/documentation/Input/Traces.md create mode 100644 site/docs/documentation/Input/Workload.md delete mode 100644 site/docs/getting-started/1-design.mdx create mode 100644 site/docs/getting-started/1-first-experiment.md delete mode 100644 site/docs/getting-started/2-experiment.mdx create mode 100644 site/docs/getting-started/documents/experiments/simple_experiment.json create mode 100644 site/docs/getting-started/documents/topologies/big.json create mode 100644 site/docs/getting-started/documents/topologies/small.json create mode 100644 site/docs/getting-started/documents/workloads/bitbrains-small.zip create mode 100644 site/old_tutorials/0-installation.md create mode 100644 site/old_tutorials/1-design.mdx create mode 100644 site/old_tutorials/2-experiment.mdx create mode 100644 site/old_tutorials/3-whats-next.md create mode 100644 site/old_tutorials/_category_.json diff --git a/opendc-compute/opendc-compute-carbon/src/main/kotlin/org/opendc/compute/carbon/CarbonTraceLoader.kt b/opendc-compute/opendc-compute-carbon/src/main/kotlin/org/opendc/compute/carbon/CarbonTraceLoader.kt index ccf1d81c..104abdca 100644 --- a/opendc-compute/opendc-compute-carbon/src/main/kotlin/org/opendc/compute/carbon/CarbonTraceLoader.kt +++ b/opendc-compute/opendc-compute-carbon/src/main/kotlin/org/opendc/compute/carbon/CarbonTraceLoader.kt @@ -22,7 +22,7 @@ package org.opendc.compute.carbon -import org.opendc.simulator.compute.power.CarbonFragmentNew +import org.opendc.simulator.compute.power.CarbonFragment import org.opendc.trace.Trace import org.opendc.trace.conv.CARBON_INTENSITY_TIMESTAMP import org.opendc.trace.conv.CARBON_INTENSITY_VALUE @@ -41,14 +41,14 @@ public class CarbonTraceLoader { /** * The cache of workloads. */ - private val cache = ConcurrentHashMap>>() + private val cache = ConcurrentHashMap>>() private val builder = CarbonFragmentNewBuilder() /** * Read the metadata into a workload. */ - private fun parseCarbon(trace: Trace): List { + private fun parseCarbon(trace: Trace): List { val reader = checkNotNull(trace.getTable(TABLE_CARBON_INTENSITIES)).newReader() val startTimeCol = reader.resolve(CARBON_INTENSITY_TIMESTAMP) @@ -77,7 +77,7 @@ public class CarbonTraceLoader { /** * Load the trace with the specified [name] and [format]. */ - public fun get(pathToFile: File): List { + public fun get(pathToFile: File): List { val trace = Trace.open(pathToFile, "carbon") return parseCarbon(trace) @@ -97,7 +97,7 @@ public class CarbonTraceLoader { /** * The total load of the trace. */ - public val fragments: MutableList = mutableListOf() + public val fragments: MutableList = mutableListOf() /** * Add a fragment to the trace. @@ -110,7 +110,11 @@ public class CarbonTraceLoader { carbonIntensity: Double, ) { fragments.add( - CarbonFragmentNew(startTime.toEpochMilli(), Long.MAX_VALUE, carbonIntensity), + CarbonFragment( + startTime.toEpochMilli(), + Long.MAX_VALUE, + carbonIntensity, + ), ) } diff --git a/opendc-compute/opendc-compute-carbon/src/main/kotlin/org/opendc/compute/carbon/CarbonTraceReader.kt b/opendc-compute/opendc-compute-carbon/src/main/kotlin/org/opendc/compute/carbon/CarbonTraceReader.kt index 0b2b07a1..b308ed21 100644 --- a/opendc-compute/opendc-compute-carbon/src/main/kotlin/org/opendc/compute/carbon/CarbonTraceReader.kt +++ b/opendc-compute/opendc-compute-carbon/src/main/kotlin/org/opendc/compute/carbon/CarbonTraceReader.kt @@ -24,14 +24,14 @@ package org.opendc.compute.carbon -import org.opendc.simulator.compute.power.CarbonFragmentNew +import org.opendc.simulator.compute.power.CarbonFragment import java.io.File import javax.management.InvalidAttributeValueException /** * Construct a workload from a trace. */ -public fun getCarbonFragments(pathToFile: String?): List? { +public fun getCarbonFragments(pathToFile: String?): List? { if (pathToFile == null) { return null } @@ -42,7 +42,7 @@ public fun getCarbonFragments(pathToFile: String?): List? { /** * Construct a workload from a trace. */ -public fun getCarbonFragments(file: File): List { +public fun getCarbonFragments(file: File): List { if (!file.exists()) { throw InvalidAttributeValueException("The carbon trace cannot be found") } diff --git a/opendc-experiments/opendc-experiments-base/build.gradle.kts b/opendc-experiments/opendc-experiments-base/build.gradle.kts index d8921ffb..36073418 100644 --- a/opendc-experiments/opendc-experiments-base/build.gradle.kts +++ b/opendc-experiments/opendc-experiments-base/build.gradle.kts @@ -52,8 +52,8 @@ dependencies { val createScenarioApp by tasks.creating(CreateStartScripts::class) { dependsOn(tasks.jar) - applicationName = "OpenDCScenarioRunner" - mainClass.set("org.opendc.experiments.base.runner.ScenarioCli") + applicationName = "OpenDCExperimentRunner" + mainClass.set("org.opendc.experiments.base.runner.ExperimentCli") classpath = tasks.jar.get().outputs.files + configurations["runtimeClasspath"] outputDir = project.buildDir.resolve("scripts") } @@ -61,7 +61,7 @@ val createScenarioApp by tasks.creating(CreateStartScripts::class) { // Create custom Scenario distribution distributions { main { - distributionBaseName.set("OpenDCScenarioRunner") + distributionBaseName.set("OpenDCExperimentRunner") contents { from("README.md") diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/ExperimentFactories.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/ExperimentFactories.kt new file mode 100644 index 00000000..5d158ea3 --- /dev/null +++ b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/ExperimentFactories.kt @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2024 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.base.experiment + +import org.opendc.experiments.base.experiment.specs.ExperimentSpec +import org.opendc.experiments.base.experiment.specs.ScenarioSpec +import java.io.File + +private val experimentReader = ExperimentReader() +private val experimentWriter = ExperimentWriter() + +/** + * Returns a list of Scenarios from a given file path (input). + * + * @param filePath The path to the file containing the scenario specifications. + * @return A list of Scenarios. + */ +public fun getExperiment(filePath: String): List { + return getExperiment(File(filePath)) +} + +/** + * Returns a list of Scenarios from a given file. Reads and decodes the contents of the (JSON) file. + * + * @param file The file containing the scenario specifications. + * @return A list of Scenarios. + */ +public fun getExperiment(file: File): List { + return getExperiment(experimentReader.read(file)) +} + +/** + * Returns a list of Scenarios from a given ScenarioSpec by generating all possible combinations of + * workloads, allocation policies, failure models, and export models within a topology. + * + * @param experimentSpec The ScenarioSpec containing the scenario specifications. + * @return A list of Scenarios. + */ +public fun getExperiment(experimentSpec: ExperimentSpec): List { + val outputFolder = experimentSpec.outputFolder + "/" + experimentSpec.name + File(outputFolder).mkdirs() + + val trackrPath = "$outputFolder/trackr.json" + File(trackrPath).createNewFile() + + val scenarios = mutableListOf() + + val cartesianInput = experimentSpec.getCartesian() + + for ((scenarioID, scenarioSpec) in cartesianInput.withIndex()) { + val scenario = + Scenario( + id = scenarioID, + name = scenarioID.toString(), + outputFolder = outputFolder, + runs = experimentSpec.runs, + initialSeed = experimentSpec.initialSeed, + computeExportConfig = scenarioSpec.computeExportConfig, + topologySpec = scenarioSpec.topology, + workloadSpec = scenarioSpec.workload, + allocationPolicySpec = scenarioSpec.allocationPolicy, + exportModelSpec = scenarioSpec.exportModel, + failureModelSpec = scenarioSpec.failureModel, + checkpointModelSpec = scenarioSpec.checkpointModel, + maxNumFailures = scenarioSpec.maxNumFailures, + ) + trackScenario(scenarioSpec, outputFolder) + scenarios.add(scenario) + } + + return scenarios +} + +/** + * Writes a ScenarioSpec to a file. + * + * @param scenariosSpec The ScenarioSpec. + * @param outputFolder The output folder path. + * @param scenario The Scenario. + * @param topologySpec The TopologySpec. + + */ +public fun trackScenario( + scenarioSpec: ScenarioSpec, + outputFolder: String, +) { + val trackrPath = "$outputFolder/trackr.json" + experimentWriter.write( + scenarioSpec, + File(trackrPath), + ) + + // remove the last comma + File(trackrPath).writeText(File(trackrPath).readText().dropLast(3) + "]") +} diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/ExperimentReader.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/ExperimentReader.kt new file mode 100644 index 00000000..12127644 --- /dev/null +++ b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/ExperimentReader.kt @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2024 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.base.experiment + +import kotlinx.serialization.ExperimentalSerializationApi +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.decodeFromStream +import org.opendc.compute.simulator.telemetry.parquet.ComputeExportConfig +import org.opendc.experiments.base.experiment.specs.ExperimentSpec +import java.io.File +import java.io.InputStream +import java.nio.file.Path +import kotlin.io.path.inputStream + +public class ExperimentReader { + private val jsonReader = Json + + public fun read(file: File): ExperimentSpec = read(file.inputStream()) + + public fun read(path: Path): ExperimentSpec = read(path.inputStream()) + + /** + * Read the specified [input]. + */ + @OptIn(ExperimentalSerializationApi::class) + public fun read(input: InputStream): ExperimentSpec { + // Loads the default parquet output fields, + // so that they can be deserialized + ComputeExportConfig.loadDfltColumns() + + return jsonReader.decodeFromStream(input) + } +} diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/ExperimentWriter.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/ExperimentWriter.kt new file mode 100644 index 00000000..73331fe2 --- /dev/null +++ b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/ExperimentWriter.kt @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2024 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.base.experiment + +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json +import org.opendc.experiments.base.experiment.specs.ScenarioSpec +import java.io.File + +/** + * A writer for writing scenarios to a file. + * @param jsonText The JSON text to write to the file, which is constantly updated during the writing process. + * @param json The JSON object used to encode the scenario specification. + */ +public class ExperimentWriter { + private var jsonText = "[" + private val json = Json { prettyPrint = true } + + /** + * Write the given [scenariosSpec] to the given [file]. + */ + public fun write( + scenarioSpec: ScenarioSpec, + file: File, + ) { + openArray(file) + val jsonString = json.encodeToString(scenarioSpec) + "," + jsonText += jsonString + "\n" + file.writeText(jsonText) + closeArray(file) + } + + /** + * Delete the last character of the file. + */ + private fun openArray(file: File) { + val text = file.readText() + file.writeText(text.dropLast(0)) + } + + /** + * Add the closing bracket to the file. + */ + private fun closeArray(file: File) { + file.appendText("]") + } +} diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/Scenario.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/Scenario.kt new file mode 100644 index 00000000..a99bd061 --- /dev/null +++ b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/Scenario.kt @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2024 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.base.experiment + +import org.opendc.compute.simulator.telemetry.parquet.ComputeExportConfig +import org.opendc.experiments.base.experiment.specs.AllocationPolicySpec +import org.opendc.experiments.base.experiment.specs.CheckpointModelSpec +import org.opendc.experiments.base.experiment.specs.ExportModelSpec +import org.opendc.experiments.base.experiment.specs.FailureModelSpec +import org.opendc.experiments.base.experiment.specs.ScenarioTopologySpec +import org.opendc.experiments.base.experiment.specs.WorkloadSpec + +/** + * A data class representing a scenario for a set of experiments. + * + * @property topology The list of HostSpec representing the topology of the scenario. + * @property workload The WorkloadSpec representing the workload of the scenario. + * @property allocationPolicy The AllocationPolicySpec representing the allocation policy of the scenario. + * @property failureModel The FailureModel representing the failure model of the scenario. It can be null. + * @property exportModel The ExportSpec representing the export model of the scenario. It defaults to an instance of ExportSpec. + * @property outputFolder The String representing the output folder of the scenario. It defaults to "output". + * @property name The String representing the name of the scenario. It defaults to an empty string. + * @property runs The Int representing the number of runs of the scenario. It defaults to 1. + * @property initialSeed The Int representing the initial seed of the scenario. It defaults to 0. + * @property computeExportConfig configures which parquet columns are to be included in the output files. + */ +public data class Scenario( + var id: Int = -1, + val name: String = "", + val outputFolder: String = "output", + val runs: Int = 1, + val initialSeed: Int = 0, + val computeExportConfig: ComputeExportConfig, + val topologySpec: ScenarioTopologySpec, + val workloadSpec: WorkloadSpec, + val allocationPolicySpec: AllocationPolicySpec, + val exportModelSpec: ExportModelSpec = ExportModelSpec(), + val failureModelSpec: FailureModelSpec?, + val checkpointModelSpec: CheckpointModelSpec?, + val maxNumFailures: Int = 10, +) diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/AllocationPolicySpec.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/AllocationPolicySpec.kt new file mode 100644 index 00000000..0bd3d476 --- /dev/null +++ b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/AllocationPolicySpec.kt @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024 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.base.experiment.specs + +import kotlinx.serialization.Serializable +import org.opendc.compute.simulator.scheduler.ComputeSchedulerEnum + +/** + * specification describing how tasks are allocated + * + * @property policyType + * + * TODO: expand with more variables such as allowed over-subscription + */ +@Serializable +public data class AllocationPolicySpec( + val policyType: ComputeSchedulerEnum = ComputeSchedulerEnum.Mem, +) { + public val name: String = policyType.toString() +} diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/CheckpointModelSpec.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/CheckpointModelSpec.kt new file mode 100644 index 00000000..47c3eb70 --- /dev/null +++ b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/CheckpointModelSpec.kt @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2024 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.base.experiment.specs + +import kotlinx.serialization.Serializable + +@Serializable +public data class CheckpointModelSpec( + val checkpointInterval: Long = 60 * 60 * 1000, + val checkpointDuration: Long = 5 * 60 * 1000, + val checkpointIntervalScaling: Double = 1.0, +) diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/ExperimentSpec.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/ExperimentSpec.kt new file mode 100644 index 00000000..6d8c8ebf --- /dev/null +++ b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/ExperimentSpec.kt @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2024 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.base.experiment.specs + +import kotlinx.serialization.Serializable +import org.opendc.common.logger.infoNewLine +import org.opendc.common.logger.logger +import org.opendc.compute.simulator.telemetry.parquet.ComputeExportConfig +import java.util.UUID + +/** + * specification describing a scenario + * + * @property topologies + * @property workloads + * @property allocationPolicies + * @property failureModels + * @property exportModels + * @property outputFolder + * @property initialSeed + * @property runs + * @property computeExportConfig configures which parquet columns are to + * be included in the output files. + */ + +@Serializable +public data class ExperimentSpec( + var id: Int = -1, + var name: String = "", + val outputFolder: String = "output", + val initialSeed: Int = 0, + val runs: Int = 1, + val exportModels: Set = setOf(ExportModelSpec()), + val computeExportConfig: ComputeExportConfig = ComputeExportConfig.ALL_COLUMNS, + val maxNumFailures: Set = setOf(10), + val topologies: Set, + val workloads: Set, + val allocationPolicies: Set = setOf(AllocationPolicySpec()), + val failureModels: Set = setOf(null), + val checkpointModels: Set = setOf(null), +) { + init { + require(runs > 0) { "The number of runs should always be positive" } + + // generate name if not provided + // TODO: improve this + if (name == "") { + name = "unnamed-simulation-${UUID.randomUUID().toString().substring(0, 4)}" +// "workload=${workloads[0].name}_topology=${topologies[0].name}_allocationPolicy=${allocationPolicies[0].name}" + } + + LOG.infoNewLine(computeExportConfig.fmt()) + } + + public fun getCartesian(): Sequence { + return sequence { + val checkpointDiv = maxNumFailures.size + val failureDiv = checkpointDiv * checkpointModels.size + val exportDiv = failureDiv * failureModels.size + val allocationDiv = exportDiv * exportModels.size + val workloadDiv = allocationDiv * allocationPolicies.size + val topologyDiv = workloadDiv * workloads.size + val numScenarios = topologyDiv * topologies.size + + val topologyList = topologies.toList() + val workloadList = workloads.toList() + val allocationPolicyList = allocationPolicies.toList() + val exportModelList = exportModels.toList() + val failureModelList = failureModels.toList() + val checkpointModelList = checkpointModels.toList() + val maxNumFailuresList = maxNumFailures.toList() + + for (i in 0 until numScenarios) { + yield( + ScenarioSpec( + id, + name, + outputFolder, + computeExportConfig = computeExportConfig, + topologyList[(i / topologyDiv) % topologyList.size], + workloadList[(i / workloadDiv) % workloadList.size], + allocationPolicyList[(i / allocationDiv) % allocationPolicyList.size], + exportModelList[(i / exportDiv) % exportModelList.size], + failureModelList[(i / failureDiv) % failureModelList.size], + checkpointModelList[(i / checkpointDiv) % checkpointModelList.size], + maxNumFailuresList[i % maxNumFailuresList.size], + ), + ) + } + } + } + + internal companion object { + private val LOG by logger() + } +} diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/ExportModelSpec.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/ExportModelSpec.kt new file mode 100644 index 00000000..62f1ea4b --- /dev/null +++ b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/ExportModelSpec.kt @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2024 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.base.experiment.specs + +import kotlinx.serialization.Serializable + +/** + * specification describing how the results should be exported + * + * @property exportInterval The interval of exporting results in s. Should be higher than 0.0 + */ +@Serializable +public data class ExportModelSpec( + val exportInterval: Long = 5 * 60, +) { + init { + require(exportInterval > 0) { "The Export interval has to be higher than 0" } + } +} diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/FailureModelSpec.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/FailureModelSpec.kt new file mode 100644 index 00000000..520d7e3d --- /dev/null +++ b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/FailureModelSpec.kt @@ -0,0 +1,320 @@ +/* + * Copyright (c) 2024 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.base.experiment.specs + +/* + * Copyright (c) 2024 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. + */ + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import org.apache.commons.math3.distribution.ConstantRealDistribution +import org.apache.commons.math3.distribution.ExponentialDistribution +import org.apache.commons.math3.distribution.GammaDistribution +import org.apache.commons.math3.distribution.LogNormalDistribution +import org.apache.commons.math3.distribution.NormalDistribution +import org.apache.commons.math3.distribution.ParetoDistribution +import org.apache.commons.math3.distribution.RealDistribution +import org.apache.commons.math3.distribution.UniformRealDistribution +import org.apache.commons.math3.distribution.WeibullDistribution +import org.apache.commons.math3.random.Well19937c +import org.opendc.compute.failure.models.FailureModel +import org.opendc.compute.failure.models.SampleBasedFailureModel +import org.opendc.compute.failure.models.TraceBasedFailureModel +import org.opendc.compute.failure.prefab.FailurePrefab +import org.opendc.compute.failure.prefab.createFailureModelPrefab +import org.opendc.compute.simulator.service.ComputeService +import java.io.File +import java.time.InstantSource +import kotlin.coroutines.CoroutineContext + +/** + * Specifications of the different Failure models + * There are three types of Specs that can be used by using their SerialName as the type. + * + * @constructor Create empty Failure model spec + */ + +@Serializable +public sealed interface FailureModelSpec { + public var name: String +} + +/** + * A failure model spec for failure models based on a failure trace. + * + * @property pathToFile Path to the parquet file that contains the failure trace + */ +@Serializable +@SerialName("trace-based") +public data class TraceBasedFailureModelSpec( + public val pathToFile: String, +) : FailureModelSpec { + override var name: String = File(pathToFile).nameWithoutExtension + + init { + require(File(pathToFile).exists()) { "Path to file $pathToFile does not exist" } + } +} + +/** + * A specification for a failure model that is already present in OpenDC. + * + * @property prefabName The name of the prefab. It needs to be valid [FailurePrefab] + */ +@Serializable +@SerialName("prefab") +public data class PrefabFailureModelSpec( + public val prefabName: FailurePrefab, +) : FailureModelSpec { + override var name: String = prefabName.toString() +} + +/** + * Specification of a custom failure model that is defined by three distributions to sample from. + * Distributions are defined using a [DistributionSpec]. + * + * @property iatSampler Sampler for the time between failures defined in hours + * @property durationSampler Sampler for the time of a failure defined in hours + * @property nohSampler Sampler for ratio of hosts that fail defined as a double between 0.0 and 1.0 + * @constructor Create empty Custom failure model spec + */ +@Serializable +@SerialName("custom") +public data class CustomFailureModelSpec( + public val iatSampler: DistributionSpec, + public val durationSampler: DistributionSpec, + public val nohSampler: DistributionSpec, +) : FailureModelSpec { + override var name: String = "custom" +} + +/** + * Specifications of the different Distributions that can used to create a [CustomFailureModelSpec] + * All [DistributionSpec]s have a different definition based on the variables they need to function. + * Available [DistributionSpec] are: + * - [ConstantDistributionSpec] + * - [ExponentialDistributionSpec] + * - [GammaDistributionSpec] + * - [LogNormalDistributionSpec] + * - [ParetoDistributionSpec] + * - [UniformDistributionSpec] + * - [WeibullDistributionSpec] +*/ + +@Serializable +public sealed interface DistributionSpec + +@Serializable +@SerialName("constant") +public data class ConstantDistributionSpec( + public val value: Double, +) : DistributionSpec { + init { + require(value > 0.0) { "Value must be greater than 0.0" } + } +} + +@Serializable +@SerialName("exponential") +public data class ExponentialDistributionSpec( + public val mean: Double, +) : DistributionSpec + +@Serializable +@SerialName("gamma") +public data class GammaDistributionSpec( + public val shape: Double, + public val scale: Double, +) : DistributionSpec + +@Serializable +@SerialName("log-normal") +public data class LogNormalDistributionSpec( + public val scale: Double, + public val shape: Double, +) : DistributionSpec + +@Serializable +@SerialName("normal") +public data class NormalDistributionSpec( + public val mean: Double, + public val std: Double, +) : DistributionSpec + +@Serializable +@SerialName("pareto") +public data class ParetoDistributionSpec( + public val scale: Double, + public val shape: Double, +) : DistributionSpec + +@Serializable +@SerialName("uniform") +public data class UniformDistributionSpec( + public val upper: Double, + public val lower: Double, +) : DistributionSpec { + init { + require(upper > lower) { "Upper bound must be greater than the lower bound" } + } +} + +@Serializable +@SerialName("weibull") +public data class WeibullDistributionSpec( + public val alpha: Double, + public val beta: Double, +) : DistributionSpec + +/** + * Create a [FailureModel] based on the provided [FailureModelSpec] + * + * @param context + * @param clock + * @param service + * @param random + * @param failureModelSpec + * @return + */ +public fun createFailureModel( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: java.util.random.RandomGenerator, + failureModelSpec: FailureModelSpec?, +): FailureModel? { + return when (failureModelSpec) { + is PrefabFailureModelSpec -> createFailureModel(context, clock, service, random, failureModelSpec) + is CustomFailureModelSpec -> createFailureModel(context, clock, service, random, failureModelSpec) + is TraceBasedFailureModelSpec -> createFailureModel(context, clock, service, random, failureModelSpec) + else -> null + } +} + +/** + * Create [FailureModel] based on the provided [PrefabFailureModelSpec] + * + * @param context + * @param clock + * @param service + * @param random + * @param failureModel + * @return + */ +public fun createFailureModel( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: java.util.random.RandomGenerator, + failureModel: PrefabFailureModelSpec, +): FailureModel { + return createFailureModelPrefab(context, clock, service, random, failureModel.prefabName) +} + +/** + * Create [FailureModel] based on the provided [TraceBasedFailureModel] + * + * @param context + * @param clock + * @param service + * @param random + * @param failureModel + * @return + */ +public fun createFailureModel( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: java.util.random.RandomGenerator, + failureModel: TraceBasedFailureModelSpec, +): FailureModel { + return TraceBasedFailureModel(context, clock, service, random, failureModel.pathToFile) +} + +/** + * Create [FailureModel] based on the provided [CustomFailureModelSpec] + * + * @param context + * @param clock + * @param service + * @param random + * @param failureModel + * @return + */ +public fun createFailureModel( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: java.util.random.RandomGenerator, + failureModel: CustomFailureModelSpec, +): FailureModel { + val rng: org.apache.commons.math3.random.RandomGenerator = Well19937c(random.nextLong()) + + val iatSampler = createSampler(rng, failureModel.iatSampler) + val durationSampler = createSampler(rng, failureModel.durationSampler) + val nohSampler = createSampler(rng, failureModel.nohSampler) + + return SampleBasedFailureModel(context, clock, service, random, iatSampler, durationSampler, nohSampler) +} + +/** + * Create a [RealDistribution] to sample from based on the provided [DistributionSpec] + * + * @param rng + * @param distributionSpec + * @return + */ +public fun createSampler( + rng: org.apache.commons.math3.random.RandomGenerator, + distributionSpec: DistributionSpec, +): RealDistribution { + return when (distributionSpec) { + is ConstantDistributionSpec -> ConstantRealDistribution(distributionSpec.value) + is ExponentialDistributionSpec -> ExponentialDistribution(rng, distributionSpec.mean) + is GammaDistributionSpec -> GammaDistribution(rng, distributionSpec.shape, distributionSpec.scale) + is LogNormalDistributionSpec -> LogNormalDistribution(rng, distributionSpec.scale, distributionSpec.shape) + is NormalDistributionSpec -> NormalDistribution(rng, distributionSpec.mean, distributionSpec.std) + is ParetoDistributionSpec -> ParetoDistribution(rng, distributionSpec.scale, distributionSpec.shape) + is UniformDistributionSpec -> UniformRealDistribution(rng, distributionSpec.lower, distributionSpec.upper) + is WeibullDistributionSpec -> WeibullDistribution(rng, distributionSpec.alpha, distributionSpec.beta) + } +} diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/PowerModelSpec.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/PowerModelSpec.kt new file mode 100644 index 00000000..a508d8c1 --- /dev/null +++ b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/PowerModelSpec.kt @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2024 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.base.experiment.specs + +import kotlinx.serialization.Serializable + +@Serializable +public data class PowerModelSpec( + val type: String = "constant", + val idlePower: Double = 200.0, + val maxPower: Double = 350.0, +) diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/ScenarioSpec.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/ScenarioSpec.kt new file mode 100644 index 00000000..b41eb37b --- /dev/null +++ b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/ScenarioSpec.kt @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2024 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.base.experiment.specs + +import kotlinx.serialization.Serializable +import org.opendc.compute.simulator.telemetry.parquet.ComputeExportConfig + +@Serializable +public data class ScenarioSpec( + var id: Int = -1, + var name: String = "", + val outputFolder: String = "output", + val computeExportConfig: ComputeExportConfig, + val topology: ScenarioTopologySpec, + val workload: WorkloadSpec, + val allocationPolicy: AllocationPolicySpec = AllocationPolicySpec(), + val exportModel: ExportModelSpec = ExportModelSpec(), + val failureModel: FailureModelSpec? = null, + val checkpointModel: CheckpointModelSpec? = null, + val maxNumFailures: Int = 10, +) diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/ScenarioTopologySpec.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/ScenarioTopologySpec.kt new file mode 100644 index 00000000..02c40af4 --- /dev/null +++ b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/ScenarioTopologySpec.kt @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2024 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.base.experiment.specs + +import kotlinx.serialization.Serializable +import java.io.File + +/** + * specification describing a topology + * + * @property pathToFile + */ +@Serializable +public data class ScenarioTopologySpec( + val pathToFile: String, +) { + public val name: String = File(pathToFile).nameWithoutExtension + + init { + require(File(pathToFile).exists()) { "The provided path to the topology: $pathToFile does not exist " } + } +} diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/WorkloadSpec.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/WorkloadSpec.kt new file mode 100644 index 00000000..7f34c508 --- /dev/null +++ b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/WorkloadSpec.kt @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2024 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.base.experiment.specs + +import kotlinx.serialization.Serializable +import org.opendc.compute.workload.ComputeWorkload +import org.opendc.compute.workload.sampleByLoad +import org.opendc.compute.workload.trace +import java.io.File + +/** + * specification describing a workload + * + * @property pathToFile + * @property type + */ +@Serializable +public data class WorkloadSpec( + val pathToFile: String, + val type: WorkloadTypes, +) { + public val name: String = File(pathToFile).nameWithoutExtension + + init { + require(File(pathToFile).exists()) { "The provided path to the workload: $pathToFile does not exist " } + } +} + +/** + * specification describing a workload type + * + * @constructor Create empty Workload types + */ +public enum class WorkloadTypes { + /** + * Compute workload + * + * @constructor Create empty Compute workload + */ + ComputeWorkload, +} + +/** + * + *TODO: move to separate file + * @param type + */ +public fun getWorkloadType(type: WorkloadTypes): ComputeWorkload { + return when (type) { + WorkloadTypes.ComputeWorkload -> trace().sampleByLoad(1.0) + } +} diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/runner/ExperimentCli.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/runner/ExperimentCli.kt index 28ebe45c..e067bf45 100644 --- a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/runner/ExperimentCli.kt +++ b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/runner/ExperimentCli.kt @@ -30,7 +30,7 @@ import com.github.ajalt.clikt.parameters.options.defaultLazy import com.github.ajalt.clikt.parameters.options.option import com.github.ajalt.clikt.parameters.types.file import com.github.ajalt.clikt.parameters.types.int -import org.opendc.experiments.base.scenario.getExperiment +import org.opendc.experiments.base.experiment.getExperiment import java.io.File /** diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/runner/ExperimentRunner.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/runner/ExperimentRunner.kt index 076cfb9f..0b45806b 100644 --- a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/runner/ExperimentRunner.kt +++ b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/runner/ExperimentRunner.kt @@ -22,7 +22,7 @@ package org.opendc.experiments.base.runner -import org.opendc.experiments.base.scenario.Scenario +import org.opendc.experiments.base.experiment.Scenario import java.util.concurrent.ForkJoinPool /** diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/runner/ScenarioReplayer.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/runner/ScenarioReplayer.kt index c82e2557..a0263e38 100644 --- a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/runner/ScenarioReplayer.kt +++ b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/runner/ScenarioReplayer.kt @@ -35,8 +35,8 @@ import org.opendc.compute.simulator.TaskWatcher import org.opendc.compute.simulator.service.ComputeService import org.opendc.compute.simulator.service.ServiceTask import org.opendc.compute.workload.Task -import org.opendc.experiments.base.scenario.specs.FailureModelSpec -import org.opendc.experiments.base.scenario.specs.createFailureModel +import org.opendc.experiments.base.experiment.specs.FailureModelSpec +import org.opendc.experiments.base.experiment.specs.createFailureModel import java.time.InstantSource import java.util.Random import kotlin.coroutines.coroutineContext diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/runner/ScenarioRunner.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/runner/ScenarioRunner.kt index d525e066..4d6069e4 100644 --- a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/runner/ScenarioRunner.kt +++ b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/runner/ScenarioRunner.kt @@ -33,8 +33,8 @@ import org.opendc.compute.simulator.service.ComputeService import org.opendc.compute.simulator.telemetry.parquet.ParquetComputeMonitor import org.opendc.compute.topology.clusterTopology import org.opendc.compute.workload.ComputeWorkloadLoader -import org.opendc.experiments.base.scenario.Scenario -import org.opendc.experiments.base.scenario.specs.getWorkloadType +import org.opendc.experiments.base.experiment.Scenario +import org.opendc.experiments.base.experiment.specs.getWorkloadType import org.opendc.simulator.kotlin.runSimulation import java.io.File import java.time.Duration diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/ExperimentFactories.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/ExperimentFactories.kt deleted file mode 100644 index 524d4219..00000000 --- a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/ExperimentFactories.kt +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2024 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.base.scenario - -import org.opendc.experiments.base.scenario.specs.ExperimentSpec -import org.opendc.experiments.base.scenario.specs.ScenarioSpec -import java.io.File - -private val experimentReader = ExperimentReader() -private val experimentWriter = ExperimentWriter() - -/** - * Returns a list of Scenarios from a given file path (input). - * - * @param filePath The path to the file containing the scenario specifications. - * @return A list of Scenarios. - */ -public fun getExperiment(filePath: String): List { - return getExperiment(File(filePath)) -} - -/** - * Returns a list of Scenarios from a given file. Reads and decodes the contents of the (JSON) file. - * - * @param file The file containing the scenario specifications. - * @return A list of Scenarios. - */ -public fun getExperiment(file: File): List { - return getExperiment(experimentReader.read(file)) -} - -/** - * Returns a list of Scenarios from a given ScenarioSpec by generating all possible combinations of - * workloads, allocation policies, failure models, and export models within a topology. - * - * @param experimentSpec The ScenarioSpec containing the scenario specifications. - * @return A list of Scenarios. - */ -public fun getExperiment(experimentSpec: ExperimentSpec): List { - val outputFolder = experimentSpec.outputFolder + "/" + experimentSpec.name - File(outputFolder).mkdirs() - - val trackrPath = "$outputFolder/trackr.json" - File(trackrPath).createNewFile() - - val scenarios = mutableListOf() - - val cartesianInput = experimentSpec.getCartesian() - - for ((scenarioID, scenarioSpec) in cartesianInput.withIndex()) { - val scenario = - Scenario( - id = scenarioID, - name = scenarioID.toString(), - outputFolder = outputFolder, - runs = experimentSpec.runs, - initialSeed = experimentSpec.initialSeed, - computeExportConfig = scenarioSpec.computeExportConfig, - topologySpec = scenarioSpec.topology, - workloadSpec = scenarioSpec.workload, - allocationPolicySpec = scenarioSpec.allocationPolicy, - exportModelSpec = scenarioSpec.exportModel, - failureModelSpec = scenarioSpec.failureModel, - checkpointModelSpec = scenarioSpec.checkpointModel, - maxNumFailures = scenarioSpec.maxNumFailures, - ) - trackScenario(scenarioSpec, outputFolder) - scenarios.add(scenario) - } - - return scenarios -} - -/** - * Writes a ScenarioSpec to a file. - * - * @param scenariosSpec The ScenarioSpec. - * @param outputFolder The output folder path. - * @param scenario The Scenario. - * @param topologySpec The TopologySpec. - - */ -public fun trackScenario( - scenarioSpec: ScenarioSpec, - outputFolder: String, -) { - val trackrPath = "$outputFolder/trackr.json" - experimentWriter.write( - scenarioSpec, - File(trackrPath), - ) - - // remove the last comma - File(trackrPath).writeText(File(trackrPath).readText().dropLast(3) + "]") -} diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/ExperimentReader.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/ExperimentReader.kt deleted file mode 100644 index 8ed60b08..00000000 --- a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/ExperimentReader.kt +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2024 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.base.scenario - -import kotlinx.serialization.ExperimentalSerializationApi -import kotlinx.serialization.json.Json -import kotlinx.serialization.json.decodeFromStream -import org.opendc.compute.simulator.telemetry.parquet.ComputeExportConfig -import org.opendc.experiments.base.scenario.specs.ExperimentSpec -import java.io.File -import java.io.InputStream -import java.nio.file.Path -import kotlin.io.path.inputStream - -public class ExperimentReader { - private val jsonReader = Json - - public fun read(file: File): ExperimentSpec = read(file.inputStream()) - - public fun read(path: Path): ExperimentSpec = read(path.inputStream()) - - /** - * Read the specified [input]. - */ - @OptIn(ExperimentalSerializationApi::class) - public fun read(input: InputStream): ExperimentSpec { - // Loads the default parquet output fields, - // so that they can be deserialized - ComputeExportConfig.loadDfltColumns() - - return jsonReader.decodeFromStream(input) - } -} diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/ExperimentWriter.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/ExperimentWriter.kt deleted file mode 100644 index 6afe6031..00000000 --- a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/ExperimentWriter.kt +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2024 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.base.scenario - -import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.Json -import org.opendc.experiments.base.scenario.specs.ScenarioSpec -import java.io.File - -/** - * A writer for writing scenarios to a file. - * @param jsonText The JSON text to write to the file, which is constantly updated during the writing process. - * @param json The JSON object used to encode the scenario specification. - */ -public class ExperimentWriter { - private var jsonText = "[" - private val json = Json { prettyPrint = true } - - /** - * Write the given [scenariosSpec] to the given [file]. - */ - public fun write( - scenarioSpec: ScenarioSpec, - file: File, - ) { - openArray(file) - val jsonString = json.encodeToString(scenarioSpec) + "," - jsonText += jsonString + "\n" - file.writeText(jsonText) - closeArray(file) - } - - /** - * Delete the last character of the file. - */ - private fun openArray(file: File) { - val text = file.readText() - file.writeText(text.dropLast(0)) - } - - /** - * Add the closing bracket to the file. - */ - private fun closeArray(file: File) { - file.appendText("]") - } -} diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/Scenario.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/Scenario.kt deleted file mode 100644 index e62669e4..00000000 --- a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/Scenario.kt +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2024 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.base.scenario - -import org.opendc.compute.simulator.telemetry.parquet.ComputeExportConfig -import org.opendc.experiments.base.scenario.specs.AllocationPolicySpec -import org.opendc.experiments.base.scenario.specs.CheckpointModelSpec -import org.opendc.experiments.base.scenario.specs.ExportModelSpec -import org.opendc.experiments.base.scenario.specs.FailureModelSpec -import org.opendc.experiments.base.scenario.specs.ScenarioTopologySpec -import org.opendc.experiments.base.scenario.specs.WorkloadSpec - -/** - * A data class representing a scenario for a set of experiments. - * - * @property topology The list of HostSpec representing the topology of the scenario. - * @property workload The WorkloadSpec representing the workload of the scenario. - * @property allocationPolicy The AllocationPolicySpec representing the allocation policy of the scenario. - * @property failureModel The FailureModel representing the failure model of the scenario. It can be null. - * @property exportModel The ExportSpec representing the export model of the scenario. It defaults to an instance of ExportSpec. - * @property outputFolder The String representing the output folder of the scenario. It defaults to "output". - * @property name The String representing the name of the scenario. It defaults to an empty string. - * @property runs The Int representing the number of runs of the scenario. It defaults to 1. - * @property initialSeed The Int representing the initial seed of the scenario. It defaults to 0. - * @property computeExportConfig configures which parquet columns are to be included in the output files. - */ -public data class Scenario( - var id: Int = -1, - val name: String = "", - val outputFolder: String = "output", - val runs: Int = 1, - val initialSeed: Int = 0, - val computeExportConfig: ComputeExportConfig, - val topologySpec: ScenarioTopologySpec, - val workloadSpec: WorkloadSpec, - val allocationPolicySpec: AllocationPolicySpec, - val exportModelSpec: ExportModelSpec = ExportModelSpec(), - val failureModelSpec: FailureModelSpec?, - val checkpointModelSpec: CheckpointModelSpec?, - val maxNumFailures: Int = 10, -) diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/AllocationPolicySpec.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/AllocationPolicySpec.kt deleted file mode 100644 index ddc11a50..00000000 --- a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/AllocationPolicySpec.kt +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2024 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.base.scenario.specs - -import kotlinx.serialization.Serializable -import org.opendc.compute.simulator.scheduler.ComputeSchedulerEnum - -/** - * specification describing how tasks are allocated - * - * @property policyType - * - * TODO: expand with more variables such as allowed over-subscription - */ -@Serializable -public data class AllocationPolicySpec( - val policyType: ComputeSchedulerEnum = ComputeSchedulerEnum.Mem, -) { - public val name: String = policyType.toString() -} diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/CheckpointModelSpec.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/CheckpointModelSpec.kt deleted file mode 100644 index ad0fba1d..00000000 --- a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/CheckpointModelSpec.kt +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2024 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.base.scenario.specs - -import kotlinx.serialization.Serializable - -@Serializable -public data class CheckpointModelSpec( - val checkpointInterval: Long = 60 * 60 * 1000, - val checkpointDuration: Long = 5 * 60 * 1000, - val checkpointIntervalScaling: Double = 1.0, -) diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/ExperimentSpec.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/ExperimentSpec.kt deleted file mode 100644 index 7805ed2b..00000000 --- a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/ExperimentSpec.kt +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2024 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.base.scenario.specs - -import kotlinx.serialization.Serializable -import org.opendc.common.logger.infoNewLine -import org.opendc.common.logger.logger -import org.opendc.compute.simulator.telemetry.parquet.ComputeExportConfig -import java.util.UUID - -/** - * specification describing a scenario - * - * @property topologies - * @property workloads - * @property allocationPolicies - * @property failureModels - * @property exportModels - * @property outputFolder - * @property initialSeed - * @property runs - * @property computeExportConfig configures which parquet columns are to - * be included in the output files. - */ - -@Serializable -public data class ExperimentSpec( - var id: Int = -1, - var name: String = "", - val outputFolder: String = "output", - val initialSeed: Int = 0, - val runs: Int = 1, - val topologies: Set, - val workloads: Set, - val allocationPolicies: Set = setOf(AllocationPolicySpec()), - val exportModels: Set = setOf(ExportModelSpec()), - val failureModels: Set = setOf(null), - val checkpointModels: Set = setOf(null), - val computeExportConfig: ComputeExportConfig = ComputeExportConfig.ALL_COLUMNS, - val maxNumFailures: Set = setOf(10), -) { - init { - require(runs > 0) { "The number of runs should always be positive" } - - // generate name if not provided - // TODO: improve this - if (name == "") { - name = "unnamed-simulation-${UUID.randomUUID().toString().substring(0, 4)}" -// "workload=${workloads[0].name}_topology=${topologies[0].name}_allocationPolicy=${allocationPolicies[0].name}" - } - - LOG.infoNewLine(computeExportConfig.fmt()) - } - - public fun getCartesian(): Sequence { - return sequence { - val checkpointDiv = maxNumFailures.size - val failureDiv = checkpointDiv * checkpointModels.size - val exportDiv = failureDiv * failureModels.size - val allocationDiv = exportDiv * exportModels.size - val workloadDiv = allocationDiv * allocationPolicies.size - val topologyDiv = workloadDiv * workloads.size - val numScenarios = topologyDiv * topologies.size - - val topologyList = topologies.toList() - val workloadList = workloads.toList() - val allocationPolicyList = allocationPolicies.toList() - val exportModelList = exportModels.toList() - val failureModelList = failureModels.toList() - val checkpointModelList = checkpointModels.toList() - val maxNumFailuresList = maxNumFailures.toList() - - for (i in 0 until numScenarios) { - yield( - ScenarioSpec( - id, - name, - outputFolder, - computeExportConfig = computeExportConfig, - topologyList[(i / topologyDiv) % topologyList.size], - workloadList[(i / workloadDiv) % workloadList.size], - allocationPolicyList[(i / allocationDiv) % allocationPolicyList.size], - exportModelList[(i / exportDiv) % exportModelList.size], - failureModelList[(i / failureDiv) % failureModelList.size], - checkpointModelList[(i / checkpointDiv) % checkpointModelList.size], - maxNumFailuresList[i % maxNumFailuresList.size], - ), - ) - } - } - } - - internal companion object { - private val LOG by logger() - } -} diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/ExportModelSpec.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/ExportModelSpec.kt deleted file mode 100644 index d51de27b..00000000 --- a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/ExportModelSpec.kt +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2024 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.base.scenario.specs - -import kotlinx.serialization.Serializable - -/** - * specification describing how the results should be exported - * - * @property exportInterval The interval of exporting results in s. Should be higher than 0.0 - */ -@Serializable -public data class ExportModelSpec( - val exportInterval: Long = 5 * 60, -) { - init { - require(exportInterval > 0) { "The Export interval has to be higher than 0" } - } -} diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/FailureModelSpec.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/FailureModelSpec.kt deleted file mode 100644 index c20b4467..00000000 --- a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/FailureModelSpec.kt +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Copyright (c) 2024 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.base.scenario.specs - -/* - * Copyright (c) 2024 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. - */ - -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable -import org.apache.commons.math3.distribution.ConstantRealDistribution -import org.apache.commons.math3.distribution.ExponentialDistribution -import org.apache.commons.math3.distribution.GammaDistribution -import org.apache.commons.math3.distribution.LogNormalDistribution -import org.apache.commons.math3.distribution.NormalDistribution -import org.apache.commons.math3.distribution.ParetoDistribution -import org.apache.commons.math3.distribution.RealDistribution -import org.apache.commons.math3.distribution.UniformRealDistribution -import org.apache.commons.math3.distribution.WeibullDistribution -import org.apache.commons.math3.random.Well19937c -import org.opendc.compute.failure.models.FailureModel -import org.opendc.compute.failure.models.SampleBasedFailureModel -import org.opendc.compute.failure.models.TraceBasedFailureModel -import org.opendc.compute.failure.prefab.FailurePrefab -import org.opendc.compute.failure.prefab.createFailureModelPrefab -import org.opendc.compute.simulator.service.ComputeService -import java.io.File -import java.time.InstantSource -import kotlin.coroutines.CoroutineContext - -/** - * Specifications of the different Failure models - * There are three types of Specs that can be used by using their SerialName as the type. - * - * @constructor Create empty Failure model spec - */ - -@Serializable -public sealed interface FailureModelSpec { - public var name: String -} - -/** - * A failure model spec for failure models based on a failure trace. - * - * @property pathToFile Path to the parquet file that contains the failure trace - */ -@Serializable -@SerialName("trace-based") -public data class TraceBasedFailureModelSpec( - public val pathToFile: String, -) : FailureModelSpec { - override var name: String = File(pathToFile).nameWithoutExtension - - init { - require(File(pathToFile).exists()) { "Path to file $pathToFile does not exist" } - } -} - -/** - * A specification for a failure model that is already present in OpenDC. - * - * @property prefabName The name of the prefab. It needs to be valid [FailurePrefab] - */ -@Serializable -@SerialName("prefab") -public data class PrefabFailureModelSpec( - public val prefabName: FailurePrefab, -) : FailureModelSpec { - override var name: String = prefabName.toString() -} - -/** - * Specification of a custom failure model that is defined by three distributions to sample from. - * Distributions are defined using a [DistributionSpec]. - * - * @property iatSampler Sampler for the time between failures defined in hours - * @property durationSampler Sampler for the time of a failure defined in hours - * @property nohSampler Sampler for ratio of hosts that fail defined as a double between 0.0 and 1.0 - * @constructor Create empty Custom failure model spec - */ -@Serializable -@SerialName("custom") -public data class CustomFailureModelSpec( - public val iatSampler: DistributionSpec, - public val durationSampler: DistributionSpec, - public val nohSampler: DistributionSpec, -) : FailureModelSpec { - override var name: String = "custom" -} - -/** - * Specifications of the different Distributions that can used to create a [CustomFailureModelSpec] - * All [DistributionSpec]s have a different definition based on the variables they need to function. - * Available [DistributionSpec] are: - * - [ConstantDistributionSpec] - * - [ExponentialDistributionSpec] - * - [GammaDistributionSpec] - * - [LogNormalDistributionSpec] - * - [ParetoDistributionSpec] - * - [UniformDistributionSpec] - * - [WeibullDistributionSpec] -*/ - -@Serializable -public sealed interface DistributionSpec - -@Serializable -@SerialName("constant") -public data class ConstantDistributionSpec( - public val value: Double, -) : DistributionSpec { - init { - require(value > 0.0) { "Value must be greater than 0.0" } - } -} - -@Serializable -@SerialName("exponential") -public data class ExponentialDistributionSpec( - public val mean: Double, -) : DistributionSpec - -@Serializable -@SerialName("gamma") -public data class GammaDistributionSpec( - public val shape: Double, - public val scale: Double, -) : DistributionSpec - -@Serializable -@SerialName("log-normal") -public data class LogNormalDistributionSpec( - public val scale: Double, - public val shape: Double, -) : DistributionSpec - -@Serializable -@SerialName("normal") -public data class NormalDistributionSpec( - public val mean: Double, - public val std: Double, -) : DistributionSpec - -@Serializable -@SerialName("pareto") -public data class ParetoDistributionSpec( - public val scale: Double, - public val shape: Double, -) : DistributionSpec - -@Serializable -@SerialName("uniform") -public data class UniformDistributionSpec( - public val upper: Double, - public val lower: Double, -) : DistributionSpec { - init { - require(upper > lower) { "Upper bound must be greater than the lower bound" } - } -} - -@Serializable -@SerialName("weibull") -public data class WeibullDistributionSpec( - public val alpha: Double, - public val beta: Double, -) : DistributionSpec - -/** - * Create a [FailureModel] based on the provided [FailureModelSpec] - * - * @param context - * @param clock - * @param service - * @param random - * @param failureModelSpec - * @return - */ -public fun createFailureModel( - context: CoroutineContext, - clock: InstantSource, - service: ComputeService, - random: java.util.random.RandomGenerator, - failureModelSpec: FailureModelSpec?, -): FailureModel? { - return when (failureModelSpec) { - is PrefabFailureModelSpec -> createFailureModel(context, clock, service, random, failureModelSpec) - is CustomFailureModelSpec -> createFailureModel(context, clock, service, random, failureModelSpec) - is TraceBasedFailureModelSpec -> createFailureModel(context, clock, service, random, failureModelSpec) - else -> null - } -} - -/** - * Create [FailureModel] based on the provided [PrefabFailureModelSpec] - * - * @param context - * @param clock - * @param service - * @param random - * @param failureModel - * @return - */ -public fun createFailureModel( - context: CoroutineContext, - clock: InstantSource, - service: ComputeService, - random: java.util.random.RandomGenerator, - failureModel: PrefabFailureModelSpec, -): FailureModel { - return createFailureModelPrefab(context, clock, service, random, failureModel.prefabName) -} - -/** - * Create [FailureModel] based on the provided [TraceBasedFailureModel] - * - * @param context - * @param clock - * @param service - * @param random - * @param failureModel - * @return - */ -public fun createFailureModel( - context: CoroutineContext, - clock: InstantSource, - service: ComputeService, - random: java.util.random.RandomGenerator, - failureModel: TraceBasedFailureModelSpec, -): FailureModel { - return TraceBasedFailureModel(context, clock, service, random, failureModel.pathToFile) -} - -/** - * Create [FailureModel] based on the provided [CustomFailureModelSpec] - * - * @param context - * @param clock - * @param service - * @param random - * @param failureModel - * @return - */ -public fun createFailureModel( - context: CoroutineContext, - clock: InstantSource, - service: ComputeService, - random: java.util.random.RandomGenerator, - failureModel: CustomFailureModelSpec, -): FailureModel { - val rng: org.apache.commons.math3.random.RandomGenerator = Well19937c(random.nextLong()) - - val iatSampler = createSampler(rng, failureModel.iatSampler) - val durationSampler = createSampler(rng, failureModel.durationSampler) - val nohSampler = createSampler(rng, failureModel.nohSampler) - - return SampleBasedFailureModel(context, clock, service, random, iatSampler, durationSampler, nohSampler) -} - -/** - * Create a [RealDistribution] to sample from based on the provided [DistributionSpec] - * - * @param rng - * @param distributionSpec - * @return - */ -public fun createSampler( - rng: org.apache.commons.math3.random.RandomGenerator, - distributionSpec: DistributionSpec, -): RealDistribution { - return when (distributionSpec) { - is ConstantDistributionSpec -> ConstantRealDistribution(distributionSpec.value) - is ExponentialDistributionSpec -> ExponentialDistribution(rng, distributionSpec.mean) - is GammaDistributionSpec -> GammaDistribution(rng, distributionSpec.shape, distributionSpec.scale) - is LogNormalDistributionSpec -> LogNormalDistribution(rng, distributionSpec.scale, distributionSpec.shape) - is NormalDistributionSpec -> NormalDistribution(rng, distributionSpec.mean, distributionSpec.std) - is ParetoDistributionSpec -> ParetoDistribution(rng, distributionSpec.scale, distributionSpec.shape) - is UniformDistributionSpec -> UniformRealDistribution(rng, distributionSpec.lower, distributionSpec.upper) - is WeibullDistributionSpec -> WeibullDistribution(rng, distributionSpec.alpha, distributionSpec.beta) - } -} diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/PowerModelSpec.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/PowerModelSpec.kt deleted file mode 100644 index f9679b26..00000000 --- a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/PowerModelSpec.kt +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2024 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.base.scenario.specs - -import kotlinx.serialization.Serializable - -@Serializable -public data class PowerModelSpec( - val type: String = "constant", - val idlePower: Double = 200.0, - val maxPower: Double = 350.0, -) diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/ScenarioSpec.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/ScenarioSpec.kt deleted file mode 100644 index b4f04c1c..00000000 --- a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/ScenarioSpec.kt +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2024 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.base.scenario.specs - -import kotlinx.serialization.Serializable -import org.opendc.compute.simulator.telemetry.parquet.ComputeExportConfig - -@Serializable -public data class ScenarioSpec( - var id: Int = -1, - var name: String = "", - val outputFolder: String = "output", - val computeExportConfig: ComputeExportConfig, - val topology: ScenarioTopologySpec, - val workload: WorkloadSpec, - val allocationPolicy: AllocationPolicySpec = AllocationPolicySpec(), - val exportModel: ExportModelSpec = ExportModelSpec(), - val failureModel: FailureModelSpec? = null, - val checkpointModel: CheckpointModelSpec? = null, - val maxNumFailures: Int = 10, -) diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/ScenarioTopologySpec.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/ScenarioTopologySpec.kt deleted file mode 100644 index feaca0c6..00000000 --- a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/ScenarioTopologySpec.kt +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2024 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.base.scenario.specs - -import kotlinx.serialization.Serializable -import java.io.File - -/** - * specification describing a topology - * - * @property pathToFile - */ -@Serializable -public data class ScenarioTopologySpec( - val pathToFile: String, -) { - public val name: String = File(pathToFile).nameWithoutExtension - - init { - require(File(pathToFile).exists()) { "The provided path to the topology: $pathToFile does not exist " } - } -} diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/WorkloadSpec.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/WorkloadSpec.kt deleted file mode 100644 index 956e97f1..00000000 --- a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/WorkloadSpec.kt +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2024 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.base.scenario.specs - -import kotlinx.serialization.Serializable -import org.opendc.compute.workload.ComputeWorkload -import org.opendc.compute.workload.sampleByLoad -import org.opendc.compute.workload.trace -import java.io.File - -/** - * specification describing a workload - * - * @property pathToFile - * @property type - */ -@Serializable -public data class WorkloadSpec( - val pathToFile: String, - val type: WorkloadTypes, -) { - public val name: String = File(pathToFile).nameWithoutExtension - - init { - require(File(pathToFile).exists()) { "The provided path to the workload: $pathToFile does not exist " } - } -} - -/** - * specification describing a workload type - * - * @constructor Create empty Workload types - */ -public enum class WorkloadTypes { - /** - * Compute workload - * - * @constructor Create empty Compute workload - */ - ComputeWorkload, -} - -/** - * - *TODO: move to separate file - * @param type - */ -public fun getWorkloadType(type: WorkloadTypes): ComputeWorkload { - return when (type) { - WorkloadTypes.ComputeWorkload -> trace().sampleByLoad(1.0) - } -} diff --git a/opendc-experiments/opendc-experiments-base/src/test/kotlin/org/opendc/experiments/base/ScenarioIntegrationTest.kt b/opendc-experiments/opendc-experiments-base/src/test/kotlin/org/opendc/experiments/base/ScenarioIntegrationTest.kt index 9fa1a09a..132ed7b5 100644 --- a/opendc-experiments/opendc-experiments-base/src/test/kotlin/org/opendc/experiments/base/ScenarioIntegrationTest.kt +++ b/opendc-experiments/opendc-experiments-base/src/test/kotlin/org/opendc/experiments/base/ScenarioIntegrationTest.kt @@ -45,8 +45,8 @@ import org.opendc.compute.workload.ComputeWorkloadLoader import org.opendc.compute.workload.Task import org.opendc.compute.workload.sampleByLoad import org.opendc.compute.workload.trace +import org.opendc.experiments.base.experiment.specs.TraceBasedFailureModelSpec import org.opendc.experiments.base.runner.replay -import org.opendc.experiments.base.scenario.specs.TraceBasedFailureModelSpec import org.opendc.simulator.kotlin.runSimulation import java.io.File import java.util.Random diff --git a/opendc-experiments/opendc-experiments-m3sa/src/main/kotlin/org/opendc/experiments/m3sa/runner/M3SACli.kt b/opendc-experiments/opendc-experiments-m3sa/src/main/kotlin/org/opendc/experiments/m3sa/runner/M3SACli.kt index 8036e5b7..4fe58d88 100644 --- a/opendc-experiments/opendc-experiments-m3sa/src/main/kotlin/org/opendc/experiments/m3sa/runner/M3SACli.kt +++ b/opendc-experiments/opendc-experiments-m3sa/src/main/kotlin/org/opendc/experiments/m3sa/runner/M3SACli.kt @@ -30,8 +30,8 @@ import com.github.ajalt.clikt.parameters.options.defaultLazy import com.github.ajalt.clikt.parameters.options.option import com.github.ajalt.clikt.parameters.types.file import com.github.ajalt.clikt.parameters.types.int +import org.opendc.experiments.base.experiment.getExperiment import org.opendc.experiments.base.runner.runExperiment -import org.opendc.experiments.base.scenario.getExperiment import org.opendc.experiments.m3sa.m3saAnalyze import org.opendc.experiments.m3sa.scenario.getOutputFolder import java.io.File diff --git a/opendc-experiments/opendc-experiments-m3sa/src/main/kotlin/org/opendc/experiments/m3sa/runner/M3SARunner.kt b/opendc-experiments/opendc-experiments-m3sa/src/main/kotlin/org/opendc/experiments/m3sa/runner/M3SARunner.kt index 89daf5f3..0068738a 100644 --- a/opendc-experiments/opendc-experiments-m3sa/src/main/kotlin/org/opendc/experiments/m3sa/runner/M3SARunner.kt +++ b/opendc-experiments/opendc-experiments-m3sa/src/main/kotlin/org/opendc/experiments/m3sa/runner/M3SARunner.kt @@ -24,9 +24,9 @@ package org.opendc.experiments.m3sa.runner +import org.opendc.experiments.base.experiment.Scenario import org.opendc.experiments.base.runner.runScenario import org.opendc.experiments.base.runner.setupOutputFolderStructure -import org.opendc.experiments.base.scenario.Scenario import java.util.concurrent.ForkJoinPool /** diff --git a/opendc-experiments/opendc-experiments-m3sa/src/main/kotlin/org/opendc/experiments/m3sa/scenario/M3SAFactories.kt b/opendc-experiments/opendc-experiments-m3sa/src/main/kotlin/org/opendc/experiments/m3sa/scenario/M3SAFactories.kt index a4df40e1..bb217f0d 100644 --- a/opendc-experiments/opendc-experiments-m3sa/src/main/kotlin/org/opendc/experiments/m3sa/scenario/M3SAFactories.kt +++ b/opendc-experiments/opendc-experiments-m3sa/src/main/kotlin/org/opendc/experiments/m3sa/scenario/M3SAFactories.kt @@ -22,7 +22,7 @@ package org.opendc.experiments.m3sa.scenario -import org.opendc.experiments.base.scenario.ExperimentReader +import org.opendc.experiments.base.experiment.ExperimentReader import java.io.File private val experimentReader = ExperimentReader() diff --git a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/CarbonFragment.java b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/CarbonFragment.java new file mode 100644 index 00000000..2563a61d --- /dev/null +++ b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/CarbonFragment.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2024 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.simulator.compute.power; + +/** + * An object holding the carbon intensity during a specific time frame. + * Used by {@link CarbonModel}. + */ +public class CarbonFragment { + private long startTime; + private long endTime; + private double carbonIntensity; + + public CarbonFragment(long startTime, long endTime, double carbonIntensity) { + this.setStartTime(startTime); + this.setEndTime(endTime); + this.setCarbonIntensity(carbonIntensity); + } + + public double getCarbonIntensity() { + return carbonIntensity; + } + + public void setCarbonIntensity(double carbonIntensity) { + this.carbonIntensity = carbonIntensity; + } + + public long getEndTime() { + return endTime; + } + + public void setEndTime(long endTime) { + this.endTime = endTime; + } + + public long getStartTime() { + return startTime; + } + + public void setStartTime(long startTime) { + this.startTime = startTime; + } +} diff --git a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/CarbonFragmentNew.java b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/CarbonFragmentNew.java deleted file mode 100644 index 78281a77..00000000 --- a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/CarbonFragmentNew.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2024 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.simulator.compute.power; - -public class CarbonFragmentNew { - private long endTime; - private long startTime; - private double carbonIntensity; - - public CarbonFragmentNew(long startTime, long endTime, double carbonIntensity) { - this.setStartTime(startTime); - this.setEndTime(endTime); - this.setCarbonIntensity(carbonIntensity); - } - - public double getCarbonIntensity() { - return carbonIntensity; - } - - public void setCarbonIntensity(double carbonIntensity) { - this.carbonIntensity = carbonIntensity; - } - - public long getEndTime() { - return endTime; - } - - public void setEndTime(long endTime) { - this.endTime = endTime; - } - - public long getStartTime() { - return startTime; - } - - public void setStartTime(long startTime) { - this.startTime = startTime; - } -} diff --git a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/CarbonModel.java b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/CarbonModel.java index 87ced77a..98ef2b72 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/CarbonModel.java +++ b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/CarbonModel.java @@ -26,26 +26,32 @@ import java.util.List; import org.opendc.simulator.engine.FlowGraph; import org.opendc.simulator.engine.FlowNode; +/** + * CarbonModel used to provide the Carbon Intensity of a {@link SimPowerSource} + * A CarbonModel is based on a list of {@link CarbonFragment} that define the carbon intensity at specific time frames. + */ public class CarbonModel extends FlowNode { private SimPowerSource powerSource; private long startTime = 0L; // The absolute timestamp on which the workload started - private List fragments; - private CarbonFragmentNew current_fragment; + private List fragments; + private CarbonFragment current_fragment; private int fragment_index; + /** - * Construct a new {@link FlowNode} instance. + * Construct a CarbonModel * - * @param parentGraph The {@link FlowGraph} this stage belongs to. + * @param parentGraph The active FlowGraph which should be used to make the new FlowNode + * @param powerSource The Power Source which should be updated with the carbon intensity + * @param carbonFragments A list of Carbon Fragments defining the carbon intensity at different time frames + * @param startTime The start time of the simulation. This is used to go from relative time (used by the clock) + * to absolute time (used by carbon fragments). */ public CarbonModel( - FlowGraph parentGraph, - SimPowerSource powerSource, - List carbonFragments, - long startTime) { + FlowGraph parentGraph, SimPowerSource powerSource, List carbonFragments, long startTime) { super(parentGraph); this.powerSource = powerSource; @@ -62,27 +68,31 @@ public class CarbonModel extends FlowNode { } /** - * Convert the given time to the absolute time by adding the start of workload - * - * @param time + * Convert the given relative time to the absolute time by adding the start of workload */ private long getAbsoluteTime(long time) { return time + startTime; } + /** + * Convert the given absolute time to the relative time by subtracting the start of workload + */ private long getRelativeTime(long time) { return time - startTime; } - private void findCorrectFragment(long absolute_time) { + /** + * Traverse the fragments to find the fragment that matches the given absoluteTime + */ + private void findCorrectFragment(long absoluteTime) { // Traverse to the previous fragment, until you reach the correct fragment - while (absolute_time < this.current_fragment.getStartTime()) { + while (absoluteTime < this.current_fragment.getStartTime()) { this.current_fragment = fragments.get(--this.fragment_index); } // Traverse to the next fragment, until you reach the correct fragment - while (absolute_time >= this.current_fragment.getEndTime()) { + while (absoluteTime >= this.current_fragment.getEndTime()) { this.current_fragment = fragments.get(++this.fragment_index); } } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/SimPowerSource.java b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/SimPowerSource.java index 03d54ad3..2c953d06 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/SimPowerSource.java +++ b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/SimPowerSource.java @@ -100,8 +100,7 @@ public final class SimPowerSource extends FlowNode implements FlowSupplier { // Constructors //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - public SimPowerSource( - FlowGraph graph, double max_capacity, List carbonFragments, long startTime) { + public SimPowerSource(FlowGraph graph, double max_capacity, List carbonFragments, long startTime) { super(graph); this.capacity = max_capacity; diff --git a/site/docs/documentation/Input/Experiment.md b/site/docs/documentation/Input/Experiment.md new file mode 100644 index 00000000..c8b96d1f --- /dev/null +++ b/site/docs/documentation/Input/Experiment.md @@ -0,0 +1,175 @@ +When using OpenDC, an experiment defines what should be run, and how. An experiment consists of one or more scenarios, +each defining a different simulation to run. Scenarios can differ in many things, such as the topology that is used, +the workload that is run, or the policies that are used to name a few. An experiment is defined using a JSON file. +In this page, we will discuss how to properly define experiments for OpenDC. + +:::info Code +All code related to reading and processing Experiment files can be found [here](https://github.com/atlarge-research/opendc/tree/master/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment) + +The code used to run a given experiment can be found [here](https://github.com/atlarge-research/opendc/tree/master/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/runner) +::: + +## Schema + +The schema for the scenario file is provided in [schema](ExperimentSchema) +In the following section, we describe the different components of the schema. +Some components of an experiment are not single values, but lists. This is used to run multiple scenarios using +a single experiment file. OpenDC will execute all permutations of the different values. +This means that if all list based values have a single value, only one Scenario will be run. + +| Variable | Type | Required? | Default | Description | +|---------------------|----------------------------------------------|-----------|----------|-------------------------------------------------------------------| +| name | string | no | "" | Name of the scenario, used for identification and referencing. | +| outputFolder | string | no | "output" | Directory where the simulation outputs will be stored. | +| initialSeed | integer | no | 0 | Seed used for random number generation to ensure reproducibility. | +| runs | integer | no | 1 | Number of times the scenario should be run. | +| exportModels | List[[ExportModel](#exportmodel)] | no | Default | Specifications for exporting data from the simulation. | +| computeExportConfig | [ComputeExportConfig](#checkpointmodel) | no | Default | The features that should be exported during the simulation | +| maxNumFailures | List[integer] | no | [10] | The max number of times a task can fail before being terminated. | +| topologies | List[[Topology](#topology)] | yes | N/A | List of topologies used in the scenario. | +| workloads | List[[Workload](#workload)] | yes | N/A | List of workloads to be executed within the scenario. | +| allocationPolicies | List[[AllocationPolicy](#allocation-policy)] | yes | N/A | Allocation policies used for resource management in the scenario. | +| failureModels | List[[FailureModel](#failuremodel)] | no | Default | List of failure models to simulate various types of failures. | +| checkpointModels | List[[CheckpointModel](#checkpointmodel)] | no | null | Paths to carbon footprint trace files. | +| carbonTracePaths | List[string] | no | null | Paths to carbon footprint trace files. | + + +Many of the input fields of the experiment file are complex objects themselves. Next, we will describe the required input +type of each of these fields. + +### ExportModel + +| Variable | Type | Required? | Default | Description | +|----------------|-------|-----------|---------|---------------------------------------------| +| exportInterval | Int64 | no | 300 | The duration between two exports in seconds | + + +### ComputeExportConfig +The features that should be exported by OpenDC + +| Variable | Type | Required? | Default | Description | +|--------------------------|--------------|-----------|--------------|-----------------------------------------------------------------------| +| hostExportColumns | List[String] | no | All features | The features that should be exported to the host output file. | +| taskExportColumns | List[String] | no | All features | The features that should be exported to the task output file. | +| powerSourceExportColumns | List[String] | no | All features | The features that should be exported to the power source output file. | +| serviceExportColumns | List[String] | no | All features | The features that should be exported to the service output file. | + + +### Topology +Defines the topology on which the workload will be run. + +:::info +For more information about the Topology go [here](Topology) +::: + +| Variable | Type | Required? | Default | Description | +|-------------|--------|-----------|---------|---------------------------------------------------------------------| +| pathToFile | string | yes | N/A | Path to the JSON file defining the topology. | + +### Workload +Defines the workload that needs to be executed. + +:::info +For more information about workloads go [here](Workload) +::: + +| Variable | Type | Required? | Default | Description | +|-------------|--------|-----------|---------|---------------------------------------------------------------------| +| pathToFile | string | yes | N/A | Path to the file containing the workload trace. | +| type | string | yes | N/A | Type of the workload (e.g., "ComputeWorkload"). | + +### Allocation Policy +Defines the allocation policy that should be used to decide on which host each task should be executed + +:::info Code +The different allocation policies that can be used can be found [here](https://github.com/atlarge-research/opendc/blob/master/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/ComputeSchedulers.kt) +::: + +| Variable | Type | Required? | Default | Description | +|------------|--------|-----------|---------|----------------------------| +| policyType | string | yes | N/A | Type of allocation policy. | + +### FailureModel +The failure model that should be used during the simulation +See [FailureModels](FailureModel) for detailed instructions. + +### CheckpointModel +The checkpoint model that should be used to create snapshots. + +| Variable | Type | Required? | Default | Description | +|---------------------------|--------|-----------|---------|---------------------------------------------------------------------------------------------------------------------| +| checkpointInterval | Int64 | no | 3600000 | The time between checkpoints in ms | +| checkpointDuration | Int64 | no | 300000 | The time to create a snapshot in ms | +| checkpointIntervalScaling | Double | no | 1.0 | The scaling of the checkpointInterval after each succesful checkpoint. The default of 1.0 means no scaling happens. | + + +## Examples +In the following section, we discuss several examples of Scenario files. Any scenario file can be verified using the +JSON schema defined in [schema](TopologySchema). + +### Simple + +The simplest scneario that can be provided to OpenDC is shown below: +```json +{ + "topologies": [ + { + "pathToFile": "topologies/topology1.json" + } + ], + "workloads": [ + { + "type": "ComputeWorkload", + "pathToFile": "traces/bitbrains-small" + } + ], + "allocationPolicies": [ + { + "policyType": "Mem" + } + ] +} +``` + +This scenario creates a simulation from file topology1, located in the topologies folder, with a workload trace from the +bitbrains-small file, and an allocation policy of type Mem. The simulation is run once (by default), and the default +name is "". + +### Complex +Following is an example of a more complex topology: +```json +{ + "topologies": [ + { + "pathToFile": "topologies/topology1.json" + }, + { + "pathToFile": "topologies/topology2.json" + }, + { + "pathToFile": "topologies/topology3.json" + } + ], + "workloads": [ + { + "pathToFile": "traces/bitbrains-small", + "type": "ComputeWorkload" + }, + { + "pathToFile": "traces/bitbrains-large", + "type": "ComputeWorkload" + } + ], + "allocationPolicies": [ + { + "policyType": "Mem" + }, + { + "policyType": "Mem-Inv" + } + ] +} +``` + +This scenario runs a total of 12 experiments. We have 3 topologies (3 datacenter configurations), each simulated with +2 distinct workloads, each using a different allocation policy (either Mem or Mem-Inv). diff --git a/site/docs/documentation/Input/ExperimentSchema.md b/site/docs/documentation/Input/ExperimentSchema.md new file mode 100644 index 00000000..78ec55f7 --- /dev/null +++ b/site/docs/documentation/Input/ExperimentSchema.md @@ -0,0 +1,81 @@ +Below is the schema for the Scenario JSON file. This schema can be used to validate a scenario file. +A scenario file can be validated using a JSON schema validator, such as https://www.jsonschemavalidator.net/. + +```json +{ + "$schema": "OpenDC/Scenario", + "$defs": { + "topology": { + "type": "object", + "properties": { + "pathToFile": { + "type": "string" + } + }, + "required": [ + "pathToFile" + ] + }, + "workload": { + "type": "object", + "properties": { + "pathToFile": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "pathToFile", + "type" + ] + }, + "allocationPolicy": { + "type": "object", + "properties": { + "policyType": { + "type": "string" + } + }, + "required": [ + "policyType" + ] + } + }, + "properties": { + "name": { + "type": "string" + }, + "topologies": { + "type": "array", + "items": { + "$ref": "#/$defs/topology" + }, + "minItems": 1 + }, + "workloads": { + "type": "array", + "items": { + "$ref": "#/$defs/workload" + }, + "minItems": 1 + }, + "allocationPolicies": { + "type": "array", + "items": { + "$ref": "#/$defs/allocationPolicy" + }, + "minItems": 1 + }, + "runs": { + "type": "integer" + } + }, + "required": [ + "topologies", + "workloads", + "allocationPolicies" + ] +} +``` diff --git a/site/docs/documentation/Input/FailureModel.md b/site/docs/documentation/Input/FailureModel.md new file mode 100644 index 00000000..ecaf7c03 --- /dev/null +++ b/site/docs/documentation/Input/FailureModel.md @@ -0,0 +1,218 @@ +OpenDC provides three types of failure models: [Trace-based](#trace-based-failure-models), [Sample-based](#sample-based-failure-models), +and [Prefab](#prefab-failure-models). + +All failure models have a similar structure containing three simple steps. + +1. The _interval_ time determines the time between two failures. +2. The _duration_ time determines how long a single failure takes. +3. The _intensity_ determines how many hosts are effected by a failure. + +:::info Code +The code that defines the Failure Models can found [here](https://github.com/atlarge-research/opendc/blob/master/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/FailureModelSpec.kt). +::: + +## Trace based failure models +Trace-based failure models are defined by a parquet file. This file defines the interval, duration, and intensity of +several failures. The failures defined in the file are looped. A valid failure model file follows the format defined below: + +| Metric | Datatype | Unit | Summary | +|-------------------|------------|---------------|--------------------------------------------| +| failure_interval | int64 | milli seconds | The duration since the last failure | +| failure_duration | int64 | milli seconds | The duration of the failure | +| failure_intensity | float64 | ratio | The ratio of hosts effected by the failure | + +:::info Code +The code implementation of Trace Based Failure Models can be found [here](https://github.com/atlarge-research/opendc/blob/master/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/models/TraceBasedFailureModel.kt) +::: + +### Example +A trace-based failure model is specified by setting "type" to "trace-based". +After, the user can define the path to the failure trace using "pathToFile": +```json +{ + "type": "trace-based", + "pathToFile": "path/to/your/failure_trace.parquet" +} +``` + +The "repeat" value can be set to false if the user does not want the failures to loop: +```json +{ + "type": "trace-based", + "pathToFile": "path/to/your/failure_trace.parquet", + "repeat": "false" +} +``` + +## Sample based failure models +Sample based failure models sample from three distributions to get the _interval_, _duration_, and _intensity_ of +each failure. Sample-based failure models are effected by randomness and will thus create different results based +on the provided seed. + +:::info Code +The code implementation for the Sample based failure models can be found [here](https://github.com/atlarge-research/opendc/blob/master/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/models/SampleBasedFailureModel.kt) +::: + +### Distributions +OpenDC supports eight different distributions based on java's [RealDistributions](https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/distribution/RealDistribution.html). +Because the different distributions require different variables, they have to be specified with a specific "type". +Next, we show an example of a correct specification of all available distributions in OpenDC. + +#### [ConstantRealDistribution](https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/distribution/ConstantRealDistribution.html) + +```json +{ + "type": "constant", + "value": 10.0 +} +``` + +#### [ExponentialDistribution](https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/distribution/ExponentialDistribution.html) +```json +{ + "type": "exponential", + "mean": 1.5 +} +``` + +#### [GammaDistribution](https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/distribution/GammaDistribution.html) +```json +{ + "type": "gamma", + "shape": 1.0, + "scale": 0.5 +} +``` + +#### [LogNormalDistribution](https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/distribution/LogNormalDistribution.html) +```json +{ + "type": "log-normal", + "scale": 1.0, + "shape": 0.5 +} +``` + +#### [NormalDistribution](https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/distribution/NormalDistribution.html) +```json +{ + "type": "normal", + "mean": 1.0, + "std": 0.5 +} +``` + +#### [ParetoDistribution](https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/distribution/ParetoDistribution.html) +```json +{ + "type": "pareto", + "scale": 1.0, + "shape": 0.6 +} +``` + +#### [UniformRealDistribution](https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/distribution/UniformRealDistribution.html) +```json +{ + "type": "constant", + "lower": 5.0, + "upper": 10.0 +} +``` + +#### [WeibullDistribution](https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/distribution/WeibullDistribution.html) +```json +{ + "type": "constant", + "alpha": 0.5, + "beta": 1.2 +} +``` + +### Example +A sample-based failure model is defined using three distributions for _intensity_, _duration_, and _intensity_. +Distributions can be mixed however the user wants. Note, values for _intensity_ and _duration_ are clamped to be positive. +The _intensity_ is clamped to the range [0.0, 1.0). +To specify a sample-based failure model, the type needs to be set to "custom". + +Example: +```json +{ + "type": "custom", + "iatSampler": { + "type": "exponential", + "mean": 1.5 + }, + "durationSampler": { + "type": "constant", + "alpha": 0.5, + "beta": 1.2 + }, + "nohSampler": { + "type": "constant", + "value": 0.5 + } +} +``` + +## Prefab failure models +The final type of failure models is the prefab models. These are models that are predefined in OpenDC and are based on +research. Currently, OpenDC has 9 prefab models based on [The Failure Trace Archive: Enabling the comparison of failure measurements and models of distributed systems](https://www-sciencedirect-com.vu-nl.idm.oclc.org/science/article/pii/S0743731513000634) +The figure below shows the values used to define the failure models. +![img.png](img.png) + +Each failure model is defined four times, on for each of the four distribution. +The final list of available prefabs is thus: + + G5k06Exp + G5k06Wbl + G5k06LogN + G5k06Gam + Lanl05Exp + Lanl05Wbl + Lanl05LogN + Lanl05Gam + Ldns04Exp + Ldns04Wbl + Ldns04LogN + Ldns04Gam + Microsoft99Exp + Microsoft99Wbl + Microsoft99LogN + Microsoft99Gam + Nd07cpuExp + Nd07cpuWbl + Nd07cpuLogN + Nd07cpuGam + Overnet03Exp + Overnet03Wbl + Overnet03LogN + Overnet03Gam + Pl05Exp + Pl05Wbl + Pl05LogN + Pl05Gam + Skype06Exp + Skype06Wbl + Skype06LogN + Skype06Gam + Websites02Exp + Websites02Wbl + Websites02LogN + Websites02Gam + +:::info Code +The different Prefab models can be found [here](https://github.com/atlarge-research/opendc/tree/master/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab) +::: + +### Example +To specify a prefab model, the "type" needs to be set to "prefab". +After, the prefab can be defined with "prefabName": + +```json +{ + "type": "prefab", + "prefabName": "G5k06Exp" +} +``` + diff --git a/site/docs/documentation/Input/FailureModels.md b/site/docs/documentation/Input/FailureModels.md deleted file mode 100644 index d62767f6..00000000 --- a/site/docs/documentation/Input/FailureModels.md +++ /dev/null @@ -1,202 +0,0 @@ -OpenDC provides three types of failure models: [Trace-based](#trace-based-failure-models), [Sample-based](#sample-based-failure-models), -and [Prefab](#prefab-failure-models). - -All failure models have a similar structure containing three simple steps. - -1. The _interval_ time determines the time between two failures. -2. The _duration_ time determines how long a single failure takes. -3. The _intensity_ determines how many hosts are effected by a failure. - -# Trace based failure models -Trace-based failure models are defined by a parquet file. This file defines the interval, duration, and intensity of -several failures. The failures defined in the file are looped. A valid failure model file follows the format defined below: - -| Metric | Datatype | Unit | Summary | -|-------------------|------------|---------------|--------------------------------------------| -| failure_interval | int64 | milli seconds | The duration since the last failure | -| failure_duration | int64 | milli seconds | The duration of the failure | -| failure_intensity | float64 | ratio | The ratio of hosts effected by the failure | - -## Schema -A trace-based failure model is specified by setting "type" to "trace-based". -After, the user can define the path to the failure trace using "pathToFile": -```json -{ - "type": "trace-based", - "pathToFile": "path/to/your/failure_trace.parquet" -} -``` - -The "repeat" value can be set to false if the user does not want the failures to loop: -```json -{ - "type": "trace-based", - "pathToFile": "path/to/your/failure_trace.parquet", - "repeat": "false" -} -``` - -# Sample based failure models -Sample based failure models sample from three distributions to get the _interval_, _duration_, and _intensity_ of -each failure. Sample-based failure models are effected by randomness and will thus create different results based -on the provided seed. - -## Distributions -OpenDC supports eight different distributions based on java's [RealDistributions](https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/distribution/RealDistribution.html). -Because the different distributions require different variables, they have to be specified with a specific "type". - -#### [ConstantRealDistribution](https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/distribution/ConstantRealDistribution.html) -A distribution that always returns the same value. - -```json -{ - "type": "constant", - "value": 10.0 -} -``` - -#### [ExponentialDistribution](https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/distribution/ExponentialDistribution.html) -```json -{ - "type": "exponential", - "mean": 1.5 -} -``` - -#### [GammaDistribution](https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/distribution/GammaDistribution.html) -```json -{ - "type": "gamma", - "shape": 1.0, - "scale": 0.5 -} -``` - -#### [LogNormalDistribution](https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/distribution/LogNormalDistribution.html) -```json -{ - "type": "log-normal", - "scale": 1.0, - "shape": 0.5 -} -``` - -#### [NormalDistribution](https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/distribution/NormalDistribution.html) -```json -{ - "type": "normal", - "mean": 1.0, - "std": 0.5 -} -``` - -#### [ParetoDistribution](https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/distribution/ParetoDistribution.html) -```json -{ - "type": "constant", - "scale": 1.0, - "shape": 0.6 -} -``` - -#### [UniformRealDistribution](https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/distribution/UniformRealDistribution.html) -```json -{ - "type": "constant", - "lower": 5.0, - "upper": 10.0 -} -``` - -#### [WeibullDistribution](https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/distribution/WeibullDistribution.html) -```json -{ - "type": "constant", - "alpha": 0.5, - "beta": 1.2 -} -``` - -## Schema -A sample-based failure model is defined using three distributions for _intensity_, _duration_, and _intensity_. -Distributions can be mixed however the user wants. Note, values for _intensity_ and _duration_ are clamped to be positive. -The _intensity_ is clamped to the range [0.0, 1.0). -To specify a sample-based failure model, the type needs to be set to "custom". - -Example: -```json -{ - "type": "custom", - "iatSampler": { - "type": "exponential", - "mean": 1.5 - }, - "durationSampler": { - "type": "constant", - "alpha": 0.5, - "beta": 1.2 - }, - "nohSampler": { - "type": "constant", - "value": 0.5 - } -} -``` - -# Prefab failure models -The final type of failure models is the prefab models. These are models that are predefined in OpenDC and are based on -research. Currently, OpenDC has 9 prefab models based on [The Failure Trace Archive: Enabling the comparison of failure measurements and models of distributed systems](https://www-sciencedirect-com.vu-nl.idm.oclc.org/science/article/pii/S0743731513000634) -The figure below shows the values used to define the failure models. -![img.png](img.png) - -Each failure model is defined four times, on for each of the four distribution. -The final list of available prefabs is thus: - - G5k06Exp - G5k06Wbl - G5k06LogN - G5k06Gam - Lanl05Exp - Lanl05Wbl - Lanl05LogN - Lanl05Gam - Ldns04Exp - Ldns04Wbl - Ldns04LogN - Ldns04Gam - Microsoft99Exp - Microsoft99Wbl - Microsoft99LogN - Microsoft99Gam - Nd07cpuExp - Nd07cpuWbl - Nd07cpuLogN - Nd07cpuGam - Overnet03Exp - Overnet03Wbl - Overnet03LogN - Overnet03Gam - Pl05Exp - Pl05Wbl - Pl05LogN - Pl05Gam - Skype06Exp - Skype06Wbl - Skype06LogN - Skype06Gam - Websites02Exp - Websites02Wbl - Websites02LogN - Websites02Gam - -## Schema -To specify a prefab model, the "type" needs to be set to "prefab". -After, the prefab can be defined with "prefabName": - -```json -{ - "type": "prefab", - "prefabName": "G5k06Exp" -} -``` - diff --git a/site/docs/documentation/Input/Scenario.md b/site/docs/documentation/Input/Scenario.md deleted file mode 100644 index ff7b9ffb..00000000 --- a/site/docs/documentation/Input/Scenario.md +++ /dev/null @@ -1,125 +0,0 @@ -The scenario of a simulation is defined using a JSON file. A scenario consists of one or more topologies, one or more -workloads, one or more allocation policies, a name and a number of times the simulation is being run. - -## Schema - -The schema for the scenario file is provided in [schema](ScenarioSchema) -In the following section, we describe the different components of the schema. - -### General Structure - -| Variable | Type | Required? | Default | Description | -|----------------------|----------------------------------------------|-----------|-------|--------------------------------------------------------------------------| -| name | string | no | "" | Name of the scenario, used for identification and referencing. | -| topologies | List[[Topology](#topology)] | yes | N/A | List of topologies used in the scenario. | -| workloads | List[[Workload](#workload)] | yes | N/A | List of workloads to be executed within the scenario. | -| allocationPolicies | List[[AllocationPolicy](#allocation-policy)] | yes | N/A | Allocation policies used for resource management in the scenario. | -| failureModels | List[[FailureModel](#failuremodel)] | no | empty | List of failure models to simulate various types of failures. | -| exportModels | List[[ExportModel](#exportmodel)] | no | empty | Specifications for exporting data from the simulation. | -| carbonTracePaths | List[string] | no | null | Paths to carbon footprint trace files. | -| outputFolder | string | no | "output" | Directory where the simulation outputs will be stored. | -| initialSeed | integer | no | 0 | Seed used for random number generation to ensure reproducibility. | -| runs | integer | no | 1 | Number of times the scenario should be run. | - -### Topology - -| Variable | Type | Required? | Default | Description | -|-------------|--------|-----------|---------|---------------------------------------------------------------------| -| pathToFile | string | yes | N/A | Path to the JSON file defining the topology. | - -### Workload - -| Variable | Type | Required? | Default | Description | -|-------------|--------|-----------|---------|---------------------------------------------------------------------| -| pathToFile | string | yes | N/A | Path to the file containing the workload trace. | -| type | string | yes | N/A | Type of the workload (e.g., "ComputeWorkload"). | - -### Allocation Policy - -| Variable | Type | Required? | Default | Description | -|-------------|--------|-----------|---------|---------------------------------------------------------------------| -| policyType | string | yes | N/A | Type of allocation policy (e.g., "BestFit", "FirstFit"). | - -### FailureModel - -| Variable | Type | Required? | Default | Description | -|-------------|--------|-----------|---------|---------------------------------------------------------------------| -| modelType | string | yes | N/A | Type of failure model to simulate specific operational failures. | - -### ExportModel - -| Variable | Type | Required? | Default | Description | -|-------------|--------|-----------|---------|---------------------------------------------------------------------| -| exportType | string | yes | N/A | Specifies the type of data export model for simulation results. | - - -## Examples -In the following section, we discuss several examples of Scenario files. Any scenario file can be verified using the -JSON schema defined in [schema](TopologySchema). - -### Simple - -The simplest scneario that can be provided to OpenDC is shown below: -```json -{ - "topologies": [ - { - "pathToFile": "topologies/topology1.json" - } - ], - "workloads": [ - { - "pathToFile": "traces/bitbrains-small", - "type": "ComputeWorkload" - } - ], - "allocationPolicies": [ - { - "policyType": "Mem" - } - ] -} -``` - -This scenario creates a simulation from file topology1, located in the topologies folder, with a workload trace from the -bitbrains-small file, and an allocation policy of type Mem. The simulation is run once (by default), and the default -name is "". - -### Complex -Following is an example of a more complex topology: -```json -{ - "topologies": [ - { - "pathToFile": "topologies/topology1.json" - }, - { - "pathToFile": "topologies/topology2.json" - }, - { - "pathToFile": "topologies/topology3.json" - } - ], - "workloads": [ - { - "pathToFile": "traces/bitbrains-small", - "type": "ComputeWorkload" - }, - { - "pathToFile": "traces/bitbrains-large", - "type": "ComputeWorkload" - } - ], - "allocationPolicies": [ - { - "policyType": "Mem" - }, - { - "policyType": "Mem-Inv" - } - ] -} -``` - -This scenario runs a total of 12 experiments. We have 3 topologies (3 datacenter configurations), each simulated with -2 distinct workloads, each using a different allocation policy (either Mem or Mem-Inv). diff --git a/site/docs/documentation/Input/ScenarioSchema.md b/site/docs/documentation/Input/ScenarioSchema.md deleted file mode 100644 index 78ec55f7..00000000 --- a/site/docs/documentation/Input/ScenarioSchema.md +++ /dev/null @@ -1,81 +0,0 @@ -Below is the schema for the Scenario JSON file. This schema can be used to validate a scenario file. -A scenario file can be validated using a JSON schema validator, such as https://www.jsonschemavalidator.net/. - -```json -{ - "$schema": "OpenDC/Scenario", - "$defs": { - "topology": { - "type": "object", - "properties": { - "pathToFile": { - "type": "string" - } - }, - "required": [ - "pathToFile" - ] - }, - "workload": { - "type": "object", - "properties": { - "pathToFile": { - "type": "string" - }, - "type": { - "type": "string" - } - }, - "required": [ - "pathToFile", - "type" - ] - }, - "allocationPolicy": { - "type": "object", - "properties": { - "policyType": { - "type": "string" - } - }, - "required": [ - "policyType" - ] - } - }, - "properties": { - "name": { - "type": "string" - }, - "topologies": { - "type": "array", - "items": { - "$ref": "#/$defs/topology" - }, - "minItems": 1 - }, - "workloads": { - "type": "array", - "items": { - "$ref": "#/$defs/workload" - }, - "minItems": 1 - }, - "allocationPolicies": { - "type": "array", - "items": { - "$ref": "#/$defs/allocationPolicy" - }, - "minItems": 1 - }, - "runs": { - "type": "integer" - } - }, - "required": [ - "topologies", - "workloads", - "allocationPolicies" - ] -} -``` diff --git a/site/docs/documentation/Input/Topology.md b/site/docs/documentation/Input/Topology.md index cf726616..0d2479bd 100644 --- a/site/docs/documentation/Input/Topology.md +++ b/site/docs/documentation/Input/Topology.md @@ -2,6 +2,11 @@ The topology of a datacenter is defined using a JSON file. A topology consist of Each cluster consist of at least one host on which jobs can be executed. Each host consist of one or more CPUs, a memory unit and a power model. +:::info Code +The code related to reading and processing topology files can be found [here](https://github.com/atlarge-research/opendc/tree/master/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology) +::: + + ## Schema The schema for the topology file is provided in [schema](TopologySchema). @@ -17,12 +22,12 @@ In the following section, we describe the different components of the schema. ### Host -| variable | type | required? | default | description | -|------------|-----------------------|-----------|---------|--------------------------------------------------------------------------------| -| name | string | no | Host | The name of the host. This is only important for debugging and post-processing | -| count | integer | no | 1 | The amount of hosts of this type are in the cluster | -| cpuModel | [CPU](#cpuModel) | yes | N/A | The CPUs in the host | -| memory | [Memory](#memory) | yes | N/A | The memory used by the host | +| variable | type | required? | default | description | +|-------------|-----------------------------|-----------|---------|--------------------------------------------------------------------------------| +| name | string | no | Host | The name of the host. This is only important for debugging and post-processing | +| count | integer | no | 1 | The amount of hosts of this type are in the cluster | +| cpuModel | [CPU](#cpu) | yes | N/A | The CPUs in the host | +| memory | [Memory](#memory) | yes | N/A | The memory used by the host | | power model | [Power Model](#power-model) | yes | N/A | The power model used to determine the power draw of the host | ### CPU @@ -49,12 +54,13 @@ In the following section, we describe the different components of the schema. ### Power Model -| variable | type | Unit | required? | default | description | -|-----------|---------|------|-----------|---------|----------------------------------------------------------------------------| -| modelType | string | N/A | yes | N/A | The type of model used to determine power draw | -| power | string | Watt | no | 400 | The constant power draw when using the 'constant' power model type in Watt | -| maxPower | string | Watt | yes | N/A | The power draw of a host when using max capacity in Watt | -| idlePower | integer | Watt | yes | N/A | The power draw of a host when idle in Watt | +| variable | type | Unit | required? | default | description | +|-----------------|--------|------|-----------|----------|-------------------------------------------------------------------------------| +| vendor | string | N/A | yes | N/A | The type of model used to determine power draw | +| modelName | string | N/A | yes | N/A | The type of model used to determine power draw | +| arch | string | N/A | yes | N/A | The type of model used to determine power draw | +| totalPower | Int64 | Watt | no | max long | The power draw of a host when using max capacity in Watt | +| carbonTracePath | string | N/A | no | null | Path to a carbon intensity trace. If not given, carbon intensity is always 0. | ## Examples @@ -71,12 +77,11 @@ The simplest data center that can be provided to OpenDC is shown below: { "hosts": [ { - "cpus": [ - { - "coreCount": 16, - "coreSpeed": 1000 - } - ], + "cpu": + { + "coreCount": 16, + "coreSpeed": 1000 + }, "memory": { "memorySize": 100000 } @@ -87,7 +92,7 @@ The simplest data center that can be provided to OpenDC is shown below: } ``` -This is creates a data center with a single cluster containing a single host. This host consist of a single 16 core CPU +This creates a data center with a single cluster containing a single host. This host consist of a single 16 core CPU with a speed of 1 Ghz, and 100 MiB RAM memory. ### Count @@ -102,14 +107,14 @@ Duplicating clusters, hosts, or CPUs is easy using the "count" keyword: "hosts": [ { "count": 5, - "cpus": [ - { - "coreCount": 16, - "coreSpeed": 1000, - "count": 10 - } - ], - "memory": { + "cpu": + { + "coreCount": 16, + "coreSpeed": 1000, + "count": 10 + }, + "memory": + { "memorySize": 100000 } } @@ -205,7 +210,7 @@ Aside from using number to indicate values it is also possible to define values "modelType": "linear", "power": "400 Watts", "maxPower": "1 KW", - "idlePower": "0.4W" + "idlePower": "0.4 W" } } ] diff --git a/site/docs/documentation/Input/Traces.md b/site/docs/documentation/Input/Traces.md deleted file mode 100644 index ec5782cb..00000000 --- a/site/docs/documentation/Input/Traces.md +++ /dev/null @@ -1,26 +0,0 @@ -### Traces -OpenDC works with two types of traces that describe the servers that need to be run. Both traces have to be provided as -parquet files. - -#### Meta -The meta trace provides an overview of the servers: - -| Metric | Datatype | Unit | Summary | -|--------------|------------|----------|--------------------------------------------------| -| id | string | | The id of the server | -| start_time | datetime64 | datetime | The submission time of the server | -| stop_time | datetime64 | datetime | The finish time of the submission | -| cpu_count | int32 | count | The number of CPUs required to run this server | -| cpu_capacity | float64 | MHz | The amount of CPU required to run this server | -| mem_capacity | int64 | MB | The amount of memory required to run this server | - -#### Trace -The Trace file provides information about the computational demand of each server over time: - -| Metric | Datatype | Unit | Summary | -|-----------|------------|---------------|---------------------------------------------| -| id | string | | The id of the server | -| timestamp | datetime64 | datetime | The timestamp of the sample | -| duration | int64 | milli seconds | The duration since the last sample | -| cpu_count | int32 | count | The number of cpus required | -| cpu_usage | float64 | MHz | The amount of computational power required. | diff --git a/site/docs/documentation/Input/Workload.md b/site/docs/documentation/Input/Workload.md new file mode 100644 index 00000000..5f2e61ae --- /dev/null +++ b/site/docs/documentation/Input/Workload.md @@ -0,0 +1,24 @@ +OpenDC works with two types of traces that describe the servers that need to be run. Both traces have to be provided as +parquet files. + +#### Task +The meta trace provides an overview of the servers: + +| Metric | Datatype | Unit | Summary | +|-----------------|----------|----------|--------------------------------------------------| +| id | string | | The id of the server | +| submission_time | int64 | datetime | The submission time of the server | +| duration | int64 | datetime | The finish time of the submission | +| cpu_count | int32 | count | The number of CPUs required to run this server | +| cpu_capacity | float64 | MHz | The amount of CPU required to run this server | +| mem_capacity | int64 | MB | The amount of memory required to run this server | + +#### Fragment +The Fragment file provides information about the computational demand of each server over time: + +| Metric | Datatype | Unit | Summary | +|-----------|------------|---------------|---------------------------------------------| +| id | string | | The id of the task | +| duration | int64 | milli seconds | The duration since the last sample | +| cpu_count | int32 | count | The number of cpus required | +| cpu_usage | float64 | MHz | The amount of computational power required. | diff --git a/site/docs/documentation/Output.md b/site/docs/documentation/Output.md index dbc2a765..3f9eb3d5 100644 --- a/site/docs/documentation/Output.md +++ b/site/docs/documentation/Output.md @@ -3,27 +3,31 @@ Running OpenDC results in three output files. The first file ([Server](#server)) The second file ([Host](#host)) contains all metrics related to the hosts on which jobs can be executed. Finally, the third file ([Service](#service)) contains metrics describing the overall performance. An experiment in OpenDC has -### Server -The server output file, contains all metrics of related to the servers run. +### Task +The task output file, contains all metrics of related to the tasks that are being executed. -| Metric | Datatype | Unit | Summary | -|--------------------|----------|--------|-------------------------------------------------------------------------------| -| timestamp | int64 | ms | Timestamp of the sample since the start of the workload | -| absolute timestamp | int64 | ms | The absolute timestamp based on the given workload | -| server_id | binary | string | The id of the server determined during runtime | -| server_name | binary | string | The name of the server provided by the Trace | -| host_id | binary | string | The id of the host on which the server is hosted or `null` if it has no host. | -| mem_capacity | int64 | Mb | | -| cpu_count | int32 | count | | -| cpu_limit | double | MHz | The capacity of the CPUs of Host on which the server is running. | -| cpu_time_active | int64 | ms | The duration that a CPU was active in the server. | -| cpu_time_idle | int64 | ms | The duration that a CPU was idle in the server. | -| cpu_time_steal | int64 | ms | The duration that a vCPU wanted to run, but no capacity was available. | -| cpu_time_lost | int64 | ms | The duration of CPU time that was lost due to interference. | -| uptime | int64 | ms | The uptime of the host since last sample. | -| downtime | int64 | ms | The downtime of the host since last sample. | -| provision_time | int64 | ms | The time for which the server was enqueued for the scheduler. | -| boot_time | int64 | ms | The time the server took booting. | +| Metric | Datatype | Unit | Summary | +|--------------------|----------|-----------|-------------------------------------------------------------------------------| +| timestamp | int64 | ms | Timestamp of the sample since the start of the workload | +| absolute timestamp | int64 | ms | The absolute timestamp based on the given workload | +| server_id | binary | string | The id of the server determined during runtime | +| server_name | binary | string | The name of the server provided by the Trace | +| host_id | binary | string | The id of the host on which the server is hosted or `null` if it has no host. | +| mem_capacity | int64 | Mb | | +| cpu_count | int32 | count | | +| cpu_limit | double | MHz | The capacity of the CPUs of Host on which the server is running. | +| cpu_time_active | int64 | ms | The duration that a CPU was active in the server. | +| cpu_time_idle | int64 | ms | The duration that a CPU was idle in the server. | +| cpu_time_steal | int64 | ms | The duration that a vCPU wanted to run, but no capacity was available. | +| cpu_time_lost | int64 | ms | The duration of CPU time that was lost due to interference. | +| uptime | int64 | ms | The uptime of the host since last sample. | +| downtime | int64 | ms | The downtime of the host since last sample. | +| provision_time | int64 | ms | The time for which the server was enqueued for the scheduler. | +| boot_time | int64 | ms | The time a task got booted. | +| boot_time_absolute | int64 | ms | The absolute time a task got booted. | +| creation_time | int64 | ms | The time at which the task was created by the ComputeService | +| finish_time | int64 | ms | The time at which the task was finished (either completed or terminated) | +| task_state | String | TaskState | The status of the Task | ### Host The host output file, contains all metrics of related to the host run. @@ -33,7 +37,7 @@ The host output file, contains all metrics of related to the host run. | timestamp | int64 | ms | Timestamp of the sample | | absolute timestamp | int64 | ms | The absolute timestamp based on the given workload | | host_id | binary | string | The id of the host given by OpenDC | -| cpu_count | int32 | count | The number of available cpuModel cores | +| cpu_count | int32 | count | The number of available cpuModel cores | | mem_capacity | int64 | Mb | The amount of available memory | | guests_terminated | int32 | count | The number of guests that are in a terminated state. | | guests_running | int32 | count | The number of guests that are in a running state. | @@ -49,11 +53,24 @@ The host output file, contains all metrics of related to the host run. | cpu_time_lost | int64 | ms | The duration of CPU time that was lost due to interference. | | power_draw | double | Watt | The current power draw of the host. | | energy_usage | double | Joule (Ws) | The total energy consumption of the host since last sample. | -| carbon_intensity | double | gCO2/kW | The amount of carbon that is emitted when using a unit of energy | -| carbon_emission | double | gram | The amount of carbon emitted since the previous sample | | uptime | int64 | ms | The uptime of the host since last sample. | | downtime | int64 | ms | The downtime of the host since last sample. | -| boot_time | int64 | ms | The time the host took to boot. | +| boot_time | int64 | ms | The time a host got booted. | +| boot_time_absolute | int64 | ms | The absolute time a host got booted. | + +### Power Source +The host output file, contains all metrics of related to the host run. + +| Metric | DataType | Unit | Summary | +|--------------------|----------|------------|------------------------------------------------------------------------------------------| +| timestamp | int64 | ms | Timestamp of the sample | +| absolute timestamp | int64 | ms | The absolute timestamp based on the given workload | +| hosts_connected | int | Count | The number of hosts connected to the power Source (WARNING: does not work at the moment) | +| power_draw | double | Watt | The current power draw of the host. | +| energy_usage | double | Joule (Ws) | The total energy consumption of the host since last sample. | +| carbon_intensity | double | gCO2/kW | The amount of carbon that is emitted when using a unit of energy | +| carbon_emission | double | gram | The amount of carbon emitted since the previous sample | + ### Service The service output file, contains metrics providing an overview of the performance. @@ -64,8 +81,10 @@ The service output file, contains metrics providing an overview of the performan | absolute timestamp | int64 | ms | The absolute timestamp based on the given workload | | hosts_up | int32 | count | The number of hosts that are up at this instant. | | hosts_down | int32 | count | The number of hosts that are down at this instant. | -| servers_pending | int32 | count | The number of servers that are pending to be scheduled. | -| servers_active | int32 | count | The number of servers that are currently active. | +| tasks_total | int32 | count | The number of servers that are currently active. | +| tasks_pending | int32 | count | The number of servers that are pending to be scheduled. | +| tasks_active | int32 | count | The number of servers that are currently active. | +| tasks_terminated | int32 | count | The number of servers that are currently active. | +| tasks_completed | int32 | count | The number of servers that are currently active. | | attempts_success | int32 | count | The scheduling attempts that were successful. | | attempts_failure | int32 | count | The scheduling attempts that were unsuccessful due to client error. | -| attempts_error | int32 | count | The scheduling attempts that were unsuccessful due to scheduler error. | diff --git a/site/docs/getting-started/0-installation.md b/site/docs/getting-started/0-installation.md index e9f539a8..281e811f 100644 --- a/site/docs/getting-started/0-installation.md +++ b/site/docs/getting-started/0-installation.md @@ -6,7 +6,7 @@ description: How to install OpenDC locally, and start experimenting in no time. This page describes how to set up and configure a local single-user OpenDC installation so that you can quickly get your experiments running. You can also use the [hosted version of OpenDC](https://app.opendc.org) to get started even -quicker. +quicker (The web server is however missing some more complex features). ## Prerequisites @@ -14,42 +14,18 @@ quicker. 1. **Supported Platforms** OpenDC is actively tested on Windows, macOS and GNU/Linux. 2. **Required Software** - A Java installation of version 17 or higher is required for OpenDC. You may download the + A Java installation of version 19 or higher is required for OpenDC. You may download the [Java distribution from Oracle](https://www.oracle.com/java/technologies/downloads/) or use the distribution provided by your package manager. ## Download -To get an OpenDC distribution, download a recent version from our [Releases](https://github.com/atlarge-research/opendc/releases) -page on GitHub. +To get an OpenDC distribution, download a recent version from our [Releases](https://github.com/atlarge-research/opendc/releases) page on GitHub. +For basic usage, the OpenDCExperimentRunner is all that is needed. ## Setup -Unpack the downloaded OpenDC distribution and try the following command: - -```bash -$ bin/opendc-server -__ ____ __ _____ ___ __ ____ ______ - --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ - -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \ ---\___\_\____/_/ |_/_/|_/_/|_|\____/___/ -2022-09-12 10:30:22,064 INFO [org.fly.cor.int.dat.bas.BaseDatabaseType] (main) Database: jdbc:h2:file:./data/opendc.db (H2 2.1) -2022-09-12 10:30:22,089 WARN [org.fly.cor.int.dat.bas.Database] (main) Flyway upgrade recommended: H2 2.1.214 is newer than this version of Flyway and support has not been tested. The latest supported version of H2 is 2.1.210. -2022-09-12 10:30:22,098 INFO [org.fly.cor.int.com.DbMigrate] (main) Current version of schema "PUBLIC": 1.0.0 -2022-09-12 10:30:22,099 INFO [org.fly.cor.int.com.DbMigrate] (main) Schema "PUBLIC" is up to date. No migration necessary. -2022-09-12 10:30:22,282 INFO [org.ope.web.run.run.OpenDCRunnerRecorder] (main) Starting OpenDC Runner in background (polling every PT30S) -2022-09-12 10:30:22,347 INFO [io.quarkus] (main) opendc-web-server 2.1-rc1 on JVM (powered by Quarkus 2.11.1.Final) started in 1.366s. Listening on: http://0.0.0.0:8080 -2022-09-12 10:30:22,348 INFO [io.quarkus] (main) Profile prod activated. -2022-09-12 10:30:22,348 INFO [io.quarkus] (main) Installed features: [agroal, cdi, flyway, hibernate-orm, hibernate-validator, jdbc-h2, jdbc-postgresql, kotlin, narayana-jta, opendc-runner, opendc-ui, resteasy, resteasy-jackson, security, smallrye-simHyperVisorContext-propagation, smallrye-openapi, swagger-ui, vertx] -``` -This will launch the built-in single-user OpenDC server on port 8080. Visit -[http://localhost:8080](http://localhost:8080) to access the bundled web UI. - -## Configuration - -OpenDC can be configured using the configuration files located in the `conf` directory. By default, all user data is -stored in the `data` directory using the H2 database engine. - -## Multi-tenant deployment - -For more information on setting up multi-tenant, non-trivial deployments, see the [Deployment Guide](docs/advanced-guides/deploy.md). +Unpack the downloaded OpenDC distribution. Opening OpenDCExperimentRunner results in two folders, `bin` and `lib`. +`lib` contains all `.jar` files needed to run OpenDC. `bin` two executable versions of the OpenDCExperimentRunner. +In the following pages, we discuss how to run an experiment using the executables. + diff --git a/site/docs/getting-started/1-design.mdx b/site/docs/getting-started/1-design.mdx deleted file mode 100644 index e8ab2c58..00000000 --- a/site/docs/getting-started/1-design.mdx +++ /dev/null @@ -1,154 +0,0 @@ ---- -description: How to design a virtual datacenter in OpenDC from scratch. ---- - -# Design a Datacenter - -Now that you have installed OpenDC (or are using the hosted version), we will start designing a (virtual) datacenter -in OpenDC. - -## Before we start - -There are a couple of steps we need to perform before we can start designing a datacenter in OpenDC. First, we need to -enter the OpenDC web application. This done as follows: - -
-
-
-
-
-

Hosted Deployment

- - To enter the hosted version of OpenDC, you need a user account. User management is provided - by Auth0, which allows you to login with social accounts or via - email. - -
- -
-
-
-
-
-

Local Deployment

- - The local distribution of OpenDC runs in single-user mode by default, which does not require - authentication. This allows you to quickly start designing and experimenting with new - datacenters. - -
- -
-
-
-
- -### Create a Project - -Next, we need to create a new project. Projects allow you to organize your designs and experiments together. -Click on ‘+ New Project’ in the right corner to open the project creation dialog. -Give your project a name and save it. You can now open it by clicking on it in the project table. If all went well, -you’re redirected to your new project, and are presented with an empty project overview. - -### Create a Topology - -In OpenDC, the datacenter design is also called a **topology**. This topology represents the physical layout of a -datacenter and specifies everything from the architectural layout of the datacenter’s rooms to which CPUs are in a -particular machine. - -To create a design (topology), click on ‘+ New Topology’ in the top right corner of the topology table. -Once you have created the topology, it will appear the topology table. By clicking on the topology, you will be -redirected to a (still empty) overview of the topology. From here, we'll start designing a datacenter. - -### Terminology - -Here’s an overview of some of the language you’ll find when designing a datacenter in OpenDC: - -- **Topology**: the physical layout of your datacenter -- **Room**: a room in the datacenter -- **Tile**: one of the tiles that forms a room -- **Rack**: a rack of servers that stands on top of a tile -- **Machine**: a machine that takes up a single slot in a server rack, containing several components such as CPUs, GPUs, - network interfaces and storage drives. - -## Build the datacenter - -Open the project and topology that you have created and click on the 'Floor Plan' tab (see [Figure 1](#floor-plan)). -We’re now in datacenter construction mode. Notice the grid on the canvas? That’s where you’ll place tiles, in order to -build rooms. Let’s take a moment to familiarize ourselves with the interface. - -If you dismiss the sidebar on your left, you have controls for zooming in and out. Next to the zooming buttons, you also -have a ‘Screenshot’ button, in case you want to record the state of the canvas and export it to an image file. On the -right side of the screen, you have the simHyperVisorContext menu. This menu changes depending on your zoom level. - -As there are currently no rooms, we are in ‘Building’ mode, and our only option is to ‘Construct a new room’. Click on -that button to build a first datacenter room - once you’ve clicked on it, every tile of the canvas that you click on -becomes a tile of that room. There is one restriction though: Each tile that you add must be adjacent to any previous -tiles that you have added. You can see for yourself which tile positions are clickable through the highlight color that -is shown on hovering over them. - -
- Analysis of results reported by OpenDC -
The floor plan of a (virtual) datacenter in OpenDC.
-
- -### Create a Room - -:::note Action - -Create at least a single room, with help of the above instructions. - -::: - -Once you’ve placed the tiles, you can give the room a name, if you want to. To do this, click on the room you want to -edit. You’ll notice the application going into ‘Room’ mode, allowing you to manipulate the topology of the datacenter at -a more fine-grained level. In the simHyperVisorContext menu, change the room name, and click on the ‘Save’ button. You can exit -‘Room’ mode by clicking on any of the darkened areas outside of the selected room. This will bring you back to -‘Building’ mode. - -### Place Server Racks - -:::note Action - -Add at least a single rack in the room. - -::: - -Empty rooms are of no use to the stakeholders of a datacenter. They want machines! Let’s place some racks in the room -to fulfill this demand. Click on the room and add some racks. To stop adding racks, click on the blue element in the -sidebar, again. - -### Fill the Racks with Servers - -:::note Action - -Add a couple of servers to the rack. - -::: - -To add actual servers to the empty racks, we’ll need to go one level deeper in the topological hierarchy of the -datacenter. Clicking on a rack lets you do just that. Once you’ve clicked on it, you’ll notice the simHyperVisorContext menu now -displaying slots. In each slot fits exactly one server unit. To add such a server unit, click on the ‘Add machine’ -button of that slot. -Just like in ‘Room’ mode, you can exit ‘Rack’ mode by clicking on any of the darkened tiles around the currently -selected rack. - -### Add Resources to the Servers - -We’re almost done creating our datacenter! The only problem we have is that the machines / servers we just added lack -any real resources (such as CPUs, GPUs, memory cards, and disk storage). - -:::note Action - -Populate the machines with CPU and memory resources. - -::: - -To do this, click on any machine you want to edit. Notice the simHyperVisorContext menu changing, with tabs to add different kinds of -units to your machine. Have a look around as to what can be added. - -Once you are satisfied with the datacenter design, we will experiment with the design in the next chapter. diff --git a/site/docs/getting-started/1-first-experiment.md b/site/docs/getting-started/1-first-experiment.md new file mode 100644 index 00000000..313d757b --- /dev/null +++ b/site/docs/getting-started/1-first-experiment.md @@ -0,0 +1,200 @@ +--- +description: Designing a simple experiment +--- + +# First Experiment +Now that you have downloaded OpenDC, we will start creating a simple experiment. +In this experiment we will compare the performance of a small, and a big data center on the same workload. + +:::info Learning goal +During this tutorial, we will learn how to create and execute a simple experiment in OpenDC. +::: + +## Designing a Data Center + +The first requirement to run an experiment in OpenDC is a **topology**. +A **topology** defines the hardware on which a **workload** is executed. +Larger topologies will be capable of running more workloads, and will often quicker. + +A **topology** is defined using a JSON file. A **topology** contains one or more _clusters_. +_clusters_ are groups of _hosts_ on a specific location. Each cluster consists of one or more _hosts_. +A _host_ is a machine on which one or more tasks can be executed. _hosts_ are composed of a _cpu_ and a _memory_ unit. + +### Simple Data Center +in this experiment, we are comparing two data centers. Below is an example of the small **topology** file: + +```json +{ + "clusters": + [ + { + "name": "C01", + "hosts" : + [ + { + "name": "H01", + "cpu": + { + "coreCount": 12, + "coreSpeed": 3300 + }, + "memory": { + "memorySize": 140457600000 + } + } + ] + } + ] +} +``` + +This **topology** consist of a single _cluster_, with a single _host_. + +:::tip +To use this **topology** in experiment copy the content to a new JSON file, or download it [here](documents/topologies/small.json "download") +::: + +### Simple Data Center +in this experiment, we are comparing two data centers. Below is an example of the bigger **topology** file: + +```json +{ + "clusters": + [ + { + "name": "C01", + "hosts" : + [ + { + "name": "H01", + "cpu": + { + "coreCount": 32, + "coreSpeed": 3200 + }, + "memory": { + "memorySize": 256000 + } + } + ] + }, + { + "name": "C02", + "hosts" : + [ + { + "name": "H02", + "count": 6, + "cpu": + { + "coreCount": 8, + "coreSpeed": 2930 + }, + "memory": { + "memorySize": 64000 + } + } + ] + }, + { + "name": "C03", + "hosts" : + [ + { + "name": "H03", + "count": 2, + "cpu": + { + "coreCount": 16, + "coreSpeed": 3200 + }, + "memory": { + "memorySize": 128000 + } + } + ] + } + ] +} +``` + +Compared to the small topology, the big topology consist of three clusters, all consisting of a single host. + +:::tip +To use this **topology** in experiment copy the content to a new JSON file, or download it [here](documents/topologies/big.json "download") +::: + +:::info +For more in depth information about Topologies, see [Topology](../documentation/Input/Topology) +::: + +## Workloads + +Next to the topology, we need a workload to simulate on the data center. +In OpenDC, workloads are defined as a bag of tasks. Each task is accompanied by one or more fragments. +These fragments define the computational requirements of the task over time. +For this experiment, we will use the bitbrains-small workload. This is a small workload of 50 tasks, +spanning over a bit more than a month time. You can download the workload [here](documents/workloads/bitbrains-small.zip "download") + +:::info +For more in depth information about Workloads, see [Workload](../documentation/Input/Workload) +::: + +## Executing an experiment + +To run an experiment, we need to create an **experiment** file. This is a JSON file, that defines what should be executed +by OpenDC, and how. Below is an example of a simple **experiment** file: + +```json +{ + "name": "simple", + "topologies": [{ + "pathToFile": "topologies/small.json" + }, + { + "pathToFile": "topologies/big.json" + }], + "workloads": [{ + "pathToFile": "traces/bitbrains-small", + "type": "ComputeWorkload" + }] +} +``` + +In this **experiment**, three things are defined. First, is the `name`. This defines how the experiment is called +in the output folder. Second, is the `topologies`. This defines where OpenDC can find the topology files. +Finally, the `workloads`. This defines which workload OpenDC should run. You can download the experiment file [here](documents/experiments/simple_experiment.json "download") + +As you can see, `topologies` defines two topologies. In this case OpenDC will run two simulations, one with the small +topology, and one with the big topology. + +:::info +For more in depth information about Experiments, see [Experiment](../documentation/Input/Experiment) +::: + +## Running OpenDC +At this point, we should have all components to run an experiment. To make sure every file can be used by OpenDC, +please create an experiment folder such as the one shown below: +``` +── {simulation-folder-name} 📁 🔧 + ├── topologies 📁 🔒 + │ └── small.json 📄 🔧 + │ └── big.json 📄 🔧 + ├── experiments 📁 🔒 + │ └── simple_experiment.json 📄 🔧 + ├── workloads 📁 🔒 + │ └── bitbrains-small 📁 🔒 + │ └── fragments.parquet 📄 🔧 + │ └── tasks.parquet 📄 🔧 + ├── OpenDCExperimentRunner 📁 🔒 + │ └── lib 📁 🔒 + │ └── bin 📁 🔒 + ├── output 📁 🔒 +``` + +Executing the experiment can be done directly from the terminal. +Execute the following code from the terminal in simulation-folder-name + +``` +$ ./OpenDCExperimentRunner/bin/OpenDCExperimentRunner.sh --experiment-path "experiments/simple_experiment.json" +``` diff --git a/site/docs/getting-started/2-experiment.mdx b/site/docs/getting-started/2-experiment.mdx deleted file mode 100644 index 14970ea6..00000000 --- a/site/docs/getting-started/2-experiment.mdx +++ /dev/null @@ -1,74 +0,0 @@ ---- -description: How to experiment with your datacenter designs. ---- - -# Create an Experiment - -After designing a datacenter in OpenDC, the next step is to experiment with the design using OpenDC's built-in -simulator, in order to analyze its performance and compare it against other designs. - -In OpenDC, we use the concept of portfolios of scenarios to experiment with datacenter designs. In the next sections, we -will explain how you can use these powerful concepts for the experimental analysis of your designs. - -## Create a Portfolio -OpenDC organizes multiple scenarios (experiments) into a **portfolio**. Each portfolio is composed of a base scenario, -a set of candidate scenarios given by the user and a set of targets (e.g., metrics) used to compare scenarios. - -To create a new portfolio, open a project in the OpenDC web interface and click on ‘+ New Portfolio’ in the top right -corner of the portfolio table. This opens a modal with the following options: - -1. **Name**: the name of your portfolio. -2. **Metrics**: the metrics that you want to use to compare the scenarios in the portfolio. -3. **Repeats per Scenario**: the number of times each scenario should be simulated (to account for variance). - -## Create Scenarios - -A **scenario** represents a point in the datacenter design space that should be explored. It consists of a combination -of workload, topology, and a set of operational phenomena. Phenomena can include correlated failures, performance -variability, security breaches, etc., allowing the scenarios to more accurately capture the real-world operations. - -The baseline for comparison in a portfolio is the **base scenario**. It represents the status quo of the infrastructure -or, when planning infrastructure from scratch, it consists of very simple base workloads and topologies. -The other scenarios in a portfolio, called the **candidate scenarios**, represent changes to the configuration -that might be of interest to the datacenter designer. Dividing scenarios into these two categories ensures that any -comparative insights provided by OpenDC are meaningful within the simHyperVisorContext of the current architecture. - -To create a new scenario, open a portfolio in the OpenDC web interface and click on ‘+ New Scenario’ in the top right -corner of the scenario table. This opens a modal with the following options (as shown in [Figure 1](#explore)): - -1. **Name**: the name of your scenario. The first scenario of a portfolio is always called the _Base scenario_. -2. **Workload**: the applications (e.g., virtual machines, workflows, functions) that consume resources in your - datacenter. - 1. **Workload Trace**: A dataset that characterizes the historical runtime behavior of virtual machines in the - workload over time. - 2. **Load Sampling Fraction**: The percentage of the workload that should be simulated (e.g., 10% of virtual - machines in the workload trace). -3. **Environment**: - 1. **Topology**: one of the topologies of the project to use for the scenario. - 2. **Scheduler**: the algorithm that decides on which hosts the virtual machines should be placed. -4. **Operational Phenomena**: - 1. **Failures**: a flag to enable stochastic host failures during simulation. - 2. **Performance interference**: a flag to enable performance interference between virtual machines (only available - for a subset of traces). - -Once you have created the scenario, it will be enqueued for simulation. Usually the results of the simulation should be -available within one minute after creation. However, if there are lots of queued simulation jobs, it might take a bit -longer. - -
- Creating a new scenario in OpenDC -
Creating a new scenario in OpenDC. The user can select the topology, workload, and operational phenomena.
-
- -## Analyze Results - -After creating scenarios, the scenario table will show whether the simulation is still pending, completed successfully, -or failed for some reason. If the scenario was simulated successfully, its results will become visible on the ‘Results’ -tab as shown in [Figure 2](#analysis). - -
- Analysis of results reported by OpenDC -
Plots and visual summaries generated by OpenDC comparing different scenarios.
-
- -This tab will show the selected metrics for the portfolio and allow you to compare their values for different scenarios. diff --git a/site/docs/getting-started/documents/experiments/simple_experiment.json b/site/docs/getting-started/documents/experiments/simple_experiment.json new file mode 100644 index 00000000..74429fdb --- /dev/null +++ b/site/docs/getting-started/documents/experiments/simple_experiment.json @@ -0,0 +1,13 @@ +{ + "name": "simple", + "topologies": [{ + "pathToFile": "topologies/small.json" + }, + { + "pathToFile": "topologies/big.json" + }], + "workloads": [{ + "pathToFile": "traces/bitbrains-small", + "type": "ComputeWorkload" + }] +} diff --git a/site/docs/getting-started/documents/topologies/big.json b/site/docs/getting-started/documents/topologies/big.json new file mode 100644 index 00000000..c3a060cc --- /dev/null +++ b/site/docs/getting-started/documents/topologies/big.json @@ -0,0 +1,59 @@ +{ + "clusters": + [ + { + "name": "C01", + "hosts" : + [ + { + "name": "H01", + "cpu": + { + "coreCount": 32, + "coreSpeed": 3200 + }, + "memory": { + "memorySize": 256000 + } + } + ] + }, + { + "name": "C02", + "hosts" : + [ + { + "name": "H02", + "count": 6, + "cpu": + { + "coreCount": 8, + "coreSpeed": 2930 + }, + "memory": { + "memorySize": 64000 + } + } + ] + }, + { + "name": "C03", + "hosts" : + [ + { + "name": "H03", + "count": 2, + "cpu": + { + "coreCount": 16, + "coreSpeed": 3200 + }, + "memory": { + "memorySize": 128000 + } + } + ] + } + ] +} + diff --git a/site/docs/getting-started/documents/topologies/small.json b/site/docs/getting-started/documents/topologies/small.json new file mode 100644 index 00000000..54e3c6fc --- /dev/null +++ b/site/docs/getting-started/documents/topologies/small.json @@ -0,0 +1,22 @@ +{ + "clusters": + [ + { + "name": "C01", + "hosts" : + [ + { + "name": "H01", + "cpu": + { + "coreCount": 12, + "coreSpeed": 3300 + }, + "memory": { + "memorySize": 140457600000 + } + } + ] + } + ] +} diff --git a/site/docs/getting-started/documents/workloads/bitbrains-small.zip b/site/docs/getting-started/documents/workloads/bitbrains-small.zip new file mode 100644 index 00000000..f128e636 Binary files /dev/null and b/site/docs/getting-started/documents/workloads/bitbrains-small.zip differ diff --git a/site/old_tutorials/0-installation.md b/site/old_tutorials/0-installation.md new file mode 100644 index 00000000..281e811f --- /dev/null +++ b/site/old_tutorials/0-installation.md @@ -0,0 +1,31 @@ +--- +description: How to install OpenDC locally, and start experimenting in no time. +--- + +# Installation + +This page describes how to set up and configure a local single-user OpenDC installation so that you can quickly get your +experiments running. You can also use the [hosted version of OpenDC](https://app.opendc.org) to get started even +quicker (The web server is however missing some more complex features). + + +## Prerequisites + +1. **Supported Platforms** + OpenDC is actively tested on Windows, macOS and GNU/Linux. +2. **Required Software** + A Java installation of version 19 or higher is required for OpenDC. You may download the + [Java distribution from Oracle](https://www.oracle.com/java/technologies/downloads/) or use the distribution provided + by your package manager. + +## Download + +To get an OpenDC distribution, download a recent version from our [Releases](https://github.com/atlarge-research/opendc/releases) page on GitHub. +For basic usage, the OpenDCExperimentRunner is all that is needed. + +## Setup + +Unpack the downloaded OpenDC distribution. Opening OpenDCExperimentRunner results in two folders, `bin` and `lib`. +`lib` contains all `.jar` files needed to run OpenDC. `bin` two executable versions of the OpenDCExperimentRunner. +In the following pages, we discuss how to run an experiment using the executables. + diff --git a/site/old_tutorials/1-design.mdx b/site/old_tutorials/1-design.mdx new file mode 100644 index 00000000..e8ab2c58 --- /dev/null +++ b/site/old_tutorials/1-design.mdx @@ -0,0 +1,154 @@ +--- +description: How to design a virtual datacenter in OpenDC from scratch. +--- + +# Design a Datacenter + +Now that you have installed OpenDC (or are using the hosted version), we will start designing a (virtual) datacenter +in OpenDC. + +## Before we start + +There are a couple of steps we need to perform before we can start designing a datacenter in OpenDC. First, we need to +enter the OpenDC web application. This done as follows: + +
+
+
+
+
+

Hosted Deployment

+ + To enter the hosted version of OpenDC, you need a user account. User management is provided + by Auth0, which allows you to login with social accounts or via + email. + +
+ +
+
+
+
+
+

Local Deployment

+ + The local distribution of OpenDC runs in single-user mode by default, which does not require + authentication. This allows you to quickly start designing and experimenting with new + datacenters. + +
+ +
+
+
+
+ +### Create a Project + +Next, we need to create a new project. Projects allow you to organize your designs and experiments together. +Click on ‘+ New Project’ in the right corner to open the project creation dialog. +Give your project a name and save it. You can now open it by clicking on it in the project table. If all went well, +you’re redirected to your new project, and are presented with an empty project overview. + +### Create a Topology + +In OpenDC, the datacenter design is also called a **topology**. This topology represents the physical layout of a +datacenter and specifies everything from the architectural layout of the datacenter’s rooms to which CPUs are in a +particular machine. + +To create a design (topology), click on ‘+ New Topology’ in the top right corner of the topology table. +Once you have created the topology, it will appear the topology table. By clicking on the topology, you will be +redirected to a (still empty) overview of the topology. From here, we'll start designing a datacenter. + +### Terminology + +Here’s an overview of some of the language you’ll find when designing a datacenter in OpenDC: + +- **Topology**: the physical layout of your datacenter +- **Room**: a room in the datacenter +- **Tile**: one of the tiles that forms a room +- **Rack**: a rack of servers that stands on top of a tile +- **Machine**: a machine that takes up a single slot in a server rack, containing several components such as CPUs, GPUs, + network interfaces and storage drives. + +## Build the datacenter + +Open the project and topology that you have created and click on the 'Floor Plan' tab (see [Figure 1](#floor-plan)). +We’re now in datacenter construction mode. Notice the grid on the canvas? That’s where you’ll place tiles, in order to +build rooms. Let’s take a moment to familiarize ourselves with the interface. + +If you dismiss the sidebar on your left, you have controls for zooming in and out. Next to the zooming buttons, you also +have a ‘Screenshot’ button, in case you want to record the state of the canvas and export it to an image file. On the +right side of the screen, you have the simHyperVisorContext menu. This menu changes depending on your zoom level. + +As there are currently no rooms, we are in ‘Building’ mode, and our only option is to ‘Construct a new room’. Click on +that button to build a first datacenter room - once you’ve clicked on it, every tile of the canvas that you click on +becomes a tile of that room. There is one restriction though: Each tile that you add must be adjacent to any previous +tiles that you have added. You can see for yourself which tile positions are clickable through the highlight color that +is shown on hovering over them. + +
+ Analysis of results reported by OpenDC +
The floor plan of a (virtual) datacenter in OpenDC.
+
+ +### Create a Room + +:::note Action + +Create at least a single room, with help of the above instructions. + +::: + +Once you’ve placed the tiles, you can give the room a name, if you want to. To do this, click on the room you want to +edit. You’ll notice the application going into ‘Room’ mode, allowing you to manipulate the topology of the datacenter at +a more fine-grained level. In the simHyperVisorContext menu, change the room name, and click on the ‘Save’ button. You can exit +‘Room’ mode by clicking on any of the darkened areas outside of the selected room. This will bring you back to +‘Building’ mode. + +### Place Server Racks + +:::note Action + +Add at least a single rack in the room. + +::: + +Empty rooms are of no use to the stakeholders of a datacenter. They want machines! Let’s place some racks in the room +to fulfill this demand. Click on the room and add some racks. To stop adding racks, click on the blue element in the +sidebar, again. + +### Fill the Racks with Servers + +:::note Action + +Add a couple of servers to the rack. + +::: + +To add actual servers to the empty racks, we’ll need to go one level deeper in the topological hierarchy of the +datacenter. Clicking on a rack lets you do just that. Once you’ve clicked on it, you’ll notice the simHyperVisorContext menu now +displaying slots. In each slot fits exactly one server unit. To add such a server unit, click on the ‘Add machine’ +button of that slot. +Just like in ‘Room’ mode, you can exit ‘Rack’ mode by clicking on any of the darkened tiles around the currently +selected rack. + +### Add Resources to the Servers + +We’re almost done creating our datacenter! The only problem we have is that the machines / servers we just added lack +any real resources (such as CPUs, GPUs, memory cards, and disk storage). + +:::note Action + +Populate the machines with CPU and memory resources. + +::: + +To do this, click on any machine you want to edit. Notice the simHyperVisorContext menu changing, with tabs to add different kinds of +units to your machine. Have a look around as to what can be added. + +Once you are satisfied with the datacenter design, we will experiment with the design in the next chapter. diff --git a/site/old_tutorials/2-experiment.mdx b/site/old_tutorials/2-experiment.mdx new file mode 100644 index 00000000..14970ea6 --- /dev/null +++ b/site/old_tutorials/2-experiment.mdx @@ -0,0 +1,74 @@ +--- +description: How to experiment with your datacenter designs. +--- + +# Create an Experiment + +After designing a datacenter in OpenDC, the next step is to experiment with the design using OpenDC's built-in +simulator, in order to analyze its performance and compare it against other designs. + +In OpenDC, we use the concept of portfolios of scenarios to experiment with datacenter designs. In the next sections, we +will explain how you can use these powerful concepts for the experimental analysis of your designs. + +## Create a Portfolio +OpenDC organizes multiple scenarios (experiments) into a **portfolio**. Each portfolio is composed of a base scenario, +a set of candidate scenarios given by the user and a set of targets (e.g., metrics) used to compare scenarios. + +To create a new portfolio, open a project in the OpenDC web interface and click on ‘+ New Portfolio’ in the top right +corner of the portfolio table. This opens a modal with the following options: + +1. **Name**: the name of your portfolio. +2. **Metrics**: the metrics that you want to use to compare the scenarios in the portfolio. +3. **Repeats per Scenario**: the number of times each scenario should be simulated (to account for variance). + +## Create Scenarios + +A **scenario** represents a point in the datacenter design space that should be explored. It consists of a combination +of workload, topology, and a set of operational phenomena. Phenomena can include correlated failures, performance +variability, security breaches, etc., allowing the scenarios to more accurately capture the real-world operations. + +The baseline for comparison in a portfolio is the **base scenario**. It represents the status quo of the infrastructure +or, when planning infrastructure from scratch, it consists of very simple base workloads and topologies. +The other scenarios in a portfolio, called the **candidate scenarios**, represent changes to the configuration +that might be of interest to the datacenter designer. Dividing scenarios into these two categories ensures that any +comparative insights provided by OpenDC are meaningful within the simHyperVisorContext of the current architecture. + +To create a new scenario, open a portfolio in the OpenDC web interface and click on ‘+ New Scenario’ in the top right +corner of the scenario table. This opens a modal with the following options (as shown in [Figure 1](#explore)): + +1. **Name**: the name of your scenario. The first scenario of a portfolio is always called the _Base scenario_. +2. **Workload**: the applications (e.g., virtual machines, workflows, functions) that consume resources in your + datacenter. + 1. **Workload Trace**: A dataset that characterizes the historical runtime behavior of virtual machines in the + workload over time. + 2. **Load Sampling Fraction**: The percentage of the workload that should be simulated (e.g., 10% of virtual + machines in the workload trace). +3. **Environment**: + 1. **Topology**: one of the topologies of the project to use for the scenario. + 2. **Scheduler**: the algorithm that decides on which hosts the virtual machines should be placed. +4. **Operational Phenomena**: + 1. **Failures**: a flag to enable stochastic host failures during simulation. + 2. **Performance interference**: a flag to enable performance interference between virtual machines (only available + for a subset of traces). + +Once you have created the scenario, it will be enqueued for simulation. Usually the results of the simulation should be +available within one minute after creation. However, if there are lots of queued simulation jobs, it might take a bit +longer. + +
+ Creating a new scenario in OpenDC +
Creating a new scenario in OpenDC. The user can select the topology, workload, and operational phenomena.
+
+ +## Analyze Results + +After creating scenarios, the scenario table will show whether the simulation is still pending, completed successfully, +or failed for some reason. If the scenario was simulated successfully, its results will become visible on the ‘Results’ +tab as shown in [Figure 2](#analysis). + +
+ Analysis of results reported by OpenDC +
Plots and visual summaries generated by OpenDC comparing different scenarios.
+
+ +This tab will show the selected metrics for the portfolio and allow you to compare their values for different scenarios. diff --git a/site/old_tutorials/3-whats-next.md b/site/old_tutorials/3-whats-next.md new file mode 100644 index 00000000..7c021119 --- /dev/null +++ b/site/old_tutorials/3-whats-next.md @@ -0,0 +1,12 @@ +--- +description: How to supercharge your designs and experiments with OpenDC. +--- + +# What's next? + +Congratulations! You have just learned how to design and experiment with a (virtual) datacenter in OpenDC. What's next? + +- Follow one of the [tutorials](/docs/category/tutorials) using OpenDC. +- Check the [advanced guides](/docs/category/advanced-guides) for more complex material. +- Read about [existing work using OpenDC](/community/research). +- Get involved in the [OpenDC Community](/community/support). diff --git a/site/old_tutorials/_category_.json b/site/old_tutorials/_category_.json new file mode 100644 index 00000000..169f7a27 --- /dev/null +++ b/site/old_tutorials/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "Getting Started", + "position": 2, + "link": { + "type": "generated-index", + "description": "10 minutes to learn the most important concepts of OpenDC." + } +} -- cgit v1.2.3