Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
gaoqiong
MIGraphX
Commits
f468731a
Commit
f468731a
authored
Jan 22, 2019
by
Paul
Browse files
Merge branch 'develop' into archive
parents
27ab89a2
547fd938
Changes
27
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
236 additions
and
9 deletions
+236
-9
src/targets/gpu/include/migraphx/gpu/convolution.hpp
src/targets/gpu/include/migraphx/gpu/convolution.hpp
+3
-1
src/targets/gpu/lowering.cpp
src/targets/gpu/lowering.cpp
+1
-1
test/eval_test.cpp
test/eval_test.cpp
+97
-1
test/include/test.hpp
test/include/test.hpp
+8
-2
test/operation.cpp
test/operation.cpp
+60
-0
tools/include/operation.hpp
tools/include/operation.hpp
+56
-0
tools/te.py
tools/te.py
+11
-4
No files found.
src/targets/gpu/include/migraphx/gpu/convolution.hpp
View file @
f468731a
...
...
@@ -27,6 +27,7 @@ struct miopen_convolution
op
::
convolution
op
;
shared
<
convolution_descriptor
>
cd
;
miopenConvFwdAlgorithm_t
algo
{};
miopenHandle_t
handle
=
nullptr
;
template
<
class
Self
,
class
F
>
static
auto
reflect
(
Self
&
self
,
F
f
)
...
...
@@ -39,7 +40,8 @@ struct miopen_convolution
shape
compute_shape
(
const
std
::
vector
<
shape
>&
inputs
)
const
;
argument
compute
(
context
&
ctx
,
const
shape
&
output_shape
,
const
std
::
vector
<
argument
>&
args
)
const
;
shape
compile
(
context
&
ctx
,
const
shape
&
output_shape
,
std
::
vector
<
instruction_ref
>
inputs
);
shape
compile
(
context
&
ctx
,
const
shape
&
output_shape
,
std
::
vector
<
shape
>
inputs
);
void
finalize
(
context
&
ctx
,
const
shape
&
output_shape
,
std
::
vector
<
shape
>
inputs
);
int
output_alias
(
const
std
::
vector
<
shape
>&
shapes
)
const
{
return
shapes
.
size
()
-
1
;
}
};
...
...
src/targets/gpu/lowering.cpp
View file @
f468731a
...
...
@@ -130,7 +130,7 @@ struct miopen_apply
auto
&&
op
=
any_cast
<
op
::
convolution
>
(
ins
->
get_operator
());
auto
conv
=
miopen_convolution
{
op
,
make_conv
(
op
)};
auto
ws
=
conv
.
compile
(
ctx
,
ins
->
get_shape
(),
ins
->
inputs
());
auto
ws
=
conv
.
compile
(
ctx
,
ins
->
get_shape
(),
to_shapes
(
ins
->
inputs
())
)
;
auto
workspace
=
insert_allocation
(
ins
,
ws
,
"workspace"
);
auto
output
=
insert_allocation
(
ins
,
ins
->
get_shape
());
...
...
test/eval_test.cpp
View file @
f468731a
...
...
@@ -8,9 +8,57 @@
struct
id_target
{
struct
context
{
void
finish
()
const
{}
};
migraphx
::
context
ctx
=
context
{};
std
::
string
name
()
const
{
return
"id"
;
}
std
::
vector
<
migraphx
::
pass
>
get_passes
(
migraphx
::
context
&
)
const
{
return
{};
}
migraphx
::
context
get_context
()
const
{
return
{};
}
migraphx
::
context
get_context
()
const
{
return
ctx
;
}
};
struct
id_ctx_op
{
std
::
string
name
()
const
{
return
"id_ctx_op"
;
}
migraphx
::
argument
compute
(
id_target
::
context
&
,
const
migraphx
::
shape
&
,
std
::
vector
<
migraphx
::
argument
>
args
)
const
{
if
(
args
.
empty
())
return
{};
return
args
.
front
();
}
migraphx
::
shape
compute_shape
(
std
::
vector
<
migraphx
::
shape
>
inputs
)
const
{
if
(
inputs
.
empty
())
return
{};
return
inputs
.
front
();
}
int
output_alias
(
const
std
::
vector
<
migraphx
::
shape
>&
)
const
{
return
0
;
}
};
struct
id_ctx_final_op
{
std
::
string
name
()
const
{
return
"id_ctx_final_op"
;
}
migraphx
::
argument
compute
(
const
migraphx
::
shape
&
,
std
::
vector
<
migraphx
::
argument
>
args
)
const
{
if
(
args
.
empty
())
return
{};
return
args
.
front
();
}
void
finalize
(
id_target
::
context
&
,
const
migraphx
::
shape
&
,
const
std
::
vector
<
migraphx
::
shape
>&
)
{
}
migraphx
::
shape
compute_shape
(
std
::
vector
<
migraphx
::
shape
>
inputs
)
const
{
if
(
inputs
.
empty
())
return
{};
return
inputs
.
front
();
}
int
output_alias
(
const
std
::
vector
<
migraphx
::
shape
>&
)
const
{
return
0
;
}
};
struct
reverse_pass
...
...
@@ -224,4 +272,52 @@ TEST_CASE(double_reverse_target_test)
EXPECT
(
result
!=
migraphx
::
literal
{
4
});
}
// Check that the program doesnt modify the context directly, and only the operators modify the
// context
TEST_CASE
(
eval_context1
)
{
migraphx
::
program
p
;
id_target
t
{};
EXPECT
(
is_shared
(
t
.
ctx
,
t
.
get_context
()));
auto
one
=
p
.
add_literal
(
1
);
auto
two
=
p
.
add_literal
(
2
);
p
.
add_instruction
(
sum_op
{},
one
,
two
);
p
.
compile
(
t
);
EXPECT
(
is_shared
(
t
.
ctx
,
p
.
get_context
()));
p
.
eval
({});
EXPECT
(
is_shared
(
t
.
ctx
,
p
.
get_context
()));
}
TEST_CASE
(
eval_context2
)
{
migraphx
::
program
p
;
id_target
t
{};
EXPECT
(
is_shared
(
t
.
ctx
,
t
.
get_context
()));
auto
one
=
p
.
add_literal
(
1
);
auto
two
=
p
.
add_literal
(
2
);
p
.
add_instruction
(
id_ctx_op
{},
one
,
two
);
p
.
compile
(
t
);
EXPECT
(
is_shared
(
t
.
ctx
,
p
.
get_context
()));
p
.
eval
({});
// id_ctx_op will modify the context
EXPECT
(
not
is_shared
(
t
.
ctx
,
p
.
get_context
()));
}
TEST_CASE
(
eval_context3
)
{
migraphx
::
program
p
;
id_target
t
{};
EXPECT
(
is_shared
(
t
.
ctx
,
t
.
get_context
()));
auto
one
=
p
.
add_literal
(
1
);
auto
two
=
p
.
add_literal
(
2
);
p
.
add_instruction
(
id_ctx_final_op
{},
one
,
two
);
p
.
compile
(
t
);
// Finalizer will modify the context
EXPECT
(
not
is_shared
(
t
.
ctx
,
p
.
get_context
()));
auto
ctx
=
p
.
get_context
();
p
.
eval
({});
EXPECT
(
is_shared
(
ctx
,
p
.
get_context
()));
EXPECT
(
not
is_shared
(
t
.
ctx
,
p
.
get_context
()));
}
int
main
(
int
argc
,
const
char
*
argv
[])
{
test
::
run
(
argc
,
argv
);
}
test/include/test.hpp
View file @
f468731a
...
...
@@ -111,7 +111,7 @@ struct lhs_expression
struct
capture
{
template
<
class
T
>
auto
operator
->*
(
const
T
&
x
)
auto
operator
->*
(
const
T
&
x
)
const
{
return
make_lhs_expression
(
x
);
}
...
...
@@ -224,7 +224,13 @@ inline void run(int argc, const char* argv[])
std
::
unordered_map
<
std
::
string
,
std
::
function
<
void
()
>>
m
(
get_test_cases
().
begin
(),
get_test_cases
().
end
());
for
(
auto
&&
name
:
cases
)
run_test_case
(
name
,
m
[
name
]);
{
auto
f
=
m
.
find
(
name
);
if
(
f
==
m
.
end
())
std
::
cout
<<
"[ ERROR ] Test case '"
<<
name
<<
"' not found."
<<
std
::
endl
;
else
run_test_case
(
name
,
f
->
second
);
}
}
}
...
...
test/operation.cpp
View file @
f468731a
...
...
@@ -103,4 +103,64 @@ TEST_CASE(operation_default_print)
EXPECT
(
s
==
"simple"
);
}
struct
final_operation
{
std
::
string
name
()
const
{
return
"final"
;
}
migraphx
::
shape
compute_shape
(
const
std
::
vector
<
migraphx
::
shape
>&
)
const
{
MIGRAPHX_THROW
(
"not computable"
);
}
void
finalize
(
migraphx
::
context
&
,
const
migraphx
::
shape
&
,
const
std
::
vector
<
migraphx
::
shape
>&
)
const
{
}
};
struct
final_operation_throw
{
std
::
string
name
()
const
{
return
"final"
;
}
migraphx
::
shape
compute_shape
(
const
std
::
vector
<
migraphx
::
shape
>&
)
const
{
MIGRAPHX_THROW
(
"not computable"
);
}
[[
gnu
::
noreturn
]]
void
finalize
(
migraphx
::
context
&
,
const
migraphx
::
shape
&
,
const
std
::
vector
<
migraphx
::
shape
>&
)
const
{
MIGRAPHX_THROW
(
"finalize"
);
}
};
TEST_CASE
(
check_has_finalize_simple
)
{
migraphx
::
operation
op
=
simple_operation
{};
EXPECT
(
not
migraphx
::
has_finalize
(
op
));
}
TEST_CASE
(
check_has_finalize
)
{
migraphx
::
operation
op
=
final_operation
{};
EXPECT
(
migraphx
::
has_finalize
(
op
));
}
TEST_CASE
(
check_run_finalize
)
{
migraphx
::
operation
op
=
final_operation
{};
migraphx
::
context
ctx
{};
op
.
finalize
(
ctx
,
{},
{});
}
TEST_CASE
(
check_run_finalize_simple
)
{
migraphx
::
operation
op
=
simple_operation
{};
migraphx
::
context
ctx
{};
op
.
finalize
(
ctx
,
{},
{});
}
TEST_CASE
(
check_run_finalize_throw
)
{
migraphx
::
operation
op
=
final_operation_throw
{};
migraphx
::
context
ctx
{};
EXPECT
(
test
::
throws
([
&
]
{
op
.
finalize
(
ctx
,
{},
{});
}));
}
int
main
(
int
argc
,
const
char
*
argv
[])
{
test
::
run
(
argc
,
argv
);
}
tools/include/operation.hpp
View file @
f468731a
...
...
@@ -26,6 +26,8 @@ struct operation
{
/// A unique name identifying the operation
std
::
string
name
()
const
;
/// An optional method that can be used to finalize the operator before running
void
finalize
(
context
&
ctx
);
/// This is used to compute the resulting shape from an operation. If an
/// operation cannot be run with input shapes, then it should throw an
/// exception.
...
...
@@ -55,6 +57,8 @@ struct operation
/// Returns true if operation does not require a context to run compute
bool
is_context_free
(
const
operation
&
x
);
/// Returns true if the operation has a finalize method
bool
has_finalize
(
const
operation
&
x
);
#else
...
...
@@ -189,16 +193,60 @@ int output_alias_op(const T& x, const std::vector<shape>& shapes)
return
output_alias_op
(
rank
<
1
>
{},
x
,
shapes
);
}
template
<
class
T
>
auto
finalize_op
(
rank
<
1
>
,
T
&
x
,
context
&
ctx
,
const
shape
&
output_shape
,
const
std
::
vector
<
shape
>&
input
)
->
decltype
(
x
.
finalize
(
auto_any_cast
(
ctx
),
output_shape
,
input
),
void
())
{
x
.
finalize
(
auto_any_cast
(
ctx
),
output_shape
,
input
);
}
template
<
class
T
>
void
finalize_op
(
rank
<
0
>
,
T
&
,
context
&
,
const
shape
&
,
const
std
::
vector
<
shape
>&
)
{
}
template
<
class
T
>
void
finalize_op
(
T
&
x
,
context
&
ctx
,
const
shape
&
output_shape
,
const
std
::
vector
<
shape
>&
input
)
{
finalize_op
(
rank
<
1
>
{},
x
,
ctx
,
output_shape
,
input
);
}
template
<
class
T
>
auto
has_finalize_op
(
rank
<
1
>
,
T
&
x
,
context
&
ctx
,
const
shape
&
output_shape
,
const
std
::
vector
<
shape
>&
input
)
->
decltype
(
x
.
finalize
(
auto_any_cast
(
ctx
),
output_shape
,
input
),
std
::
true_type
{});
template
<
class
T
>
auto
has_finalize_op
(
rank
<
0
>
,
T
&
,
context
&
,
const
shape
&
,
const
std
::
vector
<
shape
>&
)
->
std
::
false_type
;
template
<
class
T
>
auto
has_finalize_op
(
const
T
&
)
->
decltype
(
has_finalize_op
(
rank
<
1
>
{},
std
::
declval
<
T
&>
(),
std
::
declval
<
context
&>
(),
std
::
declval
<
const
shape
&>
(),
std
::
declval
<
std
::
vector
<
shape
>>
()))
{
return
{};
}
<%
interface
(
'
operation
'
,
virtual
(
'
name
'
,
returns
=
'
std
::
string
'
,
const
=
True
),
virtual
(
'
is_context_free
'
,
returns
=
'
bool
'
,
const
=
True
,
default
=
'
is_context_free_op
'
),
virtual
(
'
has_finalize
'
,
returns
=
'
bool
'
,
const
=
True
,
default
=
'
has_finalize_op
'
),
virtual
(
'
output_alias
'
,
returns
=
'
int
'
,
input
=
'
const
std
::
vector
<
shape
>&
'
,
const
=
True
,
default
=
'
output_alias_op
'
),
virtual
(
'
finalize
'
,
ctx
=
'
context
&
'
,
output
=
'
const
shape
&
'
,
input
=
'
const
std
::
vector
<
shape
>&
'
,
default
=
'
finalize_op
'
),
virtual
(
'
compute_shape
'
,
returns
=
'
shape
'
,
input
=
'
const
std
::
vector
<
shape
>&
'
,
const
=
True
),
virtual
(
'
compute
'
,
returns
=
'
argument
'
,
...
...
@@ -237,6 +285,14 @@ bool is_context_free(const T& x)
return
is_context_free_op
(
x
);
}
inline
bool
has_finalize
(
const
operation
&
op
)
{
return
op
.
has_finalize
();
}
template
<
class
T
>
bool
has_finalize
(
const
T
&
x
)
{
return
has_finalize_op
(
x
);
}
#endif
}
// namespace MIGRAPHX_INLINE_NS
...
...
tools/te.py
View file @
f468731a
...
...
@@ -71,6 +71,11 @@ struct ${struct_name}
${nonvirtual_members}
friend bool is_shared(const ${struct_name} & private_detail_x, const ${struct_name} & private_detail_y)
{
return private_detail_x.private_detail_te_handle_mem_var == private_detail_y.private_detail_te_handle_mem_var;
}
private:
struct private_detail_te_handle_base_type
{
...
...
@@ -179,7 +184,7 @@ nonvirtual_member = string.Template('''
${friend} ${return_type} ${name}(${params}) ${const}
{
assert(${this}.private_detail_te_handle_mem_var);
return ${this}.private_detail_te_get_handle().${internal_name}(${member_args});
${
return
_}
${this}.private_detail_te_get_handle().${internal_name}(${member_args});
}
'''
)
...
...
@@ -189,7 +194,7 @@ virtual_member = string.Template('''
${return_type} ${internal_name}(${member_params}) ${member_const} override
{
${using}
return ${call};
${
return
_}
${call};
}
'''
)
...
...
@@ -240,7 +245,8 @@ def convert_member(d, struct_name):
'friend'
:
''
,
'this'
:
'(*this)'
,
'using'
:
''
,
'brief'
:
''
'brief'
:
''
,
'return_'
:
''
}
args
=
[]
params
=
[]
...
...
@@ -257,7 +263,8 @@ def convert_member(d, struct_name):
for
x
in
d
[
name
]:
t
=
d
[
name
][
x
]
if
x
==
'return'
:
member
[
'return_type'
]
=
t
member
[
'return_type'
]
=
t
if
t
else
'void'
if
member
[
'return_type'
]
!=
'void'
:
member
[
'return_'
]
=
'return'
elif
x
==
'const'
:
member
[
'const'
]
=
'const'
member
[
'member_const'
]
=
'const'
...
...
Prev
1
2
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment