Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
MegEngine 天元
MegEngine
提交
7f280058
MegEngine
项目概览
MegEngine 天元
/
MegEngine
1 年多 前同步成功
通知
403
Star
4705
Fork
582
代码
文件
提交
分支
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看板
提交
7f280058
编写于
11月 09, 2022
作者:
M
Megvii Engine Team
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix(imperative): fix the matrix mul error when symbolic trace
GitOrigin-RevId: 3754dc5a658718a4b00bd16d58e581116574adb7
上级
485f0a1f
变更
5
显示空白变更内容
内联
并排
Showing
5 changed file
with
180 addition
and
44 deletion
+180
-44
imperative/python/test/integration/test_trace_dump.py
imperative/python/test/integration/test_trace_dump.py
+34
-0
imperative/src/impl/ops/matmul.cpp
imperative/src/impl/ops/matmul.cpp
+62
-44
imperative/src/test/helper.cpp
imperative/src/test/helper.cpp
+25
-0
imperative/src/test/helper.h
imperative/src/test/helper.h
+3
-0
imperative/src/test/imperative.cpp
imperative/src/test/imperative.cpp
+56
-0
未找到文件。
imperative/python/test/integration/test_trace_dump.py
浏览文件 @
7f280058
...
@@ -12,6 +12,7 @@ import megengine.optimizer as optim
...
@@ -12,6 +12,7 @@ import megengine.optimizer as optim
from
megengine
import
tensor
from
megengine
import
tensor
from
megengine.autodiff
import
GradManager
from
megengine.autodiff
import
GradManager
from
megengine.jit
import
trace
from
megengine.jit
import
trace
from
megengine.optimizer
import
SGD
@
contextlib
.
contextmanager
@
contextlib
.
contextmanager
...
@@ -138,3 +139,36 @@ def test_dump_bn_train_mode():
...
@@ -138,3 +139,36 @@ def test_dump_bn_train_mode():
bn_train
(
data
)
bn_train
(
data
)
with
pytest
.
raises
(
RuntimeError
):
with
pytest
.
raises
(
RuntimeError
):
bn_train
.
dump
(
"test.mge"
)
bn_train
.
dump
(
"test.mge"
)
class
ViTmode
(
M
.
Module
):
def
__init__
(
self
,
patch_size
=
16
,
in_chans
=
3
,
embed_dim
=
384
):
super
().
__init__
()
self
.
proj
=
M
.
Conv2d
(
in_chans
,
embed_dim
,
kernel_size
=
patch_size
,
stride
=
patch_size
)
self
.
head
=
M
.
Linear
(
embed_dim
,
1000
)
def
forward
(
self
,
x
):
x
=
self
.
proj
(
x
)
x
=
F
.
flatten
(
x
,
2
).
transpose
(
0
,
2
,
1
)
x
=
self
.
head
(
x
)
return
x
def
test_ViTmode_trace_train
():
model
=
ViTmode
(
embed_dim
=
384
)
data
=
mge
.
random
.
normal
(
size
=
(
1
,
3
,
224
,
224
))
optim
=
SGD
(
model
.
parameters
(),
lr
=
0.01
)
gm
=
GradManager
()
gm
.
attach
(
model
.
parameters
())
@
trace
(
symbolic
=
True
,
capture_as_const
=
True
)
def
train
():
for
i
in
range
(
2
):
with
gm
:
loss
=
model
(
data
)
gm
.
backward
(
loss
)
optim
.
step
().
clear_grad
()
train
()
imperative/src/impl/ops/matmul.cpp
浏览文件 @
7f280058
...
@@ -22,62 +22,80 @@ auto apply_on_var_node(const OpDef& def, const VarNodeArray& inputs) {
...
@@ -22,62 +22,80 @@ auto apply_on_var_node(const OpDef& def, const VarNodeArray& inputs) {
mgb_assert
(
inputs
.
size
()
==
2
);
mgb_assert
(
inputs
.
size
()
==
2
);
auto
inp1
=
SymbolVar
{
inputs
[
0
]},
inp2
=
SymbolVar
{
inputs
[
1
]};
auto
inp1
=
SymbolVar
{
inputs
[
0
]},
inp2
=
SymbolVar
{
inputs
[
1
]};
auto
dim1
=
matmul
.
dimA
,
dim2
=
matmul
.
dimB
;
auto
dim1
=
matmul
.
dimA
,
dim2
=
matmul
.
dimB
;
mgb_assert
(
dim1
>=
2
&&
dim2
>=
2
,
"the dim of one input the matmul operator dim is less than 2."
);
auto
cn
=
inputs
[
0
]
->
comp_node
();
auto
cn
=
inputs
[
0
]
->
comp_node
();
using
IndexDesc
=
opr
::
Subtensor
::
IndexDesc
;
using
IndexDesc
=
opr
::
Subtensor
::
IndexDesc
;
OperatorNodeConfig
config
{
matmul
.
make_name
(),
cn
};
OperatorNodeConfig
config
{
matmul
.
make_name
(),
cn
};
DTypeScalar
vi
{
-
1
};
auto
graph
=
inputs
[
0
]
->
owner_graph
();
auto
graph
=
inputs
[
0
]
->
owner_graph
();
if
(
dim1
==
2
&&
dim2
==
2
)
{
SymbolVar
shp1_head
,
shp1_tail
,
shp2_head
,
shp2_tail
;
return
opr
::
MatrixMul
::
make
(
if
(
dim1
>
2
)
{
inp1
,
inp2
,
matmul
.
param
(),
matmul
.
policy
(),
config
);
}
//! use batched matrix mul
SymbolVar
shp_head
,
batch
;
DTypeScalar
vi
{
-
2
};
auto
compress_shape
=
[
&
](
SymbolVar
inp
)
{
if
(
inp
.
shape
().
ndim
>
3
)
{
auto
idx
=
opr
::
ImmutableTensor
::
make
(
*
graph
,
vi
,
config
);
auto
idx
=
opr
::
ImmutableTensor
::
make
(
*
graph
,
vi
,
config
);
auto
shp1
=
inp1
.
symshape
();
auto
shp
=
inp
.
symshape
();
IndexDesc
head_desc
(
1
);
IndexDesc
head_desc
(
1
);
head_desc
[
0
].
end
=
idx
;
head_desc
[
0
].
end
=
idx
;
shp1_head
=
opr
::
Subtensor
::
make
(
shp1
,
head_desc
);
shp_head
=
opr
::
Subtensor
::
make
(
shp
,
head_desc
);
auto
batch
=
opr
::
Reduce
::
make
(
shp1
_head
,
{
Reduce
::
Mode
::
PRODUCT
,
0
});
batch
=
opr
::
Reduce
::
make
(
shp
_head
,
{
Reduce
::
Mode
::
PRODUCT
,
0
});
IndexDesc
tail_desc
(
1
);
IndexDesc
tail_desc
(
1
);
tail_desc
[
0
].
begin
=
idx
;
tail_desc
[
0
].
begin
=
idx
;
shp1_tail
=
opr
::
Subtensor
::
make
(
shp1
,
tail_desc
);
auto
shp_tail
=
opr
::
Subtensor
::
make
(
shp
,
tail_desc
);
auto
tshp
=
opr
::
Concat
::
make
({
batch
,
shp1_tail
},
0
,
cn
);
auto
tshp
=
opr
::
Concat
::
make
({
batch
,
shp_tail
},
0
,
cn
);
inp1
=
inp1
.
reshape
(
tshp
);
return
inp
.
reshape
(
tshp
);
}
}
else
if
(
inp
.
shape
().
ndim
==
3
)
{
if
(
dim2
>
2
)
{
auto
idx
=
opr
::
ImmutableTensor
::
make
(
*
graph
,
vi
,
config
);
auto
idx
=
opr
::
ImmutableTensor
::
make
(
*
graph
,
vi
,
config
);
auto
shp2
=
inp2
.
symshape
();
auto
shp
=
inp
.
symshape
();
IndexDesc
head_desc
(
1
);
IndexDesc
head_desc
(
1
);
head_desc
[
0
].
end
=
idx
;
head_desc
[
0
].
end
=
idx
;
shp2_head
=
opr
::
Subtensor
::
make
(
shp2
,
head_desc
);
shp_head
=
opr
::
Subtensor
::
make
(
shp
,
head_desc
);
auto
batch
=
opr
::
Reduce
::
make
(
shp2_head
,
{
Reduce
::
Mode
::
PRODUCT
,
0
});
batch
=
opr
::
Reduce
::
make
(
shp_head
,
{
Reduce
::
Mode
::
PRODUCT
,
0
});
IndexDesc
tail_desc
(
1
);
return
inp
;
tail_desc
[
0
].
begin
=
idx
;
}
else
{
auto
shp2_tail
=
opr
::
Subtensor
::
make
(
shp2
,
tail_desc
);
return
inp
;
auto
tshp
=
opr
::
Concat
::
make
({
batch
,
shp2_tail
},
0
,
cn
);
inp2
=
inp2
.
reshape
(
tshp
);
}
}
auto
result
=
};
opr
::
MatrixMul
::
make
(
inp1
,
inp2
,
matmul
.
param
(),
matmul
.
policy
(),
config
);
if
(
dim1
>
2
)
{
inp1
=
compress_shape
(
inp1
);
auto
idx
=
opr
::
ImmutableTensor
::
make
(
*
graph
,
vi
,
config
);
inp2
=
compress_shape
(
inp2
);
auto
result_shape
=
result
.
symshape
();
IndexDesc
tail_desc
(
1
);
auto
expand_shape
=
[
&
](
SymbolVar
inp
)
{
tail_desc
[
0
].
begin
=
idx
;
if
(
inp
.
shape
().
ndim
<
3
)
{
auto
shp_tail
=
opr
::
Subtensor
::
make
(
result_shape
,
tail_desc
);
auto
shp
=
inp
.
symshape
();
auto
tshp
=
opr
::
Concat
::
make
({
shp1_head
,
shp_tail
},
0
,
cn
);
using
Desc
=
opr
::
AxisAddRemove
::
AxisDesc
;
result
=
result
.
reshape
(
tshp
);
std
::
vector
<
Desc
>
add_axis_param
;
add_axis_param
.
push_back
(
Desc
::
make_add
(
0
));
auto
out
=
opr
::
AxisAddRemove
::
make
(
inp
,
add_axis_param
);
auto
target_shape
=
opr
::
Concat
::
make
({
batch
,
shp
},
0
,
cn
);
return
opr
::
Broadcast
::
make
(
out
,
target_shape
);
}
else
{
return
inp
;
}
}
if
(
dim2
>
2
)
{
};
inp1
=
expand_shape
(
inp1
);
inp2
=
expand_shape
(
inp2
);
auto
result
=
opr
::
BatchedMatrixMul
::
make
(
inp1
,
inp2
,
matmul
.
param
(),
matmul
.
policy
(),
config
);
size_t
max_dim
=
std
::
max
(
dim1
,
dim2
);
if
(
max_dim
>
3
)
{
auto
idx
=
opr
::
ImmutableTensor
::
make
(
*
graph
,
vi
,
config
);
auto
idx
=
opr
::
ImmutableTensor
::
make
(
*
graph
,
vi
,
config
);
auto
res
ult_shape
=
result
.
symshape
();
auto
res
_shp
=
result
.
symshape
();
IndexDesc
tail_desc
(
1
);
IndexDesc
tail_desc
(
1
);
tail_desc
[
0
].
begin
=
idx
;
tail_desc
[
0
].
begin
=
idx
;
auto
shp_tail
=
opr
::
Subtensor
::
make
(
result_shape
,
tail_desc
);
auto
tail_shape
=
opr
::
Subtensor
::
make
(
res_shp
,
tail_desc
);
auto
tshp
=
opr
::
Concat
::
make
({
shp
2_head
,
shp_tail
},
0
,
cn
);
auto
tshp
=
opr
::
Concat
::
make
({
shp
_head
,
tail_shape
},
0
,
cn
);
result
=
result
.
reshape
(
tshp
);
result
=
result
.
reshape
(
tshp
);
}
}
return
result
;
return
result
;
}
}
...
...
imperative/src/test/helper.cpp
浏览文件 @
7f280058
...
@@ -150,6 +150,31 @@ void OprChecker::run(std::vector<InputSpec> inp_keys, std::set<size_t> bypass) {
...
@@ -150,6 +150,31 @@ void OprChecker::run(std::vector<InputSpec> inp_keys, std::set<size_t> bypass) {
}
}
}
}
VarNodeArray
OprChecker
::
run_apply_on_var_node
(
std
::
vector
<
InputSpec
>
inp_keys
)
{
HostTensorGenerator
<>
gen
;
size_t
nr_inps
=
inp_keys
.
size
();
SmallVector
<
HostTensorND
>
host_inp
(
nr_inps
);
VarNodeArray
sym_inp
(
nr_inps
);
auto
graph
=
ComputingGraph
::
make
();
graph
->
options
().
graph_opt_level
=
0
;
for
(
size_t
i
=
0
;
i
<
nr_inps
;
++
i
)
{
// TODO: remove std::visit for support osx 10.12
host_inp
[
i
]
=
std
::
visit
(
[
&
gen
](
auto
&&
arg
)
->
HostTensorND
{
using
T
=
std
::
decay_t
<
decltype
(
arg
)
>
;
if
constexpr
(
std
::
is_same_v
<
TensorShape
,
T
>
)
{
return
*
gen
(
arg
);
}
else
{
static_assert
(
std
::
is_same_v
<
HostTensorND
,
T
>
);
return
arg
;
}
},
inp_keys
[
i
]);
sym_inp
[
i
]
=
opr
::
SharedDeviceTensor
::
make
(
*
graph
,
host_inp
[
i
]).
node
();
}
return
OpDef
::
apply_on_var_node
(
*
m_op
,
sym_inp
);
}
TEST
(
TestHelper
,
PyModule
)
{
TEST
(
TestHelper
,
PyModule
)
{
py
::
module
m
=
PyEnv
::
get
();
py
::
module
m
=
PyEnv
::
get
();
py
::
print
(
m
);
py
::
print
(
m
);
...
...
imperative/src/test/helper.h
浏览文件 @
7f280058
...
@@ -14,6 +14,9 @@ public:
...
@@ -14,6 +14,9 @@ public:
OprChecker
(
std
::
shared_ptr
<
OpDef
>
opdef
);
OprChecker
(
std
::
shared_ptr
<
OpDef
>
opdef
);
void
run
(
std
::
vector
<
InputSpec
>
inp_shapes
,
std
::
set
<
size_t
>
bypass
=
{});
void
run
(
std
::
vector
<
InputSpec
>
inp_shapes
,
std
::
set
<
size_t
>
bypass
=
{});
//! test the interface of apply_on_var_node
VarNodeArray
run_apply_on_var_node
(
std
::
vector
<
InputSpec
>
inp_shapes
);
private:
private:
std
::
shared_ptr
<
OpDef
>
m_op
;
std
::
shared_ptr
<
OpDef
>
m_op
;
};
};
...
...
imperative/src/test/imperative.cpp
浏览文件 @
7f280058
#include "./helper.h"
#include "./helper.h"
#include "megbrain/comp_node_env.h"
#include "megbrain/comp_node_env.h"
#include "megbrain/imperative/blob_manager.h"
#include "megbrain/imperative/blob_manager.h"
#include "megbrain/imperative/ops/autogen.h"
#include "megbrain/imperative/ops/opr_attr.h"
#include "megbrain/imperative/ops/opr_attr.h"
#include "megbrain/opr/basic_arith.h"
#include "megbrain/opr/basic_arith.h"
#include "megbrain/opr/basic_arith_wrapper.h"
#include "megbrain/opr/basic_arith_wrapper.h"
#include "megbrain/opr/blas.h"
#include "megbrain/opr/dnn/batch_norm.h"
#include "megbrain/opr/dnn/batch_norm.h"
#include "megbrain/opr/dnn/convolution.h"
#include "megbrain/opr/dnn/convolution.h"
#include "megbrain/opr/tensor_manip.h"
#include "megbrain/opr/tensor_manip.h"
...
@@ -164,4 +166,58 @@ TEST(TestImperative, Defragment) {
...
@@ -164,4 +166,58 @@ TEST(TestImperative, Defragment) {
}
}
#endif // MGB_CUDA && MGB_ENABLE_EXCEPTION
#endif // MGB_CUDA && MGB_ENABLE_EXCEPTION
TEST
(
TestImperative
,
MatrixMulApplyOnVarNode
)
{
using
Param
=
opr
::
MatrixMul
::
Param
;
Param
param
;
std
::
vector
<
std
::
pair
<
TensorShape
,
TensorShape
>>
shapes
;
std
::
vector
<
TensorShape
>
target_shapes
;
std
::
vector
<
Param
>
params
;
//! testcase 0
params
.
push_back
(
param
);
shapes
.
push_back
({
TensorShape
{
10
,
5
},
TensorShape
{
5
,
10
}});
target_shapes
.
push_back
(
TensorShape
{
10
,
10
});
//! testcase 1
params
.
push_back
(
param
);
shapes
.
push_back
({
TensorShape
{
3
,
10
,
5
},
TensorShape
{
5
,
10
}});
target_shapes
.
push_back
(
TensorShape
{
3
,
10
,
10
});
//! testcase 2
param
.
transposeA
=
true
;
param
.
transposeB
=
false
;
params
.
push_back
(
param
);
shapes
.
push_back
({
TensorShape
{
3
,
7
,
6
},
TensorShape
{
7
,
10
}});
target_shapes
.
push_back
(
TensorShape
{
3
,
6
,
10
});
//! testcase 3
param
.
transposeA
=
true
;
param
.
transposeB
=
false
;
params
.
push_back
(
param
);
shapes
.
push_back
({
TensorShape
{
2
,
3
,
7
,
6
},
TensorShape
{
7
,
10
}});
target_shapes
.
push_back
(
TensorShape
{
2
,
3
,
6
,
10
});
//! testcase 4
param
.
transposeA
=
false
;
param
.
transposeB
=
true
;
params
.
push_back
(
param
);
shapes
.
push_back
({
TensorShape
{
2
,
3
,
7
,
6
},
TensorShape
{
2
,
3
,
8
,
6
}});
target_shapes
.
push_back
(
TensorShape
{
2
,
3
,
7
,
8
});
//! testcase 5
param
.
transposeA
=
false
;
param
.
transposeB
=
true
;
params
.
push_back
(
param
);
shapes
.
push_back
({
TensorShape
{
2
,
3
,
7
,
6
},
TensorShape
{
8
,
6
}});
target_shapes
.
push_back
(
TensorShape
{
2
,
3
,
7
,
8
});
for
(
size_t
i
=
0
;
i
<
params
.
size
();
i
++
)
{
auto
&
shape
=
shapes
[
i
];
auto
op
=
MatrixMul
::
make
(
params
[
i
],
::
megdnn
::
param
::
ExecutionPolicy
{},
shape
.
first
.
ndim
,
shape
.
second
.
ndim
);
auto
result
=
OprChecker
(
op
).
run_apply_on_var_node
({
shape
.
first
,
shape
.
second
});
ASSERT_GT
(
result
.
size
(),
0
);
ASSERT_EQ
(
target_shapes
[
i
].
ndim
,
result
[
0
]
->
shape
().
ndim
);
for
(
size_t
id
=
0
;
id
<
target_shapes
[
i
].
ndim
;
id
++
)
{
ASSERT_EQ
(
target_shapes
[
i
][
id
],
result
[
0
]
->
shape
()[
id
]);
}
}
}
// vim: syntax=cpp.doxygen foldmethod=marker foldmarker=f{{{,f}}}
// vim: syntax=cpp.doxygen foldmethod=marker foldmarker=f{{{,f}}}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录