summaryrefslogtreecommitdiff
path: root/opendc-compute/opendc-compute-workload/src/main/kotlin/org
diff options
context:
space:
mode:
authorDante Niewenhuis <d.niewenhuis@hotmail.com>2025-01-22 14:35:21 +0100
committerGitHub <noreply@github.com>2025-01-22 14:35:21 +0100
commit9403af12f5d015497894fab5a2dea93eb094ecaf (patch)
treeceae49147e70389b761930677a1d5df5d5047dd8 /opendc-compute/opendc-compute-workload/src/main/kotlin/org
parent5c193e77812c306e968e9fae6855ebbc39cdf0fc (diff)
Simplified the WorkloadLoader into a single class that can be extended when new workload types are added (#294)
Diffstat (limited to 'opendc-compute/opendc-compute-workload/src/main/kotlin/org')
-rw-r--r--opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkload.kt38
-rw-r--r--opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt21
-rw-r--r--opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloads.kt66
-rw-r--r--opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/WorkloadLoader.kt (renamed from opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/LoadSampledComputeWorkload.kt)29
-rw-r--r--opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/CompositeComputeWorkload.kt69
-rw-r--r--opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/HpcSampledComputeWorkload.kt155
-rw-r--r--opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/TraceComputeWorkload.kt40
7 files changed, 19 insertions, 399 deletions
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<Task>
-}
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<String, SoftReference<List<Task>>>()
+ private val cache = ConcurrentHashMap<File, SoftReference<List<Task>>>()
/**
* 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<Task> {
+ override fun load(): List<Task> {
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, Double>): 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/internal/LoadSampledComputeWorkload.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/WorkloadLoader.kt
index 534ac6a0..f4a93c24 100644
--- 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/WorkloadLoader.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 AtLarge Research
+ * 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
@@ -20,28 +20,19 @@
* SOFTWARE.
*/
-package org.opendc.compute.workload.internal
-
+package org.opendc.compute.workload
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.
- */
+public abstract class WorkloadLoader {
private val logger = KotlinLogging.logger {}
- override fun resolve(
- loader: ComputeWorkloadLoader,
- random: RandomGenerator,
- ): List<Task> {
- val vms = source.resolve(loader, random) // fixme: Should be shuffled, otherwise the first fraction is always chosen
+ public abstract fun load(): List<Task>
+
+ /**
+ * Load the workload at sample tasks until a fraction of the workload is loaded
+ */
+ public fun sampleByLoad(fraction: Double): List<Task> {
+ val vms = this.load()
val res = mutableListOf<Task>()
val totalLoad = vms.sumOf { it.totalLoad }
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, Double>) : ComputeWorkload {
- /**
- * The logging instance of this class.
- */
- private val logger = KotlinLogging.logger {}
-
- override fun resolve(
- loader: ComputeWorkloadLoader,
- random: RandomGenerator,
- ): List<Task> {
- val traces = sources.map { (source, fraction) -> fraction to source.resolve(loader, random) }
-
- val totalLoad = traces.sumOf { (_, vms) -> vms.sumOf { it.totalLoad } }
-
- val res = mutableListOf<Task>()
-
- 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<Task> {
- 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<Task>()
- hpc.mapTo(res) { sample(it, index) }
- res
- }
- .flatten()
-
- val nonHpcSequence =
- generateSequence(0) { it + 1 }
- .map { index ->
- val res = mutableListOf<Task>()
- 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<Task>()
-
- 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/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<Task> {
- return loader.get(name, format)
- }
-}