Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Struct support #67

Merged
merged 43 commits into from
Jun 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
9c27bc2
reviewed ImplementTaskDesignSpace
ZTTTX Jun 6, 2023
db5b079
Reviewed ImplementTaskDesignSpace
ZTTTX Jun 6, 2023
01bc0d9
formatted
ZTTTX Jun 6, 2023
af00d86
Formatted
ZTTTX Jun 6, 2023
dea8043
Formatted_ver2
ZTTTX Jun 6, 2023
19257db
Formatted_ver3
ZTTTX Jun 6, 2023
0d1b4e1
partial done emit cpp
ZTTTX Jun 6, 2023
139c92a
partial done emit cpp with annotation
ZTTTX Jun 6, 2023
5abba1c
c emit work with include
ZTTTX Jun 7, 2023
654b8b3
c emit include bug fix
ZTTTX Jun 7, 2023
99f635d
c emit include v1.1
ZTTTX Jun 7, 2023
daf2687
v1.2
ZTTTX Jun 7, 2023
aaeeefb
v1.3
ZTTTX Jun 7, 2023
98e7cb8
Merge branch 'awakening' of https://github.com/hanchenye/scalehls int…
ZTTTX Jun 8, 2023
ddc4bd9
cemit v2.0, added include check
ZTTTX Jun 8, 2023
326c047
cemit include check v2.0
ZTTTX Jun 9, 2023
7bd31cb
added regression test
ZTTTX Jun 9, 2023
b9c4252
v3.1
ZTTTX Jun 9, 2023
4dbe45d
v3.2
ZTTTX Jun 9, 2023
5477f7b
v3.3
ZTTTX Jun 9, 2023
471bd78
v3.4
ZTTTX Jun 9, 2023
10b86eb
v3.5
ZTTTX Jun 9, 2023
91ee80e
v3.6
ZTTTX Jun 9, 2023
b114a03
fixed print issue
ZTTTX Jun 10, 2023
30f6d71
fixed bug
ZTTTX Jun 10, 2023
c4dd762
Merge branch 'awakening' of https://github.com/hanchenye/scalehls int…
ZTTTX Jun 19, 2023
0e38607
added struct uip
ZTTTX Jun 22, 2023
c0086f3
strut print almost done
ZTTTX Jun 24, 2023
b8bba6d
struct cemit is ready
ZTTTX Jun 24, 2023
6655d19
struct support added as emitStructOp
ZTTTX Jun 24, 2023
3a0be67
local struct now support different template values
ZTTTX Jun 25, 2023
6691aeb
[HLS] Add symbols and memory_layout attribute to PortOp
hanchenye Jun 28, 2023
d1aa229
[ImplementTaskDesignSpace] Support to collect ip value to instance va…
hanchenye Jun 28, 2023
95f60c8
[HLS] Add isStream helper to PortOp; Add two new constructor for Stre…
hanchenye Jun 28, 2023
e1e3e38
[HLS] Add TensorToStreamOp and StreamToTensorOp; [ImplementTaskDesign…
hanchenye Jun 28, 2023
ab10065
[Matchers] Move from scalehls utils to HLS dialect utils
hanchenye Jun 28, 2023
f58e099
Merge remote-tracking branch 'tianxiang/struct_support' into struct_s…
hanchenye Jun 29, 2023
d2e0dff
Update StructOp definition; Add StructType and python bindings
hanchenye Jun 29, 2023
2345026
[HLS] Add a getStructPeeledTemplates method to peel structs and get r…
hanchenye Jun 29, 2023
a9f2ff2
[HLS] Add TemplatedOpInterface; Add static_template array attribute t…
hanchenye Jun 29, 2023
74acc8d
[ImplementTaskDesignSpace] Update the pass to better support struct I…
hanchenye Jun 29, 2023
6b1de7c
[HLS] Augment StructType with name parameter
hanchenye Jun 29, 2023
dddf658
[EmitHLSCpp] Support to emit StructInstanceOp
hanchenye Jun 29, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions include/scalehls-c/Dialect/HLS/HLS.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ mlirSemanticsInitializeBlockArguments(MlirOperation semantics,
// HLS Dialect Types
//===----------------------------------------------------------------------===//

MLIR_CAPI_EXPORTED bool mlirTypeIsHLSStructType(MlirType type);
MLIR_CAPI_EXPORTED MlirType mlirHLSStructTypeGet(MlirStringRef name,
MlirContext ctx);

MLIR_CAPI_EXPORTED bool mlirTypeIsHLSTypeType(MlirType type);
MLIR_CAPI_EXPORTED MlirType mlirHLSTypeTypeGet(MlirContext ctx);

Expand Down
32 changes: 32 additions & 0 deletions include/scalehls/Dialect/HLS/IR/HLS.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "mlir/Dialect/Func/IR/FuncOps.h"
#include "mlir/Dialect/Linalg/IR/Linalg.h"
#include "mlir/Dialect/SCF/IR/SCF.h"
#include "mlir/Dialect/Utils/StaticValueUtils.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/PatternMatch.h"
#include "mlir/Interfaces/ControlFlowInterfaces.h"
Expand Down Expand Up @@ -38,6 +39,37 @@ struct Push : public MemoryEffects::Effect::Base<Push> {};
struct Pop : public MemoryEffects::Effect::Base<Pop> {};
} // namespace StreamEffects

/// Printer hook for custom directive in assemblyFormat.
///
/// custom<DynamicTemplateList>($templates, $staticTemplates)
///
/// where `template` is of ODS type `Variadic<AnyType>` and `staticTemplates`
/// is of ODS type `ArrayAttr`. Prints a list with either (1) the static
/// attribute value in `staticTemplates` is `dynVal` or (2) the next value
/// otherwise. This allows idiomatic printing of mixed value and attributes in a
/// list. E.g. `<%arg0, 7, f32, %arg42>`.
void printDynamicTemplateList(OpAsmPrinter &printer, Operation *op,
OperandRange templates,
ArrayAttr staticTemplates);

/// Pasrer hook for custom directive in assemblyFormat.
///
/// custom<DynamicTemplateList>($templates, $staticTemplates)
///
/// where `templates` is of ODS type `Variadic<AnyType>` and `staticTemplates`
/// is of ODS type `ArrayAttr`. Parse a mixed list with either (1) static
/// templates or (2) SSA templates. Fill `staticTemplates` with the ArrayAttr,
/// where `dynVal` encodes the position of SSA templates. Add the parsed SSA
/// templates to `templates` in-order.
//
/// E.g. after parsing "<%arg0, 7, f32, %arg42>":
/// 1. `result` is filled with the ArrayAttr "[`dynVal`, 7, f32, `dynVal`]"
/// 2. `ssa` is filled with "[%arg0, %arg42]".
ParseResult parseDynamicTemplateList(
OpAsmParser &parser,
SmallVectorImpl<OpAsmParser::UnresolvedOperand> &templates,
ArrayAttr &staticTemplates);

} // namespace hls
} // namespace scalehls
} // namespace mlir
Expand Down
6 changes: 5 additions & 1 deletion include/scalehls/Dialect/HLS/IR/HLSAttributes.td
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ include "mlir/IR/EnumAttr.td"
class HLSAttr<string name, list<Trait> traits = []> :
AttrDef<HLSDialect, name, traits>;

def IndexArrayAttr : TypedArrayAttrBase<IndexAttr, "index array attribute"> {
let constBuilderCall = "$_builder.getIndexArrayAttr($0)";
}

//===----------------------------------------------------------------------===//
// DSE Attributes
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -45,7 +49,7 @@ def TaskImplAttr : HLSAttr<"TaskImpl"> {
let parameters = (ins IPLibraryParam:$library, IPNameParam:$name);

let mnemonic = "impl";
let assemblyFormat = "`<` $library `_` $name `>`";
let assemblyFormat = "`<` $library `:` $name `>`";

let extraClassDeclaration = [{
bool isDefaultImpl() {
Expand Down
19 changes: 19 additions & 0 deletions include/scalehls/Dialect/HLS/IR/HLSInterfaces.td
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,25 @@

include "mlir/IR/OpBase.td"

def TemplatedOpInterface : OpInterface<"TemplatedOpInterface"> {
let methods = [
InterfaceMethod<"Return the composed templates",
"mlir::SmallVector<OpFoldResult>", "getComposedTemplates", (ins), [{
SmallVector<OpFoldResult> composedTemplates;
unsigned dynIdx = 0;
for (auto attr : $_op.getStaticTemplates()) {
if (auto intAttr = attr.template dyn_cast<IntegerAttr>())
if (intAttr.getInt() == ShapedType::kDynamic) {
composedTemplates.push_back($_op.getTemplates()[dynIdx++]);
continue;
}
composedTemplates.push_back(attr);
}
return composedTemplates;
}]>
];
}

def ParamLikeInterface : OpInterface<"ParamLikeInterface"> {
let methods = [
InterfaceMethod<"Return the value of the parameter if it exists",
Expand Down
41 changes: 29 additions & 12 deletions include/scalehls/Dialect/HLS/IR/HLSTypes.td
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,40 @@ include "scalehls/Dialect/HLS/IR/HLSAttributes.td"
class HLSType<string name, list<Trait> traits = []> :
TypeDef<HLSDialect, name, traits>;

def StreamType : HLSType<"Stream"> {
let summary = "An HLS stream type";
let description = [{
Represents a stream of any type that can be transfered between HLS modules.
This type is equal to the hls::stream<> type in Xilinx Vivado HLS.
}];
let mnemonic = "stream";

let parameters = (ins "mlir::Type":$elementType, "unsigned":$depth);
let assemblyFormat = "`<` qualified($elementType) `,` $depth `>`";

let extraClassDeclaration = [{
static StreamType get(mlir::Type elementType, unsigned depth) {
return get(elementType.getContext(), elementType, depth);
}
static StreamType get(mlir::Type elementType) {
return get(elementType, 1);
}
}];
}

def SpaceType : HLSType<"Space"> {
let summary = "Represent a design space containing multiple parameters";
let mnemonic = "space";
}

def StructType : HLSType<"Struct"> {
let summary = "Represent a struct type";
let mnemonic = "struct";

let parameters = (ins StringRefParameter<>:$name);
let assemblyFormat = "`<` $name `>`";
}

def TypeType : HLSType<"Type"> {
let summary = "Used to represent a type";
let mnemonic = "type";
Expand All @@ -37,16 +66,4 @@ def MemoryKindType : HLSType<"MemoryKind"> {
let mnemonic = "memory";
}

def StreamType : HLSType<"Stream"> {
let summary = "An HLS stream type";
let description = [{
Represents a stream of any type that can be transfered between HLS modules.
This type is equal to the hls::stream<> type in Xilinx Vivado HLS.
}];
let mnemonic = "stream";

let parameters = (ins "mlir::Type":$elementType, "unsigned":$depth);
let assemblyFormat = "`<` qualified($elementType) `,` $depth `>`";
}

#endif // SCALEHLS_DIALECT_HLS_HLSTYPES_TD
30 changes: 30 additions & 0 deletions include/scalehls/Dialect/HLS/IR/HLSUBUFOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,36 @@
// Unified Buffer (UBUF) Operations
//===----------------------------------------------------------------------===//

def TensorToStreamOp : HLSOp<"ubuf.tensor_to_stream",[
AttrSizedOperandSegments, NoMemoryEffect]> {
let summary = "Convert a tensor to a stream channel";

let arguments = (ins AnyTensor:$tensor, Variadic<Index>:$dims,
Variadic<Index>:$symbols, MemRefLayoutAttrInterface:$stream_layout,
MemRefLayoutAttrInterface:$memory_layout);
let results = (outs StreamOf<[AnyType]>:$stream);
let assemblyFormat = [{
$tensor (`[` $dims^ `]`)? (`(` $symbols^ `)`)? `stream_layout`
$stream_layout `memory_layout` $memory_layout attr-dict `:`
functional-type($tensor, $stream)
}];
}

def StreamToTensorOp : HLSOp<"ubuf.stream_to_tensor", [
AttrSizedOperandSegments, NoMemoryEffect]> {
let summary = "Convert a stream channel to a tensor";

let arguments = (ins StreamOf<[AnyType]>:$stream, Variadic<Index>:$dims,
Variadic<Index>:$symbols, MemRefLayoutAttrInterface:$stream_layout,
MemRefLayoutAttrInterface:$memory_layout);
let results = (outs AnyTensor:$tensor);
let assemblyFormat = [{
$stream (`[` $dims^ `]`)? (`(` $symbols^ `)`)? `stream_layout`
$stream_layout `memory_layout` $memory_layout attr-dict `:`
functional-type($stream, $tensor)
}];
}

def BufferOp : HLSOp<"ubuf.buffer", [
DeclareOpInterfaceMethods<MemoryEffectsOpInterface>,
DeclareOpInterfaceMethods<BufferLikeInterface>]> {
Expand Down
79 changes: 67 additions & 12 deletions include/scalehls/Dialect/HLS/IR/HLSUIPOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,27 @@ def DeclareOp : HLSOp<"uip.declare", [IsolatedFromAbove, SymbolTable, Symbol,
}];
}

def InstanceOp : HLSOp<"uip.instance", [
DeclareOpInterfaceMethods<SymbolUserOpInterface>]> {
def InstanceOp : HLSOp<"uip.instance", [AttrSizedOperandSegments,
DeclareOpInterfaceMethods<SymbolUserOpInterface>,
DeclareOpInterfaceMethods<TemplatedOpInterface>]> {
let summary = "Instantiate an IP declared by DeclareOp";

let arguments = (ins Variadic<AnyType>:$ports, ArrayAttr:$templates,
SymbolRefAttr:$name);
let arguments = (ins Variadic<AnyType>:$ports, Variadic<AnyType>:$templates,
ArrayAttr:$static_templates, SymbolRefAttr:$name);
let results = (outs Variadic<AnyType>:$results);

let assemblyFormat = [{
$name `<` $templates `>` `(` $ports `)` attr-dict `:`
$name custom<DynamicTemplateList>($templates, $static_templates) `(` $ports
`)` attr-dict `:` (`<` type($templates)^ `>`)?
functional-type($ports, $results)
}];

let builders = [
OpBuilder<(ins "mlir::TypeRange":$results, "mlir::ValueRange":$ports,
"mlir::ArrayRef<mlir::OpFoldResult>":$composedTemplates,
"mlir::SymbolRefAttr":$name)>
];

let extraClassDeclaration = [{
/// Get the type of operand: input, output, or param.
PortKind getPortKind(OpOperand &operand);
Expand All @@ -65,17 +73,27 @@ def InstanceOp : HLSOp<"uip.instance", [
}];
}

def PortOp : HLSOp<"uip.port", [Symbol, HasParent<"DeclareOp">]> {
def PortOp : HLSOp<"uip.port", [Symbol, AttrSizedOperandSegments,
HasParent<"DeclareOp">]> {
let summary = "Declare a port of an IP";

let arguments = (ins TypeType:$type, Variadic<AnyType>:$sizes,
MemRefLayoutAttrInterface:$layout, PortKindAttr:$kind,
let arguments = (ins TypeType:$type, Variadic<AnyType>:$dims,
Variadic<AnyType>:$symbols, PortKindAttr:$kind,
OptionalAttr<MemRefLayoutAttrInterface>:$stream_layout,
MemRefLayoutAttrInterface:$memory_layout,
OptionalAttr<TypedAttrInterface>:$value, SymbolNameAttr:$sym_name);
let results = (outs PortType:$result);

let assemblyFormat = [{
$sym_name $kind `type` $type `sizes` `(` $sizes `)` $layout attr-dict
`:` functional-type($sizes, $result)
$sym_name $kind `type` $type (`[` $dims^ `]`)? (`(` $symbols^ `)`)?
(`stream_layout` $stream_layout^)? `memory_layout` $memory_layout attr-dict
`:` (`[` type($dims)^ `]`)? functional-type($symbols, $result)
}];

let extraClassDeclaration = [{
bool isStream() {
return getStreamLayout().has_value();
}
}];
}

Expand All @@ -86,8 +104,40 @@ def IncludeOp : HLSOp<"uip.include", [HasParent<"DeclareOp">]> {
let assemblyFormat = "$paths attr-dict";
}

def IndexArrayAttr : TypedArrayAttrBase<IndexAttr, "index array attribute"> {
let constBuilderCall = "$_builder.getIndexArrayAttr($0)";
def StructOp : HLSOp<"uip.struct", [Symbol, AttrSizedOperandSegments,
HasParent<"SpaceOp, DeclareOp">]> {
let summary = "Declare a struct containing multiple parameters";

let arguments = (ins Variadic<AnyType>:$params, Variadic<AnyType>:$templates,
SymbolNameAttr:$sym_name);
let results = (outs StructType:$result);

let assemblyFormat = [{
$sym_name (`<` $templates^ `>`)? `(` $params `)` attr-dict `:`
(`<` type($templates)^ `>`)? functional-type($params, $result)
}];
}

def StructInstanceOp : HLSOp<"uip.struct_instance", [AttrSizedOperandSegments,
DeclareOpInterfaceMethods<SymbolUserOpInterface>,
DeclareOpInterfaceMethods<TemplatedOpInterface>]> {
let summary = "Instantiate a struct declared by StructOp";

let arguments = (ins Variadic<AnyType>:$params, Variadic<AnyType>:$templates,
ArrayAttr:$static_templates, SymbolRefAttr:$name);
let results = (outs StructType:$result);

let assemblyFormat = [{
$name custom<DynamicTemplateList>($templates, $static_templates) `(` $params
`)` attr-dict `:` (`<` type($templates)^ `>`)?
functional-type($params, $result)
}];

let builders = [
OpBuilder<(ins "mlir::Type":$result, "mlir::ValueRange":$params,
"mlir::ArrayRef<mlir::OpFoldResult>":$composedTemplates,
"mlir::SymbolRefAttr":$name)>
];
}

def SemanticsOp : HLSOp<"uip.semantics", [Terminator, IsolatedFromAbove,
Expand Down Expand Up @@ -120,6 +170,11 @@ def SemanticsOp : HLSOp<"uip.semantics", [Terminator, IsolatedFromAbove,

PortKind getPortKind(OpOperand &operand);
PortKind getPortKind(unsigned operandIdx);

/// The template of an IP could be recursively a struct type. This method
/// can recursively peel off all the structs and return the real templates,
/// which are gauranteed to be ParamOp.
SmallVector<Value> getStructPeeledTemplates();
}];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
//
//===----------------------------------------------------------------------===//

#ifndef SCALEHLS_UTILS_MATCHERS_H
#define SCALEHLS_UTILS_MATCHERS_H
#ifndef SCALEHLS_DIALECT_HLS_UTILS_MATCHERS_H
#define SCALEHLS_DIALECT_HLS_UTILS_MATCHERS_H

#include "scalehls/Dialect/HLS/IR/HLS.h"
#include "scalehls/Utils/Utils.h"
Expand All @@ -15,8 +15,7 @@

namespace mlir {
namespace scalehls {

using namespace hls;
namespace hls {

//===----------------------------------------------------------------------===//
// BlockMatcher
Expand Down Expand Up @@ -257,7 +256,7 @@ struct Port : OpFoldResult {

struct IPMatchingResult {
const SmallVector<Port> instPorts;
const SmallVector<Attribute> instTemplates;
const SmallVector<Attribute> instStructPeeledTemplates;
const LinalgMatchingResult result;

unsigned mapIpResIndexToPayload(unsigned ipResIndex) const {
Expand All @@ -268,9 +267,10 @@ struct IPMatchingResult {
}

IPMatchingResult(const SmallVector<Port> &instPorts,
const SmallVector<Attribute> &instTemplates,
const SmallVector<Attribute> &instStructPeeledTemplates,
const LinalgMatchingResult &result)
: instPorts(instPorts), instTemplates(instTemplates), result(result) {}
: instPorts(instPorts),
instStructPeeledTemplates(instStructPeeledTemplates), result(result) {}
};

struct IPMatchingStatus {
Expand Down Expand Up @@ -369,7 +369,7 @@ struct IPMatcher {
unsigned maxIterations = 3)
: payload(payload), declare(declare), maxIterations(maxIterations),
status(declare.getSemanticsOp().getPorts(),
declare.getSemanticsOp().getTemplates()) {}
declare.getSemanticsOp().getStructPeeledTemplates()) {}

FailureOr<IPMatchingResult> match();

Expand All @@ -380,7 +380,8 @@ struct IPMatcher {
IPMatchingStatus status;
};

} // namespace hls
} // namespace scalehls
} // namespace mlir

#endif // SCALEHLS_UTILS_MATCHERS_H
#endif // SCALEHLS_DIALECT_HLS_UTILS_MATCHERS_H
Loading