summaryrefslogtreecommitdiff
path: root/opendc-simulator/opendc-simulator-flow
diff options
context:
space:
mode:
authorNiels Thiele <noleu66@posteo.net>2025-06-22 12:31:21 +0200
committerGitHub <noreply@github.com>2025-06-22 12:31:21 +0200
commit0203254b709614fa732c114aa25916f61b8b3275 (patch)
tree63232140a8e60e16e1668a51eb58954d8609fbdc /opendc-simulator/opendc-simulator-flow
parent8f846655347195bf6f22a4a102aa06f0ab127da1 (diff)
Implemented Single GPU Support & outline of host-level allocation policies (#342)
* renamed performance counter to distinguish different resource types * added GPU, modelled similar to CPU * added GPUs to machine model * list of GPUs instead of single instance * renamed memory speed to bandwidth * enabled parsing of GPU resources * split powermodel into cpu and GPU powermodel * added gpu parsing tests * added idea of host level scheduling * added tests for multi gpu parsing * renamed powermodel to cpupowermodel * clarified naming of cpu and gpu components * added resource type to flow suplier and edge * added resourcetype * added GPU components and resource type to fragments * added GPU to workload and updated resource usage retrieval * implemented first version of multi resource * added name to workload * renamed perfomance counters * removed commented out code * removed deprecated comments * included demand and supply into calculations * resolving rebase mismatches * moved resource type from flowedge class to common package * added available resources to machinees * cleaner separation if workload is started of simmachine or vm * Replaced exception with dedicated enum * Only looping over resources that are actually used * using hashmaps to handle resourcetype instead of arrays for readability * fixed condition * tracking finished workloads per resource type * removed resource type from flowedge * made supply and demand distribution resource specific * added power model for GPU * removed unused test setup * removed depracated comments * removed unused parameter * added ID for GPU * added GPUs and GPU performance counters (naively) * implemented capturing of GPU statistics * added reminders for future implementations * renamed properties for better identification * added capturing GPU statistics * implemented first tests for GPUs * unified access to performance counters * added interface for general compute resource handling * implemented multi resource support in simmachine * added individual edge to VM per resource * extended compute resource interface * implemented multi-resource support in PSU * implemented generic retrieval of computeresources * implemented mult-resource suppport in vm * made method use more resource specific * implemented simple GPU tests * rolled back frquency and demand use * made naming independent of used resource * using workloads resources instead of VMs to determine available resource * implemented determination of used resources in workload * removed logging statements * implemented reading from workload * fixed naming for host-level allocation * fixed next deadline calculation * fixed forwarding supply * reduced memory footprint * made GPU powermodel nullable * maded Gpu powermodel configurable in topology * implemented tests for basic gpu scheduler * added gpu properties * implemented weights, filter and simple cpu-gpu scheduler * spotless apply * spotless apply pt. 2 * fixed capitalization * spotless kotlin run * implemented coloumn export * todo update * removed code comments * Merged PerformanceCounter classes into one & removed interface * removed GPU specific powermodel * Rebase master: kept both versions of TopologyFactories * renamed CpuPowermodel to resource independent Powermodel Moved it from Cpu package to power package * implementated default of getResourceType & removed overrides if possible * split getResourceType into Consumer and Supplier * added power as resource type * reduced supply demand from arrayList to single value * combining GPUs into one large GPU, until full multi-gpu support * merged distribution policy enum with corresponding factory * added comment * post-rebase fixes * aligned naming * Added GPU metrics to task output * Updates power resource type to uppercase. Standardizes the `ResourceType.Power` enum to `ResourceType.POWER` for consistency with other resource types and improved readability. * Removes deprecated test assertions Removes commented-out assertions in GPU tests. These assertions are no longer needed and clutter the test code. * Renames MaxMinFairnessStrategy to Policy Renames MaxMinFairnessStrategy to MaxMinFairnessPolicy for clarity and consistency with naming conventions. This change affects the factory and distributor to use the updated name. * applies spotless * nulls GPUs as it is not used
Diffstat (limited to 'opendc-simulator/opendc-simulator-flow')
-rw-r--r--opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowConsumer.java15
-rw-r--r--opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowDistributor.java91
-rw-r--r--opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowEdge.java56
-rw-r--r--opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowSupplier.java20
-rw-r--r--opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/DistributionPolicy.java29
-rw-r--r--opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/DistributionPolicyFactory.java42
-rw-r--r--opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/FixedShare.java48
-rw-r--r--opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/MaxMinFairnessPolicy.java72
8 files changed, 319 insertions, 54 deletions
diff --git a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowConsumer.java b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowConsumer.java
index a9da6f5d..ac6ba8da 100644
--- a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowConsumer.java
+++ b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowConsumer.java
@@ -22,13 +22,28 @@
package org.opendc.simulator.engine.graph;
+import org.opendc.common.ResourceType;
+
public interface FlowConsumer {
void handleIncomingSupply(FlowEdge supplierEdge, double newSupply);
+ default void handleIncomingSupply(FlowEdge supplierEdge, double newSupply, ResourceType resourceType) {
+ handleIncomingSupply(supplierEdge, newSupply);
+ }
+
void pushOutgoingDemand(FlowEdge supplierEdge, double newDemand);
+ default void pushOutgoingDemand(FlowEdge supplierEdge, double newDemand, ResourceType resourceType) {
+ pushOutgoingDemand(supplierEdge, newDemand);
+ }
+
void addSupplierEdge(FlowEdge supplierEdge);
void removeSupplierEdge(FlowEdge supplierEdge);
+
+ // needed for flow nodes with multiple edges to same other flow node (PSU, VM)
+ default ResourceType getConsumerResourceType() {
+ return ResourceType.AUXILIARY;
+ }
}
diff --git a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowDistributor.java b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowDistributor.java
index 09cd73f6..674db8ca 100644
--- a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowDistributor.java
+++ b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowDistributor.java
@@ -23,13 +23,15 @@
package org.opendc.simulator.engine.graph;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import org.opendc.common.ResourceType;
import org.opendc.simulator.engine.engine.FlowEngine;
+import org.opendc.simulator.engine.graph.distributionPolicies.DistributionPolicy;
+import org.opendc.simulator.engine.graph.distributionPolicies.MaxMinFairnessPolicy;
public class FlowDistributor extends FlowNode implements FlowSupplier, FlowConsumer {
private final ArrayList<FlowEdge> consumerEdges = new ArrayList<>();
@@ -47,9 +49,16 @@ public class FlowDistributor extends FlowNode implements FlowSupplier, FlowConsu
private boolean overloaded = false;
private double capacity; // What is the max capacity. Can probably be removed
+ private DistributionPolicy distributionPolicy;
public FlowDistributor(FlowEngine engine) {
super(engine);
+ this.distributionPolicy = new MaxMinFairnessPolicy();
+ }
+
+ public FlowDistributor(FlowEngine engine, DistributionPolicy distributionPolicy) {
+ super(engine);
+ this.distributionPolicy = distributionPolicy;
}
public double getTotalIncomingDemand() {
@@ -88,6 +97,7 @@ public class FlowDistributor extends FlowNode implements FlowSupplier, FlowConsu
this.invalidate();
}
+ // TODO: This should probably be moved to the distribution strategy
private void updateOutgoingSupplies() {
// If the demand is higher than the current supply, the system is overloaded.
@@ -95,10 +105,11 @@ public class FlowDistributor extends FlowNode implements FlowSupplier, FlowConsu
if (this.totalIncomingDemand > this.currentIncomingSupply) {
this.overloaded = true;
- double[] supplies = distributeSupply(this.incomingDemands, this.currentIncomingSupply);
+ double[] supplies =
+ this.distributionPolicy.distributeSupply(this.incomingDemands, this.currentIncomingSupply);
for (int idx = 0; idx < this.consumerEdges.size(); idx++) {
- this.pushOutgoingSupply(this.consumerEdges.get(idx), supplies[idx]);
+ this.pushOutgoingSupply(this.consumerEdges.get(idx), supplies[idx], this.getConsumerResourceType());
}
} else {
@@ -108,7 +119,10 @@ public class FlowDistributor extends FlowNode implements FlowSupplier, FlowConsu
if (this.overloaded) {
for (int idx = 0; idx < this.consumerEdges.size(); idx++) {
if (!Objects.equals(this.outgoingSupplies.get(idx), this.incomingDemands.get(idx))) {
- this.pushOutgoingSupply(this.consumerEdges.get(idx), this.incomingDemands.get(idx));
+ this.pushOutgoingSupply(
+ this.consumerEdges.get(idx),
+ this.incomingDemands.get(idx),
+ this.getConsumerResourceType());
}
}
this.overloaded = false;
@@ -117,7 +131,8 @@ public class FlowDistributor extends FlowNode implements FlowSupplier, FlowConsu
// Update the supplies of the consumers that changed their demand in the current cycle
else {
for (int idx : this.updatedDemands) {
- this.pushOutgoingSupply(this.consumerEdges.get(idx), this.incomingDemands.get(idx));
+ this.pushOutgoingSupply(
+ this.consumerEdges.get(idx), this.incomingDemands.get(idx), this.getConsumerResourceType());
}
}
}
@@ -125,48 +140,6 @@ public class FlowDistributor extends FlowNode implements FlowSupplier, FlowConsu
this.updatedDemands.clear();
}
- private record Demand(int idx, double value) {}
-
- /**
- * Distributed the available supply over the different demands.
- * The supply is distributed using MaxMin Fairness.
- */
- private static double[] distributeSupply(ArrayList<Double> demands, double currentSupply) {
- int inputSize = demands.size();
-
- final double[] supplies = new double[inputSize];
- final Demand[] tempDemands = new Demand[inputSize];
-
- for (int i = 0; i < inputSize; i++) {
- tempDemands[i] = new Demand(i, demands.get(i));
- }
-
- Arrays.sort(tempDemands, (o1, o2) -> {
- Double i1 = o1.value;
- Double i2 = o2.value;
- return i1.compareTo(i2);
- });
-
- double availableCapacity = currentSupply; // totalSupply
-
- for (int i = 0; i < inputSize; i++) {
- double d = tempDemands[i].value;
-
- if (d == 0.0) {
- continue;
- }
-
- double availableShare = availableCapacity / (inputSize - i);
- double r = Math.min(d, availableShare);
-
- int idx = tempDemands[i].idx;
- supplies[idx] = r; // Update the rates
- availableCapacity -= r;
- }
-
- return supplies;
- }
-
/**
* Add a new consumer.
* Set its demand and supply to 0.0
@@ -260,6 +233,15 @@ public class FlowDistributor extends FlowNode implements FlowSupplier, FlowConsu
}
@Override
+ public void handleIncomingDemand(FlowEdge consumerEdge, double newDemand, ResourceType resourceType) {
+ if (resourceType != this.getSupplierResourceType()) {
+ throw new IllegalArgumentException("Resource type " + resourceType
+ + " does not match distributor resource type " + this.getSupplierResourceType());
+ }
+ this.handleIncomingDemand(consumerEdge, newDemand);
+ }
+
+ @Override
public void handleIncomingSupply(FlowEdge supplierEdge, double newSupply) {
this.currentIncomingSupply = newSupply;
@@ -268,7 +250,7 @@ public class FlowDistributor extends FlowNode implements FlowSupplier, FlowConsu
@Override
public void pushOutgoingDemand(FlowEdge supplierEdge, double newDemand) {
- this.supplierEdge.pushDemand(newDemand);
+ this.supplierEdge.pushDemand(newDemand, false, this.getSupplierResourceType());
}
@Override
@@ -284,7 +266,8 @@ public class FlowDistributor extends FlowNode implements FlowSupplier, FlowConsu
}
outgoingSupplies.set(idx, newSupply);
- consumerEdge.pushSupply(newSupply);
+ consumerEdge.pushSupply(newSupply, false, this.getSupplierResourceType());
+ consumerEdge.pushSupply(newSupply, false, this.getSupplierResourceType());
}
@Override
@@ -293,4 +276,14 @@ public class FlowDistributor extends FlowNode implements FlowSupplier, FlowConsu
return Map.of(FlowEdge.NodeType.CONSUMING, supplyingEdges, FlowEdge.NodeType.SUPPLYING, this.consumerEdges);
}
+
+ @Override
+ public ResourceType getSupplierResourceType() {
+ return this.supplierEdge.getSupplierResourceType();
+ }
+
+ @Override
+ public ResourceType getConsumerResourceType() {
+ return this.consumerEdges.getFirst().getConsumerResourceType();
+ }
}
diff --git a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowEdge.java b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowEdge.java
index 95eac20b..aa3894c1 100644
--- a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowEdge.java
+++ b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowEdge.java
@@ -22,6 +22,8 @@
package org.opendc.simulator.engine.graph;
+import org.opendc.common.ResourceType;
+
/**
* An edge that connects two FlowStages.
* A connection between FlowStages always consist of a FlowStage that demands
@@ -38,7 +40,9 @@ public class FlowEdge {
private double demand = 0.0;
private double supply = 0.0;
- private double capacity;
+ private final double capacity;
+
+ private final ResourceType resourceType;
public enum NodeType {
CONSUMING,
@@ -46,6 +50,10 @@ public class FlowEdge {
}
public FlowEdge(FlowConsumer consumer, FlowSupplier supplier) {
+ this(consumer, supplier, ResourceType.AUXILIARY);
+ }
+
+ public FlowEdge(FlowConsumer consumer, FlowSupplier supplier, ResourceType resourceType) {
if (!(consumer instanceof FlowNode)) {
throw new IllegalArgumentException("Flow consumer is not a FlowNode");
}
@@ -55,8 +63,9 @@ public class FlowEdge {
this.consumer = consumer;
this.supplier = supplier;
+ this.resourceType = resourceType;
- this.capacity = supplier.getCapacity();
+ this.capacity = supplier.getCapacity(resourceType);
this.consumer.addSupplierEdge(this);
this.supplier.addConsumerEdge(this);
@@ -112,6 +121,33 @@ public class FlowEdge {
return this.supply;
}
+ /**
+ * Get the resource type of this edge.
+ *
+ * @return The resource type of this edge.
+ */
+ public ResourceType getResourceType() {
+ return this.resourceType;
+ }
+
+ /**
+ * Get the resource type of the supplier of this edge.
+ *
+ * @return The resource type of the supplier.
+ */
+ public ResourceType getSupplierResourceType() {
+ return this.supplier.getSupplierResourceType();
+ }
+
+ /**
+ * Get the resource type of the consumer of this edge.
+ *
+ * @return The resource type of the consumer.
+ */
+ public ResourceType getConsumerResourceType() {
+ return this.consumer.getConsumerResourceType();
+ }
+
public int getConsumerIndex() {
return consumerIndex;
}
@@ -128,6 +164,16 @@ public class FlowEdge {
this.supplierIndex = supplierIndex;
}
+ public void pushDemand(double newDemand, boolean forceThrough, ResourceType resourceType) {
+ // or store last resource type in the edge
+ if ((newDemand == this.demand) && !forceThrough) {
+ return;
+ }
+
+ this.demand = newDemand;
+ this.supplier.handleIncomingDemand(this, newDemand, resourceType);
+ }
+
/**
* Push new demand from the Consumer to the Supplier
*/
@@ -150,19 +196,19 @@ public class FlowEdge {
/**
* Push new supply from the Supplier to the Consumer
*/
- public void pushSupply(double newSupply, boolean forceThrough) {
+ public void pushSupply(double newSupply, boolean forceThrough, ResourceType resourceType) {
if ((newSupply == this.supply) && !forceThrough) {
return;
}
this.supply = newSupply;
- this.consumer.handleIncomingSupply(this, newSupply);
+ this.consumer.handleIncomingSupply(this, newSupply, resourceType);
}
/**
* Push new supply from the Supplier to the Consumer
*/
public void pushSupply(double newSupply) {
- this.pushSupply(newSupply, false);
+ this.pushSupply(newSupply, false, this.supplier.getSupplierResourceType());
}
}
diff --git a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowSupplier.java b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowSupplier.java
index da65392b..eb665b8c 100644
--- a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowSupplier.java
+++ b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowSupplier.java
@@ -22,15 +22,35 @@
package org.opendc.simulator.engine.graph;
+import org.opendc.common.ResourceType;
+
public interface FlowSupplier {
void handleIncomingDemand(FlowEdge consumerEdge, double newDemand);
+ default void handleIncomingDemand(FlowEdge consumerEdge, double newDemand, ResourceType resourceType) {
+ handleIncomingDemand(consumerEdge, newDemand);
+ }
+
void pushOutgoingSupply(FlowEdge consumerEdge, double newSupply);
+ default void pushOutgoingSupply(FlowEdge consumerEdge, double newSupply, ResourceType resourceType) {
+ pushOutgoingSupply(consumerEdge, newSupply);
+ }
+ ;
+
void addConsumerEdge(FlowEdge consumerEdge);
void removeConsumerEdge(FlowEdge consumerEdge);
double getCapacity();
+
+ default double getCapacity(ResourceType resourceType) {
+ return getCapacity();
+ }
+
+ default ResourceType getSupplierResourceType() {
+ return ResourceType.AUXILIARY;
+ }
+ ;
}
diff --git a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/DistributionPolicy.java b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/DistributionPolicy.java
new file mode 100644
index 00000000..9d2246cd
--- /dev/null
+++ b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/DistributionPolicy.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2025 AtLarge Research
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package org.opendc.simulator.engine.graph.distributionPolicies;
+
+import java.util.ArrayList;
+
+public interface DistributionPolicy {
+ double[] distributeSupply(ArrayList<Double> supply, double currentSupply);
+}
diff --git a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/DistributionPolicyFactory.java b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/DistributionPolicyFactory.java
new file mode 100644
index 00000000..53cded87
--- /dev/null
+++ b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/DistributionPolicyFactory.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2025 AtLarge Research
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package org.opendc.simulator.engine.graph.distributionPolicies;
+
+public class DistributionPolicyFactory {
+
+ public enum DistributionPolicyType {
+ MaxMinFairness,
+ FixedShare;
+ }
+
+ public static DistributionPolicy getDistributionStrategy(DistributionPolicyType distributionPolicyType) {
+
+ return switch (distributionPolicyType) {
+ case MaxMinFairness -> new MaxMinFairnessPolicy();
+ case FixedShare -> new FixedShare(1);
+ // actively misspelling
+ default -> throw new IllegalArgumentException(
+ "Unknown distribution strategy type: " + distributionPolicyType);
+ };
+ }
+}
diff --git a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/FixedShare.java b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/FixedShare.java
new file mode 100644
index 00000000..40d70b5e
--- /dev/null
+++ b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/FixedShare.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2025 AtLarge Research
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package org.opendc.simulator.engine.graph.distributionPolicies;
+
+import java.util.ArrayList;
+
+/**
+ * A distribution policy that distributes supply equally among all nodes.
+ * The share can be set to a fixed value, defaulting to 1.
+ * This policy not implemented yet and is used as a placeholder.
+ */
+public class FixedShare implements DistributionPolicy {
+
+ private int share;
+
+ public FixedShare() {
+ this.share = 1;
+ }
+
+ public FixedShare(int share) {
+ this.share = share;
+ }
+
+ @Override
+ public double[] distributeSupply(ArrayList<Double> supply, double currentSupply) {
+ return new double[0];
+ }
+}
diff --git a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/MaxMinFairnessPolicy.java b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/MaxMinFairnessPolicy.java
new file mode 100644
index 00000000..1d387349
--- /dev/null
+++ b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/MaxMinFairnessPolicy.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2025 AtLarge Research
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package org.opendc.simulator.engine.graph.distributionPolicies;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * A distribution policy that implements the Max-Min Fairness algorithm.
+ * This policy distributes supply to demands in a way that maximizes the minimum
+ * allocation across all demands, ensuring fairness.
+ */
+public class MaxMinFairnessPolicy implements DistributionPolicy {
+ private record Demand(int idx, double value) {}
+
+ @Override
+ public double[] distributeSupply(ArrayList<Double> demands, double currentSupply) {
+ int inputSize = demands.size();
+
+ final double[] supplies = new double[inputSize];
+ final Demand[] tempDemands = new Demand[inputSize];
+
+ for (int i = 0; i < inputSize; i++) {
+ tempDemands[i] = new Demand(i, demands.get(i));
+ }
+
+ Arrays.sort(tempDemands, (o1, o2) -> {
+ Double i1 = o1.value;
+ Double i2 = o2.value;
+ return i1.compareTo(i2);
+ });
+
+ double availableCapacity = currentSupply; // totalSupply
+
+ for (int i = 0; i < inputSize; i++) {
+ double d = tempDemands[i].value;
+
+ if (d == 0.0) {
+ continue;
+ }
+
+ double availableShare = availableCapacity / (inputSize - i);
+ double r = Math.min(d, availableShare);
+
+ int idx = tempDemands[i].idx;
+ supplies[idx] = r; // Update the rates
+ availableCapacity -= r;
+ }
+
+ return supplies;
+ }
+}