diff options
| author | Dante Niewenhuis <d.niewenhuis@hotmail.com> | 2025-03-24 09:15:53 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-24 09:15:53 +0100 |
| commit | 24f89ae21df182bb91d92e4a60b4049829ac4d9e (patch) | |
| tree | fd74543f27aabac92a9554808aeedbb60f657b21 /opendc-experiments/opendc-experiments-base/src/main | |
| parent | fb7d3010d6141dd518d8ebfacd41d399c3f9758d (diff) | |
Updated AllocationPolicy input (#324)
Diffstat (limited to 'opendc-experiments/opendc-experiments-base/src/main')
8 files changed, 289 insertions, 45 deletions
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 index 64ff51ad..06b7b89d 100644 --- 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 @@ -22,12 +22,12 @@ package org.opendc.experiments.base.experiment -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 +import org.opendc.experiments.base.experiment.specs.allocation.AllocationPolicySpec /** * A data class representing a scenario for a set of experiments. 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 deleted file mode 100644 index 0bd3d476..00000000 --- a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/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.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/ExperimentSpec.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/ExperimentSpec.kt index 91d0b986..df0a862d 100644 --- 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 @@ -25,7 +25,10 @@ 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.scheduler.ComputeSchedulerEnum import org.opendc.compute.simulator.telemetry.parquet.ComputeExportConfig +import org.opendc.experiments.base.experiment.specs.allocation.AllocationPolicySpec +import org.opendc.experiments.base.experiment.specs.allocation.PrefabAllocationPolicySpec import java.util.UUID /** @@ -55,7 +58,7 @@ public data class ExperimentSpec( val maxNumFailures: Set<Int> = setOf(10), val topologies: Set<ScenarioTopologySpec>, val workloads: Set<WorkloadSpec>, - val allocationPolicies: Set<AllocationPolicySpec> = setOf(AllocationPolicySpec()), + val allocationPolicies: Set<AllocationPolicySpec> = setOf(PrefabAllocationPolicySpec(ComputeSchedulerEnum.Mem)), val failureModels: Set<FailureModelSpec?> = setOf(null), val checkpointModels: Set<CheckpointModelSpec?> = setOf(null), ) { 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 index eb0d71ed..7d24c55d 100644 --- 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 @@ -23,6 +23,9 @@ package org.opendc.experiments.base.experiment.specs import kotlinx.serialization.Serializable +import org.opendc.compute.simulator.scheduler.ComputeSchedulerEnum +import org.opendc.experiments.base.experiment.specs.allocation.AllocationPolicySpec +import org.opendc.experiments.base.experiment.specs.allocation.PrefabAllocationPolicySpec @Serializable public data class ScenarioSpec( @@ -31,7 +34,7 @@ public data class ScenarioSpec( val outputFolder: String = "output", val topology: ScenarioTopologySpec, val workload: WorkloadSpec, - val allocationPolicy: AllocationPolicySpec = AllocationPolicySpec(), + val allocationPolicy: AllocationPolicySpec = PrefabAllocationPolicySpec(ComputeSchedulerEnum.Mem), val exportModel: ExportModelSpec = ExportModelSpec(), val failureModel: FailureModelSpec? = null, val checkpointModel: CheckpointModelSpec? = null, diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/allocation/AllocationPolicySpec.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/allocation/AllocationPolicySpec.kt new file mode 100644 index 00000000..686bb84e --- /dev/null +++ b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/allocation/AllocationPolicySpec.kt @@ -0,0 +1,85 @@ +/* + * 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.allocation + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import org.opendc.compute.simulator.scheduler.ComputeScheduler +import org.opendc.compute.simulator.scheduler.ComputeSchedulerEnum +import org.opendc.compute.simulator.scheduler.FilterScheduler +import org.opendc.compute.simulator.scheduler.TimeshiftScheduler +import org.opendc.compute.simulator.scheduler.createPrefabComputeScheduler +import java.time.InstantSource +import java.util.random.RandomGenerator + +/** + * specification describing how tasks are allocated + */ +@Serializable +public sealed interface AllocationPolicySpec + +@Serializable +@SerialName("prefab") +public data class PrefabAllocationPolicySpec( + val policyName: ComputeSchedulerEnum = ComputeSchedulerEnum.Mem, +) : AllocationPolicySpec { + public val name: String = policyName.toString() +} + +@Serializable +@SerialName("filter") +public data class FilterAllocationPolicySpec( + val filters: List<HostFilterSpec>, + val weighers: List<HostWeigherSpec>, + val subsetSize: Int = 1, +) : AllocationPolicySpec + +@Serializable +@SerialName("timeshift") +public data class TimeShiftAllocationPolicySpec( + val filters: List<HostFilterSpec>, + val weighers: List<HostWeigherSpec>, + val windowSize: Int = 168, + val subsetSize: Int = 1, + val peakShift: Boolean = true, +) : AllocationPolicySpec + +public fun createComputeScheduler( + spec: AllocationPolicySpec, + seeder: RandomGenerator, + clock: InstantSource, +): ComputeScheduler { + return when (spec) { + is PrefabAllocationPolicySpec -> createPrefabComputeScheduler(spec.policyName, seeder, clock) + is FilterAllocationPolicySpec -> { + val filters = spec.filters.map { createHostFilter(it) } + val weighers = spec.weighers.map { createHostWeigher(it) } + FilterScheduler(filters, weighers, spec.subsetSize, seeder) + } + is TimeShiftAllocationPolicySpec -> { + val filters = spec.filters.map { createHostFilter(it) } + val weighers = spec.weighers.map { createHostWeigher(it) } + TimeshiftScheduler(filters, weighers, spec.windowSize, clock, spec.subsetSize, spec.peakShift, seeder) + } + } +} diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/allocation/HostFilterSpec.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/allocation/HostFilterSpec.kt new file mode 100644 index 00000000..6a0ed2b8 --- /dev/null +++ b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/allocation/HostFilterSpec.kt @@ -0,0 +1,111 @@ +/* + * 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.experiments.base.experiment.specs.allocation + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import org.opendc.compute.simulator.scheduler.filters.ComputeFilter +import org.opendc.compute.simulator.scheduler.filters.DifferentHostFilter +import org.opendc.compute.simulator.scheduler.filters.HostFilter +import org.opendc.compute.simulator.scheduler.filters.InstanceCountFilter +import org.opendc.compute.simulator.scheduler.filters.RamFilter +import org.opendc.compute.simulator.scheduler.filters.SameHostFilter +import org.opendc.compute.simulator.scheduler.filters.VCpuCapacityFilter +import org.opendc.compute.simulator.scheduler.filters.VCpuFilter + +public enum class HostFilterEnum { + Compute, + DifferentHost, + InstanceCount, + Ram, + SameHost, + VCpuCapacity, + VCpu, +} + +/** + * A specification for a host filter. + * + * A host filter can be defined in a JSON file by adding the serialName as the type parameter. + * + * The user then has to specify any additional parameters required for the filter. + */ +@Serializable +public sealed class HostFilterSpec + +@Serializable +@SerialName("Compute") +public data class ComputeFilterSpec( + val filterName: HostFilterEnum = HostFilterEnum.Compute, +) : HostFilterSpec() + +@Serializable +@SerialName("DifferentHost") +public data class DifferentHostFilterSpec( + val filterName: HostFilterEnum = HostFilterEnum.DifferentHost, +) : HostFilterSpec() + +@Serializable +@SerialName("InstanceCount") +public data class InstanceCountHostFilterSpec( + val filterName: HostFilterEnum = HostFilterEnum.InstanceCount, + val limit: Int, +) : HostFilterSpec() + +@Serializable +@SerialName("Ram") +public data class RamHostFilterSpec( + val filterName: HostFilterEnum = HostFilterEnum.Ram, + val allocationRatio: Double = 1.0, +) : HostFilterSpec() + +@Serializable +@SerialName("SameHost") +public data class SameHostHostFilterSpec( + val filterName: HostFilterEnum = HostFilterEnum.SameHost, +) : HostFilterSpec() + +@Serializable +@SerialName("VCpuCapacity") +public data class VCpuCapacityHostFilterSpec( + val filterName: HostFilterEnum = HostFilterEnum.VCpuCapacity, +) : HostFilterSpec() + +@Serializable +@SerialName("VCpu") +public data class VCpuHostFilterSpec( + val filterName: HostFilterEnum = HostFilterEnum.VCpu, + val allocationRatio: Double = 1.0, +) : HostFilterSpec() + +public fun createHostFilter(filterSpec: HostFilterSpec): HostFilter { + return when (filterSpec) { + is ComputeFilterSpec -> ComputeFilter() + is DifferentHostFilterSpec -> DifferentHostFilter() + is InstanceCountHostFilterSpec -> InstanceCountFilter(filterSpec.limit) + is RamHostFilterSpec -> RamFilter(filterSpec.allocationRatio) + is SameHostHostFilterSpec -> SameHostFilter() + is VCpuCapacityHostFilterSpec -> VCpuCapacityFilter() + is VCpuHostFilterSpec -> VCpuFilter(filterSpec.allocationRatio) + } +} diff --git a/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/allocation/HostWeigherSpec.kt b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/allocation/HostWeigherSpec.kt new file mode 100644 index 00000000..60f5ff8b --- /dev/null +++ b/opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/allocation/HostWeigherSpec.kt @@ -0,0 +1,82 @@ +/* + * 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.experiments.base.experiment.specs.allocation + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import org.opendc.compute.simulator.scheduler.weights.CoreRamWeigher +import org.opendc.compute.simulator.scheduler.weights.HostWeigher +import org.opendc.compute.simulator.scheduler.weights.InstanceCountWeigher +import org.opendc.compute.simulator.scheduler.weights.RamWeigher +import org.opendc.compute.simulator.scheduler.weights.VCpuCapacityWeigher +import org.opendc.compute.simulator.scheduler.weights.VCpuWeigher + +/** + * A specification for a host weigher. + * + * A host weigher can be defined in a JSON file by adding the serialName as the type parameter. + * + * The user then has to specify any additional parameters required for the weigher. + */ +@Serializable +public sealed class HostWeigherSpec + +@Serializable +@SerialName("CoreRam") +public data class CoreRamWeigherSpec( + val multiplier: Double, +) : HostWeigherSpec() + +@Serializable +@SerialName("InstanceCount") +public data class InstanceCountWeigherSpec( + val multiplier: Double, +) : HostWeigherSpec() + +@Serializable +@SerialName("Ram") +public data class RamWeigherSpec( + val multiplier: Double, +) : HostWeigherSpec() + +@Serializable +@SerialName("VCpuCapacity") +public data class VCpuCapacityWeigherSpec( + val multiplier: Double, +) : HostWeigherSpec() + +@Serializable +@SerialName("VCpu") +public data class VCpuWeigherSpec( + val multiplier: Double, +) : HostWeigherSpec() + +public fun createHostWeigher(weigherSpec: HostWeigherSpec): HostWeigher { + return when (weigherSpec) { + is CoreRamWeigherSpec -> CoreRamWeigher(weigherSpec.multiplier) + is InstanceCountWeigherSpec -> InstanceCountWeigher(weigherSpec.multiplier) + is RamWeigherSpec -> RamWeigher(weigherSpec.multiplier) + is VCpuCapacityWeigherSpec -> VCpuCapacityWeigher(weigherSpec.multiplier) + is VCpuWeigherSpec -> VCpuWeigher(weigherSpec.multiplier) + } +} 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 f8cbb4fd..43bab2f5 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 @@ -28,11 +28,11 @@ import org.opendc.compute.simulator.provisioner.Provisioner import org.opendc.compute.simulator.provisioner.registerComputeMonitor import org.opendc.compute.simulator.provisioner.setupComputeService import org.opendc.compute.simulator.provisioner.setupHosts -import org.opendc.compute.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.experiments.base.experiment.Scenario +import org.opendc.experiments.base.experiment.specs.allocation.createComputeScheduler import org.opendc.experiments.base.experiment.specs.getScalingPolicy import org.opendc.experiments.base.experiment.specs.getWorkloadLoader import org.opendc.simulator.compute.power.CarbonReceiver @@ -108,7 +108,7 @@ public fun runScenario( { val computeScheduler = createComputeScheduler( - scenario.allocationPolicySpec.policyType, + scenario.allocationPolicySpec, Random(it.seeder.nextLong()), timeSource, ) |
