From 32f08bcf0c8c85d5d1a20d4d60d8050d22d5344a Mon Sep 17 00:00:00 2001 From: Gheorghe-Teodor Bercea Date: Tue, 25 Feb 2020 09:54:29 -0500 Subject: [PATCH] Clean-up code. (#98) --- src/dialect/krnl/krnl_helper.cpp | 58 ++++++++++++--------- src/dialect/krnl/krnl_helper.hpp | 89 ++++++++++++++++++++------------ 2 files changed, 90 insertions(+), 57 deletions(-) diff --git a/src/dialect/krnl/krnl_helper.cpp b/src/dialect/krnl/krnl_helper.cpp index 87a5f80..91e9825 100644 --- a/src/dialect/krnl/krnl_helper.cpp +++ b/src/dialect/krnl/krnl_helper.cpp @@ -131,7 +131,7 @@ void KrnlIterateOperandPack::pushConstantBound(int64_t bound) { boundMaps.emplace_back(AffineMapAttr::get(map)); } -void KrnlIterateOperandPack::pushOperandBound(mlir::Value operand) { +void KrnlIterateOperandPack::pushOperandBound(Value operand) { if (boundMaps.size() % 2 == 0) _operands.emplace_back(inputLoops[boundMaps.size() / 2]); AffineMap map = builder.getSymbolIdentityMap(); @@ -145,7 +145,7 @@ BuildKrnlLoop::BuildKrnlLoop( pushCount(0), createdDefineOp(false), createdOptimizeOp(false), createdIterateOp(false) { if (originalLoopNum <= 0) - emitError(loc, "expected positive number of original loops"); + emitError(loc, "Expected positive number of original loops."); } BuildKrnlLoop::BuildKrnlLoop( @@ -154,27 +154,24 @@ BuildKrnlLoop::BuildKrnlLoop( memRefOperand.getType().cast().getShape().size()) {} BuildKrnlLoop::~BuildKrnlLoop() { - if (!createdDefineOp) - emitError(loc, "expected to create define op"); - if (!createdIterateOp) - emitError(loc, "expected to create iteration op"); if (pack) free(pack); } void BuildKrnlLoop::createDefineAndOptimizeOp(bool withEmptyOptimization) { - // insert define loop op + // Insert define loop operation. auto loopsOp = rewriter.create(loc, originalLoopNum); originalLoops.reserve(originalLoopNum); for (auto result : loopsOp.getResults()) originalLoops.push_back(result); createdDefineOp = true; - // inserte optimize loop op. + // Insert optimize loop operation. auto optimizedLoopsOp = rewriter.create(loc, originalLoopNum); optLoops.reserve(originalLoopNum); - // Emit empty optimizations + + // Emit empty optimizations if flag is set. if (withEmptyOptimization) { for (auto result : optimizedLoopsOp.getResults()) optLoops.push_back(result); @@ -190,7 +187,6 @@ void BuildKrnlLoop::createDefineAndOptimizeOp(bool withEmptyOptimization) { pack = new KrnlIterateOperandPack(rewriter, originalLoops, optLoops); } -// push bounds (lower and upper) and return index for loop info int BuildKrnlLoop::pushBounds(int64_t lowerBound, int64_t upperBound) { pack->pushConstantBound(lowerBound); pack->pushConstantBound(upperBound); @@ -206,17 +202,20 @@ int BuildKrnlLoop::pushBounds(int64_t lowerBound, Value upperBound) { int BuildKrnlLoop::pushBounds(int64_t lowerBound, Value upperBoundMemRefOperand, int upperBoundMemRefIndex, bool upperBoundMustBeConstant) { pack->pushConstantBound(lowerBound); - // process upperBound as a dimension of mem ref, possibly non-constant + + // Process upperBound as a dimension of the MemRef. Non-constant dimensions + // are supported. auto shape = upperBoundMemRefOperand.getType().cast().getShape(); if (shape[upperBoundMemRefIndex] < 0) { if (upperBoundMustBeConstant) - emitError(loc, "bound expected to be constant"); + emitError(loc, "Bound expected to be constant."); pack->pushOperandBound( rewriter .create(loc, upperBoundMemRefOperand, upperBoundMemRefIndex) .getResult()); } else pack->pushConstantBound(shape[upperBoundMemRefIndex]); + return pushCount++; } @@ -226,19 +225,20 @@ int BuildKrnlLoop::pushBounds(Value lowerBound, Value upperBound) { return pushCount++; } -// create iter void BuildKrnlLoop::createIterateOp() { + // Loop definition operation is mandatory. if (!createdDefineOp) - emitError(loc, "must create define op before iterate op"); - // Tight now, optimize (possibly empty) is mandatory. This may change + emitError(loc, "Must create define op before iterate op."); + + // Loop optimization operation is mandatory (for now). if (!createdOptimizeOp) - emitError(loc, "must create optimize op before iterate op"); - // have to have defined all bounds - if (pushCount != originalLoopNum) { - printf(" push count %d, original loop %d\n", pushCount, originalLoopNum); - emitError(loc, "must push bounds for all original loops"); - } - // create iterate op + emitError(loc, "Must create optimize op before iterate op."); + + // Check if all bounds have been defined. + if (pushCount != originalLoopNum) + emitError(loc, "Must push bounds for all original loops."); + + // Emit iteration operation. auto iterateOp = rewriter.create(loc, *pack); iterBlock = &iterateOp.bodyRegion().front(); createdIterateOp = true; @@ -246,19 +246,27 @@ void BuildKrnlLoop::createIterateOp() { void BuildKrnlLoop::createDefineOptimizeAndIterateOp( Value memRefOperand, bool withEmptyOptimization) { + // Rank of the MemRef operand. We will emit a loop for each dimension. int loopNum = memRefOperand.getType().cast().getShape().size(); if (originalLoopNum != loopNum) - emitError(loc, "mismatch in loop numbers from constructor and define"); + emitError(loc, "Mismatch in loop numbers from constructor and define."); + + // Emit the definition and the optimization operations for the loop nest. createDefineAndOptimizeOp(withEmptyOptimization); + + // Push a lower-upper bound pair for each dimension of the MemRef operand. + // The lower bound in this case is always zero. for (int i = 0; i < originalLoopNum; ++i) pushBounds(0, memRefOperand, i); + + // Emit the iteration operation over the current loop nest. createIterateOp(); } -// get induction variable to be use within iter BlockArgument &BuildKrnlLoop::getInductionVar(int originalLoopIndex) { + // Check if loop iteration variable is within bounds. if (originalLoopIndex < 0 || originalLoopIndex >= originalLoopNum) - emitError(loc, "original loop index is out of bound"); + emitError(loc, "Original loop index is out of bounds."); return iterBlock->getArguments()[originalLoopIndex]; } diff --git a/src/dialect/krnl/krnl_helper.hpp b/src/dialect/krnl/krnl_helper.hpp index cfe1787..aebbe0b 100644 --- a/src/dialect/krnl/krnl_helper.hpp +++ b/src/dialect/krnl/krnl_helper.hpp @@ -106,19 +106,21 @@ private: // // The sequence is as follow: // -// 1) Create a object giving the rewriter, location, and number of loop in the -// original (non optimized) loop. +// 1) Create an object giving the rewriter, location, and number of loop in +// the original (non optimized) loop. // // 2) Create define & optimize ops (currently paired). Optimizations can then -// be added to the inner block of the optimize operation. Make sure to set the -// insertion point to that block for optimizations to go in the right place. +// be added to the inner block of the optimize operation. Make sure to set +// the insertion point to that block for optimizations to go in the right +// place. // // 3) Push the bounds for each of the original loops. Bounds are pushed in -// pairs (lower & upper bounds). THere are a few methods to do it depending on -// the type of the bounds. When pushing bounds, the method returns a number -// that represent the index associated with that iteration (induction variable -// and bounds). That index can be used later to extract the induction variable -// for reference in computation and/or index calculations of mem refs. +// pairs (lower & upper bounds). There are a few methods to do it depending +// on the type of the bounds. When pushing bounds, the method returns a +// number that represent the index associated with that iteration (induction +// variable and bounds). That index can be used later to extract the +// induction variable for reference in computation and/or index calculations +// of mem refs. // // 4) Once all the bounds are pushed, create the iterate operation. Once this // is done, we can add operations within the iterate blocks by setting the @@ -127,67 +129,90 @@ private: class BuildKrnlLoop { public: - // Create a build kernel loop for the given location and loop number. + // Create kernel loop builder for a loop nest of depth loopNum. BuildKrnlLoop(ConversionPatternRewriter &rewriter, Location loc, int loopNum); - // Do the same, but where the loop number corresponds to the dimensionality of - // the mem ref operand. + + // Create kernel loop builder for a loop nest of depth equal to the + // dimensionality of the operand. An operand of MemRef type is requied. BuildKrnlLoop( ConversionPatternRewriter &rewriter, Location loc, Value memRefOperand); ~BuildKrnlLoop(); // Create define and optimize loop with loopNum original loops. If - // withEmptyOptimization, the optimization is simply the identity function (no - // optimizations). + // withEmptyOptimization is true, the optimization is simply the identity + // function (no optimizations). void createDefineAndOptimizeOp(bool withEmptyOptimization = true); - // Push bounds (lower and upper) for each of the loops, in order. It returns - // the index associated with the loop iteration. This index is in the range - // from zero to original loop number -1, and is monotonally increasing from - // call to call. This index is later used in the getInductionVar call. + // Push bounds (lower and upper) for each of the loops (order matters). + // The function returns the order number associated with the loop iteration. + // This index is used by the getInductionVar call. Non-constant operands + // must be of MemRef type. int pushBounds(int64_t lowerBound, int64_t upperBound); int pushBounds(int64_t lowerBound, Value upperBound); int pushBounds(Value lowerBound, Value upperBound); - // same, where the lower bound is an integer, and the uppoer bound is given by - // the size of the mem ref operand along the upperBoundMemRefIndex dimension. int pushBounds(int64_t lowerBound, Value upperBoundMemRefOperand, int upperBoundMemRefIndex, bool upperBoundMustBeConstant = false); - // Create an iterate op. + // Create the KrnlIterateOp assiciated with this loop nest. The loops + // iteration will be created if the definition and the optimization + // operations associated with this loop nest have been emitted already. void createIterateOp(); - // Create an define, optimize and iterate op, with the same loop nummber as - // the rank of the memRefOperand. The lower bound of each loops is zero, and - // the upper bound of each loops is the dimension given by the mem refs + + // Create the loop nest definition, optimization and iteration operations + // for a given operand of MemRef type. The loop nest has a depth equal to the + // rank of the MemRef operand. The lower bound of each loop is zero. The + // upper bound of each loop is given by the corresponding dimension of the + // MemRef operand. void createDefineOptimizeAndIterateOp( Value memRefOperand, bool withEmptyOptimization = true); - // Get the (original loop) induction variable associated with the given index. - // Use the index returned when pushing the bounds. + // Get the (original loop) induction variable associated with the given + // index. Use the index returned when pushing the bounds. BlockArgument &getInductionVar(int originalLoopIndex); - // Get blocks. This allow us to set the insertion point to the inner block of - // the optimize and the iterate Operation + // Get a reference to the code region of the optimization operation. + // This allows us to set the insertion point to the inner block of the + // loop nest optimization operation. Block *getOptimizationBlock() { return optBlock; } + + // Get a reference to the code region of the iteration operation. + // This allows us to set the insertion point to the inner block of the + // loop nest iteration operation. Block *getIterateBlock() { return iterBlock; } - // get original or optimized loops + // Get original loop nest. std::vector &getOriginalLoops() { return originalLoops; } + + // Get optimized loop nest. std::vector &getOptimizedLoops() { return optLoops; } private: - // inputs + // Required for emitting operations. ConversionPatternRewriter &rewriter; Location loc; int originalLoopNum; - // track loops and bounds + + // List of original, un-optimized loops. std::vector originalLoops; + + // List of optimized loops. std::vector optLoops; + + // List of lower-upper bound pairs needed by the KrnlIterateOp. KrnlIterateOperandPack *pack; + + // Number of lower-upper bound pairs pushed. int pushCount; + + // Flags that keep track of emitted operations. bool createdDefineOp; bool createdOptimizeOp; bool createdIterateOp; - // insertion points (opt block, iterate) + + // Saved insertion point in the code region of the KrnlOptimizeLoopsOp. Block *optBlock; + + // Saved insertion point in the code region of the KrnlIterateOp. Block *iterBlock; };