Search in sources :

Example 26 with UnaryOp

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

the class DMLTranslator method processLeftIndexedExpression.

private Hop processLeftIndexedExpression(Expression source, IndexedIdentifier target, HashMap<String, Hop> hops) {
    // process target indexed expressions
    Hop rowLowerHops = null, rowUpperHops = null, colLowerHops = null, colUpperHops = null;
    if (target.getRowLowerBound() != null)
        rowLowerHops = processExpression(target.getRowLowerBound(), null, hops);
    else
        rowLowerHops = new LiteralOp(1);
    if (target.getRowUpperBound() != null)
        rowUpperHops = processExpression(target.getRowUpperBound(), null, hops);
    else {
        if (target.getDim1() != -1)
            rowUpperHops = new LiteralOp(target.getOrigDim1());
        else {
            rowUpperHops = new UnaryOp(target.getName(), DataType.SCALAR, ValueType.INT, Hop.OpOp1.NROW, hops.get(target.getName()));
            rowUpperHops.setParseInfo(target);
        }
    }
    if (target.getColLowerBound() != null)
        colLowerHops = processExpression(target.getColLowerBound(), null, hops);
    else
        colLowerHops = new LiteralOp(1);
    if (target.getColUpperBound() != null)
        colUpperHops = processExpression(target.getColUpperBound(), null, hops);
    else {
        if (target.getDim2() != -1)
            colUpperHops = new LiteralOp(target.getOrigDim2());
        else
            colUpperHops = new UnaryOp(target.getName(), DataType.SCALAR, ValueType.INT, Hop.OpOp1.NCOL, hops.get(target.getName()));
    }
    // process the source expression to get source Hops
    Hop sourceOp = processExpression(source, target, hops);
    // process the target to get targetHops
    Hop targetOp = hops.get(target.getName());
    if (targetOp == null) {
        LOG.error(target.printErrorLocation() + " must define matrix " + target.getName() + " before indexing operations are allowed ");
        throw new ParseException(target.printErrorLocation() + " must define matrix " + target.getName() + " before indexing operations are allowed ");
    }
    if (sourceOp.getDataType().isMatrix() && source.getOutput().getDataType().isScalar())
        sourceOp.setDataType(DataType.SCALAR);
    Hop leftIndexOp = new LeftIndexingOp(target.getName(), target.getDataType(), ValueType.DOUBLE, targetOp, sourceOp, rowLowerHops, rowUpperHops, colLowerHops, colUpperHops, target.getRowLowerEqualsUpper(), target.getColLowerEqualsUpper());
    setIdentifierParams(leftIndexOp, target);
    leftIndexOp.setParseInfo(target);
    leftIndexOp.setDim1(target.getOrigDim1());
    leftIndexOp.setDim2(target.getOrigDim2());
    return leftIndexOp;
}
Also used : AggUnaryOp(org.apache.sysml.hops.AggUnaryOp) UnaryOp(org.apache.sysml.hops.UnaryOp) Hop(org.apache.sysml.hops.Hop) LiteralOp(org.apache.sysml.hops.LiteralOp) LeftIndexingOp(org.apache.sysml.hops.LeftIndexingOp)

Example 27 with UnaryOp

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

the class DMLTranslator method processBuiltinFunctionExpression.

/**
 * Construct Hops from parse tree : Process BuiltinFunction Expression in an
 * assignment statement
 *
 * @param source built-in function expression
 * @param target data identifier
 * @param hops map of high-level operators
 * @return high-level operator
 */
private Hop processBuiltinFunctionExpression(BuiltinFunctionExpression source, DataIdentifier target, HashMap<String, Hop> hops) {
    Hop expr = processExpression(source.getFirstExpr(), null, hops);
    Hop expr2 = null;
    if (source.getSecondExpr() != null) {
        expr2 = processExpression(source.getSecondExpr(), null, hops);
    }
    Hop expr3 = null;
    if (source.getThirdExpr() != null) {
        expr3 = processExpression(source.getThirdExpr(), null, hops);
    }
    Hop currBuiltinOp = null;
    if (target == null) {
        target = createTarget(source);
    }
    // Construct the hop based on the type of Builtin function
    switch(source.getOpCode()) {
        case EVAL:
            currBuiltinOp = new NaryOp(target.getName(), target.getDataType(), target.getValueType(), OpOpN.EVAL, processAllExpressions(source.getAllExpr(), hops));
            break;
        case COLSUM:
            currBuiltinOp = new AggUnaryOp(target.getName(), target.getDataType(), target.getValueType(), AggOp.SUM, Direction.Col, expr);
            break;
        case COLMAX:
            currBuiltinOp = new AggUnaryOp(target.getName(), target.getDataType(), target.getValueType(), AggOp.MAX, Direction.Col, expr);
            break;
        case COLMIN:
            currBuiltinOp = new AggUnaryOp(target.getName(), target.getDataType(), target.getValueType(), AggOp.MIN, Direction.Col, expr);
            break;
        case COLMEAN:
            currBuiltinOp = new AggUnaryOp(target.getName(), target.getDataType(), target.getValueType(), AggOp.MEAN, Direction.Col, expr);
            break;
        case COLSD:
            // colStdDevs = sqrt(colVariances)
            currBuiltinOp = new AggUnaryOp(target.getName(), target.getDataType(), target.getValueType(), AggOp.VAR, Direction.Col, expr);
            currBuiltinOp = new UnaryOp(target.getName(), target.getDataType(), target.getValueType(), Hop.OpOp1.SQRT, currBuiltinOp);
            break;
        case COLVAR:
            currBuiltinOp = new AggUnaryOp(target.getName(), target.getDataType(), target.getValueType(), AggOp.VAR, Direction.Col, expr);
            break;
        case ROWSUM:
            currBuiltinOp = new AggUnaryOp(target.getName(), target.getDataType(), target.getValueType(), AggOp.SUM, Direction.Row, expr);
            break;
        case ROWMAX:
            currBuiltinOp = new AggUnaryOp(target.getName(), target.getDataType(), target.getValueType(), AggOp.MAX, Direction.Row, expr);
            break;
        case ROWINDEXMAX:
            currBuiltinOp = new AggUnaryOp(target.getName(), target.getDataType(), target.getValueType(), AggOp.MAXINDEX, Direction.Row, expr);
            break;
        case ROWINDEXMIN:
            currBuiltinOp = new AggUnaryOp(target.getName(), target.getDataType(), target.getValueType(), AggOp.MININDEX, Direction.Row, expr);
            break;
        case ROWMIN:
            currBuiltinOp = new AggUnaryOp(target.getName(), target.getDataType(), target.getValueType(), AggOp.MIN, Direction.Row, expr);
            break;
        case ROWMEAN:
            currBuiltinOp = new AggUnaryOp(target.getName(), target.getDataType(), target.getValueType(), AggOp.MEAN, Direction.Row, expr);
            break;
        case ROWSD:
            // rowStdDevs = sqrt(rowVariances)
            currBuiltinOp = new AggUnaryOp(target.getName(), target.getDataType(), target.getValueType(), AggOp.VAR, Direction.Row, expr);
            currBuiltinOp = new UnaryOp(target.getName(), target.getDataType(), target.getValueType(), Hop.OpOp1.SQRT, currBuiltinOp);
            break;
        case ROWVAR:
            currBuiltinOp = new AggUnaryOp(target.getName(), target.getDataType(), target.getValueType(), AggOp.VAR, Direction.Row, expr);
            break;
        case NROW:
            // If the dimensions are available at compile time, then create a LiteralOp (constant propagation)
            // Else create a UnaryOp so that a control program instruction is generated
            long nRows = expr.getDim1();
            if (nRows == -1) {
                currBuiltinOp = new UnaryOp(target.getName(), target.getDataType(), target.getValueType(), Hop.OpOp1.NROW, expr);
            } else {
                currBuiltinOp = new LiteralOp(nRows);
            }
            break;
        case NCOL:
            // If the dimensions are available at compile time, then create a LiteralOp (constant propagation)
            // Else create a UnaryOp so that a control program instruction is generated
            long nCols = expr.getDim2();
            if (nCols == -1) {
                currBuiltinOp = new UnaryOp(target.getName(), target.getDataType(), target.getValueType(), Hop.OpOp1.NCOL, expr);
            } else {
                currBuiltinOp = new LiteralOp(nCols);
            }
            break;
        case LENGTH:
            long nRows2 = expr.getDim1();
            long nCols2 = expr.getDim2();
            /* 
			 * If the dimensions are available at compile time, then create a LiteralOp (constant propagation)
			 * Else create a UnaryOp so that a control program instruction is generated
			 */
            if ((nCols2 == -1) || (nRows2 == -1)) {
                currBuiltinOp = new UnaryOp(target.getName(), target.getDataType(), target.getValueType(), Hop.OpOp1.LENGTH, expr);
            } else {
                long lval = (nCols2 * nRows2);
                currBuiltinOp = new LiteralOp(lval);
            }
            break;
        case SUM:
            currBuiltinOp = new AggUnaryOp(target.getName(), target.getDataType(), target.getValueType(), AggOp.SUM, Direction.RowCol, expr);
            break;
        case MEAN:
            if (expr2 == null) {
                // example: x = mean(Y);
                currBuiltinOp = new AggUnaryOp(target.getName(), target.getDataType(), target.getValueType(), AggOp.MEAN, Direction.RowCol, expr);
            } else {
                // example: x = mean(Y,W);
                // stable weighted mean is implemented by using centralMoment with order = 0
                Hop orderHop = new LiteralOp(0);
                currBuiltinOp = new TernaryOp(target.getName(), target.getDataType(), target.getValueType(), Hop.OpOp3.CENTRALMOMENT, expr, expr2, orderHop);
            }
            break;
        case SD:
            // stdDev = sqrt(variance)
            currBuiltinOp = new AggUnaryOp(target.getName(), target.getDataType(), target.getValueType(), AggOp.VAR, Direction.RowCol, expr);
            HopRewriteUtils.setOutputParametersForScalar(currBuiltinOp);
            currBuiltinOp = new UnaryOp(target.getName(), target.getDataType(), target.getValueType(), Hop.OpOp1.SQRT, currBuiltinOp);
            break;
        case VAR:
            currBuiltinOp = new AggUnaryOp(target.getName(), target.getDataType(), target.getValueType(), AggOp.VAR, Direction.RowCol, expr);
            break;
        case MIN:
            // construct AggUnary for min(X) but BinaryOp for min(X,Y)
            if (expr2 == null) {
                currBuiltinOp = new AggUnaryOp(target.getName(), target.getDataType(), target.getValueType(), AggOp.MIN, Direction.RowCol, expr);
            } else {
                currBuiltinOp = new BinaryOp(target.getName(), target.getDataType(), target.getValueType(), OpOp2.MIN, expr, expr2);
            }
            break;
        case MAX:
            // construct AggUnary for max(X) but BinaryOp for max(X,Y)
            if (expr2 == null) {
                currBuiltinOp = new AggUnaryOp(target.getName(), target.getDataType(), target.getValueType(), AggOp.MAX, Direction.RowCol, expr);
            } else {
                currBuiltinOp = new BinaryOp(target.getName(), target.getDataType(), target.getValueType(), OpOp2.MAX, expr, expr2);
            }
            break;
        case PPRED:
            String sop = ((StringIdentifier) source.getThirdExpr()).getValue();
            sop = sop.replace("\"", "");
            OpOp2 operation;
            if (sop.equalsIgnoreCase(">="))
                operation = OpOp2.GREATEREQUAL;
            else if (sop.equalsIgnoreCase(">"))
                operation = OpOp2.GREATER;
            else if (sop.equalsIgnoreCase("<="))
                operation = OpOp2.LESSEQUAL;
            else if (sop.equalsIgnoreCase("<"))
                operation = OpOp2.LESS;
            else if (sop.equalsIgnoreCase("=="))
                operation = OpOp2.EQUAL;
            else if (sop.equalsIgnoreCase("!="))
                operation = OpOp2.NOTEQUAL;
            else {
                LOG.error(source.printErrorLocation() + "Unknown argument (" + sop + ") for PPRED.");
                throw new ParseException(source.printErrorLocation() + "Unknown argument (" + sop + ") for PPRED.");
            }
            currBuiltinOp = new BinaryOp(target.getName(), target.getDataType(), target.getValueType(), operation, expr, expr2);
            break;
        case PROD:
            currBuiltinOp = new AggUnaryOp(target.getName(), target.getDataType(), target.getValueType(), AggOp.PROD, Direction.RowCol, expr);
            break;
        case TRACE:
            currBuiltinOp = new AggUnaryOp(target.getName(), target.getDataType(), target.getValueType(), AggOp.TRACE, Direction.RowCol, expr);
            break;
        case TRANS:
            currBuiltinOp = new ReorgOp(target.getName(), target.getDataType(), target.getValueType(), Hop.ReOrgOp.TRANSPOSE, expr);
            break;
        case REV:
            currBuiltinOp = new ReorgOp(target.getName(), target.getDataType(), target.getValueType(), Hop.ReOrgOp.REV, expr);
            break;
        case CBIND:
        case RBIND:
            OpOp2 appendOp1 = (source.getOpCode() == BuiltinFunctionOp.CBIND) ? OpOp2.CBIND : OpOp2.RBIND;
            OpOpN appendOp2 = (source.getOpCode() == BuiltinFunctionOp.CBIND) ? OpOpN.CBIND : OpOpN.RBIND;
            currBuiltinOp = (source.getAllExpr().length == 2) ? new BinaryOp(target.getName(), target.getDataType(), target.getValueType(), appendOp1, expr, expr2) : new NaryOp(target.getName(), target.getDataType(), target.getValueType(), appendOp2, processAllExpressions(source.getAllExpr(), hops));
            break;
        case DIAG:
            currBuiltinOp = new ReorgOp(target.getName(), target.getDataType(), target.getValueType(), Hop.ReOrgOp.DIAG, expr);
            break;
        case TABLE:
            // Always a TertiaryOp is created for table().
            // - create a hop for weights, if not provided in the function call.
            int numTableArgs = source._args.length;
            switch(numTableArgs) {
                case 2:
                case 4:
                    // example DML statement: F = ctable(A,B) or F = ctable(A,B,10,15)
                    // here, weight is interpreted as 1.0
                    Hop weightHop = new LiteralOp(1.0);
                    // set dimensions
                    weightHop.setDim1(0);
                    weightHop.setDim2(0);
                    weightHop.setNnz(-1);
                    weightHop.setRowsInBlock(0);
                    weightHop.setColsInBlock(0);
                    if (numTableArgs == 2)
                        currBuiltinOp = new TernaryOp(target.getName(), target.getDataType(), target.getValueType(), OpOp3.CTABLE, expr, expr2, weightHop);
                    else {
                        Hop outDim1 = processExpression(source._args[2], null, hops);
                        Hop outDim2 = processExpression(source._args[3], null, hops);
                        currBuiltinOp = new TernaryOp(target.getName(), target.getDataType(), target.getValueType(), OpOp3.CTABLE, expr, expr2, weightHop, outDim1, outDim2);
                    }
                    break;
                case 3:
                case 5:
                    // example DML statement: F = ctable(A,B,W) or F = ctable(A,B,W,10,15)
                    if (numTableArgs == 3)
                        currBuiltinOp = new TernaryOp(target.getName(), target.getDataType(), target.getValueType(), OpOp3.CTABLE, expr, expr2, expr3);
                    else {
                        Hop outDim1 = processExpression(source._args[3], null, hops);
                        Hop outDim2 = processExpression(source._args[4], null, hops);
                        currBuiltinOp = new TernaryOp(target.getName(), target.getDataType(), target.getValueType(), OpOp3.CTABLE, expr, expr2, expr3, outDim1, outDim2);
                    }
                    break;
                default:
                    throw new ParseException("Invalid number of arguments " + numTableArgs + " to table() function.");
            }
            break;
        // data type casts
        case CAST_AS_SCALAR:
            currBuiltinOp = new UnaryOp(target.getName(), DataType.SCALAR, target.getValueType(), Hop.OpOp1.CAST_AS_SCALAR, expr);
            break;
        case CAST_AS_MATRIX:
            currBuiltinOp = new UnaryOp(target.getName(), DataType.MATRIX, target.getValueType(), Hop.OpOp1.CAST_AS_MATRIX, expr);
            break;
        case CAST_AS_FRAME:
            currBuiltinOp = new UnaryOp(target.getName(), DataType.FRAME, target.getValueType(), Hop.OpOp1.CAST_AS_FRAME, expr);
            break;
        // value type casts
        case CAST_AS_DOUBLE:
            currBuiltinOp = new UnaryOp(target.getName(), target.getDataType(), ValueType.DOUBLE, Hop.OpOp1.CAST_AS_DOUBLE, expr);
            break;
        case CAST_AS_INT:
            currBuiltinOp = new UnaryOp(target.getName(), target.getDataType(), ValueType.INT, Hop.OpOp1.CAST_AS_INT, expr);
            break;
        case CAST_AS_BOOLEAN:
            currBuiltinOp = new UnaryOp(target.getName(), target.getDataType(), ValueType.BOOLEAN, Hop.OpOp1.CAST_AS_BOOLEAN, expr);
            break;
        // Boolean binary
        case XOR:
            currBuiltinOp = new BinaryOp(target.getName(), target.getDataType(), target.getValueType(), Hop.OpOp2.XOR, expr, expr2);
            break;
        case BITWAND:
            currBuiltinOp = new BinaryOp(target.getName(), target.getDataType(), target.getValueType(), OpOp2.BITWAND, expr, expr2);
            break;
        case BITWOR:
            currBuiltinOp = new BinaryOp(target.getName(), target.getDataType(), target.getValueType(), OpOp2.BITWOR, expr, expr2);
            break;
        case BITWXOR:
            currBuiltinOp = new BinaryOp(target.getName(), target.getDataType(), target.getValueType(), OpOp2.BITWXOR, expr, expr2);
            break;
        case BITWSHIFTL:
            currBuiltinOp = new BinaryOp(target.getName(), target.getDataType(), target.getValueType(), OpOp2.BITWSHIFTL, expr, expr2);
            break;
        case BITWSHIFTR:
            currBuiltinOp = new BinaryOp(target.getName(), target.getDataType(), target.getValueType(), OpOp2.BITWSHIFTR, expr, expr2);
            break;
        case ABS:
        case SIN:
        case COS:
        case TAN:
        case ASIN:
        case ACOS:
        case ATAN:
        case SINH:
        case COSH:
        case TANH:
        case SIGN:
        case SQRT:
        case EXP:
        case ROUND:
        case CEIL:
        case FLOOR:
        case CUMSUM:
        case CUMPROD:
        case CUMMIN:
        case CUMMAX:
            Hop.OpOp1 mathOp1;
            switch(source.getOpCode()) {
                case ABS:
                    mathOp1 = Hop.OpOp1.ABS;
                    break;
                case SIN:
                    mathOp1 = Hop.OpOp1.SIN;
                    break;
                case COS:
                    mathOp1 = Hop.OpOp1.COS;
                    break;
                case TAN:
                    mathOp1 = Hop.OpOp1.TAN;
                    break;
                case ASIN:
                    mathOp1 = Hop.OpOp1.ASIN;
                    break;
                case ACOS:
                    mathOp1 = Hop.OpOp1.ACOS;
                    break;
                case ATAN:
                    mathOp1 = Hop.OpOp1.ATAN;
                    break;
                case SINH:
                    mathOp1 = Hop.OpOp1.SINH;
                    break;
                case COSH:
                    mathOp1 = Hop.OpOp1.COSH;
                    break;
                case TANH:
                    mathOp1 = Hop.OpOp1.TANH;
                    break;
                case SIGN:
                    mathOp1 = Hop.OpOp1.SIGN;
                    break;
                case SQRT:
                    mathOp1 = Hop.OpOp1.SQRT;
                    break;
                case EXP:
                    mathOp1 = Hop.OpOp1.EXP;
                    break;
                case ROUND:
                    mathOp1 = Hop.OpOp1.ROUND;
                    break;
                case CEIL:
                    mathOp1 = Hop.OpOp1.CEIL;
                    break;
                case FLOOR:
                    mathOp1 = Hop.OpOp1.FLOOR;
                    break;
                case CUMSUM:
                    mathOp1 = Hop.OpOp1.CUMSUM;
                    break;
                case CUMPROD:
                    mathOp1 = Hop.OpOp1.CUMPROD;
                    break;
                case CUMMIN:
                    mathOp1 = Hop.OpOp1.CUMMIN;
                    break;
                case CUMMAX:
                    mathOp1 = Hop.OpOp1.CUMMAX;
                    break;
                default:
                    LOG.error(source.printErrorLocation() + "processBuiltinFunctionExpression():: Could not find Operation type for builtin function: " + source.getOpCode());
                    throw new ParseException(source.printErrorLocation() + "processBuiltinFunctionExpression():: Could not find Operation type for builtin function: " + source.getOpCode());
            }
            currBuiltinOp = new UnaryOp(target.getName(), target.getDataType(), target.getValueType(), mathOp1, expr);
            break;
        case LOG:
            if (expr2 == null) {
                Hop.OpOp1 mathOp2;
                switch(source.getOpCode()) {
                    case LOG:
                        mathOp2 = Hop.OpOp1.LOG;
                        break;
                    default:
                        LOG.error(source.printErrorLocation() + "processBuiltinFunctionExpression():: Could not find Operation type for builtin function: " + source.getOpCode());
                        throw new ParseException(source.printErrorLocation() + "processBuiltinFunctionExpression():: Could not find Operation type for builtin function: " + source.getOpCode());
                }
                currBuiltinOp = new UnaryOp(target.getName(), target.getDataType(), target.getValueType(), mathOp2, expr);
            } else {
                Hop.OpOp2 mathOp3;
                switch(source.getOpCode()) {
                    case LOG:
                        mathOp3 = Hop.OpOp2.LOG;
                        break;
                    default:
                        LOG.error(source.printErrorLocation() + "processBuiltinFunctionExpression():: Could not find Operation type for builtin function: " + source.getOpCode());
                        throw new ParseException(source.printErrorLocation() + "processBuiltinFunctionExpression():: Could not find Operation type for builtin function: " + source.getOpCode());
                }
                currBuiltinOp = new BinaryOp(target.getName(), target.getDataType(), target.getValueType(), mathOp3, expr, expr2);
            }
            break;
        case MOMENT:
            if (expr3 == null) {
                currBuiltinOp = new BinaryOp(target.getName(), target.getDataType(), target.getValueType(), Hop.OpOp2.CENTRALMOMENT, expr, expr2);
            } else {
                currBuiltinOp = new TernaryOp(target.getName(), target.getDataType(), target.getValueType(), Hop.OpOp3.CENTRALMOMENT, expr, expr2, expr3);
            }
            break;
        case COV:
            if (expr3 == null) {
                currBuiltinOp = new BinaryOp(target.getName(), target.getDataType(), target.getValueType(), Hop.OpOp2.COVARIANCE, expr, expr2);
            } else {
                currBuiltinOp = new TernaryOp(target.getName(), target.getDataType(), target.getValueType(), Hop.OpOp3.COVARIANCE, expr, expr2, expr3);
            }
            break;
        case QUANTILE:
            if (expr3 == null) {
                currBuiltinOp = new BinaryOp(target.getName(), target.getDataType(), target.getValueType(), Hop.OpOp2.QUANTILE, expr, expr2);
            } else {
                currBuiltinOp = new TernaryOp(target.getName(), target.getDataType(), target.getValueType(), Hop.OpOp3.QUANTILE, expr, expr2, expr3);
            }
            break;
        case INTERQUANTILE:
            if (expr3 == null) {
                currBuiltinOp = new BinaryOp(target.getName(), target.getDataType(), target.getValueType(), Hop.OpOp2.INTERQUANTILE, expr, expr2);
            } else {
                currBuiltinOp = new TernaryOp(target.getName(), target.getDataType(), target.getValueType(), Hop.OpOp3.INTERQUANTILE, expr, expr2, expr3);
            }
            break;
        case IQM:
            if (expr2 == null) {
                currBuiltinOp = new UnaryOp(target.getName(), target.getDataType(), target.getValueType(), Hop.OpOp1.IQM, expr);
            } else {
                currBuiltinOp = new BinaryOp(target.getName(), target.getDataType(), target.getValueType(), Hop.OpOp2.IQM, expr, expr2);
            }
            break;
        case MEDIAN:
            if (expr2 == null) {
                currBuiltinOp = new UnaryOp(target.getName(), target.getDataType(), target.getValueType(), Hop.OpOp1.MEDIAN, expr);
            } else {
                currBuiltinOp = new BinaryOp(target.getName(), target.getDataType(), target.getValueType(), Hop.OpOp2.MEDIAN, expr, expr2);
            }
            break;
        case IFELSE:
            currBuiltinOp = new TernaryOp(target.getName(), target.getDataType(), target.getValueType(), Hop.OpOp3.IFELSE, expr, expr2, expr3);
            break;
        case SEQ:
            HashMap<String, Hop> randParams = new HashMap<>();
            randParams.put(Statement.SEQ_FROM, expr);
            randParams.put(Statement.SEQ_TO, expr2);
            randParams.put(Statement.SEQ_INCR, (expr3 != null) ? expr3 : new LiteralOp(1));
            // note incr: default -1 (for from>to) handled during runtime
            currBuiltinOp = new DataGenOp(DataGenMethod.SEQ, target, randParams);
            break;
        case SAMPLE:
            {
                Expression[] in = source.getAllExpr();
                // arguments: range/size/replace/seed; defaults: replace=FALSE
                HashMap<String, Hop> tmpparams = new HashMap<>();
                // range
                tmpparams.put(DataExpression.RAND_MAX, expr);
                tmpparams.put(DataExpression.RAND_ROWS, expr2);
                tmpparams.put(DataExpression.RAND_COLS, new LiteralOp(1));
                if (in.length == 4) {
                    tmpparams.put(DataExpression.RAND_PDF, expr3);
                    Hop seed = processExpression(in[3], null, hops);
                    tmpparams.put(DataExpression.RAND_SEED, seed);
                } else if (in.length == 3) {
                    // check if the third argument is "replace" or "seed"
                    if (expr3.getValueType() == ValueType.BOOLEAN) {
                        tmpparams.put(DataExpression.RAND_PDF, expr3);
                        tmpparams.put(DataExpression.RAND_SEED, new LiteralOp(DataGenOp.UNSPECIFIED_SEED));
                    } else if (expr3.getValueType() == ValueType.INT) {
                        tmpparams.put(DataExpression.RAND_PDF, new LiteralOp(false));
                        tmpparams.put(DataExpression.RAND_SEED, expr3);
                    } else
                        throw new HopsException("Invalid input type " + expr3.getValueType() + " in sample().");
                } else if (in.length == 2) {
                    tmpparams.put(DataExpression.RAND_PDF, new LiteralOp(false));
                    tmpparams.put(DataExpression.RAND_SEED, new LiteralOp(DataGenOp.UNSPECIFIED_SEED));
                }
                currBuiltinOp = new DataGenOp(DataGenMethod.SAMPLE, target, tmpparams);
                break;
            }
        case SOLVE:
            currBuiltinOp = new BinaryOp(target.getName(), target.getDataType(), target.getValueType(), Hop.OpOp2.SOLVE, expr, expr2);
            break;
        case INVERSE:
            currBuiltinOp = new UnaryOp(target.getName(), target.getDataType(), target.getValueType(), Hop.OpOp1.INVERSE, expr);
            break;
        case CHOLESKY:
            currBuiltinOp = new UnaryOp(target.getName(), target.getDataType(), target.getValueType(), Hop.OpOp1.CHOLESKY, expr);
            break;
        case OUTER:
            if (!(expr3 instanceof LiteralOp))
                throw new HopsException("Operator for outer builtin function must be a constant: " + expr3);
            OpOp2 op = Hop.getOpOp2ForOuterVectorOperation(((LiteralOp) expr3).getStringValue());
            if (op == null)
                throw new HopsException("Unsupported outer vector binary operation: " + ((LiteralOp) expr3).getStringValue());
            currBuiltinOp = new BinaryOp(target.getName(), target.getDataType(), target.getValueType(), op, expr, expr2);
            // flag op as specific outer vector operation
            ((BinaryOp) currBuiltinOp).setOuterVectorOperation(true);
            // force size reevaluation according to 'outer' flag otherwise danger of incorrect dims
            currBuiltinOp.refreshSizeInformation();
            break;
        case CONV2D:
            {
                Hop image = expr;
                ArrayList<Hop> inHops1 = getALHopsForConvOp(image, source, 1, hops);
                currBuiltinOp = new ConvolutionOp(target.getName(), target.getDataType(), target.getValueType(), Hop.ConvOp.DIRECT_CONV2D, inHops1);
                setBlockSizeAndRefreshSizeInfo(image, currBuiltinOp);
                break;
            }
        case BIAS_ADD:
            {
                ArrayList<Hop> inHops1 = new ArrayList<>();
                inHops1.add(expr);
                inHops1.add(expr2);
                currBuiltinOp = new ConvolutionOp(target.getName(), target.getDataType(), target.getValueType(), Hop.ConvOp.BIAS_ADD, inHops1);
                setBlockSizeAndRefreshSizeInfo(expr, currBuiltinOp);
                break;
            }
        case BIAS_MULTIPLY:
            {
                ArrayList<Hop> inHops1 = new ArrayList<>();
                inHops1.add(expr);
                inHops1.add(expr2);
                currBuiltinOp = new ConvolutionOp(target.getName(), target.getDataType(), target.getValueType(), Hop.ConvOp.BIAS_MULTIPLY, inHops1);
                setBlockSizeAndRefreshSizeInfo(expr, currBuiltinOp);
                break;
            }
        case AVG_POOL:
        case MAX_POOL:
            {
                Hop image = expr;
                ArrayList<Hop> inHops1 = getALHopsForPoolingForwardIM2COL(image, source, 1, hops);
                if (source.getOpCode() == BuiltinFunctionOp.MAX_POOL)
                    currBuiltinOp = new ConvolutionOp(target.getName(), target.getDataType(), target.getValueType(), Hop.ConvOp.MAX_POOLING, inHops1);
                else
                    currBuiltinOp = new ConvolutionOp(target.getName(), target.getDataType(), target.getValueType(), Hop.ConvOp.AVG_POOLING, inHops1);
                setBlockSizeAndRefreshSizeInfo(image, currBuiltinOp);
                break;
            }
        case AVG_POOL_BACKWARD:
        case MAX_POOL_BACKWARD:
            {
                Hop image = expr;
                // process dout as well
                ArrayList<Hop> inHops1 = getALHopsForConvOpPoolingCOL2IM(image, source, 1, hops);
                if (source.getOpCode() == BuiltinFunctionOp.MAX_POOL_BACKWARD)
                    currBuiltinOp = new ConvolutionOp(target.getName(), target.getDataType(), target.getValueType(), Hop.ConvOp.MAX_POOLING_BACKWARD, inHops1);
                else
                    currBuiltinOp = new ConvolutionOp(target.getName(), target.getDataType(), target.getValueType(), Hop.ConvOp.AVG_POOLING_BACKWARD, inHops1);
                setBlockSizeAndRefreshSizeInfo(image, currBuiltinOp);
                break;
            }
        case CONV2D_BACKWARD_FILTER:
            {
                Hop image = expr;
                ArrayList<Hop> inHops1 = getALHopsForConvOp(image, source, 1, hops);
                currBuiltinOp = new ConvolutionOp(target.getName(), target.getDataType(), target.getValueType(), Hop.ConvOp.DIRECT_CONV2D_BACKWARD_FILTER, inHops1);
                setBlockSizeAndRefreshSizeInfo(image, currBuiltinOp);
                break;
            }
        case CONV2D_BACKWARD_DATA:
            {
                Hop image = expr;
                ArrayList<Hop> inHops1 = getALHopsForConvOp(image, source, 1, hops);
                currBuiltinOp = new ConvolutionOp(target.getName(), target.getDataType(), target.getValueType(), Hop.ConvOp.DIRECT_CONV2D_BACKWARD_DATA, inHops1);
                setBlockSizeAndRefreshSizeInfo(image, currBuiltinOp);
                break;
            }
        default:
            throw new ParseException("Unsupported builtin function type: " + source.getOpCode());
    }
    boolean isConvolution = source.getOpCode() == BuiltinFunctionOp.CONV2D || source.getOpCode() == BuiltinFunctionOp.CONV2D_BACKWARD_DATA || source.getOpCode() == BuiltinFunctionOp.CONV2D_BACKWARD_FILTER || source.getOpCode() == BuiltinFunctionOp.MAX_POOL || source.getOpCode() == BuiltinFunctionOp.MAX_POOL_BACKWARD || source.getOpCode() == BuiltinFunctionOp.AVG_POOL || source.getOpCode() == BuiltinFunctionOp.AVG_POOL_BACKWARD;
    if (!isConvolution) {
        // Since the dimension of output doesnot match that of input variable for these operations
        setIdentifierParams(currBuiltinOp, source.getOutput());
    }
    currBuiltinOp.setParseInfo(source);
    return currBuiltinOp;
}
Also used : OpOpN(org.apache.sysml.hops.Hop.OpOpN) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) OpOp2(org.apache.sysml.hops.Hop.OpOp2) DataGenOp(org.apache.sysml.hops.DataGenOp) ReorgOp(org.apache.sysml.hops.ReorgOp) LiteralOp(org.apache.sysml.hops.LiteralOp) AggBinaryOp(org.apache.sysml.hops.AggBinaryOp) BinaryOp(org.apache.sysml.hops.BinaryOp) AggUnaryOp(org.apache.sysml.hops.AggUnaryOp) UnaryOp(org.apache.sysml.hops.UnaryOp) Hop(org.apache.sysml.hops.Hop) HopsException(org.apache.sysml.hops.HopsException) TernaryOp(org.apache.sysml.hops.TernaryOp) AggUnaryOp(org.apache.sysml.hops.AggUnaryOp) ConvolutionOp(org.apache.sysml.hops.ConvolutionOp) NaryOp(org.apache.sysml.hops.NaryOp) OpOp2(org.apache.sysml.hops.Hop.OpOp2)

Example 28 with UnaryOp

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

the class RewriteForLoopVectorization method vectorizeElementwiseUnary.

private static StatementBlock vectorizeElementwiseUnary(StatementBlock sb, StatementBlock csb, Hop from, Hop to, Hop increment, String itervar) {
    StatementBlock ret = sb;
    // check supported increment values
    if (!(increment instanceof LiteralOp && ((LiteralOp) increment).getDoubleValue() == 1.0)) {
        return ret;
    }
    // check for applicability
    boolean apply = false;
    // row or col
    boolean rowIx = false;
    if (csb.getHops() != null && csb.getHops().size() == 1) {
        Hop root = csb.getHops().get(0);
        if (root.getDataType() == DataType.MATRIX && root.getInput().get(0) instanceof LeftIndexingOp) {
            LeftIndexingOp lix = (LeftIndexingOp) root.getInput().get(0);
            Hop lixlhs = lix.getInput().get(0);
            Hop lixrhs = lix.getInput().get(1);
            if (lixlhs instanceof DataOp && lixrhs instanceof UnaryOp && lixrhs.getInput().get(0) instanceof IndexingOp && lixrhs.getInput().get(0).getInput().get(0) instanceof DataOp) {
                boolean[] tmp = checkLeftAndRightIndexing(lix, (IndexingOp) lixrhs.getInput().get(0), itervar);
                apply = tmp[0];
                rowIx = tmp[1];
            }
        }
    }
    // apply rewrite if possible
    if (apply) {
        Hop root = csb.getHops().get(0);
        LeftIndexingOp lix = (LeftIndexingOp) root.getInput().get(0);
        UnaryOp uop = (UnaryOp) lix.getInput().get(1);
        IndexingOp rix = (IndexingOp) uop.getInput().get(0);
        int index1 = rowIx ? 2 : 4;
        int index2 = rowIx ? 3 : 5;
        // modify left indexing bounds
        HopRewriteUtils.replaceChildReference(lix, lix.getInput().get(index1), from, index1);
        HopRewriteUtils.replaceChildReference(lix, lix.getInput().get(index2), to, index2);
        // modify right indexing
        HopRewriteUtils.replaceChildReference(rix, rix.getInput().get(index1 - 1), from, index1 - 1);
        HopRewriteUtils.replaceChildReference(rix, rix.getInput().get(index2 - 1), to, index2 - 1);
        updateLeftAndRightIndexingSizes(rowIx, lix, rix);
        uop.refreshSizeInformation();
        // after uop update
        lix.refreshSizeInformation();
        ret = csb;
        LOG.debug("Applied vectorizeElementwiseUnaryForLoop.");
    }
    return ret;
}
Also used : AggUnaryOp(org.apache.sysml.hops.AggUnaryOp) UnaryOp(org.apache.sysml.hops.UnaryOp) IndexingOp(org.apache.sysml.hops.IndexingOp) LeftIndexingOp(org.apache.sysml.hops.LeftIndexingOp) Hop(org.apache.sysml.hops.Hop) LiteralOp(org.apache.sysml.hops.LiteralOp) DataOp(org.apache.sysml.hops.DataOp) IfStatementBlock(org.apache.sysml.parser.IfStatementBlock) WhileStatementBlock(org.apache.sysml.parser.WhileStatementBlock) ForStatementBlock(org.apache.sysml.parser.ForStatementBlock) StatementBlock(org.apache.sysml.parser.StatementBlock) LeftIndexingOp(org.apache.sysml.hops.LeftIndexingOp)

Example 29 with UnaryOp

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

the class RewriteForLoopVectorization method vectorizeScalarAggregate.

private static StatementBlock vectorizeScalarAggregate(StatementBlock sb, StatementBlock csb, Hop from, Hop to, Hop increment, String itervar) {
    StatementBlock ret = sb;
    // check missing and supported increment values
    if (!(increment != null && increment instanceof LiteralOp && ((LiteralOp) increment).getDoubleValue() == 1.0)) {
        return ret;
    }
    // check for applicability
    boolean leftScalar = false;
    boolean rightScalar = false;
    // row or col
    boolean rowIx = false;
    if (csb.getHops() != null && csb.getHops().size() == 1) {
        Hop root = csb.getHops().get(0);
        if (root.getDataType() == DataType.SCALAR && root.getInput().get(0) instanceof BinaryOp) {
            BinaryOp bop = (BinaryOp) root.getInput().get(0);
            Hop left = bop.getInput().get(0);
            Hop right = bop.getInput().get(1);
            // check for left scalar plus
            if (HopRewriteUtils.isValidOp(bop.getOp(), MAP_SCALAR_AGGREGATE_SOURCE_OPS) && left instanceof DataOp && left.getDataType() == DataType.SCALAR && root.getName().equals(left.getName()) && right instanceof UnaryOp && ((UnaryOp) right).getOp() == OpOp1.CAST_AS_SCALAR && right.getInput().get(0) instanceof IndexingOp) {
                IndexingOp ix = (IndexingOp) right.getInput().get(0);
                if (ix.isRowLowerEqualsUpper() && ix.getInput().get(1) instanceof DataOp && ix.getInput().get(1).getName().equals(itervar)) {
                    leftScalar = true;
                    rowIx = true;
                } else if (ix.isColLowerEqualsUpper() && ix.getInput().get(3) instanceof DataOp && ix.getInput().get(3).getName().equals(itervar)) {
                    leftScalar = true;
                    rowIx = false;
                }
            } else // check for right scalar plus
            if (HopRewriteUtils.isValidOp(bop.getOp(), MAP_SCALAR_AGGREGATE_SOURCE_OPS) && right instanceof DataOp && right.getDataType() == DataType.SCALAR && root.getName().equals(right.getName()) && left instanceof UnaryOp && ((UnaryOp) left).getOp() == OpOp1.CAST_AS_SCALAR && left.getInput().get(0) instanceof IndexingOp) {
                IndexingOp ix = (IndexingOp) left.getInput().get(0);
                if (ix.isRowLowerEqualsUpper() && ix.getInput().get(1) instanceof DataOp && ix.getInput().get(1).getName().equals(itervar)) {
                    rightScalar = true;
                    rowIx = true;
                } else if (ix.isColLowerEqualsUpper() && ix.getInput().get(3) instanceof DataOp && ix.getInput().get(3).getName().equals(itervar)) {
                    rightScalar = true;
                    rowIx = false;
                }
            }
        }
    }
    // apply rewrite if possible
    if (leftScalar || rightScalar) {
        Hop root = csb.getHops().get(0);
        BinaryOp bop = (BinaryOp) root.getInput().get(0);
        Hop cast = bop.getInput().get(leftScalar ? 1 : 0);
        Hop ix = cast.getInput().get(0);
        int aggOpPos = HopRewriteUtils.getValidOpPos(bop.getOp(), MAP_SCALAR_AGGREGATE_SOURCE_OPS);
        AggOp aggOp = MAP_SCALAR_AGGREGATE_TARGET_OPS[aggOpPos];
        // replace cast with sum
        AggUnaryOp newSum = HopRewriteUtils.createAggUnaryOp(ix, aggOp, Direction.RowCol);
        HopRewriteUtils.removeChildReference(cast, ix);
        HopRewriteUtils.removeChildReference(bop, cast);
        HopRewriteUtils.addChildReference(bop, newSum, leftScalar ? 1 : 0);
        // modify indexing expression according to loop predicate from-to
        // NOTE: any redundant index operations are removed via dynamic algebraic simplification rewrites
        int index1 = rowIx ? 1 : 3;
        int index2 = rowIx ? 2 : 4;
        HopRewriteUtils.replaceChildReference(ix, ix.getInput().get(index1), from, index1);
        HopRewriteUtils.replaceChildReference(ix, ix.getInput().get(index2), to, index2);
        // update indexing size information
        if (rowIx)
            ((IndexingOp) ix).setRowLowerEqualsUpper(false);
        else
            ((IndexingOp) ix).setColLowerEqualsUpper(false);
        ix.refreshSizeInformation();
        ret = csb;
        LOG.debug("Applied vectorizeScalarSumForLoop.");
    }
    return ret;
}
Also used : AggUnaryOp(org.apache.sysml.hops.AggUnaryOp) UnaryOp(org.apache.sysml.hops.UnaryOp) IndexingOp(org.apache.sysml.hops.IndexingOp) LeftIndexingOp(org.apache.sysml.hops.LeftIndexingOp) AggUnaryOp(org.apache.sysml.hops.AggUnaryOp) AggOp(org.apache.sysml.hops.Hop.AggOp) Hop(org.apache.sysml.hops.Hop) LiteralOp(org.apache.sysml.hops.LiteralOp) DataOp(org.apache.sysml.hops.DataOp) IfStatementBlock(org.apache.sysml.parser.IfStatementBlock) WhileStatementBlock(org.apache.sysml.parser.WhileStatementBlock) ForStatementBlock(org.apache.sysml.parser.ForStatementBlock) StatementBlock(org.apache.sysml.parser.StatementBlock) BinaryOp(org.apache.sysml.hops.BinaryOp)

Example 30 with UnaryOp

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

the class RewriteRemoveUnnecessaryCasts method rule_RemoveUnnecessaryCasts.

@SuppressWarnings("unchecked")
private void rule_RemoveUnnecessaryCasts(Hop hop) {
    // check mark processed
    if (hop.isVisited())
        return;
    // recursively process childs
    ArrayList<Hop> inputs = hop.getInput();
    for (int i = 0; i < inputs.size(); i++) rule_RemoveUnnecessaryCasts(inputs.get(i));
    // remove unnecessary value type cast
    if (hop instanceof UnaryOp && HopRewriteUtils.isValueTypeCast(((UnaryOp) hop).getOp())) {
        Hop in = hop.getInput().get(0);
        // type cast input
        ValueType vtIn = in.getValueType();
        // type cast output
        ValueType vtOut = hop.getValueType();
        // if input/output types match, no need to cast
        if (vtIn == vtOut && vtIn != ValueType.UNKNOWN) {
            ArrayList<Hop> parents = hop.getParent();
            for (// for all parents
            int i = 0; // for all parents
            i < parents.size(); // for all parents
            i++) {
                Hop p = parents.get(i);
                ArrayList<Hop> pin = p.getInput();
                for (// for all parent childs
                int j = 0; // for all parent childs
                j < pin.size(); // for all parent childs
                j++) {
                    Hop pinj = pin.get(j);
                    if (// found parent ref
                    pinj == hop) {
                        // rehang cast input as child of cast consumer
                        // remove cast ref
                        pin.remove(j);
                        // add ref to cast input
                        pin.add(j, in);
                        // remove cast from cast input parents
                        in.getParent().remove(hop);
                        // add parent to cast input parents
                        in.getParent().add(p);
                    }
                }
            }
            parents.clear();
        }
    }
    // remove unnecessary data type casts
    if (hop instanceof UnaryOp && hop.getInput().get(0) instanceof UnaryOp) {
        UnaryOp uop1 = (UnaryOp) hop;
        UnaryOp uop2 = (UnaryOp) hop.getInput().get(0);
        if ((uop1.getOp() == OpOp1.CAST_AS_MATRIX && uop2.getOp() == OpOp1.CAST_AS_SCALAR) || (uop1.getOp() == OpOp1.CAST_AS_SCALAR && uop2.getOp() == OpOp1.CAST_AS_MATRIX)) {
            Hop input = uop2.getInput().get(0);
            // rewire parents
            ArrayList<Hop> parents = (ArrayList<Hop>) hop.getParent().clone();
            for (Hop p : parents) HopRewriteUtils.replaceChildReference(p, hop, input);
        }
    }
    // mark processed
    hop.setVisited();
}
Also used : UnaryOp(org.apache.sysml.hops.UnaryOp) ValueType(org.apache.sysml.parser.Expression.ValueType) Hop(org.apache.sysml.hops.Hop) ArrayList(java.util.ArrayList)

Aggregations

UnaryOp (org.apache.sysml.hops.UnaryOp)42 AggUnaryOp (org.apache.sysml.hops.AggUnaryOp)39 Hop (org.apache.sysml.hops.Hop)35 LiteralOp (org.apache.sysml.hops.LiteralOp)24 AggBinaryOp (org.apache.sysml.hops.AggBinaryOp)18 BinaryOp (org.apache.sysml.hops.BinaryOp)18 DataOp (org.apache.sysml.hops.DataOp)9 IndexingOp (org.apache.sysml.hops.IndexingOp)8 ParameterizedBuiltinOp (org.apache.sysml.hops.ParameterizedBuiltinOp)6 TernaryOp (org.apache.sysml.hops.TernaryOp)6 ArrayList (java.util.ArrayList)5 HashMap (java.util.HashMap)5 ReorgOp (org.apache.sysml.hops.ReorgOp)5 DMLRuntimeException (org.apache.sysml.runtime.DMLRuntimeException)5 DataGenOp (org.apache.sysml.hops.DataGenOp)4 HopsException (org.apache.sysml.hops.HopsException)4 LeftIndexingOp (org.apache.sysml.hops.LeftIndexingOp)4 MatrixObject (org.apache.sysml.runtime.controlprogram.caching.MatrixObject)4 OpOp2 (org.apache.sysml.hops.Hop.OpOp2)3 CNode (org.apache.sysml.hops.codegen.cplan.CNode)3