diff options
Diffstat (limited to 'Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/DesignSpaceExplorer.java')
-rw-r--r-- | Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/DesignSpaceExplorer.java | 622 |
1 files changed, 622 insertions, 0 deletions
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/DesignSpaceExplorer.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/DesignSpaceExplorer.java new file mode 100644 index 00000000..9cd6e68a --- /dev/null +++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/api/DesignSpaceExplorer.java | |||
@@ -0,0 +1,622 @@ | |||
1 | /******************************************************************************* | ||
2 | * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro | ||
3 | * This program and the accompanying materials are made available under the | ||
4 | * terms of the Eclipse Public License v. 2.0 which is available at | ||
5 | * http://www.eclipse.org/legal/epl-v20.html. | ||
6 | * | ||
7 | * SPDX-License-Identifier: EPL-2.0 | ||
8 | *******************************************************************************/ | ||
9 | package org.eclipse.viatra.dse.api; | ||
10 | |||
11 | import java.util.Collection; | ||
12 | import java.util.HashSet; | ||
13 | import java.util.Set; | ||
14 | import java.util.Timer; | ||
15 | import java.util.TimerTask; | ||
16 | import java.util.concurrent.atomic.AtomicBoolean; | ||
17 | |||
18 | import org.apache.log4j.BasicConfigurator; | ||
19 | import org.apache.log4j.Level; | ||
20 | import org.apache.log4j.Logger; | ||
21 | import org.eclipse.emf.common.notify.Notifier; | ||
22 | import org.eclipse.emf.ecore.EObject; | ||
23 | import org.eclipse.emf.ecore.EPackage; | ||
24 | import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy; | ||
25 | import org.eclipse.viatra.dse.base.DesignSpaceManager; | ||
26 | import org.eclipse.viatra.dse.base.GlobalContext; | ||
27 | import org.eclipse.viatra.dse.designspace.api.DesignSpace; | ||
28 | import org.eclipse.viatra.dse.designspace.api.IDesignSpace; | ||
29 | import org.eclipse.viatra.dse.objectives.IGlobalConstraint; | ||
30 | import org.eclipse.viatra.dse.objectives.IObjective; | ||
31 | import org.eclipse.viatra.dse.solutionstore.ISolutionNameProvider; | ||
32 | import org.eclipse.viatra.dse.solutionstore.IdBasedSolutionNameProvider; | ||
33 | import org.eclipse.viatra.dse.solutionstore.SolutionStore; | ||
34 | import org.eclipse.viatra.dse.statecode.IStateCoder; | ||
35 | import org.eclipse.viatra.dse.statecode.IStateCoderFactory; | ||
36 | import org.eclipse.viatra.dse.statecoding.simple.SimpleStateCoderFactory; | ||
37 | import org.eclipse.viatra.dse.visualizer.IDesignSpaceVisualizer; | ||
38 | import org.eclipse.viatra.query.runtime.matchers.util.Preconditions; | ||
39 | import org.eclipse.viatra.transformation.evm.api.resolver.ConflictResolver; | ||
40 | import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule; | ||
41 | |||
42 | /** | ||
43 | * <p> | ||
44 | * The {@link DesignSpaceExplorer} is the main API of the <b>Design Space Exploration</b> engine. | ||
45 | * </p> | ||
46 | * | ||
47 | * <p> | ||
48 | * To parameterize the algorithm one must use the following methods after instantiating: | ||
49 | * <ul> | ||
50 | * <li>{@link #setInitialModel(EObject)} or it's overloads to set the starting model.</li> | ||
51 | * <li>{@link #addTransformationRule(BatchTransformationRule)} to define the transformations.</li> <li | ||
52 | * {@link #addObjective(IObjective)} to define the objective functions. Use the {@link Objectives} helper class for | ||
53 | * instantiating built-in, configurable objectives.</li> | ||
54 | * <li>{@link #startExploration(IStrategy)} or it's overloads to start an exploration with the given exploration | ||
55 | * strategy. Use the {@link Strategies} helper class for instantiating built-in, configurable exploration strategies. | ||
56 | * </li> | ||
57 | * </ul> | ||
58 | * </p> | ||
59 | * | ||
60 | * <p> | ||
61 | * <b>Designs Space Exploration</b> is the process of finding a sequence (or sequences) of predefined transformation | ||
62 | * rules ("transitions") that, if applied in order on the starting model, results in a new model state that fulfills the | ||
63 | * hard (or goal) constraints and is near optimal with respect to the objectives. | ||
64 | * </p> | ||
65 | * | ||
66 | * <p> | ||
67 | * An extension to this paradigm is the introduction of global constraints, which guarantees, that no sequence will be | ||
68 | * returned, which if executed, results in an intermediate model state that violates the specified global constraints, | ||
69 | * including the final state. You can add constraints by invoking {@link #addGlobalConstraint(IGlobalConstraint)}. | ||
70 | * </p> | ||
71 | * | ||
72 | * @author Andras Szabolcs Nagy & Miklos Foldenyi | ||
73 | * | ||
74 | */ | ||
75 | public class DesignSpaceExplorer { | ||
76 | |||
77 | private Notifier model; | ||
78 | |||
79 | private GlobalContext globalContext = new GlobalContext(); | ||
80 | |||
81 | private final Logger logger = Logger.getLogger(this.getClass()); | ||
82 | |||
83 | private Set<EPackage> metaModelPackages = new HashSet<EPackage>(); | ||
84 | |||
85 | private static final String MODEL_NOT_YET_GIVEN = "The starting model is not given yet. Please call the setInitialModel method first."; | ||
86 | |||
87 | private boolean deepCopyModel; | ||
88 | |||
89 | /** | ||
90 | * <p> | ||
91 | * Creates a {@link DesignSpaceExplorer} object that is able to execute a design space exploration process. | ||
92 | * </p> | ||
93 | * | ||
94 | * <p> | ||
95 | * By default the state coder used is the generic (not meta-model specific) {@link GraphHash}. You can provide your | ||
96 | * custom state coder by implementing the {@link IStateCoderFactory} and {@link IStateCoder} interfaces, and passing | ||
97 | * the former to the {@link #setStateCoderFactory(IStateCoderFactory)} method. | ||
98 | * | ||
99 | */ | ||
100 | public DesignSpaceExplorer() { | ||
101 | setDesignspace(new DesignSpace()); | ||
102 | } | ||
103 | |||
104 | /** | ||
105 | * Adds a metamodel in the form of {@link EPackage}, which is needed for certain guidance. | ||
106 | * | ||
107 | * @param metaModelPackage | ||
108 | */ | ||
109 | public void addMetaModelPackage(EPackage metaModelPackage) { | ||
110 | metaModelPackages.add(metaModelPackage); | ||
111 | } | ||
112 | |||
113 | /** | ||
114 | * Defines the initial model of the exploration, and whether it is supposed to be used to execute the DSE process or | ||
115 | * it should be cloned. Please note, that in multithreaded mode any subsequent threads will be working on cloned | ||
116 | * models. | ||
117 | * | ||
118 | * @param model | ||
119 | * The root object of the EMF model. | ||
120 | * @param deepCopyModel | ||
121 | * If it is set to true, the exploration will run on a cloned model. | ||
122 | */ | ||
123 | public void setInitialModel(Notifier model, boolean deepCopyModel) { | ||
124 | this.model = model; | ||
125 | this.deepCopyModel = deepCopyModel; | ||
126 | } | ||
127 | |||
128 | /** | ||
129 | * Defines the initial model of the exploration. The model will be cloned, which is desired in most cases as the | ||
130 | * given model won't be changed. | ||
131 | * | ||
132 | * @param model | ||
133 | * The root object of the EMF model. | ||
134 | */ | ||
135 | public void setInitialModel(Notifier model) { | ||
136 | setInitialModel(model, true); | ||
137 | } | ||
138 | |||
139 | /** | ||
140 | * Defines the initial model of the exploration. The given model won't be cloned, thus the exploration will modify | ||
141 | * it. | ||
142 | * | ||
143 | * @param model | ||
144 | * The root object of the EMF model. It won't be cloned. | ||
145 | */ | ||
146 | public void setInitialModelUncloned(Notifier model) { | ||
147 | setInitialModel(model, false); | ||
148 | } | ||
149 | |||
150 | /** | ||
151 | * Adds a {@link BatchTransformationRule}. | ||
152 | * | ||
153 | * @param rule | ||
154 | * The transformationRule. | ||
155 | */ | ||
156 | public void addTransformationRule(BatchTransformationRule<?, ?> rule) { | ||
157 | Preconditions.checkArgument(rule != null); | ||
158 | for (BatchTransformationRule<?, ?> rule2 : globalContext.getTransformations()) { | ||
159 | if (rule.getPrecondition().equals(rule2.getPrecondition())) { | ||
160 | throw new DSEException( | ||
161 | "Two transformation rule (" | ||
162 | + rule.getName() | ||
163 | + "; " | ||
164 | + rule2.getName() | ||
165 | + ") uses the same LHS VIATRA Query pattern (" | ||
166 | + rule.getPrecondition().getFullyQualifiedName() | ||
167 | + "), which may lead to hash collision." | ||
168 | + " Please wrap the pattern with an other pattern with the 'find' keyword (or duplicate the code), and use that for one of the rules LHS."); | ||
169 | } | ||
170 | } | ||
171 | |||
172 | globalContext.getTransformations().add(rule); | ||
173 | } | ||
174 | |||
175 | /** | ||
176 | * Adds a global constraint to the exploration process. Please see the {@link IGlobalConstraint} interface and its | ||
177 | * implementations for details. | ||
178 | * | ||
179 | * @param constraint | ||
180 | * The global constraint. | ||
181 | * @see IGlobalConstraint | ||
182 | */ | ||
183 | public void addGlobalConstraint(IGlobalConstraint constraint) { | ||
184 | globalContext.getGlobalConstraints().add(constraint); | ||
185 | } | ||
186 | |||
187 | /** | ||
188 | * Adds an objective the the exploration process. Please see the {@link IObjective} interface and its | ||
189 | * implementations for details. | ||
190 | * | ||
191 | * @param objective | ||
192 | * The objective. | ||
193 | * @see IObjective | ||
194 | */ | ||
195 | public void addObjective(IObjective objective) { | ||
196 | for (IObjective o : globalContext.getObjectives()) { | ||
197 | if (o.getName().equals(objective.getName())) { | ||
198 | throw new DSEException("Two objectives with the same name cannot be registered:" + o.getName()); | ||
199 | } | ||
200 | } | ||
201 | globalContext.getObjectives().add(objective); | ||
202 | } | ||
203 | |||
204 | /** | ||
205 | * Sets a {@link IStateCoderFactory} for which will be used for creating {@link IStateCoder}s. The default | ||
206 | * implementation is the {@link SimpleStateCoderFactory}, which works well in most of the cases. | ||
207 | * | ||
208 | * @param stateCoderFactory | ||
209 | * The factory. | ||
210 | */ | ||
211 | public final void setStateCoderFactory(IStateCoderFactory stateCoderFactory) { | ||
212 | globalContext.setStateCoderFactory(stateCoderFactory); | ||
213 | } | ||
214 | |||
215 | /** | ||
216 | * Defines the maximum processing threads that the design space exploration can use. Note, that this is only | ||
217 | * limiting the threads doing the actual calculation. By default this value will be set to the number of logical | ||
218 | * processors (including HyperThreading) in the computer, reported by {@link Runtime#availableProcessors()}. | ||
219 | * | ||
220 | * @param maxNumberOfThreads | ||
221 | * The number of maximum processing threads available to the design space exploration process. | ||
222 | */ | ||
223 | public void setMaxNumberOfThreads(int maxNumberOfThreads) { | ||
224 | globalContext.getThreadPool().setMaximumPoolSize(maxNumberOfThreads); | ||
225 | } | ||
226 | |||
227 | /** | ||
228 | * Sets the {@link IDesignSpace} implementation that is to be used during the design space exploration process. By | ||
229 | * default, the {@link DesignSpace} implementation is used. | ||
230 | * | ||
231 | * @param designspace | ||
232 | * The {@link IDesignSpace} implementation. | ||
233 | */ | ||
234 | public final void setDesignspace(IDesignSpace designspace) { | ||
235 | globalContext.setDesignSpace(designspace); | ||
236 | } | ||
237 | |||
238 | /** | ||
239 | * Sets the solution store for strategies. Please see the {@link SolutionStore} for how to configure it. | ||
240 | * | ||
241 | * @param solutionStore | ||
242 | * The parameterized {@link SolutionStore} implementation. | ||
243 | */ | ||
244 | public void setSolutionStore(SolutionStore solutionStore) { | ||
245 | globalContext.setSolutionStore(solutionStore); | ||
246 | } | ||
247 | |||
248 | /** | ||
249 | * Starts the design space exploration. It returns only when the strategy decides to stop the execution. | ||
250 | * | ||
251 | * @param strategy | ||
252 | * The strategy of the exploration. | ||
253 | */ | ||
254 | public void startExploration(IStrategy strategy) { | ||
255 | startExploration(strategy, true, -1); | ||
256 | } | ||
257 | |||
258 | /** | ||
259 | * Starts the design space exploration asynchronously. Completion of the process can be verified by calling | ||
260 | * {@link DesignSpaceExplorer#isDone()}. | ||
261 | * | ||
262 | * @param strategy | ||
263 | * The strategy of the exploration. | ||
264 | */ | ||
265 | public void startExplorationAsync(IStrategy strategy) { | ||
266 | startExploration(strategy, false, -1); | ||
267 | } | ||
268 | |||
269 | /** | ||
270 | * Starts the design space exploration with a timeout. It returns only when the strategy decides to stop the | ||
271 | * execution or the given timeout is elapsed. | ||
272 | * | ||
273 | * @param strategy | ||
274 | * The strategy of the exploration. | ||
275 | * @param timeout | ||
276 | * The number of milliseconds before the exploration is forced to stop. | ||
277 | * @return Returns true if the exploration stopped by the timeout. | ||
278 | */ | ||
279 | public boolean startExplorationWithTimeout(IStrategy strategy, long timeout) { | ||
280 | return startExploration(strategy, true, timeout); | ||
281 | } | ||
282 | |||
283 | /** | ||
284 | * Starts the design space exploration asynchronously with a timeout. Completion of the process can be verified by | ||
285 | * calling {@link DesignSpaceExplorer#isDone()}. | ||
286 | * | ||
287 | * @param strategy | ||
288 | * The strategy of the exploration. | ||
289 | * @param timeout | ||
290 | * The number of milliseconds before the exploration is forced to stop. | ||
291 | * @return Returns true if the exploration stopped by the timeout. | ||
292 | */ | ||
293 | public boolean startExplorationAsyncWithTimeout(IStrategy strategy, long timeout) { | ||
294 | return startExploration(strategy, false, timeout); | ||
295 | } | ||
296 | |||
297 | /** | ||
298 | * Starts the design space exploration. If {@code waitForTermination} is true, then it returns only when the | ||
299 | * strategy decides to stop the execution or there was a timeout, otherwise when the exploration process is started | ||
300 | * it returns immediately. In this case, process completion can be verified by calling | ||
301 | * {@link DesignSpaceExplorer#isDone()}. | ||
302 | * | ||
303 | * @param strategy | ||
304 | * The strategy of the exploration. | ||
305 | * @param waitForTermination | ||
306 | * True if the method must wait for the engine to stop, i.e. whether to start synchronously. | ||
307 | * @param timeout | ||
308 | * The number of milliseconds before the exploration is forced to stop. | ||
309 | * @return Returns true if the exploration stopped by the timeout. | ||
310 | */ | ||
311 | public boolean startExploration(IStrategy strategy, boolean waitForTermination, final long timeout) { | ||
312 | initExploration(strategy); | ||
313 | |||
314 | Timer timer = new Timer(); | ||
315 | final AtomicBoolean wasTimeout = new AtomicBoolean(false); | ||
316 | |||
317 | if (timeout > 0) { | ||
318 | TimerTask timerTask = new TimerTask() { | ||
319 | @Override | ||
320 | public void run() { | ||
321 | logger.info("Timeout, stopping threads..."); | ||
322 | globalContext.stopAllThreads(); | ||
323 | wasTimeout.set(true); | ||
324 | } | ||
325 | }; | ||
326 | timer.schedule(timerTask, timeout); | ||
327 | } | ||
328 | |||
329 | if (waitForTermination) { | ||
330 | waitForTerminaition(); | ||
331 | timer.cancel(); | ||
332 | } else { | ||
333 | logger.info("Design space exploration started asynchronously."); | ||
334 | } | ||
335 | |||
336 | return wasTimeout.get(); | ||
337 | |||
338 | } | ||
339 | |||
340 | private void initExploration(IStrategy strategy) { | ||
341 | Preconditions.checkArgument(model != null, MODEL_NOT_YET_GIVEN); | ||
342 | Preconditions.checkArgument(strategy != null, "A strategy must be given. Use the Strategies helper class."); | ||
343 | Preconditions.checkState(!globalContext.getTransformations().isEmpty(), | ||
344 | "At least one transformation rule must be added to start the exploration."); | ||
345 | |||
346 | if (globalContext.getStateCoderFactory() == null) { | ||
347 | if (getMetaModelPackages() == null || getMetaModelPackages().isEmpty()) { | ||
348 | throw new DSEException("Cannot initialize state coder." | ||
349 | + " Please specifiy the EPackages your model uses with addMetaModelPackage(EPackage)"); | ||
350 | } | ||
351 | globalContext.setStateCoderFactory(new SimpleStateCoderFactory(getMetaModelPackages())); | ||
352 | } | ||
353 | |||
354 | logger.info("DesignSpaceExplorer started exploration."); | ||
355 | |||
356 | if (deepCopyModel) { | ||
357 | globalContext.startFirstThread(strategy, model); | ||
358 | } else { | ||
359 | globalContext.startFirstThreadWithoutModelClone(strategy, model); | ||
360 | } | ||
361 | } | ||
362 | |||
363 | /** | ||
364 | * Returns all of the found {@link Solution}s, trajectories. Call it after | ||
365 | * {@link DesignSpaceExplorer#startExploration()}. Calling this while the process is running returns the solutions | ||
366 | * that have been found <b>so far</b>. The returned {@link Solution} objects may change internal state after they | ||
367 | * have been returned, if a shorter trajectory has been found to the referred state. | ||
368 | * | ||
369 | * @return The found solutions. | ||
370 | */ | ||
371 | public Collection<Solution> getSolutions() { | ||
372 | return globalContext.getSolutionStore().getSolutions(); | ||
373 | } | ||
374 | |||
375 | /** | ||
376 | * Returns an arbitrary solution trajectory or null if the exploration failed to find any. | ||
377 | * | ||
378 | * @return An arbitrary solution trajectory. | ||
379 | */ | ||
380 | public SolutionTrajectory getArbitrarySolution() { | ||
381 | Collection<Solution> solutions = getSolutions(); | ||
382 | if (solutions.isEmpty()) { | ||
383 | return null; | ||
384 | } | ||
385 | return solutions.iterator().next().getArbitraryTrajectory(); | ||
386 | } | ||
387 | |||
388 | /** | ||
389 | * Returns the number of distinct states the exploration process has visited so far. | ||
390 | * | ||
391 | * @return the number of distinct states. | ||
392 | */ | ||
393 | public long getNumberOfStates() { | ||
394 | return globalContext.getDesignSpace().getNumberOfStates(); | ||
395 | } | ||
396 | |||
397 | /** | ||
398 | * Returns the number of distinct transitions the exploration process has discovered (but not necessarily traversed) | ||
399 | * so far. | ||
400 | * | ||
401 | * @return the number of distinct transitions. | ||
402 | */ | ||
403 | public long getNumberOfTransitions() { | ||
404 | return globalContext.getDesignSpace().getNumberOfTransitions(); | ||
405 | } | ||
406 | |||
407 | /** | ||
408 | * Returns the {@link EPackage}s, which were registered with the | ||
409 | * {@link DesignSpaceExplorer#addMetaModelPackage(EPackage)} method. | ||
410 | * | ||
411 | * @return The set of meta model packages. | ||
412 | */ | ||
413 | public Set<EPackage> getMetaModelPackages() { | ||
414 | return metaModelPackages; | ||
415 | } | ||
416 | |||
417 | /** | ||
418 | * Returns true if the {@link IExplorerThread strategy} decided to stop, and all the threads finished their work. | ||
419 | * | ||
420 | * @return true if the process has finished, false otherwise. | ||
421 | */ | ||
422 | public boolean isDone() { | ||
423 | return globalContext.isDone(); | ||
424 | } | ||
425 | |||
426 | /** | ||
427 | * Returns the {@link GlobalContext} which holds the configurations such as rule, objectives, etc. | ||
428 | * | ||
429 | * @return The global context. | ||
430 | */ | ||
431 | public GlobalContext getGlobalContext() { | ||
432 | return globalContext; | ||
433 | } | ||
434 | |||
435 | /** | ||
436 | * Registers a design space visualizer. Please see the corresponding interface {@link IDesignSpaceVisualizer}. | ||
437 | * | ||
438 | * @see IDesignSpaceVisualizer | ||
439 | * | ||
440 | * @param visualizer | ||
441 | */ | ||
442 | public void addDesignSpaceVisulaizer(IDesignSpaceVisualizer visualizer) { | ||
443 | globalContext.registerDesignSpaceVisualizer(visualizer); | ||
444 | } | ||
445 | |||
446 | /** | ||
447 | * Creates a string containing the state codes of all the found solutions and the found trajectories to these | ||
448 | * solutions with fitness values. | ||
449 | * | ||
450 | * @return A pretty string with the solutions. | ||
451 | */ | ||
452 | public String toStringSolutions() { | ||
453 | StringBuilder sb = new StringBuilder(); | ||
454 | Collection<Solution> solutions = getSolutions(); | ||
455 | sb.append("Number of solutions: "); | ||
456 | sb.append(solutions.size()); | ||
457 | sb.append("\n"); | ||
458 | for (Solution solution : solutions) { | ||
459 | sb.append("Solution: "); | ||
460 | sb.append(solution.getStateCode()); | ||
461 | sb.append("\n"); | ||
462 | for (SolutionTrajectory trajectory : solution.getTrajectories()) { | ||
463 | sb.append(" "); | ||
464 | sb.append(trajectory.toPrettyString()); | ||
465 | sb.append("\n"); | ||
466 | } | ||
467 | } | ||
468 | return sb.toString(); | ||
469 | } | ||
470 | |||
471 | /** | ||
472 | * A conflict resolver can filter rule activations the DSE engine will see. The primary use of this is symmetry | ||
473 | * reduction. This function is subject to change for better API. | ||
474 | * | ||
475 | * @param conflictResolver | ||
476 | */ | ||
477 | public void setConflictResolver(ConflictResolver conflictResolver) { | ||
478 | globalContext.setConflictResolver(conflictResolver); | ||
479 | } | ||
480 | |||
481 | /** | ||
482 | * Enumeration for different use cases of logging, including: | ||
483 | * <ul> | ||
484 | * <li>OFF - no error messages.</li> | ||
485 | * <li>WARN - only error and warn messages.</li> | ||
486 | * <li>BASIC - logs basic information on how the exploration is going.</li> | ||
487 | * <li>VERBOSE_STRATEGY - logs everything the exploration strategy is prepared for.</li> | ||
488 | * <li>VERBOSE_FULL - logs every transformation.</li> | ||
489 | * </ul> | ||
490 | * | ||
491 | * @author Andras Szabolcs Nagy | ||
492 | * | ||
493 | */ | ||
494 | public enum DseLoggingLevel { | ||
495 | OFF, WARN, BASIC, VERBOSE_STRATEGY, VERBOSE_FULL | ||
496 | } | ||
497 | |||
498 | /** | ||
499 | * Changes the level of logging. See {@link DseLoggingLevel} for details. | ||
500 | * | ||
501 | * @param dseLoggingLevel | ||
502 | */ | ||
503 | public static void turnOnLogging(DseLoggingLevel dseLoggingLevel) { | ||
504 | switch (dseLoggingLevel) { | ||
505 | case OFF: | ||
506 | Logger.getLogger(DesignSpaceExplorer.class).setLevel(Level.OFF); | ||
507 | Logger.getLogger(IStrategy.class).setLevel(Level.OFF); | ||
508 | Logger.getLogger(DesignSpaceManager.class).setLevel(Level.OFF); | ||
509 | break; | ||
510 | case WARN: | ||
511 | Logger.getLogger(DesignSpaceExplorer.class).setLevel(Level.WARN); | ||
512 | Logger.getLogger(IStrategy.class).setLevel(Level.WARN); | ||
513 | Logger.getLogger(DesignSpaceManager.class).setLevel(Level.WARN); | ||
514 | break; | ||
515 | case BASIC: | ||
516 | Logger.getLogger(DesignSpaceExplorer.class).setLevel(Level.INFO); | ||
517 | Logger.getLogger(IStrategy.class).setLevel(Level.INFO); | ||
518 | Logger.getLogger(DesignSpaceManager.class).setLevel(Level.WARN); | ||
519 | break; | ||
520 | case VERBOSE_STRATEGY: | ||
521 | Logger.getLogger(DesignSpaceExplorer.class).setLevel(Level.DEBUG); | ||
522 | Logger.getLogger(IStrategy.class).setLevel(Level.DEBUG); | ||
523 | Logger.getLogger(DesignSpaceManager.class).setLevel(Level.WARN); | ||
524 | break; | ||
525 | case VERBOSE_FULL: | ||
526 | Logger.getLogger(DesignSpaceExplorer.class).setLevel(Level.DEBUG); | ||
527 | Logger.getLogger(IStrategy.class).setLevel(Level.DEBUG); | ||
528 | Logger.getLogger(DesignSpaceManager.class).setLevel(Level.DEBUG); | ||
529 | break; | ||
530 | default: | ||
531 | throw new DSEException("Not supported logging level."); | ||
532 | } | ||
533 | } | ||
534 | |||
535 | /** | ||
536 | * Changes the level of logging. See {@link DseLoggingLevel} for details. | ||
537 | * | ||
538 | * Also configures a basic console appender for log4j. | ||
539 | * | ||
540 | * @param dseLoggingLevel | ||
541 | */ | ||
542 | public static void turnOnLoggingWithBasicConfig(DseLoggingLevel dseLoggingLevel) { | ||
543 | BasicConfigurator.configure(); | ||
544 | Logger.getRootLogger().setLevel(Level.WARN); | ||
545 | turnOnLogging(dseLoggingLevel); | ||
546 | } | ||
547 | |||
548 | /** | ||
549 | * Stops the exploration and waits for termination. It has no effect if the exploration is already terminated or not | ||
550 | * even started. | ||
551 | */ | ||
552 | public void stopExploration() { | ||
553 | if (globalContext.isDone()) { | ||
554 | logger.info("Cannot stop exploration - design space exploration has already finished."); | ||
555 | } else if (globalContext.isNotStarted()) { | ||
556 | logger.info("Cannot stop exploration - design space exploration has not been started."); | ||
557 | } else { | ||
558 | globalContext.stopAllThreads(); | ||
559 | waitForTerminaition(); | ||
560 | } | ||
561 | } | ||
562 | |||
563 | /** | ||
564 | * Stops the exploration asynchronously. It has no effect if the exploration is already terminated or not even | ||
565 | * started. | ||
566 | */ | ||
567 | public void stopExplorationAsync() { | ||
568 | if (globalContext.isDone()) { | ||
569 | logger.info("Cannot stop exploration - design space exploration has already finished."); | ||
570 | } else if (globalContext.isNotStarted()) { | ||
571 | logger.info("Cannot stop exploration - design space exploration has not been started."); | ||
572 | } else { | ||
573 | globalContext.stopAllThreads(); | ||
574 | } | ||
575 | } | ||
576 | |||
577 | /** | ||
578 | * Waits for termination. | ||
579 | */ | ||
580 | public void waitForTerminaition() { | ||
581 | globalContext.waitForTermination(); | ||
582 | } | ||
583 | |||
584 | /** | ||
585 | * Serializes all the found solutions by transforming the given initial model. | ||
586 | * </p>Files will be named <code>solution[id].xmi</code>. | ||
587 | * @param model The initial model. | ||
588 | */ | ||
589 | public void saveModels(Notifier model) { | ||
590 | this.saveModels(model, "solution", "xmi"); | ||
591 | } | ||
592 | |||
593 | /** | ||
594 | * Serializes all the found solutions by transforming the given initial model. | ||
595 | * </p>Files will be named <code>solution[id].[extension]</code>. | ||
596 | * @param model The initial model. | ||
597 | * @param extension The extension of the omitted file. | ||
598 | */ | ||
599 | public void saveModels(Notifier model, String extension) { | ||
600 | this.saveModels(model, "solution", extension); | ||
601 | } | ||
602 | |||
603 | /** | ||
604 | * Serializes all the found solutions by transforming the given initial model. | ||
605 | * </p>Files will be named <code>[fileNamePrefix][id].[extension]</code>. | ||
606 | * @param model The initial model. | ||
607 | * @param fileNamePrefix The prefix (optionally including a file path) of the omitted file. | ||
608 | * @param extension The extension of the omitted file. | ||
609 | */ | ||
610 | public void saveModels(Notifier model, String fileNamePrefix, String extension) { | ||
611 | globalContext.getSolutionStore().saveModels(model, new IdBasedSolutionNameProvider(fileNamePrefix, extension)); | ||
612 | } | ||
613 | |||
614 | /** | ||
615 | * Serializes all the found solutions by transforming the given initial model. | ||
616 | * </p>Files will be named using the {@link ISolutionNameProvider}. | ||
617 | * @param model The initial model. | ||
618 | */ | ||
619 | public void saveModels(Notifier model, ISolutionNameProvider solutionNameProvider) { | ||
620 | globalContext.getSolutionStore().saveModels(model, solutionNameProvider); | ||
621 | } | ||
622 | } | ||