From e11bce7ad3e803e80883499fec0ad6e4540ffe43 Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Tue, 30 Jun 2020 18:03:48 +0200 Subject: Add modified VIATRA-DSE version --- .../org/eclipse/viatra/dse/base/ThreadContext.java | 542 +++++++++++++++++++++ 1 file changed, 542 insertions(+) create mode 100644 Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/ThreadContext.java (limited to 'Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/ThreadContext.java') diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/ThreadContext.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/ThreadContext.java new file mode 100644 index 00000000..b62442ce --- /dev/null +++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/base/ThreadContext.java @@ -0,0 +1,542 @@ +/******************************************************************************* + * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-v20.html. + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.viatra.dse.base; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.apache.log4j.Logger; +import org.eclipse.emf.common.notify.Notifier; +import org.eclipse.emf.edit.domain.EditingDomain; +import org.eclipse.viatra.dse.api.DSEException; +import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy; +import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategyFactory; +import org.eclipse.viatra.dse.designspace.api.IDesignSpace; +import org.eclipse.viatra.dse.designspace.api.TrajectoryInfo; +import org.eclipse.viatra.dse.objectives.Fitness; +import org.eclipse.viatra.dse.objectives.IGlobalConstraint; +import org.eclipse.viatra.dse.objectives.IObjective; +import org.eclipse.viatra.dse.objectives.ObjectiveComparatorHelper; +import org.eclipse.viatra.dse.solutionstore.SolutionStore; +import org.eclipse.viatra.dse.statecode.IStateCoder; +import org.eclipse.viatra.dse.util.EMFHelper; +import org.eclipse.viatra.query.runtime.api.IPatternMatch; +import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; +import org.eclipse.viatra.query.runtime.emf.EMFScope; +import org.eclipse.viatra.query.runtime.exception.ViatraQueryException; +import org.eclipse.viatra.query.runtime.matchers.util.Preconditions; +import org.eclipse.viatra.transformation.evm.api.Activation; +import org.eclipse.viatra.transformation.evm.api.RuleEngine; +import org.eclipse.viatra.transformation.evm.api.RuleSpecification; +import org.eclipse.viatra.transformation.evm.api.event.EventFilter; +import org.eclipse.viatra.transformation.evm.api.resolver.ChangeableConflictSet; +import org.eclipse.viatra.transformation.evm.api.resolver.ConflictResolver; +import org.eclipse.viatra.transformation.evm.api.resolver.ConflictSet; +import org.eclipse.viatra.transformation.evm.specific.RuleEngines; +import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule; + +/** + * This class holds all the information that is related to a single processing thread of the DesignSpaceExploration + * process. For any attributes related to the Design Space Exploration process as a whole, see {@link GlobalContext}. + * + * @author Miklos Foldenyi + * + */ +public class ThreadContext implements IDseStrategyContext{ + + private final GlobalContext globalContext; + private final IStrategy strategy; + private ExplorerThread explorerThread; + private RuleEngine ruleEngine; + private ViatraQueryEngine queryEngine; + private EditingDomain domain; + private Notifier model; + private DesignSpaceManager designSpaceManager; + private List objectives; + private List globalConstraints; + private Fitness lastFitness; + private ObjectiveComparatorHelper objectiveComparatorHelper; + private IStateCoder stateCoder; + private DseConflictResolver dseConflictResolver; + private DseConflictSet dseConflictSet; + private ActivationCodesConflictSet activationCodesConflictSet; + + /** + * This value is true after the {@link ThreadContext} has been initialized in it's own thread. + */ + private AtomicBoolean inited = new AtomicBoolean(false); + + private boolean isFirstThread = false; + private IObjective[][] leveledObjectives; + + private static class GetRuleExecutionsImpl implements DseIdPoolHelper.IGetRuleExecutions { + + private List> executedRules; + + public GetRuleExecutionsImpl(List> executedRulesView) { + this.executedRules = executedRulesView; + } + + @Override + public int getRuleExecutions(BatchTransformationRule rule) { + int nextId = 0; + for (BatchTransformationRule r : executedRules) { + if (r.equals(rule)) { + nextId ++; + } + } + return nextId; + } + + } + + public DseConflictResolver getConflictResolver() { + return dseConflictResolver; + } + + public ConflictSet getConflictSet() { + return dseConflictSet; + } + + /** + * Creates a {@link ThreadContext} and sets it up to be initialized on the given {@link TransactionalEditingDomain} + * + * @param globalContext + * @param strategyBase + * @param domain + * @param trajectoryInfoToClone + * @param parentGuidance + */ + public ThreadContext(final GlobalContext globalContext, IStrategy strategy, Notifier model) { + Preconditions.checkArgument(model != null, "Cannot initialize ThreadContext on a null model."); + this.globalContext = globalContext; + this.strategy = strategy; + this.model = model; + } + + /** + * Initializes the {@link ThreadContext} by initializing the underlying {@link ViatraQueryEngine} and + * {@link RuleEngine}. {@link Guidance} initialization is also happening within this method. + * + * @throws DSEException + */ + public void init() { + + AtomicBoolean isFirst = globalContext.getFirstThreadContextIniting(); + AtomicBoolean isFirstReady = globalContext.getFirstThreadContextInited(); + if (!isFirstReady.get()) { + if (!isFirst.compareAndSet(false, true)) { + try { + do { + Thread.sleep(5); + } while (!isFirstReady.get()); + } catch (InterruptedException e) { + } + } else { + isFirstThread = true; + } + } + // prohibit re-initialization + Preconditions.checkArgument(!inited.getAndSet(true), "This Thread context has been initialized already!"); + + try { + // initialize query engine + final EMFScope scope = new EMFScope(model); + queryEngine = ViatraQueryEngine.on(scope); + + + stateCoder = getGlobalContext().getStateCoderFactory().createStateCoder(); + stateCoder.init(model); + stateCoder.createStateCode(); + + ConflictResolver activationOrderingCconflictResolver = globalContext.getConflictResolver(); + dseConflictResolver = new DseConflictResolver(activationOrderingCconflictResolver, stateCoder); + + ruleEngine = RuleEngines.createViatraQueryRuleEngine(queryEngine); + ruleEngine.setConflictResolver(dseConflictResolver); + for (BatchTransformationRule tr : globalContext.getTransformations()) { + ruleEngine.addRule(tr.getRuleSpecification(), (EventFilter) tr.getFilter()); + } + dseConflictSet = dseConflictResolver.getLastCreatedConflictSet(); + activationCodesConflictSet = dseConflictSet.getActivationCodesConflictSet(); + activationCodesConflictSet.updateActivationCodes(); + + + } catch (ViatraQueryException e) { + throw new DSEException("Failed to create unmanaged ViatraQueryEngine on the model.", e); + } + + if (isFirstThread) { + + objectives = globalContext.getObjectives(); + leveledObjectives = globalContext.getLeveledObjectives(); + globalConstraints = globalContext.getGlobalConstraints(); + + } else { + objectives = new ArrayList(); + + IObjective[][] leveledObjectivesToCopy = globalContext.getLeveledObjectives(); + leveledObjectives = new IObjective[leveledObjectivesToCopy.length][]; + for (int i = 0; i < leveledObjectivesToCopy.length; i++) { + leveledObjectives[i] = new IObjective[leveledObjectivesToCopy[i].length]; + for (int j = 0; j < leveledObjectivesToCopy[i].length; j++) { + leveledObjectives[i][j] = leveledObjectivesToCopy[i][j].createNew(); + objectives.add(leveledObjectives[i][j]); + } + } + + globalConstraints = new ArrayList(); + for (IGlobalConstraint globalConstraint : globalContext.getGlobalConstraints()) { + globalConstraints.add(globalConstraint.createNew()); + } + + } + // create the thread specific DesignSpaceManager + this.domain = EMFHelper.createEditingDomain(model); + designSpaceManager = new DesignSpaceManager(this); + + boolean isThereHardObjective = false; + for (IObjective objective : objectives) { + objective.init(this); + if (objective.isHardObjective()) { + isThereHardObjective = true; + } + } + if (!isThereHardObjective) { + Logger.getLogger(IStrategy.class).warn( + "No hard objective is specified: all reachable state is a solution. Use a dummy hard objective to be explicit."); + } + + for (IGlobalConstraint globalConstraint : globalConstraints) { + globalConstraint.init(this); + } + + DseIdPoolHelper.INSTANCE.registerRules(new GetRuleExecutionsImpl(getDesignSpaceManager().getTrajectoryInfo().getRules()), getRules()); + + globalContext.initVisualizersForThread(this); + + if (isFirstThread) { + isFirstReady.set(true); + } + + } + + public Fitness calculateFitness() { + Fitness result = new Fitness(); + + boolean satisifiesHardObjectives = true; + + for (IObjective objective : objectives) { + Double fitness = objective.getFitness(this); + result.put(objective.getName(), fitness); + if (objective.isHardObjective() && !objective.satisifiesHardObjective(fitness)) { + satisifiesHardObjectives = false; + } + } + + result.setSatisifiesHardObjectives(satisifiesHardObjectives); + + lastFitness = result; + + return result; + } + + public boolean checkGlobalConstraints() { + for (IGlobalConstraint globalConstraint : globalContext.getGlobalConstraints()) { + if (!globalConstraint.checkGlobalConstraint(this)) { + return false; + } + } + return true; + } + + public RuleEngine getRuleEngine() { + return ruleEngine; + } + + public GlobalContext getGlobalContext() { + return globalContext; + } + + public DesignSpaceManager getDesignSpaceManager() { + return designSpaceManager; + } + + public EditingDomain getEditingDomain() { + return domain; + } + + public Notifier getModel() { + return model; + } + + public ViatraQueryEngine getQueryEngine() { + return queryEngine; + } + + public IStrategy getStrategy() { + return strategy; + } + + public ExplorerThread getExplorerThread() { + return explorerThread; + } + + public void setExplorerThread(ExplorerThread explorerThread) { + this.explorerThread = explorerThread; + } + + public Fitness getLastFitness() { + return lastFitness; + } + + public ObjectiveComparatorHelper getObjectiveComparatorHelper() { + if (objectiveComparatorHelper == null) { + objectiveComparatorHelper = new ObjectiveComparatorHelper(leveledObjectives); + } + return objectiveComparatorHelper; + } + + public IObjective[][] getLeveledObjectives() { + return leveledObjectives; + } + + public List getObjectives() { + return objectives; + } + + public List getGlobalConstraints() { + return globalConstraints; + } + + @Override + public SolutionStore getSolutionStore() { + return globalContext.getSolutionStore(); + } + + @Override + public void newSolution() { + globalContext.getSolutionStore().newSolution(this); + } + + @Override + public Object getSharedObject() { + return globalContext.getSharedObject(); + } + + @Override + public void setSharedObject(Object sharedObject) { + globalContext.setSharedObject(sharedObject); + } + + @Override + public Set> getRules() { + return globalContext.getTransformations(); + } + + @Override + public BatchTransformationRule getRuleByRuleSpecification(RuleSpecification ruleSpecification) { + return globalContext.getSpecificationRuleMap().get(ruleSpecification); + } + + @Override + public ExplorerThread tryStartNewThread(IStrategy strategy) { + return globalContext.tryStartNewThread(this, strategy); + } + + @Override + public ExplorerThread tryStartNewThreadWithoutModelClone(IStrategy strategy) { + return globalContext.tryStartNewThreadWithoutModelClone(this, strategy); + } + + @Override + public void startAllThreads(IStrategyFactory strategyFactory) { + globalContext.startAllThreads(this, strategyFactory); + } + + @Override + public IStateCoder getStateCoder() { + return stateCoder; + } + + @Override + public IDesignSpace getDesignSpace() { + return globalContext.getDesignSpace(); + } + + @Override + public TrajectoryInfo getTrajectoryInfo() { + return designSpaceManager.getTrajectoryInfo(); + } + + @Override + public List getTrajectory() { + return designSpaceManager.getTrajectoryInfo().getTrajectory(); + } + + @Override + public List getTrajectoryCopied() { + return new ArrayList(getTrajectory()); + } + + @Override + public int getDepth() { + return designSpaceManager.getTrajectoryInfo().getDepth(); + } + + @Override + public Object getCurrentStateId() { + return designSpaceManager.getTrajectoryInfo().getCurrentStateId(); + } + + @Override + public Object getTransitionByActivation(Activation activation) { + return designSpaceManager.getTransitionByActivation(activation); + } + + @Override + public Activation getActivationById(Object activationId) { + return designSpaceManager.getActivationById(activationId); + } + + @Override + public BatchTransformationRule getRuleByActivation(Activation activation) { + return designSpaceManager.getRuleByActivation(activation); + } + + @Override + public BatchTransformationRule getRuleByActivationId(Object activationId) { + return designSpaceManager.getRuleByActivationId(activationId); + } + + @Override + public Collection getCurrentActivationIds() { + return designSpaceManager.getTransitionsFromCurrentState(); + } + + @Override + public Collection getUntraversedActivationIds() { + return designSpaceManager.getUntraversedTransitionsFromCurrentState(); + } + + @Override + public void executeAcitvationId(Object activationId) { + designSpaceManager.fireActivation(activationId); + } + + @Override + public boolean tryExecuteAcitvationId(Object activationId) { + return designSpaceManager.tryFireActivation(activationId); + } + + @Override + public boolean executeRandomActivationId() { + return designSpaceManager.executeRandomActivationId(); + } + + @Override + public void executeTrajectory(Object[] activationIds) { + designSpaceManager.executeTrajectory(activationIds); + } + + @Override + public void executeTrajectory(Object[] activationIds, int fromIncludedIndex, int toExcludedIndex) { + designSpaceManager.executeTrajectory(activationIds, fromIncludedIndex, toExcludedIndex); + } + + @Override + public int executeTrajectoryByTrying(Object[] activationIds) { + return designSpaceManager.executeTrajectoryByTrying(activationIds); + } + + @Override + public int executeTrajectoryByTrying(Object[] activationIds, int fromIncludedIndex, int toExcludedIndex) { + return designSpaceManager.executeTrajectoryByTrying(activationIds, fromIncludedIndex, toExcludedIndex); + } + + @Override + public int executeTrajectoryWithoutStateCoding(Object[] activationIds) { + return designSpaceManager.executeTrajectoryWithoutStateCoding(activationIds); + } + + @Override + public int executeTrajectoryWithoutStateCoding(Object[] activationIds, int fromIncludedIndex, int toExcludedIndex) { + return designSpaceManager.executeTrajectoryWithoutStateCoding(activationIds, fromIncludedIndex, toExcludedIndex); + } + + @Override + public int executeTrajectoryByTryingWithoutStateCoding(Object[] activationIds) { + return designSpaceManager.executeTrajectoryByTryingWithoutStateCoding(activationIds); + } + + @Override + public int executeTrajectoryByTryingWithoutStateCoding(Object[] activationIds, int fromIncludedIndex, int toExcludedIndex) { + return designSpaceManager.executeTrajectoryByTryingWithoutStateCoding(activationIds, fromIncludedIndex, toExcludedIndex); + } + + @Override + public void executeTrajectoryWithMinimalBacktrack(Object[] trajectory) { + designSpaceManager.executeTrajectoryWithMinimalBacktrack(trajectory); + } + + @Override + public void executeTrajectoryWithMinimalBacktrack(Object[] trajectory, int toExcludedIndex) { + designSpaceManager.executeTrajectoryWithMinimalBacktrack(trajectory, toExcludedIndex); + } + + @Override + public void executeTrajectoryWithMinimalBacktrackWithoutStateCoding(Object[] trajectory) { + designSpaceManager.executeTrajectoryWithMinimalBacktrackWithoutStateCoding(trajectory); + } + + @Override + public void executeTrajectoryWithMinimalBacktrackWithoutStateCoding(Object[] trajectory, int toExcludedIndex) { + designSpaceManager.executeTrajectoryWithMinimalBacktrackWithoutStateCoding(trajectory, toExcludedIndex); + } + + @Override + public boolean backtrack() { + return designSpaceManager.undoLastTransformation(); + } + + @Override + public void backtrackUntilLastCommonActivation(Object[] trajectory) { + designSpaceManager.backtrackUntilLastCommonActivation(trajectory); + } + + @Override + public void backtrackUntilRoot() { + designSpaceManager.undoUntilRoot(); + } + + @Override + public boolean isCurrentStateAlreadyTraversed() { + return designSpaceManager.isNewModelStateAlreadyTraversed(); + } + + @Override + public boolean isCurrentStateInTrajectory() { + return designSpaceManager.isCurentStateInTrajectory(); + } + + public ActivationCodesConflictSet getActivationCodesConflictSet() { + return activationCodesConflictSet; + } + + public void changeActivationOrdering(ChangeableConflictSet activationOrderingConflictSet) { + this.dseConflictSet.changeActivationOrderingConflictSet(activationOrderingConflictSet); + } + + public void changeActivationOrderingBack() { + this.dseConflictSet.changeActivationOrderingConflictSetBack(); + } +} -- cgit v1.2.3-54-g00ecf