Skip to content

Commit 4741518

Browse files
committed
WIP, add custom MLIR type and step op
1 parent 8efcfab commit 4741518

12 files changed

Lines changed: 323 additions & 122 deletions

README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ While working on [REANA](https://github.com/reanahub/reana) project at CERN, I n
1111
Please make sure to build LLVM and MLIR projects first according to [the instruction](https://mlir.llvm.org/getting_started/). For this particular project those commands were used to build LLVM and MLIR project (provided as an example):
1212

1313
```sh
14-
cmake -G Ninja ../llvm \
14+
$ mkdir build && cd build
15+
16+
$ cmake -G Ninja ../llvm \
1517
-DLLVM_ENABLE_PROJECTS=mlir \
1618
-DLLVM_BUILD_EXAMPLES=ON \
1719
-DLLVM_TARGETS_TO_BUILD="host" \
@@ -23,7 +25,8 @@ cmake -G Ninja ../llvm \
2325
-DMLIR_INCLUDE_INTEGRATION_TESTS=ON \
2426
-DLLVM_INSTALL_UTILS=ON \
2527
-DLLVM_INCLUDE_TOOLS=ON
26-
cmake --build . --target check-mlir
28+
29+
$ cmake --build . --target check-mlir
2730
```
2831

2932
To build PolyFlow, run the following commands:
@@ -48,4 +51,4 @@ cmake --build . --target mlir-doc
4851

4952
# Credits
5053

51-
- [MLIR Hello World repo](https://github.com/Lewuathe/mlir-hello)
54+
- [MLIR Hello World repo](https://github.com/Lewuathe/mlir-hello)

example_workflow.snakefile

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
rule task1:
2+
input:
3+
"inputs/input1.txt",
4+
"inputs/input2.txt"
5+
output:
6+
"./output_task1.txt"
7+
shell:
8+
"cat input1.txt input2.txt > outputs/task1.txt | echo Done >> outputs/task1.txt"
9+
10+
rule task2:
11+
input:
12+
"outputs/task1.txt"
13+
output:
14+
"outputs/task2.txt"
15+
shell:
16+
"cat outputs/task1.txt >> outputs/task2.txt"

include/Parsers/SnakemakeParser.hpp

Lines changed: 76 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,16 @@
44
#include <string>
55
#include <vector>
66
#include <memory>
7+
#include "mlir/IR/Builders.h"
8+
#include "mlir/IR/BuiltinOps.h"
9+
#include "mlir/IR/MLIRContext.h"
10+
11+
#include "PolyFlow/PolyFlowDialect.h"
12+
#include "PolyFlow/PolyFlowTypes.h"
13+
#include "PolyFlow/PolyFlowOps.h"
14+
15+
16+
namespace snakemake {
717

818
enum TokenType {
919
RULE,
@@ -26,9 +36,9 @@ struct Token {
2636
size_t column;
2737
};
2838

29-
class SnakemakeLexer {
39+
class Lexer {
3040
public:
31-
SnakemakeLexer(std::istream& input) : input_(input) {}
41+
Lexer(std::istream& input) : input_(input) {}
3242
Token nextToken();
3343
bool eof() const { return input_.eof(); }
3444

@@ -49,57 +59,89 @@ class SnakemakeLexer {
4959
Token readIdentifierOrKeyword();
5060
};
5161

52-
class TreeNode {
62+
class BaseAST {
5363
public:
54-
std::string name;
55-
std::vector<std::shared_ptr<TreeNode>> children;
64+
enum ASTKind {
65+
Rule,
66+
};
5667

57-
TreeNode(const std::string &name) : name(name) {}
68+
BaseAST(ASTKind kind, Token location)
69+
: kind(kind), location(std::move(location)) {}
70+
virtual ~BaseAST() = default;
5871

59-
void add_child(const std::shared_ptr<TreeNode> &child) {
60-
children.push_back(child);
61-
}
72+
ASTKind getKind() const { return kind; }
6273

63-
void print(int indent = 0) {
64-
for (int i = 0; i < indent; ++i) {
65-
std::cout << " ";
66-
}
67-
std::cout << name << std::endl;
68-
for (const auto &child : children) {
69-
child->print(indent + 1);
70-
}
71-
}
74+
const Token &loc() { return location; }
75+
76+
private:
77+
const ASTKind kind;
78+
Token location;
79+
};
80+
81+
class RuleAST : public BaseAST {
82+
public:
83+
std::string name;
84+
std::vector<std::string> inputs;
85+
std::vector<std::string> outputs;
86+
std::string command;
87+
88+
RuleAST(Token loc,
89+
std::string name,
90+
std::vector<std::string> inputs,
91+
std::vector<std::string> outputs,
92+
std::string command)
93+
: BaseAST(Rule, std::move(loc)), name(std::move(name)), inputs(std::move(inputs)), outputs(std::move(outputs)), command(std::move(command)) {}
94+
95+
static bool classof(const BaseAST *c) { return c->getKind() == Rule; }
7296
};
7397

74-
class SnakemakeParser {
98+
class ModuleAST {
99+
public:
100+
std::vector<std::unique_ptr<RuleAST>> rules;
101+
ModuleAST(std::vector<std::unique_ptr<RuleAST>> rules)
102+
: rules(std::move(rules)) {}
103+
};
104+
105+
void dumpAST(ModuleAST &);
106+
107+
class Parser {
75108
public:
76-
SnakemakeParser(std::istream& input): lexer_(input) {}
109+
Parser(std::istream& input): lexer_(input) {}
77110

78-
void parse() {
111+
std::unique_ptr<ModuleAST> parseModule() {
79112
advance();
80-
snakemake();
81-
}
82-
83-
void print_tree() {
84-
root->print();
113+
return snakemake();
85114
}
86115

87116
private:
88-
SnakemakeLexer lexer_;
117+
Lexer lexer_;
89118
Token lookahead;
90-
std::shared_ptr<TreeNode> root = std::make_shared<TreeNode>("snakemake");
91119

92120
void advance();
93121

94122
void throw_unexpected_token();
95123

96124
void match(const TokenType tokenType);
97125

98-
std::shared_ptr<TreeNode> snakemake();
99-
std::shared_ptr<TreeNode> rule();
126+
std::unique_ptr<ModuleAST> snakemake();
127+
std::unique_ptr<RuleAST> rule();
100128

101-
std::shared_ptr<TreeNode> input_rule();
102-
std::shared_ptr<TreeNode> output_rule();
103-
std::shared_ptr<TreeNode> shell_rule();
104-
std::shared_ptr<TreeNode> parameter_list();
129+
std::vector<std::string> input_rule();
130+
std::vector<std::string> output_rule();
131+
std::string shell_rule();
132+
std::vector<std::string> parameter_list();
105133
};
134+
135+
class MLIRGen {
136+
public:
137+
MLIRGen(mlir::MLIRContext &context) : builder(&context) {}
138+
mlir::ModuleOp mlirGen(ModuleAST &);
139+
140+
private:
141+
mlir::ModuleOp theModule;
142+
mlir::OpBuilder builder;
143+
144+
polyflow::StepOp mlirGen(RuleAST &);
145+
};
146+
147+
} // namespace snakemake

include/PolyFlow/PolyFlowDialect.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,6 @@
22
#define POLYFLOW_POLYFLOWDIALECT_H
33

44
#include "mlir/IR/Dialect.h"
5-
#include "mlir/IR/BuiltinOps.h"
6-
#include "mlir/IR/BuiltinDialect.h"
7-
#include "mlir/IR/BuiltinTypes.h"
8-
#include "mlir/IR/Dialect.h"
9-
#include "mlir/Interfaces/SideEffectInterfaces.h"
105

116
#include "PolyFlow/PolyFlowOpsDialect.h.inc"
127

include/PolyFlow/PolyFlowDialect.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ def PolyFlow_Dialect : Dialect {
1515
}];
1616
let cppNamespace = "::polyflow";
1717
let hasConstantMaterializer = 0;
18+
let useDefaultTypePrinterParser = 1;
1819
}
1920

2021
//===----------------------------------------------------------------------===//

include/PolyFlow/PolyFlowOps.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@
44
#include "mlir/IR/BuiltinTypes.h"
55
#include "mlir/IR/Dialect.h"
66
#include "mlir/IR/OpDefinition.h"
7+
#include "mlir/Interfaces/InferTypeOpInterface.h"
78
#include "mlir/Interfaces/SideEffectInterfaces.h"
89

10+
#include "PolyFlow/PolyFlowTypes.h"
11+
912
#define GET_OP_CLASSES
1013
#include "PolyFlow/PolyFlowOps.h.inc"
1114

include/PolyFlow/PolyFlowOps.td

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,33 @@
22
#define POLYFLOW_OPS
33

44
include "PolyFlowDialect.td"
5+
include "PolyFlowTypes.td"
6+
include "mlir/Interfaces/InferTypeOpInterface.td"
57
include "mlir/Interfaces/SideEffectInterfaces.td"
68

7-
def ConstantOp : PolyFlow_Op<"constant", [Pure]> {
8-
let summary = "constant";
9-
let description = "simple constant operation";
109

11-
let arguments = (ins F64Attr:$value);
12-
let results = (outs F64:$result);
10+
def FileLocation : PolyFlow_Op<"FileLocation", [Pure]> {
11+
let summary = "An input value to a file.";
12+
let description = "A single step in the workflow execution.";
1313

14-
let assemblyFormat = "attr-dict `(` $value `)` `:` type($result)";
14+
let arguments = (ins StrAttr:$value);
15+
16+
let results = (outs PolyFlow_StringType:$result);
17+
let assemblyFormat = "attr-dict `:` type($result)";
18+
}
19+
20+
def StepOp : PolyFlow_Op<"Step", []> {
21+
let summary = "A single step in the workflow execution.";
22+
let description = "A single step in the workflow execution.";
23+
24+
let arguments = (ins
25+
StrAttr:$name,
26+
Variadic<PolyFlow_StringType>:$inputs
27+
);
28+
29+
let regions = (region AnyRegion:$body);
30+
31+
let assemblyFormat = "$name `(` $inputs `)` attr-dict `(` type($inputs) `)` `:` $body";
1532
}
1633

1734
#endif // POLYFLOW_OPS

include/PolyFlow/PolyFlowTypes.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#ifndef POLYFLOW_POLYFLOWTYPES_H
2+
#define POLYFLOW_POLYFLOWTYPES_H
3+
4+
#include "mlir/IR/BuiltinTypes.h"
5+
6+
#define GET_TYPEDEF_CLASSES
7+
#include "PolyFlow/PolyFlowOpsTypes.h.inc"
8+
9+
#endif // POLYFLOW_POLYFLOWTYPES_H

include/PolyFlow/PolyFlowTypes.td

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#ifndef STANDALONE_TYPES
2+
#define STANDALONE_TYPES
3+
4+
include "mlir/IR/AttrTypeBase.td"
5+
include "PolyFlowDialect.td"
6+
7+
8+
class PolyFlow_Type<string name, string typeMnemonic, list<Trait> traits = []>
9+
: TypeDef<PolyFlow_Dialect, name, traits> {
10+
let mnemonic = typeMnemonic;
11+
}
12+
13+
14+
def PolyFlow_StringType : PolyFlow_Type<"Polyflow_Str", "polyflow_str"> {
15+
let summary = "A string";
16+
let description = "Custom type in standalone dialect";
17+
//let parameters = (ins StringRefParameter<"the custom value">:$value);
18+
//let assemblyFormat = "`<` $value `>`";
19+
}
20+
21+
#endif

0 commit comments

Comments
 (0)