From 4838b15b0fc285578a812d0bf27943c605b105ed Mon Sep 17 00:00:00 2001 From: Hanchen Ye Date: Thu, 1 Oct 2020 20:10:51 -0500 Subject: [PATCH] update func_pragma definition; update readme --- README.md | 18 ++++++++++++------ include/Dialect/HLSCpp/PragmaOps.td | 6 ------ lib/Analysis/QoREstimation.cpp | 4 ++-- lib/EmitHLSCpp/EmitHLSCpp.cpp | 14 +++----------- test/Analysis/QoREstimation/test_for.mlir | 23 +++++++++++------------ 5 files changed, 28 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index f5c1342..bb15d38 100644 --- a/README.md +++ b/README.md @@ -20,18 +20,24 @@ scalehls-opt -convert-to-hlscpp test/EmitHLSCpp/test_*.mlir | scalehls-translate ## TODOs List ### HLSCpp Dialect -1. TODOs in HLSCpp/PragmaOps.td. +1. Enhance array_pragma operation. +2. Update attributes definition. +3. TODOs in HLSCpp/PragmaOps.td. ### QoREstimation Pass -1. **Performance estimator implementation.** +1. Implement comprehensive partition-aware II analysis. +2. Consider the case of flattened inner loop under a pipelined region. +3. Support read latency from profiling data. +4. Support operation chainning. ### PragmaDSE Pass ### EmitHLSCpp -1. Support AffineFor iter_args feature; -2. TODOs in EmitHLSCpp.cpp; -3. Support memref/tensor cast/view/subview operations; -4. Support atomic/complex/extention -related operations. +1. Emitting array_pragma operation. +2. Support AffineFor iter_args feature. +3. TODOs in EmitHLSCpp.cpp. +4. Support memref/tensor cast/view/subview operations. +5. Support atomic/complex/extention -related operations. ## References 1. [MLIR Documents](https://mlir.llvm.org) diff --git a/include/Dialect/HLSCpp/PragmaOps.td b/include/Dialect/HLSCpp/PragmaOps.td index 16819d1..32a4fc0 100644 --- a/include/Dialect/HLSCpp/PragmaOps.td +++ b/include/Dialect/HLSCpp/PragmaOps.td @@ -42,12 +42,6 @@ def FuncPragmaOp : HLSCppOp<"func_pragma", [ }]; let arguments = (ins - // Pipeline pragma-related attributes. - Confined : $II, - BoolAttr : $enable_flush, - BoolAttr : $rewind, - BoolAttr : $off, - // Dataflow pragma-related attributes. BoolAttr : $dataflow ); diff --git a/lib/Analysis/QoREstimation.cpp b/lib/Analysis/QoREstimation.cpp index d7dfba9..37ed332 100644 --- a/lib/Analysis/QoREstimation.cpp +++ b/lib/Analysis/QoREstimation.cpp @@ -189,7 +189,7 @@ unsigned QoREstimator::getBlockII(Block &block, ScheduleMap &opScheduleMap, for (auto &op : block) { // Handle load operations. - if (auto loadOp = dyn_cast(op)) { + if (auto loadOp = dyn_cast(op)) { for (auto memStore : memStoreList) { if (loadOp.getMemRef() == memStore.first) { // TODO: For now, we simply assume the distance between dependency @@ -204,7 +204,7 @@ unsigned QoREstimator::getBlockII(Block &block, ScheduleMap &opScheduleMap, } // Handle Store operations. - else if (auto storeOp = dyn_cast(op)) { + else if (auto storeOp = dyn_cast(op)) { for (auto memStore : memStoreList) { if (loadOp.getMemRef() == memStore.first) { unsigned WAWLatency = diff --git a/lib/EmitHLSCpp/EmitHLSCpp.cpp b/lib/EmitHLSCpp/EmitHLSCpp.cpp index 62681b0..d7f40d2 100644 --- a/lib/EmitHLSCpp/EmitHLSCpp.cpp +++ b/lib/EmitHLSCpp/EmitHLSCpp.cpp @@ -1047,17 +1047,9 @@ void ModuleEmitter::emitLoopPragma(LoopPragmaOp *op) { } void ModuleEmitter::emitFuncPragma(FuncPragmaOp *op) { - indent(); - os << "#pragma HLS pipeline"; - if (op->off()) - os << " off\n"; - else { - os << " II=" << op->II(); - if (op->rewind()) - os << " rewind"; - if (op->enable_flush()) - os << " enable_flush"; - os << "\n"; + if (op->dataflow()) { + indent(); + os << "#pragma HLS dataflow\n"; } } diff --git a/test/Analysis/QoREstimation/test_for.mlir b/test/Analysis/QoREstimation/test_for.mlir index 3e50b45..9895ccc 100644 --- a/test/Analysis/QoREstimation/test_for.mlir +++ b/test/Analysis/QoREstimation/test_for.mlir @@ -1,18 +1,17 @@ // RUN: scalehls-opt -qor-estimation %s | FileCheck %s // CHECK-LABEL: func @test_for -func @test_for(%arg0: memref<16xindex>, %arg1: index) { - %c11 = constant 11 : index - - affine.for %i = 0 to 16 step 2 { - "hlscpp.loop_pragma" () {II = 1 : ui32, enable_flush = false, rewind = false, off = true, factor = 4 : ui32, region = false, skip_exit_check = true} : () -> () - affine.for %j = 0 to 8 { - "hlscpp.loop_pragma" () {II = 1 : ui32, enable_flush = false, rewind = false, off = false, factor = 1 : ui32, region = false, skip_exit_check = true} : () -> () - affine.for %k = 0 to 8 step 2 { - "hlscpp.loop_pragma" () {II = 1 : ui32, enable_flush = false, rewind = false, off = true, factor = 4 : ui32, region = false, skip_exit_check = true} : () -> () - %0 = load %arg0[%i] : memref<16xindex> - %1 = addi %0, %j : index - store %1, %arg0[%k] : memref<16xindex> +func @test_for(%arg0: memref<16x4x4xindex>, %arg1: memref<16x4x4xindex>) { + affine.for %i = 0 to 16 { + "hlscpp.loop_pragma" () {II = 1 : ui32, off = true, enable_flush = false, rewind = false, factor = 4 : ui32, region = false, skip_exit_check = false} : () -> () + affine.for %j = 0 to 4 { + "hlscpp.loop_pragma" () {II = 1 : ui32, off = false, enable_flush = false, rewind = false, factor = 1 : ui32, region = false, skip_exit_check = false} : () -> () + affine.for %k = 0 to 4 { + "hlscpp.loop_pragma" () {II = 1 : ui32, off = true, enable_flush = false, rewind = false, factor = 4 : ui32, region = false, skip_exit_check = false} : () -> () + %0 = affine.load %arg0[%i, %j, %k] : memref<16x4x4xindex> + %1 = affine.load %arg1[%i, %j, %k] : memref<16x4x4xindex> + %2 = muli %0, %1 : index + affine.store %2, %arg0[%i, %j, %k] : memref<16x4x4xindex> } } }