| 1 | package de.uka.ipd.sdq.dsexplore.opt4j.optimizer.heuristic.operators.impl; |
| 2 | |
| 3 | import java.util.Collection; |
| 4 | |
| 5 | import org.apache.log4j.Logger; |
| 6 | import org.opt4j.core.problem.Genotype; |
| 7 | import org.opt4j.operator.copy.Copy; |
| 8 | |
| 9 | import de.uka.ipd.sdq.dsexplore.helper.EMFHelper; |
| 10 | import de.uka.ipd.sdq.dsexplore.launch.DSEWorkflowConfiguration; |
| 11 | import de.uka.ipd.sdq.dsexplore.opt4j.optimizer.heuristic.operators.AbstractTactic; |
| 12 | import de.uka.ipd.sdq.dsexplore.opt4j.optimizer.heuristic.operators.TacticsResultCandidate; |
| 13 | import de.uka.ipd.sdq.dsexplore.opt4j.representation.DSEIndividual; |
| 14 | import de.uka.ipd.sdq.dsexplore.opt4j.representation.DSEIndividualBuilder; |
| 15 | import de.uka.ipd.sdq.pcm.designdecision.Choice; |
| 16 | import de.uka.ipd.sdq.pcm.designdecision.ContinousRangeChoice; |
| 17 | import de.uka.ipd.sdq.pcm.designdecision.ContinuousProcessingRateDegree; |
| 18 | import de.uka.ipd.sdq.pcm.designdecision.DegreeOfFreedomInstance; |
| 19 | import de.uka.ipd.sdq.pcm.designdecision.DiscreteRangeChoice; |
| 20 | import de.uka.ipd.sdq.pcm.designdecision.NumberOfCoresDegree; |
| 21 | import de.uka.ipd.sdq.pcm.resourceenvironment.ProcessingResourceSpecification; |
| 22 | import de.uka.ipd.sdq.pcm.resultdecorator.resourceenvironmentdecorator.ProcessingResourceSpecificationResult; |
| 23 | import de.uka.ipd.sdq.pcm.resultdecorator.resourceenvironmentdecorator.UtilisationResult; |
| 24 | |
| 25 | public abstract class AbstractProcessingRateTactic extends AbstractTactic { |
| 26 | |
| 27 | /** Logger for log4j. */ |
| 28 | protected static Logger logger = Logger.getLogger("de.uka.ipd.sdq.opt4j.optimizer.heuristic.operators.impl.ProcessingRateImpl"); |
| 29 | |
| 30 | public AbstractProcessingRateTactic(Copy<Genotype> copy, |
| 31 | DSEIndividualBuilder individualBuilder, |
| 32 | DSEWorkflowConfiguration configuration, |
| 33 | String[] improvesDimensionPath) { |
| 34 | super(copy, individualBuilder, configuration, improvesDimensionPath); |
| 35 | } |
| 36 | |
| 37 | protected void addNewProcRateCandidate(DSEIndividual individual, Collection<TacticsResultCandidate> candidates, |
| 38 | ProcessingResourceSpecificationResult utilisationResultToBeChanged, ProcessingResourceSpecification utilProcessingResourceToBeChanged) { |
| 39 | // 2. Copy current genotype |
| 40 | TacticsResultCandidate candidate = individualBuilder.buildCandidate(copy.copy(individual.getGenotype()), individual); |
| 41 | // 3. Iterate through choices and find processing rate degree to change |
| 42 | boolean hasAppliedChange = false; |
| 43 | for (Choice choice : candidate.getGenotype()) { |
| 44 | if (choice instanceof ContinousRangeChoice) { |
| 45 | ContinousRangeChoice continousRangeChoice = (ContinousRangeChoice) choice; |
| 46 | DegreeOfFreedomInstance DegreeOfFreedomInstance = choice.getDegreeOfFreedomInstance(); |
| 47 | if (DegreeOfFreedomInstance instanceof ContinuousProcessingRateDegree) { |
| 48 | ContinuousProcessingRateDegree processingRateDegree = (ContinuousProcessingRateDegree) DegreeOfFreedomInstance; |
| 49 | if (EMFHelper.checkIdentity(processingRateDegree.getPrimaryChanged(), utilProcessingResourceToBeChanged.getResourceContainer_ProcessingResourceSpecification()) |
| 50 | && EMFHelper.checkIdentity(processingRateDegree.getProcessingresourcetype(), utilProcessingResourceToBeChanged.getActiveResourceType_ActiveResourceSpecification())) { |
| 51 | // apply change (either increase or decrease. Respect |
| 52 | // minimum allowed value of processing rate |
| 53 | double newProcessingRate = getUpdatedProcessingRate(continousRangeChoice, processingRateDegree); |
| 54 | continousRangeChoice.setChosenValue(newProcessingRate); |
| 55 | hasAppliedChange = true; |
| 56 | } |
| 57 | } |
| 58 | } |
| 59 | } |
| 60 | if (hasAppliedChange){ |
| 61 | finalizeAndAddCandidate(candidates, utilisationResultToBeChanged, |
| 62 | candidate); |
| 63 | } else { |
| 64 | logger.warn("Tried to apply Processing Rate Increase / Decrease Tactic, but the resource with the highest / lowest utilisation "+ |
| 65 | utilProcessingResourceToBeChanged.getActiveResourceType_ActiveResourceSpecification().getEntityName()+" of "+ |
| 66 | utilProcessingResourceToBeChanged.getResourceContainer_ProcessingResourceSpecification().getEntityName()+ |
| 67 | " is not in the degrees of freedom."); |
| 68 | } |
| 69 | } |
| 70 | |
| 71 | private void finalizeAndAddCandidate( |
| 72 | Collection<TacticsResultCandidate> candidates, |
| 73 | ProcessingResourceSpecificationResult utilisationResultToBeChanged, |
| 74 | TacticsResultCandidate candidate) { |
| 75 | candidate.setCandidateWeight(getCandidateWeight(utilisationResultToBeChanged)); |
| 76 | candidate.setHeuristic(this); |
| 77 | candidates.add(candidate); |
| 78 | increaseCounterOfGeneratedCandidates(); |
| 79 | } |
| 80 | |
| 81 | protected void addNewNumberOfCoresCandidate(DSEIndividual individual, |
| 82 | Collection<TacticsResultCandidate> candidates, |
| 83 | ProcessingResourceSpecificationResult maxUtilisationResult, |
| 84 | ProcessingResourceSpecification maxUtilProcessingResource) { |
| 85 | // 2. Copy current genotype |
| 86 | TacticsResultCandidate candidate = individualBuilder.buildCandidate(copy.copy(individual.getGenotype()), individual); |
| 87 | // 3. Iterate through choices and find number of cores degree to change |
| 88 | for (Choice choice : candidate.getGenotype()) { |
| 89 | if (choice instanceof DiscreteRangeChoice && choice.getDegreeOfFreedomInstance() instanceof NumberOfCoresDegree) { |
| 90 | DiscreteRangeChoice discreteChoice = (DiscreteRangeChoice)choice; |
| 91 | NumberOfCoresDegree numberOfCoresDegree = (NumberOfCoresDegree)choice.getDegreeOfFreedomInstance(); |
| 92 | |
| 93 | // check if degree handles the resource to update |
| 94 | if (EMFHelper.checkIdentity(numberOfCoresDegree.getProcessingresourcetype(),maxUtilProcessingResource.getActiveResourceType_ActiveResourceSpecification()) |
| 95 | && EMFHelper.checkIdentity(numberOfCoresDegree.getPrimaryChanged(), maxUtilProcessingResource.getResourceContainer_ProcessingResourceSpecification())){ |
| 96 | int newNumberOfCores = getUpdatedNumberOfCores(discreteChoice, numberOfCoresDegree); |
| 97 | // check whether number of cores can be increased |
| 98 | if (newNumberOfCores != discreteChoice.getChosenValue()){ |
| 99 | finalizeAndAddCandidate(candidates, maxUtilisationResult, |
| 100 | candidate); |
| 101 | break; |
| 102 | } |
| 103 | } |
| 104 | |
| 105 | } |
| 106 | } |
| 107 | |
| 108 | |
| 109 | } |
| 110 | |
| 111 | protected abstract double getCandidateWeight( |
| 112 | UtilisationResult utilisationResultToBeChanged); |
| 113 | |
| 114 | protected abstract double getUpdatedProcessingRate( |
| 115 | ContinousRangeChoice continousRangeChoice, |
| 116 | ContinuousProcessingRateDegree processingRateDegree) ; |
| 117 | |
| 118 | protected abstract int getUpdatedNumberOfCores( |
| 119 | DiscreteRangeChoice discreteChoice, |
| 120 | NumberOfCoresDegree numberOfCoresDegree) ; |
| 121 | |
| 122 | |
| 123 | } |