Merge pull request #77 from Echtzeitsysteme/feature/gips-bw-ignore

Adds GIPS-based VNE algorithm that ignores all bandwidth constraints
This commit is contained in:
Maximilian Kratz 2024-06-13 09:05:07 +02:00 committed by GitHub
commit e11f951897
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 456 additions and 2 deletions

2
.gitignore vendored
View file

@ -139,3 +139,5 @@ org.emoflon.gips.gipsl.examples.mdvne.migration/
org.emoflon.gips.gipsl.examples.mdvne.seq/
*.lp
org.emoflon.gips.gipsl.examples.mdvne.bwignore/

View file

@ -14,4 +14,7 @@ xcopy ..\..\gips-examples\%MDVNE_PROJECT_NAME%.migration\src-gen ..\%MDVNE_PROJE
rmdir ..\%MDVNE_PROJECT_NAME%.seq\src-gen /s /q
xcopy ..\..\gips-examples\%MDVNE_PROJECT_NAME%.seq\src-gen ..\%MDVNE_PROJECT_NAME%.seq\src-gen\ /e
rmdir ..\%MDVNE_PROJECT_NAME%.bwignore\src-gen /s /q
xcopy ..\..\gips-examples\%MDVNE_PROJECT_NAME%.bwignore\src-gen ..\%MDVNE_PROJECT_NAME%.bwignore\src-gen\ /e
endlocal

View file

@ -15,3 +15,6 @@ rsync -a --progress --stats ../../gips-examples/$MDVNE_PROJECT_NAME.migration/sr
rm -rf ../$MDVNE_PROJECT_NAME.seq/src-gen
rsync -a --progress --stats ../../gips-examples/$MDVNE_PROJECT_NAME.seq/src-gen ../$MDVNE_PROJECT_NAME.seq
rm -rf ../$MDVNE_PROJECT_NAME.bwignore/src-gen
rsync -a --progress --stats ../../gips-examples/$MDVNE_PROJECT_NAME.bwignore/src-gen ../$MDVNE_PROJECT_NAME.bwignore

View file

@ -0,0 +1,82 @@
package test.algorithms.gips.bwignore;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.util.Set;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import algorithms.gips.VneGipsBwIgnoreAlgorithm;
import facade.config.ModelFacadeConfig;
import model.SubstrateNetwork;
import model.VirtualNetwork;
import test.algorithms.generic.AAlgorithmTest;
/**
* Test class for the VNE GIPS algorithm implementation that ignores the
* bandwidth constraints for simple checks and debugging.
*
* @author Maximilian Kratz {@literal <maximilian.kratz@es.tu-darmstadt.de>}
*/
public class VneGipsBwIgnoreAlgorithmConfigTest extends AAlgorithmTest {
/**
* Substrate network.
*/
SubstrateNetwork sNet;
/**
* Virtual network.
*/
VirtualNetwork vNet;
@Override
public void initAlgo(final SubstrateNetwork sNet, final Set<VirtualNetwork> vNets) {
algo = VneGipsBwIgnoreAlgorithm.prepare(sNet, vNets);
}
@AfterEach
public void resetAlgo() {
facade.resetAll();
if (algo != null) {
((VneGipsBwIgnoreAlgorithm) algo).dispose();
}
}
//
// Tests
//
@Test
public void testBwIgnoreException() {
facade.addServerToNetwork("ssrv1", "sub", 1, 1, 1, 1);
sNet = (SubstrateNetwork) facade.getNetworkById("sub");
vNet = (VirtualNetwork) facade.getNetworkById("virt");
ModelFacadeConfig.IGNORE_BW = false;
initAlgo(sNet, Set.of(vNet));
assertThrows(UnsupportedOperationException.class, () -> {
algo.execute();
});
}
@Test
public void testBwIgnoreNoException() {
facade.addServerToNetwork("ssrv1", "sub", 1, 1, 1, 1);
sNet = (SubstrateNetwork) facade.getNetworkById("sub");
vNet = (VirtualNetwork) facade.getNetworkById("virt");
ModelFacadeConfig.IGNORE_BW = true;
initAlgo(sNet, Set.of(vNet));
assertDoesNotThrow(() -> {
algo.execute();
});
}
}

View file

@ -0,0 +1,79 @@
package test.algorithms.gips.bwignore;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.Set;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import algorithms.AlgorithmConfig;
import algorithms.AlgorithmConfig.Objective;
import algorithms.gips.VneGipsBwIgnoreAlgorithm;
import facade.config.ModelFacadeConfig;
import model.SubstrateNetwork;
import model.VirtualLink;
import model.VirtualNetwork;
import test.algorithms.gips.VneGipsAlgorithmRejectionTest;
/**
* Test class for the VNE GIPS bandwidth ignore algorithm implementation for
* rejecting VNs that can not be embedded properly.
*
* @author Maximilian Kratz {@literal <maximilian.kratz@es.tu-darmstadt.de>}
*/
public class VneGipsBwIgnoreAlgorithmRejectionTest extends VneGipsAlgorithmRejectionTest {
/**
* Substrate network.
*/
SubstrateNetwork sNet;
/**
* Virtual network.
*/
VirtualNetwork vNet;
@Override
public void initAlgo(final SubstrateNetwork sNet, final Set<VirtualNetwork> vNets) {
// The algorithm is only able to use the total communication objective C because
// it is hard-coded in GIPSL
AlgorithmConfig.obj = Objective.TOTAL_COMMUNICATION_OBJECTIVE_C;
ModelFacadeConfig.IGNORE_BW = true;
algo = VneGipsBwIgnoreAlgorithm.prepare(sNet, vNets);
}
@AfterEach
public void resetAlgo() {
facade.resetAll();
((VneGipsBwIgnoreAlgorithm) algo).dispose();
}
//
// Tests
//
@Test
@Override
public void testAllLinksInVnetTooLarge() {
sNet = setUpSubNet(2, 2);
vNet = setUpVirtNet(4);
for (int i = 0; i < 8; i++) {
((VirtualLink) facade.getLinkById("virt_ln_" + i)).setBandwidth(100);
}
vNet = (VirtualNetwork) facade.getNetworkById("virt");
embedAndCheckNoReject();
}
//
// Utilities
//
public void embedAndCheckNoReject() {
initAlgo(sNet, Set.of(vNet));
assertTrue(algo.execute());
facade.validateModel();
}
}

View file

@ -0,0 +1,39 @@
package test.algorithms.gips.bwignore;
import java.util.Set;
import org.junit.jupiter.api.AfterEach;
import algorithms.AlgorithmConfig;
import algorithms.AlgorithmConfig.Objective;
import algorithms.gips.VneGipsBwIgnoreAlgorithm;
import facade.config.ModelFacadeConfig;
import model.SubstrateNetwork;
import model.VirtualNetwork;
import test.algorithms.gips.VneGipsAlgorithmSimpleTest;
/**
* Test class for the VNE GIPS algorithm implementation for simple checks and
* debugging.
*
* @author Maximilian Kratz {@literal <maximilian.kratz@es.tu-darmstadt.de>}
*/
public class VneGipsBwIgnoreAlgorithmSimpleTest extends VneGipsAlgorithmSimpleTest {
@Override
public void initAlgo(final SubstrateNetwork sNet, final Set<VirtualNetwork> vNets) {
// The algorithm is only able to use the total communication objective C because
// it is hard-coded in GIPSL
AlgorithmConfig.obj = Objective.TOTAL_COMMUNICATION_OBJECTIVE_C;
ModelFacadeConfig.IGNORE_BW = true;
algo = VneGipsBwIgnoreAlgorithm.prepare(sNet, vNets);
}
@Override
@AfterEach
public void resetAlgo() {
facade.resetAll();
((VneGipsBwIgnoreAlgorithm) algo).dispose();
}
}

View file

@ -0,0 +1,56 @@
package test.algorithms.gips.bwignore;
import java.util.Set;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Disabled;
import algorithms.AlgorithmConfig;
import algorithms.AlgorithmConfig.Objective;
import algorithms.gips.VneGipsBwIgnoreAlgorithm;
import facade.config.ModelFacadeConfig;
import model.SubstrateNetwork;
import model.VirtualNetwork;
import test.algorithms.gips.VneGipsAlgorithmTotalCommunicationObjectiveCTest;
/**
* Test class for the VNE GIPS sequence algorithm implementation for minimizing
* the total communication cost objective C.
*
* @author Maximilian Kratz {@literal <maximilian.kratz@es.tu-darmstadt.de>}
*/
public class VneGipsBwIgnoreAlgorithmTotalCommunicationObjectiveCTest
extends VneGipsAlgorithmTotalCommunicationObjectiveCTest {
@Override
public void initAlgo(final SubstrateNetwork sNet, final Set<VirtualNetwork> vNets) {
AlgorithmConfig.obj = Objective.TOTAL_COMMUNICATION_OBJECTIVE_C;
ModelFacadeConfig.IGNORE_BW = true;
algo = VneGipsBwIgnoreAlgorithm.prepare(sNet, vNets);
}
@AfterEach
public void resetAlgo() {
facade.resetAll();
if (algo != null) {
((VneGipsBwIgnoreAlgorithm) algo).dispose();
}
}
//
// Tests
//
@Disabled
public void testAllOnOneServer() {
}
@Disabled
public void testPreferenceOfFilledServers() {
}
@Disabled
public void testAllOnMultipleRacks() {
}
}

View file

@ -0,0 +1,82 @@
package test.algorithms.gips.bwignore;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.util.Set;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import algorithms.AlgorithmConfig;
import algorithms.AlgorithmConfig.Objective;
import algorithms.gips.VneGipsBwIgnoreAlgorithm;
import model.SubstrateNetwork;
import model.VirtualNetwork;
import test.algorithms.generic.AAlgorithmTest;
/**
* Test class for the VNE GIPS bandwidth ignore algorithm implementation to
* check its rejection of an invalid model state.
*
* @author Maximilian Kratz {@literal <maximilian.kratz@es.tu-darmstadt.de>}
*/
public class VneGipsBwIgnoreAlgorithmVnetSetExceptionTest extends AAlgorithmTest {
/**
* Substrate network.
*/
SubstrateNetwork sNet;
/**
* Virtual network.
*/
VirtualNetwork vNet;
@Override
public void initAlgo(final SubstrateNetwork sNet, final Set<VirtualNetwork> vNets) {
// The algorithm is only able to use the total communication objective C because
// it is hard-coded in GIPSL
AlgorithmConfig.obj = Objective.TOTAL_COMMUNICATION_OBJECTIVE_C;
algo = VneGipsBwIgnoreAlgorithm.prepare(sNet, vNets);
}
@AfterEach
public void resetAlgo() {
facade.resetAll();
if (algo != null) {
((VneGipsBwIgnoreAlgorithm) algo).dispose();
}
}
//
// Tests
//
// No virtual elements
@Test
public void testTwoVirtualNetworksEmbedding() {
facade.addServerToNetwork("ssrv1", "sub", 1, 1, 1, 1);
sNet = (SubstrateNetwork) facade.getNetworkById("sub");
vNet = (VirtualNetwork) facade.getNetworkById("virt");
// Second virtual network should trigger an exception
facade.addNetworkToRoot("vnet2", true);
checkAndValidate();
}
//
// Utility methods
//
private void checkAndValidate() {
sNet = (SubstrateNetwork) facade.getNetworkById("sub");
vNet = (VirtualNetwork) facade.getNetworkById("virt");
assertThrows(IllegalStateException.class, () -> {
initAlgo(sNet, Set.of(vNet));
});
}
}

View file

@ -23,5 +23,6 @@ Export-Package: algorithms,
algorithms.simple
Bundle-Vendor: Real-Time Systems Lab - TU Darmstadt
Import-Package: org.emoflon.gips.gipsl.examples.mdvne,
org.emoflon.gips.gipsl.examples.mdvne.bwignore,
org.emoflon.gips.gipsl.examples.mdvne.migration,
org.emoflon.gips.gipsl.examples.mdvne.seq

View file

@ -0,0 +1,104 @@
package algorithms.gips;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.emoflon.gips.gipsl.examples.mdvne.bwignore.MdvneGipsBwIgnoreIflyeAdapter;
import algorithms.AbstractAlgorithm;
import algorithms.AlgorithmConfig;
import algorithms.AlgorithmConfig.Objective;
import facade.ModelFacade;
import facade.config.ModelFacadeConfig;
import model.SubstrateNetwork;
import model.VirtualNetwork;
/**
* GIPS-based VNE algorithm implementation that ignores all bandwidth
* constraints.
*
* @author Maximilian Kratz {@literal <maximilian.kratz@es.tu-darmstadt.de>}
*/
public class VneGipsBwIgnoreAlgorithm extends AbstractAlgorithm {
/**
* Algorithm instance (singleton).
*/
private static VneGipsBwIgnoreAlgorithm instance;
/**
* Constructor that gets the substrate as well as the virtual network.
*
* @param sNet Substrate network to work with.
* @param vNets Set of virtual networks to work with.
*/
public VneGipsBwIgnoreAlgorithm(final SubstrateNetwork sNet, final Set<VirtualNetwork> vNets) {
super(sNet, vNets);
}
@Override
public boolean execute() {
// Check if correct objective is used
if (AlgorithmConfig.obj != Objective.TOTAL_COMMUNICATION_OBJECTIVE_C) {
throw new UnsupportedOperationException(
"The VNE GIPS algorithm can only be used with the total communication cost C.");
}
if (!ModelFacadeConfig.IGNORE_BW) {
throw new UnsupportedOperationException(
"Bandwidth ignore must be globally enabled when using this VNE algorithm implementation.");
}
// TODO: Time measurement
final ResourceSet model = ModelFacade.getInstance().getResourceSet();
final boolean gipsSuccess = MdvneGipsBwIgnoreIflyeAdapter.execute(model);
// The following workaround is not necessary because of the global bandwidth
// ignoring needed for this VNE algorithm
// // Workaround to fix the residual bandwidth of other paths possibly affected by
// // virtual link to substrate path embeddings
// ModelFacade.getInstance().updateAllPathsResidualBandwidth(sNet.getName());
return gipsSuccess;
}
/**
* Initializes a new instance of the GIPS-based VNE algorithm.
*
* @param sNet Substrate network to work with.
* @param vNets Set of virtual networks to work with.
* @return Instance of this algorithm implementation.
*/
public static VneGipsBwIgnoreAlgorithm prepare(final SubstrateNetwork sNet, final Set<VirtualNetwork> vNets) {
if (sNet == null || vNets == null) {
throw new IllegalArgumentException("One of the provided network objects was null.");
}
if (vNets.size() == 0) {
throw new IllegalArgumentException("Provided set of virtual networks was empty.");
}
VneGipsAlgorithmUtils.checkGivenVnets(vNets);
if (instance == null) {
instance = new VneGipsBwIgnoreAlgorithm(sNet, vNets);
}
instance.sNet = sNet;
instance.vNets = new HashSet<>();
instance.vNets.addAll(vNets);
return instance;
}
/**
* Resets the algorithm instance.
*/
public void dispose() {
MdvneGipsBwIgnoreIflyeAdapter.resetInit();
if (instance == null) {
return;
}
instance = null;
}
}

View file

@ -17,6 +17,7 @@ import algorithms.AlgorithmConfig;
import algorithms.AlgorithmConfig.Embedding;
import algorithms.AlgorithmConfig.Objective;
import algorithms.gips.VneGipsAlgorithm;
import algorithms.gips.VneGipsBwIgnoreAlgorithm;
import algorithms.gips.VneGipsMigrationAlgorithm;
import algorithms.gips.VneGipsSeqAlgorithm;
import algorithms.heuristics.TafAlgorithm;
@ -164,8 +165,8 @@ public class DissScenarioLoad {
* <ol>
* <li>#0: Algorithm "pm", "pm-migration", "pm-pipeline2-vnet",
* "pm-pipeline2-racka", "pm-pipeline2-rackb", "pm-pipeline3a", "pm-pipeline3b",
* "ilp", "ilp-batch", "gips", "gips-mig", "gips-seq", random, or "taf"
* (required)</li>
* "ilp", "ilp-batch", "gips", "gips-mig", "gips-seq", "gips-bwignore", random,
* or "taf" (required)</li>
* <li>#1: Objective "total-path", "total-comm-a", "total-comm-b",
* "total-obj-c", "total-obj-d", "total-taf-comm" (required)</li>
* <li>#2: Embedding "emoflon", "emoflon_wo_update" or "manual" [only relevant
@ -418,6 +419,8 @@ public class DissScenarioLoad {
return VneGipsMigrationAlgorithm.prepare(sNet, vNets);
case "gips-seq":
return VneGipsSeqAlgorithm.prepare(sNet, vNets);
case "gips-bwignore":
return VneGipsBwIgnoreAlgorithm.prepare(sNet, vNets);
case "taf":
ModelFacadeConfig.IGNORE_BW = true;
return new TafAlgorithm(sNet, vNets);