Search in sources :

Example 66 with DataOp

use of org.apache.sysml.hops.DataOp in project systemml by apache.

the class DMLTranslator method processMultipleReturnBuiltinFunctionExpression.

/**
 * Construct HOps from parse tree: process BuiltinFunction Expressions in
 * MultiAssignment Statements. For all other builtin function expressions,
 * <code>processBuiltinFunctionExpression()</code> is used.
 *
 * @param source built-in function expression
 * @param targetList list of data identifiers
 * @param hops map of high-level operators
 * @return high-level operator
 */
private Hop processMultipleReturnBuiltinFunctionExpression(BuiltinFunctionExpression source, ArrayList<DataIdentifier> targetList, HashMap<String, Hop> hops) {
    // Construct Hops for all inputs
    ArrayList<Hop> inputs = new ArrayList<>();
    inputs.add(processExpression(source.getFirstExpr(), null, hops));
    if (source.getSecondExpr() != null)
        inputs.add(processExpression(source.getSecondExpr(), null, hops));
    if (source.getThirdExpr() != null)
        inputs.add(processExpression(source.getThirdExpr(), null, hops));
    FunctionType ftype = FunctionType.MULTIRETURN_BUILTIN;
    String nameSpace = DMLProgram.INTERNAL_NAMESPACE;
    // Create an array list to hold the outputs of this lop.
    // Exact list of outputs are added based on opcode.
    ArrayList<Hop> outputs = new ArrayList<>();
    // Construct Hop for current builtin function expression based on its type
    Hop currBuiltinOp = null;
    switch(source.getOpCode()) {
        case QR:
        case LU:
        case EIGEN:
        case SVD:
            // Number of outputs = size of targetList = #of identifiers in source.getOutputs
            String[] outputNames = new String[targetList.size()];
            for (int i = 0; i < targetList.size(); i++) {
                outputNames[i] = ((DataIdentifier) targetList.get(i)).getName();
                Hop output = new DataOp(outputNames[i], DataType.MATRIX, ValueType.DOUBLE, inputs.get(0), DataOpTypes.FUNCTIONOUTPUT, outputNames[i]);
                outputs.add(output);
            }
            // Create the hop for current function call
            FunctionOp fcall = new FunctionOp(ftype, nameSpace, source.getOpCode().toString(), inputs, outputNames, outputs);
            currBuiltinOp = fcall;
            break;
        default:
            throw new ParseException("Invaid Opcode in DMLTranslator:processMultipleReturnBuiltinFunctionExpression(): " + source.getOpCode());
    }
    // set properties for created hops based on outputs of source expression
    for (int i = 0; i < source.getOutputs().length; i++) {
        setIdentifierParams(outputs.get(i), source.getOutputs()[i]);
        outputs.get(i).setParseInfo(source);
    }
    currBuiltinOp.setParseInfo(source);
    return currBuiltinOp;
}
Also used : FunctionType(org.apache.sysml.hops.FunctionOp.FunctionType) Hop(org.apache.sysml.hops.Hop) ArrayList(java.util.ArrayList) ParameterizedBuiltinFunctionOp(org.apache.sysml.parser.Expression.ParameterizedBuiltinFunctionOp) BuiltinFunctionOp(org.apache.sysml.parser.Expression.BuiltinFunctionOp) FunctionOp(org.apache.sysml.hops.FunctionOp) DataOp(org.apache.sysml.hops.DataOp)

Example 67 with DataOp

use of org.apache.sysml.hops.DataOp in project systemml by apache.

the class DMLTranslator method processExpression.

/**
 * Construct Hops from parse tree : Process Expression in an assignment
 * statement
 *
 * @param source source expression
 * @param target data identifier
 * @param hops map of high-level operators
 * @return high-level operator
 */
private Hop processExpression(Expression source, DataIdentifier target, HashMap<String, Hop> hops) {
    try {
        if (source instanceof BinaryExpression)
            return processBinaryExpression((BinaryExpression) source, target, hops);
        else if (source instanceof RelationalExpression)
            return processRelationalExpression((RelationalExpression) source, target, hops);
        else if (source instanceof BooleanExpression)
            return processBooleanExpression((BooleanExpression) source, target, hops);
        else if (source instanceof BuiltinFunctionExpression)
            return processBuiltinFunctionExpression((BuiltinFunctionExpression) source, target, hops);
        else if (source instanceof ParameterizedBuiltinFunctionExpression)
            return processParameterizedBuiltinFunctionExpression((ParameterizedBuiltinFunctionExpression) source, target, hops);
        else if (source instanceof DataExpression) {
            Hop ae = (Hop) processDataExpression((DataExpression) source, target, hops);
            if (ae instanceof DataOp) {
                String formatName = ((DataExpression) source).getVarParam(DataExpression.FORMAT_TYPE).toString();
                ((DataOp) ae).setInputFormatType(Expression.convertFormatType(formatName));
            }
            return ae;
        } else if (source instanceof IndexedIdentifier)
            return processIndexingExpression((IndexedIdentifier) source, target, hops);
        else if (source instanceof IntIdentifier) {
            IntIdentifier sourceInt = (IntIdentifier) source;
            LiteralOp litop = new LiteralOp(sourceInt.getValue());
            litop.setParseInfo(sourceInt);
            setIdentifierParams(litop, sourceInt);
            return litop;
        } else if (source instanceof DoubleIdentifier) {
            DoubleIdentifier sourceDouble = (DoubleIdentifier) source;
            LiteralOp litop = new LiteralOp(sourceDouble.getValue());
            litop.setParseInfo(sourceDouble);
            setIdentifierParams(litop, sourceDouble);
            return litop;
        } else if (source instanceof BooleanIdentifier) {
            BooleanIdentifier sourceBoolean = (BooleanIdentifier) source;
            LiteralOp litop = new LiteralOp(sourceBoolean.getValue());
            litop.setParseInfo(sourceBoolean);
            setIdentifierParams(litop, sourceBoolean);
            return litop;
        } else if (source instanceof StringIdentifier) {
            StringIdentifier sourceString = (StringIdentifier) source;
            LiteralOp litop = new LiteralOp(sourceString.getValue());
            litop.setParseInfo(sourceString);
            setIdentifierParams(litop, sourceString);
            return litop;
        } else if (source instanceof DataIdentifier)
            return hops.get(((DataIdentifier) source).getName());
    } catch (Exception e) {
        throw new ParseException(e.getMessage());
    }
    return null;
}
Also used : Hop(org.apache.sysml.hops.Hop) HopsException(org.apache.sysml.hops.HopsException) DMLRuntimeException(org.apache.sysml.runtime.DMLRuntimeException) LopsException(org.apache.sysml.lops.LopsException) IOException(java.io.IOException) LiteralOp(org.apache.sysml.hops.LiteralOp) DataOp(org.apache.sysml.hops.DataOp)

Example 68 with DataOp

use of org.apache.sysml.hops.DataOp in project systemml by apache.

the class TemplateCell method rConstructCplan.

protected void rConstructCplan(Hop hop, CPlanMemoTable memo, HashMap<Long, CNode> tmp, HashSet<Hop> inHops, boolean compileLiterals) {
    // memoization for common subexpression elimination and to avoid redundant work
    if (tmp.containsKey(hop.getHopID()))
        return;
    MemoTableEntry me = memo.getBest(hop.getHopID(), TemplateType.CELL);
    // recursively process required childs
    if (me != null && me.type.isIn(TemplateType.ROW, TemplateType.OUTER)) {
        CNodeData cdata = TemplateUtils.createCNodeData(hop, compileLiterals);
        tmp.put(hop.getHopID(), cdata);
        inHops.add(hop);
        return;
    }
    for (int i = 0; i < hop.getInput().size(); i++) {
        Hop c = hop.getInput().get(i);
        if (me != null && me.isPlanRef(i) && !(c instanceof DataOp) && (me.type != TemplateType.MAGG || memo.contains(c.getHopID(), TemplateType.CELL)))
            rConstructCplan(c, memo, tmp, inHops, compileLiterals);
        else if (me != null && (me.type == TemplateType.MAGG || me.type == TemplateType.CELL) && HopRewriteUtils.isMatrixMultiply(hop) && // skip transpose
        i == 0)
            rConstructCplan(c.getInput().get(0), memo, tmp, inHops, compileLiterals);
        else {
            CNodeData cdata = TemplateUtils.createCNodeData(c, compileLiterals);
            tmp.put(c.getHopID(), cdata);
            inHops.add(c);
        }
    }
    // construct cnode for current hop
    CNode out = null;
    if (hop instanceof UnaryOp) {
        CNode cdata1 = tmp.get(hop.getInput().get(0).getHopID());
        cdata1 = TemplateUtils.wrapLookupIfNecessary(cdata1, hop.getInput().get(0));
        String primitiveOpName = ((UnaryOp) hop).getOp().name();
        out = new CNodeUnary(cdata1, UnaryType.valueOf(primitiveOpName));
    } else if (hop instanceof BinaryOp) {
        BinaryOp bop = (BinaryOp) hop;
        CNode cdata1 = tmp.get(hop.getInput().get(0).getHopID());
        CNode cdata2 = tmp.get(hop.getInput().get(1).getHopID());
        String primitiveOpName = bop.getOp().name();
        // add lookups if required
        cdata1 = TemplateUtils.wrapLookupIfNecessary(cdata1, hop.getInput().get(0));
        cdata2 = TemplateUtils.wrapLookupIfNecessary(cdata2, hop.getInput().get(1));
        // construct binary cnode
        out = new CNodeBinary(cdata1, cdata2, BinType.valueOf(primitiveOpName));
    } else if (hop instanceof TernaryOp) {
        TernaryOp top = (TernaryOp) hop;
        CNode cdata1 = tmp.get(hop.getInput().get(0).getHopID());
        CNode cdata2 = tmp.get(hop.getInput().get(1).getHopID());
        CNode cdata3 = tmp.get(hop.getInput().get(2).getHopID());
        // add lookups if required
        cdata1 = TemplateUtils.wrapLookupIfNecessary(cdata1, hop.getInput().get(0));
        cdata2 = TemplateUtils.wrapLookupIfNecessary(cdata2, hop.getInput().get(1));
        cdata3 = TemplateUtils.wrapLookupIfNecessary(cdata3, hop.getInput().get(2));
        // construct ternary cnode, primitive operation derived from OpOp3
        out = new CNodeTernary(cdata1, cdata2, cdata3, TernaryType.valueOf(top.getOp().name()));
    } else if (hop instanceof ParameterizedBuiltinOp) {
        CNode cdata1 = tmp.get(((ParameterizedBuiltinOp) hop).getTargetHop().getHopID());
        cdata1 = TemplateUtils.wrapLookupIfNecessary(cdata1, hop.getInput().get(0));
        CNode cdata2 = tmp.get(((ParameterizedBuiltinOp) hop).getParameterHop("pattern").getHopID());
        CNode cdata3 = tmp.get(((ParameterizedBuiltinOp) hop).getParameterHop("replacement").getHopID());
        TernaryType ttype = (cdata2.isLiteral() && cdata2.getVarname().equals("Double.NaN")) ? TernaryType.REPLACE_NAN : TernaryType.REPLACE;
        out = new CNodeTernary(cdata1, cdata2, cdata3, ttype);
    } else if (hop instanceof IndexingOp) {
        CNode cdata1 = tmp.get(hop.getInput().get(0).getHopID());
        out = new CNodeTernary(cdata1, TemplateUtils.createCNodeData(new LiteralOp(hop.getInput().get(0).getDim2()), true), TemplateUtils.createCNodeData(hop.getInput().get(4), true), TernaryType.LOOKUP_RC1);
    } else if (HopRewriteUtils.isTransposeOperation(hop)) {
        out = TemplateUtils.skipTranspose(tmp.get(hop.getHopID()), hop, tmp, compileLiterals);
        // correct indexing types of existing lookups
        if (!HopRewriteUtils.containsOp(hop.getParent(), AggBinaryOp.class))
            TemplateUtils.rFlipVectorLookups(out);
        // maintain input hops
        if (out instanceof CNodeData && !inHops.contains(hop.getInput().get(0)))
            inHops.add(hop.getInput().get(0));
    } else if (hop instanceof AggUnaryOp) {
        // aggregation handled in template implementation (note: we do not compile
        // ^2 of SUM_SQ into the operator to simplify the detection of single operators)
        out = tmp.get(hop.getInput().get(0).getHopID());
    } else if (hop instanceof AggBinaryOp) {
        // (1) t(X)%*%X -> sum(X^2) and t(X) %*% Y -> sum(X*Y)
        if (HopRewriteUtils.isTransposeOfItself(hop.getInput().get(0), hop.getInput().get(1))) {
            CNode cdata1 = tmp.get(hop.getInput().get(1).getHopID());
            if (TemplateUtils.isColVector(cdata1))
                cdata1 = new CNodeUnary(cdata1, UnaryType.LOOKUP_R);
            out = new CNodeUnary(cdata1, UnaryType.POW2);
        } else {
            CNode cdata1 = TemplateUtils.skipTranspose(tmp.get(hop.getInput().get(0).getHopID()), hop.getInput().get(0), tmp, compileLiterals);
            if (cdata1 instanceof CNodeData && !inHops.contains(hop.getInput().get(0).getInput().get(0)))
                inHops.add(hop.getInput().get(0).getInput().get(0));
            if (TemplateUtils.isColVector(cdata1))
                cdata1 = new CNodeUnary(cdata1, UnaryType.LOOKUP_R);
            CNode cdata2 = tmp.get(hop.getInput().get(1).getHopID());
            if (TemplateUtils.isColVector(cdata2))
                cdata2 = new CNodeUnary(cdata2, UnaryType.LOOKUP_R);
            out = new CNodeBinary(cdata1, cdata2, BinType.MULT);
        }
    }
    tmp.put(hop.getHopID(), out);
}
Also used : TernaryType(org.apache.sysml.hops.codegen.cplan.CNodeTernary.TernaryType) CNodeData(org.apache.sysml.hops.codegen.cplan.CNodeData) AggUnaryOp(org.apache.sysml.hops.AggUnaryOp) UnaryOp(org.apache.sysml.hops.UnaryOp) CNodeTernary(org.apache.sysml.hops.codegen.cplan.CNodeTernary) AggBinaryOp(org.apache.sysml.hops.AggBinaryOp) Hop(org.apache.sysml.hops.Hop) CNodeBinary(org.apache.sysml.hops.codegen.cplan.CNodeBinary) TernaryOp(org.apache.sysml.hops.TernaryOp) CNode(org.apache.sysml.hops.codegen.cplan.CNode) ParameterizedBuiltinOp(org.apache.sysml.hops.ParameterizedBuiltinOp) CNodeUnary(org.apache.sysml.hops.codegen.cplan.CNodeUnary) IndexingOp(org.apache.sysml.hops.IndexingOp) AggUnaryOp(org.apache.sysml.hops.AggUnaryOp) MemoTableEntry(org.apache.sysml.hops.codegen.template.CPlanMemoTable.MemoTableEntry) LiteralOp(org.apache.sysml.hops.LiteralOp) DataOp(org.apache.sysml.hops.DataOp) AggBinaryOp(org.apache.sysml.hops.AggBinaryOp) BinaryOp(org.apache.sysml.hops.BinaryOp)

Example 69 with DataOp

use of org.apache.sysml.hops.DataOp in project systemml by apache.

the class RewriteBlockSizeAndReblock method rule_BlockSizeAndReblock.

private void rule_BlockSizeAndReblock(Hop hop, final int blocksize) {
    // Go to the source(s) of the DAG
    for (Hop hi : hop.getInput()) {
        if (!hi.isVisited())
            rule_BlockSizeAndReblock(hi, blocksize);
    }
    boolean canReblock = isReblockValid();
    if (hop instanceof DataOp) {
        DataOp dop = (DataOp) hop;
        // if block size does not match
        if (canReblock && ((dop.getDataType() == DataType.MATRIX && (dop.getRowsInBlock() != blocksize || dop.getColsInBlock() != blocksize)) || (dop.getDataType() == DataType.FRAME && OptimizerUtils.isSparkExecutionMode() && (dop.getInputFormatType() == FileFormatTypes.TEXT || dop.getInputFormatType() == FileFormatTypes.CSV)))) {
            if (dop.getDataOpType() == DataOp.DataOpTypes.PERSISTENTREAD) {
                // insert reblock after the hop
                dop.setRequiresReblock(true);
                dop.setOutputBlocksizes(blocksize, blocksize);
            } else if (dop.getDataOpType() == DataOp.DataOpTypes.PERSISTENTWRITE) {
                if (dop.getRowsInBlock() == -1 && dop.getColsInBlock() == -1) {
                // if this dataop is for cell output, then no reblock is needed
                // as (A) all jobtypes can produce block2cell and cell2cell and
                // (B) we don't generate an explicit instruction for it (the info
                // is conveyed through OutputInfo.
                } else if (dop.getInput().get(0).requiresReblock() && dop.getInput().get(0).getParent().size() == 1) {
                    // if a reblock is feeding into this, then use it if this is
                    // the only parent, otherwise new Reblock
                    dop.getInput().get(0).setOutputBlocksizes(dop.getRowsInBlock(), dop.getColsInBlock());
                } else {
                    // insert reblock after the hop
                    dop.setRequiresReblock(true);
                    dop.setOutputBlocksizes(blocksize, blocksize);
                }
            } else if (dop.getDataOpType() == DataOp.DataOpTypes.TRANSIENTWRITE || dop.getDataOpType() == DataOp.DataOpTypes.TRANSIENTREAD) {
                if (DMLScript.rtplatform == RUNTIME_PLATFORM.SINGLE_NODE) {
                    // simply copy the values from its input
                    dop.setRowsInBlock(hop.getInput().get(0).getRowsInBlock());
                    dop.setColsInBlock(hop.getInput().get(0).getColsInBlock());
                } else {
                    // by default, all transient reads and writes are in blocked format
                    dop.setRowsInBlock(blocksize);
                    dop.setColsInBlock(blocksize);
                }
            } else {
                throw new HopsException(hop.printErrorLocation() + "unexpected non-scalar Data HOP in reblock.\n");
            }
        }
    } else // NO DATAOP
    {
        if (hop.requiresReblock()) {
            hop.setRowsInBlock(blocksize);
            hop.setColsInBlock(blocksize);
        } else // Constraint C2:
        if (hop.getDataType() == DataType.SCALAR) {
            hop.setRowsInBlock(-1);
            hop.setColsInBlock(-1);
        } else // Constraint C3:
        {
            if (!canReblock) {
                hop.setRowsInBlock(-1);
                hop.setColsInBlock(-1);
            } else {
                hop.setRowsInBlock(blocksize);
                hop.setColsInBlock(blocksize);
                // Reblock properties need to be set for each output.
                if (hop instanceof FunctionOp) {
                    FunctionOp fop = (FunctionOp) hop;
                    if (fop.getOutputs() != null) {
                        for (Hop out : fop.getOutputs()) {
                            out.setRowsInBlock(blocksize);
                            out.setColsInBlock(blocksize);
                        }
                    }
                }
            }
            // if any input is not blocked then the output of current Hop should not be blocked
            for (Hop h : hop.getInput()) {
                if (h.getDataType() == DataType.MATRIX && h.getRowsInBlock() == -1 && h.getColsInBlock() == -1) {
                    hop.setRowsInBlock(-1);
                    hop.setColsInBlock(-1);
                    break;
                }
            }
        }
    }
    hop.setVisited();
}
Also used : Hop(org.apache.sysml.hops.Hop) FunctionOp(org.apache.sysml.hops.FunctionOp) HopsException(org.apache.sysml.hops.HopsException) DataOp(org.apache.sysml.hops.DataOp)

Example 70 with DataOp

use of org.apache.sysml.hops.DataOp in project systemml by apache.

the class RewriteCommonSubexpressionElimination method rule_CommonSubexpressionElimination_MergeLeafs.

private int rule_CommonSubexpressionElimination_MergeLeafs(Hop hop, HashMap<String, Hop> dataops, HashMap<String, Hop> literalops) {
    int ret = 0;
    if (hop.isVisited())
        return ret;
    if (// LEAF NODE
    hop.getInput().isEmpty()) {
        if (hop instanceof LiteralOp) {
            String key = hop.getValueType() + "_" + hop.getName();
            if (!literalops.containsKey(key))
                literalops.put(key, hop);
        } else if (hop instanceof DataOp && ((DataOp) hop).isRead()) {
            if (!dataops.containsKey(hop.getName()))
                dataops.put(hop.getName(), hop);
        }
    } else // INNER NODE
    {
        // merge leaf nodes (data, literal)
        for (int i = 0; i < hop.getInput().size(); i++) {
            Hop hi = hop.getInput().get(i);
            String litKey = hi.getValueType() + "_" + hi.getName();
            if (hi instanceof DataOp && ((DataOp) hi).isRead() && dataops.containsKey(hi.getName())) {
                // replace child node ref
                Hop tmp = dataops.get(hi.getName());
                if (tmp != hi) {
                    // if required
                    tmp.getParent().add(hop);
                    tmp.setVisited();
                    hop.getInput().set(i, tmp);
                    ret++;
                }
            } else if (hi instanceof LiteralOp && literalops.containsKey(litKey)) {
                Hop tmp = literalops.get(litKey);
                // replace child node ref
                if (tmp != hi) {
                    // if required
                    tmp.getParent().add(hop);
                    tmp.setVisited();
                    hop.getInput().set(i, tmp);
                    ret++;
                }
            }
            // recursive invocation (direct return on merged nodes)
            ret += rule_CommonSubexpressionElimination_MergeLeafs(hi, dataops, literalops);
        }
    }
    hop.setVisited();
    return ret;
}
Also used : Hop(org.apache.sysml.hops.Hop) LiteralOp(org.apache.sysml.hops.LiteralOp) DataOp(org.apache.sysml.hops.DataOp)

Aggregations

DataOp (org.apache.sysml.hops.DataOp)86 Hop (org.apache.sysml.hops.Hop)75 LiteralOp (org.apache.sysml.hops.LiteralOp)44 ArrayList (java.util.ArrayList)23 AggUnaryOp (org.apache.sysml.hops.AggUnaryOp)20 UnaryOp (org.apache.sysml.hops.UnaryOp)18 StatementBlock (org.apache.sysml.parser.StatementBlock)17 MatrixObject (org.apache.sysml.runtime.controlprogram.caching.MatrixObject)17 HopsException (org.apache.sysml.hops.HopsException)16 IndexingOp (org.apache.sysml.hops.IndexingOp)16 HashMap (java.util.HashMap)13 FunctionOp (org.apache.sysml.hops.FunctionOp)13 ForStatementBlock (org.apache.sysml.parser.ForStatementBlock)13 WhileStatementBlock (org.apache.sysml.parser.WhileStatementBlock)13 DMLRuntimeException (org.apache.sysml.runtime.DMLRuntimeException)12 DataIdentifier (org.apache.sysml.parser.DataIdentifier)11 IfStatementBlock (org.apache.sysml.parser.IfStatementBlock)11 Data (org.apache.sysml.runtime.instructions.cp.Data)11 BinaryOp (org.apache.sysml.hops.BinaryOp)9 LeftIndexingOp (org.apache.sysml.hops.LeftIndexingOp)9