Skip to content
Snippets Groups Projects
Commit 0a0edb66 authored by Johannes Mey's avatar Johannes Mey
Browse files

adapt mquat model to more correct runtime estimations

parent b21bafac
No related branches found
No related tags found
No related merge requests found
......@@ -5,7 +5,6 @@ import de.tudresden.inf.st.mquat.jastadd.model.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
......@@ -14,7 +13,7 @@ public class ErisMQuATBuilder {
private static final Logger logger = LogManager.getLogger(ErisMQuATBuilder.class);
static Root createModel(ERISModel erisModel, boolean USE_CURRENT_CONFIG) {
static Root createModel(ERISModel erisModel) {
Root root = new Root();
......@@ -37,6 +36,7 @@ public class ErisMQuATBuilder {
Property indexAttributeCount = new Property(new Name("indexAttributeCount"), "flag");
Property indexOrderPreserving = new Property(new Name("indexOrderPreserving"), "flag");
Property direct = new Property(new Name("isDirect"), "flag");
Property index = new Property(new Name("isIndex"), "flag");
accessPath.addProperty(dynamic);
accessPath.addProperty(attributeCount);
accessPath.addProperty(attributeNull);
......@@ -45,6 +45,7 @@ public class ErisMQuATBuilder {
accessPath.addProperty(indexAttributeCount);
accessPath.addProperty(indexOrderPreserving);
accessPath.addProperty(direct);
accessPath.addProperty(index);
// add energy benchmark properties
Map<Integer, Property> insertProperties = new HashMap<>();
......@@ -103,6 +104,10 @@ public class ErisMQuATBuilder {
multiResource.addCurrentResourceValue(
new CurrentResourceValue(direct.createRef(), new LiteralExpression(isDirect ? 1D : 0D))
);
boolean isIndex = erisAccessPath.getAddressingMode().equals("index");
multiResource.addCurrentResourceValue(
new CurrentResourceValue(index.createRef(), new LiteralExpression(isIndex ? 1D : 0D))
);
// add all the attribute stat values
for (ERISBenchmarkResult benchmarkResult : erisAccessPath.getResultList()) {
......@@ -148,90 +153,6 @@ public class ErisMQuATBuilder {
SoftwareModel softwareModel = new SoftwareModel();
if (USE_CURRENT_CONFIG) {
for (ERISContainer erisContainer : erisModel.getErisContainers()) {
for (ERISLivingPartition livingPartition : erisContainer.getPartitionList()) {
for (ERISLPConfiguration config : livingPartition.getConfigurations()) {
// ignore the default config for now
boolean foundAttribute = false;
for (ERISAttribute attribute : config.getAttributesAndKeys()) {
System.out.println(attribute.getName());
if (!attribute.isSystem()) {
foundAttribute = true;
}
}
if (!foundAttribute) continue;
// create a component for every config
Component component = new Component();
String configName = "Config_";
for (ERISAttribute attribute : config.getAttributesAndKeys()) {
configName += attribute.getName();
}
component.setName(new Name(configName));
Implementation implementation = new Implementation();
implementation.setName(new Name("accessPathSelector"));
Instance accessPathInstance = new Instance(new Name("accessPath"));
ResourceRequirement resourceRequirement = new ResourceRequirement();
resourceRequirement.addInstance(accessPathInstance);
resourceRequirement.setResourceTypeRef(accessPath.createRef());
implementation.setResourceRequirement(resourceRequirement);
// create the requirements
// the number of attributes
implementation.addClause(new Clause(ClauseType.REQUIRING, new PropertyResourceDesignator(accessPathInstance.createRef(), attributeCount.createRef()), ClauseComparator.GE, new LiteralExpression(config.getAttributesAndKeys().size())));
boolean canBeNull = false;
boolean canBeUndefined = false;
// collect the requirements of all contained attributes
for (ERISAttribute attribute : livingPartition.getAttributes()) {
canBeNull = canBeNull | !attribute.isNotNull();
canBeUndefined = canBeUndefined | !attribute.isNotUndefined();
}
if (canBeNull) {
implementation.addClause(new Clause(ClauseType.REQUIRING, new PropertyResourceDesignator(accessPathInstance.createRef(), attributeNull.createRef()), ClauseComparator.EQ, new LiteralExpression(canBeNull ? 1 : 0)));
}
if (canBeUndefined) {
implementation.addClause(new Clause(ClauseType.REQUIRING, new PropertyResourceDesignator(accessPathInstance.createRef(), attributeUndefined.createRef()), ClauseComparator.EQ, new LiteralExpression(canBeUndefined ? 1 : 0)));
}
// create the provisions
java.util.List<Expression> attributeExpressions = new ArrayList<>();
for (ERISAttribute attribute : livingPartition.getAttributes()) {
Expression expression = buildRuntimeProvision(insertProperties, linkProperties, lookupProperties, scanProperties, accessPathInstance, attribute);
attributeExpressions.add(expression);
}
Expression expression = attributeExpressions.remove(0);
for (Expression ex : attributeExpressions) {
expression = new AddExpression(ex, expression);
}
implementation.addClause(new Clause(ClauseType.PROVIDING, new SoftwareDesignator(new Opt<>(), runtime.createRef()), ClauseComparator.EQ, expression));
component.addImplementation(implementation);
// create a request
Request request = new Request();
request.setTarget(component.createRef());
root.addRequest(request);
softwareModel.addComponent(component);
}
}
}
} else {
// for each container, living partition, and attribute, create a software component and a request
for (ERISContainer erisContainer : erisModel.getErisContainers()) {
for (ERISAttribute attribute : erisContainer.getAttributeList()) {
......@@ -240,7 +161,6 @@ public class ErisMQuATBuilder {
if (attribute.isLinkage()) continue;
for (ERISLivingPartition erisLivingPartition : erisContainer.getPartitionList()) {
ERISAttributeStatistics statistics = null;
......@@ -256,8 +176,6 @@ public class ErisMQuATBuilder {
&& statistics.getScans() == 0) {
logger.debug("counters are all zero for attribute {}", attribute.getId());
continue;
} else {
logger.debug("in lp {} in cont {}: {} {} {} {}", erisLivingPartition.getLocalId(), erisContainer.getId(), statistics.getScans(), statistics.getLookups(), statistics.getInserts(), statistics.getLinks());
}
if (erisLivingPartition.isAdaptationScheduled()) {
......@@ -266,90 +184,135 @@ public class ErisMQuATBuilder {
}
// create a new top-level software component and two implementations, one of which enforces direct access
Component component = new Component();
Component directComponent = new Component();
component.setName(new Name(createName(erisContainer, erisLivingPartition, attribute)));
directComponent.setName(new Name("direct_" + createName(erisContainer, erisLivingPartition, attribute)));
Implementation implementation = new Implementation();
Implementation directImplementation = new Implementation();
implementation.setName(new Name("accessPathSelector"));
directImplementation.setName(new Name("directAccessPathSelector"));
Component indexComponent = new Component();
Component directOrIndirectComponent = new Component();
indexComponent.setName(new Name("index_" + createName(erisContainer, erisLivingPartition, attribute)));
directOrIndirectComponent.setName(new Name("direct_or_indirect_" + createName(erisContainer, erisLivingPartition, attribute)));
Implementation indexImplementation = new Implementation();
Implementation directOrIndirectImplementation = new Implementation();
indexImplementation.setName(new Name("indexAccessPathSelector"));
directOrIndirectImplementation.setName(new Name("directOrIndirectAccessPathSelector"));
// create the requirement for an access path
Instance accessPathInstance = new Instance(new Name("accessPath_" + attribute.getName()));
Instance directAccessPathInstance = new Instance(new Name("directAccessPath_" + attribute.getName()));
ResourceRequirement resourceRequirement = new ResourceRequirement();
ResourceRequirement directResourceRequirement = new ResourceRequirement();
resourceRequirement.addInstance(accessPathInstance);
directResourceRequirement.addInstance(directAccessPathInstance);
resourceRequirement.setResourceTypeRef(accessPath.createRef());
directResourceRequirement.setResourceTypeRef(accessPath.createRef());
implementation.setResourceRequirement(resourceRequirement);
directImplementation.setResourceRequirement(directResourceRequirement);
Instance indexAccessPathInstance = new Instance(new Name("indexAccessPath_" + attribute.getName()));
Instance directOrIndirectAccessPathInstance = new Instance(new Name("directOrIndirectAccessPath_" + attribute.getName()));
ResourceRequirement indexResourceRequirement = new ResourceRequirement();
ResourceRequirement directOrIndirectResourceRequirement = new ResourceRequirement();
indexResourceRequirement.addInstance(indexAccessPathInstance);
directOrIndirectResourceRequirement.addInstance(directOrIndirectAccessPathInstance);
indexResourceRequirement.setResourceTypeRef(accessPath.createRef());
directOrIndirectResourceRequirement.setResourceTypeRef(accessPath.createRef());
indexImplementation.setResourceRequirement(indexResourceRequirement);
directOrIndirectImplementation.setResourceRequirement(directOrIndirectResourceRequirement);
// ensure access path properties
// on a per-attribute access path configuration, only the null and undefined checks have to be done
if (!attribute.isNotNull()) {
implementation.addClause(new Clause(
indexImplementation.addClause(new Clause(
ClauseType.REQUIRING,
new PropertyResourceDesignator(accessPathInstance.createRef(), attributeNull.createRef()),
new PropertyResourceDesignator(indexAccessPathInstance.createRef(), attributeNull.createRef()),
ClauseComparator.EQ,
new LiteralExpression(1D)
));
directImplementation.addClause(new Clause(
directOrIndirectImplementation.addClause(new Clause(
ClauseType.REQUIRING,
new PropertyResourceDesignator(directAccessPathInstance.createRef(), attributeNull.createRef()),
new PropertyResourceDesignator(directOrIndirectAccessPathInstance.createRef(), attributeNull.createRef()),
ClauseComparator.EQ,
new LiteralExpression(1D)
));
}
if (!attribute.isNotUndefined()) {
implementation.addClause(new Clause(
indexImplementation.addClause(new Clause(
ClauseType.REQUIRING,
new PropertyResourceDesignator(accessPathInstance.createRef(), attributeUndefined.createRef()),
new PropertyResourceDesignator(indexAccessPathInstance.createRef(), attributeUndefined.createRef()),
ClauseComparator.EQ,
new LiteralExpression(1D)
));
directImplementation.addClause(new Clause(
directOrIndirectImplementation.addClause(new Clause(
ClauseType.REQUIRING,
new PropertyResourceDesignator(directAccessPathInstance.createRef(), attributeUndefined.createRef()),
new PropertyResourceDesignator(directOrIndirectAccessPathInstance.createRef(), attributeUndefined.createRef()),
ClauseComparator.EQ,
new LiteralExpression(1D)
));
}
// create the provisions
Expression expression = buildRuntimeProvision(insertProperties, linkProperties, lookupProperties, scanProperties, accessPathInstance, attribute);
implementation.addClause(new Clause(ClauseType.PROVIDING, new SoftwareDesignator(new Opt<>(), runtime.createRef()), ClauseComparator.EQ, expression));
// if (!as || as->lookups < 1) {
// return -1;
// }
// AccessPathBechmarkInfo* bmiref = Eris::instance->accessPathManager->getAccessPathPerformance(refCandidate->factory, refCandidate->dynamic);
// double refdiff = AccessPathBechmarkInfo::getTimeForSize(&bmiref->lookupTimes, as->count) - AccessPathBechmarkInfo::getTimeForSize(&bmi->lookupTimes, as->count);
// score += as->lookups * refdiff;
// if (as->inserts > 0) {
// score -= as->inserts * AccessPathBechmarkInfo::getTimeForSize(&bmi->insertTimes, as->count);
// }
// ref is the best direct or indirect access path
// score = ref.lookuptime*this.count - this.lookuptime*this.count - this.inserts*this.insertTime
// because we do not know ref.lookuptime here, we omit this part. it is irrelevant for selecting the index
// access path, anyway. It is required later during the decision IF the index should be built. So the actual
// score is:
// score = -this.lookupTime*this.numLookups - this.insertTime*this.numInserts
// get the statistics
ERISAttributeStatistics attStats = attribute.getStatistics();
int num_lookups = attStats.getLookups();
int num_inserts = attStats.getInserts();
int num_scans = attStats.getScans();
int num_links = attStats.getLinks();
int att_count = attStats.getCount();
// get the correct size
int lookupsize = getLookupSize(lookupProperties, att_count);
{
MultExpression negatedLoopups = new MultExpression(new LiteralExpression(-num_lookups), new PropertyResourceDesignator(indexAccessPathInstance.createRef(), lookupProperties.get(lookupsize).createRef()));
MultExpression inserts = new MultExpression(new LiteralExpression(num_inserts), new PropertyResourceDesignator(indexAccessPathInstance.createRef(), insertProperties.get(lookupsize).createRef()));
Expression indexExpression = new SubExpression(negatedLoopups, inserts);
indexImplementation.addClause(new Clause(ClauseType.PROVIDING, new SoftwareDesignator(new Opt<>(), runtime.createRef()), ClauseComparator.EQ, indexExpression));
}
Expression directExpression = buildRuntimeProvision(insertProperties, linkProperties, lookupProperties, scanProperties, directAccessPathInstance, attribute);
directImplementation.addClause(new Clause(ClauseType.PROVIDING, new SoftwareDesignator(new Opt<>(), runtime.createRef()), ClauseComparator.EQ, directExpression));
{
MultExpression loopups = new MultExpression(new LiteralExpression(num_lookups), new PropertyResourceDesignator(directOrIndirectAccessPathInstance.createRef(), lookupProperties.get(lookupsize).createRef()));
MultExpression inserts = new MultExpression(new LiteralExpression(num_inserts), new PropertyResourceDesignator(directOrIndirectAccessPathInstance.createRef(), insertProperties.get(lookupsize).createRef()));
MultExpression scans = new MultExpression(new MultExpression(new LiteralExpression(num_scans), new PropertyResourceDesignator(directOrIndirectAccessPathInstance.createRef(), scanProperties.get(lookupsize).createRef())), new LiteralExpression(att_count));
MultExpression links = new MultExpression(new LiteralExpression(num_links), new PropertyResourceDesignator(directOrIndirectAccessPathInstance.createRef(), linkProperties.get(lookupsize).createRef()));
Expression directOrIndirectExpression = new AddExpression(loopups, new AddExpression(inserts, new AddExpression(scans, links)));
directOrIndirectImplementation.addClause(new Clause(ClauseType.PROVIDING, new SoftwareDesignator(new Opt<>(), runtime.createRef()), ClauseComparator.EQ, directOrIndirectExpression));
}
// add an additional requirement to only allow direct access paths for the direct implementation
directImplementation.addClause(new Clause(
// add an additional requirement to only index access paths for the direct implementation
indexImplementation.addClause(new Clause(
ClauseType.REQUIRING,
new PropertyResourceDesignator(directAccessPathInstance.createRef(), direct.createRef()),
new PropertyResourceDesignator(indexAccessPathInstance.createRef(), index.createRef()),
ClauseComparator.EQ,
new LiteralExpression(1D)
));
component.addImplementation(implementation);
directComponent.addImplementation(directImplementation);
softwareModel.addComponent(component);
softwareModel.addComponent(directComponent);
// add an additional requirement to only allow direct or indirect access paths for the direct implementation
directOrIndirectImplementation.addClause(new Clause(
ClauseType.REQUIRING,
new PropertyResourceDesignator(directOrIndirectAccessPathInstance.createRef(), index.createRef()),
ClauseComparator.EQ,
new LiteralExpression(0D)
));
indexComponent.addImplementation(indexImplementation);
directOrIndirectComponent.addImplementation(directOrIndirectImplementation);
softwareModel.addComponent(indexComponent);
softwareModel.addComponent(directOrIndirectComponent);
// create the requests
Request request = new Request();
request.setTarget(component.createRef());
request.setName(new Name("request_" + createName(erisContainer, erisLivingPartition, attribute)));
root.addRequest(request);
Request directRequest = new Request();
directRequest.setTarget(directComponent.createRef());
directRequest.setName(new Name("direct_request_" + createName(erisContainer, erisLivingPartition, attribute)));
root.addRequest(directRequest);
}
Request indexRequest = new Request();
indexRequest.setTarget(indexComponent.createRef());
indexRequest.setName(new Name("index_request_" + createName(erisContainer, erisLivingPartition, attribute)));
root.addRequest(indexRequest);
Request directOrIndirectRequest = new Request();
directOrIndirectRequest.setTarget(directOrIndirectComponent.createRef());
directOrIndirectRequest.setName(new Name("request_" + createName(erisContainer, erisLivingPartition, attribute)));
root.addRequest(directOrIndirectRequest);
}
}
}
......@@ -365,27 +328,6 @@ public class ErisMQuATBuilder {
return root;
}
private static Expression buildRuntimeProvision(Map<Integer, Property> insertProperties, Map<Integer, Property> linkProperties, Map<Integer, Property> lookupProperties, Map<Integer, Property> scanProperties, Instance accessPathInstance, ERISAttribute attribute) {
// get the statistics
ERISAttributeStatistics attStats = attribute.getStatistics();
int num_lookups = attStats.getLookups();
int num_inserts = attStats.getInserts();
int num_scans = attStats.getScans();
int num_links = attStats.getLinks();
int att_count = attStats.getCount();
// get the correct size
int lookupsize = getLookupSize(lookupProperties, att_count);
MultExpression loopups = new MultExpression(new LiteralExpression(num_lookups), new PropertyResourceDesignator(accessPathInstance.createRef(), lookupProperties.get(lookupsize).createRef()));
MultExpression inserts = new MultExpression(new LiteralExpression(num_inserts), new PropertyResourceDesignator(accessPathInstance.createRef(), insertProperties.get(lookupsize).createRef()));
MultExpression scans = new MultExpression(new LiteralExpression(num_scans), new PropertyResourceDesignator(accessPathInstance.createRef(), scanProperties.get(lookupsize).createRef()));
MultExpression links = new MultExpression(new LiteralExpression(num_links), new PropertyResourceDesignator(accessPathInstance.createRef(), linkProperties.get(lookupsize).createRef()));
return new AddExpression(loopups, new AddExpression(inserts, new AddExpression(scans, links)));
}
private static int getLookupSize(Map<Integer, Property> lookupProperties, int att_count) {
// get the correct size
int lookupsize = 0;
......@@ -402,8 +344,6 @@ public class ErisMQuATBuilder {
private static String createName(ERISContainer container, ERISLivingPartition partition, ERISAttribute attribute) {
// TODO use ID instead of name for attribute if possible
return container.getId() + "_" + partition.getNodeId() + "_" + partition.getLocalId() + "_" + attribute.getId() + "_" + attribute.getName();
//return "Container_" + container.getId() + "_Node_" + partition.getNodeId() + "_LP_" + partition.getLocalId() + "_Attribute_" + attribute.getId() + "_" + attribute.getName();
}
}
......@@ -2,6 +2,7 @@ package de.tudresden.inf.st.mquat.eris;
import de.tudresden.inf.st.mquat.benchmark.SolverFactory;
import de.tudresden.inf.st.mquat.eris.coupling.ERISConnector;
import de.tudresden.inf.st.mquat.jastadd.model.MquatWriteSettings;
import de.tudresden.inf.st.mquat.jastadd.model.Root;
import de.tudresden.inf.st.mquat.jastadd.model.Solution;
import de.tudresden.inf.st.mquat.solving.SolvingException;
......@@ -20,7 +21,9 @@ public class ErisTask extends TimerTask {
try {
ERISConnector erisConnector = new ERISConnector();
erisConnector.read();
Root model = ErisMQuATBuilder.createModel(erisConnector.getErisModel(), false);
Root model = ErisMQuATBuilder.createModel(erisConnector.getErisModel());
System.out.println(model.print(new MquatWriteSettings(" ")));
ILPExternalSolver solver = (ILPExternalSolver) SolverFactory.getSolverByName("ilp-glpk");
......@@ -28,6 +31,8 @@ public class ErisTask extends TimerTask {
Solution solution = solver.solve(model);
System.out.println(solution.print(new MquatWriteSettings(" ")));
if (solution.getNumAssignment() > 0) {
logger.info("Found solution. Sending now...");
erisConnector.write(solution);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment