summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--frontend/src/components/app/map/MapConstants.js2
-rw-r--r--frontend/src/components/app/sidebars/topology/machine/MachineSidebarComponent.js2
-rw-r--r--frontend/src/components/app/sidebars/topology/machine/UnitAddComponent.js2
-rw-r--r--frontend/src/components/app/sidebars/topology/machine/UnitTabsComponent.js2
-rw-r--r--frontend/src/components/modals/custom-components/NewTopologyModalComponent.js2
-rw-r--r--frontend/src/containers/app/sidebars/project/TopologyListContainer.js4
-rw-r--r--frontend/src/index.sass3
-rw-r--r--simulator/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/workload/PerformanceInterferenceModel.kt14
-rw-r--r--simulator/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/experiment/Portfolios.kt1
-rw-r--r--simulator/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/telemetry/parquet/ParquetRunEventWriter.kt2
-rw-r--r--simulator/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/trace/WorkloadSampler.kt67
-rw-r--r--simulator/opendc/opendc-experiments-sc20/src/main/resources/log4j2.xml3
12 files changed, 72 insertions, 32 deletions
diff --git a/frontend/src/components/app/map/MapConstants.js b/frontend/src/components/app/map/MapConstants.js
index 0a970701..d6ea1f84 100644
--- a/frontend/src/components/app/map/MapConstants.js
+++ b/frontend/src/components/app/map/MapConstants.js
@@ -23,6 +23,6 @@ export const MAP_SCALE_PER_EVENT = 1.1
export const MAP_MIN_SCALE = 0.5
export const MAP_MAX_SCALE = 1.5
-export const MAX_NUM_UNITS_PER_MACHINE = 4
+export const MAX_NUM_UNITS_PER_MACHINE = 6
export const DEFAULT_RACK_SLOT_CAPACITY = 42
export const DEFAULT_RACK_POWER_CAPACITY = 10000
diff --git a/frontend/src/components/app/sidebars/topology/machine/MachineSidebarComponent.js b/frontend/src/components/app/sidebars/topology/machine/MachineSidebarComponent.js
index 02e7b8d4..7c78cf9e 100644
--- a/frontend/src/components/app/sidebars/topology/machine/MachineSidebarComponent.js
+++ b/frontend/src/components/app/sidebars/topology/machine/MachineSidebarComponent.js
@@ -6,7 +6,7 @@ import UnitTabsContainer from '../../../../../containers/app/sidebars/topology/m
const MachineSidebarComponent = ({ machineId }) => {
return (
- <div>
+ <div className="h-100 overflow-auto">
<MachineNameContainer />
<BackToRackContainer />
<DeleteMachineContainer />
diff --git a/frontend/src/components/app/sidebars/topology/machine/UnitAddComponent.js b/frontend/src/components/app/sidebars/topology/machine/UnitAddComponent.js
index d5ecbce3..4e9dbc7e 100644
--- a/frontend/src/components/app/sidebars/topology/machine/UnitAddComponent.js
+++ b/frontend/src/components/app/sidebars/topology/machine/UnitAddComponent.js
@@ -11,7 +11,7 @@ class UnitAddComponent extends React.Component {
return (
<div className="form-inline">
<div className="form-group w-100">
- <select className="form-control w-75 mr-1" ref={(unitSelect) => (this.unitSelect = unitSelect)}>
+ <select className="form-control w-70 mr-1" ref={(unitSelect) => (this.unitSelect = unitSelect)}>
{this.props.units.map((unit) => (
<option value={unit._id} key={unit._id}>
{unit.name}
diff --git a/frontend/src/components/app/sidebars/topology/machine/UnitTabsComponent.js b/frontend/src/components/app/sidebars/topology/machine/UnitTabsComponent.js
index 15c89ed5..c03b826f 100644
--- a/frontend/src/components/app/sidebars/topology/machine/UnitTabsComponent.js
+++ b/frontend/src/components/app/sidebars/topology/machine/UnitTabsComponent.js
@@ -22,7 +22,7 @@ const UnitTabsComponent = () => (
</li>
<li className="nav-item">
<a className="nav-link" data-toggle="tab" href="#storage-units" role="tab">
- Storage
+ Stor.
</a>
</li>
</ul>
diff --git a/frontend/src/components/modals/custom-components/NewTopologyModalComponent.js b/frontend/src/components/modals/custom-components/NewTopologyModalComponent.js
index a244b730..d8262baa 100644
--- a/frontend/src/components/modals/custom-components/NewTopologyModalComponent.js
+++ b/frontend/src/components/modals/custom-components/NewTopologyModalComponent.js
@@ -64,7 +64,7 @@ class NewTopologyModalComponent extends React.Component {
/>
</div>
<div className="form-group">
- <label className="form-control-label">Topology to duplicate (not supported yet)</label>
+ <label className="form-control-label">Topology to duplicate</label>
<select
className="form-control"
ref={(originTopology) => (this.originTopology = originTopology)}
diff --git a/frontend/src/containers/app/sidebars/project/TopologyListContainer.js b/frontend/src/containers/app/sidebars/project/TopologyListContainer.js
index f65982ef..e1de18f9 100644
--- a/frontend/src/containers/app/sidebars/project/TopologyListContainer.js
+++ b/frontend/src/containers/app/sidebars/project/TopologyListContainer.js
@@ -4,7 +4,7 @@ import { setCurrentTopology } from '../../../../actions/topology/building'
import { openNewTopologyModal } from '../../../../actions/modals/topology'
import { withRouter } from 'react-router-dom'
import { getState } from '../../../../util/state-utils'
-import { deleteScenario } from '../../../../actions/scenarios'
+import { deleteTopology } from '../../../../actions/topologies'
const mapStateToProps = (state) => {
let topologies = state.objects.project[state.currentProjectId]
@@ -33,7 +33,7 @@ const mapDispatchToProps = (dispatch, ownProps) => {
onDeleteTopology: async (id) => {
if (id) {
const state = await getState(dispatch)
- dispatch(deleteScenario(id))
+ dispatch(deleteTopology(id))
dispatch(setCurrentTopology(state.objects.project[state.currentProjectId].topologyIds[0]))
ownProps.history.push(`/projects/${state.currentProjectId}`)
}
diff --git a/frontend/src/index.sass b/frontend/src/index.sass
index ec756bc5..77acc23a 100644
--- a/frontend/src/index.sass
+++ b/frontend/src/index.sass
@@ -42,3 +42,6 @@ a, a:hover
.app-page-container
padding-left: $side-bar-width
padding-top: 15px
+
+.w-70
+ width: 70% !important
diff --git a/simulator/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/workload/PerformanceInterferenceModel.kt b/simulator/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/workload/PerformanceInterferenceModel.kt
index f458877b..3f885f89 100644
--- a/simulator/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/workload/PerformanceInterferenceModel.kt
+++ b/simulator/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/workload/PerformanceInterferenceModel.kt
@@ -25,8 +25,7 @@
package com.atlarge.opendc.compute.core.workload
import com.atlarge.opendc.compute.core.Server
-import java.util.SortedSet
-import java.util.TreeSet
+import java.util.*
import kotlin.random.Random
/**
@@ -44,23 +43,22 @@ class PerformanceInterferenceModel(
val random: Random = Random(0)
) {
private var intersectingItems: List<PerformanceInterferenceModelItem> = emptyList()
- private val colocatedWorkloads = TreeSet<String>()
+ private val colocatedWorkloads = TreeMap<String, Int>()
fun vmStarted(server: Server) {
- colocatedWorkloads.add(server.image.name)
+ colocatedWorkloads.merge(server.image.name, 1, Int::plus)
intersectingItems = items.filter { item -> doesMatch(item) }
}
fun vmStopped(server: Server) {
- colocatedWorkloads.remove(server.image.name)
+ colocatedWorkloads.computeIfPresent(server.image.name) { _, v -> (v - 1).takeUnless { it == 0 } }
intersectingItems = items.filter { item -> doesMatch(item) }
}
private fun doesMatch(item: PerformanceInterferenceModelItem): Boolean {
var count = 0
- for (name in item.workloadNames.subSet(colocatedWorkloads.first(), colocatedWorkloads.last() + "\u0000")) {
- if (name in colocatedWorkloads)
- count++
+ for (name in item.workloadNames.subSet(colocatedWorkloads.firstKey(), colocatedWorkloads.lastKey() + "\u0000")) {
+ count += colocatedWorkloads.getOrDefault(name, 0)
if (count > 1)
return true
}
diff --git a/simulator/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/experiment/Portfolios.kt b/simulator/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/experiment/Portfolios.kt
index b8dfb1be..09a6ce40 100644
--- a/simulator/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/experiment/Portfolios.kt
+++ b/simulator/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/experiment/Portfolios.kt
@@ -203,6 +203,7 @@ public class MoreHpcPortfolio(parent: Experiment, id: Int) : Portfolio(parent, i
)
override val workloads = listOf(
+ Workload("solvinity", 0.0, samplingStrategy = SamplingStrategy.HPC),
Workload("solvinity", 0.25, samplingStrategy = SamplingStrategy.HPC),
Workload("solvinity", 0.5, samplingStrategy = SamplingStrategy.HPC),
Workload("solvinity", 1.0, samplingStrategy = SamplingStrategy.HPC),
diff --git a/simulator/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/telemetry/parquet/ParquetRunEventWriter.kt b/simulator/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/telemetry/parquet/ParquetRunEventWriter.kt
index c1724369..043e4670 100644
--- a/simulator/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/telemetry/parquet/ParquetRunEventWriter.kt
+++ b/simulator/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/telemetry/parquet/ParquetRunEventWriter.kt
@@ -51,6 +51,7 @@ public class ParquetRunEventWriter(path: File, bufferSize: Int) :
record.put("topology", scenario.topology.name)
record.put("workload_name", scenario.workload.name)
record.put("workload_fraction", scenario.workload.fraction)
+ record.put("workload_sampler", scenario.workload.samplingStrategy)
record.put("allocation_policy", scenario.allocationPolicy)
record.put("failure_frequency", scenario.operationalPhenomena.failureFrequency)
record.put("interference", scenario.operationalPhenomena.hasInterference)
@@ -69,6 +70,7 @@ public class ParquetRunEventWriter(path: File, bufferSize: Int) :
.name("topology").type().stringType().noDefault()
.name("workload_name").type().stringType().noDefault()
.name("workload_fraction").type().doubleType().noDefault()
+ .name("workload_sampler").type().stringType().noDefault()
.name("allocation_policy").type().stringType().noDefault()
.name("failure_frequency").type().doubleType().noDefault()
.name("interference").type().booleanType().noDefault()
diff --git a/simulator/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/trace/WorkloadSampler.kt b/simulator/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/trace/WorkloadSampler.kt
index b24d6de1..a46bb3e6 100644
--- a/simulator/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/trace/WorkloadSampler.kt
+++ b/simulator/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/trace/WorkloadSampler.kt
@@ -109,6 +109,24 @@ fun sampleHpcWorkload(
name.matches(pattern)
}
+ val hpcSequence = generateSequence(0) { it + 1 }
+ .map { index ->
+ val res = mutableListOf<TraceEntry<VmWorkload>>()
+ hpc.mapTo(res) { sample(it, index) }
+ res.shuffle(random)
+ res
+ }
+ .flatten()
+
+ val nonHpcSequence = generateSequence(0) { it + 1 }
+ .map { index ->
+ val res = mutableListOf<TraceEntry<VmWorkload>>()
+ nonHpc.mapTo(res) { sample(it, index) }
+ res.shuffle(random)
+ res
+ }
+ .flatten()
+
logger.debug { "Found ${hpc.size} HPC workloads and ${nonHpc.size} non-HPC workloads" }
val totalLoad = if (workload is CompositeWorkload) {
@@ -117,45 +135,60 @@ fun sampleHpcWorkload(
trace.sumByDouble { it.workload.image.tags.getValue("total-load") as Double }
}
+ logger.debug { "Total trace load: $totalLoad" }
+ var hpcCount = 0
+ var hpcLoad = 0.0
+ var nonHpcCount = 0
+ var nonHpcLoad = 0.0
+
val res = mutableListOf<TraceEntry<VmWorkload>>()
if (sampleOnLoad) {
var currentLoad = 0.0
var i = 0
- while (true) {
- // Sample random HPC entry with replacement
- val entry = sample(hpc.random(random), i++)
-
+ for (entry in hpcSequence) {
val entryLoad = entry.workload.image.tags.getValue("total-load") as Double
- if ((currentLoad + entryLoad) / totalLoad > fraction || res.size > trace.size) {
+ if ((currentLoad + entryLoad) / totalLoad > fraction) {
break
}
+ hpcLoad += entryLoad
+ hpcCount += 1
currentLoad += entryLoad
res += entry
}
- (nonHpc as MutableList<TraceEntry<VmWorkload>>).shuffle(random)
- for (entry in nonHpc) {
+ for (entry in nonHpcSequence) {
val entryLoad = entry.workload.image.tags.getValue("total-load") as Double
- if ((currentLoad + entryLoad) / totalLoad > 1 || res.size > trace.size) {
+ if ((currentLoad + entryLoad) / totalLoad > 1) {
break
}
+ nonHpcLoad += entryLoad
+ nonHpcCount += 1
currentLoad += entryLoad
res += entry
}
} else {
- repeat((fraction * trace.size).toInt()) { i ->
- // Sample random HPC entry with replacement
- val entry = sample(hpc.random(random), i)
- res.add(entry)
- }
+ hpcSequence
+ .take((fraction * trace.size).toInt())
+ .forEach { entry ->
+ hpcLoad += entry.workload.image.tags.getValue("total-load") as Double
+ hpcCount += 1
+ res.add(entry)
+ }
- (nonHpc as MutableList<TraceEntry<VmWorkload>>).shuffle(random)
- res.addAll(nonHpc.subList(0, ((1 - fraction) * trace.size).toInt()))
+ nonHpcSequence
+ .take(((1 - fraction) * trace.size).toInt())
+ .forEach { entry ->
+ nonHpcLoad += entry.workload.image.tags.getValue("total-load") as Double
+ nonHpcCount += 1
+ res.add(entry)
+ }
}
+ logger.debug { "HPC $hpcCount (load $hpcLoad) and non-HPC $nonHpcCount (load $nonHpcLoad)" }
+ logger.debug { "Total sampled load: ${hpcLoad + nonHpcLoad}" }
logger.info { "Sampled ${trace.size} VMs (fraction $fraction) into subset of ${res.size} VMs" }
return res
@@ -168,13 +201,13 @@ private fun sample(entry: TraceEntry<VmWorkload>, i: Int): TraceEntry<VmWorkload
val id = UUID.nameUUIDFromBytes("${entry.workload.image.uid}-$i".toByteArray())
val image = VmImage(
id,
- entry.workload.image.name + "-$i",
+ entry.workload.image.name,
entry.workload.image.tags,
entry.workload.image.flopsHistory,
entry.workload.image.maxCores,
entry.workload.image.requiredMemory
)
- val vmWorkload = entry.workload.copy(uid = id, image = image, name = entry.workload.name + "-$i")
+ val vmWorkload = entry.workload.copy(uid = id, image = image, name = entry.workload.name)
return VmTraceEntry(vmWorkload, entry.submissionTime)
}
diff --git a/simulator/opendc/opendc-experiments-sc20/src/main/resources/log4j2.xml b/simulator/opendc/opendc-experiments-sc20/src/main/resources/log4j2.xml
index f47a6da8..6906bfc3 100644
--- a/simulator/opendc/opendc-experiments-sc20/src/main/resources/log4j2.xml
+++ b/simulator/opendc/opendc-experiments-sc20/src/main/resources/log4j2.xml
@@ -39,6 +39,9 @@
<Logger name="com.atlarge.opendc.experiments.sc20" level="info" additivity="false">
<AppenderRef ref="Console"/>
</Logger>
+ <Logger name="com.atlarge.opendc.experiments.sc20.trace" level="debug" additivity="false">
+ <AppenderRef ref="Console"/>
+ </Logger>
<Logger name="org.apache.hadoop" level="warn" additivity="false">
<AppenderRef ref="Console"/>
</Logger>