diff options
| author | Dante Niewenhuis <d.niewenhuis@hotmail.com> | 2024-10-25 13:32:41 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-10-25 13:32:41 +0200 |
| commit | 5a365dbc068f2a8cdfa9813c39cc84bb30e15637 (patch) | |
| tree | 72716d562787b85e03cdc7fe1d30c827054d25a0 /opendc-experiments/opendc-experiments-tf20/src | |
| parent | 27f5b7dcb05aefdab9b762175d538931face0aba (diff) | |
Rewrote the FlowEngine (#256)
* Removed unused components. Updated tests.
Improved checkpointing model
Improved model, started with SimPowerSource
implemented FailureModels and Checkpointing
First working version
midway commit
first update
All simulation are now run with a single CPU and single MemoryUnit. multi CPUs are combined into one. This is for performance and explainability.
* fixed merge conflicts
* Updated M3SA paths.
* Fixed small typo
Diffstat (limited to 'opendc-experiments/opendc-experiments-tf20/src')
29 files changed, 0 insertions, 2276 deletions
diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/Models.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/Models.kt deleted file mode 100644 index 78a63df8..00000000 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/Models.kt +++ /dev/null @@ -1,89 +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.experiments.tf20 - -import org.opendc.experiments.tf20.keras.Sequential -import org.opendc.experiments.tf20.keras.TrainableModel -import org.opendc.experiments.tf20.keras.activations.Activation -import org.opendc.experiments.tf20.keras.layer.conv.Conv2D -import org.opendc.experiments.tf20.keras.layer.conv.ConvPadding -import org.opendc.experiments.tf20.keras.layer.core.ActivationLayer -import org.opendc.experiments.tf20.keras.layer.core.Input -import org.opendc.experiments.tf20.keras.layer.pool.Pool2D -import org.opendc.experiments.tf20.keras.layer.regularization.Dropout - -/** - * Construct an AlexNet model with the given batch size. - */ -fun getAlexNet(batchSize: Long): TrainableModel { - return Sequential( - Input(batchSize, 227, 227, 3, name = "Input"), - Conv2D(longArrayOf(11, 11, 3, 96), longArrayOf(1, 4, 4, 1), padding = ConvPadding.VALID, name = "conv1"), - Pool2D(intArrayOf(1, 3, 3, 1), intArrayOf(1, 2, 2, 1), padding = ConvPadding.VALID, name = "pool1"), - Conv2D(longArrayOf(5, 5, 96, 256), longArrayOf(1, 1, 1, 1), padding = ConvPadding.SAME, name = "conv2"), - Pool2D(intArrayOf(1, 3, 3, 1), intArrayOf(1, 2, 2, 1), padding = ConvPadding.VALID, name = "pool2"), - Conv2D(longArrayOf(3, 3, 256, 384), longArrayOf(1, 1, 1, 1), padding = ConvPadding.SAME, name = "conv3"), - Conv2D(longArrayOf(3, 3, 384, 384), longArrayOf(1, 1, 1, 1), padding = ConvPadding.SAME, name = "conv4"), - Conv2D(longArrayOf(3, 3, 384, 256), longArrayOf(1, 1, 1, 1), padding = ConvPadding.SAME, name = "conv5"), - Pool2D(intArrayOf(1, 3, 3, 1), intArrayOf(1, 2, 2, 1), padding = ConvPadding.VALID, name = "pool5"), - Conv2D(longArrayOf(6, 6, 256, 4096), longArrayOf(1, 1, 1, 1), padding = ConvPadding.VALID, name = "fc6"), - Dropout(0.5f, name = "dropout6"), - Conv2D(longArrayOf(1, 1, 4096, 4096), longArrayOf(1, 1, 1, 1), padding = ConvPadding.SAME, name = "fc7"), - Dropout(0.5f, name = "dropout7"), - Conv2D(longArrayOf(1, 1, 4096, 1000), longArrayOf(1, 1, 1, 1), padding = ConvPadding.SAME, name = "f8"), - ActivationLayer(Activation.Softmax, name = "softmax"), - ) -} - -/** - * Construct an VGG16 model with the given batch size. - */ -fun getVGG16(batchSize: Long = 128): TrainableModel { - return Sequential( - Input(batchSize, 224, 224, 3, name = "Input"), - Conv2D(longArrayOf(3, 3, 3, 64), longArrayOf(1, 1, 1, 1), padding = ConvPadding.SAME, name = "conv1-1"), - Conv2D(longArrayOf(3, 3, 64, 64), longArrayOf(1, 1, 1, 1), padding = ConvPadding.SAME, name = "conv1-2"), - Pool2D(intArrayOf(1, 2, 2, 1), intArrayOf(1, 2, 2, 1), padding = ConvPadding.VALID, name = "pool1"), - Conv2D(longArrayOf(3, 3, 64, 128), longArrayOf(1, 1, 1, 1), padding = ConvPadding.SAME, name = "conv2-1"), - Conv2D(longArrayOf(3, 3, 128, 128), longArrayOf(1, 1, 1, 1), padding = ConvPadding.SAME, name = "conv2-2"), - Pool2D(intArrayOf(1, 2, 2, 1), intArrayOf(1, 2, 2, 1), padding = ConvPadding.VALID, name = "pool2"), - Conv2D(longArrayOf(3, 3, 128, 256), longArrayOf(1, 1, 1, 1), padding = ConvPadding.SAME, name = "conv3-1"), - Conv2D(longArrayOf(3, 3, 256, 256), longArrayOf(1, 1, 1, 1), padding = ConvPadding.SAME, name = "conv3-2"), - Conv2D(longArrayOf(3, 3, 256, 256), longArrayOf(1, 1, 1, 1), padding = ConvPadding.SAME, name = "conv3-3"), - Pool2D(intArrayOf(1, 2, 2, 1), intArrayOf(1, 2, 2, 1), padding = ConvPadding.VALID, name = "pool3"), - Conv2D(longArrayOf(3, 3, 256, 512), longArrayOf(1, 1, 1, 1), padding = ConvPadding.SAME, name = "conv4-1"), - Conv2D(longArrayOf(3, 3, 512, 512), longArrayOf(1, 1, 1, 1), padding = ConvPadding.SAME, name = "conv4-2"), - Conv2D(longArrayOf(3, 3, 512, 512), longArrayOf(1, 1, 1, 1), padding = ConvPadding.SAME, name = "conv4-3"), - Pool2D(intArrayOf(1, 2, 2, 1), intArrayOf(1, 2, 2, 1), padding = ConvPadding.VALID, name = "pool4"), - Conv2D(longArrayOf(3, 3, 512, 512), longArrayOf(1, 1, 1, 1), padding = ConvPadding.SAME, name = "conv5-1"), - Conv2D(longArrayOf(3, 3, 512, 512), longArrayOf(1, 1, 1, 1), padding = ConvPadding.SAME, name = "conv5-2"), - Conv2D(longArrayOf(3, 3, 512, 512), longArrayOf(1, 1, 1, 1), padding = ConvPadding.SAME, name = "conv5-3"), - Pool2D(intArrayOf(1, 2, 2, 1), intArrayOf(1, 2, 2, 1), padding = ConvPadding.VALID, name = "pool5"), - Conv2D(longArrayOf(7, 7, 512, 4096), longArrayOf(1, 1, 1, 1), padding = ConvPadding.VALID, name = "fc6"), - Dropout(0.5f, name = "dropout6"), - Conv2D(longArrayOf(1, 1, 4096, 4096), longArrayOf(1, 1, 1, 1), padding = ConvPadding.SAME, name = "fc7"), - Dropout(0.5f, name = "dropout7"), - Conv2D(longArrayOf(1, 1, 4096, 1000), longArrayOf(1, 1, 1, 1), padding = ConvPadding.SAME, name = "f8"), - ActivationLayer(Activation.Softmax, name = "softmax"), - ) -} diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/SimTFDevice.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/SimTFDevice.kt deleted file mode 100644 index 11e010ec..00000000 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/SimTFDevice.kt +++ /dev/null @@ -1,212 +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.experiments.tf20.core - -import kotlinx.coroutines.delay -import kotlinx.coroutines.suspendCancellableCoroutine -import org.opendc.common.Dispatcher -import org.opendc.simulator.compute.SimBareMetalMachine -import org.opendc.simulator.compute.SimMachine -import org.opendc.simulator.compute.SimMachineContext -import org.opendc.simulator.compute.SimPsuFactories -import org.opendc.simulator.compute.model.Cpu -import org.opendc.simulator.compute.model.MachineModel -import org.opendc.simulator.compute.model.MemoryUnit -import org.opendc.simulator.compute.power.CpuPowerModel -import org.opendc.simulator.compute.workload.SimWorkload -import org.opendc.simulator.flow2.FlowEngine -import org.opendc.simulator.flow2.FlowStage -import org.opendc.simulator.flow2.FlowStageLogic -import org.opendc.simulator.flow2.OutPort -import java.util.ArrayDeque -import java.util.UUID -import kotlin.coroutines.Continuation -import kotlin.coroutines.resume -import kotlin.math.ceil -import kotlin.math.roundToLong - -/** - * A [TFDevice] implementation using simulated components. - */ -public class SimTFDevice( - override val uid: UUID, - override val isGpu: Boolean, - dispatcher: Dispatcher, - pu: Cpu, - private val memory: MemoryUnit, - powerModel: CpuPowerModel, -) : TFDevice { - /** - * The [SimMachine] representing the device. - */ - private val machine = - SimBareMetalMachine.create( - FlowEngine.create(dispatcher).newGraph(), - MachineModel(pu, memory), - SimPsuFactories.simple(powerModel), - ) - - /** - * The workload that will be run by the device. - */ - private val workload = - object : SimWorkload, FlowStageLogic { - /** - * The [FlowStage] of the workload. - */ - var stage: FlowStage? = null - - /** - * The output of the workload. - */ - private var output: OutPort? = null - - /** - * The queue of work to run. - */ - val queue = ArrayDeque<Work>() - - /** - * A flag to indicate that the workload is idle. - */ - val isIdle - get() = activeWork == null - - /** - * The active work of the workload. - */ - private var activeWork: Work? = null - - /** - * The timestamp of the last pull. - */ - private var lastPull: Long = 0L - - override fun onStart(ctx: SimMachineContext) { - val stage = ctx.graph.newStage(this) - this.stage = stage - output = stage.getOutlet("out") - lastPull = ctx.graph.engine.clock.millis() - - ctx.graph.connect(output, ctx.cpu.input) - } - - override fun onStop(ctx: SimMachineContext) { - stage?.close() - stage = null - output = null - } - - override fun makeSnapshot(now: Long) {} - - override fun setOffset(now: Long) {} - - override fun getSnapshot(): SimWorkload = throw UnsupportedOperationException() - - override fun createCheckpointModel() {} - - override fun getCheckpointInterval(): Long { - return -1 - } - - override fun getCheckpointDuration(): Long { - return -1 - } - - override fun getCheckpointIntervalScaling(): Double { - return -1.0 - } - - override fun onUpdate( - ctx: FlowStage, - now: Long, - ): Long { - val output = output ?: return Long.MAX_VALUE - val lastPull = lastPull - this.lastPull = now - val delta = (now - lastPull).coerceAtLeast(0) - val consumedWork = output.rate * delta / 1000.0 - - val activeWork = activeWork - if (activeWork != null) { - if (activeWork.consume(consumedWork)) { - this.activeWork = null - } else { - val duration = ceil(activeWork.flops / output.capacity * 1000).toLong() - output.push(output.capacity) - return now + duration - } - } - - val queue = queue - val head = queue.poll() - return if (head != null) { - this.activeWork = head - val duration = (head.flops / output.capacity * 1000).roundToLong() - output.push(output.capacity) - now + duration - } else { - output.push(0.0f) - Long.MAX_VALUE - } - } - } - - init { - machine.startWorkload(workload, emptyMap()) {} - } - - override suspend fun load(dataSize: Long) { - val duration = dataSize / memory.speed * 1000 - delay(duration.toLong()) - } - - override suspend fun compute(flops: Double) = - suspendCancellableCoroutine<Unit> { cont -> - workload.queue.add(Work(flops, cont)) - if (workload.isIdle) { - workload.stage?.invalidate() - } - } - - override fun getDeviceStats(): TFDeviceStats { - return TFDeviceStats(machine.cpuUsage, machine.psu.powerDraw, machine.psu.energyUsage) - } - - override fun close() { - machine.cancel() - } - - private data class Work(var flops: Double, val cont: Continuation<Unit>) { - fun consume(flops: Double): Boolean { - this.flops -= flops - - if (this.flops <= 0) { - cont.resume(Unit) - return true - } - - return false - } - } -} diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/TFDevice.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/TFDevice.kt deleted file mode 100644 index 2d23f5b3..00000000 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/TFDevice.kt +++ /dev/null @@ -1,55 +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.experiments.tf20.core - -import java.util.UUID - -/** - * A compute device on which tensor operations are performed. - */ -public interface TFDevice : AutoCloseable { - /** - * The unique identifier of the device. - */ - public val uid: UUID - - /** - * A flag to indicate whether the device is a GPU. - */ - public val isGpu: Boolean - - /** - * Transfer the specified amount of data from memory. - */ - public suspend fun load(dataSize: Long) - - /** - * Perform [flops] amount of computation on the device. - */ - public suspend fun compute(flops: Double) - - /** - * Collect device statistics. - */ - public fun getDeviceStats(): TFDeviceStats -} diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/TFDeviceStats.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/TFDeviceStats.kt deleted file mode 100644 index c40982f8..00000000 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/core/TFDeviceStats.kt +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2022 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.tf20.core - -/** - * Statistics about a TensorFlow [TFDevice]. - * - * @property resourceUsage The resource usage of the device (in MHz). - * @property powerDraw The instantaneous power draw of the device (in W). - * @property energyUsage Cumulative energy usage of the device since boot (in J). - */ -data class TFDeviceStats( - val resourceUsage: Double, - val powerDraw: Double, - val energyUsage: Double, -) diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/distribute/MirroredStrategy.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/distribute/MirroredStrategy.kt deleted file mode 100644 index 69d180a9..00000000 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/distribute/MirroredStrategy.kt +++ /dev/null @@ -1,44 +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.experiments.tf20.distribute - -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.launch -import org.opendc.experiments.tf20.core.TFDevice - -/** - * A distribution [Strategy] that supports synchronous distributed training on multiple GPUs on one machine. - * - * It creates one replica per GPU device. Each variable in the model is mirrored across all the replicas. - */ -public class MirroredStrategy(val devices: List<TFDevice>) : Strategy { - override suspend fun run( - forward: Double, - backward: Double, - batchSize: Int, - ) = coroutineScope { - for (device in devices) { - launch { device.compute(forward * batchSize / devices.size + backward) } - } - } -} diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/distribute/OneDeviceStrategy.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/distribute/OneDeviceStrategy.kt deleted file mode 100644 index 05235b12..00000000 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/distribute/OneDeviceStrategy.kt +++ /dev/null @@ -1,38 +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.experiments.tf20.distribute - -import org.opendc.experiments.tf20.core.TFDevice - -/** - * A distribution [Strategy] that places all variables and computation on a single specified device. - */ -public class OneDeviceStrategy(val device: TFDevice) : Strategy { - override suspend fun run( - forward: Double, - backward: Double, - batchSize: Int, - ) { - device.compute(forward * batchSize + backward) - } -} diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/distribute/Strategy.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/distribute/Strategy.kt deleted file mode 100644 index d5da628a..00000000 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/distribute/Strategy.kt +++ /dev/null @@ -1,37 +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.experiments.tf20.distribute - -/** - * A strategy for distributing TensorFlow state and computation over multiple devices. - */ -public interface Strategy { - /** - * Converge the specified batch using the given strategy. - */ - public suspend fun run( - forward: Double, - backward: Double, - batchSize: Int, - ) -} diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/Sequential.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/Sequential.kt deleted file mode 100644 index 83995fa1..00000000 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/Sequential.kt +++ /dev/null @@ -1,58 +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.experiments.tf20.keras - -import org.opendc.experiments.tf20.keras.layer.Layer -import org.opendc.experiments.tf20.keras.layer.core.Input -import org.opendc.experiments.tf20.keras.shape.TensorShape - -/** - * Sequential model groups a linear stack of layers into a TensorFlow TrainableModel. - * - * @param [layers] The layers to describe the model design. - */ -public class Sequential(vararg layers: Layer) : TrainableModel(*layers) { - override fun buildLayers() { - val inputShape = TensorShape(*inputLayer.packedDims) - inputLayer.inputTensor = inputShape - inputLayer.build(inputShape) - var nextShape: TensorShape = inputLayer.getOutputShape(inputShape) - inputLayer.outputTensor = nextShape - - layers.filter { it !is Input }.forEach { - it.inputTensor = nextShape - it.build(nextShape) - - nextShape = it.getOutputShape(nextShape) - it.outputTensor = nextShape - } - } - - override fun forward(): Double { - return layers.sumOf { it.forward() } - } - - override fun backward(): Double { - return layers.sumOf { it.backward() } - } -} diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/TrainableModel.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/TrainableModel.kt deleted file mode 100644 index 2d621d16..00000000 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/TrainableModel.kt +++ /dev/null @@ -1,133 +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.experiments.tf20.keras - -import org.opendc.experiments.tf20.distribute.Strategy -import org.opendc.experiments.tf20.keras.layer.Layer -import org.opendc.experiments.tf20.keras.layer.core.Input - -/** - * A model groups layers into an object with training and inference features. - */ -public abstract class TrainableModel(vararg layers: Layer) : AutoCloseable { - /** - * The layers to describe the model design. Main part of the internal state of the model. - */ - public val layers: List<Layer> = listOf(*layers) - - /** - * First layer that is responsible for the input shape of the Neural Network. - */ - public val inputLayer: Input - get() = layers[0] as Input - - /** - * Returns input dimensions in order HWC (height, width, channels) - */ - public val inputDimensions: LongArray - get() = (layers[0] as Input).packedDims - - /** - * Layers indexed by name. - */ - protected val layersByName: MutableMap<String, Layer> = mutableMapOf() - - /** - * A flag to indicate that the model is compiled. - */ - public var isCompiled: Boolean = false - private set - - /** - * The strategy that is being used. - */ - private lateinit var strategy: Strategy - - /** - * Common method for building the initial part of the model static graph. - */ - protected abstract fun buildLayers() - - /** - * Perform a forward propagation. - */ - protected abstract fun forward(): Double - - /** - * Perform a backward propagation. - */ - protected abstract fun backward(): Double - - init { - for (layer in layers) { - if (layersByName.containsKey(layer.name)) { - throw IllegalArgumentException(layer.name) - } else { - layersByName[layer.name] = layer - } - - layer.parentModel = this - } - } - - /** - * Configures the model for training. - * - * @param strategy The distribution strategy for training. - */ - public fun compile(strategy: Strategy) { - check(!isCompiled) { "Model is already compiled." } - - buildLayers() - - this.strategy = strategy - this.isCompiled = true - } - - /** - * Train the model for a fixed number of [epochs] (iterations over a dataset). - * - * @param [epochs] Number of epochs to train the model. An epoch is an iteration over the entire x and y data provided. - * @param [batchSize] Number of samples per gradient update. - */ - public suspend fun fit( - epochs: Int = 5, - batchSize: Int = 32, - ) { - check(isCompiled) { "Model not yet compiled." } - - val forwardFlops = forward() - val backwardFlops = backward() - - for (i in 1..epochs) { - strategy.run(forwardFlops, backwardFlops, batchSize) - } - } - - override fun close() { - } - - override fun toString(): String { - return "TrainableModel ${super.toString()}" - } -} diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/activations/Activation.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/activations/Activation.kt deleted file mode 100644 index cb3b778e..00000000 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/activations/Activation.kt +++ /dev/null @@ -1,198 +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.experiments.tf20.keras.activations - -/** - * Neural network hyper-parameter, activation function of a node defines the output of that node given an input or - * set of inputs. - */ -public enum class Activation { - /** - * Linear unit. Returns unmodified input. - * - * NOTE: Doing nothing useful. Returns to ancient times of linear perceptron. - */ - Linear, - - /** - * Sigmoid activation function. - * - * Transforms input 'x' according formula: - * ``` - * sigmoid(x) = 1 / (1 + exp(-x)) - * ``` - * - * For small values (<-5), `sigmoid` returns a value close to zero, and for large values (>5) - * the result of the function gets close to 1. - * - * NOTE: Sigmoid is equivalent to a 2-element ActivationLayer, where the second element is - * assumed to be zero. The sigmoid function always returns a value between 0 and 1. - */ - Sigmoid, - - /** - * Hyperbolic tangent activation function. - * - * Transforms input 'x' according formula: - * ``` - * tanh(x) = sinh(x)/cosh(x) = ((exp(x) - exp(-x))/(exp(x) + exp(-x))) - * ``` - */ - Tanh, - - /** - * Rectified linear unit (ReLU). - * - * With default values, this returns the standard ReLU activation: - * `max(x, 0)`, the element-wise maximum of 0 and the input tensor. - */ - Relu, - - /** - * Computes Rectified Linear 6: - * ``` - * min(max(features, 0), 6) - * ``` - * @see <a href="http://www.cs.utoronto.ca/~kriz/conv-cifar10-aug2010.pdf"> - * Convolutional Deep Belief Networks on CIFAR-10. A. Krizhevsky</a> - */ - Relu6, - - /** - * Exponential Linear Unit. - * - * The exponential linear unit (ELU) with `alpha > 0` is: - * `x` if `x > 0` and `alpha * (exp(x) - 1)` if `x < 0` - * - * For this implementations alpha is equal to 1.0. - * - * The ELU hyperparameter `alpha` controls the value to which an - * ELU saturates for negative net inputs. ELUs diminish the - * vanishing gradient effect. - * - * ELUs have negative values which pushes the mean of the activations closer to zero. - * - * Mean activations that are closer to zero enable faster learning as they - * bring the gradient closer to the natural gradient. - * - * ELUs saturate to a negative value when the argument gets smaller. - * Saturation means a small derivative which decreases the variation - * and the information that is propagated to the next layer. - * - * @see <a href="https://arxiv.org/abs/1511.07289">Fast and Accurate Deep Network Learning by Exponential Linear Units - * (ELUs) (Clevert et al, 2016)</a> - */ - Elu, - - /** - * Scaled Exponential Linear Unit (SELU). - * - * The Scaled Exponential Linear Unit (SELU) activation function is defined as: - * ``` - * if x > 0: return scale * x - * if x < 0: return scale * alpha * (exp(x) - 1) - * ``` - * where `alpha` and `scale` are pre-defined constants (`alpha=1.67326324` and `scale=1.05070098`). - * - * Basically, the SELU activation function multiplies `scale` (> 1) with the - * output of the `tf.keras.activations.elu` function to ensure a slope larger - * than one for positive inputs. - * - * @see <a href="https://arxiv.org/abs/1706.02515">Klambauer et al., 2017</a> - */ - Selu, - - /** - * ActivationLayer converts a real vector to a vector of categorical probabilities. - * The elements of the output vector are in range (0, 1) and sum to 1. - * - * ActivationLayer is often used as the activation for the last - * layer of a classification network because the result could be interpreted as - * a probability distribution. - */ - Softmax, - - /** - * - */ - LogSoftmax, - - /** - * Exponential activation function. - * - * Transforms input 'x' according formula: - * ``` - * exp(x) - * ``` - */ - Exponential, - - /** - * Softplus activation function. - * - * Transforms input 'x' according formula: - * ``` - * softplus(x) = log(exp(x) + 1) - * ``` - */ - SoftPlus, - - /*** - * Softsign activation function. - * - * Transforms input 'x' according formula: - * ``` - * softsign(x) = x / (abs(x) + 1) - * ``` - */ - SoftSign, - - /** - * Hard sigmoid activation function. - * - * Transforms input 'x' according formula: - * ``` - * if x < -2.5: return 0 - * if x > 2.5: return 1 - * if -2.5 <= x <= 2.5: return 0.2 * x + 0.5 - * ``` - * A faster approximation of the sigmoid activation. - */ - HardSigmoid, - - /** - * Swish activation function. - * - * Transforms input 'x' according formula: - * ``` - * swish(x) = x * sigmoid(x) - * ``` - * - * It is a smooth, non-monotonic function that consistently matches - * or outperforms ReLU on deep networks, it is unbounded above and - * bounded below. - * - * @see <a href="https://arxiv.org/abs/1710.05941">Ramachandran et al., 2017</a> - */ - Swish, -} diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/layer/Layer.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/layer/Layer.kt deleted file mode 100644 index 143b27f0..00000000 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/layer/Layer.kt +++ /dev/null @@ -1,72 +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.experiments.tf20.keras.layer - -import org.opendc.experiments.tf20.keras.TrainableModel -import org.opendc.experiments.tf20.keras.shape.TensorShape - -/** - * Abstract class from which all layers inherit. - * - * @param name The name of the layer. - */ -public abstract class Layer(public val name: String) { - /** - * TrainableModel in which the layer exists. - */ - internal var parentModel: TrainableModel? = null - - /** - * The input shape of the layer. - */ - public lateinit var inputTensor: TensorShape - internal set - - /** - * The output shape of the layer. - */ - public lateinit var outputTensor: TensorShape - internal set - - /** - * Build the layer for the specified [inputShape]. - * - * @param [inputShape] Input shape, result of [getOutputShape] call from previous layer. - */ - public abstract fun build(inputShape: TensorShape) - - /** - * Compute output shape of this layer, based on [inputShape] and [Layer] type. - */ - public abstract fun getOutputShape(inputShape: TensorShape): TensorShape - - /** - * Perform a forward propagation - */ - public abstract fun forward(): Double - - /** - * Perform a backward propagation. - */ - public abstract fun backward(): Double -} diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/layer/conv/Conv2D.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/layer/conv/Conv2D.kt deleted file mode 100644 index f89c47c6..00000000 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/layer/conv/Conv2D.kt +++ /dev/null @@ -1,98 +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.experiments.tf20.keras.layer.conv - -import org.opendc.experiments.tf20.keras.activations.Activation -import org.opendc.experiments.tf20.keras.layer.Layer -import org.opendc.experiments.tf20.keras.shape.TensorShape -import kotlin.math.ceil - -/** - * 2D convolution layer (e.g. spatial convolution over images). - * - * This layer creates a convolution kernel that is convolved (actually cross-correlated) - * with the layer input to produce a tensor of outputs. - * Finally, if `activation` is applied to the outputs as well. - */ -public class Conv2D( - public val filter: LongArray = LongArray(4), - public val strides: LongArray = LongArray(4), - public val activation: Activation = Activation.Relu, - public val padding: ConvPadding = ConvPadding.VALID, - name: String = "", -) : Layer(name) { - private var padHeight: Double = 0.0 - private var padWidth: Double = 0.0 - - override fun build(inputShape: TensorShape) {} - - override fun getOutputShape(inputShape: TensorShape): TensorShape { - check(filter[2] == inputShape[3]) { "Input channel ${filter[2]} and ${inputShape[3]} shall match" } - - var outHeight = 0L - var outWidth = 0L - - if (padding == ConvPadding.VALID) { - outHeight = ceil((inputShape[1] - filter[0] + 1).toDouble() / strides[1].toDouble()).toLong() - outWidth = ceil((inputShape[2] - filter[1] + 1).toDouble() / strides[2].toDouble()).toLong() - padHeight = 0.0 - padWidth = 0.0 - } else if (padding == ConvPadding.SAME) { - outHeight = ceil(inputShape[1].toFloat() / strides[1].toFloat()).toLong() - outWidth = ceil(inputShape[2].toFloat() / strides[2].toFloat()).toLong() - - val padAlongHeight = (outHeight - 1) * strides[1] + filter[0] - inputShape[1] - val padAlongWidth = (outWidth - 1) * strides[2] + filter[1] - inputShape[2] - - padHeight = (padAlongHeight / 2).toDouble() - padWidth = (padAlongWidth / 2).toDouble() - } - - return TensorShape(inputShape[0], outHeight, outWidth, filter[3]) - } - - override fun forward(): Double { - // Mul and add per output pixel: kernel_w x kernel_h x in_channel - var flops: Long = (2 * filter[0] * filter[1] * filter[2]) - - val output = outputTensor - // Flops per output map. - flops *= output[1] * output[2] * filter[3] - - // Flops across multiple input patches. - flops *= inputTensor[0] - - if (activation == Activation.Relu) { - flops += output[0] * output[1] * output[2] * output[3] - } - - // return paramsNum() * output.H * output.W * FLOAT_BYTES / MILLION - return flops * 4.0 / 1_000_000 - } - - override fun backward(): Double = forward() - - override fun toString(): String { - return "Conv2D[filter=${filter.contentToString()}, strides=${strides.contentToString()}, activation=$activation, padding=$padding]" - } -} diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/layer/conv/ConvPadding.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/layer/conv/ConvPadding.kt deleted file mode 100644 index a47c435a..00000000 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/layer/conv/ConvPadding.kt +++ /dev/null @@ -1,39 +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.experiments.tf20.keras.layer.conv - -/** - * Enumeration of convolution padding types. - */ -public enum class ConvPadding { - /** - * Pad evenly to the left/right or up/down of the input such that output has the same - * height/width dimension as the input. - */ - SAME, - - /** - * No padding. - */ - VALID, -} diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/layer/core/ActivationLayer.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/layer/core/ActivationLayer.kt deleted file mode 100644 index 000401b9..00000000 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/layer/core/ActivationLayer.kt +++ /dev/null @@ -1,49 +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.experiments.tf20.keras.layer.core - -import org.opendc.experiments.tf20.keras.activations.Activation -import org.opendc.experiments.tf20.keras.layer.Layer -import org.opendc.experiments.tf20.keras.shape.TensorShape - -/** - * This layer applies an activation function to an output. - */ -public class ActivationLayer( - public val activation: Activation = Activation.Relu, - name: String = "", -) : Layer(name) { - override fun build(inputShape: TensorShape) { - // Intentionally left empty - } - - override fun getOutputShape(inputShape: TensorShape): TensorShape = inputShape - - override fun forward(): Double = 0.0 - - override fun backward(): Double = forward() - - override fun toString(): String { - return "ActivationLayer[activation=$activation]" - } -} diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/layer/core/Input.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/layer/core/Input.kt deleted file mode 100644 index 6619ccc0..00000000 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/layer/core/Input.kt +++ /dev/null @@ -1,50 +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.experiments.tf20.keras.layer.core - -import org.opendc.experiments.tf20.keras.layer.Layer -import org.opendc.experiments.tf20.keras.shape.TensorShape - -/** - * This layer is responsible for the input shape of the built model. - */ -public class Input(vararg dims: Long, name: String) : Layer(name) { - /** - * Input data dimensions. Rank = 3 or 4 for most popular supported cases. - */ - public val packedDims: LongArray = dims - - override fun build(inputShape: TensorShape) {} - - override fun getOutputShape(inputShape: TensorShape): TensorShape { - return inputShape - } - - override fun forward(): Double = 0.0 - - override fun backward(): Double = 0.0 - - override fun toString(): String { - return "Input[shape=${packedDims.contentToString()}]" - } -} diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/layer/pool/Pool2D.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/layer/pool/Pool2D.kt deleted file mode 100644 index a9a54938..00000000 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/layer/pool/Pool2D.kt +++ /dev/null @@ -1,92 +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.experiments.tf20.keras.layer.pool - -import org.opendc.experiments.tf20.keras.layer.Layer -import org.opendc.experiments.tf20.keras.layer.conv.ConvPadding -import org.opendc.experiments.tf20.keras.shape.TensorShape -import kotlin.math.ceil - -/** - * Max pooling layer for 2D inputs (e.g. images). - * - * @property [poolSize] The size of the sliding window for each dimension of input tensor (pool batch, pool height, pool width, pool channels). - * Usually, pool batch and pool channels are equal to 1. - * @property [strides] Strides of the pooling operation for each dimension of input tensor. - * @property [padding] The padding method, either 'valid' or 'same' or 'full'. - * @property [name] Custom layer name. - */ -public class Pool2D( - public val poolSize: IntArray = intArrayOf(1, 2, 2, 1), - public val strides: IntArray = intArrayOf(1, 2, 2, 1), - public val padding: ConvPadding = ConvPadding.VALID, - name: String, -) : Layer(name) { - private var padHeight = 0L - private var padWidth = 0L - - override fun build(inputShape: TensorShape) { - } - - override fun getOutputShape(inputShape: TensorShape): TensorShape { - var outHeight = 0L - var outWidth = 0L - // return the output tensor shape - if (padding == ConvPadding.VALID) { - outHeight = ceil((inputShape[1] - poolSize[1] + 1).toDouble() / strides[1].toDouble()).toLong() - outWidth = ceil((inputShape[2] - poolSize[2] + 1).toDouble() / strides[2].toDouble()).toLong() - padHeight = 0 - padWidth = 0 - } else if (padding == ConvPadding.SAME) { - outHeight = ceil(inputShape[1].toFloat() / strides[1].toFloat()).toLong() - outWidth = ceil(inputShape[2].toFloat() / strides[2].toFloat()).toLong() - val padAlongHeight = (outHeight - 1) * strides[1] + poolSize[1] - inputShape[1] - val padAlongWidth = (outWidth - 1) * strides[2] + poolSize[2] - inputShape[2] - - padHeight = padAlongHeight / 2 - padWidth = padAlongWidth / 2 - } - - return TensorShape(inputShape[0], outHeight, outWidth, inputShape[3]) - } - - override fun forward(): Double { - val output = outputTensor - // Per output pixel: kernel_w x kernel_h x in_channel - var flops: Long = 2 * poolSize[1] * poolSize[2] * inputTensor[3] - - // Flops per output map. - flops *= output[2] * output[1] - - // Flops across multiple input patches. - flops *= inputTensor[0] - - return flops * 4.0 / 1_000_000 - } - - override fun backward(): Double = forward() - - override fun toString(): String { - return "MaxPool2D[poolSize=${poolSize.contentToString()}, strides=${strides.contentToString()}, padding=$padding]" - } -} diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/layer/regularization/Dropout.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/layer/regularization/Dropout.kt deleted file mode 100644 index 8198f98c..00000000 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/layer/regularization/Dropout.kt +++ /dev/null @@ -1,57 +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.experiments.tf20.keras.layer.regularization - -import org.opendc.experiments.tf20.keras.layer.Layer -import org.opendc.experiments.tf20.keras.shape.TensorShape - -/** - * This layer applies dropout to the input. - * - * Dropout consists in randomly setting a fraction `rate` of input units to 0 - * at each update during training time, which helps prevent overfitting. - * The units that are kept are scaled by `1 / (1 - rate)`, so that their - * sum is unchanged at training time and inference time. - * - * @property keepProbability The dropout rate, between 0 and 1. E.g. `rate=0.1` would drop out 10% of input units. - * @property [name] Custom layer name. - */ -public class Dropout( - public val keepProbability: Float = 0.1f, - name: String, -) : Layer(name) { - override fun build(inputShape: TensorShape) {} - - override fun getOutputShape(inputShape: TensorShape): TensorShape { - return inputShape - } - - override fun forward(): Double { - val output = outputTensor - return output[0] * output[1] * output[2] * output[3] * 4.0 / 1_000_000 - } - - override fun backward(): Double = forward() - - override fun toString(): String = "Dropout[keepProbability=$keepProbability]" -} diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/shape/TensorShape.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/shape/TensorShape.kt deleted file mode 100644 index 67e00e24..00000000 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/keras/shape/TensorShape.kt +++ /dev/null @@ -1,114 +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.experiments.tf20.keras.shape - -import kotlin.math.abs - -/** - * Represents the shape of a tensor. - * - * @param dims The sizes of the tensor dimensions. - */ -public class TensorShape(vararg dims: Long) { - /** - * The dimensions of the tensor represented as [LongArray]. - */ - private val localDims: LongArray = dims - - /** - * Return amount of elements in Tensor with the given shape. - */ - public val numElements: Long - get() { - var prod = 1L - for (i in 0 until rank) { - prod *= abs(localDims[i]) - } - return prod - } - - /** - * Returns the rank of this shape. - */ - public val rank: Int - get() = localDims.size - - /** - * Returns the value of a dimension - * - * @param i The index at which to retrieve a dimension. - * @return The size of dimension i - */ - public operator fun get(i: Int): Long { - return localDims[i] - } - - /** - * Test whether dimension i in this shape is known - * - * @param i Target dimension to test - * @return Whether dimension i is unknown (equal to -1) - */ - private fun isKnown(i: Int): Boolean { - return localDims[i] != -1L - } - - /** - * Get the size of a target dimension. - * - * @param i Target dimension. - * @return The size of dimension i - */ - public fun size(i: Int): Long { - return localDims[i] - } - - /** - * Clone the [TensorShape] and return a new instance. - */ - public fun clone(): TensorShape { - return TensorShape(*localDims) - } - - /** - * Create a string representation of this [TensorShape]. - */ - override fun toString(): String { - return localDims.contentToString().replace("-1", "None") - } - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as TensorShape - - if (!localDims.contentEquals(other.localDims)) return false - - return true - } - - override fun hashCode(): Int { - return localDims.contentHashCode() - } -} diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/network/Message.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/network/Message.kt deleted file mode 100644 index fddcc779..00000000 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/network/Message.kt +++ /dev/null @@ -1,39 +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.experiments.tf20.network - -/** - * A communication message between TensorFlow worker and master nodes. - * - * @property from The source node. - * @property to The destination node. - * @property type The type of message sent. - * @property dataSize message data size. - */ -public data class Message( - val from: NetworkNode, - val to: NetworkNode, - val type: MessageType, - val dataSize: Long, - val iterations: Int, -) diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/network/MessageType.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/network/MessageType.kt deleted file mode 100644 index d7130137..00000000 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/network/MessageType.kt +++ /dev/null @@ -1,31 +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.experiments.tf20.network - -/** - * Enumeration of the types of messages exchanged between worker and master nodes during TensorFlow execution. - */ -public enum class MessageType { - REQUEST, - WEIGHTS, -} diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/network/NetworkController.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/network/NetworkController.kt deleted file mode 100644 index a4e79b4e..00000000 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/network/NetworkController.kt +++ /dev/null @@ -1,97 +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.experiments.tf20.network - -import kotlinx.coroutines.channels.Channel -import org.opendc.common.Dispatcher -import org.opendc.common.util.TimerScheduler - -/** - * The network controller represents a simple network model between the worker and master nodes during - * TensorFlow execution. - */ -public class NetworkController(dispatcher: Dispatcher) : AutoCloseable { - /** - * The scheduler for the message. - */ - private val scheduler = TimerScheduler<Message>(dispatcher) - - /** - * The outbound communication channels. - */ - private val channels = mutableMapOf<NetworkNode, Channel<Message>>() - - /** - * A map of the bandwidth between the different nodes. - */ - private val bandwidthMatrix: MutableMap<Pair<NetworkNode, NetworkNode>, Long> = mutableMapOf() - - /** - * A counter representing the amount of messages sent via the controller. - */ - private var messageCounter = 0 - - /** - * Add the specified link to this controller. - */ - public fun addLink(node: NetworkNode): Channel<Message> { - val channel = Channel<Message>(Channel.UNLIMITED) - channels[node] = channel - return channel - } - - /** - * Add a connection between two links. - */ - public fun addConnection( - node1: NetworkNode, - node2: NetworkNode, - bandwidth: Long, - ) { - bandwidthMatrix[Pair(node1, node2)] = bandwidth - } - - /** - * Route the specified [message]. - */ - public fun send(message: Message) { - val from = message.from - val to = message.to - val bandwidth = bandwidthMatrix[Pair(from, to)] ?: bandwidthMatrix[Pair(to, from)] ?: 1 - val size = message.dataSize / 1_000_000 - val delayTime = size / bandwidth + (0..5).random() - - messageCounter++ - - val target = channels[to] ?: return // Drop if destination not found - - scheduler.startSingleTimer(message, delayTime) { target.trySend(message) } - } - - /** - * Stop the network controller. - */ - override fun close() { - scheduler.cancelAll() - } -} diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/network/NetworkNode.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/network/NetworkNode.kt deleted file mode 100644 index 46fb5ce9..00000000 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/network/NetworkNode.kt +++ /dev/null @@ -1,28 +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.experiments.tf20.network - -/** - * A node represents a machine with which other nodes can communicate. - */ -public data class NetworkNode(val hostname: String) diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/util/MLEnvironmentReader.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/util/MLEnvironmentReader.kt deleted file mode 100644 index 34b4bc7b..00000000 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/util/MLEnvironmentReader.kt +++ /dev/null @@ -1,128 +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.experiments.tf20.util - -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue -import org.opendc.simulator.compute.model.Cpu -import org.opendc.simulator.compute.model.MachineModel -import org.opendc.simulator.compute.model.MemoryUnit -import org.opendc.simulator.compute.power.CpuPowerModels -import java.io.InputStream -import java.util.UUID - -/** - * An environment reader for the TensorFlow experiments. - */ -public class MLEnvironmentReader { - /** - * The [ObjectMapper] to convert the format. - */ - private val mapper = jacksonObjectMapper() - - public fun readEnvironment(input: InputStream): List<MachineDef> { - val setup: Setup = mapper.readValue(input) - var counter = 0 - return setup.rooms.flatMap { room -> - room.objects.flatMap { roomObject -> - when (roomObject) { - is RoomObject.Rack -> { - roomObject.machines.map { machine -> - var isGpuFlag = true - var maxPower = 350.0 - var minPower = 200.0 - val cores = - machine.cpus.map { id -> - when (id) { - 1 -> { - // ref: https://www.guru3d.com/articles-pages/nvidia-geforce-gtx-titan-x-review,8.html#:~:text=GeForce%20GTX%20Titan%20X%20%2D%20On,power%20supply%20unit%20as%20minimum. - Cpu( - 0, - 4992, - 824.0, - "NVidia", - "TITAN X", - "Pascal", - ) - } - 2 -> { - // ref: https://www.microway.com/hpc-tech-tips/nvidia-tesla-p100-pci-e-16gb-gpu-accelerator-pascal-gp100-close/ - Cpu( - 0, - 3584, - 1190.0, - "NVIDIA", - "Tesla P100", - "Pascal", - ) - } - 3 -> { - // ref: https://www.anandtech.com/show/10923/openpower-saga-tyans-1u-power8-gt75/7 - Cpu( - 0, - 24, - 3498.0, - "Intel", - "E5-2690v3 Haswell24", - "amd64", - ) - } - 4 -> { - Cpu( - 0, - 10, - 143000.0, - "IBM", - "POWER8", - "RISC", - ) - } - else -> throw IllegalArgumentException("The cpu id $id is not recognized") - } - } - val memories = - machine.memories.map { id -> - when (id) { - 1 -> MemoryUnit("NVidia", "GDDR5X", 480.0, 24L) - 2 -> MemoryUnit("NVidia", "GDDR5X", 720.0, 16L) - 3 -> MemoryUnit("IBM", "GDDR5X", 115.0, 160L) - 4 -> MemoryUnit("Inter", "GDDR5X", 68.0, 512L) - else -> throw IllegalArgumentException("The cpu id $id is not recognized") - } - } - - MachineDef( - UUID(0, counter.toLong()), - "node-${counter++}", - mapOf("gpu" to isGpuFlag), - MachineModel(cores, memories[0]), - CpuPowerModels.linear(maxPower, minPower), - ) - } - } - } - } - } - } -} diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/util/MachineDef.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/util/MachineDef.kt deleted file mode 100644 index 7ff91797..00000000 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/util/MachineDef.kt +++ /dev/null @@ -1,38 +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.experiments.tf20.util - -import org.opendc.simulator.compute.model.MachineModel -import org.opendc.simulator.compute.power.CpuPowerModel -import java.util.UUID - -/** - * A definition of a machine in a cluster. - */ -public data class MachineDef( - val uid: UUID, - val name: String, - val meta: Map<String, Any>, - val model: MachineModel, - val powerModel: CpuPowerModel, -) diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/util/Model.kt b/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/util/Model.kt deleted file mode 100644 index 0487a36f..00000000 --- a/opendc-experiments/opendc-experiments-tf20/src/main/kotlin/org/opendc/experiments/tf20/util/Model.kt +++ /dev/null @@ -1,67 +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.experiments.tf20.util - -import com.fasterxml.jackson.annotation.JsonSubTypes -import com.fasterxml.jackson.annotation.JsonTypeInfo - -/** - * A datacenter setup. - * - * @property name The name of the setup. - * @property rooms The rooms in the datacenter. - */ -internal data class Setup(val name: String, val rooms: List<Room>) - -/** - * A room in a datacenter. - * - * @property type The type of room in the datacenter. - * @property objects The objects in the room. - */ -internal data class Room(val type: String, val objects: List<RoomObject>) - -/** - * An object in a [Room]. - * - * @property type The type of the room object. - */ -@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type") -@JsonSubTypes(value = [JsonSubTypes.Type(name = "RACK", value = RoomObject.Rack::class)]) -internal sealed class RoomObject(val type: String) { - /** - * A rack in a server room. - * - * @property machines The machines in the rack. - */ - internal data class Rack(val machines: List<Machine>) : RoomObject("RACK") -} - -/** - * A machine in the setup that consists of the specified CPU's represented as - * integer identifiers and ethernet speed. - * - * @property cpus The Processing Units(CPUs/GPUs) in the machine represented as integer identifiers. - * @property memories The memories in the machine represented as integer identifiers. - */ -internal data class Machine(val cpus: List<Int>, val memories: List<Int>) diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/resources/ibm.json b/opendc-experiments/opendc-experiments-tf20/src/main/resources/ibm.json deleted file mode 100644 index b16d1b18..00000000 --- a/opendc-experiments/opendc-experiments-tf20/src/main/resources/ibm.json +++ /dev/null @@ -1,113 +0,0 @@ -{ - "name": "IBM Environment Setup", - "rooms": [ - { - "type": "SERVER", - "objects": [ - { - "type": "RACK", - "machines": [ - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]} - ] - }, - { - "type": "RACK", - "machines": [ - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]} - ] - }, - { - "type": "RACK", - "machines": [ - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]} - ] - }, - { - "type": "RACK", - "machines": [ - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]}, - { "cpus": [2], "memories": [2]} - ] - }, - { - "type": "RACK", - "machines": [ - { "cpus": [4], "memories": [4]}, - { "cpus": [4], "memories": [4]}, - { "cpus": [4], "memories": [4]}, - { "cpus": [4], "memories": [4]}, - { "cpus": [4], "memories": [4]}, - { "cpus": [4], "memories": [4]}, - { "cpus": [4], "memories": [4]}, - { "cpus": [4], "memories": [4]}, - { "cpus": [4], "memories": [4]}, - { "cpus": [4], "memories": [4]}, - { "cpus": [4], "memories": [4]}, - { "cpus": [4], "memories": [4]} - ] - }, - { - "type": "RACK", - "machines": [ - { "cpus": [4], "memories": [4]}, - { "cpus": [4], "memories": [4]}, - { "cpus": [4], "memories": [4]}, - { "cpus": [4], "memories": [4]}, - { "cpus": [4], "memories": [4]}, - { "cpus": [4], "memories": [4]}, - { "cpus": [4], "memories": [4]}, - { "cpus": [4], "memories": [4]}, - { "cpus": [4], "memories": [4]}, - { "cpus": [4], "memories": [4]}, - { "cpus": [4], "memories": [4]}, - { "cpus": [4], "memories": [4]} - ] - } - - ] - } - ] -} diff --git a/opendc-experiments/opendc-experiments-tf20/src/main/resources/kth.json b/opendc-experiments/opendc-experiments-tf20/src/main/resources/kth.json deleted file mode 100644 index 50eecb47..00000000 --- a/opendc-experiments/opendc-experiments-tf20/src/main/resources/kth.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "KTH Environment Setup", - "rooms": [ - { - "type": "SERVER", - "objects": [ - { - "type": "RACK", - "machines": [ - {"cpus": [1], "memories": [1]}, - {"cpus": [1], "memories": [1]}, - {"cpus": [1], "memories": [1]}, - {"cpus": [1], "memories": [1]}, - {"cpus": [1], "memories": [1]}, - {"cpus": [1], "memories": [1]}, - {"cpus": [1], "memories": [1]}, - {"cpus": [1], "memories": [1]}, - {"cpus": [1], "memories": [1]}, - {"cpus": [3], "memories": [3]}, - {"cpus": [3], "memories": [3]}, - {"cpus": [3], "memories": [3]}, - {"cpus": [3], "memories": [3]}, - {"cpus": [3], "memories": [3]}, - {"cpus": [3], "memories": [3]}, - {"cpus": [3], "memories": [3]}, - {"cpus": [3], "memories": [3]}, - {"cpus": [3], "memories": [3]} - ] - } - ] - } - ] -} diff --git a/opendc-experiments/opendc-experiments-tf20/src/test/kotlin/org/opendc/experiments/tf20/TensorFlowTest.kt b/opendc-experiments/opendc-experiments-tf20/src/test/kotlin/org/opendc/experiments/tf20/TensorFlowTest.kt deleted file mode 100644 index 447827e9..00000000 --- a/opendc-experiments/opendc-experiments-tf20/src/test/kotlin/org/opendc/experiments/tf20/TensorFlowTest.kt +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2022 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.tf20 - -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.assertAll -import org.opendc.experiments.tf20.core.SimTFDevice -import org.opendc.experiments.tf20.distribute.MirroredStrategy -import org.opendc.experiments.tf20.distribute.OneDeviceStrategy -import org.opendc.experiments.tf20.util.MLEnvironmentReader -import org.opendc.simulator.compute.power.CpuPowerModels -import org.opendc.simulator.kotlin.runSimulation -import java.util.UUID - -/** - * Integration test suite for the TensorFlow application model in OpenDC. - */ -class TensorFlowTest { - /** - * Smoke test that tests the capabilities of the TensorFlow application model in OpenDC. - */ - fun testSmokeAlexNet() = - runSimulation { - val envInput = checkNotNull(TensorFlowTest::class.java.getResourceAsStream("/kth.json")) - val def = MLEnvironmentReader().readEnvironment(envInput).first() - - val device = - SimTFDevice( - def.uid, - def.meta["gpu"] as Boolean, - dispatcher, - def.model.cpu, - def.model.memory, - CpuPowerModels.linear(250.0, 60.0), - ) - val strategy = OneDeviceStrategy(device) - val batchSize = 32 - val model = getAlexNet(batchSize.toLong()) - model.use { - it.compile(strategy) - - it.fit(epochs = 9088 / batchSize, batchSize = batchSize) - } - - device.close() - - val stats = device.getDeviceStats() - assertAll( - { assertEquals(3309694252, timeSource.millis()) }, - { assertEquals(8.27423563E8, stats.energyUsage) }, - ) - } - - /** - * Smoke test that tests the capabilities of the TensorFlow application model in OpenDC. - */ - fun testSmokeVGG() = - runSimulation { - val envInput = checkNotNull(TensorFlowTest::class.java.getResourceAsStream("/kth.json")) - val def = MLEnvironmentReader().readEnvironment(envInput).first() - - val device = - SimTFDevice( - def.uid, - def.meta["gpu"] as Boolean, - dispatcher, - def.model.cpu, - def.model.memory, - CpuPowerModels.linear(250.0, 60.0), - ) - val strategy = OneDeviceStrategy(device) - val batchSize = 128 - val model = getVGG16(batchSize.toLong()) - model.use { - it.compile(strategy) - - it.fit(epochs = 9088 / batchSize, batchSize = batchSize) - } - - device.close() - - val stats = device.getDeviceStats() - assertAll( - { assertEquals(176230328513, timeSource.millis()) }, - { assertEquals(4.405758212825E10, stats.energyUsage) }, - ) - } - - /** - * Smoke test that tests the capabilities of the TensorFlow application model in OpenDC. - */ - fun testSmokeDistribute() = - runSimulation { - val envInput = checkNotNull(TensorFlowTest::class.java.getResourceAsStream("/kth.json")) - val def = MLEnvironmentReader().readEnvironment(envInput).first() - - val deviceA = - SimTFDevice( - def.uid, - def.meta["gpu"] as Boolean, - dispatcher, - def.model.cpu, - def.model.memory, - CpuPowerModels.linear(250.0, 60.0), - ) - - val deviceB = - SimTFDevice( - UUID.randomUUID(), - def.meta["gpu"] as Boolean, - dispatcher, - def.model.cpu, - def.model.memory, - CpuPowerModels.linear(250.0, 60.0), - ) - - val strategy = MirroredStrategy(listOf(deviceA, deviceB)) - val batchSize = 32 - val model = getAlexNet(batchSize.toLong()) - model.use { - it.compile(strategy) - - it.fit(epochs = 9088 / batchSize, batchSize = batchSize) - } - - deviceA.close() - deviceB.close() - - val statsA = deviceA.getDeviceStats() - val statsB = deviceB.getDeviceStats() - assertAll( - { assertEquals(1704994000, timeSource.millis()) }, - { assertEquals(4.262485E8, statsA.energyUsage) }, - { assertEquals(4.262485E8, statsB.energyUsage) }, - ) - } -} diff --git a/opendc-experiments/opendc-experiments-tf20/src/test/kotlin/org/opendc/experiments/tf20/core/SimTFDeviceTest.kt b/opendc-experiments/opendc-experiments-tf20/src/test/kotlin/org/opendc/experiments/tf20/core/SimTFDeviceTest.kt deleted file mode 100644 index e0c4599a..00000000 --- a/opendc-experiments/opendc-experiments-tf20/src/test/kotlin/org/opendc/experiments/tf20/core/SimTFDeviceTest.kt +++ /dev/null @@ -1,74 +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.experiments.tf20.core - -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.launch -import org.junit.jupiter.api.Assertions.assertAll -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Test -import org.opendc.simulator.compute.model.Cpu -import org.opendc.simulator.compute.model.MemoryUnit -import org.opendc.simulator.compute.power.CpuPowerModels -import org.opendc.simulator.kotlin.runSimulation -import java.util.UUID - -/** - * Test suite for the [SimTFDevice] class. - */ -internal class SimTFDeviceTest { - @Test - fun testSmoke() = - runSimulation { - val pu = Cpu(0, 1, 960 * 1230.0, "NVIDIA", "Tesla V100", "unknown") - val memory = MemoryUnit("NVIDIA", "Tesla V100", 877.0, 32_000) - - val device = - SimTFDevice( - UUID.randomUUID(), - isGpu = true, - dispatcher, - pu, - memory, - CpuPowerModels.linear(250.0, 100.0), - ) - - // Load 1 GiB into GPU memory - device.load(1000) - assertEquals(1140, timeSource.millis()) - - coroutineScope { - launch { device.compute(1e6) } - launch { device.compute(2e6) } - } - - device.close() - - val stats = device.getDeviceStats() - - assertAll( - { assertEquals(3681, timeSource.millis()) }, - { assertEquals(749.25, stats.energyUsage) }, - ) - } -} |
