diff options
| author | Dante Niewenhuis <d.niewenhuis@hotmail.com> | 2025-02-03 13:11:48 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-02-03 13:11:48 +0100 |
| commit | df1028c71cb6d50db886c8076c7139ec24feb6d7 (patch) | |
| tree | 9ab240a87df720d5eec588027c84a4d614bb4394 /opendc-compute | |
| parent | f471d06e842f3675b634c4ceceb108cfd8817837 (diff) | |
Added Batteries (#300)
* Batteries are implemented. Small problem with the deletion when running larger workloads.
Added mock files for the Battery implementation. Updated the Carbon Model to allow for multiple receivers of CarbonIntensity
* Implemented batteries in OpenDC.
* Spotless applied
Diffstat (limited to 'opendc-compute')
6 files changed, 122 insertions, 8 deletions
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt index 7f5f09eb..83968d35 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt @@ -96,6 +96,7 @@ public class Guest( val scalingPolicy = NoDelayScaling() + // TODO: This is not being used at the moment val bootworkload = TraceWorkload( ArrayList( diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/HostsProvisioningStep.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/HostsProvisioningStep.kt index 933b4e63..572335e1 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/HostsProvisioningStep.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/HostsProvisioningStep.kt @@ -27,7 +27,11 @@ import org.opendc.compute.simulator.host.SimHost import org.opendc.compute.simulator.service.ComputeService import org.opendc.compute.topology.specs.ClusterSpec import org.opendc.compute.topology.specs.HostSpec +import org.opendc.simulator.compute.power.CarbonModel import org.opendc.simulator.compute.power.SimPowerSource +import org.opendc.simulator.compute.power.batteries.BatteryAggregator +import org.opendc.simulator.compute.power.batteries.SimBattery +import org.opendc.simulator.compute.power.batteries.policy.SingleThresholdBatteryPolicy import org.opendc.simulator.engine.engine.FlowEngine import org.opendc.simulator.engine.graph.FlowDistributor @@ -57,15 +61,50 @@ public class HostsProvisioningStep internal constructor( for (cluster in clusterSpecs) { // Create the Power Source to which hosts are connected + // Create Power Source + val simPowerSource = SimPowerSource(graph, cluster.powerSource.totalPower.toDouble()) + simPowerSources.add(simPowerSource) + service.addPowerSource(simPowerSource) + + val hostDistributor = FlowDistributor(graph) + val carbonFragments = getCarbonFragments(cluster.powerSource.carbonTracePath) - val simPowerSource = SimPowerSource(graph, cluster.powerSource.totalPower.toDouble(), carbonFragments, startTime) + var carbonModel: CarbonModel? = null + // Create Carbon Model + if (carbonFragments != null) { + carbonModel = CarbonModel(graph, carbonFragments, startTime) + carbonModel.addReceiver(simPowerSource) + } - service.addPowerSource(simPowerSource) - simPowerSources.add(simPowerSource) + if (cluster.battery != null) { + // Create Battery Distributor + val batteryDistributor = FlowDistributor(graph) + graph.addEdge(batteryDistributor, simPowerSource) - val powerDistributor = FlowDistributor(graph) - graph.addEdge(powerDistributor, simPowerSource) + // Create Battery + val battery = + SimBattery(graph, cluster.battery!!.capacity, cluster.battery!!.chargingSpeed, cluster.battery!!.initialCharge) + graph.addEdge(battery, batteryDistributor) + + // Create Aggregator + val batteryAggregator = BatteryAggregator(graph, battery, batteryDistributor) + + // Create BatteryPolicy + val batteryPolicy = + SingleThresholdBatteryPolicy( + graph, + battery, + batteryAggregator, + cluster.battery!!.batteryPolicy.carbonThreshold, + ) + + carbonModel?.addReceiver(batteryPolicy) + + graph.addEdge(hostDistributor, batteryAggregator) + } else { + graph.addEdge(hostDistributor, simPowerSource) + } // Create hosts, they are connected to the powerMux when SimMachine is created for (hostSpec in cluster.hostSpecs) { @@ -78,7 +117,7 @@ public class HostsProvisioningStep internal constructor( graph, hostSpec.model, hostSpec.cpuPowerModel, - powerDistributor, + hostDistributor, ) require(simHosts.add(simHost)) { "Host with uid ${hostSpec.uid} already exists" } @@ -92,7 +131,6 @@ public class HostsProvisioningStep internal constructor( } for (simPowerSource in simPowerSources) { - // TODO: add close function simPowerSource.close() } } diff --git a/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/TopologyFactories.kt b/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/TopologyFactories.kt index f271c028..721119cd 100644 --- a/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/TopologyFactories.kt +++ b/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/TopologyFactories.kt @@ -24,6 +24,7 @@ package org.opendc.compute.topology +import org.opendc.compute.topology.specs.BatterySpec import org.opendc.compute.topology.specs.ClusterJSONSpec import org.opendc.compute.topology.specs.ClusterSpec import org.opendc.compute.topology.specs.HostJSONSpec @@ -109,8 +110,21 @@ private fun ClusterJSONSpec.toClusterSpec(random: RandomGenerator): ClusterSpec totalPower = this.powerSource.totalPower, carbonTracePath = this.powerSource.carbonTracePath, ) + + var batterySpec: BatterySpec? = null + if (this.battery != null) { + batterySpec = + BatterySpec( + UUID(random.nextLong(), clusterId.toLong()), + this.battery.capacity, + this.battery.chargingSpeed, + this.battery.batteryPolicy, + this.battery.initialCharge, + ) + } + clusterId++ - return ClusterSpec(this.name, hostSpecs, powerSourceSpec) + return ClusterSpec(this.name, hostSpecs, powerSourceSpec, batterySpec) } /** diff --git a/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/specs/BatterySpec.kt b/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/specs/BatterySpec.kt new file mode 100644 index 00000000..fd849b01 --- /dev/null +++ b/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/specs/BatterySpec.kt @@ -0,0 +1,33 @@ +/* + * 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.topology.specs + +import java.util.UUID + +public data class BatterySpec( + val uid: UUID, + val capacity: Double, + val chargingSpeed: Double, + val batteryPolicy: BatteryPolicyJSONSpec, + val initialCharge: Double, +) diff --git a/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/specs/ClusterSpec.kt b/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/specs/ClusterSpec.kt index 3b49b266..6e7c8dfa 100644 --- a/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/specs/ClusterSpec.kt +++ b/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/specs/ClusterSpec.kt @@ -26,4 +26,5 @@ public data class ClusterSpec( val name: String, val hostSpecs: List<HostSpec>, val powerSource: PowerSourceSpec, + val battery: BatterySpec? = null, ) diff --git a/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/specs/TopologySpecs.kt b/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/specs/TopologySpecs.kt index 39b95347..3ccb4e59 100644 --- a/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/specs/TopologySpecs.kt +++ b/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/specs/TopologySpecs.kt @@ -51,6 +51,7 @@ public data class ClusterJSONSpec( val count: Int = 1, val hosts: List<HostJSONSpec>, val powerSource: PowerSourceJSONSpec = PowerSourceJSONSpec.DFLT, + val battery: BatteryJSONSpec? = null, val location: String = "NL", ) @@ -155,3 +156,29 @@ public data class PowerSourceJSONSpec( ) } } + +/** + * Definition of a power source used for JSON input. + * + * @property vendor + * @property modelName + * @property arch + * @property totalPower + */ +@Serializable +public data class BatteryJSONSpec( + var capacity: Double, + val chargingSpeed: Double, + val batteryPolicy: BatteryPolicyJSONSpec, + var initialCharge: Double = 0.0, +) { + init { + this.capacity *= 3600000 + this.initialCharge *= 3600000 + } +} + +@Serializable +public data class BatteryPolicyJSONSpec( + val carbonThreshold: Double, +) |
