diff --git a/src/ir/daphneir/Canonicalize.cpp b/src/ir/daphneir/Canonicalize.cpp index e769bdc3b..689915746 100644 --- a/src/ir/daphneir/Canonicalize.cpp +++ b/src/ir/daphneir/Canonicalize.cpp @@ -15,9 +15,12 @@ */ #include "ir/daphneir/Daphne.h" +#include "ir/daphneir/DaphnePushDownTraits.h" #include "mlir/Dialect/SCF/IR/SCF.h" +#include "mlir/IR/Builders.h" #include "mlir/Support/LogicalResult.h" #include +#include mlir::LogicalResult mlir::daphne::VectorizedPipelineOp::canonicalize(mlir::daphne::VectorizedPipelineOp op, mlir::PatternRewriter &rewriter) { @@ -231,6 +234,215 @@ mlir::LogicalResult mlir::daphne::SparsityOp::canonicalize(mlir::daphne::Sparsit return mlir::failure(); } +/** + * @brief PushDown optimizations will try to optimize aways intermediate results + * when function results are used with arithmetic operations. + * An example is `abs(fill(2,2,-3))` which will evaluate to + * -3,-3 + * -3,-3 + * + * and the applies abs to each element of the intermediate individually leading to + * + * 3,3 + * 3,3 + * + * Instead we can push the math inside the function and have it evaluate first: + * + * fill(2,2,abs(3)) -> fill(2,2,3) + * + * which directly fills the matrix + * + * 3,3 + * 3,3 + * + * and skips the intermediate. + */ +template bool tryPushDownUnary(Operation op, mlir::PatternRewriter &rewriter) { + mlir::Value arg = op.getArg(); + mlir::daphne::FillOp fill = arg.getDefiningOp(); + mlir::daphne::RandMatrixOp rand = arg.getDefiningOp(); + + const bool supportsPushDownLinear = op->template hasTrait(); + + // This will check for the fill operation to push down the arithmetic inside + if (fill) { + auto fillValue = fill.getArg(); + auto height = fill.getNumRows(); + auto width = fill.getNumCols(); + auto newOp = + rewriter.create(op.getLoc(), CompilerUtils::getValueType(op.getResult().getType()), fillValue); + rewriter.replaceOpWithNewOp(op, op.getResult().getType(), newOp, height, width); + return true; + } + // This will check for the rand operation to push down the arithmetic inside + // of it + if (rand) { + auto max = rand.getMax(); + auto min = rand.getMin(); + auto height = rand.getNumRows(); + auto width = rand.getNumCols(); + auto sparsity = rand.getSparsity(); + auto seed = rand.getSeed(); + + if (supportsPushDownLinear) { + auto newMax = + rewriter.create(op.getLoc(), CompilerUtils::getValueType(op.getResult().getType()), max); + auto newMin = + rewriter.create(op.getLoc(), CompilerUtils::getValueType(op.getResult().getType()), min); + + if constexpr (std::is_same()) { + // max and min have to be swapped after being negated + rewriter.replaceOpWithNewOp(op, op.getResult().getType(), height, width, + newMax, newMin, sparsity, seed); + return true; + } + + rewriter.replaceOpWithNewOp(op, op.getResult().getType(), height, width, newMin, + newMax, sparsity, seed); + return true; + } + // Handle the special case of RandMatrixOp and EwAbsOp which only works + // if the max and min are both positive (Abs is no-op) or both are + // negative (swap them) + if constexpr (std::is_same()) { + auto maxValueInt = CompilerUtils::isConstant(max); + auto minValueInt = CompilerUtils::isConstant(min); + auto maxValueDouble = CompilerUtils::isConstant(max); + auto minValueDouble = CompilerUtils::isConstant(min); + + if ((maxValueInt.first && minValueInt.first) || (maxValueDouble.first && minValueDouble.first) || + (maxValueInt.first && minValueDouble.first) || (maxValueDouble.first && minValueInt.first) + + ) { + // will be int or double. Whichever it isn't will default to 0 + // so they can simply be added together here + + auto maxValue = maxValueDouble.second + maxValueInt.second; + auto minValue = minValueDouble.second + minValueInt.second; + if (minValue >= 0 && maxValue >= minValue) { + // simply remove Abs function + rewriter.replaceOp(op, {arg.getDefiningOp()}); + return true; + } + if (maxValue <= 0 && maxValue >= minValue) { + // swap max and min + auto newMax = rewriter.create( + op.getLoc(), CompilerUtils::getValueType(op.getResult().getType()), min); + auto newMin = rewriter.create( + op.getLoc(), CompilerUtils::getValueType(op.getResult().getType()), max); + rewriter.replaceOpWithNewOp(op, op.getResult().getType(), height, width, + newMin, newMax, sparsity, seed); + return true; + } + } + } + } + return false; +} +/** + * @brief PushDown optimizations will try to optimize aways intermediate results + * when function results are used with arithmetic operations. + * An example is `fill(2,2,3) + 3` which will evaluate to + * 3,3 + * 3,3 + * + * and the applies +3 to each element of the intermediate individually leading to + * + * 6,6 + * 6,6 + * + * Instead we can push the math inside the function and have it evaluate first: + * + * fill(2,2,3 + 3) -> fill(2,2,6) + * + * which directly fills the matrix + * + * 6,6 + * 6,6 + * + * and skips the intermediate. + */ +template bool tryPushDownBinary(Operation op, mlir::PatternRewriter &rewriter) { + mlir::Type u = mlir::daphne::UnknownType::get(rewriter.getContext()); + mlir::Value lhs = op.getLhs(); + mlir::Value rhs = op.getRhs(); + mlir::daphne::FillOp lhsFill = lhs.getDefiningOp(); + mlir::daphne::RandMatrixOp lhsRand = lhs.getDefiningOp(); + mlir::daphne::SeqOp lhsSeq = lhs.getDefiningOp(); + const bool rhsIsSca = CompilerUtils::isScaType(rhs.getType()); + + const bool supportsPushDownLinear = op->template hasTrait(); + const bool supportsPushDownIncrementUpdate = op->template hasTrait(); + + // This will check for the fill operation to push down the arithmetic inside + // of it + if (lhsFill && rhsIsSca) { + auto fillValue = lhsFill.getArg(); + auto height = lhsFill.getNumRows(); + auto width = lhsFill.getNumCols(); + auto newOp = CompilerUtils::retValWithInferredType(rewriter.create(op.getLoc(), u, fillValue, rhs)); + rewriter.replaceOpWithNewOp(op, op.getResult().getType(), newOp, height, width); + return true; + } + // This will check for the rand operation to push down the arithmetic inside + // of it + if (lhsRand && rhsIsSca && supportsPushDownLinear) { + auto max = lhsRand.getMax(); + auto min = lhsRand.getMin(); + auto height = lhsRand.getNumRows(); + auto width = lhsRand.getNumCols(); + auto sparsity = lhsRand.getSparsity(); + auto seed = lhsRand.getSeed(); + auto maxValueInt = CompilerUtils::isConstant(max); + auto minValueInt = CompilerUtils::isConstant(min); + + if (maxValueInt.first && minValueInt.first) { + // do not push down for integer values as the result might include + // ranges not available in between the original values + return false; + } + auto newMax = CompilerUtils::retValWithInferredType(rewriter.create(op.getLoc(), u, max, rhs)); + auto newMin = CompilerUtils::retValWithInferredType(rewriter.create(op.getLoc(), u, min, rhs)); + rewriter.replaceOpWithNewOp(op, op.getResult().getType(), height, width, newMin, + newMax, sparsity, seed); + return true; + } + + // This will check for the seq operation to push down the arithmetic inside + // of it + if (lhsSeq && rhsIsSca && supportsPushDownLinear) { + auto from = lhsSeq.getFrom(); + auto to = lhsSeq.getTo(); + auto inc = lhsSeq.getInc(); + + auto newFrom = CompilerUtils::retValWithInferredType(rewriter.create(op.getLoc(), u, from, rhs)); + auto newTo = CompilerUtils::retValWithInferredType(rewriter.create(op.getLoc(), u, to, rhs)); + + if (supportsPushDownIncrementUpdate) { + auto incInt = CompilerUtils::isConstant(inc); + auto valueInt = CompilerUtils::isConstant(rhs); + auto valueDouble = CompilerUtils::isConstant(rhs); + + if (incInt.first && (((valueInt.first && incInt.second % valueInt.second != 0)) || valueDouble.first)) { + // do not push down for integer values in increment + // that can not be cleanly divided or if divided by an FP + // value, as the results would + // change + return false; + } + auto newInc = CompilerUtils::retValWithInferredType(rewriter.create(op.getLoc(), u, rhs, inc)); + + rewriter.replaceOpWithNewOp(op, op.getResult().getType(), newFrom, newTo, newInc); + return true; + + } else { + rewriter.replaceOpWithNewOp(op, op.getResult().getType(), newFrom, newTo, inc); + return true; + } + } + return false; +} + /** * @brief Replaces (1) `a + b` by `a concat b`, if `a` or `b` is a string, * and (2) `a + X` by `X + a` (`a` scalar, `X` matrix/frame). @@ -249,6 +461,9 @@ mlir::LogicalResult mlir::daphne::SparsityOp::canonicalize(mlir::daphne::Sparsit mlir::LogicalResult mlir::daphne::EwAddOp::canonicalize(mlir::daphne::EwAddOp op, PatternRewriter &rewriter) { mlir::Value lhs = op.getLhs(); mlir::Value rhs = op.getRhs(); + if (tryPushDownBinary(op, rewriter)) { + return mlir::success(); + } const bool lhsIsStr = llvm::isa(lhs.getType()); const bool rhsIsStr = llvm::isa(rhs.getType()); @@ -307,6 +522,11 @@ mlir::LogicalResult mlir::daphne::EwSubOp::canonicalize(mlir::daphne::EwSubOp op mlir::Value rhs = op.getRhs(); const bool lhsIsSca = CompilerUtils::isScaType(lhs.getType()); const bool rhsIsSca = CompilerUtils::isScaType(rhs.getType()); + + if (tryPushDownBinary(op, rewriter)) { + return mlir::success(); + } + if (lhsIsSca && !rhsIsSca) { rewriter.replaceOpWithNewOp( op, op.getResult().getType(), @@ -333,8 +553,13 @@ mlir::LogicalResult mlir::daphne::EwSubOp::canonicalize(mlir::daphne::EwSubOp op mlir::LogicalResult mlir::daphne::EwMulOp::canonicalize(mlir::daphne::EwMulOp op, PatternRewriter &rewriter) { mlir::Value lhs = op.getLhs(); mlir::Value rhs = op.getRhs(); - const bool lhsIsSca = CompilerUtils::isScaType(lhs.getType()); const bool rhsIsSca = CompilerUtils::isScaType(rhs.getType()); + const bool lhsIsSca = CompilerUtils::isScaType(lhs.getType()); + + if (tryPushDownBinary(op, rewriter)) { + return mlir::success(); + } + if (lhsIsSca && !rhsIsSca) { rewriter.replaceOpWithNewOp(op, op.getResult().getType(), rhs, lhs); return mlir::success(); @@ -358,8 +583,12 @@ mlir::LogicalResult mlir::daphne::EwMulOp::canonicalize(mlir::daphne::EwMulOp op mlir::LogicalResult mlir::daphne::EwDivOp::canonicalize(mlir::daphne::EwDivOp op, PatternRewriter &rewriter) { mlir::Value lhs = op.getLhs(); mlir::Value rhs = op.getRhs(); - const bool lhsIsSca = CompilerUtils::isScaType(lhs.getType()); const bool rhsIsSca = CompilerUtils::isScaType(rhs.getType()); + const bool lhsIsSca = CompilerUtils::isScaType(lhs.getType()); + if (tryPushDownBinary(op, rewriter)) { + return mlir::success(); + } + const bool rhsIsFP = llvm::isa(CompilerUtils::getValueType(rhs.getType())); if (lhsIsSca && !rhsIsSca && rhsIsFP) { rewriter.replaceOpWithNewOp( @@ -373,6 +602,85 @@ mlir::LogicalResult mlir::daphne::EwDivOp::canonicalize(mlir::daphne::EwDivOp op } return mlir::failure(); } +/** + * + */ +mlir::LogicalResult mlir::daphne::EwLogOp::canonicalize(mlir::daphne::EwLogOp op, PatternRewriter &rewriter) { + + if (tryPushDownBinary(op, rewriter)) { + return mlir::success(); + } + return mlir::failure(); +} +/** + * + */ +mlir::LogicalResult mlir::daphne::EwModOp::canonicalize(mlir::daphne::EwModOp op, PatternRewriter &rewriter) { + if (tryPushDownBinary(op, rewriter)) { + return mlir::success(); + } + return mlir::failure(); +} + +/** + * + */ +mlir::LogicalResult mlir::daphne::EwAbsOp::canonicalize(mlir::daphne::EwAbsOp op, PatternRewriter &rewriter) { + if (tryPushDownUnary(op, rewriter)) { + return mlir::success(); + } + return mlir::failure(); +} + +/** + * + */ +mlir::LogicalResult mlir::daphne::EwSignOp::canonicalize(mlir::daphne::EwSignOp op, PatternRewriter &rewriter) { + if (tryPushDownUnary(op, rewriter)) { + return mlir::success(); + } + return mlir::failure(); +} + +/** + * + */ +mlir::LogicalResult mlir::daphne::EwExpOp::canonicalize(mlir::daphne::EwExpOp op, PatternRewriter &rewriter) { + if (tryPushDownUnary(op, rewriter)) { + return mlir::success(); + } + return mlir::failure(); +} + +/** + * + */ +mlir::LogicalResult mlir::daphne::EwLnOp::canonicalize(mlir::daphne::EwLnOp op, PatternRewriter &rewriter) { + if (tryPushDownUnary(op, rewriter)) { + return mlir::success(); + } + return mlir::failure(); +} + +/** + * + */ +mlir::LogicalResult mlir::daphne::EwSqrtOp::canonicalize(mlir::daphne::EwSqrtOp op, PatternRewriter &rewriter) { + if (tryPushDownUnary(op, rewriter)) { + return mlir::success(); + } + return mlir::failure(); +} + +/** + * + */ +mlir::LogicalResult mlir::daphne::EwPowOp::canonicalize(mlir::daphne::EwPowOp op, PatternRewriter &rewriter) { + if (tryPushDownBinary(op, rewriter)) { + return mlir::success(); + } + return mlir::failure(); +} /** * @brief Replaces a `DistributeOp` by a `DistributedReadOp`, if its input @@ -594,6 +902,9 @@ mlir::LogicalResult mlir::daphne::EwMinusOp::canonicalize(mlir::daphne::EwMinusO rewriter.replaceOp(op, innerOp.getOperand()); return mlir::success(); } + if (tryPushDownUnary(op, rewriter)) { + return mlir::success(); + } return mlir::failure(); } @@ -606,10 +917,10 @@ mlir::LogicalResult mlir::daphne::EwMinusOp::canonicalize(mlir::daphne::EwMinusO mlir::LogicalResult mlir::daphne::ConvertBitmapToPosListOp::canonicalize(mlir::daphne::ConvertBitmapToPosListOp bmplcOp, PatternRewriter &rewriter) { if (auto plbmcOp = bmplcOp.getArg().getDefiningOp()) { - // The ConvertPosListToBitmapOp has a second argument for the number of rows (bitmap size). No matter what this - // size is, we always get back the original position list. The only exception would be if the bitmap size is - // less than the greatest position in the original position list (information loss or error during conversion - // from position list to bitmap). However, this case is not relevant to us at the moment. + // The ConvertPosListToBitmapOp has a second argument for the number of rows (bitmap size). No matter what + // this size is, we always get back the original position list. The only exception would be if the bitmap + // size is less than the greatest position in the original position list (information loss or error during + // conversion from position list to bitmap). However, this case is not relevant to us at the moment. rewriter.replaceOp(bmplcOp, plbmcOp.getArg()); return mlir::success(); } @@ -626,8 +937,8 @@ mlir::LogicalResult mlir::daphne::ExtractColOp::canonicalize(mlir::daphne::Extra if (auto srcFrmTy = src.getType().dyn_cast()) { if (sel.getType().isa()) { if (srcFrmTy.getNumCols() == 1) { - // Eliminate the extraction of a single column (by its label) from a frame with a single column which - // has exactly that label. + // Eliminate the extraction of a single column (by its label) from a frame with a single column + // which has exactly that label. if (std::vector *labels = srcFrmTy.getLabels()) { std::pair selConst = CompilerUtils::isConstant(sel); @@ -637,22 +948,24 @@ mlir::LogicalResult mlir::daphne::ExtractColOp::canonicalize(mlir::daphne::Extra } } } else if (auto cfOp = src.getDefiningOp()) { - // Replace the extraction of a single column (by its label) from the result of a CreateFrameOp, by the - // respective input column of the CreateFrameOp. This simplification rewrite can help us avoid the - // unnecessary creation of frames when we are interested only in certain columns later on. It can lead - // to the elimination of the operations creating later unused input columns of the CreateFrameOp. - - // CreateFrameOp always has an even number of arguments. The first half are the columns and the second - // half are the labels. + // Replace the extraction of a single column (by its label) from the result of a CreateFrameOp, by + // the respective input column of the CreateFrameOp. This simplification rewrite can help us avoid + // the unnecessary creation of frames when we are interested only in certain columns later on. It + // can lead to the elimination of the operations creating later unused input columns of the + // CreateFrameOp. + + // CreateFrameOp always has an even number of arguments. The first half are the columns and the + // second half are the labels. const size_t cfNumCols = cfOp->getNumOperands() / 2; // Search for the column with the specified label. for (size_t i = 0; i < cfNumCols; i++) { Value label = cfOp->getOperand(cfNumCols + i); if (label == sel) { - // We need to insert an additional cast of the CreateFrameOp's input column to the result type - // of the ExtractColOp, because usually, the arguments to CreateFrameOp are single-column - // *matrices*, while the result of ExtractColOp on a frame is a single-column *frame*. Such - // additional casts will often be eliminated through the canonicalization of CastOp later. + // We need to insert an additional cast of the CreateFrameOp's input column to the result + // type of the ExtractColOp, because usually, the arguments to CreateFrameOp are + // single-column *matrices*, while the result of ExtractColOp on a frame is a single-column + // *frame*. Such additional casts will often be eliminated through the canonicalization of + // CastOp later. Type resTy = ecOp.getResult().getType(); if (auto resFrmTy = resTy.dyn_cast()) { // Reset the labels to unknown, because TODO @@ -662,11 +975,11 @@ mlir::LogicalResult mlir::daphne::ExtractColOp::canonicalize(mlir::daphne::Extra .getResult(); // If the result of the ExtractColOp is a (single-column) frame (typically the case), we // must make sure that it gets the right column label after the rewrite. The label is an - // argument to the CreateFrameOp and might not be known as a compile-time constant at the - // point in time when this rewrite happens (the label could be the result of a complex - // string expression, which is resolved later during compile-time through constant folding - // or only at run-time). Thus, we additionally insert a SetColLabelsOp which reuses exactly - // the same input as the CreateFrameOp for the label. + // argument to the CreateFrameOp and might not be known as a compile-time constant at + // the point in time when this rewrite happens (the label could be the result of a + // complex string expression, which is resolved later during compile-time through + // constant folding or only at run-time). Thus, we additionally insert a SetColLabelsOp + // which reuses exactly the same input as the CreateFrameOp for the label. Value labeled = rewriter.create(ecOp.getLoc(), resTy, casted, label) .getResult(); @@ -712,10 +1025,10 @@ mlir::LogicalResult mlir::daphne::ExtractColOp::canonicalize(mlir::daphne::Extra /** * @brief Simplifies various patterns of ops that end with a CastOp. * - * Simple examples include the elimination of trivial casts (casting from A to A) and the simplification of chains of - * casts (e.g., casting from A to B to C becomes casting from A to C, in case there is no information loss). Besides - * that, there are patterns that by-pass ops that create the input of a CastOp and patterns that by-pass the CastOp - * itself. + * Simple examples include the elimination of trivial casts (casting from A to A) and the simplification of chains + * of casts (e.g., casting from A to B to C becomes casting from A to C, in case there is no information loss). + * Besides that, there are patterns that by-pass ops that create the input of a CastOp and patterns that by-pass the + * CastOp itself. */ mlir::LogicalResult mlir::daphne::CastOp::canonicalize(mlir::daphne::CastOp cOp, PatternRewriter &rewriter) { // TODO Maybe skip property casts, or separate them, combine multiple property casts. @@ -736,9 +1049,9 @@ mlir::LogicalResult mlir::daphne::CastOp::canonicalize(mlir::daphne::CastOp cOp, } } - // Bypass operations manipulating frame column labels in case their result is casted to a data type that does not - // support column labels (matrix/column). This is sound, since the column label information from the frame would be - // gone after the cast anyway. + // Bypass operations manipulating frame column labels in case their result is casted to a data type that does + // not support column labels (matrix/column). This is sound, since the column label information from the frame + // would be gone after the cast anyway. if (cOp.getArg().getType().isa() && cOp.getRes().getType().isa()) { if (auto sclOp = cOp.getArg().getDefiningOp()) { @@ -788,4 +1101,4 @@ mlir::LogicalResult mlir::daphne::SetColLabelsOp::canonicalize(mlir::daphne::Set } } return mlir::failure(); -} \ No newline at end of file +} diff --git a/src/ir/daphneir/Daphne.h b/src/ir/daphneir/Daphne.h index ded52d201..66b96a554 100644 --- a/src/ir/daphneir/Daphne.h +++ b/src/ir/daphneir/Daphne.h @@ -82,6 +82,7 @@ BoolOrUnknown stringToBoolOrUnknown(const std::string &str); #include #include #include +#include #include #include diff --git a/src/ir/daphneir/DaphneOps.td b/src/ir/daphneir/DaphneOps.td index 84d519129..f5373a003 100644 --- a/src/ir/daphneir/DaphneOps.td +++ b/src/ir/daphneir/DaphneOps.td @@ -30,6 +30,7 @@ include "ir/daphneir/DaphneInferSparsityOpInterface.td" include "ir/daphneir/DaphneInferSparsityTraits.td" include "ir/daphneir/DaphneInferTypesOpInterface.td" include "ir/daphneir/DaphneInferTypesTraits.td" +include "ir/daphneir/DaphnePushDownTraits.td" include "ir/daphneir/DaphneVectorizableOpInterface.td" include "ir/daphneir/DaphneTypeAdaptationTraits.td" include "ir/daphneir/CUDASupport.td" @@ -119,7 +120,7 @@ def Daphne_ConvertCSRMatrixToRowOffsetsMemRef : Daphne_Op<"convertCSRMatrixToRow def Daphne_FillOp : Daphne_Op<"fill", [ DataTypeMat, ValueTypeFromFirstArg, - NumRowsFromIthScalar<1>, NumColsFromIthScalar<2>, CUDASupport, + NumRowsFromIthScalar<1>, NumColsFromIthScalar<2>, CUDASupport, Pure, DeclareOpInterfaceMethods ]> { let arguments = (ins AnyScalar:$arg, Size:$numRows, Size:$numCols); @@ -157,7 +158,7 @@ def Daphne_DiagMatrixOp : Daphne_Op<"diagMatrix", [ def Daphne_RandMatrixOp : Daphne_Op<"randMatrix", [ TypesMatchWith<"min and max arguments must be of the same type", "min", "max", "$_self">, NumRowsFromIthScalar<0>, NumColsFromIthScalar<1>, DeclareOpInterfaceMethods, - SparsityFromIthScalar<4>, CastArgsToResTypeRandMatrixOp + SparsityFromIthScalar<4>, CastArgsToResTypeRandMatrixOp, Pure ]> { let arguments = (ins Size:$numRows, Size:$numCols, AnyScalar:$min, AnyScalar:$max, F64:$sparsity, IntScalar:$seed); let results = (outs MatrixOrU:$res); @@ -175,7 +176,8 @@ def Daphne_SeqOp : Daphne_Op<"seq", [ DataTypeMat, ValueTypeFromArgs, OneCol, DeclareOpInterfaceMethods, CompletelyDense, - CastArgsToResType + CastArgsToResType, + Pure ]> { let arguments = (ins NumScalar:$from, NumScalar:$to, NumScalar:$inc); let results = (outs MatrixOf<[NumScalar]>); @@ -254,15 +256,25 @@ class Daphne_EwUnaryOp traits = []> : // ---------------------------------------------------------------------------- // TODO EwMinusOp: Should an unsigned integer argument yield a signed integer result? -def Daphne_EwMinusOp : Daphne_EwUnaryOp<"ewMinus", NumScalar, [ValueTypeFromFirstArg]> { +def Daphne_EwMinusOp : Daphne_EwUnaryOp<"ewMinus", NumScalar, [ValueTypeFromFirstArg,PushDownLinear]> { let hasFolder = 1; let hasCanonicalizeMethod = 1; } -def Daphne_EwAbsOp : Daphne_EwUnaryOp<"ewAbs", NumScalar, [ValueTypeFromFirstArg]>; -def Daphne_EwSignOp : Daphne_EwUnaryOp<"ewSign", NumScalar, [ValueTypeFromFirstArg]>; -def Daphne_EwExpOp : Daphne_EwUnaryOp<"ewExp", NumScalar, [ValueTypeFromArgsFP]>; -def Daphne_EwLnOp : Daphne_EwUnaryOp<"ewLn", NumScalar, [ValueTypeFromArgsFP]>; -def Daphne_EwSqrtOp : Daphne_EwUnaryOp<"ewSqrt", NumScalar, [ValueTypeFromArgsFP, DeclareOpInterfaceMethods]>; +def Daphne_EwAbsOp : Daphne_EwUnaryOp<"ewAbs", NumScalar, [ValueTypeFromFirstArg]>{ + let hasCanonicalizeMethod = 1; +} +def Daphne_EwSignOp : Daphne_EwUnaryOp<"ewSign", NumScalar, [ValueTypeFromFirstArg]>{ + let hasCanonicalizeMethod = 1; +} +def Daphne_EwExpOp : Daphne_EwUnaryOp<"ewExp", NumScalar, [ValueTypeFromArgsFP]>{ + let hasCanonicalizeMethod = 1; +} +def Daphne_EwLnOp : Daphne_EwUnaryOp<"ewLn", NumScalar, [ValueTypeFromArgsFP]>{ + let hasCanonicalizeMethod = 1; +} +def Daphne_EwSqrtOp : Daphne_EwUnaryOp<"ewSqrt", NumScalar, [ValueTypeFromArgsFP, DeclareOpInterfaceMethods]>{ + let hasCanonicalizeMethod = 1; +} // ---------------------------------------------------------------------------- // Logical @@ -334,21 +346,27 @@ class Daphne_EwBinaryOp traits = []> // ---------------------------------------------------------------------------- // TODO Make EwAddOp Commutative again (see #449). -def Daphne_EwAddOp : Daphne_EwBinaryOp<"ewAdd", AnyScalar, [ValueTypeFromArgs, CastArgsToResType/*, Commutative*/, EwSparseIfBoth, CUDASupport]> { +def Daphne_EwAddOp : Daphne_EwBinaryOp<"ewAdd", AnyScalar, [ValueTypeFromArgs, CastArgsToResType/*, Commutative*/, EwSparseIfBoth, CUDASupport, PushDownLinear]> { + let hasCanonicalizeMethod = 1; +} +def Daphne_EwSubOp : Daphne_EwBinaryOp<"ewSub", NumScalar, [ValueTypeFromArgs, CastArgsToResType, EwSparseIfBoth, CUDASupport, PushDownLinear]> { + let hasCanonicalizeMethod = 1; +} +def Daphne_EwMulOp : Daphne_EwBinaryOp<"ewMul", NumScalar, [ValueTypeFromArgs, CastArgsToResType, Commutative, EwSparseIfEither, CUDASupport, PushDownLinear, PushDownIncrementUpdate]> { + let hasCanonicalizeMethod = 1; +} +def Daphne_EwDivOp : Daphne_EwBinaryOp<"ewDiv", NumScalar, [ValueTypeFromArgs, CastArgsToResType, CUDASupport, PushDownLinear, PushDownIncrementUpdate]> { let hasCanonicalizeMethod = 1; } -def Daphne_EwSubOp : Daphne_EwBinaryOp<"ewSub", NumScalar, [ValueTypeFromArgs, CastArgsToResType, EwSparseIfBoth, CUDASupport]> { +def Daphne_EwPowOp : Daphne_EwBinaryOp<"ewPow", NumScalar, [ValueTypeFromArgs, CastArgsToResType, CUDASupport]> { let hasCanonicalizeMethod = 1; } -def Daphne_EwMulOp : Daphne_EwBinaryOp<"ewMul", NumScalar, [ValueTypeFromArgs, CastArgsToResType, Commutative, EwSparseIfEither, CUDASupport]> { +def Daphne_EwModOp : Daphne_EwBinaryOp<"ewMod", NumScalar, [ValueTypeFromArgs, CastArgsToResType]> { let hasCanonicalizeMethod = 1; } -def Daphne_EwDivOp : Daphne_EwBinaryOp<"ewDiv", NumScalar, [ValueTypeFromArgs, CastArgsToResType, CUDASupport]> { +def Daphne_EwLogOp : Daphne_EwBinaryOp<"ewLog", NumScalar, [ValueTypeFromArgsFP, CastArgsToResType]> { let hasCanonicalizeMethod = 1; } -def Daphne_EwPowOp : Daphne_EwBinaryOp<"ewPow", NumScalar, [ValueTypeFromArgs, CastArgsToResType, CUDASupport]>; -def Daphne_EwModOp : Daphne_EwBinaryOp<"ewMod", NumScalar, [ValueTypeFromArgs, CastArgsToResType]>; -def Daphne_EwLogOp : Daphne_EwBinaryOp<"ewLog", NumScalar, [ValueTypeFromArgsFP, CastArgsToResType]>; // ---------------------------------------------------------------------------- // Min/max diff --git a/src/ir/daphneir/DaphnePushDownTraits.h b/src/ir/daphneir/DaphnePushDownTraits.h new file mode 100644 index 000000000..39ce317e8 --- /dev/null +++ b/src/ir/daphneir/DaphnePushDownTraits.h @@ -0,0 +1,24 @@ +#ifndef SRC_IR_DAPHNEIR_DAPHNEPUSHDOWNTRAITS_H +#define SRC_IR_DAPHNEIR_DAPHNEPUSHDOWNTRAITS_H + +namespace mlir::OpTrait { + +// ============================================================================ +// Traits determining advanced push-down rewrite possibilities +// ============================================================================ + +/** + * @brief This trait is for operations that are linear and might allow for push-downs into functions that + * act on e.g. ranges + */ +template class PushDownLinear : public TraitBase {}; + +/** + * @brief This trait is for operations that are using an increment value which + * needs to be accounted for during push-down optimizations + */ +template class PushDownIncrementUpdate : public TraitBase {}; + +} // namespace mlir::OpTrait + +#endif // SRC_IR_DAPHNEIR_DAPHNEPUSHDOWNTRAITS_H diff --git a/src/ir/daphneir/DaphnePushDownTraits.td b/src/ir/daphneir/DaphnePushDownTraits.td new file mode 100644 index 000000000..15cf5ab33 --- /dev/null +++ b/src/ir/daphneir/DaphnePushDownTraits.td @@ -0,0 +1,29 @@ +/* + * Copyright 2025 The DAPHNE Consortium + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SRC_IR_DAPHNEIR_DAPHNEPUSHDOWNTRAITS_TD +#define SRC_IR_DAPHNEIR_DAPHNEPUSHDOWNTRAITS_TD + +include "mlir/IR/OpBase.td" + +// ============================================================================ +// Traits determining pushdown rewrite possibilities +// ============================================================================ + +def PushDownLinear: NativeOpTrait<"PushDownLinear">; +def PushDownIncrementUpdate: NativeOpTrait<"PushDownIncrementUpdate">; + +#endif //SRC_IR_DAPHNEIR_DAPHNEPUSHDOWNTRAITS_TD diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 5d20ae772..ac6cf241c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -67,7 +67,9 @@ set(TEST_SOURCES api/cli/codegen/TransposeTest.cpp ir/daphneir/InferTypesTest.cpp + ir/daphneir/PushdownArithmetics.cpp api/cli/operations/CanonicalizationConstantFoldingOpTest.cpp + api/cli/operations/CanonicalizationPushDownTest.cpp parser/config/ConfigParserTest.cpp diff --git a/test/api/cli/distributed/distributed_4.daphne b/test/api/cli/distributed/distributed_4.daphne index ca44a4c41..bf74b2cf1 100644 --- a/test/api/cli/distributed/distributed_4.daphne +++ b/test/api/cli/distributed/distributed_4.daphne @@ -1,3 +1,3 @@ m1 = rand(10, 10, 0.0, 20.0, 1.0, 1); -m2 = rand(10, 10, 0.0, 20.0, 1.0, 1); -print(m1 @ m2); \ No newline at end of file +m2 = rand(10, 10, 0.0, 30.0, 1.0, 1); +print(m1 @ m2); diff --git a/test/api/cli/operations/CanonicalizationPushDownTest.cpp b/test/api/cli/operations/CanonicalizationPushDownTest.cpp new file mode 100644 index 000000000..4d87e4936 --- /dev/null +++ b/test/api/cli/operations/CanonicalizationPushDownTest.cpp @@ -0,0 +1,61 @@ +/* + * Copyright 2021 The DAPHNE Consortium + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include + +#include + +#include +#include + +const std::string dirPath = "test/api/cli/operations/"; + +#define MAKE_TEST_CASE(name, count) \ + TEST_CASE(name, TAG_OPERATIONS) { \ + for (unsigned i = 1; i <= count; i++) { \ + DYNAMIC_SECTION(name "_" << i << ".daphne") { compareDaphneToRefSimple(dirPath, name, i); } \ + } \ + } + +// These tests simply ensure that basic functionality stays +// functional after pushdown optimizations are performed. +// Check the dedicated "pushdown_arithmetics" testcase for more in depth testing +// of the canonicalizations. +MAKE_TEST_CASE("fillEwAdd", 2) +MAKE_TEST_CASE("fillEwSub", 2) +MAKE_TEST_CASE("fillEwMul", 2) +MAKE_TEST_CASE("fillEwDiv", 2) +MAKE_TEST_CASE("fillEwPow", 2) +MAKE_TEST_CASE("fillEwMod", 2) +MAKE_TEST_CASE("fillEwLog", 2) +MAKE_TEST_CASE("fillEwAbs", 2) +MAKE_TEST_CASE("fillEwSign", 2) +MAKE_TEST_CASE("fillEwExp", 2) +MAKE_TEST_CASE("fillEwLn", 1) +MAKE_TEST_CASE("fillEwSqrt", 1) +MAKE_TEST_CASE("fillEwMinus", 2) +MAKE_TEST_CASE("randEwAdd", 2) +MAKE_TEST_CASE("randEwSub", 1) +MAKE_TEST_CASE("randEwMul", 3) +MAKE_TEST_CASE("randEwDiv", 3) +MAKE_TEST_CASE("randEwAbs", 3) +MAKE_TEST_CASE("randEwMinus", 3) +MAKE_TEST_CASE("seqEwAdd", 2) +MAKE_TEST_CASE("seqEwSub", 2) +MAKE_TEST_CASE("seqEwMul", 3) +MAKE_TEST_CASE("seqEwDiv", 3) diff --git a/test/api/cli/operations/fillEwAbs_1.daphne b/test/api/cli/operations/fillEwAbs_1.daphne new file mode 100644 index 000000000..56f33c9a9 --- /dev/null +++ b/test/api/cli/operations/fillEwAbs_1.daphne @@ -0,0 +1,4 @@ +fillIntermediate = fill(-3,3,3); +result = abs(fillIntermediate); + +print(result); diff --git a/test/api/cli/operations/fillEwAbs_1.txt b/test/api/cli/operations/fillEwAbs_1.txt new file mode 100644 index 000000000..70b0d0a0f --- /dev/null +++ b/test/api/cli/operations/fillEwAbs_1.txt @@ -0,0 +1,4 @@ +DenseMatrix(3x3, int64_t) +3 3 3 +3 3 3 +3 3 3 diff --git a/test/api/cli/operations/fillEwAbs_2.daphne b/test/api/cli/operations/fillEwAbs_2.daphne new file mode 100644 index 000000000..f0c80ac87 --- /dev/null +++ b/test/api/cli/operations/fillEwAbs_2.daphne @@ -0,0 +1,4 @@ +fillIntermediate = fill(3,3,3); +result = abs(fillIntermediate); + +print(result); diff --git a/test/api/cli/operations/fillEwAbs_2.txt b/test/api/cli/operations/fillEwAbs_2.txt new file mode 100644 index 000000000..70b0d0a0f --- /dev/null +++ b/test/api/cli/operations/fillEwAbs_2.txt @@ -0,0 +1,4 @@ +DenseMatrix(3x3, int64_t) +3 3 3 +3 3 3 +3 3 3 diff --git a/test/api/cli/operations/fillEwAdd_1.daphne b/test/api/cli/operations/fillEwAdd_1.daphne new file mode 100644 index 000000000..ef193dd1d --- /dev/null +++ b/test/api/cli/operations/fillEwAdd_1.daphne @@ -0,0 +1,3 @@ +result = fill(1,3,3) + 3; + +print(result); diff --git a/test/api/cli/operations/fillEwAdd_1.txt b/test/api/cli/operations/fillEwAdd_1.txt new file mode 100644 index 000000000..5e671bb18 --- /dev/null +++ b/test/api/cli/operations/fillEwAdd_1.txt @@ -0,0 +1,4 @@ +DenseMatrix(3x3, int64_t) +4 4 4 +4 4 4 +4 4 4 diff --git a/test/api/cli/operations/fillEwAdd_2.daphne b/test/api/cli/operations/fillEwAdd_2.daphne new file mode 100644 index 000000000..e547e48a6 --- /dev/null +++ b/test/api/cli/operations/fillEwAdd_2.daphne @@ -0,0 +1,2 @@ +result = 2 + fill(1.0,2,2); +print(result); diff --git a/test/api/cli/operations/fillEwAdd_2.txt b/test/api/cli/operations/fillEwAdd_2.txt new file mode 100644 index 000000000..c0938fb13 --- /dev/null +++ b/test/api/cli/operations/fillEwAdd_2.txt @@ -0,0 +1,3 @@ +DenseMatrix(2x2, double) +3 3 +3 3 diff --git a/test/api/cli/operations/fillEwDiv_1.daphne b/test/api/cli/operations/fillEwDiv_1.daphne new file mode 100644 index 000000000..b15596905 --- /dev/null +++ b/test/api/cli/operations/fillEwDiv_1.daphne @@ -0,0 +1,3 @@ +result = fill(12.3,2,3) / 3; + +print(result); diff --git a/test/api/cli/operations/fillEwDiv_1.txt b/test/api/cli/operations/fillEwDiv_1.txt new file mode 100644 index 000000000..940755db7 --- /dev/null +++ b/test/api/cli/operations/fillEwDiv_1.txt @@ -0,0 +1,3 @@ +DenseMatrix(2x3, double) +4.1 4.1 4.1 +4.1 4.1 4.1 diff --git a/test/api/cli/operations/fillEwDiv_2.daphne b/test/api/cli/operations/fillEwDiv_2.daphne new file mode 100644 index 000000000..93c4625b8 --- /dev/null +++ b/test/api/cli/operations/fillEwDiv_2.daphne @@ -0,0 +1,3 @@ +result = fill(12,3,2) / 3; + +print(result); diff --git a/test/api/cli/operations/fillEwDiv_2.txt b/test/api/cli/operations/fillEwDiv_2.txt new file mode 100644 index 000000000..d60cab690 --- /dev/null +++ b/test/api/cli/operations/fillEwDiv_2.txt @@ -0,0 +1,4 @@ +DenseMatrix(3x2, int64_t) +4 4 +4 4 +4 4 diff --git a/test/api/cli/operations/fillEwExp_1.daphne b/test/api/cli/operations/fillEwExp_1.daphne new file mode 100644 index 000000000..1c3e78ed1 --- /dev/null +++ b/test/api/cli/operations/fillEwExp_1.daphne @@ -0,0 +1,4 @@ +fillIntermediate = fill(3,3,3); +result = exp(fillIntermediate); + +print(result); diff --git a/test/api/cli/operations/fillEwExp_1.txt b/test/api/cli/operations/fillEwExp_1.txt new file mode 100644 index 000000000..295cba68e --- /dev/null +++ b/test/api/cli/operations/fillEwExp_1.txt @@ -0,0 +1,4 @@ +DenseMatrix(3x3, double) +20.0855 20.0855 20.0855 +20.0855 20.0855 20.0855 +20.0855 20.0855 20.0855 diff --git a/test/api/cli/operations/fillEwExp_2.daphne b/test/api/cli/operations/fillEwExp_2.daphne new file mode 100644 index 000000000..d80aa3dec --- /dev/null +++ b/test/api/cli/operations/fillEwExp_2.daphne @@ -0,0 +1,4 @@ +fillIntermediate = fill(-3,3,3); +result = exp(fillIntermediate); + +print(result); diff --git a/test/api/cli/operations/fillEwExp_2.txt b/test/api/cli/operations/fillEwExp_2.txt new file mode 100644 index 000000000..e1f8832a9 --- /dev/null +++ b/test/api/cli/operations/fillEwExp_2.txt @@ -0,0 +1,4 @@ +DenseMatrix(3x3, double) +0.0497871 0.0497871 0.0497871 +0.0497871 0.0497871 0.0497871 +0.0497871 0.0497871 0.0497871 diff --git a/test/api/cli/operations/fillEwLn_1.daphne b/test/api/cli/operations/fillEwLn_1.daphne new file mode 100644 index 000000000..6fb0f0176 --- /dev/null +++ b/test/api/cli/operations/fillEwLn_1.daphne @@ -0,0 +1,4 @@ +fillIntermediate = fill(3,3,3); +result = ln(fillIntermediate); + +print(result); diff --git a/test/api/cli/operations/fillEwLn_1.txt b/test/api/cli/operations/fillEwLn_1.txt new file mode 100644 index 000000000..7becbddf2 --- /dev/null +++ b/test/api/cli/operations/fillEwLn_1.txt @@ -0,0 +1,4 @@ +DenseMatrix(3x3, double) +1.09861 1.09861 1.09861 +1.09861 1.09861 1.09861 +1.09861 1.09861 1.09861 diff --git a/test/api/cli/operations/fillEwLog_1.daphne b/test/api/cli/operations/fillEwLog_1.daphne new file mode 100644 index 000000000..8db59aba0 --- /dev/null +++ b/test/api/cli/operations/fillEwLog_1.daphne @@ -0,0 +1,4 @@ +a = fill(8,3,3); +result = log(a,2); + +print(result); diff --git a/test/api/cli/operations/fillEwLog_1.txt b/test/api/cli/operations/fillEwLog_1.txt new file mode 100644 index 000000000..20b3eb67f --- /dev/null +++ b/test/api/cli/operations/fillEwLog_1.txt @@ -0,0 +1,4 @@ +DenseMatrix(3x3, double) +3 3 3 +3 3 3 +3 3 3 diff --git a/test/api/cli/operations/fillEwLog_2.daphne b/test/api/cli/operations/fillEwLog_2.daphne new file mode 100644 index 000000000..88bade5b4 --- /dev/null +++ b/test/api/cli/operations/fillEwLog_2.daphne @@ -0,0 +1,4 @@ +a = fill(16.0,3,3); +result = log(a,2); + +print(result); diff --git a/test/api/cli/operations/fillEwLog_2.txt b/test/api/cli/operations/fillEwLog_2.txt new file mode 100644 index 000000000..7aec689a2 --- /dev/null +++ b/test/api/cli/operations/fillEwLog_2.txt @@ -0,0 +1,4 @@ +DenseMatrix(3x3, double) +4 4 4 +4 4 4 +4 4 4 diff --git a/test/api/cli/operations/fillEwMinus_1.daphne b/test/api/cli/operations/fillEwMinus_1.daphne new file mode 100644 index 000000000..4259512d1 --- /dev/null +++ b/test/api/cli/operations/fillEwMinus_1.daphne @@ -0,0 +1,3 @@ +result = - fill(3,2,3); + +print(result); diff --git a/test/api/cli/operations/fillEwMinus_1.txt b/test/api/cli/operations/fillEwMinus_1.txt new file mode 100644 index 000000000..45abb15d0 --- /dev/null +++ b/test/api/cli/operations/fillEwMinus_1.txt @@ -0,0 +1,3 @@ +DenseMatrix(2x3, int64_t) +-3 -3 -3 +-3 -3 -3 diff --git a/test/api/cli/operations/fillEwMinus_2.daphne b/test/api/cli/operations/fillEwMinus_2.daphne new file mode 100644 index 000000000..03fc4624d --- /dev/null +++ b/test/api/cli/operations/fillEwMinus_2.daphne @@ -0,0 +1,3 @@ +result = - fill(-3,2,3); + +print(result); diff --git a/test/api/cli/operations/fillEwMinus_2.txt b/test/api/cli/operations/fillEwMinus_2.txt new file mode 100644 index 000000000..2ab8aa13d --- /dev/null +++ b/test/api/cli/operations/fillEwMinus_2.txt @@ -0,0 +1,3 @@ +DenseMatrix(2x3, int64_t) +3 3 3 +3 3 3 diff --git a/test/api/cli/operations/fillEwMod_1.daphne b/test/api/cli/operations/fillEwMod_1.daphne new file mode 100644 index 000000000..e62ccfd98 --- /dev/null +++ b/test/api/cli/operations/fillEwMod_1.daphne @@ -0,0 +1,3 @@ +result = mod(fill(33,2,2),5); + +print(result); diff --git a/test/api/cli/operations/fillEwMod_1.txt b/test/api/cli/operations/fillEwMod_1.txt new file mode 100644 index 000000000..edc1da2f9 --- /dev/null +++ b/test/api/cli/operations/fillEwMod_1.txt @@ -0,0 +1,3 @@ +DenseMatrix(2x2, int64_t) +3 3 +3 3 diff --git a/test/api/cli/operations/fillEwMod_2.daphne b/test/api/cli/operations/fillEwMod_2.daphne new file mode 100644 index 000000000..45081f193 --- /dev/null +++ b/test/api/cli/operations/fillEwMod_2.daphne @@ -0,0 +1,3 @@ +result = fill(33.0,2,2) % 5; + +print(result); diff --git a/test/api/cli/operations/fillEwMod_2.txt b/test/api/cli/operations/fillEwMod_2.txt new file mode 100644 index 000000000..c0938fb13 --- /dev/null +++ b/test/api/cli/operations/fillEwMod_2.txt @@ -0,0 +1,3 @@ +DenseMatrix(2x2, double) +3 3 +3 3 diff --git a/test/api/cli/operations/fillEwMul_1.daphne b/test/api/cli/operations/fillEwMul_1.daphne new file mode 100644 index 000000000..57b23cf97 --- /dev/null +++ b/test/api/cli/operations/fillEwMul_1.daphne @@ -0,0 +1,3 @@ +result = fill(1,3,3) * 3; + +print(result); diff --git a/test/api/cli/operations/fillEwMul_1.txt b/test/api/cli/operations/fillEwMul_1.txt new file mode 100644 index 000000000..70b0d0a0f --- /dev/null +++ b/test/api/cli/operations/fillEwMul_1.txt @@ -0,0 +1,4 @@ +DenseMatrix(3x3, int64_t) +3 3 3 +3 3 3 +3 3 3 diff --git a/test/api/cli/operations/fillEwMul_2.daphne b/test/api/cli/operations/fillEwMul_2.daphne new file mode 100644 index 000000000..8926f20f4 --- /dev/null +++ b/test/api/cli/operations/fillEwMul_2.daphne @@ -0,0 +1,2 @@ +result = fill(2.1,3,3) * 4; +print(result); diff --git a/test/api/cli/operations/fillEwMul_2.txt b/test/api/cli/operations/fillEwMul_2.txt new file mode 100644 index 000000000..c4074dc96 --- /dev/null +++ b/test/api/cli/operations/fillEwMul_2.txt @@ -0,0 +1,4 @@ +DenseMatrix(3x3, double) +8.4 8.4 8.4 +8.4 8.4 8.4 +8.4 8.4 8.4 diff --git a/test/api/cli/operations/fillEwPow_1.daphne b/test/api/cli/operations/fillEwPow_1.daphne new file mode 100644 index 000000000..ea99ae81a --- /dev/null +++ b/test/api/cli/operations/fillEwPow_1.daphne @@ -0,0 +1,3 @@ +result = fill(3,3,3) ^ 3; + +print(result); diff --git a/test/api/cli/operations/fillEwPow_1.txt b/test/api/cli/operations/fillEwPow_1.txt new file mode 100644 index 000000000..40b58586c --- /dev/null +++ b/test/api/cli/operations/fillEwPow_1.txt @@ -0,0 +1,4 @@ +DenseMatrix(3x3, int64_t) +27 27 27 +27 27 27 +27 27 27 diff --git a/test/api/cli/operations/fillEwPow_2.daphne b/test/api/cli/operations/fillEwPow_2.daphne new file mode 100644 index 000000000..b72553359 --- /dev/null +++ b/test/api/cli/operations/fillEwPow_2.daphne @@ -0,0 +1,2 @@ +result = pow(fill(3.0,2,2),3); +print(result); diff --git a/test/api/cli/operations/fillEwPow_2.txt b/test/api/cli/operations/fillEwPow_2.txt new file mode 100644 index 000000000..3f3ebd397 --- /dev/null +++ b/test/api/cli/operations/fillEwPow_2.txt @@ -0,0 +1,3 @@ +DenseMatrix(2x2, double) +27 27 +27 27 diff --git a/test/api/cli/operations/fillEwSign_1.daphne b/test/api/cli/operations/fillEwSign_1.daphne new file mode 100644 index 000000000..bc97be0b4 --- /dev/null +++ b/test/api/cli/operations/fillEwSign_1.daphne @@ -0,0 +1,4 @@ +fillIntermediate = fill(3,3,3); +result = sign(fillIntermediate); + +print(result); diff --git a/test/api/cli/operations/fillEwSign_1.txt b/test/api/cli/operations/fillEwSign_1.txt new file mode 100644 index 000000000..dce75368f --- /dev/null +++ b/test/api/cli/operations/fillEwSign_1.txt @@ -0,0 +1,4 @@ +DenseMatrix(3x3, int64_t) +1 1 1 +1 1 1 +1 1 1 diff --git a/test/api/cli/operations/fillEwSign_2.daphne b/test/api/cli/operations/fillEwSign_2.daphne new file mode 100644 index 000000000..6e277d5f4 --- /dev/null +++ b/test/api/cli/operations/fillEwSign_2.daphne @@ -0,0 +1,4 @@ +fillIntermediate = fill(-3,3,3); +result = sign(fillIntermediate); + +print(result); diff --git a/test/api/cli/operations/fillEwSign_2.txt b/test/api/cli/operations/fillEwSign_2.txt new file mode 100644 index 000000000..0010831ac --- /dev/null +++ b/test/api/cli/operations/fillEwSign_2.txt @@ -0,0 +1,4 @@ +DenseMatrix(3x3, int64_t) +-1 -1 -1 +-1 -1 -1 +-1 -1 -1 diff --git a/test/api/cli/operations/fillEwSqrt_1.daphne b/test/api/cli/operations/fillEwSqrt_1.daphne new file mode 100644 index 000000000..8e0e49b84 --- /dev/null +++ b/test/api/cli/operations/fillEwSqrt_1.daphne @@ -0,0 +1,4 @@ +fillIntermediate = fill(9,3,3); +result = sqrt(fillIntermediate); + +print(result); diff --git a/test/api/cli/operations/fillEwSqrt_1.txt b/test/api/cli/operations/fillEwSqrt_1.txt new file mode 100644 index 000000000..20b3eb67f --- /dev/null +++ b/test/api/cli/operations/fillEwSqrt_1.txt @@ -0,0 +1,4 @@ +DenseMatrix(3x3, double) +3 3 3 +3 3 3 +3 3 3 diff --git a/test/api/cli/operations/fillEwSub_1.daphne b/test/api/cli/operations/fillEwSub_1.daphne new file mode 100644 index 000000000..80851fa06 --- /dev/null +++ b/test/api/cli/operations/fillEwSub_1.daphne @@ -0,0 +1,3 @@ +result = fill(3,3,3) - 2; + +print(result); diff --git a/test/api/cli/operations/fillEwSub_1.txt b/test/api/cli/operations/fillEwSub_1.txt new file mode 100644 index 000000000..dce75368f --- /dev/null +++ b/test/api/cli/operations/fillEwSub_1.txt @@ -0,0 +1,4 @@ +DenseMatrix(3x3, int64_t) +1 1 1 +1 1 1 +1 1 1 diff --git a/test/api/cli/operations/fillEwSub_2.daphne b/test/api/cli/operations/fillEwSub_2.daphne new file mode 100644 index 000000000..43485d999 --- /dev/null +++ b/test/api/cli/operations/fillEwSub_2.daphne @@ -0,0 +1,3 @@ +result = 4 - fill(5.0,3,3); + +print(result); diff --git a/test/api/cli/operations/fillEwSub_2.txt b/test/api/cli/operations/fillEwSub_2.txt new file mode 100644 index 000000000..acbdf26f7 --- /dev/null +++ b/test/api/cli/operations/fillEwSub_2.txt @@ -0,0 +1,4 @@ +DenseMatrix(3x3, double) +-1 -1 -1 +-1 -1 -1 +-1 -1 -1 diff --git a/test/api/cli/operations/randEwAbs_1.daphne b/test/api/cli/operations/randEwAbs_1.daphne new file mode 100644 index 000000000..a7a96d6fc --- /dev/null +++ b/test/api/cli/operations/randEwAbs_1.daphne @@ -0,0 +1,4 @@ +randIntermediate = rand(2,2,0,3,1.0,7); +result = abs(randIntermediate); + +print(result); diff --git a/test/api/cli/operations/randEwAbs_1.txt b/test/api/cli/operations/randEwAbs_1.txt new file mode 100644 index 000000000..32df357aa --- /dev/null +++ b/test/api/cli/operations/randEwAbs_1.txt @@ -0,0 +1,3 @@ +DenseMatrix(2x2, int64_t) +3 1 +1 3 diff --git a/test/api/cli/operations/randEwAbs_2.daphne b/test/api/cli/operations/randEwAbs_2.daphne new file mode 100644 index 000000000..ab690fc1e --- /dev/null +++ b/test/api/cli/operations/randEwAbs_2.daphne @@ -0,0 +1,4 @@ +randIntermediate = rand(2,3,-3,-1,1.0,7); +result = abs(randIntermediate); + +print(result); diff --git a/test/api/cli/operations/randEwAbs_2.txt b/test/api/cli/operations/randEwAbs_2.txt new file mode 100644 index 000000000..7276699a9 --- /dev/null +++ b/test/api/cli/operations/randEwAbs_2.txt @@ -0,0 +1,3 @@ +DenseMatrix(2x3, int64_t) +1 1 3 +1 2 3 diff --git a/test/api/cli/operations/randEwAbs_3.daphne b/test/api/cli/operations/randEwAbs_3.daphne new file mode 100644 index 000000000..aaac0e0cd --- /dev/null +++ b/test/api/cli/operations/randEwAbs_3.daphne @@ -0,0 +1,3 @@ +a = abs(rand(3, 2, -77, -77, 0.8, 7)); +print(a); + diff --git a/test/api/cli/operations/randEwAbs_3.txt b/test/api/cli/operations/randEwAbs_3.txt new file mode 100644 index 000000000..d161ecdd7 --- /dev/null +++ b/test/api/cli/operations/randEwAbs_3.txt @@ -0,0 +1,4 @@ +DenseMatrix(3x2, int64_t) +0 77 +77 77 +77 77 diff --git a/test/api/cli/operations/randEwAdd_1.daphne b/test/api/cli/operations/randEwAdd_1.daphne new file mode 100644 index 000000000..44ce6a1ee --- /dev/null +++ b/test/api/cli/operations/randEwAdd_1.daphne @@ -0,0 +1,4 @@ +b = rand(2,2,0,3,1.0,-1) + 2; +print(max(b,5)); +print(min(b,2)); + diff --git a/test/api/cli/operations/randEwAdd_1.txt b/test/api/cli/operations/randEwAdd_1.txt new file mode 100644 index 000000000..38878b9d0 --- /dev/null +++ b/test/api/cli/operations/randEwAdd_1.txt @@ -0,0 +1,6 @@ +DenseMatrix(2x2, int64_t) +5 5 +5 5 +DenseMatrix(2x2, int64_t) +2 2 +2 2 diff --git a/test/api/cli/operations/randEwAdd_2.daphne b/test/api/cli/operations/randEwAdd_2.daphne new file mode 100644 index 000000000..9be342f47 --- /dev/null +++ b/test/api/cli/operations/randEwAdd_2.daphne @@ -0,0 +1,2 @@ +a = rand(2, 3, 100, 200, 1.0, 7) + 10; +print(a); diff --git a/test/api/cli/operations/randEwAdd_2.txt b/test/api/cli/operations/randEwAdd_2.txt new file mode 100644 index 000000000..c5e2e48e0 --- /dev/null +++ b/test/api/cli/operations/randEwAdd_2.txt @@ -0,0 +1,3 @@ +DenseMatrix(2x3, int64_t) +117 132 188 +142 154 208 diff --git a/test/api/cli/operations/randEwDiv_1.daphne b/test/api/cli/operations/randEwDiv_1.daphne new file mode 100644 index 000000000..11322664a --- /dev/null +++ b/test/api/cli/operations/randEwDiv_1.daphne @@ -0,0 +1,4 @@ +b = rand(2,2,-1,3,1.0,-1) / 2; +print(max(b,1.5)); +print(min(b,-0.5)); + diff --git a/test/api/cli/operations/randEwDiv_1.txt b/test/api/cli/operations/randEwDiv_1.txt new file mode 100644 index 000000000..dd65724a7 --- /dev/null +++ b/test/api/cli/operations/randEwDiv_1.txt @@ -0,0 +1,6 @@ +DenseMatrix(2x2, double) +1.5 1.5 +1.5 1.5 +DenseMatrix(2x2, double) +-0.5 -0.5 +-0.5 -0.5 diff --git a/test/api/cli/operations/randEwDiv_2.daphne b/test/api/cli/operations/randEwDiv_2.daphne new file mode 100644 index 000000000..0f6ad9441 --- /dev/null +++ b/test/api/cli/operations/randEwDiv_2.daphne @@ -0,0 +1,2 @@ +a = rand(4,2,100,300,1.0,7) / 100; +print(a); diff --git a/test/api/cli/operations/randEwDiv_2.txt b/test/api/cli/operations/randEwDiv_2.txt new file mode 100644 index 000000000..3d0115ac7 --- /dev/null +++ b/test/api/cli/operations/randEwDiv_2.txt @@ -0,0 +1,5 @@ +DenseMatrix(4x2, int64_t) +1 1 +2 1 +1 2 +2 1 diff --git a/test/api/cli/operations/randEwDiv_3.daphne b/test/api/cli/operations/randEwDiv_3.daphne new file mode 100644 index 000000000..c553b492e --- /dev/null +++ b/test/api/cli/operations/randEwDiv_3.daphne @@ -0,0 +1,2 @@ +a = rand(4,2,100.0,300.0,1.0,7) / 100; +print(a); diff --git a/test/api/cli/operations/randEwDiv_3.txt b/test/api/cli/operations/randEwDiv_3.txt new file mode 100644 index 000000000..cdf15d44a --- /dev/null +++ b/test/api/cli/operations/randEwDiv_3.txt @@ -0,0 +1,5 @@ +DenseMatrix(4x2, double) +1.45468 1.63794 +2.95645 1.91117 +1.61603 1.52774 +1.17349 1.83874 diff --git a/test/api/cli/operations/randEwMinus_1.daphne b/test/api/cli/operations/randEwMinus_1.daphne new file mode 100644 index 000000000..a8f876943 --- /dev/null +++ b/test/api/cli/operations/randEwMinus_1.daphne @@ -0,0 +1,3 @@ +b = - rand(1,3,3,6,1.0,7); +print(b); + diff --git a/test/api/cli/operations/randEwMinus_1.txt b/test/api/cli/operations/randEwMinus_1.txt new file mode 100644 index 000000000..c63a73bd1 --- /dev/null +++ b/test/api/cli/operations/randEwMinus_1.txt @@ -0,0 +1,2 @@ +DenseMatrix(1x3, int64_t) +-3 -3 -6 diff --git a/test/api/cli/operations/randEwMinus_2.daphne b/test/api/cli/operations/randEwMinus_2.daphne new file mode 100644 index 000000000..22fed46de --- /dev/null +++ b/test/api/cli/operations/randEwMinus_2.daphne @@ -0,0 +1,3 @@ +b = - rand(1,3,-6,-3,1.0,7); +print(b); + diff --git a/test/api/cli/operations/randEwMinus_2.txt b/test/api/cli/operations/randEwMinus_2.txt new file mode 100644 index 000000000..a88708ef0 --- /dev/null +++ b/test/api/cli/operations/randEwMinus_2.txt @@ -0,0 +1,2 @@ +DenseMatrix(1x3, int64_t) +6 6 3 diff --git a/test/api/cli/operations/randEwMinus_3.daphne b/test/api/cli/operations/randEwMinus_3.daphne new file mode 100644 index 000000000..af6d5ed05 --- /dev/null +++ b/test/api/cli/operations/randEwMinus_3.daphne @@ -0,0 +1,3 @@ +b = - rand(1,3,-3,6,1.0,7); +print(b); + diff --git a/test/api/cli/operations/randEwMinus_3.txt b/test/api/cli/operations/randEwMinus_3.txt new file mode 100644 index 000000000..9ea52421c --- /dev/null +++ b/test/api/cli/operations/randEwMinus_3.txt @@ -0,0 +1,2 @@ +DenseMatrix(1x3, int64_t) +3 1 -4 diff --git a/test/api/cli/operations/randEwMul_1.daphne b/test/api/cli/operations/randEwMul_1.daphne new file mode 100644 index 000000000..9bece2087 --- /dev/null +++ b/test/api/cli/operations/randEwMul_1.daphne @@ -0,0 +1,4 @@ +b = rand(2,2,0,3,1.0,-1) * 2; +print(max(b,6)); +print(min(b,0)); + diff --git a/test/api/cli/operations/randEwMul_1.txt b/test/api/cli/operations/randEwMul_1.txt new file mode 100644 index 000000000..ad6a8ff14 --- /dev/null +++ b/test/api/cli/operations/randEwMul_1.txt @@ -0,0 +1,6 @@ +DenseMatrix(2x2, int64_t) +6 6 +6 6 +DenseMatrix(2x2, int64_t) +0 0 +0 0 diff --git a/test/api/cli/operations/randEwMul_2.daphne b/test/api/cli/operations/randEwMul_2.daphne new file mode 100644 index 000000000..04d5a9730 --- /dev/null +++ b/test/api/cli/operations/randEwMul_2.daphne @@ -0,0 +1,2 @@ +a = rand(4,2,1,3,1.0,7) * 100; +print(a); diff --git a/test/api/cli/operations/randEwMul_2.txt b/test/api/cli/operations/randEwMul_2.txt new file mode 100644 index 000000000..aa3cf0d8a --- /dev/null +++ b/test/api/cli/operations/randEwMul_2.txt @@ -0,0 +1,5 @@ +DenseMatrix(4x2, int64_t) +100 100 +300 100 +200 300 +300 200 diff --git a/test/api/cli/operations/randEwMul_3.daphne b/test/api/cli/operations/randEwMul_3.daphne new file mode 100644 index 000000000..b8a2d1a13 --- /dev/null +++ b/test/api/cli/operations/randEwMul_3.daphne @@ -0,0 +1,2 @@ +a = rand(4,2,1.0,3.0,1.0,7) * 100; +print(a); diff --git a/test/api/cli/operations/randEwMul_3.txt b/test/api/cli/operations/randEwMul_3.txt new file mode 100644 index 000000000..53742745e --- /dev/null +++ b/test/api/cli/operations/randEwMul_3.txt @@ -0,0 +1,5 @@ +DenseMatrix(4x2, double) +145.468 163.794 +295.645 191.117 +161.603 152.774 +117.349 183.874 diff --git a/test/api/cli/operations/randEwSub_1.daphne b/test/api/cli/operations/randEwSub_1.daphne new file mode 100644 index 000000000..49c59d592 --- /dev/null +++ b/test/api/cli/operations/randEwSub_1.daphne @@ -0,0 +1,4 @@ +b = rand(2,2,0,3,1.0,-1) - 2; +print(max(b,1)); +print(min(b,-2)); + diff --git a/test/api/cli/operations/randEwSub_1.txt b/test/api/cli/operations/randEwSub_1.txt new file mode 100644 index 000000000..fdadb4d72 --- /dev/null +++ b/test/api/cli/operations/randEwSub_1.txt @@ -0,0 +1,6 @@ +DenseMatrix(2x2, int64_t) +1 1 +1 1 +DenseMatrix(2x2, int64_t) +-2 -2 +-2 -2 diff --git a/test/api/cli/operations/seqEwAdd_1.daphne b/test/api/cli/operations/seqEwAdd_1.daphne new file mode 100644 index 000000000..280750f68 --- /dev/null +++ b/test/api/cli/operations/seqEwAdd_1.daphne @@ -0,0 +1,3 @@ +result = seq(1,5,2) + 2; + +print(result); diff --git a/test/api/cli/operations/seqEwAdd_1.txt b/test/api/cli/operations/seqEwAdd_1.txt new file mode 100644 index 000000000..ee9b13681 --- /dev/null +++ b/test/api/cli/operations/seqEwAdd_1.txt @@ -0,0 +1,4 @@ +DenseMatrix(3x1, int64_t) +3 +5 +7 diff --git a/test/api/cli/operations/seqEwAdd_2.daphne b/test/api/cli/operations/seqEwAdd_2.daphne new file mode 100644 index 000000000..c445752aa --- /dev/null +++ b/test/api/cli/operations/seqEwAdd_2.daphne @@ -0,0 +1,3 @@ +result = seq(1,5) + 2; + +print(result); diff --git a/test/api/cli/operations/seqEwAdd_2.txt b/test/api/cli/operations/seqEwAdd_2.txt new file mode 100644 index 000000000..9b84cc131 --- /dev/null +++ b/test/api/cli/operations/seqEwAdd_2.txt @@ -0,0 +1,6 @@ +DenseMatrix(5x1, int64_t) +3 +4 +5 +6 +7 diff --git a/test/api/cli/operations/seqEwDiv_1.daphne b/test/api/cli/operations/seqEwDiv_1.daphne new file mode 100644 index 000000000..59d0f0a84 --- /dev/null +++ b/test/api/cli/operations/seqEwDiv_1.daphne @@ -0,0 +1,2 @@ +a = seq(2, 6, 2) / 2; +print(a); diff --git a/test/api/cli/operations/seqEwDiv_1.txt b/test/api/cli/operations/seqEwDiv_1.txt new file mode 100644 index 000000000..2b82ce0b4 --- /dev/null +++ b/test/api/cli/operations/seqEwDiv_1.txt @@ -0,0 +1,4 @@ +DenseMatrix(3x1, int64_t) +1 +2 +3 diff --git a/test/api/cli/operations/seqEwDiv_2.daphne b/test/api/cli/operations/seqEwDiv_2.daphne new file mode 100644 index 000000000..b7115a69f --- /dev/null +++ b/test/api/cli/operations/seqEwDiv_2.daphne @@ -0,0 +1,2 @@ +a = seq(2, 14, 3) / 2; +print(a); diff --git a/test/api/cli/operations/seqEwDiv_2.txt b/test/api/cli/operations/seqEwDiv_2.txt new file mode 100644 index 000000000..849139ecb --- /dev/null +++ b/test/api/cli/operations/seqEwDiv_2.txt @@ -0,0 +1,6 @@ +DenseMatrix(5x1, int64_t) +1 +2 +4 +5 +7 diff --git a/test/api/cli/operations/seqEwDiv_3.daphne b/test/api/cli/operations/seqEwDiv_3.daphne new file mode 100644 index 000000000..5a41d7879 --- /dev/null +++ b/test/api/cli/operations/seqEwDiv_3.daphne @@ -0,0 +1,2 @@ +a = seq(2, 14, 3) / 2.5; +print(a); diff --git a/test/api/cli/operations/seqEwDiv_3.txt b/test/api/cli/operations/seqEwDiv_3.txt new file mode 100644 index 000000000..ab2b1348d --- /dev/null +++ b/test/api/cli/operations/seqEwDiv_3.txt @@ -0,0 +1,6 @@ +DenseMatrix(5x1, double) +0.8 +2 +3.2 +4.4 +5.6 diff --git a/test/api/cli/operations/seqEwMul_1.daphne b/test/api/cli/operations/seqEwMul_1.daphne new file mode 100644 index 000000000..886e07805 --- /dev/null +++ b/test/api/cli/operations/seqEwMul_1.daphne @@ -0,0 +1,3 @@ +result = seq(1,5,2) * 2; + +print(result); diff --git a/test/api/cli/operations/seqEwMul_1.txt b/test/api/cli/operations/seqEwMul_1.txt new file mode 100644 index 000000000..12fb0b22a --- /dev/null +++ b/test/api/cli/operations/seqEwMul_1.txt @@ -0,0 +1,4 @@ +DenseMatrix(3x1, int64_t) +2 +6 +10 diff --git a/test/api/cli/operations/seqEwMul_2.daphne b/test/api/cli/operations/seqEwMul_2.daphne new file mode 100644 index 000000000..84f9e193c --- /dev/null +++ b/test/api/cli/operations/seqEwMul_2.daphne @@ -0,0 +1,3 @@ +result = seq(1,5) * 2; + +print(result); diff --git a/test/api/cli/operations/seqEwMul_2.txt b/test/api/cli/operations/seqEwMul_2.txt new file mode 100644 index 000000000..4d7544948 --- /dev/null +++ b/test/api/cli/operations/seqEwMul_2.txt @@ -0,0 +1,6 @@ +DenseMatrix(5x1, int64_t) +2 +4 +6 +8 +10 diff --git a/test/api/cli/operations/seqEwMul_3.daphne b/test/api/cli/operations/seqEwMul_3.daphne new file mode 100644 index 000000000..450fac71d --- /dev/null +++ b/test/api/cli/operations/seqEwMul_3.daphne @@ -0,0 +1,3 @@ +result = seq(1,9,2) * 2.5; + +print(result); diff --git a/test/api/cli/operations/seqEwMul_3.txt b/test/api/cli/operations/seqEwMul_3.txt new file mode 100644 index 000000000..0690d8fc1 --- /dev/null +++ b/test/api/cli/operations/seqEwMul_3.txt @@ -0,0 +1,6 @@ +DenseMatrix(5x1, double) +2.5 +7.5 +12.5 +17.5 +22.5 diff --git a/test/api/cli/operations/seqEwSub_1.daphne b/test/api/cli/operations/seqEwSub_1.daphne new file mode 100644 index 000000000..91c86baae --- /dev/null +++ b/test/api/cli/operations/seqEwSub_1.daphne @@ -0,0 +1,3 @@ +result = seq(1,5,2) - 2; + +print(result); diff --git a/test/api/cli/operations/seqEwSub_1.txt b/test/api/cli/operations/seqEwSub_1.txt new file mode 100644 index 000000000..30dcb7418 --- /dev/null +++ b/test/api/cli/operations/seqEwSub_1.txt @@ -0,0 +1,4 @@ +DenseMatrix(3x1, int64_t) +-1 +1 +3 diff --git a/test/api/cli/operations/seqEwSub_2.daphne b/test/api/cli/operations/seqEwSub_2.daphne new file mode 100644 index 000000000..e10acd1b3 --- /dev/null +++ b/test/api/cli/operations/seqEwSub_2.daphne @@ -0,0 +1,3 @@ +result = seq(1,5) - 2; + +print(result); diff --git a/test/api/cli/operations/seqEwSub_2.txt b/test/api/cli/operations/seqEwSub_2.txt new file mode 100644 index 000000000..4a9e48107 --- /dev/null +++ b/test/api/cli/operations/seqEwSub_2.txt @@ -0,0 +1,6 @@ +DenseMatrix(5x1, int64_t) +-1 +0 +1 +2 +3 diff --git a/test/ir/daphneir/PushdownArithmetics.cpp b/test/ir/daphneir/PushdownArithmetics.cpp new file mode 100644 index 000000000..75e3a49cf --- /dev/null +++ b/test/ir/daphneir/PushdownArithmetics.cpp @@ -0,0 +1,41 @@ +/* + * Copyright 2025 The DAPHNE Consortium + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "run_tests.h" + +#include "api/cli/StatusCode.h" +#include "api/cli/Utils.h" + +#include + +const std::string dirPath = "test/ir/daphneir/pushdown_arithmetics/"; + +// Place all test files with FileCheck directives in the dirPath. +// LIT will test all *.mlir files in the directory. +TEST_CASE("pushdown_arithmetics", TAG_CODEGEN TAG_MATMUL) { + std::stringstream out; + std::stringstream err; + + int status = runLIT(out, err, dirPath); + + if (status != StatusCode::SUCCESS) { + std::cout << "runLIT return status: " << std::to_string(status) << "\n"; + std::cout << "runLIT out:\n" << out.str() << "\n"; + std::cout << "runLIT err:\n" << err.str() << "\n"; + } + + CHECK(status == StatusCode::SUCCESS); +} diff --git a/test/ir/daphneir/pushdown_arithmetics/.gitignore b/test/ir/daphneir/pushdown_arithmetics/.gitignore new file mode 100644 index 000000000..2098499ce --- /dev/null +++ b/test/ir/daphneir/pushdown_arithmetics/.gitignore @@ -0,0 +1,3 @@ +.lit_test_times.txt +Output/ + diff --git a/test/ir/daphneir/pushdown_arithmetics/fillEwAbs.mlir b/test/ir/daphneir/pushdown_arithmetics/fillEwAbs.mlir new file mode 100644 index 000000000..c58ddb1c4 --- /dev/null +++ b/test/ir/daphneir/pushdown_arithmetics/fillEwAbs.mlir @@ -0,0 +1,17 @@ +// RUN: daphne-opt --canonicalize --inline %s | FileCheck %s + +module { + func.func @main() { + %0 = "daphne.constant"() {value = 3 : index} : () -> index + %1 = "daphne.constant"() {value = -3 : si64} : () -> si64 + %2 = "daphne.constant"() {value = false} : () -> i1 + %3 = "daphne.constant"() {value = true} : () -> i1 + // CHECK: daphne.fill + // CHECK-NOT: daphne.fill + %4 = "daphne.fill"(%1, %0, %0) : (si64, index, index) -> !daphne.Matrix + // CHECK-NOT: daphne.ewAbs + %5 = "daphne.ewAbs"(%4) : (!daphne.Matrix) -> !daphne.Matrix + "daphne.print"(%5, %3, %2) : (!daphne.Matrix, i1, i1) -> () + "daphne.return"() : () -> () + } +} diff --git a/test/ir/daphneir/pushdown_arithmetics/fillEwAdd.mlir b/test/ir/daphneir/pushdown_arithmetics/fillEwAdd.mlir new file mode 100644 index 000000000..e356fcc48 --- /dev/null +++ b/test/ir/daphneir/pushdown_arithmetics/fillEwAdd.mlir @@ -0,0 +1,22 @@ +// RUN: daphne-opt --canonicalize --inline %s | FileCheck %s + +module { + func.func @main() { + %0 = "daphne.constant"() {value = 1 : si64} : () -> si64 + %1 = "daphne.constant"() {value = 4 : si64} : () -> si64 + %2 = "daphne.constant"() {value = 3 : si64} : () -> si64 + %3 = "daphne.constant"() {value = 3 : si64} : () -> si64 + %4 = "daphne.cast"(%2) : (si64) -> index + %5 = "daphne.cast"(%3) : (si64) -> index + // CHECK: daphne.fill + // CHECK-NOT: daphne.fill + %6 = "daphne.fill"(%1, %4, %5) : (si64, index, index) -> !daphne.Matrix + // CHECK-NOT: daphne.ewAdd + %7 = "daphne.ewAdd"(%0, %6) : (si64, !daphne.Matrix) -> !daphne.Matrix + %8 = "daphne.constant"() {value = true} : () -> i1 + %9 = "daphne.constant"() {value = false} : () -> i1 + "daphne.print"(%7, %8, %9) : (!daphne.Matrix, i1, i1) -> () + "daphne.return"() : () -> () + } +} + diff --git a/test/ir/daphneir/pushdown_arithmetics/fillEwDiv.mlir b/test/ir/daphneir/pushdown_arithmetics/fillEwDiv.mlir new file mode 100644 index 000000000..9aab0adbc --- /dev/null +++ b/test/ir/daphneir/pushdown_arithmetics/fillEwDiv.mlir @@ -0,0 +1,22 @@ +// RUN: daphne-opt --canonicalize --inline %s | FileCheck %s + +module { + func.func @main() { + %0 = "daphne.constant"() {value = 4 : si64} : () -> si64 + %1 = "daphne.constant"() {value = 3 : si64} : () -> si64 + %2 = "daphne.constant"() {value = 3 : si64} : () -> si64 + %3 = "daphne.cast"(%1) : (si64) -> index + %4 = "daphne.cast"(%2) : (si64) -> index + // CHECK: daphne.fill + // CHECK-NOT: daphne.fill + %5 = "daphne.fill"(%0, %3, %4) : (si64, index, index) -> !daphne.Matrix + %6 = "daphne.constant"() {value = 2 : si64} : () -> si64 + // CHECK-NOT: daphne.ewDiv + %7 = "daphne.ewDiv"(%5, %6) : (!daphne.Matrix, si64) -> !daphne.Matrix + %8 = "daphne.constant"() {value = true} : () -> i1 + %9 = "daphne.constant"() {value = false} : () -> i1 + "daphne.print"(%7, %8, %9) : (!daphne.Matrix, i1, i1) -> () + "daphne.return"() : () -> () + } +} + diff --git a/test/ir/daphneir/pushdown_arithmetics/fillEwExp.mlir b/test/ir/daphneir/pushdown_arithmetics/fillEwExp.mlir new file mode 100644 index 000000000..4f5944747 --- /dev/null +++ b/test/ir/daphneir/pushdown_arithmetics/fillEwExp.mlir @@ -0,0 +1,17 @@ +// RUN: daphne-opt --canonicalize --inline %s | FileCheck %s + +module { + func.func @main() { + %0 = "daphne.constant"() {value = 3 : index} : () -> index + %1 = "daphne.constant"() {value = -3 : si64} : () -> si64 + %2 = "daphne.constant"() {value = false} : () -> i1 + %3 = "daphne.constant"() {value = true} : () -> i1 + // CHECK: daphne.fill + // CHECK-NOT: daphne.fill + %4 = "daphne.fill"(%1, %0, %0) : (si64, index, index) -> !daphne.Matrix + // CHECK-NOT: daphne.ewExp + %5 = "daphne.ewExp"(%4) : (!daphne.Matrix) -> !daphne.Matrix + "daphne.print"(%5, %3, %2) : (!daphne.Matrix, i1, i1) -> () + "daphne.return"() : () -> () + } +} diff --git a/test/ir/daphneir/pushdown_arithmetics/fillEwLn.mlir b/test/ir/daphneir/pushdown_arithmetics/fillEwLn.mlir new file mode 100644 index 000000000..89a4c2947 --- /dev/null +++ b/test/ir/daphneir/pushdown_arithmetics/fillEwLn.mlir @@ -0,0 +1,17 @@ +// RUN: daphne-opt --canonicalize --inline %s | FileCheck %s + +module { + func.func @main() { + %0 = "daphne.constant"() {value = 3 : index} : () -> index + %1 = "daphne.constant"() {value = -3 : si64} : () -> si64 + %2 = "daphne.constant"() {value = false} : () -> i1 + %3 = "daphne.constant"() {value = true} : () -> i1 + // CHECK: daphne.fill + // CHECK-NOT: daphne.fill + %4 = "daphne.fill"(%1, %0, %0) : (si64, index, index) -> !daphne.Matrix + // CHECK-NOT: daphne.ewLn + %5 = "daphne.ewLn"(%4) : (!daphne.Matrix) -> !daphne.Matrix + "daphne.print"(%5, %3, %2) : (!daphne.Matrix, i1, i1) -> () + "daphne.return"() : () -> () + } +} diff --git a/test/ir/daphneir/pushdown_arithmetics/fillEwLog.mlir b/test/ir/daphneir/pushdown_arithmetics/fillEwLog.mlir new file mode 100644 index 000000000..972be35fb --- /dev/null +++ b/test/ir/daphneir/pushdown_arithmetics/fillEwLog.mlir @@ -0,0 +1,22 @@ +// RUN: daphne-opt --canonicalize --inline %s | FileCheck %s + +module { + func.func @main() { + %0 = "daphne.constant"() {value = 8.000000e+00 : f64} : () -> f64 + %1 = "daphne.constant"() {value = 3 : si64} : () -> si64 + %2 = "daphne.constant"() {value = 3 : si64} : () -> si64 + %3 = "daphne.cast"(%1) : (si64) -> index + %4 = "daphne.cast"(%2) : (si64) -> index + // CHECK: daphne.fill + // CHECK-NOT: daphne.fill + %5 = "daphne.fill"(%0, %3, %4) : (f64, index, index) -> !daphne.Matrix + %6 = "daphne.constant"() {value = 2 : si64} : () -> si64 + // CHECK-NOT: daphne.ewLog + %7 = "daphne.ewLog"(%5, %6) : (!daphne.Matrix, si64) -> !daphne.Matrix + %8 = "daphne.constant"() {value = true} : () -> i1 + %9 = "daphne.constant"() {value = false} : () -> i1 + "daphne.print"(%7, %8, %9) : (!daphne.Matrix, i1, i1) -> () + "daphne.return"() : () -> () + + } +} diff --git a/test/ir/daphneir/pushdown_arithmetics/fillEwMinus.mlir b/test/ir/daphneir/pushdown_arithmetics/fillEwMinus.mlir new file mode 100644 index 000000000..242c7bae6 --- /dev/null +++ b/test/ir/daphneir/pushdown_arithmetics/fillEwMinus.mlir @@ -0,0 +1,18 @@ +// RUN: daphne-opt --canonicalize --inline %s | FileCheck %s +module { + func.func @main() { + %0 = "daphne.constant"() {value = 1 : index} : () -> index + %1 = "daphne.constant"() {value = 3 : index} : () -> index + %2 = "daphne.constant"() {value = false} : () -> i1 + %3 = "daphne.constant"() {value = true} : () -> i1 + %4 = "daphne.constant"() {value = 1 : si64} : () -> si64 + // CHECK: daphne.fill + // CHECK-NOT: daphne.fill + %5 = "daphne.fill"(%4, %1, %0) : (si64, index, index) -> !daphne.Matrix + // CHECK-NOT: daphne.ewMinus + %6 = "daphne.ewMinus"(%5) : (!daphne.Matrix) -> !daphne.Matrix + "daphne.print"(%6, %3, %2) : (!daphne.Matrix, i1, i1) -> () + "daphne.return"() : () -> () + + } +} diff --git a/test/ir/daphneir/pushdown_arithmetics/fillEwMod.mlir b/test/ir/daphneir/pushdown_arithmetics/fillEwMod.mlir new file mode 100644 index 000000000..28260c343 --- /dev/null +++ b/test/ir/daphneir/pushdown_arithmetics/fillEwMod.mlir @@ -0,0 +1,21 @@ +// RUN: daphne-opt --canonicalize --inline %s | FileCheck %s + +module { + func.func @main() { + %0 = "daphne.constant"() {value = 4 : si64} : () -> si64 + %1 = "daphne.constant"() {value = 3 : si64} : () -> si64 + %2 = "daphne.constant"() {value = 3 : si64} : () -> si64 + %3 = "daphne.cast"(%1) : (si64) -> index + %4 = "daphne.cast"(%2) : (si64) -> index + // CHECK: daphne.fill + // CHECK-NOT: daphne.fill + %5 = "daphne.fill"(%0, %3, %4) : (si64, index, index) -> !daphne.Matrix + %6 = "daphne.constant"() {value = 5 : si64} : () -> si64 + // CHECK-NOT: daphne.ewMod + %7 = "daphne.ewMod"(%5, %6) : (!daphne.Matrix, si64) -> !daphne.Matrix + %8 = "daphne.constant"() {value = true} : () -> i1 + %9 = "daphne.constant"() {value = false} : () -> i1 + "daphne.print"(%7, %8, %9) : (!daphne.Matrix, i1, i1) -> () + "daphne.return"() : () -> () + } +} diff --git a/test/ir/daphneir/pushdown_arithmetics/fillEwMul.mlir b/test/ir/daphneir/pushdown_arithmetics/fillEwMul.mlir new file mode 100644 index 000000000..ba873d680 --- /dev/null +++ b/test/ir/daphneir/pushdown_arithmetics/fillEwMul.mlir @@ -0,0 +1,23 @@ +// RUN: daphne-opt --canonicalize --inline %s | FileCheck %s + +module { + func.func @main() { + %0 = "daphne.constant"() {value = 4 : si64} : () -> si64 + %1 = "daphne.constant"() {value = 3 : si64} : () -> si64 + %2 = "daphne.constant"() {value = 3 : si64} : () -> si64 + %3 = "daphne.cast"(%1) : (si64) -> index + %4 = "daphne.cast"(%2) : (si64) -> index + // CHECK: daphne.fill + // CHECK-NOT: daphne.fill + %5 = "daphne.fill"(%0, %3, %4) : (si64, index, index) -> !daphne.Matrix + %6 = "daphne.constant"() {value = 2 : si64} : () -> si64 + // CHECK-NOT: daphne.ewMul + %7 = "daphne.ewMul"(%5, %6) : (!daphne.Matrix, si64) -> !daphne.Matrix + %8 = "daphne.constant"() {value = true} : () -> i1 + %9 = "daphne.constant"() {value = false} : () -> i1 + "daphne.print"(%7, %8, %9) : (!daphne.Matrix, i1, i1) -> () + "daphne.return"() : () -> () + } +} + + diff --git a/test/ir/daphneir/pushdown_arithmetics/fillEwPow.mlir b/test/ir/daphneir/pushdown_arithmetics/fillEwPow.mlir new file mode 100644 index 000000000..72ce33012 --- /dev/null +++ b/test/ir/daphneir/pushdown_arithmetics/fillEwPow.mlir @@ -0,0 +1,23 @@ +// RUN: daphne-opt --canonicalize --inline %s | FileCheck %s + +module { + func.func @main() { + %0 = "daphne.constant"() {value = 4 : si64} : () -> si64 + %1 = "daphne.constant"() {value = 3 : si64} : () -> si64 + %2 = "daphne.constant"() {value = 3 : si64} : () -> si64 + %3 = "daphne.cast"(%1) : (si64) -> index + %4 = "daphne.cast"(%2) : (si64) -> index + // CHECK: daphne.fill + // CHECK-NOT: daphne.fill + %5 = "daphne.fill"(%0, %3, %4) : (si64, index, index) -> !daphne.Matrix + %6 = "daphne.constant"() {value = 2 : si64} : () -> si64 + // CHECK-NOT: daphne.ewPow + %7 = "daphne.ewPow"(%5, %6) : (!daphne.Matrix, si64) -> !daphne.Matrix + %8 = "daphne.constant"() {value = true} : () -> i1 + %9 = "daphne.constant"() {value = false} : () -> i1 + "daphne.print"(%7, %8, %9) : (!daphne.Matrix, i1, i1) -> () + "daphne.return"() : () -> () + } +} + + diff --git a/test/ir/daphneir/pushdown_arithmetics/fillEwSign.mlir b/test/ir/daphneir/pushdown_arithmetics/fillEwSign.mlir new file mode 100644 index 000000000..3d997bd04 --- /dev/null +++ b/test/ir/daphneir/pushdown_arithmetics/fillEwSign.mlir @@ -0,0 +1,17 @@ +// RUN: daphne-opt --canonicalize --inline %s | FileCheck %s + +module { + func.func @main() { + %0 = "daphne.constant"() {value = 3 : index} : () -> index + %1 = "daphne.constant"() {value = -3 : si64} : () -> si64 + %2 = "daphne.constant"() {value = false} : () -> i1 + %3 = "daphne.constant"() {value = true} : () -> i1 + // CHECK: daphne.fill + // CHECK-NOT: daphne.fill + %4 = "daphne.fill"(%1, %0, %0) : (si64, index, index) -> !daphne.Matrix + // CHECK-NOT: daphne.ewSign + %5 = "daphne.ewSign"(%4) : (!daphne.Matrix) -> !daphne.Matrix + "daphne.print"(%5, %3, %2) : (!daphne.Matrix, i1, i1) -> () + "daphne.return"() : () -> () + } +} diff --git a/test/ir/daphneir/pushdown_arithmetics/fillEwSqrt.mlir b/test/ir/daphneir/pushdown_arithmetics/fillEwSqrt.mlir new file mode 100644 index 000000000..a0957b140 --- /dev/null +++ b/test/ir/daphneir/pushdown_arithmetics/fillEwSqrt.mlir @@ -0,0 +1,17 @@ +// RUN: daphne-opt --canonicalize --inline %s | FileCheck %s + +module { + func.func @main() { + %0 = "daphne.constant"() {value = 3 : index} : () -> index + %1 = "daphne.constant"() {value = -3 : si64} : () -> si64 + %2 = "daphne.constant"() {value = false} : () -> i1 + %3 = "daphne.constant"() {value = true} : () -> i1 + // CHECK: daphne.fill + // CHECK-NOT: daphne.fill + %4 = "daphne.fill"(%1, %0, %0) : (si64, index, index) -> !daphne.Matrix + // CHECK-NOT: daphne.ewSqrt + %5 = "daphne.ewSqrt"(%4) : (!daphne.Matrix) -> !daphne.Matrix + "daphne.print"(%5, %3, %2) : (!daphne.Matrix, i1, i1) -> () + "daphne.return"() : () -> () + } +} diff --git a/test/ir/daphneir/pushdown_arithmetics/fillEwSub.mlir b/test/ir/daphneir/pushdown_arithmetics/fillEwSub.mlir new file mode 100644 index 000000000..6a1102eb7 --- /dev/null +++ b/test/ir/daphneir/pushdown_arithmetics/fillEwSub.mlir @@ -0,0 +1,21 @@ +// RUN: daphne-opt --canonicalize --inline %s | FileCheck %s + +module { + func.func @main() { + %0 = "daphne.constant"() {value = 4 : si64} : () -> si64 + %1 = "daphne.constant"() {value = 3 : si64} : () -> si64 + %2 = "daphne.constant"() {value = 3 : si64} : () -> si64 + %3 = "daphne.cast"(%1) : (si64) -> index + %4 = "daphne.cast"(%2) : (si64) -> index + // CHECK: daphne.fill + // CHECK-NOT: daphne.fill + %5 = "daphne.fill"(%0, %3, %4) : (si64, index, index) -> !daphne.Matrix + %6 = "daphne.constant"() {value = 2 : si64} : () -> si64 + // CHECK-NOT: daphne.ewSub + %7 = "daphne.ewSub"(%5, %6) : (!daphne.Matrix, si64) -> !daphne.Matrix + %8 = "daphne.constant"() {value = true} : () -> i1 + %9 = "daphne.constant"() {value = false} : () -> i1 + "daphne.print"(%7, %8, %9) : (!daphne.Matrix, i1, i1) -> () + "daphne.return"() : () -> () + } +} diff --git a/test/ir/daphneir/pushdown_arithmetics/lit.cfg b/test/ir/daphneir/pushdown_arithmetics/lit.cfg new file mode 100644 index 000000000..39275a712 --- /dev/null +++ b/test/ir/daphneir/pushdown_arithmetics/lit.cfg @@ -0,0 +1,17 @@ +import lit.formats +import os + +config.name = "DAPHNE LIT config for pushdown arithmetics tests" +config.test_format = lit.formats.ShTest(True) + +config.suffixes = [".mlir"] + +config.test_source_root = os.path.dirname(__file__) + +config.environment["PATH"] = os.path.pathsep.join( + ( + os.path.abspath("bin/"), + os.path.abspath("thirdparty/build/llvm-project/bin/"), + config.environment["PATH"], + ) +) diff --git a/test/ir/daphneir/pushdown_arithmetics/randEwAbs_1.mlir b/test/ir/daphneir/pushdown_arithmetics/randEwAbs_1.mlir new file mode 100644 index 000000000..9d9228dbe --- /dev/null +++ b/test/ir/daphneir/pushdown_arithmetics/randEwAbs_1.mlir @@ -0,0 +1,21 @@ +// RUN: daphne-opt --canonicalize --inline %s | FileCheck %s + +module { + func.func @main() { + %0 = "daphne.constant"() {value = 3 : index} : () -> index + %1 = "daphne.constant"() {value = -1 : si64} : () -> si64 + %2 = "daphne.constant"() {value = false} : () -> i1 + %3 = "daphne.constant"() {value = true} : () -> i1 + %4 = "daphne.constant"() {value = 3 : si64} : () -> si64 + %5 = "daphne.constant"() {value = 2 : si64} : () -> si64 + %6 = "daphne.constant"() {value = 1.000000e+00 : f64} : () -> f64 + // CHECK: daphne.randMatrix + // CHECK-NOT: daphne.randMatrix + %7 = "daphne.randMatrix"(%0, %0, %5, %4, %6, %1) : (index, index, si64, si64, f64, si64) -> !daphne.Matrix + // CHECK-NOT: daphne.ewAbs + %8 = "daphne.ewAbs"(%7) : (!daphne.Matrix) -> !daphne.Matrix + "daphne.print"(%8, %3, %2) : (!daphne.Matrix, i1, i1) -> () + "daphne.return"() : () -> () + } + +} diff --git a/test/ir/daphneir/pushdown_arithmetics/randEwAbs_2.mlir b/test/ir/daphneir/pushdown_arithmetics/randEwAbs_2.mlir new file mode 100644 index 000000000..fe51a4557 --- /dev/null +++ b/test/ir/daphneir/pushdown_arithmetics/randEwAbs_2.mlir @@ -0,0 +1,21 @@ +// RUN: daphne-opt --canonicalize --inline %s | FileCheck %s + +module { + func.func @main() { + %0 = "daphne.constant"() {value = 3 : index} : () -> index + %1 = "daphne.constant"() {value = -1 : si64} : () -> si64 + %2 = "daphne.constant"() {value = false} : () -> i1 + %3 = "daphne.constant"() {value = true} : () -> i1 + %4 = "daphne.constant"() {value = -2 : si64} : () -> si64 + %5 = "daphne.constant"() {value = -3 : si64} : () -> si64 + %6 = "daphne.constant"() {value = 1.000000e+00 : f64} : () -> f64 + // CHECK: daphne.randMatrix + // CHECK-NOT: daphne.randMatrix + %7 = "daphne.randMatrix"(%0, %0, %5, %4, %6, %1) : (index, index, si64, si64, f64, si64) -> !daphne.Matrix + // CHECK-NOT: daphne.ewAbs + %8 = "daphne.ewAbs"(%7) : (!daphne.Matrix) -> !daphne.Matrix + "daphne.print"(%8, %3, %2) : (!daphne.Matrix, i1, i1) -> () + "daphne.return"() : () -> () + } + +} diff --git a/test/ir/daphneir/pushdown_arithmetics/randEwAbs_3.mlir b/test/ir/daphneir/pushdown_arithmetics/randEwAbs_3.mlir new file mode 100644 index 000000000..33e1e4a13 --- /dev/null +++ b/test/ir/daphneir/pushdown_arithmetics/randEwAbs_3.mlir @@ -0,0 +1,21 @@ +// RUN: daphne-opt --canonicalize --inline %s | FileCheck %s + +module { + func.func @main() { + %0 = "daphne.constant"() {value = 3 : index} : () -> index + %1 = "daphne.constant"() {value = -1 : si64} : () -> si64 + %2 = "daphne.constant"() {value = false} : () -> i1 + %3 = "daphne.constant"() {value = true} : () -> i1 + %4 = "daphne.constant"() {value = -77 : si64} : () -> si64 + %5 = "daphne.constant"() {value = -77 : si64} : () -> si64 + %6 = "daphne.constant"() {value = 1.000000e+00 : f64} : () -> f64 + // CHECK: daphne.randMatrix + // CHECK-NOT: daphne.randMatrix + %7 = "daphne.randMatrix"(%0, %0, %5, %4, %6, %1) : (index, index, si64, si64, f64, si64) -> !daphne.Matrix + // CHECK-NOT: daphne.ewAbs + %8 = "daphne.ewAbs"(%7) : (!daphne.Matrix) -> !daphne.Matrix + "daphne.print"(%8, %3, %2) : (!daphne.Matrix, i1, i1) -> () + "daphne.return"() : () -> () + } + +} diff --git a/test/ir/daphneir/pushdown_arithmetics/randEwAdd.mlir b/test/ir/daphneir/pushdown_arithmetics/randEwAdd.mlir new file mode 100644 index 000000000..eb398c1d2 --- /dev/null +++ b/test/ir/daphneir/pushdown_arithmetics/randEwAdd.mlir @@ -0,0 +1,27 @@ +// RUN: daphne-opt --canonicalize --inline %s | FileCheck %s + +module { + func.func @main() { + // CHECK-NOT: daphne.ewAdd + %0 = "daphne.constant"() {value = 3 : si64} : () -> si64 + %1 = "daphne.constant"() {value = 3 : si64} : () -> si64 + %2 = "daphne.constant"() {value = 0 : si64} : () -> si64 + %3 = "daphne.constant"() {value = 3 : si64} : () -> si64 + %4 = "daphne.constant"() {value = 1.000000e+00 : f64} : () -> f64 + %5 = "daphne.constant"() {value = 1 : si64} : () -> si64 + %6 = "daphne.ewMinus"(%5) : (si64) -> si64 + %7 = "daphne.cast"(%0) : (si64) -> index + %8 = "daphne.cast"(%1) : (si64) -> index + // CHECK: daphne.randMatrix + // CHECK-NOT: daphne.randMatrix + %9 = "daphne.randMatrix"(%7, %8, %2, %3, %4, %6) : (index, index, si64, si64, f64, si64) -> !daphne.Matrix + %10 = "daphne.constant"() {value = 2 : si64} : () -> si64 + %11 = "daphne.ewAdd"(%9, %10) : (!daphne.Matrix, si64) -> !daphne.Matrix + %12 = "daphne.constant"() {value = true} : () -> i1 + %13 = "daphne.constant"() {value = false} : () -> i1 + "daphne.print"(%11, %12, %13) : (!daphne.Matrix, i1, i1) -> () + "daphne.return"() : () -> () + + } +} + diff --git a/test/ir/daphneir/pushdown_arithmetics/randEwDiv_1.mlir b/test/ir/daphneir/pushdown_arithmetics/randEwDiv_1.mlir new file mode 100644 index 000000000..a0d2b4dc4 --- /dev/null +++ b/test/ir/daphneir/pushdown_arithmetics/randEwDiv_1.mlir @@ -0,0 +1,29 @@ +// RUN: daphne-opt --canonicalize --inline %s | FileCheck %s + +module { + func.func @main() { + // CHECK-NOT: daphne.ewDiv + %0 = "daphne.constant"() {value = 3 : si64} : () -> si64 + %1 = "daphne.constant"() {value = 3 : si64} : () -> si64 + %2 = "daphne.constant"() {value = 0 : si64} : () -> si64 + %3 = "daphne.constant"() {value = 8 : si64} : () -> si64 + %4 = "daphne.constant"() {value = 1.000000e+00 : f64} : () -> f64 + %5 = "daphne.constant"() {value = 1 : si64} : () -> si64 + %6 = "daphne.ewMinus"(%5) : (si64) -> si64 + %7 = "daphne.cast"(%0) : (si64) -> index + %8 = "daphne.cast"(%1) : (si64) -> index + // CHECK: daphne.randMatrix + // CHECK-NOT: daphne.randMatrix + %9 = "daphne.randMatrix"(%7, %8, %2, %3, %4, %6) : (index, index, si64, si64, f64, si64) -> !daphne.Matrix + %10 = "daphne.constant"() {value = 2 : si64} : () -> si64 + %11 = "daphne.ewDiv"(%9, %10) : (!daphne.Matrix, si64) -> !daphne.Matrix + %12 = "daphne.constant"() {value = true} : () -> i1 + %13 = "daphne.constant"() {value = false} : () -> i1 + "daphne.print"(%11, %12, %13) : (!daphne.Matrix, i1, i1) -> () + "daphne.return"() : () -> () + + } +} + + + diff --git a/test/ir/daphneir/pushdown_arithmetics/randEwDiv_2.mlir b/test/ir/daphneir/pushdown_arithmetics/randEwDiv_2.mlir new file mode 100644 index 000000000..0e26c56b5 --- /dev/null +++ b/test/ir/daphneir/pushdown_arithmetics/randEwDiv_2.mlir @@ -0,0 +1,30 @@ +// RUN: daphne-opt --canonicalize --inline %s | FileCheck %s + +module { + func.func @main() { + %0 = "daphne.constant"() {value = 3 : si64} : () -> si64 + %1 = "daphne.constant"() {value = 3 : si64} : () -> si64 + %2 = "daphne.constant"() {value = 0.0 : f64} : () -> f64 + %3 = "daphne.constant"() {value = 8.0 : f64} : () -> f64 + %4 = "daphne.constant"() {value = 1.000000e+00 : f64} : () -> f64 + %5 = "daphne.constant"() {value = 1 : si64} : () -> si64 + %6 = "daphne.ewMinus"(%5) : (si64) -> si64 + %7 = "daphne.cast"(%0) : (si64) -> index + %8 = "daphne.cast"(%1) : (si64) -> index + // CHECK: daphne.ewDiv + // CHECK: daphne.ewDiv + // CHECK: daphne.randMatrix + // CHECK-NOT: daphne.randMatrix + %9 = "daphne.randMatrix"(%7, %8, %2, %3, %4, %6) : (index, index, f64, f64, f64, si64) -> !daphne.Matrix + %10 = "daphne.constant"() {value = 2 : si64} : () -> si64 + %11 = "daphne.ewDiv"(%9, %10) : (!daphne.Matrix, si64) -> !daphne.Matrix + %12 = "daphne.constant"() {value = true} : () -> i1 + %13 = "daphne.constant"() {value = false} : () -> i1 + "daphne.print"(%11, %12, %13) : (!daphne.Matrix, i1, i1) -> () + "daphne.return"() : () -> () + + } +} + + + diff --git a/test/ir/daphneir/pushdown_arithmetics/randEwMinus.mlir b/test/ir/daphneir/pushdown_arithmetics/randEwMinus.mlir new file mode 100644 index 000000000..45e28c1cf --- /dev/null +++ b/test/ir/daphneir/pushdown_arithmetics/randEwMinus.mlir @@ -0,0 +1,22 @@ +// RUN: daphne-opt --canonicalize --inline %s | FileCheck %s + +module { + func.func @main() { + %0 = "daphne.constant"() {value = 3 : index} : () -> index + %1 = "daphne.constant"() {value = 1 : index} : () -> index + %2 = "daphne.constant"() {value = -3 : si64} : () -> si64 + %3 = "daphne.constant"() {value = -6 : si64} : () -> si64 + %4 = "daphne.constant"() {value = false} : () -> i1 + %5 = "daphne.constant"() {value = true} : () -> i1 + %6 = "daphne.constant"() {value = 7 : si64} : () -> si64 + %7 = "daphne.constant"() {value = 1.000000e+00 : f64} : () -> f64 + // CHECK: daphne.randMatrix + // CHECK-NOT: daphne.randMatrix + %8 = "daphne.randMatrix"(%1, %0, %3, %2, %7, %6) : (index, index, si64, si64, f64, si64) -> !daphne.Matrix + // CHECK-NOT: daphne.ewMinus + %9 = "daphne.ewMinus"(%8) : (!daphne.Matrix) -> !daphne.Matrix + "daphne.print"(%9, %5, %4) : (!daphne.Matrix, i1, i1) -> () + "daphne.return"() : () -> () + } +} + diff --git a/test/ir/daphneir/pushdown_arithmetics/randEwMul_1.mlir b/test/ir/daphneir/pushdown_arithmetics/randEwMul_1.mlir new file mode 100644 index 000000000..5396f023f --- /dev/null +++ b/test/ir/daphneir/pushdown_arithmetics/randEwMul_1.mlir @@ -0,0 +1,26 @@ +// RUN: daphne-opt --canonicalize --inline %s | FileCheck %s + +module { + func.func @main() { + // CHECK-NOT: daphne.ewMul + %0 = "daphne.constant"() {value = 3 : si64} : () -> si64 + %1 = "daphne.constant"() {value = 3 : si64} : () -> si64 + %2 = "daphne.constant"() {value = 0 : si64} : () -> si64 + %3 = "daphne.constant"() {value = 3 : si64} : () -> si64 + %4 = "daphne.constant"() {value = 1.000000e+00 : f64} : () -> f64 + %5 = "daphne.constant"() {value = 1 : si64} : () -> si64 + %6 = "daphne.ewMinus"(%5) : (si64) -> si64 + %7 = "daphne.cast"(%0) : (si64) -> index + %8 = "daphne.cast"(%1) : (si64) -> index + // CHECK: daphne.randMatrix + // CHECK-NOT: daphne.randMatrix + %9 = "daphne.randMatrix"(%7, %8, %2, %3, %4, %6) : (index, index, si64, si64, f64, si64) -> !daphne.Matrix + %10 = "daphne.constant"() {value = 2 : si64} : () -> si64 + %11 = "daphne.ewMul"(%9, %10) : (!daphne.Matrix, si64) -> !daphne.Matrix + %12 = "daphne.constant"() {value = true} : () -> i1 + %13 = "daphne.constant"() {value = false} : () -> i1 + "daphne.print"(%11, %12, %13) : (!daphne.Matrix, i1, i1) -> () + "daphne.return"() : () -> () + + } +} diff --git a/test/ir/daphneir/pushdown_arithmetics/randEwMul_2.mlir b/test/ir/daphneir/pushdown_arithmetics/randEwMul_2.mlir new file mode 100644 index 000000000..afe0c9eba --- /dev/null +++ b/test/ir/daphneir/pushdown_arithmetics/randEwMul_2.mlir @@ -0,0 +1,27 @@ +// RUN: daphne-opt --canonicalize --inline %s | FileCheck %s + +module { + func.func @main() { + %0 = "daphne.constant"() {value = 3 : si64} : () -> si64 + %1 = "daphne.constant"() {value = 3 : si64} : () -> si64 + %2 = "daphne.constant"() {value = 0.0 : f64} : () -> f64 + %3 = "daphne.constant"() {value = 3.0 : f64} : () -> f64 + %4 = "daphne.constant"() {value = 1.000000e+00 : f64} : () -> f64 + %5 = "daphne.constant"() {value = 1 : si64} : () -> si64 + %6 = "daphne.ewMinus"(%5) : (si64) -> si64 + %7 = "daphne.cast"(%0) : (si64) -> index + %8 = "daphne.cast"(%1) : (si64) -> index + // CHECK: daphne.ewMul + // CHECK: daphne.ewMul + // CHECK: daphne.randMatrix + // CHECK-NOT: daphne.randMatrix + %9 = "daphne.randMatrix"(%7, %8, %2, %3, %4, %6) : (index, index, f64, f64, f64, si64) -> !daphne.Matrix + %10 = "daphne.constant"() {value = 2 : si64} : () -> si64 + %11 = "daphne.ewMul"(%9, %10) : (!daphne.Matrix, si64) -> !daphne.Matrix + %12 = "daphne.constant"() {value = true} : () -> i1 + %13 = "daphne.constant"() {value = false} : () -> i1 + "daphne.print"(%11, %12, %13) : (!daphne.Matrix, i1, i1) -> () + "daphne.return"() : () -> () + + } +} diff --git a/test/ir/daphneir/pushdown_arithmetics/randEwSub.mlir b/test/ir/daphneir/pushdown_arithmetics/randEwSub.mlir new file mode 100644 index 000000000..e869233f6 --- /dev/null +++ b/test/ir/daphneir/pushdown_arithmetics/randEwSub.mlir @@ -0,0 +1,27 @@ +// RUN: daphne-opt --canonicalize --inline %s | FileCheck %s + +module { + func.func @main() { + // CHECK-NOT: daphne.ewSub + %0 = "daphne.constant"() {value = 3 : si64} : () -> si64 + %1 = "daphne.constant"() {value = 3 : si64} : () -> si64 + %2 = "daphne.constant"() {value = 0 : si64} : () -> si64 + %3 = "daphne.constant"() {value = 3 : si64} : () -> si64 + %4 = "daphne.constant"() {value = 1.000000e+00 : f64} : () -> f64 + %5 = "daphne.constant"() {value = 1 : si64} : () -> si64 + %6 = "daphne.ewMinus"(%5) : (si64) -> si64 + %7 = "daphne.cast"(%0) : (si64) -> index + %8 = "daphne.cast"(%1) : (si64) -> index + // CHECK: daphne.randMatrix + // CHECK-NOT: daphne.randMatrix + %9 = "daphne.randMatrix"(%7, %8, %2, %3, %4, %6) : (index, index, si64, si64, f64, si64) -> !daphne.Matrix + %10 = "daphne.constant"() {value = 2 : si64} : () -> si64 + %11 = "daphne.ewSub"(%9, %10) : (!daphne.Matrix, si64) -> !daphne.Matrix + %12 = "daphne.constant"() {value = true} : () -> i1 + %13 = "daphne.constant"() {value = false} : () -> i1 + "daphne.print"(%11, %12, %13) : (!daphne.Matrix, i1, i1) -> () + "daphne.return"() : () -> () + } +} + + diff --git a/test/ir/daphneir/pushdown_arithmetics/run-lit.py b/test/ir/daphneir/pushdown_arithmetics/run-lit.py new file mode 100644 index 000000000..39898435c --- /dev/null +++ b/test/ir/daphneir/pushdown_arithmetics/run-lit.py @@ -0,0 +1,4 @@ +#!/usr/bin/env python + +from lit.main import main +main() diff --git a/test/ir/daphneir/pushdown_arithmetics/seqEwAdd.mlir b/test/ir/daphneir/pushdown_arithmetics/seqEwAdd.mlir new file mode 100644 index 000000000..9ddda9feb --- /dev/null +++ b/test/ir/daphneir/pushdown_arithmetics/seqEwAdd.mlir @@ -0,0 +1,19 @@ +// RUN: daphne-opt --canonicalize --inline %s | FileCheck %s + +module { + func.func @main() { + %0 = "daphne.constant"() {value = false} : () -> i1 + %1 = "daphne.constant"() {value = true} : () -> i1 + %2 = "daphne.constant"() {value = 1 : si64} : () -> si64 + %3 = "daphne.constant"() {value = 5 : si64} : () -> si64 + %4 = "daphne.constant"() {value = 2 : si64} : () -> si64 + // CHECK: daphne.seq + // CHECK-NOT: daphne.seq + %5 = "daphne.seq"(%2, %3, %4) : (si64, si64, si64) -> !daphne.Matrix + // CHECK-NOT: ewAdd + %6 = "daphne.ewAdd"(%5, %4) : (!daphne.Matrix, si64) -> !daphne.Matrix + "daphne.print"(%6, %1, %0) : (!daphne.Matrix, i1, i1) -> () + "daphne.return"() : () -> () + } +} + diff --git a/test/ir/daphneir/pushdown_arithmetics/seqEwDiv.mlir b/test/ir/daphneir/pushdown_arithmetics/seqEwDiv.mlir new file mode 100644 index 000000000..c9cfb38b5 --- /dev/null +++ b/test/ir/daphneir/pushdown_arithmetics/seqEwDiv.mlir @@ -0,0 +1,20 @@ +// RUN: daphne-opt --canonicalize --inline %s | FileCheck %s + +module { + func.func @main() { + %0 = "daphne.constant"() {value = false} : () -> i1 + %1 = "daphne.constant"() {value = true} : () -> i1 + %2 = "daphne.constant"() {value = 1 : si64} : () -> si64 + %3 = "daphne.constant"() {value = 5 : si64} : () -> si64 + %4 = "daphne.constant"() {value = 2 : si64} : () -> si64 + // CHECK: daphne.seq + // CHECK-NOT: daphne.seq + %5 = "daphne.seq"(%2, %3, %4) : (si64, si64, si64) -> !daphne.Matrix + // CHECK-NOT: ewDiv + %6 = "daphne.ewDiv"(%5, %4) : (!daphne.Matrix, si64) -> !daphne.Matrix + "daphne.print"(%6, %1, %0) : (!daphne.Matrix, i1, i1) -> () + "daphne.return"() : () -> () + } + +} + diff --git a/test/ir/daphneir/pushdown_arithmetics/seqEwMul.mlir b/test/ir/daphneir/pushdown_arithmetics/seqEwMul.mlir new file mode 100644 index 000000000..608ef6d8f --- /dev/null +++ b/test/ir/daphneir/pushdown_arithmetics/seqEwMul.mlir @@ -0,0 +1,20 @@ +// RUN: daphne-opt --canonicalize --inline %s | FileCheck %s + +module { + func.func @main() { + %0 = "daphne.constant"() {value = false} : () -> i1 + %1 = "daphne.constant"() {value = true} : () -> i1 + %2 = "daphne.constant"() {value = 1 : si64} : () -> si64 + %3 = "daphne.constant"() {value = 5 : si64} : () -> si64 + %4 = "daphne.constant"() {value = 2 : si64} : () -> si64 + // CHECK: daphne.seq + // CHECK-NOT: daphne.seq + %5 = "daphne.seq"(%2, %3, %4) : (si64, si64, si64) -> !daphne.Matrix + // CHECK-NOT: ewMul + %6 = "daphne.ewMul"(%5, %4) : (!daphne.Matrix, si64) -> !daphne.Matrix + "daphne.print"(%6, %1, %0) : (!daphne.Matrix, i1, i1) -> () + "daphne.return"() : () -> () + } + +} + diff --git a/test/ir/daphneir/pushdown_arithmetics/seqEwSub.mlir b/test/ir/daphneir/pushdown_arithmetics/seqEwSub.mlir new file mode 100644 index 000000000..1883ab91c --- /dev/null +++ b/test/ir/daphneir/pushdown_arithmetics/seqEwSub.mlir @@ -0,0 +1,20 @@ +// RUN: daphne-opt --canonicalize --inline %s | FileCheck %s + +module { + func.func @main() { + %0 = "daphne.constant"() {value = false} : () -> i1 + %1 = "daphne.constant"() {value = true} : () -> i1 + %2 = "daphne.constant"() {value = 1 : si64} : () -> si64 + %3 = "daphne.constant"() {value = 5 : si64} : () -> si64 + %4 = "daphne.constant"() {value = 2 : si64} : () -> si64 + // CHECK: daphne.seq + // CHECK-NOT: daphne.seq + %5 = "daphne.seq"(%2, %3, %4) : (si64, si64, si64) -> !daphne.Matrix + // CHECK-NOT: ewSub + %6 = "daphne.ewSub"(%5, %4) : (!daphne.Matrix, si64) -> !daphne.Matrix + "daphne.print"(%6, %1, %0) : (!daphne.Matrix, i1, i1) -> () + "daphne.return"() : () -> () + } + +} + diff --git a/workspace/minus.daphne b/workspace/minus.daphne new file mode 100644 index 000000000..419e15a36 --- /dev/null +++ b/workspace/minus.daphne @@ -0,0 +1,3 @@ + +b = - rand(1,3,-6,-3,1.0,7); +print(b);