From 9403af12f5d015497894fab5a2dea93eb094ecaf Mon Sep 17 00:00:00 2001 From: Dante Niewenhuis Date: Wed, 22 Jan 2025 14:35:21 +0100 Subject: Simplified the WorkloadLoader into a single class that can be extended when new workload types are added (#294) --- .../org/opendc/compute/workload/ComputeWorkload.kt | 38 ----- .../compute/workload/ComputeWorkloadLoader.kt | 21 ++- .../opendc/compute/workload/ComputeWorkloads.kt | 66 --------- .../org/opendc/compute/workload/WorkloadLoader.kt | 55 ++++++++ .../workload/internal/CompositeComputeWorkload.kt | 69 --------- .../workload/internal/HpcSampledComputeWorkload.kt | 155 --------------------- .../internal/LoadSampledComputeWorkload.kt | 64 --------- .../workload/internal/TraceComputeWorkload.kt | 40 ------ .../base/experiment/specs/WorkloadSpec.kt | 25 ++-- .../experiments/base/runner/ScenarioRunner.kt | 23 ++- .../kotlin/org/opendc/web/runner/OpenDCRunner.kt | 10 +- 11 files changed, 102 insertions(+), 464 deletions(-) delete mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkload.kt delete mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloads.kt create mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/WorkloadLoader.kt delete mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/CompositeComputeWorkload.kt delete mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/HpcSampledComputeWorkload.kt delete mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/LoadSampledComputeWorkload.kt delete mode 100644 opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/TraceComputeWorkload.kt diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkload.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkload.kt deleted file mode 100644 index 9516c56e..00000000 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkload.kt +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2021 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.compute.workload - -import java.util.random.RandomGenerator - -/** - * An interface that describes how a workload is resolved. - */ -public interface ComputeWorkload { - /** - * Resolve the workload into a list of [Task]s to simulate. - */ - public fun resolve( - loader: ComputeWorkloadLoader, - random: RandomGenerator, - ): List -} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt index 786ed82f..e773ba1d 100644 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt @@ -48,11 +48,11 @@ import kotlin.math.roundToLong * @param baseDir The directory containing the traces. */ public class ComputeWorkloadLoader( - private val baseDir: File, + private val pathToFile: File, private val checkpointInterval: Long, private val checkpointDuration: Long, private val checkpointIntervalScaling: Double, -) { +) : WorkloadLoader() { /** * The logger for this instance. */ @@ -61,7 +61,7 @@ public class ComputeWorkloadLoader( /** * The cache of workloads. */ - private val cache = ConcurrentHashMap>>() + private val cache = ConcurrentHashMap>>() /** * Read the fragments into memory. @@ -157,21 +157,18 @@ public class ComputeWorkloadLoader( } /** - * Load the trace with the specified [name] and [format]. + * Load the trace at the specified [pathToFile]. */ - public fun get( - name: String, - format: String, - ): List { + override fun load(): List { val ref = - cache.compute(name) { key, oldVal -> + cache.compute(pathToFile) { key, oldVal -> val inst = oldVal?.get() if (inst == null) { - val path = baseDir.resolve(key) +// val path = baseDir.resolve(key) - logger.info { "Loading trace $key at $path" } + logger.info { "Loading trace $key at $pathToFile" } - val trace = Trace.open(path, format) + val trace = Trace.open(pathToFile, "opendc-vm") val fragments = parseFragments(trace) val vms = parseMeta(trace, fragments) diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloads.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloads.kt deleted file mode 100644 index dd46c7c5..00000000 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloads.kt +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -@file:JvmName("ComputeWorkloads") - -package org.opendc.compute.workload - -import org.opendc.compute.workload.internal.CompositeComputeWorkload -import org.opendc.compute.workload.internal.HpcSampledComputeWorkload -import org.opendc.compute.workload.internal.LoadSampledComputeWorkload -import org.opendc.compute.workload.internal.TraceComputeWorkload - -/** - * Construct a workload from a trace. - */ -public fun trace( - name: String = "", - format: String = "opendc-vm", -): ComputeWorkload = TraceComputeWorkload(name, format) - -/** - * Construct a composite workload with the specified fractions. - */ -public fun composite(vararg pairs: Pair): ComputeWorkload { - return CompositeComputeWorkload(pairs.toMap()) -} - -/** - * Sample a workload by a [fraction] of the total load. - */ -public fun ComputeWorkload.sampleByLoad(fraction: Double): ComputeWorkload { - return LoadSampledComputeWorkload(this, fraction) -} - -/** - * Sample a workload by a [fraction] of the HPC VMs (count) - */ -public fun ComputeWorkload.sampleByHpc(fraction: Double): ComputeWorkload { - return HpcSampledComputeWorkload(this, fraction) -} - -/** - * Sample a workload by a [fraction] of the HPC load - */ -public fun ComputeWorkload.sampleByHpcLoad(fraction: Double): ComputeWorkload { - return HpcSampledComputeWorkload(this, fraction, sampleLoad = true) -} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/WorkloadLoader.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/WorkloadLoader.kt new file mode 100644 index 00000000..f4a93c24 --- /dev/null +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/WorkloadLoader.kt @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2025 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.compute.workload +import mu.KotlinLogging + +public abstract class WorkloadLoader { + private val logger = KotlinLogging.logger {} + + public abstract fun load(): List + + /** + * Load the workload at sample tasks until a fraction of the workload is loaded + */ + public fun sampleByLoad(fraction: Double): List { + val vms = this.load() + val res = mutableListOf() + + val totalLoad = vms.sumOf { it.totalLoad } + var currentLoad = 0.0 + + for (entry in vms) { + val entryLoad = entry.totalLoad + if ((currentLoad + entryLoad) / totalLoad > fraction) { + break + } + + currentLoad += entryLoad + res += entry + } + + logger.info { "Sampled ${vms.size} VMs (fraction $fraction) into subset of ${res.size} VMs" } + + return res + } +} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/CompositeComputeWorkload.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/CompositeComputeWorkload.kt deleted file mode 100644 index 998dbb34..00000000 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/CompositeComputeWorkload.kt +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2021 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.compute.workload.internal - -import mu.KotlinLogging -import org.opendc.compute.workload.ComputeWorkload -import org.opendc.compute.workload.ComputeWorkloadLoader -import org.opendc.compute.workload.Task -import java.util.random.RandomGenerator - -/** - * A [ComputeWorkload] that samples multiple workloads based on the total load of all workloads. - */ -internal class CompositeComputeWorkload(val sources: Map) : ComputeWorkload { - /** - * The logging instance of this class. - */ - private val logger = KotlinLogging.logger {} - - override fun resolve( - loader: ComputeWorkloadLoader, - random: RandomGenerator, - ): List { - val traces = sources.map { (source, fraction) -> fraction to source.resolve(loader, random) } - - val totalLoad = traces.sumOf { (_, vms) -> vms.sumOf { it.totalLoad } } - - val res = mutableListOf() - - for ((fraction, vms) in traces) { - var currentLoad = 0.0 - - for (entry in vms) { - val entryLoad = entry.totalLoad - if ((currentLoad + entryLoad) / totalLoad > fraction) { - break - } - - currentLoad += entryLoad - res += entry - } - } - - val vmCount = traces.sumOf { (_, vms) -> vms.size } - logger.info { "Sampled $vmCount VMs into subset of ${res.size} VMs" } - - return res - } -} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/HpcSampledComputeWorkload.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/HpcSampledComputeWorkload.kt deleted file mode 100644 index d3bdde31..00000000 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/HpcSampledComputeWorkload.kt +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (c) 2021 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.compute.workload.internal - -import mu.KotlinLogging -import org.opendc.compute.workload.ComputeWorkload -import org.opendc.compute.workload.ComputeWorkloadLoader -import org.opendc.compute.workload.Task -import java.util.UUID -import java.util.random.RandomGenerator - -/** - * A [ComputeWorkload] that samples HPC VMs in the workload. - * - * @param fraction The fraction of load/virtual machines to sample - * @param sampleLoad A flag to indicate that the sampling should be based on the total load or on the number of VMs. - */ -internal class HpcSampledComputeWorkload( - val source: ComputeWorkload, - val fraction: Double, - val sampleLoad: Boolean = false, -) : ComputeWorkload { - /** - * The logging instance of this class. - */ - private val logger = KotlinLogging.logger {} - - /** - * The pattern to match compute nodes in the workload. - */ - private val pattern = Regex("^(ComputeNode|cn).*") - - override fun resolve( - loader: ComputeWorkloadLoader, - random: RandomGenerator, - ): List { - val vms = source.resolve(loader, random) - - val (hpc, nonHpc) = - vms.partition { entry -> - val name = entry.name - name.matches(pattern) - } - - val hpcSequence = - generateSequence(0) { it + 1 } - .map { index -> - val res = mutableListOf() - hpc.mapTo(res) { sample(it, index) } - res - } - .flatten() - - val nonHpcSequence = - generateSequence(0) { it + 1 } - .map { index -> - val res = mutableListOf() - nonHpc.mapTo(res) { sample(it, index) } - res - } - .flatten() - - logger.debug { "Found ${hpc.size} HPC workloads and ${nonHpc.size} non-HPC workloads" } - - val totalLoad = vms.sumOf { it.totalLoad } - - logger.debug { "Total trace load: $totalLoad" } - var hpcCount = 0 - var hpcLoad = 0.0 - var nonHpcCount = 0 - var nonHpcLoad = 0.0 - - val res = mutableListOf() - - if (sampleLoad) { - var currentLoad = 0.0 - for (entry in hpcSequence) { - val entryLoad = entry.totalLoad - if ((currentLoad + entryLoad) / totalLoad > fraction) { - break - } - - hpcLoad += entryLoad - hpcCount += 1 - currentLoad += entryLoad - res += entry - } - - for (entry in nonHpcSequence) { - val entryLoad = entry.totalLoad - if ((currentLoad + entryLoad) / totalLoad > 1) { - break - } - - nonHpcLoad += entryLoad - nonHpcCount += 1 - currentLoad += entryLoad - res += entry - } - } else { - hpcSequence - .take((fraction * vms.size).toInt()) - .forEach { entry -> - hpcLoad += entry.totalLoad - hpcCount += 1 - res.add(entry) - } - - nonHpcSequence - .take(((1 - fraction) * vms.size).toInt()) - .forEach { entry -> - nonHpcLoad += entry.totalLoad - nonHpcCount += 1 - res.add(entry) - } - } - - logger.debug { "HPC $hpcCount (load $hpcLoad) and non-HPC $nonHpcCount (load $nonHpcLoad)" } - logger.debug { "Total sampled load: ${hpcLoad + nonHpcLoad}" } - logger.info { "Sampled ${vms.size} VMs (fraction $fraction) into subset of ${res.size} VMs" } - - return res - } - - /** - * Sample a random trace entry. - */ - private fun sample( - entry: Task, - i: Int, - ): Task { - val uid = UUID.nameUUIDFromBytes("${entry.uid}-$i".toByteArray()) - return entry.copy(uid = uid) - } -} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/LoadSampledComputeWorkload.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/LoadSampledComputeWorkload.kt deleted file mode 100644 index 534ac6a0..00000000 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/LoadSampledComputeWorkload.kt +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2021 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.compute.workload.internal - -import mu.KotlinLogging -import org.opendc.compute.workload.ComputeWorkload -import org.opendc.compute.workload.ComputeWorkloadLoader -import org.opendc.compute.workload.Task -import java.util.random.RandomGenerator - -/** - * A [ComputeWorkload] that is sampled based on total load. - */ -internal class LoadSampledComputeWorkload(val source: ComputeWorkload, val fraction: Double) : ComputeWorkload { - /** - * The logging instance of this class. - */ - private val logger = KotlinLogging.logger {} - - override fun resolve( - loader: ComputeWorkloadLoader, - random: RandomGenerator, - ): List { - val vms = source.resolve(loader, random) // fixme: Should be shuffled, otherwise the first fraction is always chosen - val res = mutableListOf() - - val totalLoad = vms.sumOf { it.totalLoad } - var currentLoad = 0.0 - - for (entry in vms) { - val entryLoad = entry.totalLoad - if ((currentLoad + entryLoad) / totalLoad > fraction) { - break - } - - currentLoad += entryLoad - res += entry - } - - logger.info { "Sampled ${vms.size} VMs (fraction $fraction) into subset of ${res.size} VMs" } - - return res - } -} diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/TraceComputeWorkload.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/TraceComputeWorkload.kt deleted file mode 100644 index d796341b..00000000 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/TraceComputeWorkload.kt +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2021 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.compute.workload.internal - -import org.opendc.compute.workload.ComputeWorkload -import org.opendc.compute.workload.ComputeWorkloadLoader -import org.opendc.compute.workload.Task -import java.util.random.RandomGenerator - -/** - * A [ComputeWorkload] from a trace. - */ -internal class TraceComputeWorkload(val name: String, val format: String) : ComputeWorkload { - override fun resolve( - loader: ComputeWorkloadLoader, - random: RandomGenerator, - ): List { - return loader.get(name, format) - } -} 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 index 7f34c508..a3414054 100644 --- 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 @@ -23,9 +23,8 @@ 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 org.opendc.compute.workload.ComputeWorkloadLoader +import org.opendc.compute.workload.WorkloadLoader import java.io.File /** @@ -61,12 +60,22 @@ public enum class WorkloadTypes { } /** - * - *TODO: move to separate file - * @param type + * Create a workload loader for the given workload */ -public fun getWorkloadType(type: WorkloadTypes): ComputeWorkload { +public fun getWorkloadLoader( + type: WorkloadTypes, + pathToFile: File, + checkpointInterval: Long, + checkpointDuration: Long, + checkpointIntervalScaling: Double, +): WorkloadLoader { return when (type) { - WorkloadTypes.ComputeWorkload -> trace().sampleByLoad(1.0) + WorkloadTypes.ComputeWorkload -> + ComputeWorkloadLoader( + pathToFile, + checkpointInterval, + checkpointDuration, + checkpointIntervalScaling, + ) } } 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 b6b255a6..cda43eb7 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 @@ -32,9 +32,8 @@ import org.opendc.compute.simulator.scheduler.createComputeScheduler 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.experiment.Scenario -import org.opendc.experiments.base.experiment.specs.getWorkloadType +import org.opendc.experiments.base.experiment.specs.getWorkloadLoader import org.opendc.simulator.kotlin.runSimulation import java.io.File import java.time.Duration @@ -81,16 +80,26 @@ public fun runScenario( val checkpointDuration = scenario.checkpointModelSpec?.checkpointDuration ?: 0L val checkpointIntervalScaling = scenario.checkpointModelSpec?.checkpointIntervalScaling ?: 1.0 +// val workloadLoader = +// ComputeWorkloadLoader( +// File(scenario.workloadSpec.pathToFile), +// checkpointInterval, +// checkpointDuration, +// checkpointIntervalScaling, +// ) +// val tasks = getWorkloadType(scenario.workloadSpec.type).resolve(workloadLoader, Random(seed)) + val workloadLoader = - ComputeWorkloadLoader( + getWorkloadLoader( + scenario.workloadSpec.type, File(scenario.workloadSpec.pathToFile), checkpointInterval, checkpointDuration, checkpointIntervalScaling, ) - val tasks = getWorkloadType(scenario.workloadSpec.type).resolve(workloadLoader, Random(seed)) + val workload = workloadLoader.load() - val startTimeLong = tasks.minOf { it.submissionTime }.toEpochMilli() + val startTimeLong = workload.minOf { it.submissionTime }.toEpochMilli() val startTime = Duration.ofMillis(startTimeLong) val topology = clusterTopology(scenario.topologySpec.pathToFile, Random(seed)) @@ -106,12 +115,12 @@ public fun runScenario( addExportModel(provisioner, serviceDomain, scenario, seed, startTime, scenario.id) val service = provisioner.registry.resolve(serviceDomain, ComputeService::class.java)!! - service.setTasksExpected(tasks.size) + service.setTasksExpected(workload.size) service.setMetricReader(provisioner.getMonitor()) service.replay( timeSource, - tasks, + workload, failureModelSpec = scenario.failureModelSpec, seed = seed, ) diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/OpenDCRunner.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/OpenDCRunner.kt index 7ceb32e6..8684132c 100644 --- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/OpenDCRunner.kt +++ b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/OpenDCRunner.kt @@ -35,8 +35,6 @@ import org.opendc.compute.topology.specs.ClusterSpec import org.opendc.compute.topology.specs.HostSpec import org.opendc.compute.topology.specs.PowerSourceSpec import org.opendc.compute.workload.ComputeWorkloadLoader -import org.opendc.compute.workload.sampleByLoad -import org.opendc.compute.workload.trace import org.opendc.experiments.base.runner.replay import org.opendc.simulator.compute.cpu.CpuPowerModels import org.opendc.simulator.compute.models.CpuModel @@ -273,9 +271,11 @@ public class OpenDCRunner( Provisioner(dispatcher, seed).use { provisioner -> - val workload = - trace(scenario.workload.trace.id).sampleByLoad(scenario.workload.samplingFraction) - val vms = workload.resolve(workloadLoader, Random(seed)) +// val workload = +// trace(scenario.workload.trace.id).sampleByLoad(scenario.workload.samplingFraction) +// val vms = workload.resolve(workloadLoader, Random(seed)) + + val vms = workloadLoader.sampleByLoad(scenario.workload.samplingFraction) val startTime = vms.minOf { it.submissionTime }.toEpochMilli() provisioner.runSteps( -- cgit v1.2.3