Search in sources :

Example 51 with DataOp

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

the class RewriteSplitDagDataDependentOperators method rewriteStatementBlock.

@Override
public List<StatementBlock> rewriteStatementBlock(StatementBlock sb, ProgramRewriteStatus state) {
    // DAG splits not required for forced single node
    if (DMLScript.rtplatform == RUNTIME_PLATFORM.SINGLE_NODE || !HopRewriteUtils.isLastLevelStatementBlock(sb))
        return Arrays.asList(sb);
    ArrayList<StatementBlock> ret = new ArrayList<>();
    // collect all unknown csv reads hops
    ArrayList<Hop> cand = new ArrayList<>();
    collectDataDependentOperators(sb.getHops(), cand);
    Hop.resetVisitStatus(sb.getHops());
    // split hop dag on demand
    if (!cand.isEmpty()) {
        // collect child operators of candidates (to prevent rewrite anomalies)
        HashSet<Hop> candChilds = new HashSet<>();
        collectCandidateChildOperators(cand, candChilds);
        try {
            // duplicate sb incl live variable sets
            StatementBlock sb1 = new StatementBlock();
            sb1.setDMLProg(sb.getDMLProg());
            sb1.setParseInfo(sb);
            sb1.setLiveIn(new VariableSet());
            sb1.setLiveOut(new VariableSet());
            // move data-dependent ops incl transient writes to new statement block
            // (and replace original persistent read with transient read)
            ArrayList<Hop> sb1hops = new ArrayList<>();
            for (Hop c : cand) {
                // if there are already transient writes use them and don't introduce artificial variables;
                // unless there are transient reads w/ the same variable name in the current dag which can
                // lead to invalid reordering if variable consumers are not feeding into the candidate op.
                boolean hasTWrites = hasTransientWriteParents(c);
                boolean moveTWrite = hasTWrites ? HopRewriteUtils.rHasSimpleReadChain(c, getFirstTransientWriteParent(c).getName()) : false;
                String varname = null;
                long rlen = c.getDim1();
                long clen = c.getDim2();
                long nnz = c.getNnz();
                UpdateType update = c.getUpdateType();
                int brlen = c.getRowsInBlock();
                int bclen = c.getColsInBlock();
                if (// reuse existing transient_write
                hasTWrites && moveTWrite) {
                    Hop twrite = getFirstTransientWriteParent(c);
                    varname = twrite.getName();
                    // create new transient read
                    DataOp tread = new DataOp(varname, c.getDataType(), c.getValueType(), DataOpTypes.TRANSIENTREAD, null, rlen, clen, nnz, update, brlen, bclen);
                    tread.setVisited();
                    HopRewriteUtils.copyLineNumbers(c, tread);
                    // replace data-dependent operator with transient read
                    ArrayList<Hop> parents = new ArrayList<>(c.getParent());
                    for (int i = 0; i < parents.size(); i++) {
                        // prevent concurrent modification by index access
                        Hop parent = parents.get(i);
                        if (!candChilds.contains(parent)) {
                            // anomaly filter
                            if (parent != twrite)
                                HopRewriteUtils.replaceChildReference(parent, c, tread);
                            else
                                sb.getHops().remove(parent);
                        }
                    }
                    // add data-dependent operator sub dag to first statement block
                    sb1hops.add(twrite);
                } else // create transient write to artificial variables
                {
                    varname = createCutVarName(false);
                    // create new transient read
                    DataOp tread = new DataOp(varname, c.getDataType(), c.getValueType(), DataOpTypes.TRANSIENTREAD, null, rlen, clen, nnz, update, brlen, bclen);
                    tread.setVisited();
                    HopRewriteUtils.copyLineNumbers(c, tread);
                    // replace data-dependent operator with transient read
                    ArrayList<Hop> parents = new ArrayList<>(c.getParent());
                    for (int i = 0; i < parents.size(); i++) {
                        // prevent concurrent modification by index access
                        Hop parent = parents.get(i);
                        if (// anomaly filter
                        !candChilds.contains(parent))
                            HopRewriteUtils.replaceChildReference(parent, c, tread);
                    }
                    // add data-dependent operator sub dag to first statement block
                    DataOp twrite = new DataOp(varname, c.getDataType(), c.getValueType(), c, DataOpTypes.TRANSIENTWRITE, null);
                    twrite.setVisited();
                    twrite.setOutputParams(rlen, clen, nnz, update, brlen, bclen);
                    HopRewriteUtils.copyLineNumbers(c, twrite);
                    sb1hops.add(twrite);
                }
                // update live in and out of new statement block (for piggybacking)
                DataIdentifier diVar = new DataIdentifier(varname);
                diVar.setDimensions(rlen, clen);
                diVar.setBlockDimensions(brlen, bclen);
                diVar.setDataType(c.getDataType());
                diVar.setValueType(c.getValueType());
                sb1.liveOut().addVariable(varname, new DataIdentifier(diVar));
                sb.liveIn().addVariable(varname, new DataIdentifier(diVar));
            }
            // ensure disjoint operators across DAGs (prevent replicated operations)
            handleReplicatedOperators(sb1hops, sb.getHops(), sb1.liveOut(), sb.liveIn());
            // deep copy new dag (in order to prevent any dangling references)
            sb1.setHops(Recompiler.deepCopyHopsDag(sb1hops));
            sb1.updateRecompilationFlag();
            // avoid later merge by other rewrites
            sb1.setSplitDag(true);
            // recursive application of rewrite rule (in case of multiple data dependent operators
            // with data dependencies in between each other)
            List<StatementBlock> tmp = rewriteStatementBlock(sb1, state);
            // add new statement blocks to output
            // statement block with data dependent hops
            ret.addAll(tmp);
            // statement block with remaining hops
            ret.add(sb);
            // avoid later merge by other rewrites
            sb.setSplitDag(true);
        } catch (Exception ex) {
            throw new HopsException("Failed to split hops dag for data dependent operators with unknown size.", ex);
        }
        LOG.debug("Applied splitDagDataDependentOperators (lines " + sb.getBeginLine() + "-" + sb.getEndLine() + ").");
    } else // keep original hop dag
    {
        ret.add(sb);
    }
    return ret;
}
Also used : DataIdentifier(org.apache.sysml.parser.DataIdentifier) ArrayList(java.util.ArrayList) Hop(org.apache.sysml.hops.Hop) HopsException(org.apache.sysml.hops.HopsException) UpdateType(org.apache.sysml.runtime.controlprogram.caching.MatrixObject.UpdateType) HopsException(org.apache.sysml.hops.HopsException) VariableSet(org.apache.sysml.parser.VariableSet) DataOp(org.apache.sysml.hops.DataOp) StatementBlock(org.apache.sysml.parser.StatementBlock) HashSet(java.util.HashSet)

Example 52 with DataOp

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

the class RewriteSplitDagDataDependentOperators method rCollectDataDependentOperators.

private void rCollectDataDependentOperators(Hop hop, ArrayList<Hop> cand) {
    if (hop.isVisited())
        return;
    // prevent unnecessary dag split (dims known or no consumer operations)
    boolean noSplitRequired = (hop.dimsKnown() || HopRewriteUtils.hasOnlyWriteParents(hop, true, true));
    boolean investigateChilds = true;
    // #1 removeEmpty
    if (hop instanceof ParameterizedBuiltinOp && ((ParameterizedBuiltinOp) hop).getOp() == ParamBuiltinOp.RMEMPTY && !noSplitRequired && !(hop.getParent().size() == 1 && hop.getParent().get(0) instanceof TernaryOp && ((TernaryOp) hop.getParent().get(0)).isMatrixIgnoreZeroRewriteApplicable())) {
        ParameterizedBuiltinOp pbhop = (ParameterizedBuiltinOp) hop;
        cand.add(pbhop);
        investigateChilds = false;
        // keep interesting consumer information, flag hops accordingly
        boolean noEmptyBlocks = true;
        boolean onlyPMM = true;
        boolean diagInput = pbhop.isTargetDiagInput();
        for (Hop p : hop.getParent()) {
            // list of operators without need for empty blocks to be extended as needed
            noEmptyBlocks &= (p instanceof AggBinaryOp && hop == p.getInput().get(0) || HopRewriteUtils.isUnary(p, OpOp1.NROW));
            onlyPMM &= (p instanceof AggBinaryOp && hop == p.getInput().get(0));
        }
        pbhop.setOutputEmptyBlocks(!noEmptyBlocks);
        if (onlyPMM && diagInput) {
            if (ConfigurationManager.isDynamicRecompilation())
                pbhop.setOutputPermutationMatrix(true);
            for (Hop p : hop.getParent()) ((AggBinaryOp) p).setHasLeftPMInput(true);
        }
    }
    // #2 ctable with unknown dims
    if (HopRewriteUtils.isTernary(hop, OpOp3.CTABLE) && // dims not provided
    hop.getInput().size() < 4 && !noSplitRequired) {
        cand.add(hop);
        investigateChilds = false;
        // keep interesting consumer information, flag hops accordingly
        boolean onlyPMM = true;
        for (Hop p : hop.getParent()) {
            onlyPMM &= (p instanceof AggBinaryOp && hop == p.getInput().get(0));
        }
        if (onlyPMM && HopRewriteUtils.isBasic1NSequence(hop.getInput().get(0)))
            hop.setOutputEmptyBlocks(false);
    }
    // #3 orderby childs computed in same DAG
    if (HopRewriteUtils.isReorg(hop, ReOrgOp.SORT)) {
        // params 'decreasing' / 'indexreturn'
        for (int i = 2; i <= 3; i++) {
            Hop c = hop.getInput().get(i);
            if (!(c instanceof LiteralOp || c instanceof DataOp)) {
                cand.add(c);
                c.setVisited();
                investigateChilds = false;
            }
        }
    }
    // #4 second-order eval function
    if (HopRewriteUtils.isNary(hop, OpOpN.EVAL) && !noSplitRequired) {
        cand.add(hop);
        investigateChilds = false;
    }
    // otherwise, processed by recursive rule application)
    if (investigateChilds && hop.getInput() != null)
        for (Hop c : hop.getInput()) rCollectDataDependentOperators(c, cand);
    hop.setVisited();
}
Also used : ParameterizedBuiltinOp(org.apache.sysml.hops.ParameterizedBuiltinOp) AggBinaryOp(org.apache.sysml.hops.AggBinaryOp) Hop(org.apache.sysml.hops.Hop) LiteralOp(org.apache.sysml.hops.LiteralOp) DataOp(org.apache.sysml.hops.DataOp) TernaryOp(org.apache.sysml.hops.TernaryOp)

Example 53 with DataOp

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

the class InterProceduralAnalysis method populateLocalVariableMapForFunctionCall.

private static void populateLocalVariableMapForFunctionCall(FunctionStatement fstmt, FunctionOp fop, LocalVariableMap callvars, LocalVariableMap vars, FunctionCallSizeInfo fcallSizes) {
    ArrayList<DataIdentifier> inputVars = fstmt.getInputParams();
    ArrayList<Hop> inputOps = fop.getInput();
    String fkey = fop.getFunctionKey();
    for (int i = 0; i < inputVars.size(); i++) {
        // create mapping between input hops and vars
        DataIdentifier dat = inputVars.get(i);
        Hop input = inputOps.get(i);
        if (input.getDataType() == DataType.MATRIX) {
            // propagate matrix characteristics
            MatrixObject mo = new MatrixObject(ValueType.DOUBLE, null);
            MatrixCharacteristics mc = new MatrixCharacteristics(input.getDim1(), input.getDim2(), ConfigurationManager.getBlocksize(), ConfigurationManager.getBlocksize(), fcallSizes.isSafeNnz(fkey, i) ? input.getNnz() : -1);
            MetaDataFormat meta = new MetaDataFormat(mc, null, null);
            mo.setMetaData(meta);
            vars.put(dat.getName(), mo);
        } else if (input.getDataType() == DataType.SCALAR) {
            // (for multiple calls, literal equivalence already checked)
            if (input instanceof LiteralOp) {
                vars.put(dat.getName(), ScalarObjectFactory.createScalarObject(input.getValueType(), (LiteralOp) input));
            } else // and input scalar is existing variable in symbol table
            if (PROPAGATE_SCALAR_VARS_INTO_FUN && fcallSizes.getFunctionCallCount(fkey) == 1 && input instanceof DataOp) {
                Data scalar = callvars.get(input.getName());
                if (scalar != null && scalar instanceof ScalarObject) {
                    vars.put(dat.getName(), scalar);
                }
            }
        }
    }
}
Also used : MetaDataFormat(org.apache.sysml.runtime.matrix.MetaDataFormat) DataIdentifier(org.apache.sysml.parser.DataIdentifier) MatrixObject(org.apache.sysml.runtime.controlprogram.caching.MatrixObject) Hop(org.apache.sysml.hops.Hop) Data(org.apache.sysml.runtime.instructions.cp.Data) MatrixCharacteristics(org.apache.sysml.runtime.matrix.MatrixCharacteristics) ScalarObject(org.apache.sysml.runtime.instructions.cp.ScalarObject) LiteralOp(org.apache.sysml.hops.LiteralOp) DataOp(org.apache.sysml.hops.DataOp)

Example 54 with DataOp

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

the class LiteralReplacement method replaceLiteralFullUnaryAggregateRightIndexing.

private static LiteralOp replaceLiteralFullUnaryAggregateRightIndexing(Hop c, LocalVariableMap vars) {
    LiteralOp ret = null;
    // full unary aggregate w/ indexed matrix less than 10^6 cells
    if (c instanceof AggUnaryOp && isReplaceableUnaryAggregate((AggUnaryOp) c) && c.getInput().get(0) instanceof IndexingOp && c.getInput().get(0).getInput().get(0) instanceof DataOp) {
        IndexingOp rix = (IndexingOp) c.getInput().get(0);
        Hop data = rix.getInput().get(0);
        Hop rl = rix.getInput().get(1);
        Hop ru = rix.getInput().get(2);
        Hop cl = rix.getInput().get(3);
        Hop cu = rix.getInput().get(4);
        if (data instanceof DataOp && vars.keySet().contains(data.getName()) && isIntValueDataLiteral(rl, vars) && isIntValueDataLiteral(ru, vars) && isIntValueDataLiteral(cl, vars) && isIntValueDataLiteral(cu, vars)) {
            long rlval = getIntValueDataLiteral(rl, vars);
            long ruval = getIntValueDataLiteral(ru, vars);
            long clval = getIntValueDataLiteral(cl, vars);
            long cuval = getIntValueDataLiteral(cu, vars);
            MatrixObject mo = (MatrixObject) vars.get(data.getName());
            // dimensions might not have been updated during recompile
            if (mo.getNumRows() * mo.getNumColumns() < REPLACE_LITERALS_MAX_MATRIX_SIZE) {
                MatrixBlock mBlock = mo.acquireRead();
                MatrixBlock mBlock2 = mBlock.slice((int) (rlval - 1), (int) (ruval - 1), (int) (clval - 1), (int) (cuval - 1), new MatrixBlock());
                double value = replaceUnaryAggregate((AggUnaryOp) c, mBlock2);
                mo.release();
                // literal substitution (always double)
                ret = new LiteralOp(value);
            }
        }
    }
    return ret;
}
Also used : MatrixBlock(org.apache.sysml.runtime.matrix.data.MatrixBlock) MatrixObject(org.apache.sysml.runtime.controlprogram.caching.MatrixObject) AggUnaryOp(org.apache.sysml.hops.AggUnaryOp) IndexingOp(org.apache.sysml.hops.IndexingOp) Hop(org.apache.sysml.hops.Hop) LiteralOp(org.apache.sysml.hops.LiteralOp) DataOp(org.apache.sysml.hops.DataOp)

Example 55 with DataOp

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

the class LiteralReplacement method replaceLiteralValueTypeCastRightIndexing.

private static LiteralOp replaceLiteralValueTypeCastRightIndexing(Hop c, LocalVariableMap vars) {
    LiteralOp ret = null;
    // as.scalar/right indexing w/ literals/vars and matrix less than 10^6 cells
    if (c instanceof UnaryOp && ((UnaryOp) c).getOp() == OpOp1.CAST_AS_SCALAR && c.getInput().get(0) instanceof IndexingOp && c.getInput().get(0).getDataType() == DataType.MATRIX) {
        IndexingOp rix = (IndexingOp) c.getInput().get(0);
        Hop data = rix.getInput().get(0);
        Hop rl = rix.getInput().get(1);
        Hop ru = rix.getInput().get(2);
        Hop cl = rix.getInput().get(3);
        Hop cu = rix.getInput().get(4);
        if (rix.dimsKnown() && rix.getDim1() == 1 && rix.getDim2() == 1 && data instanceof DataOp && vars.keySet().contains(data.getName()) && isIntValueDataLiteral(rl, vars) && isIntValueDataLiteral(ru, vars) && isIntValueDataLiteral(cl, vars) && isIntValueDataLiteral(cu, vars)) {
            long rlval = getIntValueDataLiteral(rl, vars);
            long clval = getIntValueDataLiteral(cl, vars);
            MatrixObject mo = (MatrixObject) vars.get(data.getName());
            // dimensions might not have been updated during recompile
            if (mo.getNumRows() * mo.getNumColumns() < REPLACE_LITERALS_MAX_MATRIX_SIZE) {
                MatrixBlock mBlock = mo.acquireRead();
                double value = mBlock.getValue((int) rlval - 1, (int) clval - 1);
                mo.release();
                // literal substitution (always double)
                ret = new LiteralOp(value);
            }
        }
    }
    return ret;
}
Also used : MatrixBlock(org.apache.sysml.runtime.matrix.data.MatrixBlock) AggUnaryOp(org.apache.sysml.hops.AggUnaryOp) UnaryOp(org.apache.sysml.hops.UnaryOp) MatrixObject(org.apache.sysml.runtime.controlprogram.caching.MatrixObject) IndexingOp(org.apache.sysml.hops.IndexingOp) 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