1 | package de.uka.ipd.sdq.dsexplore.analysis.simucom; |
2 | |
3 | import java.util.ArrayList; |
4 | import java.util.Collection; |
5 | import java.util.Date; |
6 | import java.util.HashMap; |
7 | import java.util.Iterator; |
8 | import java.util.List; |
9 | import java.util.Map; |
10 | |
11 | import org.apache.log4j.Logger; |
12 | import org.eclipse.core.runtime.CoreException; |
13 | import org.eclipse.core.runtime.IProgressMonitor; |
14 | import org.eclipse.core.runtime.Status; |
15 | import org.eclipse.debug.core.ILaunchConfiguration; |
16 | import org.eclipse.debug.core.ILaunchManager; |
17 | import org.opt4j.core.Criterion; |
18 | import org.opt4j.core.InfeasibilityConstraint; |
19 | import org.opt4j.core.Objective; |
20 | import org.opt4j.core.SatisfactionConstraint; |
21 | |
22 | import de.uka.ipd.sdq.codegen.simucontroller.runconfig.SimuComWorkflowConfiguration; |
23 | import de.uka.ipd.sdq.codegen.simucontroller.runconfig.SimuComWorkflowLauncher; |
24 | import de.uka.ipd.sdq.codegen.simucontroller.workflow.jobs.SimuComJob; |
25 | import de.uka.ipd.sdq.dsexplore.analysis.AnalysisFailedException; |
26 | import de.uka.ipd.sdq.dsexplore.analysis.IAnalysis; |
27 | import de.uka.ipd.sdq.dsexplore.analysis.IAnalysisResult; |
28 | import de.uka.ipd.sdq.dsexplore.analysis.IStatisticAnalysisResult; |
29 | import de.uka.ipd.sdq.dsexplore.analysis.PCMPhenotype; |
30 | import de.uka.ipd.sdq.dsexplore.exception.ExceptionHelper; |
31 | import de.uka.ipd.sdq.dsexplore.helper.ConfigurationHelper; |
32 | import de.uka.ipd.sdq.dsexplore.launch.DSEWorkflowConfiguration; |
33 | import de.uka.ipd.sdq.dsexplore.launch.DSEConstantsContainer.QualityAttribute; |
34 | import de.uka.ipd.sdq.dsexplore.qml.contract.QMLContract.EvaluationAspect; |
35 | import de.uka.ipd.sdq.dsexplore.qml.contracttype.QMLContractType.Dimension; |
36 | import de.uka.ipd.sdq.dsexplore.qml.pcm.datastructures.EvaluationAspectWithContext; |
37 | import de.uka.ipd.sdq.dsexplore.qml.pcm.datastructures.UsageScenarioBasedInfeasibilityConstraint; |
38 | import de.uka.ipd.sdq.dsexplore.qml.pcm.datastructures.UsageScenarioBasedObjective; |
39 | import de.uka.ipd.sdq.dsexplore.qml.pcm.datastructures.UsageScenarioBasedSatisfactionConstraint; |
40 | import de.uka.ipd.sdq.dsexplore.qml.pcm.datastructures.builder.UsageScenarioBasedInfeasibilityConstraintBuilder; |
41 | import de.uka.ipd.sdq.dsexplore.qml.pcm.datastructures.builder.UsageScenarioBasedObjectiveBuilder; |
42 | import de.uka.ipd.sdq.dsexplore.qml.pcm.datastructures.builder.UsageScenarioBasedSatisfactionConstraintBuilder; |
43 | import de.uka.ipd.sdq.dsexplore.qml.pcm.reader.PCMDeclarationsReader; |
44 | import de.uka.ipd.sdq.dsexplore.qml.profile.QMLProfile.UsageScenarioRequirement; |
45 | import de.uka.ipd.sdq.pcm.usagemodel.UsageModel; |
46 | import de.uka.ipd.sdq.pcm.usagemodel.UsageScenario; |
47 | import de.uka.ipd.sdq.pcmsolver.models.PCMInstance; |
48 | import de.uka.ipd.sdq.pipesandfilters.framework.recorder.launch.IRecorderConfiguration; |
49 | import de.uka.ipd.sdq.pipesandfilters.framework.recorder.sensorframework.DatasourceConfigurationInvalidException; |
50 | import de.uka.ipd.sdq.pipesandfilters.framework.recorder.sensorframework.launch.SensorFrameworkConfig; |
51 | import de.uka.ipd.sdq.sensorframework.SensorFrameworkDataset; |
52 | import de.uka.ipd.sdq.sensorframework.entities.Experiment; |
53 | import de.uka.ipd.sdq.sensorframework.entities.ExperimentRun; |
54 | import de.uka.ipd.sdq.sensorframework.entities.dao.IDAOFactory; |
55 | import de.uka.ipd.sdq.simucomframework.SimuComConfig; |
56 | import de.uka.ipd.sdq.workflow.exceptions.JobFailedException; |
57 | import de.uka.ipd.sdq.workflow.exceptions.UserCanceledException; |
58 | import de.uka.ipd.sdq.workflow.mdsd.blackboard.MDSDBlackboard; |
59 | import de.uka.ipd.sdq.workflow.mdsd.blackboard.ResourceSetPartition; |
60 | import de.uka.ipd.sdq.workflow.pcm.blackboard.PCMResourceSetPartition; |
61 | import de.uka.ipd.sdq.workflow.pcm.jobs.LoadPCMModelsIntoBlackboardJob; |
62 | |
63 | /** |
64 | * Starts a SimuCom Analysis for the design space exploration. |
65 | * @author Anne |
66 | * |
67 | */ |
68 | public class SimuComAnalysis extends SimuComWorkflowLauncher implements IAnalysis { |
69 | |
70 | /** Logger for log4j. */ |
71 | private static Logger logger = |
72 | Logger.getLogger("de.uka.ipd.sdq.dsexplore"); |
73 | |
74 | /** Store the launch parameters so that we do not have to pass them all the time.*/ |
75 | private ILaunchConfiguration config; |
76 | |
77 | private String initialExperimentName; |
78 | private Map<Integer, String> previousExperimentNames = new HashMap<Integer, String>(); |
79 | |
80 | private SimuComWorkflowConfiguration simuComWorkflowConfiguration; |
81 | |
82 | private MDSDBlackboard blackboard; |
83 | |
84 | private SimuComQualityAttributeDeclaration simuComQualityAttribute = new SimuComQualityAttributeDeclaration(); |
85 | |
86 | //Criteria handling |
87 | private List<Criterion> criteriaList = new ArrayList<Criterion>(); |
88 | private Map<Criterion, EvaluationAspectWithContext> criterionToAspect = new HashMap<Criterion, EvaluationAspectWithContext>(); //This is needed to determine, what THE result is (Mean, Variance, ...) |
89 | |
90 | private int datasourceReloadCount = 1; |
91 | |
92 | /** |
93 | * Calls SimuCom. Before doing so, it calls the {@link ConfigurationHelper} |
94 | * to update the {@link ILaunchConfiguration} and stores the |
95 | * {@link PCMInstance} to files, so that SimuCom can read it as usual. After |
96 | * the SimuCom run, the analysis results are extracted from the |
97 | * sensorFramework data sources and returned. The returned |
98 | * {@link IAnalysisResult} is a {@link SimuComAnalysisResult} which does not |
99 | * store the results directly, but provides access to the underlying |
100 | * sensorFramework data sources. |
101 | * |
102 | * {@inheritDoc} |
103 | * @throws UserCanceledException |
104 | * |
105 | * @see de.uka.ipd.sdq.dsexplore.analysis.IAnalysis#analyse(PCMPhenotype, de.uka.ipd.sdq.dsexplore.PCMInstance) |
106 | */ |
107 | @Override |
108 | public void analyse(PCMPhenotype pheno, IProgressMonitor monitor) throws AnalysisFailedException, CoreException, UserCanceledException { |
109 | |
110 | String experimentName = getExperimentName(pheno); |
111 | this.previousExperimentNames.put(pheno.getGenotypeID().hashCode(), experimentName); |
112 | this.simuComWorkflowConfiguration.getSimulationConfiguration().setNameBase(experimentName); |
113 | |
114 | System.gc(); |
115 | |
116 | if (isExperimentRunDoesNotExist(experimentName)){ |
117 | launchSimuCom( monitor); |
118 | } |
119 | |
120 | |
121 | } |
122 | |
123 | |
124 | |
125 | /** |
126 | * Search in all open data sources whether there is already an experiment run with this name. |
127 | * @param experimentName |
128 | * @return |
129 | */ |
130 | private boolean isExperimentRunDoesNotExist(String experimentName) { |
131 | |
132 | IRecorderConfiguration recorderConfig = this.simuComWorkflowConfiguration.getSimulationConfiguration().getRecorderConfig(); |
133 | |
134 | if (recorderConfig instanceof SensorFrameworkConfig){ |
135 | |
136 | // Every few runs the datasource needs to be reloaded because the simulation will fail with OutOfmemoryError after ~300 simulations otherwise |
137 | if (this.datasourceReloadCount >= 100 ){ |
138 | SensorFrameworkDataset.singleton().reload(); |
139 | this.datasourceReloadCount = 0; |
140 | } |
141 | this.datasourceReloadCount++; |
142 | |
143 | // Obtain DAOFactories. Search in any open data source. |
144 | Collection<IDAOFactory> daoFactoryCollection = SensorFrameworkDataset.singleton().getDataSources(); |
145 | |
146 | for (IDAOFactory daoFactory : daoFactoryCollection) { |
147 | if (daoFactory == null) |
148 | throw new DatasourceConfigurationInvalidException(); |
149 | |
150 | Experiment experiment; |
151 | // Find an existing or create a new Experiment |
152 | Collection<Experiment> experimentSet = daoFactory.createExperimentDAO().findByExperimentName(experimentName); |
153 | |
154 | if (experimentSet.size() > 0){ |
155 | experiment = experimentSet.iterator().next(); |
156 | |
157 | if (experiment.getExperimentRuns().size() > 0){ |
158 | return false; |
159 | } |
160 | |
161 | } |
162 | } |
163 | |
164 | } |
165 | return true; |
166 | } |
167 | |
168 | |
169 | |
170 | private String getExperimentName(PCMPhenotype pheno) { |
171 | return this.initialExperimentName+" "+pheno.getGenotypeID(); |
172 | } |
173 | |
174 | |
175 | /** |
176 | * FIXME: This method should not depend on the state of the blackboard anymore... but it does at this time. |
177 | * |
178 | * @param pheno |
179 | * @param usageScenario |
180 | * @return |
181 | * @throws CoreException |
182 | * @throws AnalysisFailedException |
183 | */ |
184 | private IStatisticAnalysisResult retrieveSimuComResults(PCMPhenotype pheno, UsageScenario usageScenario) |
185 | throws CoreException, AnalysisFailedException { |
186 | |
187 | String experimentName = this.previousExperimentNames.get(pheno.getGenotypeID().hashCode()); |
188 | PCMResourceSetPartition pcmPartition = (PCMResourceSetPartition)this.blackboard.getPartition(LoadPCMModelsIntoBlackboardJob.PCM_MODELS_PARTITION_ID); |
189 | PCMInstance pcmInstance = new PCMInstance(pcmPartition); |
190 | |
191 | IStatisticAnalysisResult result = null; |
192 | int selectedDataSourceID = |
193 | config.getAttribute( |
194 | SensorFrameworkConfig.DATASOURCE_ID, -1); |
195 | |
196 | // try the configured data source first. |
197 | IDAOFactory factory = SensorFrameworkDataset.singleton().getDataSourceByID(selectedDataSourceID); |
198 | if (factory != null){ |
199 | result = findExperimentRunAndCreateResult(usageScenario, |
200 | experimentName, pcmInstance, factory); |
201 | } |
202 | |
203 | if (result == null){ |
204 | // try all other open data sources. |
205 | Collection<IDAOFactory> daoFactories = SensorFrameworkDataset.singleton().getDataSources(); |
206 | for (IDAOFactory idaoFactory : daoFactories) { |
207 | if (idaoFactory == factory){ |
208 | // we tried this one already |
209 | continue; |
210 | } |
211 | result = findExperimentRunAndCreateResult(usageScenario, |
212 | experimentName, pcmInstance, idaoFactory); |
213 | |
214 | if (result != null){ |
215 | logger.warn("Found matching experiment run for this candidate in data source "+idaoFactory.getName()+" "+idaoFactory.getDescription()+"(id: "+idaoFactory.getID()+"), using it as the result for this candidate. Unload all other data sources and restart the optimisation if this is not correct. Candidate: "+pheno.getNumericID()+" "+pheno.getGenotypeID()); |
216 | break; |
217 | } |
218 | } |
219 | } |
220 | |
221 | |
222 | if (result == null){ |
223 | String errormessage = "There was no experiment run or no experiment for experiment named \"" |
224 | +experimentName+"\" in any available data source after analysing the PCM instance \"" |
225 | +experimentName+"\" of candidate "+pheno.getNumericID()+" "+pheno.getGenotypeID(); |
226 | logger.error(errormessage); |
227 | throw new AnalysisFailedException(errormessage); |
228 | } |
229 | |
230 | return result; |
231 | } |
232 | |
233 | |
234 | /** |
235 | * Tries to find a matching experiment run in the passed data source (via the passed <code>factory</code>). If a matching experiment run |
236 | * is found, a new {@link IStatisticAnalysisResult} is created for it. If not, <code>null</code> is returned. |
237 | * @param usageScenario The usage scenario to determine the response time values for. |
238 | * @param experimentName The experiment name to match |
239 | * @param pcmInstance The PCM instance to get the available resources and retrieve utilisation values. |
240 | * @param factory The access to the data source. |
241 | * @return The instantiated {@link IStatisticAnalysisResult} for this experiment name, or <code>null</code> if no matching experiment run could be found. |
242 | * @throws AnalysisFailedException |
243 | */ |
244 | private IStatisticAnalysisResult findExperimentRunAndCreateResult( |
245 | UsageScenario usageScenario, String experimentName, |
246 | PCMInstance pcmInstance, |
247 | IDAOFactory factory) throws AnalysisFailedException { |
248 | IStatisticAnalysisResult result = null; |
249 | //XXX: Quick fix: Assume that there is just one experiment with the name of the current PCM instance. |
250 | //Iterator<Experiment> it = factory.createExperimentDAO().findByExperimentName(experimentName |
251 | // +" RunNo. "+config.getAttribute(ConstantsContainer.RUN_NO, "0")).iterator(); |
252 | Iterator<Experiment> it = factory.createExperimentDAO().findByExperimentName(experimentName).iterator(); |
253 | if (it.hasNext()){ |
254 | Experiment resultingExperiment = it.next(); |
255 | Collection<ExperimentRun> runs = resultingExperiment.getExperimentRuns(); |
256 | if (runs.size() > 0){ |
257 | ExperimentRun myrun = getLatestRun(runs); |
258 | result = new SimuComAnalysisResult(myrun, resultingExperiment, pcmInstance, usageScenario, this.criterionToAspect, this.simuComQualityAttribute); |
259 | } |
260 | } |
261 | return result; |
262 | } |
263 | |
264 | |
265 | private void launchSimuCom(IProgressMonitor monitor) |
266 | throws CoreException, AnalysisFailedException, UserCanceledException { |
267 | |
268 | /* LoadPCMModelsIntoBlackboardJob loadJob = new LoadPCMModelsIntoBlackboardJob(config); |
269 | |
270 | PCMInstance pcm = new PCMInstance((PCMResourceSetPartition)this.blackboard.getPartition(LoadPCMModelsIntoBlackboardJob.PCM_MODELS_PARTITION_ID)); |
271 | pcm.saveToXMIFile(pcm.getSystem(), this.config.getAttribute(ConstantsContainer.SYSTEM_FILE, "")); |
272 | pcm.saveToXMIFile(pcm.getAllocation(), this.config.getAttribute(ConstantsContainer.ALLOCATION_FILE, "")); |
273 | |
274 | SimuComWorkflowLauncher simuCom = new SimuComWorkflowLauncher(); |
275 | |
276 | AbstractPCMWorkflowRunConfiguration PCMConfig;*/ |
277 | |
278 | // load feature config files into blackboard |
279 | |
280 | String featureConfigFile = this.simuComWorkflowConfiguration.getFeatureConfigFile(); |
281 | if (featureConfigFile != null && !"".equals(featureConfigFile)){ |
282 | ResourceSetPartition pcmPartition = this.blackboard.getPartition(LoadPCMModelsIntoBlackboardJob.PCM_MODELS_PARTITION_ID); |
283 | pcmPartition.loadModel(featureConfigFile); |
284 | } |
285 | |
286 | SimuComJob job = new SimuComJob(this.simuComWorkflowConfiguration, null, false); |
287 | job.setBlackboard(this.blackboard); |
288 | |
289 | // retry simulation if the cause was that an extension could not be loaded, because that seems to be a transient problem (it only happens sometimes) |
290 | int numberOfTries = 2; |
291 | for (int i = 0; i < numberOfTries; i++){ |
292 | try { |
293 | // start SimuCom |
294 | job.execute(monitor); |
295 | logger.debug("Finished SimuCom analysis"); |
296 | break; |
297 | } catch (JobFailedException e) { |
298 | logger.error(e.getMessage()); |
299 | if (numberOfTries > 0 && e.getCause().getMessage().contains("Couldn't find extension")){ |
300 | logger.warn("Trying to start SimuCom again."); |
301 | } else { |
302 | throw new AnalysisFailedException(e); |
303 | } |
304 | } |
305 | } |
306 | |
307 | } |
308 | |
309 | |
310 | // /** Put all the old appends back in the logger. FIXME: does not work as expected :( but whatever. |
311 | // * @throws CoreException */ |
312 | // private void restoreLogger(ILaunchConfiguration config) throws CoreException { |
313 | // BasicConfigurator.resetConfiguration(); |
314 | // LoggerHelper.initializeLogger(config); |
315 | // } |
316 | |
317 | |
318 | /** |
319 | * Get the latest Run from the {@link Collection} based on the getExperimentDateTime() |
320 | * value. |
321 | * @param runs A collection of {@link ExperimentRun} |
322 | * @return The latest run or the first in the collection if timestamps |
323 | * cannot properly be parsed. |
324 | */ |
325 | private ExperimentRun getLatestRun(Collection<ExperimentRun> runs) { |
326 | Iterator<ExperimentRun> iterator = runs.iterator(); |
327 | ExperimentRun latest = iterator.next(); |
328 | //FIXME: Due to Bug 395, I cannot get the order of ExperimentRuns. |
329 | //Quickfix: Extract it from the (nasty) ExperimentDateTime String as a long. |
330 | long dateLatest = extractTimestamp(latest.getExperimentDateTime()); |
331 | for (; iterator.hasNext();) { |
332 | ExperimentRun experimentRun = iterator.next(); |
333 | logger.debug("Looking at run "+experimentRun.getExperimentDateTime()); |
334 | long runDate = extractTimestamp(experimentRun.getExperimentDateTime()); |
335 | if (dateLatest < runDate){ |
336 | latest = experimentRun; |
337 | dateLatest = runDate; |
338 | } |
339 | } |
340 | logger.debug("Latest run: "+latest.getExperimentDateTime()); |
341 | return latest; |
342 | } |
343 | |
344 | |
345 | |
346 | /** |
347 | * Extract time stamps from the experimentDateTime string. This is just a |
348 | * QuickFix because {@link ExperimentRun}s currently do not store their |
349 | * time properly. |
350 | * |
351 | * Delete this method after Bug 395 is fixed. |
352 | * |
353 | * @param experimentDateTime |
354 | * @return The {@link Date} of the {@link ExperimentRun} |
355 | */ |
356 | private long extractTimestamp(String experimentDateTime) { |
357 | //XXX fix this as soon as Bug 395 is fixed |
358 | |
359 | //Cut the "Run " part. |
360 | experimentDateTime = experimentDateTime.substring(4); |
361 | String[] experimentDateTimeArray = experimentDateTime.split(" "); |
362 | String month = experimentDateTimeArray[1]; |
363 | |
364 | //This is stupid, but what else to do with the nasty string... |
365 | int monthNo = 0; |
366 | if (month.equals("Jan")){ |
367 | monthNo = 1; |
368 | } else if (month.equals("Feb")){ |
369 | monthNo = 2; |
370 | } else if (month.equals("Mar")){ |
371 | monthNo = 3; |
372 | } else if (month.equals("Apr")){ |
373 | monthNo = 4; |
374 | } else if (month.equals("May")){ |
375 | monthNo = 5; |
376 | } else if (month.equals("Jun")){ |
377 | monthNo = 6; |
378 | } else if (month.equals("Jul")){ |
379 | monthNo = 7; |
380 | } else if (month.equals("Aug")){ |
381 | monthNo = 8; |
382 | } else if (month.equals("Sep")){ |
383 | monthNo = 9; |
384 | } else if (month.equals("Oct")){ |
385 | monthNo = 10; |
386 | } else if (month.equals("Nov")){ |
387 | monthNo = 11; |
388 | } else monthNo = 12; |
389 | |
390 | int day = Integer.parseInt(experimentDateTimeArray[2]); |
391 | String[] time = experimentDateTimeArray[3].split(":"); |
392 | int hour = Integer.parseInt(time[0]); |
393 | int minute = Integer.parseInt(time[1]); |
394 | int second = Integer.parseInt(time[2]); |
395 | int year = Integer.parseInt(experimentDateTimeArray[5]); |
396 | |
397 | //The date in seconds since year 0. |
398 | long date = (((((year * 12) + monthNo) * 31 + day)* 24 + hour)*60 + minute ) * 60 + second; |
399 | |
400 | return date; |
401 | } |
402 | |
403 | |
404 | |
405 | /** |
406 | * {@inheritDoc} |
407 | * @throws CoreException |
408 | * @see de.uka.ipd.sdq.dsexplore.analysis.IAnalysis#initialise(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.debug.core.ILaunch, org.eclipse.core.runtime.IProgressMonitor) |
409 | */ |
410 | @Override |
411 | public void initialise(DSEWorkflowConfiguration configuration) throws CoreException { |
412 | |
413 | this.previousExperimentNames.clear(); |
414 | |
415 | this.config = configuration.getRawConfiguration(); |
416 | if (blackboard == null){ |
417 | throw ExceptionHelper.createNewCoreException("Error in initialisation: No Blackboard was set when initialising the SimuCom Analysis. Contact the developers."); |
418 | } |
419 | |
420 | this.initialExperimentName = this.config.getAttribute(SimuComConfig.EXPERIMENT_RUN, ""); |
421 | |
422 | this.simuComWorkflowConfiguration = deriveConfiguration(this.config, ILaunchManager.RUN_MODE); |
423 | this.simuComWorkflowConfiguration.setOverwriteWithoutAsking(true); |
424 | |
425 | PCMInstance pcmInstance = new PCMInstance((PCMResourceSetPartition)blackboard.getPartition(LoadPCMModelsIntoBlackboardJob.PCM_MODELS_PARTITION_ID)); |
426 | List<UsageScenario> scenarios = pcmInstance.getUsageModel().getUsageScenario_UsageModel(); |
427 | // this.objectives = new ArrayList<Objective>(scenarios.size()); |
428 | // for (UsageScenario usageScenario : scenarios) { |
429 | // objectives.add(new UsageScenarioBasedObjective(this.getQualityAttribute(), Objective.Sign.MIN, usageScenario)); |
430 | // } |
431 | |
432 | initialiseCriteria(pcmInstance, this.config, scenarios); |
433 | } |
434 | |
435 | /** |
436 | * TODO: document me! |
437 | * |
438 | * @param pcmInstance |
439 | * @param configuration |
440 | * @param scenarios |
441 | * @throws CoreException |
442 | */ |
443 | private void initialiseCriteria(PCMInstance pcmInstance, ILaunchConfiguration configuration, List<UsageScenario> scenarios) throws CoreException{ |
444 | UsageModel usageModel = pcmInstance.getUsageModel(); |
445 | |
446 | PCMDeclarationsReader reader = new PCMDeclarationsReader( |
447 | configuration.getAttribute("qmlDefinitionFile", "")); |
448 | |
449 | List<Dimension> dimensions = simuComQualityAttribute.getDimensions(); |
450 | |
451 | List<EvaluationAspectWithContext> responseTimeAspects = new ArrayList<EvaluationAspectWithContext>(6); |
452 | for (Dimension dimension : dimensions) { |
453 | responseTimeAspects.addAll(reader.getDimensionConstraintContextsForUsageModel(usageModel, dimension.getId())); |
454 | responseTimeAspects.addAll(reader.getDimensionObjectiveContextsForUsageModel(usageModel, dimension.getId())); |
455 | } |
456 | |
457 | //Check constraint aspects and create Constraint-Objects for every Aspect |
458 | for (Iterator<EvaluationAspectWithContext> iterator = responseTimeAspects.iterator(); iterator.hasNext();) { |
459 | EvaluationAspectWithContext aspectContext = iterator |
460 | .next(); |
461 | |
462 | if(aspectContext.getRequirement() instanceof UsageScenarioRequirement) { |
463 | |
464 | //handle possible aspects here |
465 | if (canEvaluateAspect(aspectContext.getEvaluationAspect(), aspectContext.getDimension())) { |
466 | |
467 | if(((UsageScenarioRequirement)aspectContext.getRequirement()).getUsageScenario() == null) { |
468 | //The criterion refers to EVERY US since none is explicitly specified |
469 | for (Iterator<UsageScenario> iterator2 = scenarios.iterator(); iterator2.hasNext();) { |
470 | UsageScenario usageScenario = (UsageScenario) iterator2 |
471 | .next(); |
472 | if(aspectContext.getCriterion() instanceof de.uka.ipd.sdq.dsexplore.qml.contract.QMLContract.Constraint) { |
473 | UsageScenarioBasedInfeasibilityConstraintBuilder builder = new UsageScenarioBasedInfeasibilityConstraintBuilder(usageScenario); |
474 | InfeasibilityConstraint c = |
475 | reader.translateEvalAspectToInfeasibilityConstraint(aspectContext, builder); |
476 | |
477 | criteriaList.add(c); |
478 | criterionToAspect.put(c, aspectContext); |
479 | } else { |
480 | //instanceof Objective |
481 | UsageScenarioBasedObjectiveBuilder objectiveBuilder = new UsageScenarioBasedObjectiveBuilder(usageScenario); |
482 | Objective o = reader.translateEvalAspectToObjective(this.getQualityAttribute().getName(), aspectContext, objectiveBuilder); |
483 | criteriaList.add(o); |
484 | criterionToAspect.put(o, aspectContext); |
485 | |
486 | UsageScenarioBasedSatisfactionConstraintBuilder builder = new UsageScenarioBasedSatisfactionConstraintBuilder(usageScenario); |
487 | SatisfactionConstraint c = |
488 | reader.translateEvalAspectToSatisfactionConstraint(aspectContext, o, builder); |
489 | criteriaList.add(c); |
490 | criterionToAspect.put(c, aspectContext); |
491 | } |
492 | } |
493 | } else { |
494 | UsageScenario usageScenario = ((UsageScenarioRequirement)aspectContext.getRequirement()).getUsageScenario(); |
495 | |
496 | if(aspectContext.getCriterion() instanceof de.uka.ipd.sdq.dsexplore.qml.contract.QMLContract.Constraint) { |
497 | |
498 | UsageScenarioBasedInfeasibilityConstraintBuilder builder = new UsageScenarioBasedInfeasibilityConstraintBuilder(usageScenario); |
499 | InfeasibilityConstraint c = |
500 | reader.translateEvalAspectToInfeasibilityConstraint(aspectContext, builder); |
501 | criteriaList.add(c); |
502 | criterionToAspect.put(c, aspectContext); |
503 | } else { |
504 | //instanceof Objective |
505 | |
506 | UsageScenarioBasedObjectiveBuilder objectiveBuilder = new UsageScenarioBasedObjectiveBuilder(usageScenario); |
507 | Objective o = reader.translateEvalAspectToObjective(this.getQualityAttribute().getName(), aspectContext, objectiveBuilder); |
508 | criteriaList.add(o); |
509 | criterionToAspect.put(o, aspectContext); |
510 | |
511 | UsageScenarioBasedSatisfactionConstraintBuilder builder = new UsageScenarioBasedSatisfactionConstraintBuilder(usageScenario); |
512 | |
513 | SatisfactionConstraint c = |
514 | reader.translateEvalAspectToSatisfactionConstraint(aspectContext, o, builder); |
515 | criteriaList.add(c); |
516 | criterionToAspect.put(c, aspectContext); |
517 | } |
518 | |
519 | } |
520 | |
521 | |
522 | } else { |
523 | //XXX: This should never be the case if the optimization is started with the LaunchConfig the aspect is checked there as well |
524 | throw new RuntimeException("Evaluation aspect not supported("+aspectContext.getEvaluationAspect()+")!"); |
525 | } |
526 | |
527 | } else { |
528 | throw new RuntimeException("Unsupported Requirement!"); |
529 | } |
530 | } |
531 | } |
532 | |
533 | private boolean canEvaluateAspect(EvaluationAspect aspect, Dimension dimension){ |
534 | return simuComQualityAttribute.canEvaluateAspectForDimension(aspect, dimension); |
535 | } |
536 | |
537 | //MOVED to PCMDeclarationsReader |
538 | // public UsageScenarioBasedObjective translateEvalAspectToObjective(EvaluationAspectWithContext aspect, UsageScenario usageScenario){ |
539 | // //Make sure, the aspect IS an objective |
540 | // try { |
541 | // if(aspect.getDimension().getType().getRelationSemantics().getRelSem() == EnumRelationSemantics.DECREASING) { |
542 | // return new UsageScenarioBasedObjective(this.getQualityAttribute(), Objective.Sign.MIN, usageScenario); |
543 | // } else { |
544 | // //INCREASING |
545 | // return new UsageScenarioBasedObjective(this.getQualityAttribute(), Objective.Sign.MAX, usageScenario); |
546 | // } |
547 | // } catch (CoreException e) { |
548 | // e.printStackTrace(); |
549 | // throw new RuntimeException("Could not get response time quality attribute!"); |
550 | // } |
551 | // } |
552 | |
553 | @Override |
554 | public IStatisticAnalysisResult retrieveResultsFor(PCMPhenotype pheno, Criterion criterion) throws CoreException, AnalysisFailedException { |
555 | if(criterion instanceof UsageScenarioBasedObjective){ |
556 | return this.retrieveSimuComResults(pheno, ((UsageScenarioBasedObjective)criterion).getUsageScenario()); |
557 | } else if (criterion instanceof UsageScenarioBasedInfeasibilityConstraint) { |
558 | //Handle constraint here |
559 | // As the mean is default (for the value as well as the evaluation aspect of the constraint), no further action is required |
560 | //We allowed only mean constraint during the initialization |
561 | |
562 | return this.retrieveSimuComResults(pheno, ((UsageScenarioBasedInfeasibilityConstraint)criterion).getUsageScenario()); |
563 | } else if (criterion instanceof UsageScenarioBasedSatisfactionConstraint) { |
564 | //Handle constraint here |
565 | // As the mean is default (for the value as well as the evaluation aspect of the constraint), no further action is required |
566 | //We allowed only mean constraint during the initialization |
567 | |
568 | return this.retrieveSimuComResults(pheno, ((UsageScenarioBasedSatisfactionConstraint)criterion).getUsageScenario()); |
569 | } |
570 | throw new CoreException(new Status(Status.ERROR, "de.uka.ipd.sdq.dsexplore.analysis.simucom", "Cannot handle Criterion of type "+criterion.getClass()+". Required is UsageScenarioBasedObjective or UsageScenarioBasedConstraint.")); |
571 | } |
572 | |
573 | |
574 | |
575 | @Override |
576 | public QualityAttribute getQualityAttribute() throws CoreException { |
577 | //return DSEConstantsContainer.MEAN_RESPONSE_TIME_QUALITY; |
578 | return simuComQualityAttribute.getQualityAttribute(); |
579 | } |
580 | |
581 | |
582 | |
583 | @Override |
584 | public boolean hasStatisticResults() throws CoreException { |
585 | return true; |
586 | } |
587 | |
588 | |
589 | |
590 | @Override |
591 | public List<Criterion> getCriterions() throws CoreException { |
592 | List<Criterion> list = new ArrayList<Criterion>(); |
593 | list.addAll(this.criteriaList); |
594 | return list; |
595 | } |
596 | |
597 | |
598 | |
599 | @Override |
600 | public boolean hasObjectivePerUsageScenario() throws CoreException { |
601 | return true; |
602 | } |
603 | |
604 | |
605 | |
606 | @Override |
607 | public void setBlackboard(MDSDBlackboard blackboard) { |
608 | this.blackboard = blackboard; |
609 | |
610 | } |
611 | |
612 | |
613 | |
614 | } |