From 9c27bc2b267d82ecefbf470ba33af24b25d49851 Mon Sep 17 00:00:00 2001 From: MIAOMIAOMIAO <907241061@qq.com> Date: Mon, 5 Jun 2023 19:14:06 -0500 Subject: [PATCH 01/27] reviewed ImplementTaskDesignSpace --- .../Transforms/ImplementTaskDesignSpace.cpp | 33 +++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/lib/Dialect/HLS/Transforms/ImplementTaskDesignSpace.cpp b/lib/Dialect/HLS/Transforms/ImplementTaskDesignSpace.cpp index 0077868b..124e8739 100644 --- a/lib/Dialect/HLS/Transforms/ImplementTaskDesignSpace.cpp +++ b/lib/Dialect/HLS/Transforms/ImplementTaskDesignSpace.cpp @@ -91,6 +91,7 @@ struct ImplementTaskDesignSpacePattern : public OpRewritePattern { if (auto symbol = implParamOp.getValue()->cast().getSymbolRef()) { + // If the task will be implemented with an IP, we substitute the original // linalg operation with an IP instance. auto ipDeclare = SymbolTable::lookupNearestSymbolFrom( @@ -153,9 +154,37 @@ struct ImplementTaskDesignSpacePattern : public OpRewritePattern { linalgOp->getResult(resIndex).replaceAllUsesWith(instance.getResult(i)); } rewriter.eraseOp(linalgOp); + } else { - // TODO: Otherwise, we parallelize the linalg op with the explored - // parallel sizes. + + // auto default_spaceOp = implSelect.getSpaces()[0].getDefiningOp(); + + SmallVector parallelParam; + + for (auto param : implSpaceOp.getSpacePackOp().getArgs()) { + // The tile size parameter must be PARALLEL_SIZE kind and have an index type. + auto paramOp = param.getDefiningOp(); + assert(paramOp.getKind() == ParamKind::PARALLEL_SIZE && + "invalid parallel parameter"); + + if (!paramOp.getValue().has_value()) + return op.removeSpaceAttr(), failure(); + + // Get the parallel size value store as an attribute of the ParamOp. + parallelParam.push_back(paramOp.getValue()->cast().getInt()); + } + + linalg::LinalgTilingOptions options; + options.setTileSizes(parallelParam); + auto parallelLinalgOp = linalg::tileLinalgOp(rewriter, linalgOp, options); + if (failed(parallelLinalgOp)) + return op.removeSpaceAttr(), failure(); + + // Replace the original linalg op with the parallel one. + rewriter.replaceOp(linalgOp, parallelLinalgOp->tensorResults); + linalgOp = parallelLinalgOp->op; + + } // Finally, we remove the space attribute from the task op. From db5b079e6093a0174bff89f8600070784b33211b Mon Sep 17 00:00:00 2001 From: MIAOMIAOMIAO <907241061@qq.com> Date: Mon, 5 Jun 2023 19:21:54 -0500 Subject: [PATCH 02/27] Reviewed ImplementTaskDesignSpace --- .../HLS/Transforms/ImplementTaskDesignSpace.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/lib/Dialect/HLS/Transforms/ImplementTaskDesignSpace.cpp b/lib/Dialect/HLS/Transforms/ImplementTaskDesignSpace.cpp index 124e8739..b4017e01 100644 --- a/lib/Dialect/HLS/Transforms/ImplementTaskDesignSpace.cpp +++ b/lib/Dialect/HLS/Transforms/ImplementTaskDesignSpace.cpp @@ -154,19 +154,18 @@ struct ImplementTaskDesignSpacePattern : public OpRewritePattern { linalgOp->getResult(resIndex).replaceAllUsesWith(instance.getResult(i)); } rewriter.eraseOp(linalgOp); - - } else { - - // auto default_spaceOp = implSelect.getSpaces()[0].getDefiningOp(); - + } + + else { + //Parallelize and use the default method SmallVector parallelParam; - for (auto param : implSpaceOp.getSpacePackOp().getArgs()) { // The tile size parameter must be PARALLEL_SIZE kind and have an index type. auto paramOp = param.getDefiningOp(); + + // Check if the params are valid assert(paramOp.getKind() == ParamKind::PARALLEL_SIZE && "invalid parallel parameter"); - if (!paramOp.getValue().has_value()) return op.removeSpaceAttr(), failure(); @@ -183,8 +182,6 @@ struct ImplementTaskDesignSpacePattern : public OpRewritePattern { // Replace the original linalg op with the parallel one. rewriter.replaceOp(linalgOp, parallelLinalgOp->tensorResults); linalgOp = parallelLinalgOp->op; - - } // Finally, we remove the space attribute from the task op. From 01bc0d9a929e9defbfc3828d0f8c13e32a62f77a Mon Sep 17 00:00:00 2001 From: MIAOMIAOMIAO <907241061@qq.com> Date: Mon, 5 Jun 2023 19:45:47 -0500 Subject: [PATCH 03/27] formatted --- .../HLS/Transforms/ImplementTaskDesignSpace.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/Dialect/HLS/Transforms/ImplementTaskDesignSpace.cpp b/lib/Dialect/HLS/Transforms/ImplementTaskDesignSpace.cpp index b4017e01..dfb3c3e9 100644 --- a/lib/Dialect/HLS/Transforms/ImplementTaskDesignSpace.cpp +++ b/lib/Dialect/HLS/Transforms/ImplementTaskDesignSpace.cpp @@ -154,23 +154,28 @@ struct ImplementTaskDesignSpacePattern : public OpRewritePattern { linalgOp->getResult(resIndex).replaceAllUsesWith(instance.getResult(i)); } rewriter.eraseOp(linalgOp); - } - + } + else { - //Parallelize and use the default method + + + + // Parallelize and use the default method SmallVector parallelParam; for (auto param : implSpaceOp.getSpacePackOp().getArgs()) { - // The tile size parameter must be PARALLEL_SIZE kind and have an index type. + // The tile size parameter must be PARALLEL_SIZE kind and have an index + // type. auto paramOp = param.getDefiningOp(); // Check if the params are valid assert(paramOp.getKind() == ParamKind::PARALLEL_SIZE && - "invalid parallel parameter"); + "invalid parallel parameter"); if (!paramOp.getValue().has_value()) return op.removeSpaceAttr(), failure(); // Get the parallel size value store as an attribute of the ParamOp. - parallelParam.push_back(paramOp.getValue()->cast().getInt()); + parallelParam.push_back( + paramOp.getValue()->cast().getInt()); } linalg::LinalgTilingOptions options; From af00d86ff9aab3ce219a5d366015afc8d8ac4e38 Mon Sep 17 00:00:00 2001 From: MIAOMIAOMIAO <907241061@qq.com> Date: Mon, 5 Jun 2023 19:51:20 -0500 Subject: [PATCH 04/27] Formatted --- lib/Dialect/HLS/Transforms/ImplementTaskDesignSpace.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/Dialect/HLS/Transforms/ImplementTaskDesignSpace.cpp b/lib/Dialect/HLS/Transforms/ImplementTaskDesignSpace.cpp index dfb3c3e9..5ce00b62 100644 --- a/lib/Dialect/HLS/Transforms/ImplementTaskDesignSpace.cpp +++ b/lib/Dialect/HLS/Transforms/ImplementTaskDesignSpace.cpp @@ -158,13 +158,11 @@ struct ImplementTaskDesignSpacePattern : public OpRewritePattern { else { - - // Parallelize and use the default method SmallVector parallelParam; for (auto param : implSpaceOp.getSpacePackOp().getArgs()) { // The tile size parameter must be PARALLEL_SIZE kind and have an index - // type. + // type auto paramOp = param.getDefiningOp(); // Check if the params are valid @@ -173,7 +171,7 @@ struct ImplementTaskDesignSpacePattern : public OpRewritePattern { if (!paramOp.getValue().has_value()) return op.removeSpaceAttr(), failure(); - // Get the parallel size value store as an attribute of the ParamOp. + // Get the parallel size value store as an attribute of the ParamOp parallelParam.push_back( paramOp.getValue()->cast().getInt()); } From dea8043ddb138cf161c7c365f38c1d4a537c13cd Mon Sep 17 00:00:00 2001 From: MIAOMIAOMIAO <907241061@qq.com> Date: Mon, 5 Jun 2023 20:01:08 -0500 Subject: [PATCH 05/27] Formatted_ver2 --- lib/Dialect/HLS/Transforms/ImplementTaskDesignSpace.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/lib/Dialect/HLS/Transforms/ImplementTaskDesignSpace.cpp b/lib/Dialect/HLS/Transforms/ImplementTaskDesignSpace.cpp index 5ce00b62..a4c3bdd5 100644 --- a/lib/Dialect/HLS/Transforms/ImplementTaskDesignSpace.cpp +++ b/lib/Dialect/HLS/Transforms/ImplementTaskDesignSpace.cpp @@ -91,7 +91,6 @@ struct ImplementTaskDesignSpacePattern : public OpRewritePattern { if (auto symbol = implParamOp.getValue()->cast().getSymbolRef()) { - // If the task will be implemented with an IP, we substitute the original // linalg operation with an IP instance. auto ipDeclare = SymbolTable::lookupNearestSymbolFrom( @@ -155,14 +154,12 @@ struct ImplementTaskDesignSpacePattern : public OpRewritePattern { } rewriter.eraseOp(linalgOp); } - else { - - // Parallelize and use the default method + // Parallelize and use the default method. SmallVector parallelParam; for (auto param : implSpaceOp.getSpacePackOp().getArgs()) { // The tile size parameter must be PARALLEL_SIZE kind and have an index - // type + // type. auto paramOp = param.getDefiningOp(); // Check if the params are valid @@ -171,7 +168,7 @@ struct ImplementTaskDesignSpacePattern : public OpRewritePattern { if (!paramOp.getValue().has_value()) return op.removeSpaceAttr(), failure(); - // Get the parallel size value store as an attribute of the ParamOp + // Get the parallel size value store as an attribute of the ParamOp. parallelParam.push_back( paramOp.getValue()->cast().getInt()); } From 19257dbf7c76cfa8b355889348cc8c4f6a1ee62c Mon Sep 17 00:00:00 2001 From: MIAOMIAOMIAO <907241061@qq.com> Date: Mon, 5 Jun 2023 20:31:41 -0500 Subject: [PATCH 06/27] Formatted_ver3 --- lib/Dialect/HLS/Transforms/ImplementTaskDesignSpace.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/Dialect/HLS/Transforms/ImplementTaskDesignSpace.cpp b/lib/Dialect/HLS/Transforms/ImplementTaskDesignSpace.cpp index a4c3bdd5..dacd588f 100644 --- a/lib/Dialect/HLS/Transforms/ImplementTaskDesignSpace.cpp +++ b/lib/Dialect/HLS/Transforms/ImplementTaskDesignSpace.cpp @@ -153,8 +153,7 @@ struct ImplementTaskDesignSpacePattern : public OpRewritePattern { linalgOp->getResult(resIndex).replaceAllUsesWith(instance.getResult(i)); } rewriter.eraseOp(linalgOp); - } - else { + } else { // Parallelize and use the default method. SmallVector parallelParam; for (auto param : implSpaceOp.getSpacePackOp().getArgs()) { From 0d1b4e1f09cec180d6858ab9a74ac50acb3b7912 Mon Sep 17 00:00:00 2001 From: MIAOMIAOMIAO <907241061@qq.com> Date: Tue, 6 Jun 2023 16:24:33 -0500 Subject: [PATCH 07/27] partial done emit cpp --- include/scalehls/Utils/Visitor.h | 7 ++- lib/Translation/EmitHLSCpp.cpp | 75 +++++++++++++++++++++++++++++--- 2 files changed, 75 insertions(+), 7 deletions(-) diff --git a/include/scalehls/Utils/Visitor.h b/include/scalehls/Utils/Visitor.h index 07925439..0fc35884 100644 --- a/include/scalehls/Utils/Visitor.h +++ b/include/scalehls/Utils/Visitor.h @@ -21,6 +21,10 @@ class HLSVisitorBase { auto *thisCast = static_cast(this); return TypeSwitch(op) .template Case< + + // HLS Ip Reg + hls::InstanceOp, + // HLS dialect operations. hls::BufferOp, hls::ConstBufferOp, hls::StreamOp, hls::StreamReadOp, hls::StreamWriteOp, hls::AffineSelectOp, @@ -94,7 +98,8 @@ class HLSVisitorBase { ResultType visitOp(OPTYPE op, ExtraArgs... args) { \ return static_cast(this)->visitUnhandledOp(op, args...); \ } - + // HLS IP Reg + HANDLE(hls::InstanceOp); // HLS dialect operations. HANDLE(hls::BufferOp); HANDLE(hls::ConstBufferOp); diff --git a/lib/Translation/EmitHLSCpp.cpp b/lib/Translation/EmitHLSCpp.cpp index 29aa48c5..0cf349dc 100644 --- a/lib/Translation/EmitHLSCpp.cpp +++ b/lib/Translation/EmitHLSCpp.cpp @@ -288,6 +288,9 @@ class ModuleEmitter : public ScaleHLSEmitterBase { explicit ModuleEmitter(ScaleHLSEmitterState &state) : ScaleHLSEmitterBase(state) {} + /// Lib Ip operation emitter + void emitLibraryIp(InstanceOp op); + /// HLS dialect operation emitters. void emitConstBuffer(ConstBufferOp op); void emitStreamChannel(StreamOp op); @@ -457,6 +460,9 @@ class StmtVisitor : public HLSVisitorBase { StmtVisitor(ModuleEmitter &emitter) : emitter(emitter) {} using HLSVisitorBase::visitOp; + // Test registered ip expression + bool visitOp(InstanceOp op) { return emitter.emitLibraryIp(op), true; } + /// HLS dialect operations. bool visitOp(BufferOp op) { if (op.getDepth() == 1) @@ -692,6 +698,63 @@ void ModuleEmitter::emitConstBuffer(ConstBufferOp op) { emitArrayDirectives(op.getResult()); } +/// Library Ip emitter +void ModuleEmitter::emitLibraryIp(InstanceOp op) { + indent(); + // Get Lib name. (Print is not used, but left for future updates) + auto ipName = op->getAttrOfType("name"); + // os << ipName.getRootReference().getValue().str(); + + // Get Ip name, print Ip name. + auto ipName = op->getAttrOfType("name"); + os << ipName.getNestedReferences()[0].getValue().str(); + + // Emit template. + os << "<"; + auto allTemplate = op.getTemplates(); + for (unsigned i = 0; i < allTemplate.size(); ++i) { + if (auto curAttr = allTemplate[i].dyn_cast()) { + + if (auto floatType = curAttr.getValue().dyn_cast()) { + os << "float"; + } else if (auto indexType = curAttr.getValue().dyn_cast()) { + os << "Int"; + } + } else if (auto curAttr = allTemplate[i].dyn_cast()) { + os << curAttr.getValue(); + } + if (i != allTemplate.size() - 1) { + os << ","; + } + } + os << ">"; + os << "("; + + // Emit Variables. + auto allVar = op.getOperands(); + for (unsigned i = 0; i < allVar.size(); ++i) { + if (auto curVar = allVar[i].getDefiningOp()) { + if (auto floatValue = curVar.getValue().dyn_cast()) { + os << floatValue.getValueAsDouble(); + } else if (auto intValue = curVar.getValue().dyn_cast()) { + os << intValue.getValue(); + } + } else { + emitValue(allVar[i]); + } + + // Check for variable end + if (i != allVar.size() - 1) { + os << ","; + } + } + os << ")"; + + // Emit ends + os << ";"; + emitInfoAndNewLine(op); +} + void ModuleEmitter::emitStreamChannel(StreamOp op) { indent(); emitValue(op.getChannel()); @@ -1385,8 +1448,8 @@ void ModuleEmitter::emitBroadcast(vector::BroadcastOp op) { /// Memref-related statement emitters. template void ModuleEmitter::emitAlloc(OpType op) { - // A declared result indicates that the memref is output of the function, and - // has been declared in the function signature. + // A declared result indicates that the memref is output of the function, + // and has been declared in the function signature. if (isDeclared(op.getResult())) return; @@ -1622,8 +1685,8 @@ unsigned ModuleEmitter::emitNestedLoopHeader(Value val) { os << "++iv" << dimIdx++ << ") {\n"; addIndent(); - // TODO: More precise control here. Now we assume vectorization loops are - // always fully unrolled. + // TODO: More precise control here. Now we assume vectorization loops + // are always fully unrolled. if (type.isa()) indent() << "#pragma HLS unroll\n"; } @@ -1746,8 +1809,8 @@ void ModuleEmitter::emitFunctionDirectives(func::FuncOp func, if (hasTopFuncAttr(func)) { indent() << "#pragma HLS interface s_axilite port=return bundle=ctrl\n"; for (auto &port : portList) { - // MemRefType and StreamType must have been converted to AXI ports for the - // top function. + // MemRefType and StreamType must have been converted to AXI ports for + // the top function. if (port.getType().isa()) { indent() << "#pragma HLS interface"; From 139c92a43962474ad58592b2ca0f71903971dc9e Mon Sep 17 00:00:00 2001 From: MIAOMIAOMIAO <907241061@qq.com> Date: Tue, 6 Jun 2023 16:32:17 -0500 Subject: [PATCH 08/27] partial done emit cpp with annotation --- lib/Translation/EmitHLSCpp.cpp | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/lib/Translation/EmitHLSCpp.cpp b/lib/Translation/EmitHLSCpp.cpp index 0cf349dc..bb521b72 100644 --- a/lib/Translation/EmitHLSCpp.cpp +++ b/lib/Translation/EmitHLSCpp.cpp @@ -701,9 +701,9 @@ void ModuleEmitter::emitConstBuffer(ConstBufferOp op) { /// Library Ip emitter void ModuleEmitter::emitLibraryIp(InstanceOp op) { indent(); - // Get Lib name. (Print is not used, but left for future updates) - auto ipName = op->getAttrOfType("name"); - // os << ipName.getRootReference().getValue().str(); + /// Get Lib name. (Print is not used, but left for future updates) + // auto libName = op->getAttrOfType("name"); + // os << libName.getRootReference().getValue().str(); // Get Ip name, print Ip name. auto ipName = op->getAttrOfType("name"); @@ -715,14 +715,20 @@ void ModuleEmitter::emitLibraryIp(InstanceOp op) { for (unsigned i = 0; i < allTemplate.size(); ++i) { if (auto curAttr = allTemplate[i].dyn_cast()) { + // If template is a TPYE, print out the corresponding type string if (auto floatType = curAttr.getValue().dyn_cast()) { os << "float"; } else if (auto indexType = curAttr.getValue().dyn_cast()) { os << "Int"; } + + // If template is a number, print the number. (For now, support integer + // only) } else if (auto curAttr = allTemplate[i].dyn_cast()) { os << curAttr.getValue(); } + + // Check for template end. if (i != allTemplate.size() - 1) { os << ","; } @@ -733,24 +739,29 @@ void ModuleEmitter::emitLibraryIp(InstanceOp op) { // Emit Variables. auto allVar = op.getOperands(); for (unsigned i = 0; i < allVar.size(); ++i) { + + // If variable is constant, print the value based on type. (Support float + // and integer ) if (auto curVar = allVar[i].getDefiningOp()) { if (auto floatValue = curVar.getValue().dyn_cast()) { os << floatValue.getValueAsDouble(); } else if (auto intValue = curVar.getValue().dyn_cast()) { os << intValue.getValue(); } + + // If variable is data, print the name of the data. } else { emitValue(allVar[i]); } - // Check for variable end + // Check for variable end. if (i != allVar.size() - 1) { os << ","; } } os << ")"; - // Emit ends + // Emit ends. os << ";"; emitInfoAndNewLine(op); } From 5abba1c9a86cc8945bc0a08481a7ac146546ed7e Mon Sep 17 00:00:00 2001 From: MIAOMIAOMIAO <907241061@qq.com> Date: Tue, 6 Jun 2023 20:47:16 -0500 Subject: [PATCH 09/27] c emit work with include --- lib/Translation/EmitHLSCpp.cpp | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/lib/Translation/EmitHLSCpp.cpp b/lib/Translation/EmitHLSCpp.cpp index bb521b72..b4a78b2d 100644 --- a/lib/Translation/EmitHLSCpp.cpp +++ b/lib/Translation/EmitHLSCpp.cpp @@ -701,7 +701,7 @@ void ModuleEmitter::emitConstBuffer(ConstBufferOp op) { /// Library Ip emitter void ModuleEmitter::emitLibraryIp(InstanceOp op) { indent(); - /// Get Lib name. (Print is not used, but left for future updates) + /// Get Lib name. (This is not used, but left for future updates) // auto libName = op->getAttrOfType("name"); // os << libName.getRootReference().getValue().str(); @@ -727,14 +727,11 @@ void ModuleEmitter::emitLibraryIp(InstanceOp op) { } else if (auto curAttr = allTemplate[i].dyn_cast()) { os << curAttr.getValue(); } - - // Check for template end. if (i != allTemplate.size() - 1) { os << ","; } } - os << ">"; - os << "("; + os << ">("; // Emit Variables. auto allVar = op.getOperands(); @@ -749,12 +746,10 @@ void ModuleEmitter::emitLibraryIp(InstanceOp op) { os << intValue.getValue(); } - // If variable is data, print the name of the data. + // If variable is data, print the name of the data. } else { emitValue(allVar[i]); } - - // Check for variable end. if (i != allVar.size() - 1) { os << ","; } @@ -1959,8 +1954,23 @@ using namespace std; )XXX"; - // Emit all functions in the call graph in a post order. + // Emit all includes for library ip. + module->walk([&](Operation *op) { + if (auto libraryOp = dyn_cast(op)) { + libraryOp.walk([&](Operation *nestedOp) { + if (nestedOp->getName().getStringRef() == "hls.uip.include") { + auto curPath = nestedOp->getAttr("paths").dyn_cast()[0]; + os << "#include "; + os << curPath; + os << "\n" + } + }); + } + }); + os << "\n"; + CallGraph graph(module); + // Emit all functions in the call graph in a post order. llvm::SmallDenseSet emittedFuncs; for (auto node : llvm::post_order(&graph)) { if (node->isExternal()) From 654b8b3cb9153758b38c7a5083c45d42b2e9e4f0 Mon Sep 17 00:00:00 2001 From: MIAOMIAOMIAO <907241061@qq.com> Date: Tue, 6 Jun 2023 20:49:53 -0500 Subject: [PATCH 10/27] c emit include bug fix --- lib/Translation/EmitHLSCpp.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/Translation/EmitHLSCpp.cpp b/lib/Translation/EmitHLSCpp.cpp index b4a78b2d..dd830b1e 100644 --- a/lib/Translation/EmitHLSCpp.cpp +++ b/lib/Translation/EmitHLSCpp.cpp @@ -1949,9 +1949,6 @@ void ModuleEmitter::emitModule(ModuleOp module) { #include #include #include - -using namespace std; - )XXX"; // Emit all includes for library ip. @@ -1962,13 +1959,15 @@ using namespace std; auto curPath = nestedOp->getAttr("paths").dyn_cast()[0]; os << "#include "; os << curPath; - os << "\n" + os << "\n"; } }); } }); os << "\n"; - + os << "using namespace std"; + os << "\n"; + CallGraph graph(module); // Emit all functions in the call graph in a post order. llvm::SmallDenseSet emittedFuncs; From 99f635d0edc9bf7eeb0498b2ce5e899c1de5cbce Mon Sep 17 00:00:00 2001 From: MIAOMIAOMIAO <907241061@qq.com> Date: Tue, 6 Jun 2023 21:48:31 -0500 Subject: [PATCH 11/27] c emit include v1.1 --- lib/Translation/EmitHLSCpp.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Translation/EmitHLSCpp.cpp b/lib/Translation/EmitHLSCpp.cpp index dd830b1e..7d25cdac 100644 --- a/lib/Translation/EmitHLSCpp.cpp +++ b/lib/Translation/EmitHLSCpp.cpp @@ -745,7 +745,7 @@ void ModuleEmitter::emitLibraryIp(InstanceOp op) { } else if (auto intValue = curVar.getValue().dyn_cast()) { os << intValue.getValue(); } - + // If variable is data, print the name of the data. } else { emitValue(allVar[i]); @@ -1967,7 +1967,7 @@ void ModuleEmitter::emitModule(ModuleOp module) { os << "\n"; os << "using namespace std"; os << "\n"; - + CallGraph graph(module); // Emit all functions in the call graph in a post order. llvm::SmallDenseSet emittedFuncs; From daf2687fd9fa6ee174b964172071705ecfc3f115 Mon Sep 17 00:00:00 2001 From: MIAOMIAOMIAO <907241061@qq.com> Date: Tue, 6 Jun 2023 22:57:00 -0500 Subject: [PATCH 12/27] v1.2 --- lib/Translation/EmitHLSCpp.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/Translation/EmitHLSCpp.cpp b/lib/Translation/EmitHLSCpp.cpp index 7d25cdac..7c2bea2e 100644 --- a/lib/Translation/EmitHLSCpp.cpp +++ b/lib/Translation/EmitHLSCpp.cpp @@ -742,10 +742,11 @@ void ModuleEmitter::emitLibraryIp(InstanceOp op) { if (auto curVar = allVar[i].getDefiningOp()) { if (auto floatValue = curVar.getValue().dyn_cast()) { os << floatValue.getValueAsDouble(); - } else if (auto intValue = curVar.getValue().dyn_cast()) { + } + else if (auto intValue = curVar.getValue().dyn_cast()) { os << intValue.getValue(); } - + // If variable is data, print the name of the data. } else { emitValue(allVar[i]); From aaeeefb422571f0ae4658fe3897b235ca5238fad Mon Sep 17 00:00:00 2001 From: MIAOMIAOMIAO <907241061@qq.com> Date: Tue, 6 Jun 2023 23:41:54 -0500 Subject: [PATCH 13/27] v1.3 --- lib/Translation/EmitHLSCpp.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/Translation/EmitHLSCpp.cpp b/lib/Translation/EmitHLSCpp.cpp index 7c2bea2e..b1bb44ee 100644 --- a/lib/Translation/EmitHLSCpp.cpp +++ b/lib/Translation/EmitHLSCpp.cpp @@ -736,25 +736,24 @@ void ModuleEmitter::emitLibraryIp(InstanceOp op) { // Emit Variables. auto allVar = op.getOperands(); for (unsigned i = 0; i < allVar.size(); ++i) { - // If variable is constant, print the value based on type. (Support float - // and integer ) + // and integer) if (auto curVar = allVar[i].getDefiningOp()) { if (auto floatValue = curVar.getValue().dyn_cast()) { os << floatValue.getValueAsDouble(); - } - else if (auto intValue = curVar.getValue().dyn_cast()) { + } else if (auto intValue = curVar.getValue().dyn_cast()) { os << intValue.getValue(); } - - // If variable is data, print the name of the data. } else { + // If variable is data, print the name of the data. emitValue(allVar[i]); } + if (i != allVar.size() - 1) { os << ","; } } + os << ")"; // Emit ends. From ddc4bd970c4aa3187b6de27b4d19416808e11542 Mon Sep 17 00:00:00 2001 From: MIAOMIAOMIAO <907241061@qq.com> Date: Thu, 8 Jun 2023 17:05:20 -0500 Subject: [PATCH 14/27] cemit v2.0, added include check --- include/scalehls/Utils/Visitor.h | 4 +- lib/Translation/EmitHLSCpp.cpp | 85 +++++++++++++------------------- 2 files changed, 37 insertions(+), 52 deletions(-) diff --git a/include/scalehls/Utils/Visitor.h b/include/scalehls/Utils/Visitor.h index 0fc35884..3750ef1d 100644 --- a/include/scalehls/Utils/Visitor.h +++ b/include/scalehls/Utils/Visitor.h @@ -22,7 +22,7 @@ class HLSVisitorBase { return TypeSwitch(op) .template Case< - // HLS Ip Reg + // HLS Library Ip operation. hls::InstanceOp, // HLS dialect operations. @@ -98,7 +98,7 @@ class HLSVisitorBase { ResultType visitOp(OPTYPE op, ExtraArgs... args) { \ return static_cast(this)->visitUnhandledOp(op, args...); \ } - // HLS IP Reg + // HLS Library Ip operation. HANDLE(hls::InstanceOp); // HLS dialect operations. HANDLE(hls::BufferOp); diff --git a/lib/Translation/EmitHLSCpp.cpp b/lib/Translation/EmitHLSCpp.cpp index b1bb44ee..00389676 100644 --- a/lib/Translation/EmitHLSCpp.cpp +++ b/lib/Translation/EmitHLSCpp.cpp @@ -288,8 +288,8 @@ class ModuleEmitter : public ScaleHLSEmitterBase { explicit ModuleEmitter(ScaleHLSEmitterState &state) : ScaleHLSEmitterBase(state) {} - /// Lib Ip operation emitter - void emitLibraryIp(InstanceOp op); + /// Lib Ip operation emitter. + void emitInstanceOp(InstanceOp op); /// HLS dialect operation emitters. void emitConstBuffer(ConstBufferOp op); @@ -460,8 +460,8 @@ class StmtVisitor : public HLSVisitorBase { StmtVisitor(ModuleEmitter &emitter) : emitter(emitter) {} using HLSVisitorBase::visitOp; - // Test registered ip expression - bool visitOp(InstanceOp op) { return emitter.emitLibraryIp(op), true; } + // Test registered ip expression. + bool visitOp(InstanceOp op) { return emitter.emitInstanceOp(op), true; } /// HLS dialect operations. bool visitOp(BufferOp op) { @@ -698,62 +698,42 @@ void ModuleEmitter::emitConstBuffer(ConstBufferOp op) { emitArrayDirectives(op.getResult()); } -/// Library Ip emitter -void ModuleEmitter::emitLibraryIp(InstanceOp op) { +/// Library Ip emitter. +void ModuleEmitter::emitInstanceOp(InstanceOp op) { indent(); - /// Get Lib name. (This is not used, but left for future updates) - // auto libName = op->getAttrOfType("name"); - // os << libName.getRootReference().getValue().str(); // Get Ip name, print Ip name. - auto ipName = op->getAttrOfType("name"); + auto ipName = op.getNameAttr(); os << ipName.getNestedReferences()[0].getValue().str(); // Emit template. os << "<"; - auto allTemplate = op.getTemplates(); - for (unsigned i = 0; i < allTemplate.size(); ++i) { - if (auto curAttr = allTemplate[i].dyn_cast()) { - - // If template is a TPYE, print out the corresponding type string - if (auto floatType = curAttr.getValue().dyn_cast()) { - os << "float"; - } else if (auto indexType = curAttr.getValue().dyn_cast()) { - os << "Int"; - } + for (auto [i, curTemplate] : llvm::enumerate(op.getTemplates())) { + if (auto curAttr = curTemplate.dyn_cast()) { + + // If template is a TPYE, print out the corresponding type string. + os << getDataTypeName(curAttr.getValue()); // If template is a number, print the number. (For now, support integer // only) - } else if (auto curAttr = allTemplate[i].dyn_cast()) { - os << curAttr.getValue(); + } else if (auto curAttr = curTemplate.dyn_cast()) { + os << curAttr.getInt(); + } else { + llvm_unreachable("Invalid template parameter"); } - if (i != allTemplate.size() - 1) { + if (i != op.getTemplates().size() - 1) { os << ","; } } os << ">("; // Emit Variables. - auto allVar = op.getOperands(); - for (unsigned i = 0; i < allVar.size(); ++i) { - // If variable is constant, print the value based on type. (Support float - // and integer) - if (auto curVar = allVar[i].getDefiningOp()) { - if (auto floatValue = curVar.getValue().dyn_cast()) { - os << floatValue.getValueAsDouble(); - } else if (auto intValue = curVar.getValue().dyn_cast()) { - os << intValue.getValue(); - } - } else { - // If variable is data, print the name of the data. - emitValue(allVar[i]); - } - - if (i != allVar.size() - 1) { + for (auto [i, curVar] : llvm::enumerate(op.getOperands())) { + emitValue(curVar); + if (i != op.getOperands().size() - 1) { os << ","; } } - os << ")"; // Emit ends. @@ -1951,17 +1931,22 @@ void ModuleEmitter::emitModule(ModuleOp module) { #include )XXX"; - // Emit all includes for library ip. + // Check for used Ip, emit corresponding include paths. + llvm::SmallDenseSet emittedDeclareOp; module->walk([&](Operation *op) { - if (auto libraryOp = dyn_cast(op)) { - libraryOp.walk([&](Operation *nestedOp) { - if (nestedOp->getName().getStringRef() == "hls.uip.include") { - auto curPath = nestedOp->getAttr("paths").dyn_cast()[0]; - os << "#include "; - os << curPath; - os << "\n"; - } - }); + if (auto instanceOp = dyn_cast(op)) { + auto declaredOp = instanceOp.getDeclareOp(); + if (!emittedDeclareOp.contains(declaredOp)) { + declaredOp.walk([&](Operation *nestedOp) { + if (nestedOp->getName().getStringRef() == "hls.uip.include") { + auto curPath = nestedOp->getAttr("paths").dyn_cast()[0]; + os << "#include "; + os << curPath; + os << "\n"; + emittedDeclareOp.insert(declaredOp); + } + }); + } } }); os << "\n"; From 326c0473c82bb9b718b363672eaea1020ed36034 Mon Sep 17 00:00:00 2001 From: MIAOMIAOMIAO <907241061@qq.com> Date: Thu, 8 Jun 2023 19:29:29 -0500 Subject: [PATCH 15/27] cemit include check v2.0 --- lib/Translation/EmitHLSCpp.cpp | 45 +++++++++++++--------------------- 1 file changed, 17 insertions(+), 28 deletions(-) diff --git a/lib/Translation/EmitHLSCpp.cpp b/lib/Translation/EmitHLSCpp.cpp index 00389676..fcfbaed6 100644 --- a/lib/Translation/EmitHLSCpp.cpp +++ b/lib/Translation/EmitHLSCpp.cpp @@ -710,19 +710,14 @@ void ModuleEmitter::emitInstanceOp(InstanceOp op) { os << "<"; for (auto [i, curTemplate] : llvm::enumerate(op.getTemplates())) { if (auto curAttr = curTemplate.dyn_cast()) { - - // If template is a TPYE, print out the corresponding type string. os << getDataTypeName(curAttr.getValue()); - - // If template is a number, print the number. (For now, support integer - // only) } else if (auto curAttr = curTemplate.dyn_cast()) { os << curAttr.getInt(); } else { llvm_unreachable("Invalid template parameter"); } if (i != op.getTemplates().size() - 1) { - os << ","; + os << ", "; } } os << ">("; @@ -731,7 +726,7 @@ void ModuleEmitter::emitInstanceOp(InstanceOp op) { for (auto [i, curVar] : llvm::enumerate(op.getOperands())) { emitValue(curVar); if (i != op.getOperands().size() - 1) { - os << ","; + os << ", "; } } os << ")"; @@ -1434,8 +1429,8 @@ void ModuleEmitter::emitBroadcast(vector::BroadcastOp op) { /// Memref-related statement emitters. template void ModuleEmitter::emitAlloc(OpType op) { - // A declared result indicates that the memref is output of the function, - // and has been declared in the function signature. + // A declared result indicates that the memref is output of the function, and + // has been declared in the function signature. if (isDeclared(op.getResult())) return; @@ -1932,26 +1927,20 @@ void ModuleEmitter::emitModule(ModuleOp module) { )XXX"; // Check for used Ip, emit corresponding include paths. - llvm::SmallDenseSet emittedDeclareOp; - module->walk([&](Operation *op) { - if (auto instanceOp = dyn_cast(op)) { - auto declaredOp = instanceOp.getDeclareOp(); - if (!emittedDeclareOp.contains(declaredOp)) { - declaredOp.walk([&](Operation *nestedOp) { - if (nestedOp->getName().getStringRef() == "hls.uip.include") { - auto curPath = nestedOp->getAttr("paths").dyn_cast()[0]; - os << "#include "; - os << curPath; - os << "\n"; - emittedDeclareOp.insert(declaredOp); - } - }); - } - } + llvm::SmallDenseSet emittedIncludeAttrs; + module->walk([&](hls::InstanceOp instance) { + auto declaredOp = instance.getDeclareOp(); + declaredOp.walk([&](hls::IncludeOp include) { + emittedIncludeAttrs.insert(include->getAttr("paths")); + }); }); - os << "\n"; - os << "using namespace std"; - os << "\n"; + for (const Attribute& curPath : emittedIncludeAttrs) { + os << "#include "; + os << curPath.dyn_cast()[0]; + os << "\n"; + } + + os << "\nusing namespace std\n\n"; CallGraph graph(module); // Emit all functions in the call graph in a post order. From 7bd31cb563e9a8298386f769e8af12be62f40366 Mon Sep 17 00:00:00 2001 From: MIAOMIAOMIAO <907241061@qq.com> Date: Thu, 8 Jun 2023 20:51:59 -0500 Subject: [PATCH 16/27] added regression test --- test/EmitHLSCpp/test-instanceOp.mlir | 63 ++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 test/EmitHLSCpp/test-instanceOp.mlir diff --git a/test/EmitHLSCpp/test-instanceOp.mlir b/test/EmitHLSCpp/test-instanceOp.mlir new file mode 100644 index 00000000..9bf3505a --- /dev/null +++ b/test/EmitHLSCpp/test-instanceOp.mlir @@ -0,0 +1,63 @@ +// RUN: scalehls-translate -scalehls-emit-hlscpp %s | FileCheck %s +// XFAIL: * + + +#map = affine_map<() -> ()> +#map1 = affine_map<(d0, d1) -> (d0, d1)> + +module attributes { torch.debug_module_name = "MLP" } { + hls.uip.library @testLib { + hls.uip.declare @testIp { + hls.uip.include ["Path/to/test.hpp"] + %1 = hls.dse.param @template1