summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/service/ComputeService.java2
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/service/ServiceTask.java16
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/ComputeSchedulers.kt6
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltHostExportColumns.kt9
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltTaskExportColumns.kt17
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/host/HostTableReader.kt11
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/host/HostTableReaderImpl.kt29
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReader.kt13
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReaderImpl.kt33
-rw-r--r--opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/Scenario.kt2
-rw-r--r--opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/AllocationPolicySpec.kt40
-rw-r--r--opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/ExperimentSpec.kt5
-rw-r--r--opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/ScenarioSpec.kt5
-rw-r--r--opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/allocation/AllocationPolicySpec.kt85
-rw-r--r--opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/allocation/HostFilterSpec.kt111
-rw-r--r--opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/experiment/specs/allocation/HostWeigherSpec.kt82
-rw-r--r--opendc-experiments/opendc-experiments-base/src/main/kotlin/org/opendc/experiments/base/runner/ScenarioRunner.kt4
-rw-r--r--opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/OpenDCRunner.kt4
-rw-r--r--opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/internal/WebComputeMonitor.kt4
19 files changed, 343 insertions, 135 deletions
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 0538a951..657e7f1e 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
@@ -413,7 +413,7 @@ public final class ComputeService implements AutoCloseable, CarbonReceiver {
long now = clock.millis();
SchedulingRequest request = new SchedulingRequest(task, now);
- task.launchedAt = Instant.ofEpochMilli(now);
+ task.scheduledAt = Instant.ofEpochMilli(now);
taskQueue.add(request);
tasksPending++;
requestSchedulingCycle();
diff --git a/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/service/ServiceTask.java b/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/service/ServiceTask.java
index 4d5611a8..9fb9b5f0 100644
--- a/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/service/ServiceTask.java
+++ b/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/service/ServiceTask.java
@@ -56,12 +56,12 @@ public class ServiceTask {
private ServiceFlavor flavor;
public Workload workload;
- private Map<String, ?> meta; // TODO: remove this
+ private final Map<String, ?> meta; // TODO: remove this
private final List<TaskWatcher> watchers = new ArrayList<>();
private TaskState state = TaskState.CREATED;
- Instant launchedAt = null;
- Instant createdAt;
+ Instant scheduledAt = null;
+ Instant submittedAt;
Instant finishedAt;
SimHost host = null;
private SchedulingRequest request = null;
@@ -88,7 +88,7 @@ public class ServiceTask {
this.workload = workload;
this.meta = meta;
- this.createdAt = this.service.getClock().instant();
+ this.submittedAt = this.service.getClock().instant();
}
@NotNull
@@ -136,13 +136,13 @@ public class ServiceTask {
}
@Nullable
- public Instant getLaunchedAt() {
- return launchedAt;
+ public Instant getScheduledAt() {
+ return scheduledAt;
}
@Nullable
- public Instant getCreatedAt() {
- return createdAt;
+ public Instant getSubmittedAt() {
+ return submittedAt;
}
@Nullable
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/ComputeSchedulers.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/ComputeSchedulers.kt
index 2e4a5bf1..ecf4804a 100644
--- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/ComputeSchedulers.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/ComputeSchedulers.kt
@@ -50,18 +50,18 @@ public enum class ComputeSchedulerEnum {
TimeshiftNoPeak,
}
-public fun createComputeScheduler(
+public fun createPrefabComputeScheduler(
name: String,
seeder: RandomGenerator,
clock: InstantSource,
): ComputeScheduler {
- return createComputeScheduler(ComputeSchedulerEnum.valueOf(name.uppercase()), seeder, clock)
+ return createPrefabComputeScheduler(ComputeSchedulerEnum.valueOf(name.uppercase()), seeder, clock)
}
/**
* Create a [ComputeScheduler] for the experiment.
*/
-public fun createComputeScheduler(
+public fun createPrefabComputeScheduler(
name: ComputeSchedulerEnum,
seeder: RandomGenerator,
clock: InstantSource,
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 13304b47..f43f4b31 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
@@ -87,12 +87,12 @@ public object DfltHostExportColumns {
public val GUESTS_TERMINATED: ExportColumn<HostTableReader> =
ExportColumn(
field = Types.required(INT32).named("guests_terminated"),
- ) { it.guestsTerminated }
+ ) { it.tasksTerminated }
public val GUESTS_RUNNING: ExportColumn<HostTableReader> =
ExportColumn(
field = Types.required(INT32).named("guests_running"),
- ) { it.guestsRunning }
+ ) { it.tasksActive }
public val GUESTS_ERROR: ExportColumn<HostTableReader> =
ExportColumn(
@@ -169,11 +169,6 @@ public object DfltHostExportColumns {
field = Types.optional(INT64).named("boot_time"),
) { it.bootTime?.toEpochMilli() }
- public val BOOT_TIME_ABS: ExportColumn<HostTableReader> =
- ExportColumn(
- field = Types.optional(INT64).named("boot_time_absolute"),
- ) { it.bootTimeAbsolute?.toEpochMilli() }
-
/**
* The columns that are always included in the output file.
*/
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltTaskExportColumns.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltTaskExportColumns.kt
index 52a84236..8603f669 100644
--- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltTaskExportColumns.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltTaskExportColumns.kt
@@ -142,26 +142,21 @@ public object DfltTaskExportColumns {
field = Types.optional(INT64).named("provision_time"),
) { it.provisionTime?.toEpochMilli() }
- public val BOOT_TIME: ExportColumn<TaskTableReader> =
+ public val SCHEDULE_TIME: ExportColumn<TaskTableReader> =
ExportColumn(
- field = Types.optional(INT64).named("boot_time"),
- ) { it.bootTime?.toEpochMilli() }
+ field = Types.optional(INT64).named("schedule_time"),
+ ) { it.scheduleTime?.toEpochMilli() }
- public val CREATION_TIME: ExportColumn<TaskTableReader> =
+ public val SUBMISSION_TIME: ExportColumn<TaskTableReader> =
ExportColumn(
- field = Types.optional(INT64).named("creation_time"),
- ) { it.creationTime?.toEpochMilli() }
+ field = Types.optional(INT64).named("submission_time"),
+ ) { it.submissionTime?.toEpochMilli() }
public val FINISH_TIME: ExportColumn<TaskTableReader> =
ExportColumn(
field = Types.optional(INT64).named("finish_time"),
) { it.finishTime?.toEpochMilli() }
- public val BOOT_TIME_ABS: ExportColumn<TaskTableReader> =
- ExportColumn(
- field = Types.optional(INT64).named("boot_time_absolute"),
- ) { it.bootTimeAbsolute?.toEpochMilli() }
-
public val TASK_STATE: ExportColumn<TaskTableReader> =
ExportColumn(
field =
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/host/HostTableReader.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/host/HostTableReader.kt
index 1d3d46d9..53282b9f 100644
--- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/host/HostTableReader.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/host/HostTableReader.kt
@@ -55,12 +55,12 @@ public interface HostTableReader : Exportable {
/**
* The number of guests that are in a terminated state.
*/
- public val guestsTerminated: Int
+ public val tasksTerminated: Int
/**
- * The number of guests that are in a running state.
+ * The number of guests that are active on the Host state.
*/
- public val guestsRunning: Int
+ public val tasksActive: Int
/**
* The number of guests that are in an error state.
@@ -136,9 +136,4 @@ public interface HostTableReader : Exportable {
* The [Instant] at which the host booted relative to the start of the workload.
*/
public val bootTime: Instant?
-
- /**
- * The [Instant] at which the host booted.
- */
- public val bootTimeAbsolute: Instant?
}
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/host/HostTableReaderImpl.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/host/HostTableReaderImpl.kt
index 5babb864..4990f0a3 100644
--- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/host/HostTableReaderImpl.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/host/HostTableReaderImpl.kt
@@ -45,8 +45,8 @@ public class HostTableReaderImpl(
_timestamp = table.timestamp
_timestampAbsolute = table.timestampAbsolute
- _guestsTerminated = table.guestsTerminated
- _guestsRunning = table.guestsRunning
+ _tasksTerminated = table.tasksTerminated
+ _tasksActive = table.tasksActive
_guestsError = table.guestsError
_guestsInvalid = table.guestsInvalid
_cpuLimit = table.cpuLimit
@@ -62,7 +62,6 @@ public class HostTableReaderImpl(
_uptime = table.uptime
_downtime = table.downtime
_bootTime = table.bootTime
- _bootTimeAbsolute = table.bootTimeAbsolute
}
override val hostInfo: HostInfo =
@@ -83,13 +82,13 @@ public class HostTableReaderImpl(
get() = _timestampAbsolute
private var _timestampAbsolute = Instant.MIN
- override val guestsTerminated: Int
- get() = _guestsTerminated
- private var _guestsTerminated = 0
+ override val tasksTerminated: Int
+ get() = _tasksTerminated
+ private var _tasksTerminated = 0
- override val guestsRunning: Int
- get() = _guestsRunning
- private var _guestsRunning = 0
+ override val tasksActive: Int
+ get() = _tasksActive
+ private var _tasksActive = 0
override val guestsError: Int
get() = _guestsError
@@ -158,10 +157,6 @@ public class HostTableReaderImpl(
get() = _bootTime
private var _bootTime: Instant? = null
- override val bootTimeAbsolute: Instant?
- get() = _bootTimeAbsolute
- private var _bootTimeAbsolute: Instant? = null
-
/**
* Record the next cycle.
*/
@@ -172,8 +167,8 @@ public class HostTableReaderImpl(
_timestamp = now
_timestampAbsolute = now + startTime
- _guestsTerminated = hostSysStats.guestsTerminated
- _guestsRunning = hostSysStats.guestsRunning
+ _tasksTerminated = hostSysStats.guestsTerminated
+ _tasksActive = hostSysStats.guestsRunning
_guestsError = hostSysStats.guestsError
_guestsInvalid = hostSysStats.guestsInvalid
_cpuLimit = hostCpuStats.capacity
@@ -205,8 +200,8 @@ public class HostTableReaderImpl(
previousUptime = _uptime
previousDowntime = _downtime
- _guestsTerminated = 0
- _guestsRunning = 0
+ _tasksTerminated = 0
+ _tasksActive = 0
_guestsError = 0
_guestsInvalid = 0
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReader.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReader.kt
index 97d8ca88..85e030aa 100644
--- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReader.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReader.kt
@@ -76,19 +76,14 @@ public interface TaskTableReader : Exportable {
public val provisionTime: Instant?
/**
- * The [Instant] at which the task booted relative to the start of the workload.
+ * The [Instant] at which the task was scheduled relative to the start of the workload.
*/
- public val bootTime: Instant?
+ public val scheduleTime: Instant?
/**
- * The [Instant] at which the task booted.
- */
- public val bootTimeAbsolute: Instant?
-
- /**
- * The [Instant] at which the task booted relative to the start of the workload.
+ * The [Instant] at which the task was submitted relative to the start of the workload.
*/
- public val creationTime: Instant?
+ public val submissionTime: Instant?
/**
* The [Instant] at which the task booted relative to the start of the workload.
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReaderImpl.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReaderImpl.kt
index 07462b14..d8c6a06e 100644
--- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReaderImpl.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReaderImpl.kt
@@ -65,10 +65,9 @@ public class TaskTableReaderImpl(
_uptime = table.uptime
_downtime = table.downtime
_provisionTime = table.provisionTime
- _bootTime = table.bootTime
- _bootTimeAbsolute = table.bootTimeAbsolute
+ _scheduleTime = table.scheduleTime
- _creationTime = table.creationTime
+ _submissionTime = table.submissionTime
_finishTime = table.finishTime
_taskState = table.taskState
@@ -115,13 +114,13 @@ public class TaskTableReaderImpl(
get() = _provisionTime
private var _provisionTime: Instant? = null
- override val bootTime: Instant?
- get() = _bootTime
- private var _bootTime: Instant? = null
+ override val scheduleTime: Instant?
+ get() = _scheduleTime
+ private var _scheduleTime: Instant? = null
- override val creationTime: Instant?
- get() = _creationTime
- private var _creationTime: Instant? = null
+ override val submissionTime: Instant?
+ get() = _submissionTime
+ private var _submissionTime: Instant? = null
override val finishTime: Instant?
get() = _finishTime
@@ -159,10 +158,6 @@ public class TaskTableReaderImpl(
private var _cpuLostTime = 0L
private var previousCpuLostTime = 0L
- override val bootTimeAbsolute: Instant?
- get() = _bootTimeAbsolute
- private var _bootTimeAbsolute: Instant? = null
-
override val taskState: TaskState?
get() = _taskState
private var _taskState: TaskState? = null
@@ -200,18 +195,12 @@ public class TaskTableReaderImpl(
_cpuLostTime = cpuStats?.lostTime ?: _cpuLostTime
_uptime = sysStats?.uptime?.toMillis() ?: _uptime
_downtime = sysStats?.downtime?.toMillis() ?: _downtime
- _provisionTime = task.launchedAt
- _bootTime = sysStats?.bootTime ?: _bootTime
- _creationTime = task.createdAt
+ _provisionTime = task.scheduledAt
+ _scheduleTime = sysStats?.bootTime ?: _scheduleTime
+ _submissionTime = task.submittedAt
_finishTime = task.finishedAt
_taskState = task.state
-
- if (sysStats != null) {
- _bootTimeAbsolute = sysStats.bootTime + startTime
- } else {
- _bootTimeAbsolute = null
- }
}
/**
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,
)
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 9a1b398e..09aaf9fa 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
@@ -29,7 +29,7 @@ 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.scheduler.createPrefabComputeScheduler
import org.opendc.compute.simulator.service.ComputeService
import org.opendc.compute.topology.specs.ClusterSpec
import org.opendc.compute.topology.specs.HostSpec
@@ -279,7 +279,7 @@ public class OpenDCRunner(
provisioner.runSteps(
setupComputeService(
serviceDomain,
- { createComputeScheduler(scenario.schedulerName, Random(it.seeder.nextLong()), timeSource) },
+ { createPrefabComputeScheduler(scenario.schedulerName, Random(it.seeder.nextLong()), timeSource) },
),
registerComputeMonitor(serviceDomain, monitor),
setupHosts(serviceDomain, topology, listOf(), startTime),
diff --git a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/internal/WebComputeMonitor.kt b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/internal/WebComputeMonitor.kt
index fbb33593..9288b403 100644
--- a/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/internal/WebComputeMonitor.kt
+++ b/opendc-web/opendc-web-runner/src/main/kotlin/org/opendc/web/runner/internal/WebComputeMonitor.kt
@@ -44,14 +44,14 @@ internal class WebComputeMonitor : ComputeMonitor {
hostAggregateMetrics.totalLostTime + reader.cpuLostTime,
hostAggregateMetrics.totalPowerDraw + reader.energyUsage,
hostAggregateMetrics.totalFailureSlices + slices,
- hostAggregateMetrics.totalFailureVmSlices + reader.guestsRunning * slices,
+ hostAggregateMetrics.totalFailureVmSlices + reader.tasksActive * slices,
)
hostMetrics.compute(reader.hostInfo.name) { _, prev ->
HostMetrics(
reader.cpuUsage + (prev?.cpuUsage ?: 0.0),
reader.cpuDemand + (prev?.cpuDemand ?: 0.0),
- reader.guestsRunning + (prev?.instanceCount ?: 0),
+ reader.tasksActive + (prev?.instanceCount ?: 0),
1 + (prev?.count ?: 0),
)
}