package de.gaalop.compressed; import de.gaalop.cfg.*; import de.gaalop.dfg.*; import de.gaalop.visitors.DFGTraversalVisitor; import java.util.*; /** * This visitor traverses the control and data flow graphs and generates C/C++ code. */ public class CompressedVisitor extends de.gaalop.cpp.CppVisitor { protected Map<String,Integer> mvSizes; protected Map<String,Map<Integer,Integer>> mvBladeMap = new HashMap<String,Map<Integer,Integer>>(); protected boolean gpcMetaInfo = true; public CompressedVisitor(Map<String,Integer> mvSizes,boolean standalone, boolean useDouble) { super(standalone, useDouble); this.mvSizes = mvSizes; } @Override public void visit(StartNode node) { graph = node.getGraph(); List<Variable> localVariables = sortVariables(graph.getLocalVariables()); if (standalone) { code.append("void calculate("); // Input Parameters List<Variable> inputParameters = sortVariables(graph.getInputVariables()); for (Variable var : inputParameters) { code.append(variableType).append(" "); // The assumption here is that they all are normal scalars code.append(var.getName()); code.append(", "); } for (Variable var : localVariables) { code.append(variableType).append(" "); code.append(var.getName()); if(mvSizes.get(var.getName()) > 1) code.append("[" + mvSizes.get(var.getName()).toString() + "]"); code.append(";\n"); } if (graph.getLocalVariables().size() > 0) { code.setLength(code.length() - 2); } code.append(") {\n"); indentation++; } else { for (Variable var : localVariables) { // GPC definition if (gpcMetaInfo) { appendIndentation(); code.append("//#pragma gpc multivector "); code.append(var.getName()); code.append('\n'); } // standard definition appendIndentation(); code.append(variableType).append(" "); code.append(var.getName()); if(mvSizes.get(var.getName()) > 1) code.append("[" + mvSizes.get(var.getName()).toString() + "]"); code.append(";\n"); } } if (graph.getScalarVariables().size() > 0) { appendIndentation(); code.append(variableType).append(" "); for (Variable tmp : graph.getScalarVariables()) { code.append(tmp.getName()); code.append(", "); } code.delete(code.length() - 2, code.length()); code.append(";\n"); } if (!graph.getLocalVariables().isEmpty()) { code.append("\n"); } node.getSuccessor().accept(this); } @Override public void visit(AssignmentNode node) { if (assigned.contains(node.getVariable().getName())) { log.warn("Reuse of variable " + node.getVariable().getName() + ". Make sure to reset this variable or use another name."); code.append("\n"); appendIndentation(); code.append("// Warning: reuse of variable "); code.append(node.getVariable().getName()); code.append(".\n"); appendIndentation(); code.append("// Make sure to reset this variable or use another name.\n"); assigned.remove(node.getVariable().getName()); } appendIndentation(); node.getVariable().accept(new MultivectorComponentWriteVisitor()); code.append(" = "); node.getValue().accept(this); code.append(";\n"); node.getSuccessor().accept(this); } @Override public void visit(MultivectorComponent component) { // this method is for reading multivector components // get blade pos in array final String name = component.getName().replace(suffix, ""); final int pos = mvBladeMap.get(name).get(component.getBladeIndex()); // standard definition code.append(name); if(mvSizes.get(name) > 1) code.append("[" + pos + "]"); } // this visitor is for writing to multivector components protected class MultivectorComponentWriteVisitor implements de.gaalop.dfg.ExpressionVisitor { @Override public void visit(MultivectorComponent component) { // this method is for writing to multivector components // get blade pos in array final String name = component.getName().replace(suffix, ""); Map<Integer,Integer> bladeMap = mvBladeMap.get(component.getName()); if(bladeMap == null) bladeMap = new HashMap<Integer, Integer>(); final int pos = bladeMap.size(); // determine component name String componentName = name; if(mvSizes.get(name) > 1) componentName += "[" + pos + "]"; // GPC definition if (gpcMetaInfo) { code.append("//#pragma gpc multivector_component "); code.append(component.getName()); code.append(' '); String bladeStr = graph.getAlgebraDefinitionFile().getBladeString(component.getBladeIndex()); bladeStr = bladeStr.replaceAll("\\(", "").replaceAll("\\)", "").replaceAll(" ", ""); code.append(bladeStr); code.append(' '); code.append(componentName); code.append('\n'); } // standard definition code.append(componentName); // save to blade map bladeMap.put(component.getBladeIndex(),pos); mvBladeMap.put(component.getName(), bladeMap); } @Override public void visit(Subtraction node) { throw new UnsupportedOperationException("Not supported yet."); } @Override public void visit(Addition node) { throw new UnsupportedOperationException("Not supported yet."); } @Override public void visit(Division node) { throw new UnsupportedOperationException("Not supported yet."); } @Override public void visit(InnerProduct node) { throw new UnsupportedOperationException("Not supported yet."); } @Override public void visit(Multiplication node) { throw new UnsupportedOperationException("Not supported yet."); } @Override public void visit(MathFunctionCall node) { throw new UnsupportedOperationException("Not supported yet."); } @Override public void visit(Variable node) { throw new UnsupportedOperationException("Not supported yet."); } @Override public void visit(Exponentiation node) { throw new UnsupportedOperationException("Not supported yet."); } @Override public void visit(FloatConstant node) { throw new UnsupportedOperationException("Not supported yet."); } @Override public void visit(OuterProduct node) { throw new UnsupportedOperationException("Not supported yet."); } @Override public void visit(BaseVector node) { throw new UnsupportedOperationException("Not supported yet."); } @Override public void visit(Negation node) { throw new UnsupportedOperationException("Not supported yet."); } @Override public void visit(Reverse node) { throw new UnsupportedOperationException("Not supported yet."); } @Override public void visit(LogicalOr node) { throw new UnsupportedOperationException("Not supported yet."); } @Override public void visit(LogicalAnd node) { throw new UnsupportedOperationException("Not supported yet."); } @Override public void visit(LogicalNegation node) { throw new UnsupportedOperationException("Not supported yet."); } @Override public void visit(Equality node) { throw new UnsupportedOperationException("Not supported yet."); } @Override public void visit(Inequality node) { throw new UnsupportedOperationException("Not supported yet."); } @Override public void visit(Relation relation) { throw new UnsupportedOperationException("Not supported yet."); } @Override public void visit(FunctionArgument node) { throw new UnsupportedOperationException("Not supported yet."); } @Override public void visit(MacroCall node) { throw new UnsupportedOperationException("Not supported yet."); } } }