Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
MegEngine 天元
MegEngine
提交
5d0f8da4
MegEngine
项目概览
MegEngine 天元
/
MegEngine
接近 2 年 前同步成功
通知
414
Star
4708
Fork
583
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
MegEngine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
5d0f8da4
编写于
11月 19, 2020
作者:
M
Megvii Engine Team
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat(mgb/jit): add Dimshuffle and lowering passes in jit mlir backend
GitOrigin-RevId: ce6f4ea42a876fafbb7ca67f30d5c0fa96d28096
上级
0007b9e0
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
166 addition
and
11 deletion
+166
-11
src/jit/impl/mlir/compiler.h
src/jit/impl/mlir/compiler.h
+1
-1
src/jit/impl/mlir/ir/lower_to_affine_pass.cpp
src/jit/impl/mlir/ir/lower_to_affine_pass.cpp
+40
-3
src/jit/impl/mlir/ir/lower_to_gpu_pass.cpp
src/jit/impl/mlir/ir/lower_to_gpu_pass.cpp
+44
-3
src/jit/impl/mlir/mlir_gen.cpp
src/jit/impl/mlir/mlir_gen.cpp
+35
-4
src/jit/test/codegen.cpp
src/jit/test/codegen.cpp
+46
-0
未找到文件。
src/jit/impl/mlir/compiler.h
浏览文件 @
5d0f8da4
...
...
@@ -34,7 +34,7 @@ public:
Property
property
()
const
override
{
using
F
=
Property
::
Flag
;
return
Property
{
F
::
NEED_INPUT_COLLAPSE
|
F
::
BIND_NDIM
,
JITFeatureBits
::
NON
E
,
64
};
JITFeatureBits
::
DIMSHUFFL
E
,
64
};
}
size_t
get_nr_workspace_outputs
(
JITExecutor
*
opr
)
const
override
;
...
...
src/jit/impl/mlir/ir/lower_to_affine_pass.cpp
浏览文件 @
5d0f8da4
...
...
@@ -62,6 +62,7 @@ struct ElemwiseLowering : public ConversionPattern {
ElemwiseLowering
(
MLIRContext
*
ctx
)
:
ConversionPattern
(
mgb
::
dialect
::
Elemwise
::
getOperationName
(),
1
,
ctx
)
{}
LogicalResult
matchAndRewrite
(
Operation
*
op
,
ArrayRef
<
Value
>
operands
,
ConversionPatternRewriter
&
rewriter
)
const
final
{
...
...
@@ -89,6 +90,7 @@ struct TypeCvtLowering : public ConversionPattern {
TypeCvtLowering
(
MLIRContext
*
ctx
)
:
ConversionPattern
(
mgb
::
dialect
::
TypeCvt
::
getOperationName
(),
1
,
ctx
)
{}
LogicalResult
matchAndRewrite
(
Operation
*
op
,
ArrayRef
<
Value
>
operands
,
ConversionPatternRewriter
&
rewriter
)
const
final
{
...
...
@@ -105,6 +107,41 @@ struct TypeCvtLowering : public ConversionPattern {
}
};
struct
DimshuffleLowering
:
public
ConversionPattern
{
DimshuffleLowering
(
MLIRContext
*
ctx
)
:
ConversionPattern
(
mgb
::
dialect
::
Dimshuffle
::
getOperationName
(),
1
,
ctx
)
{}
static
mlir
::
AffineMap
get_affinemap_from_pattern
(
const
std
::
vector
<
int32_t
>&
pattern
,
mlir
::
MLIRContext
*
ctx
)
{
size_t
ndim
=
*
std
::
max_element
(
pattern
.
begin
(),
pattern
.
end
())
+
1
;
std
::
vector
<
mlir
::
AffineExpr
>
exprs
(
ndim
);
for
(
size_t
i
=
0
;
i
<
pattern
.
size
();
i
++
)
{
int32_t
j
=
pattern
[
i
];
if
(
j
>=
0
)
{
exprs
[
j
]
=
mlir
::
getAffineDimExpr
(
i
,
ctx
);
}
}
return
mlir
::
AffineMap
::
get
(
pattern
.
size
(),
0
,
exprs
,
ctx
);
}
LogicalResult
matchAndRewrite
(
Operation
*
op
,
ArrayRef
<
Value
>
operands
,
ConversionPatternRewriter
&
rewriter
)
const
final
{
auto
loc
=
op
->
getLoc
();
auto
pattern
=
llvm
::
dyn_cast
<
dialect
::
Dimshuffle
>
(
op
).
pattern
();
auto
map
=
get_affinemap_from_pattern
(
pattern
,
op
->
getContext
());
lower_op_to_loops
(
op
,
operands
,
rewriter
,
[
loc
,
op
,
&
map
](
OpBuilder
&
builder
,
ValueRange
memref_operands
,
ValueRange
loop_ivs
)
{
return
builder
.
create
<
AffineLoadOp
>
(
loc
,
memref_operands
[
0
],
map
,
loop_ivs
);
});
return
success
();
}
};
struct
AssignOpLowering
:
public
ConversionPattern
{
AssignOpLowering
(
MLIRContext
*
ctx
)
:
ConversionPattern
(
dialect
::
AssignOp
::
getOperationName
(),
1
,
ctx
)
{
...
...
@@ -172,9 +209,9 @@ public:
target
.
addIllegalDialect
<
MgbDialect
>
();
OwningRewritePatternList
patterns
;
patterns
.
insert
<
ElemwiseLowering
,
TypeCvtLowering
,
ReturnOp
Lowering
,
AssignOpLowering
,
ConstantScalarOpLowering
>
(
&
getContext
());
patterns
.
insert
<
ElemwiseLowering
,
TypeCvtLowering
,
Dimshuffle
Lowering
,
ReturnOpLowering
,
AssignOpLowering
,
ConstantScalarOpLowering
>
(
&
getContext
());
if
(
failed
(
applyPartialConversion
(
getFunction
(),
target
,
std
::
move
(
patterns
))))
{
...
...
src/jit/impl/mlir/ir/lower_to_gpu_pass.cpp
浏览文件 @
5d0f8da4
...
...
@@ -152,6 +152,47 @@ private:
gpu
::
LaunchOp
&
m_launch_op
;
};
struct
DimshuffleLowering
:
public
ConversionPattern
{
DimshuffleLowering
(
MLIRContext
*
ctx
,
gpu
::
LaunchOp
&
launch_op
)
:
ConversionPattern
(
dialect
::
Dimshuffle
::
getOperationName
(),
1
,
ctx
),
m_launch_op
{
launch_op
}
{}
static
std
::
vector
<
mlir
::
Value
>
get_index_from_pattern
(
const
std
::
vector
<
int32_t
>&
pattern
,
const
std
::
vector
<
mlir
::
Value
>&
index
)
{
size_t
ndim
=
*
std
::
max_element
(
pattern
.
begin
(),
pattern
.
end
())
+
1
;
std
::
vector
<
mlir
::
Value
>
res
(
ndim
);
for
(
size_t
i
=
0
;
i
<
pattern
.
size
();
i
++
)
{
int32_t
j
=
pattern
[
i
];
if
(
j
>=
0
)
{
res
[
j
]
=
index
[
i
];
}
}
return
res
;
}
LogicalResult
matchAndRewrite
(
Operation
*
op
,
ArrayRef
<
Value
>
operands
,
ConversionPatternRewriter
&
rewriter
)
const
final
{
auto
loc
=
op
->
getLoc
();
rewriter
.
setInsertionPointToEnd
(
&
(
m_launch_op
.
body
().
front
()));
auto
dst_layout
=
output_layout
(
m_launch_op
);
auto
index
=
get_multidim_tid
(
rewriter
,
loc
,
operands
[
0
],
dst_layout
);
auto
pattern
=
llvm
::
dyn_cast
<
dialect
::
Dimshuffle
>
(
op
).
pattern
();
auto
shuffled_index
=
get_index_from_pattern
(
pattern
,
index
);
rewriter
.
replaceOp
(
op
,
get_operand
<
LoadOp
>
(
rewriter
,
loc
,
operands
[
0
],
shuffled_index
));
return
success
();
}
private:
gpu
::
LaunchOp
&
m_launch_op
;
};
struct
ReturnOpLowering
:
public
ConversionPattern
{
ReturnOpLowering
(
MLIRContext
*
ctx
,
gpu
::
LaunchOp
&
launch_op
)
:
ConversionPattern
(
dialect
::
ReturnOp
::
getOperationName
(),
1
,
ctx
),
...
...
@@ -275,9 +316,9 @@ public:
target
.
addLegalDialect
<
gpu
::
GPUDialect
>
();
target
.
addIllegalDialect
<
MgbDialect
>
();
patterns
.
insert
<
ElemwiseLowering
,
TypeCvtLowering
,
ReturnOp
Lowering
,
ConstantScalarOpLowering
,
AssignOpLowering
>
(
&
getContext
(),
launch_op
);
patterns
.
insert
<
ElemwiseLowering
,
TypeCvtLowering
,
Dimshuffle
Lowering
,
ReturnOpLowering
,
ConstantScalarOpLowering
,
AssignOpLowering
>
(
&
getContext
(),
launch_op
);
if
(
failed
(
applyPartialConversion
(
func_op
,
target
,
std
::
move
(
patterns
))))
{
...
...
src/jit/impl/mlir/mlir_gen.cpp
浏览文件 @
5d0f8da4
...
...
@@ -20,6 +20,7 @@
#include "megbrain/jit/mlir/ir/dialect.h"
#include "megbrain/jit/mlir/ir/utils.h"
#include "megbrain/opr/basic_arith.h"
#include "megbrain/opr/tensor_manip.h"
#include "megdnn/dtype.h"
#include <mlir/Dialect/Affine/IR/AffineOps.h>
...
...
@@ -160,6 +161,10 @@ private:
mgb_assert
(
mlir
::
succeeded
(
declare
(
opr
->
output
(
0
)
->
name
(),
out
)));
return
;
}
else
if
(
opr
->
same_type
<
opr
::
Dimshuffle
>
())
{
auto
&&
out
=
gen_dimshuffle
(
opr
->
cast_final
<
opr
::
Dimshuffle
>
());
mgb_assert
(
mlir
::
succeeded
(
declare
(
opr
->
output
(
0
)
->
name
(),
out
)));
}
else
if
(
opr
->
same_type
<
opr
::
TypeCvt
>
())
{
auto
&&
out
=
gen_typecvt
(
opr
->
cast_final
<
opr
::
TypeCvt
>
());
mgb_assert
(
...
...
@@ -186,18 +191,44 @@ private:
}
mlir
::
Value
gen_typecvt
(
const
opr
::
TypeCvt
&
opr
)
{
auto
sha
pe
=
get
(
opr
.
input
(
0
))
auto
ity
pe
=
get
(
opr
.
input
(
0
))
.
getType
()
.
dyn_cast_or_null
<
mlir
::
MemRefType
>
()
.
getShape
(
);
.
dyn_cast_or_null
<
mlir
::
MemRefType
>
()
;
mgb_assert
(
itype
,
"currently only support MemRefType"
);
auto
res_type
=
mlir
::
MemRefType
::
get
(
shape
,
itype
.
getShape
()
,
megdnn_dtype_to_mlir_type
(
opr
.
param
(),
m_builder
.
getContext
()));
return
m_builder
.
create
<
dialect
::
TypeCvt
>
(
m_builder
.
getUnknownLoc
(),
res_type
,
get
(
opr
.
input
(
0
)),
opr
.
input
(
0
)
->
dtype
(),
opr
.
param
());
}
mlir
::
Value
gen_dimshuffle
(
const
opr
::
Dimshuffle
&
opr
)
{
auto
itype
=
get
(
opr
.
input
(
0
))
.
getType
()
.
dyn_cast_or_null
<
mlir
::
MemRefType
>
();
mgb_assert
(
itype
,
"the input type of Dimshuffle must be MemRefType"
);
auto
ishape
=
itype
.
getShape
();
auto
param
=
opr
.
param
();
std
::
vector
<
int32_t
>
pattern
;
std
::
vector
<
int64_t
>
oshape
;
for
(
size_t
i
=
0
;
i
<
param
.
pattern_len
;
i
++
)
{
int32_t
j
=
param
.
pattern
[
i
];
pattern
.
push_back
(
j
);
if
(
j
<
0
)
{
oshape
.
push_back
(
1
);
}
else
{
oshape
.
push_back
(
ishape
[
j
]);
}
}
auto
res_type
=
mlir
::
MemRefType
::
get
(
oshape
,
itype
.
getElementType
());
return
m_builder
.
create
<
dialect
::
Dimshuffle
>
(
m_builder
.
getUnknownLoc
(),
res_type
,
get
(
opr
.
input
(
0
)),
pattern
);
}
mlir
::
Type
get_type
(
const
TensorLayout
&
layout
)
{
return
layout_to_mlir_type
(
layout
,
m_builder
);
}
...
...
src/jit/test/codegen.cpp
浏览文件 @
5d0f8da4
...
...
@@ -15,6 +15,7 @@
#include "megbrain/jit/executor_opr.h"
#include "megbrain/opr/basic_arith.h"
#include "megbrain/opr/basic_arith_wrapper.h"
#include "megbrain/opr/tensor_manip.h"
#include "megbrain/test/helper.h"
#include "megdnn/dtype.h"
...
...
@@ -539,6 +540,51 @@ add_typecvt_gtest(Uint8, Float32);
#undef add_typecvt_gtest
/* ===================== TestJITMlirDimshuffle ===================== */
void
run_dimshuffle
(
CompNode
cn
,
TensorShape
ishape
,
const
std
::
vector
<
int
>&
pattern
)
{
set_backend
(
Backend
::
MLIR
);
auto
graph
=
ComputingGraph
::
make
();
HostTensorGenerator
<>
gen
;
auto
host_x
=
gen
(
ishape
,
cn
);
auto
x
=
opr
::
Host2DeviceCopy
::
make
(
*
graph
,
host_x
);
auto
y
=
opr
::
Dimshuffle
::
make
(
x
,
pattern
);
auto
ig_gen
=
std
::
make_unique
<
InternalGraphGenerator
>
(
y
.
node
()
->
owner_opr
());
for
(
auto
i
:
get_rev_topo_order
(
y
))
{
if
(
!
i
->
template
same_type
<
opr
::
Host2DeviceCopy
>())
{
ig_gen
->
add_opr
(
i
);
}
}
auto
igraph
=
ig_gen
->
generate
();
auto
y_jit
=
JITExecutor
::
make
(
igraph
,
ig_gen
->
orig_inps
());
HostTensorND
host_y
,
host_y_jit
;
auto
func
=
graph
->
compile
({
make_callback_copy
(
y
,
host_y
),
make_callback_copy
(
y_jit
,
host_y_jit
)});
func
->
execute
();
MGB_ASSERT_TENSOR_EQ
(
host_y
,
host_y_jit
);
}
void
run_dimshuffle_cases
(
CompNode
cn
)
{
run_dimshuffle
(
cn
,
{
3
,
4
,
5
},
{
2
,
0
,
1
});
run_dimshuffle
(
cn
,
{
3
,
4
,
5
},
{
1
,
-
1
,
0
,
2
});
}
TEST
(
TestJITMlirDimshuffle
,
Basic
)
{
run_dimshuffle_cases
(
CompNode
::
load
(
"cpu0"
));
}
TEST
(
TestJITMlirDimshuffle
,
BasicGPU
)
{
REQUIRE_GPU
(
1
);
run_dimshuffle_cases
(
CompNode
::
load
(
"gpu0"
));
}
#endif // MGB_JIT_MLIR
#endif // MGB_JIT
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录