summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--opendc-compute/opendc-compute-carbon/src/main/kotlin/org/opendc/compute/carbon/CarbonTrace.kt113
-rw-r--r--opendc-compute/opendc-compute-carbon/src/main/kotlin/org/opendc/compute/carbon/CarbonTraceLoader.kt15
-rw-r--r--opendc-compute/opendc-compute-carbon/src/main/kotlin/org/opendc/compute/carbon/CarbonTraceReader.kt15
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/service/ComputeService.java7
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/ComputeMonitorProvisioningStep.kt3
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/ComputeSteps.kt7
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/HostsProvisioningStep.kt11
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/ComputeMetricReader.kt4
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltHostExportColumns.kt10
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/HostTableReader.kt10
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/HostTableReaderImpl.kt17
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/PowerSourceTableReaderImpl.kt12
-rw-r--r--opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/TopologyFactories.kt1
-rw-r--r--opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/specs/PowerSourceSpec.kt3
-rw-r--r--opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/specs/TopologySpecs.kt4
-rw-r--r--opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/runner/ScenarioRunner.kt36
-rw-r--r--opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/ExperimentFactories.kt1
-rw-r--r--opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/Scenario.kt1
-rw-r--r--opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/ExperimentSpec.kt6
-rw-r--r--opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/scenario/specs/ScenarioSpec.kt1
-rw-r--r--opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/CarbonFragmentNew.java59
-rw-r--r--opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/CarbonModel.java109
-rw-r--r--opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/SimPowerSource.java42
-rw-r--r--opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/OpenDCRunner.kt12
24 files changed, 276 insertions, 223 deletions
diff --git a/opendc-compute/opendc-compute-carbon/src/main/kotlin/org/opendc/compute/carbon/CarbonTrace.kt b/opendc-compute/opendc-compute-carbon/src/main/kotlin/org/opendc/compute/carbon/CarbonTrace.kt
deleted file mode 100644
index 2ba3e4e3..00000000
--- a/opendc-compute/opendc-compute-carbon/src/main/kotlin/org/opendc/compute/carbon/CarbonTrace.kt
+++ /dev/null
@@ -1,113 +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.carbon
-
-import java.time.Instant
-
-/**
- * A virtual machine workload.
- *
- * @param uid The unique identifier of the virtual machine.
- * @param name The name of the virtual machine.
- * @param cpuCapacity The required CPU capacity for the VM in MHz.
- * @param cpuCount The number of vCPUs in the VM.
- * @param memCapacity The provisioned memory for the VM in MB.
- * @param startTime The start time of the VM.
- * @param stopTime The stop time of the VM.
- * @param trace The trace that belong to this VM.
- * @param interferenceProfile The interference profile of this virtual machine.
- */
-public data class CarbonFragment(
- var startTime: Long,
- var endTime: Long,
- var carbonIntensity: Double,
-) {
- init {
- require(endTime > startTime) {
- "The end time of a report should be higher than the start time -> start time: $startTime, end time: $endTime"
- }
- require(carbonIntensity >= 0.0) { "carbon intensity cannot be negative" }
- }
-}
-
-public class CarbonTrace(reports: List<CarbonFragment>? = null) {
- private var index: Int = 0
- private val numberOfReports = reports?.size
- private val reports = reports?.sortedBy { it.startTime }
-
- private fun hasPreviousReport(): Boolean {
- return index > 0
- }
-
- private fun hasNextReport(): Boolean {
- if (numberOfReports == null) {
- return false
- }
-
- return index < numberOfReports
- }
-
- public fun getCarbonIntensity(timestamp: Instant): Double {
- return getCarbonIntensity(timestamp.toEpochMilli())
- }
-
- /**
- * Get the carbon intensity of the energy at a given timestamp
- * Returns the carbon intensity of the first or last [CarbonFragment]
- * if the given timestamp is outside the information
- *
- * @param timestamp
- * @return The carbon intensity at the given timestamp in gCO2/kWh
- */
- public fun getCarbonIntensity(timestamp: Long): Double {
- if (reports == null) {
- return 0.0
- }
-
- var currentFragment: CarbonFragment
-
- while (true) {
- currentFragment = reports[index]
-
- if (currentFragment.startTime > timestamp) {
- if (hasPreviousReport()) {
- index--
- continue
- }
- break
- }
-
- if (currentFragment.endTime <= timestamp) {
- if (hasNextReport()) {
- index++
- continue
- }
- break
- }
-
- break
- }
-
- return currentFragment.carbonIntensity
- }
-}
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 b66aedf9..ccf1d81c 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,6 +22,7 @@
package org.opendc.compute.carbon
+import org.opendc.simulator.compute.power.CarbonFragmentNew
import org.opendc.trace.Trace
import org.opendc.trace.conv.CARBON_INTENSITY_TIMESTAMP
import org.opendc.trace.conv.CARBON_INTENSITY_VALUE
@@ -40,14 +41,14 @@ public class CarbonTraceLoader {
/**
* The cache of workloads.
*/
- private val cache = ConcurrentHashMap<String, SoftReference<List<CarbonFragment>>>()
+ private val cache = ConcurrentHashMap<String, SoftReference<List<CarbonFragmentNew>>>()
- private val builder = CarbonFragmentBuilder()
+ private val builder = CarbonFragmentNewBuilder()
/**
* Read the metadata into a workload.
*/
- private fun parseCarbon(trace: Trace): List<CarbonFragment> {
+ private fun parseCarbon(trace: Trace): List<CarbonFragmentNew> {
val reader = checkNotNull(trace.getTable(TABLE_CARBON_INTENSITIES)).newReader()
val startTimeCol = reader.resolve(CARBON_INTENSITY_TIMESTAMP)
@@ -76,7 +77,7 @@ public class CarbonTraceLoader {
/**
* Load the trace with the specified [name] and [format].
*/
- public fun get(pathToFile: File): List<CarbonFragment> {
+ public fun get(pathToFile: File): List<CarbonFragmentNew> {
val trace = Trace.open(pathToFile, "carbon")
return parseCarbon(trace)
@@ -92,11 +93,11 @@ public class CarbonTraceLoader {
/**
* A builder for a VM trace.
*/
- private class CarbonFragmentBuilder {
+ private class CarbonFragmentNewBuilder {
/**
* The total load of the trace.
*/
- public val fragments: MutableList<CarbonFragment> = mutableListOf<CarbonFragment>()
+ public val fragments: MutableList<CarbonFragmentNew> = mutableListOf()
/**
* Add a fragment to the trace.
@@ -109,7 +110,7 @@ public class CarbonTraceLoader {
carbonIntensity: Double,
) {
fragments.add(
- CarbonFragment(startTime.toEpochMilli(), Long.MAX_VALUE, carbonIntensity),
+ CarbonFragmentNew(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 3e0269f8..0b2b07a1 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
@@ -20,33 +20,32 @@
* SOFTWARE.
*/
-@file:JvmName("ComputeWorkloads")
+@file:JvmName("ComputeWorkloadsNew")
package org.opendc.compute.carbon
+import org.opendc.simulator.compute.power.CarbonFragmentNew
import java.io.File
import javax.management.InvalidAttributeValueException
/**
* Construct a workload from a trace.
*/
-public fun getCarbonTrace(pathToFile: String?): CarbonTrace {
+public fun getCarbonFragments(pathToFile: String?): List<CarbonFragmentNew>? {
if (pathToFile == null) {
- return CarbonTrace(null)
+ return null
}
- return getCarbonTrace(File(pathToFile))
+ return getCarbonFragments(File(pathToFile))
}
/**
* Construct a workload from a trace.
*/
-public fun getCarbonTrace(file: File): CarbonTrace {
+public fun getCarbonFragments(file: File): List<CarbonFragmentNew> {
if (!file.exists()) {
throw InvalidAttributeValueException("The carbon trace cannot be found")
}
- val fragments = CarbonTraceLoader().get(file)
-
- return CarbonTrace(fragments)
+ return CarbonTraceLoader().get(file)
}
diff --git a/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/service/ComputeService.java b/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/service/ComputeService.java
index 8df0d7d8..b6a69209 100644
--- a/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/service/ComputeService.java
+++ b/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/service/ComputeService.java
@@ -346,8 +346,11 @@ public final class ComputeService implements AutoCloseable {
public void setTaskToBeRemoved(ServiceTask task) {
this.tasksToRemove.add(task);
- if ((tasksTerminated + tasksCompleted) == tasksExpected) {
- metricReader.loggState(); // Logg the state for the final time. This will also delete all remaining tasks.
+ if ((this.tasksTerminated + this.tasksCompleted) == this.tasksExpected) {
+ if (this.metricReader != null) {
+ this.metricReader
+ .loggState(); // Logg the state for the final time. This will also delete all remaining tasks.
+ }
}
}
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/ComputeMonitorProvisioningStep.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/ComputeMonitorProvisioningStep.kt
index da6dcfbc..29e9d541 100644
--- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/ComputeMonitorProvisioningStep.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/ComputeMonitorProvisioningStep.kt
@@ -22,7 +22,6 @@
package org.opendc.compute.simulator.provisioner
-import org.opendc.compute.carbon.CarbonTrace
import org.opendc.compute.simulator.service.ComputeService
import org.opendc.compute.simulator.telemetry.ComputeMetricReader
import org.opendc.compute.simulator.telemetry.ComputeMonitor
@@ -37,7 +36,6 @@ public class ComputeMonitorProvisioningStep(
private val monitor: ComputeMonitor,
private val exportInterval: Duration,
private val startTime: Duration = Duration.ofMillis(0),
- private val carbonTrace: CarbonTrace = CarbonTrace(null),
) : ProvisioningStep {
override fun apply(ctx: ProvisioningContext): AutoCloseable {
val service =
@@ -51,7 +49,6 @@ public class ComputeMonitorProvisioningStep(
monitor,
exportInterval,
startTime,
- carbonTrace,
)
return metricReader
}
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/ComputeSteps.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/ComputeSteps.kt
index d8bb703e..7d9cae60 100644
--- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/ComputeSteps.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/ComputeSteps.kt
@@ -24,7 +24,6 @@
package org.opendc.compute.simulator.provisioner
-import org.opendc.compute.carbon.CarbonTrace
import org.opendc.compute.simulator.scheduler.ComputeScheduler
import org.opendc.compute.simulator.telemetry.ComputeMonitor
import org.opendc.compute.topology.specs.ClusterSpec
@@ -60,9 +59,8 @@ public fun registerComputeMonitor(
monitor: ComputeMonitor,
exportInterval: Duration = Duration.ofMinutes(5),
startTime: Duration = Duration.ofMillis(0),
- carbonTrace: CarbonTrace = CarbonTrace(null),
): ProvisioningStep {
- return ComputeMonitorProvisioningStep(serviceDomain, monitor, exportInterval, startTime, carbonTrace)
+ return ComputeMonitorProvisioningStep(serviceDomain, monitor, exportInterval, startTime)
}
/**
@@ -76,6 +74,7 @@ public fun registerComputeMonitor(
public fun setupHosts(
serviceDomain: String,
specs: List<ClusterSpec>,
+ startTime: Long = 0L,
): ProvisioningStep {
- return HostsProvisioningStep(serviceDomain, specs)
+ return HostsProvisioningStep(serviceDomain, specs, startTime)
}
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 d2231f0d..8e7293c8 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
@@ -22,6 +22,7 @@
package org.opendc.compute.simulator.provisioner
+import org.opendc.compute.carbon.getCarbonFragments
import org.opendc.compute.simulator.host.SimHost
import org.opendc.compute.simulator.service.ComputeService
import org.opendc.compute.topology.specs.ClusterSpec
@@ -40,6 +41,7 @@ import org.opendc.simulator.engine.FlowEngine
public class HostsProvisioningStep internal constructor(
private val serviceDomain: String,
private val clusterSpecs: List<ClusterSpec>,
+ private val startTime: Long = 0L,
) : ProvisioningStep {
override fun apply(ctx: ProvisioningContext): AutoCloseable {
val service =
@@ -54,8 +56,11 @@ public class HostsProvisioningStep internal constructor(
for (cluster in clusterSpecs) {
// Create the Power Source to which hosts are connected
- // TODO: Add connection to totalPower
- val simPowerSource = SimPowerSource(graph)
+
+ val carbonFragments = getCarbonFragments(cluster.powerSource.carbonTracePath)
+
+ val simPowerSource = SimPowerSource(graph, cluster.powerSource.totalPower.toDouble(), carbonFragments, startTime)
+
service.addPowerSource(simPowerSource)
simPowerSources.add(simPowerSource)
@@ -88,7 +93,7 @@ public class HostsProvisioningStep internal constructor(
for (simPowerSource in simPowerSources) {
// TODO: add close function
-// simPowerSource.close()
+ simPowerSource.close()
}
}
}
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/ComputeMetricReader.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/ComputeMetricReader.kt
index 3098ed55..5dab5d7a 100644
--- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/ComputeMetricReader.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/ComputeMetricReader.kt
@@ -29,7 +29,6 @@ import kotlinx.coroutines.launch
import mu.KotlinLogging
import org.opendc.common.Dispatcher
import org.opendc.common.asCoroutineDispatcher
-import org.opendc.compute.carbon.CarbonTrace
import org.opendc.compute.simulator.host.SimHost
import org.opendc.compute.simulator.service.ComputeService
import org.opendc.compute.simulator.service.ServiceTask
@@ -55,7 +54,6 @@ public class ComputeMetricReader(
private val monitor: ComputeMonitor,
private val exportInterval: Duration = Duration.ofMinutes(5),
private val startTime: Duration = Duration.ofMillis(0),
- private val carbonTrace: CarbonTrace = CarbonTrace(null),
) : AutoCloseable {
private val logger = KotlinLogging.logger {}
private val scope = CoroutineScope(dispatcher.asCoroutineDispatcher())
@@ -119,7 +117,6 @@ public class ComputeMetricReader(
HostTableReaderImpl(
it,
startTime,
- carbonTrace,
)
}
reader.record(now)
@@ -152,7 +149,6 @@ public class ComputeMetricReader(
PowerSourceTableReaderImpl(
it,
startTime,
- carbonTrace,
)
}
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltHostExportColumns.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltHostExportColumns.kt
index 1b76da6b..805b224d 100644
--- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltHostExportColumns.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltHostExportColumns.kt
@@ -154,16 +154,6 @@ public object DfltHostExportColumns {
field = Types.required(FLOAT).named("energy_usage"),
) { it.energyUsage }
- public val CARBON_INTENSITY: ExportColumn<HostTableReader> =
- ExportColumn(
- field = Types.required(FLOAT).named("carbon_intensity"),
- ) { it.carbonIntensity }
-
- public val CARBON_EMISSION: ExportColumn<HostTableReader> =
- ExportColumn(
- field = Types.required(FLOAT).named("carbon_emission"),
- ) { it.carbonEmission }
-
public val UP_TIME: ExportColumn<HostTableReader> =
ExportColumn(
field = Types.required(INT64).named("uptime"),
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/HostTableReader.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/HostTableReader.kt
index cf8d3c8c..35565f82 100644
--- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/HostTableReader.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/HostTableReader.kt
@@ -123,16 +123,6 @@ public interface HostTableReader : Exportable {
public val energyUsage: Double
/**
- * The current carbon intensity of the host in gCO2 / kW.
- */
- public val carbonIntensity: Double
-
- /**
- * The current carbon emission since the last deadline in g.
- */
- public val carbonEmission: Double
-
- /**
* The uptime of the host since last time in ms.
*/
public val uptime: Long
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/HostTableReaderImpl.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/HostTableReaderImpl.kt
index ab8c0036..90f091f2 100644
--- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/HostTableReaderImpl.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/HostTableReaderImpl.kt
@@ -22,7 +22,6 @@
package org.opendc.compute.simulator.telemetry.table
-import org.opendc.compute.carbon.CarbonTrace
import org.opendc.compute.simulator.host.SimHost
import java.time.Duration
import java.time.Instant
@@ -33,7 +32,6 @@ import java.time.Instant
public class HostTableReaderImpl(
host: SimHost,
private val startTime: Duration = Duration.ofMillis(0),
- private val carbonTrace: CarbonTrace = CarbonTrace(null),
) : HostTableReader {
override fun copy(): HostTableReader {
val newHostTable =
@@ -61,8 +59,6 @@ public class HostTableReaderImpl(
_cpuLostTime = table.cpuLostTime
_powerDraw = table.powerDraw
_energyUsage = table.energyUsage
- _carbonIntensity = table.carbonIntensity
- _carbonEmission = table.carbonEmission
_uptime = table.uptime
_downtime = table.downtime
_bootTime = table.bootTime
@@ -150,14 +146,6 @@ public class HostTableReaderImpl(
private var _energyUsage = 0.0
private var previousEnergyUsage = 0.0
- override val carbonIntensity: Double
- get() = _carbonIntensity
- private var _carbonIntensity = 0.0
-
- override val carbonEmission: Double
- get() = _carbonEmission
- private var _carbonEmission = 0.0
-
override val uptime: Long
get() = _uptime - previousUptime
private var _uptime = 0L
@@ -200,9 +188,6 @@ public class HostTableReaderImpl(
_cpuLostTime = hostCpuStats.lostTime
_powerDraw = hostSysStats.powerDraw
_energyUsage = hostSysStats.energyUsage
- _carbonIntensity = carbonTrace.getCarbonIntensity(timestampAbsolute)
-
- _carbonEmission = carbonIntensity * (energyUsage / 3600000.0) // convert energy usage from J to kWh
_uptime = hostSysStats.uptime.toMillis()
_downtime = hostSysStats.downtime.toMillis()
_bootTime = hostSysStats.bootTime
@@ -234,7 +219,5 @@ public class HostTableReaderImpl(
_powerDraw = 0.0
_energyUsage = 0.0
- _carbonIntensity = 0.0
- _carbonEmission = 0.0
}
}
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/PowerSourceTableReaderImpl.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/PowerSourceTableReaderImpl.kt
index 91918ea8..6a44d1ea 100644
--- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/PowerSourceTableReaderImpl.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/PowerSourceTableReaderImpl.kt
@@ -22,7 +22,6 @@
package org.opendc.compute.simulator.telemetry.table
-import org.opendc.compute.carbon.CarbonTrace
import org.opendc.simulator.compute.power.SimPowerSource
import java.time.Duration
import java.time.Instant
@@ -33,7 +32,6 @@ import java.time.Instant
public class PowerSourceTableReaderImpl(
powerSource: SimPowerSource,
private val startTime: Duration = Duration.ofMillis(0),
- private val carbonTrace: CarbonTrace = CarbonTrace(null),
) : PowerSourceTableReader {
override fun copy(): PowerSourceTableReader {
val newPowerSourceTable =
@@ -84,8 +82,9 @@ public class PowerSourceTableReaderImpl(
private var _carbonIntensity = 0.0
override val carbonEmission: Double
- get() = _carbonEmission
+ get() = _carbonEmission - previousCarbonEmission
private var _carbonEmission = 0.0
+ private var previousCarbonEmission = 0.0
/**
* Record the next cycle.
@@ -95,10 +94,12 @@ public class PowerSourceTableReaderImpl(
_timestampAbsolute = now + startTime
_hostsConnected = 0
+
+ powerSource.updateCounters()
_powerDraw = powerSource.powerDraw
_energyUsage = powerSource.energyUsage
- _carbonIntensity = 0.0
- _carbonEmission = carbonIntensity * (energyUsage / 3600000.0)
+ _carbonIntensity = powerSource.carbonIntensity
+ _carbonEmission = powerSource.carbonEmission
}
/**
@@ -106,6 +107,7 @@ public class PowerSourceTableReaderImpl(
*/
override fun reset() {
previousEnergyUsage = _energyUsage
+ previousCarbonEmission = _carbonEmission
_hostsConnected = 0
_powerDraw = 0.0
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 76c653bf..f271c028 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
@@ -107,6 +107,7 @@ private fun ClusterJSONSpec.toClusterSpec(random: RandomGenerator): ClusterSpec
PowerSourceSpec(
UUID(random.nextLong(), (clusterId).toLong()),
totalPower = this.powerSource.totalPower,
+ carbonTracePath = this.powerSource.carbonTracePath,
)
clusterId++
return ClusterSpec(this.name, hostSpecs, powerSourceSpec)
diff --git a/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/specs/PowerSourceSpec.kt b/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/specs/PowerSourceSpec.kt
index 79770684..179e8f9e 100644
--- a/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/specs/PowerSourceSpec.kt
+++ b/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/specs/PowerSourceSpec.kt
@@ -29,5 +29,6 @@ public data class PowerSourceSpec(
val uid: UUID,
val name: String = "unknown",
val meta: Map<String, Any> = emptyMap(),
- val totalPower: Long,
+ val totalPower: Long = Long.MAX_VALUE,
+ val carbonTracePath: String? = 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 9acdf72a..cdc1d96a 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
@@ -115,6 +115,7 @@ public data class PowerModelSpec(
val power: Power = Power.ofWatts(400),
val maxPower: Power,
val idlePower: Power,
+ val carbonTracePaths: String? = null,
) {
init {
require(maxPower >= idlePower) { "The max power of a power model can not be less than the idle power" }
@@ -144,7 +145,8 @@ public data class PowerSourceJSONSpec(
val vendor: String = "unknown",
val modelName: String = "unknown",
val arch: String = "unknown",
- val totalPower: Long,
+ val totalPower: Long = Long.MAX_VALUE,
+ val carbonTracePath: String? = null,
) {
public companion object {
public val DFLT: PowerSourceJSONSpec =
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 d803fd7e..d525e066 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
@@ -24,8 +24,6 @@ package org.opendc.experiments.base.runner
import me.tongfei.progressbar.ProgressBarBuilder
import me.tongfei.progressbar.ProgressBarStyle
-import org.opendc.compute.carbon.CarbonTrace
-import org.opendc.compute.carbon.getCarbonTrace
import org.opendc.compute.simulator.provisioner.Provisioner
import org.opendc.compute.simulator.provisioner.registerComputeMonitor
import org.opendc.compute.simulator.provisioner.setupComputeService
@@ -82,16 +80,6 @@ public fun runScenario(
val serviceDomain = "compute.opendc.org"
Provisioner(dispatcher, seed).use { provisioner ->
- val topology = clusterTopology(scenario.topologySpec.pathToFile, Random(seed))
- provisioner.runSteps(
- setupComputeService(
- serviceDomain,
- { createComputeScheduler(scenario.allocationPolicySpec.policyType, Random(it.seeder.nextLong())) },
- maxNumFailures = scenario.maxNumFailures,
- ),
- setupHosts(serviceDomain, topology),
- )
-
val checkpointInterval = scenario.checkpointModelSpec?.checkpointInterval ?: 0L
val checkpointDuration = scenario.checkpointModelSpec?.checkpointDuration ?: 0L
val checkpointIntervalScaling = scenario.checkpointModelSpec?.checkpointIntervalScaling ?: 1.0
@@ -105,15 +93,27 @@ public fun runScenario(
)
val tasks = getWorkloadType(scenario.workloadSpec.type).resolve(workloadLoader, Random(seed))
- val carbonTrace = getCarbonTrace(scenario.carbonTracePath)
- val startTime = Duration.ofMillis(tasks.minOf { it.submissionTime }.toEpochMilli())
- addExportModel(provisioner, serviceDomain, scenario, seed, startTime, carbonTrace, scenario.id)
+ val startTimeLong = tasks.minOf { it.submissionTime }.toEpochMilli()
+ val startTime = Duration.ofMillis(startTimeLong)
- val monitor = provisioner.getMonitor()
+ val topology = clusterTopology(scenario.topologySpec.pathToFile, Random(seed))
+ provisioner.runSteps(
+ setupComputeService(
+ serviceDomain,
+ { createComputeScheduler(scenario.allocationPolicySpec.policyType, Random(it.seeder.nextLong())) },
+ maxNumFailures = scenario.maxNumFailures,
+ ),
+ setupHosts(serviceDomain, topology, startTimeLong),
+ )
+
+ addExportModel(provisioner, serviceDomain, scenario, seed, startTime, scenario.id)
val service = provisioner.registry.resolve(serviceDomain, ComputeService::class.java)!!
- service.setMetricReader(monitor)
service.setTasksExpected(tasks.size)
+
+ val monitor = provisioner.getMonitor()
+ service.setMetricReader(monitor)
+
service.replay(
timeSource,
tasks,
@@ -139,7 +139,6 @@ public fun addExportModel(
scenario: Scenario,
seed: Long,
startTime: Duration,
- carbonTrace: CarbonTrace,
index: Int,
) {
provisioner.runStep(
@@ -153,7 +152,6 @@ public fun addExportModel(
),
Duration.ofSeconds(scenario.exportModelSpec.exportInterval),
startTime,
- carbonTrace,
),
)
}
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
index ca0578a2..524d4219 100644
--- 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
@@ -82,7 +82,6 @@ public fun getExperiment(experimentSpec: ExperimentSpec): List<Scenario> {
exportModelSpec = scenarioSpec.exportModel,
failureModelSpec = scenarioSpec.failureModel,
checkpointModelSpec = scenarioSpec.checkpointModel,
- carbonTracePath = scenarioSpec.carbonTracePath,
maxNumFailures = scenarioSpec.maxNumFailures,
)
trackScenario(scenarioSpec, outputFolder)
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
index f649e4f8..e62669e4 100644
--- 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
@@ -57,6 +57,5 @@ public data class Scenario(
val exportModelSpec: ExportModelSpec = ExportModelSpec(),
val failureModelSpec: FailureModelSpec?,
val checkpointModelSpec: CheckpointModelSpec?,
- val carbonTracePath: String? = null,
val maxNumFailures: Int = 10,
)
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
index b957ea18..7805ed2b 100644
--- 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
@@ -56,7 +56,6 @@ public data class ExperimentSpec(
val exportModels: Set<ExportModelSpec> = setOf(ExportModelSpec()),
val failureModels: Set<FailureModelSpec?> = setOf(null),
val checkpointModels: Set<CheckpointModelSpec?> = setOf(null),
- val carbonTracePaths: Set<String?> = setOf(null),
val computeExportConfig: ComputeExportConfig = ComputeExportConfig.ALL_COLUMNS,
val maxNumFailures: Set<Int> = setOf(10),
) {
@@ -75,8 +74,7 @@ public data class ExperimentSpec(
public fun getCartesian(): Sequence<ScenarioSpec> {
return sequence {
- val carbonTracePathDiv = maxNumFailures.size
- val checkpointDiv = carbonTracePathDiv * carbonTracePaths.size
+ val checkpointDiv = maxNumFailures.size
val failureDiv = checkpointDiv * checkpointModels.size
val exportDiv = failureDiv * failureModels.size
val allocationDiv = exportDiv * exportModels.size
@@ -90,7 +88,6 @@ public data class ExperimentSpec(
val exportModelList = exportModels.toList()
val failureModelList = failureModels.toList()
val checkpointModelList = checkpointModels.toList()
- val carbonTracePathList = carbonTracePaths.toList()
val maxNumFailuresList = maxNumFailures.toList()
for (i in 0 until numScenarios) {
@@ -106,7 +103,6 @@ public data class ExperimentSpec(
exportModelList[(i / exportDiv) % exportModelList.size],
failureModelList[(i / failureDiv) % failureModelList.size],
checkpointModelList[(i / checkpointDiv) % checkpointModelList.size],
- carbonTracePathList[(i / carbonTracePathDiv) % carbonTracePathList.size],
maxNumFailuresList[i % maxNumFailuresList.size],
),
)
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
index 8f2146f1..b4f04c1c 100644
--- 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
@@ -37,6 +37,5 @@ public data class ScenarioSpec(
val exportModel: ExportModelSpec = ExportModelSpec(),
val failureModel: FailureModelSpec? = null,
val checkpointModel: CheckpointModelSpec? = null,
- val carbonTracePath: String? = null,
val maxNumFailures: Int = 10,
)
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
new file mode 100644
index 00000000..78281a77
--- /dev/null
+++ b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/CarbonFragmentNew.java
@@ -0,0 +1,59 @@
+/*
+ * 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
new file mode 100644
index 00000000..87ced77a
--- /dev/null
+++ b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/CarbonModel.java
@@ -0,0 +1,109 @@
+/*
+ * 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;
+
+import java.util.List;
+import org.opendc.simulator.engine.FlowGraph;
+import org.opendc.simulator.engine.FlowNode;
+
+public class CarbonModel extends FlowNode {
+
+ private SimPowerSource powerSource;
+
+ private long startTime = 0L; // The absolute timestamp on which the workload started
+
+ private List<CarbonFragmentNew> fragments;
+ private CarbonFragmentNew current_fragment;
+
+ private int fragment_index;
+ /**
+ * Construct a new {@link FlowNode} instance.
+ *
+ * @param parentGraph The {@link FlowGraph} this stage belongs to.
+ */
+ public CarbonModel(
+ FlowGraph parentGraph,
+ SimPowerSource powerSource,
+ List<CarbonFragmentNew> carbonFragments,
+ long startTime) {
+ super(parentGraph);
+
+ this.powerSource = powerSource;
+ this.startTime = startTime;
+ this.fragments = carbonFragments;
+
+ this.fragment_index = 0;
+ this.current_fragment = this.fragments.get(this.fragment_index);
+ this.pushCarbonIntensity(this.current_fragment.getCarbonIntensity());
+ }
+
+ public void close() {
+ this.closeNode();
+ }
+
+ /**
+ * Convert the given time to the absolute time by adding the start of workload
+ *
+ * @param time
+ */
+ private long getAbsoluteTime(long time) {
+ return time + startTime;
+ }
+
+ private long getRelativeTime(long time) {
+ return time - startTime;
+ }
+
+ private void findCorrectFragment(long absolute_time) {
+
+ // Traverse to the previous fragment, until you reach the correct fragment
+ while (absolute_time < 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()) {
+ this.current_fragment = fragments.get(++this.fragment_index);
+ }
+ }
+
+ @Override
+ public long onUpdate(long now) {
+ long absolute_time = getAbsoluteTime(now);
+
+ // Check if the current fragment is still the correct fragment,
+ // Otherwise, find the correct fragment.
+ if ((absolute_time < current_fragment.getStartTime()) || (absolute_time >= current_fragment.getEndTime())) {
+ this.findCorrectFragment(absolute_time);
+
+ pushCarbonIntensity(current_fragment.getCarbonIntensity());
+ }
+
+ // Update again at the end of this fragment
+ return getRelativeTime(current_fragment.getEndTime());
+ }
+
+ private void pushCarbonIntensity(double carbonIntensity) {
+ this.powerSource.updateCarbonIntensity(carbonIntensity);
+ }
+}
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 79ff93c0..03d54ad3 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
@@ -22,6 +22,7 @@
package org.opendc.simulator.compute.power;
+import java.util.List;
import org.opendc.simulator.compute.cpu.SimCpu;
import org.opendc.simulator.engine.FlowEdge;
import org.opendc.simulator.engine.FlowGraph;
@@ -38,6 +39,10 @@ public final class SimPowerSource extends FlowNode implements FlowSupplier {
private double powerSupplied = 0.0f;
private double totalEnergyUsage = 0.0f;
+ private double carbonIntensity = 0.0f;
+ private double totalCarbonEmission = 0.0f;
+
+ private CarbonModel carbonModel = null;
private FlowEdge muxEdge;
private double capacity = Long.MAX_VALUE;
@@ -71,14 +76,21 @@ public final class SimPowerSource extends FlowNode implements FlowSupplier {
return this.powerSupplied;
}
+ public double getCarbonIntensity() {
+ return this.carbonIntensity;
+ }
+
/**
* Return the cumulated energy usage of the machine (in J) measured at the InPort of the powers supply.
*/
public double getEnergyUsage() {
- updateCounters();
return totalEnergyUsage;
}
+ public double getCarbonEmission() {
+ return this.totalCarbonEmission;
+ }
+
@Override
public double getCapacity() {
return this.capacity;
@@ -88,12 +100,27 @@ public final class SimPowerSource extends FlowNode implements FlowSupplier {
// Constructors
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- public SimPowerSource(FlowGraph graph) {
+ public SimPowerSource(
+ FlowGraph graph, double max_capacity, List<CarbonFragmentNew> carbonFragments, long startTime) {
super(graph);
+ this.capacity = max_capacity;
+
+ if (carbonFragments != null) {
+ this.carbonModel = new CarbonModel(graph, this, carbonFragments, startTime);
+ }
lastUpdate = this.clock.millis();
}
+ public void close() {
+ if (this.carbonModel != null) {
+ this.carbonModel.close();
+ this.carbonModel = null;
+ }
+
+ this.closeNode();
+ }
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// FlowNode related functionality
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -123,8 +150,11 @@ public final class SimPowerSource extends FlowNode implements FlowSupplier {
long duration = now - lastUpdate;
if (duration > 0) {
+ double energyUsage = (this.powerSupplied * duration * 0.001);
+
// Compute the energy usage of the machine
- this.totalEnergyUsage += (double) (this.powerSupplied * duration * 0.001);
+ this.totalEnergyUsage += energyUsage;
+ this.totalCarbonEmission += this.carbonIntensity * (energyUsage / 3600000.0);
}
}
@@ -161,4 +191,10 @@ public final class SimPowerSource extends FlowNode implements FlowSupplier {
public void removeConsumerEdge(FlowEdge consumerEdge) {
this.muxEdge = null;
}
+
+ // Update the carbon intensity of the power source
+ public void updateCarbonIntensity(double carbonIntensity) {
+ this.updateCounters();
+ this.carbonIntensity = carbonIntensity;
+ }
}
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 ca42f566..7ceb32e6 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
@@ -272,21 +272,23 @@ public class OpenDCRunner(
val topology = listOf(ClusterSpec("cluster", topologyHosts, powerSourceSpec))
Provisioner(dispatcher, seed).use { provisioner ->
+
+ val workload =
+ trace(scenario.workload.trace.id).sampleByLoad(scenario.workload.samplingFraction)
+ val vms = workload.resolve(workloadLoader, Random(seed))
+ val startTime = vms.minOf { it.submissionTime }.toEpochMilli()
+
provisioner.runSteps(
setupComputeService(
serviceDomain,
{ createComputeScheduler(scenario.schedulerName, Random(it.seeder.nextLong())) },
),
registerComputeMonitor(serviceDomain, monitor),
- setupHosts(serviceDomain, topology),
+ setupHosts(serviceDomain, topology, startTime),
)
val service = provisioner.registry.resolve(serviceDomain, ComputeService::class.java)!!
- val workload =
- trace(scenario.workload.trace.id).sampleByLoad(scenario.workload.samplingFraction)
- val vms = workload.resolve(workloadLoader, Random(seed))
-
val phenomena = scenario.phenomena
val failureModel =
if (phenomena.failures) {