Search in sources :

Example 41 with DataOp

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

the class GDFEnumOptimizer method costRuntimePlan.

private static double costRuntimePlan(Plan p) throws DMLRuntimeException {
    Program prog = p.getNode().getProgram();
    if (prog == null)
        throw new DMLRuntimeException("Program not available for runtime plan costing.");
    //put data flow configuration into program
    rSetRuntimePlanConfig(p, new HashMap<Long, Plan>());
    double costs = -1;
    if (COST_FULL_PROGRAMS || (p.getNode().getHop() == null || p.getNode().getProgramBlock() == null)) {
        //recompile entire runtime program
        Recompiler.recompileProgramBlockHierarchy(prog.getProgramBlocks(), new LocalVariableMap(), 0, false);
        _compiledPlans++;
        //cost entire runtime program
        ExecutionContext ec = ExecutionContextFactory.createContext(prog);
        costs = CostEstimationWrapper.getTimeEstimate(prog, ec);
    } else {
        Hop currentHop = p.getNode().getHop();
        ProgramBlock pb = p.getNode().getProgramBlock();
        try {
            //keep the old dag roots
            ArrayList<Hop> oldRoots = pb.getStatementBlock().get_hops();
            Hop tmpHop = null;
            if (!(currentHop instanceof DataOp && ((DataOp) currentHop).isWrite())) {
                ArrayList<Hop> newRoots = new ArrayList<Hop>();
                tmpHop = new DataOp("_tmp", currentHop.getDataType(), currentHop.getValueType(), currentHop, DataOpTypes.TRANSIENTWRITE, "tmp");
                //ensure recursive visitstatus reset on recompile
                tmpHop.setVisited();
                newRoots.add(tmpHop);
                pb.getStatementBlock().set_hops(newRoots);
            }
            //recompile modified runtime program
            Recompiler.recompileProgramBlockHierarchy(prog.getProgramBlocks(), new LocalVariableMap(), 0, false);
            _compiledPlans++;
            //cost partial runtime program up to current hop
            ExecutionContext ec = ExecutionContextFactory.createContext(prog);
            costs = CostEstimationWrapper.getTimeEstimate(prog, ec);
            //restore original hop dag
            if (tmpHop != null)
                HopRewriteUtils.removeChildReference(tmpHop, currentHop);
            pb.getStatementBlock().set_hops(oldRoots);
        } catch (HopsException ex) {
            throw new DMLRuntimeException(ex);
        }
    }
    //release forced data flow configuration from program
    rResetRuntimePlanConfig(p, new HashMap<Long, Plan>());
    _costedPlans++;
    return costs;
}
Also used : Program(org.apache.sysml.runtime.controlprogram.Program) Hop(org.apache.sysml.hops.Hop) ArrayList(java.util.ArrayList) HopsException(org.apache.sysml.hops.HopsException) DMLRuntimeException(org.apache.sysml.runtime.DMLRuntimeException) ExecutionContext(org.apache.sysml.runtime.controlprogram.context.ExecutionContext) LocalVariableMap(org.apache.sysml.runtime.controlprogram.LocalVariableMap) ProgramBlock(org.apache.sysml.runtime.controlprogram.ProgramBlock) DataOp(org.apache.sysml.hops.DataOp)

Example 42 with DataOp

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

the class GDFEnumOptimizer method rSetRuntimePlanConfig.

private static void rSetRuntimePlanConfig(Plan p, HashMap<Long, Plan> memo) {
    ExecType CLUSTER = OptimizerUtils.isSparkExecutionMode() ? ExecType.SPARK : ExecType.MR;
    //basic memoization including containment check 
    if (memo.containsKey(p.getNode().getID())) {
        Plan pmemo = memo.get(p.getNode().getID());
        if (!p.getInterestingProperties().equals(pmemo.getInterestingProperties())) {
            //TODO this would require additional cleanup in special cases
            if (_resolve.resolveMismatch(pmemo.getRewriteConfig(), p.getRewriteConfig()))
                memo.put(p.getNode().getID(), p);
            //logging of encounter plan mismatch
            LOG.warn("Configuration mismatch on shared node (" + p.getNode().getHop().getHopID() + "). Falling back to heuristic '" + _resolve.getName() + "'.");
            LOG.warn(p.getInterestingProperties().toString());
            LOG.warn(memo.get(p.getNode().getID()).getInterestingProperties());
            _planMismatches++;
            return;
        }
    }
    //set plan configuration
    Hop hop = p.getNode().getHop();
    if (hop != null) {
        RewriteConfig rc = p.getRewriteConfig();
        //set exec type
        hop.setForcedExecType(rc.getExecType());
        //set blocksizes and reblock
        hop.setRowsInBlock(rc.getBlockSize());
        hop.setColsInBlock(rc.getBlockSize());
        if (//after blocksize update
        rc.getExecType() == CLUSTER) {
            //TODO double check dataop condition - side effect from plan validity
            boolean reblock = HopRewriteUtils.alwaysRequiresReblock(hop) || (hop.hasMatrixInputWithDifferentBlocksizes() && !(hop instanceof DataOp));
            hop.setRequiresReblock(reblock);
        } else
            hop.setRequiresReblock(false);
    }
    //process childs
    if (p.getChilds() != null)
        for (Plan c : p.getChilds()) rSetRuntimePlanConfig(c, memo);
    //memoization (mark as processed)
    memo.put(p.getNode().getID(), p);
}
Also used : Hop(org.apache.sysml.hops.Hop) ExecType(org.apache.sysml.lops.LopProperties.ExecType) DataOp(org.apache.sysml.hops.DataOp)

Example 43 with DataOp

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

the class DMLTranslator method processDataExpression.

/**
 * Construct Hops from parse tree : Process ParameterizedExpression in a
 * read/write/rand statement
 *
 * @param source data expression
 * @param target data identifier
 * @param hops map of high-level operators
 * @return high-level operator
 */
private Hop processDataExpression(DataExpression source, DataIdentifier target, HashMap<String, Hop> hops) {
    // this expression has multiple "named" parameters
    HashMap<String, Hop> paramHops = new HashMap<>();
    // -- construct hops for all input parameters
    // -- store them in hashmap so that their "name"s are maintained
    Hop pHop = null;
    for (String paramName : source.getVarParams().keySet()) {
        pHop = processExpression(source.getVarParam(paramName), null, hops);
        paramHops.put(paramName, pHop);
    }
    Hop currBuiltinOp = null;
    if (target == null) {
        target = createTarget(source);
    }
    // construct hop based on opcode
    switch(source.getOpCode()) {
        case READ:
            currBuiltinOp = new DataOp(target.getName(), target.getDataType(), target.getValueType(), DataOpTypes.PERSISTENTREAD, paramHops);
            ((DataOp) currBuiltinOp).setFileName(((StringIdentifier) source.getVarParam(DataExpression.IO_FILENAME)).getValue());
            break;
        case WRITE:
            currBuiltinOp = new DataOp(target.getName(), target.getDataType(), target.getValueType(), DataOpTypes.PERSISTENTWRITE, hops.get(target.getName()), paramHops);
            break;
        case RAND:
            // We limit RAND_MIN, RAND_MAX, RAND_SPARSITY, RAND_SEED, and RAND_PDF to be constants
            DataGenMethod method = (paramHops.get(DataExpression.RAND_MIN).getValueType() == ValueType.STRING) ? DataGenMethod.SINIT : DataGenMethod.RAND;
            currBuiltinOp = new DataGenOp(method, target, paramHops);
            break;
        case MATRIX:
            ArrayList<Hop> tmp = new ArrayList<>();
            tmp.add(0, paramHops.get(DataExpression.RAND_DATA));
            tmp.add(1, paramHops.get(DataExpression.RAND_ROWS));
            tmp.add(2, paramHops.get(DataExpression.RAND_COLS));
            tmp.add(3, paramHops.get(DataExpression.RAND_BY_ROW));
            currBuiltinOp = new ReorgOp(target.getName(), target.getDataType(), target.getValueType(), ReOrgOp.RESHAPE, tmp);
            break;
        default:
            LOG.error(source.printErrorLocation() + "processDataExpression():: Unknown operation:  " + source.getOpCode());
            throw new ParseException(source.printErrorLocation() + "processDataExpression():: Unknown operation:  " + source.getOpCode());
    }
    // set identifier meta data (incl dimensions and blocksizes)
    setIdentifierParams(currBuiltinOp, source.getOutput());
    if (source.getOpCode() == DataExpression.DataOp.READ)
        ((DataOp) currBuiltinOp).setInputBlockSizes(target.getRowsInBlock(), target.getColumnsInBlock());
    currBuiltinOp.setParseInfo(source);
    return currBuiltinOp;
}
Also used : HashMap(java.util.HashMap) DataGenOp(org.apache.sysml.hops.DataGenOp) Hop(org.apache.sysml.hops.Hop) ArrayList(java.util.ArrayList) ReorgOp(org.apache.sysml.hops.ReorgOp) DataGenMethod(org.apache.sysml.hops.Hop.DataGenMethod) DataOp(org.apache.sysml.hops.DataOp)

Example 44 with DataOp

use of org.apache.sysml.hops.DataOp in project incubator-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 45 with DataOp

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

the class RewriteConstantFolding method evalScalarOperation.

/**
 * In order to (1) prevent unexpected side effects from constant folding and
 * (2) for simplicity with regard to arbitrary value type combinations,
 * we use the same compilation and runtime for constant folding as we would
 * use for actual instruction execution.
 *
 * @param bop high-level operator
 * @return literal op
 */
private LiteralOp evalScalarOperation(Hop bop) {
    // Timing time = new Timing( true );
    DataOp tmpWrite = new DataOp(TMP_VARNAME, bop.getDataType(), bop.getValueType(), bop, DataOpTypes.TRANSIENTWRITE, TMP_VARNAME);
    // generate runtime instruction
    Dag<Lop> dag = new Dag<>();
    // prevent lops reuse
    Recompiler.rClearLops(tmpWrite);
    // reconstruct lops
    Lop lops = tmpWrite.constructLops();
    lops.addToDag(dag);
    ArrayList<Instruction> inst = dag.getJobs(null, ConfigurationManager.getDMLConfig());
    // execute instructions
    ExecutionContext ec = getExecutionContext();
    ProgramBlock pb = getProgramBlock();
    pb.setInstructions(inst);
    pb.execute(ec);
    // get scalar result (check before invocation) and create literal according
    // to observed scalar output type (not hop type) for runtime consistency
    ScalarObject so = (ScalarObject) ec.getVariable(TMP_VARNAME);
    LiteralOp literal = null;
    switch(so.getValueType()) {
        case DOUBLE:
            literal = new LiteralOp(so.getDoubleValue());
            break;
        case INT:
            literal = new LiteralOp(so.getLongValue());
            break;
        case BOOLEAN:
            literal = new LiteralOp(so.getBooleanValue());
            break;
        case STRING:
            literal = new LiteralOp(so.getStringValue());
            break;
        default:
            throw new HopsException("Unsupported literal value type: " + bop.getValueType());
    }
    // cleanup
    tmpWrite.getInput().clear();
    bop.getParent().remove(tmpWrite);
    pb.setInstructions(null);
    ec.getVariables().removeAll();
    // set literal properties (scalar)
    HopRewriteUtils.setOutputParametersForScalar(literal);
    return literal;
}
Also used : ScalarObject(org.apache.sysml.runtime.instructions.cp.ScalarObject) ExecutionContext(org.apache.sysml.runtime.controlprogram.context.ExecutionContext) ProgramBlock(org.apache.sysml.runtime.controlprogram.ProgramBlock) Dag(org.apache.sysml.lops.compile.Dag) HopsException(org.apache.sysml.hops.HopsException) Lop(org.apache.sysml.lops.Lop) Instruction(org.apache.sysml.runtime.instructions.Instruction) 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