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
029b1e64
Commit
029b1e64
authored
Sep 11, 2018
by
mei-ye
Browse files
merge to master
parent
733591e1
Changes
27
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
664 additions
and
33 deletions
+664
-33
CMakeLists.txt
CMakeLists.txt
+1
-1
src/CMakeLists.txt
src/CMakeLists.txt
+9
-0
src/eliminate_allocation.cpp
src/eliminate_allocation.cpp
+5
-0
src/include/migraph/operators.hpp
src/include/migraph/operators.hpp
+13
-1
src/include/migraph/pass.hpp
src/include/migraph/pass.hpp
+1
-0
src/include/migraph/program.hpp
src/include/migraph/program.hpp
+7
-3
src/include/migraph/target.hpp
src/include/migraph/target.hpp
+10
-7
src/opt/common_header.hpp
src/opt/common_header.hpp
+28
-0
src/opt/memory_coloring.cpp
src/opt/memory_coloring.cpp
+13
-0
src/opt/memory_coloring_impl.cpp
src/opt/memory_coloring_impl.cpp
+333
-0
src/opt/memory_coloring_impl.hpp
src/opt/memory_coloring_impl.hpp
+170
-0
src/program.cpp
src/program.cpp
+21
-2
src/targets/cpu/CMakeLists.txt
src/targets/cpu/CMakeLists.txt
+5
-0
src/targets/cpu/include/migraph/cpu/context.hpp
src/targets/cpu/include/migraph/cpu/context.hpp
+6
-1
src/targets/cpu/include/migraph/cpu/cpu_target.hpp
src/targets/cpu/include/migraph/cpu/cpu_target.hpp
+1
-1
src/targets/gpu/CMakeLists.txt
src/targets/gpu/CMakeLists.txt
+10
-0
src/targets/gpu/eliminate_workspace.cpp
src/targets/gpu/eliminate_workspace.cpp
+4
-0
src/targets/gpu/hip.cpp
src/targets/gpu/hip.cpp
+5
-0
src/targets/gpu/include/migraph/gpu/context.hpp
src/targets/gpu/include/migraph/gpu/context.hpp
+5
-1
src/targets/gpu/include/migraph/gpu/hip.hpp
src/targets/gpu/include/migraph/gpu/hip.hpp
+17
-16
No files found.
CMakeLists.txt
View file @
029b1e64
...
@@ -18,7 +18,7 @@ else()
...
@@ -18,7 +18,7 @@ else()
set
(
MIGRAPH_ENABLE_GPU Off CACHE BOOL
""
)
set
(
MIGRAPH_ENABLE_GPU Off CACHE BOOL
""
)
endif
()
endif
()
add_compile_options
(
-std=c++14
)
add_compile_options
(
-std=c++14
-g -O0
)
list
(
APPEND CMAKE_MODULE_PATH
${
CMAKE_CURRENT_SOURCE_DIR
}
/cmake
)
list
(
APPEND CMAKE_MODULE_PATH
${
CMAKE_CURRENT_SOURCE_DIR
}
/cmake
)
include
(
EnableCompilerWarnings
)
include
(
EnableCompilerWarnings
)
...
...
src/CMakeLists.txt
View file @
029b1e64
...
@@ -10,6 +10,8 @@ add_library(migraph
...
@@ -10,6 +10,8 @@ add_library(migraph
program.cpp
program.cpp
shape.cpp
shape.cpp
simplify_reshapes.cpp
simplify_reshapes.cpp
opt/memory_coloring.cpp
opt/memory_coloring_impl.cpp
)
)
rocm_clang_tidy_check
(
migraph
)
rocm_clang_tidy_check
(
migraph
)
target_include_directories
(
migraph PUBLIC $<BUILD_INTERFACE:
${
CMAKE_CURRENT_SOURCE_DIR
}
/include>
)
target_include_directories
(
migraph PUBLIC $<BUILD_INTERFACE:
${
CMAKE_CURRENT_SOURCE_DIR
}
/include>
)
...
@@ -19,3 +21,10 @@ add_subdirectory(targets/cpu)
...
@@ -19,3 +21,10 @@ add_subdirectory(targets/cpu)
if
(
MIGRAPH_ENABLE_GPU
)
if
(
MIGRAPH_ENABLE_GPU
)
add_subdirectory
(
targets/gpu
)
add_subdirectory
(
targets/gpu
)
endif
()
endif
()
install
(
TARGETS migraph
LIBRARY DESTINATION /opt/rocm/lib
)
install
(
DIRECTORY include/migraph DESTINATION /opt/rocm/include
)
src/eliminate_allocation.cpp
View file @
029b1e64
...
@@ -4,12 +4,17 @@
...
@@ -4,12 +4,17 @@
#include <migraph/operators.hpp>
#include <migraph/operators.hpp>
#include <migraph/iterator_for.hpp>
#include <migraph/iterator_for.hpp>
#include <migraph/ranges.hpp>
#include <migraph/ranges.hpp>
#include <migraph/stringutils.hpp>
#include <migraph/pass_config.hpp>
namespace
migraph
{
namespace
migraph
{
void
eliminate_allocation
::
apply
(
program
&
p
)
const
void
eliminate_allocation
::
apply
(
program
&
p
)
const
{
{
assert
(
alignment
>
0
);
assert
(
alignment
>
0
);
if
(
!
enabled
(
MIGRAPH_DISABLE_MEMORY_COLORING
{}))
return
;
std
::
size_t
n
=
0
;
std
::
size_t
n
=
0
;
std
::
vector
<
std
::
pair
<
instruction_ref
,
std
::
size_t
>>
allocs
;
std
::
vector
<
std
::
pair
<
instruction_ref
,
std
::
size_t
>>
allocs
;
for
(
auto
ins
:
iterator_for
(
p
))
for
(
auto
ins
:
iterator_for
(
p
))
...
...
src/include/migraph/operators.hpp
View file @
029b1e64
...
@@ -538,7 +538,7 @@ struct load
...
@@ -538,7 +538,7 @@ struct load
{
{
shape
s
;
shape
s
;
std
::
size_t
offset
=
0
;
std
::
size_t
offset
=
0
;
std
::
string
name
()
const
{
return
"load"
;
}
std
::
string
name
()
const
{
return
"load
:
"
;
}
shape
compute_shape
(
const
std
::
vector
<
shape
>&
inputs
)
const
shape
compute_shape
(
const
std
::
vector
<
shape
>&
inputs
)
const
{
{
check_shapes
{
inputs
}.
has
(
1
);
check_shapes
{
inputs
}.
has
(
1
);
...
@@ -548,6 +548,18 @@ struct load
...
@@ -548,6 +548,18 @@ struct load
{
{
return
{
s
,
args
[
0
].
data
()
+
offset
};
return
{
s
,
args
[
0
].
data
()
+
offset
};
}
}
};
struct
write_literal
{
std
::
size_t
offset
=
0
;
bool
pre_copy
=
false
;
std
::
string
name
()
const
{
return
"write_literal"
;
}
shape
compute_shape
(
std
::
vector
<
shape
>
inputs
)
const
{
return
inputs
.
at
(
1
);
}
argument
compute
(
context
&
,
const
shape
&
,
const
std
::
vector
<
argument
>&
)
const
{
MIGRAPH_THROW
(
"not computable"
);
}
};
};
struct
outline
struct
outline
...
...
src/include/migraph/pass.hpp
View file @
029b1e64
...
@@ -216,6 +216,7 @@ inline const ValueType& any_cast(const pass& x)
...
@@ -216,6 +216,7 @@ inline const ValueType& any_cast(const pass& x)
#endif
#endif
}
// namespace migraph
}
// namespace migraph
#endif
#endif
src/include/migraph/program.hpp
View file @
029b1e64
...
@@ -18,7 +18,9 @@ struct program_impl;
...
@@ -18,7 +18,9 @@ struct program_impl;
const
operation
&
get_operation
(
instruction_ref
ins
);
const
operation
&
get_operation
(
instruction_ref
ins
);
/**
/**
* @brief Stores the instruction stream
* @brief Stores the instruction stream
*/
*/
struct
program
struct
program
...
@@ -28,7 +30,7 @@ struct program
...
@@ -28,7 +30,7 @@ struct program
program
&
operator
=
(
program
&&
)
noexcept
;
program
&
operator
=
(
program
&&
)
noexcept
;
~
program
()
noexcept
;
~
program
()
noexcept
;
using
parameter_map
=
std
::
unordered_map
<
std
::
string
,
argument
>
;
using
parameter_map
=
migraph
::
parameter_map
;
template
<
class
...
Ts
>
template
<
class
...
Ts
>
instruction_ref
add_instruction
(
operation
op
,
Ts
...
args
)
instruction_ref
add_instruction
(
operation
op
,
Ts
...
args
)
...
@@ -75,6 +77,8 @@ struct program
...
@@ -75,6 +77,8 @@ struct program
shape
get_parameter_shape
(
std
::
string
name
)
const
;
shape
get_parameter_shape
(
std
::
string
name
)
const
;
instruction_ref
get_parameter
(
std
::
string
name
)
const
;
std
::
unordered_map
<
std
::
string
,
shape
>
get_parameter_shapes
()
const
;
std
::
unordered_map
<
std
::
string
,
shape
>
get_parameter_shapes
()
const
;
argument
eval
(
parameter_map
params
)
const
;
argument
eval
(
parameter_map
params
)
const
;
...
@@ -89,7 +93,7 @@ struct program
...
@@ -89,7 +93,7 @@ struct program
instruction_ref
validate
()
const
;
instruction_ref
validate
()
const
;
void
compile
(
const
target
&
t
,
tracer
trace
=
tracer
{});
void
compile
(
const
target
&
t
,
tracer
trace
=
tracer
{}
,
parameter_map
params
=
parameter_map
()
);
void
perf_report
(
std
::
ostream
&
os
,
std
::
size_t
n
,
parameter_map
params
)
const
;
void
perf_report
(
std
::
ostream
&
os
,
std
::
size_t
n
,
parameter_map
params
)
const
;
...
...
src/include/migraph/target.hpp
View file @
029b1e64
...
@@ -8,13 +8,16 @@
...
@@ -8,13 +8,16 @@
#include <type_traits>
#include <type_traits>
#include <utility>
#include <utility>
#include <vector>
#include <vector>
#include <unordered_map>
#include <migraph/context.hpp>
#include <migraph/context.hpp>
#include <migraph/pass.hpp>
#include <migraph/pass.hpp>
#include <migraph/argument.hpp>
namespace
migraph
{
namespace
migraph
{
using
parameter_map
=
std
::
unordered_map
<
std
::
string
,
argument
>
;
#ifdef DOXYGEN
#ifdef DOXYGEN
/// An interface for a compilation target
/// An interface for a compilation target
struct
target
struct
target
{
{
...
@@ -33,7 +36,7 @@ struct target
...
@@ -33,7 +36,7 @@ struct target
* @brief Construct a context for the target.
* @brief Construct a context for the target.
* @return The context to be used during compilation and execution.
* @return The context to be used during compilation and execution.
*/
*/
context
get_context
()
const
;
context
get_context
(
parameter_map
params
=
parameter_map
()
)
const
;
};
};
#else
#else
...
@@ -119,10 +122,10 @@ struct target
...
@@ -119,10 +122,10 @@ struct target
return
(
*
this
).
private_detail_te_get_handle
().
get_passes
(
ctx
);
return
(
*
this
).
private_detail_te_get_handle
().
get_passes
(
ctx
);
}
}
context
get_context
()
const
context
get_context
(
parameter_map
params
=
parameter_map
()
)
const
{
{
assert
((
*
this
).
private_detail_te_handle_mem_var
);
assert
((
*
this
).
private_detail_te_handle_mem_var
);
return
(
*
this
).
private_detail_te_get_handle
().
get_context
();
return
(
*
this
).
private_detail_te_get_handle
().
get_context
(
params
);
}
}
private:
private:
...
@@ -134,7 +137,7 @@ struct target
...
@@ -134,7 +137,7 @@ struct target
virtual
std
::
string
name
()
const
=
0
;
virtual
std
::
string
name
()
const
=
0
;
virtual
std
::
vector
<
pass
>
get_passes
(
context
&
ctx
)
const
=
0
;
virtual
std
::
vector
<
pass
>
get_passes
(
context
&
ctx
)
const
=
0
;
virtual
context
get_context
()
const
=
0
;
virtual
context
get_context
(
parameter_map
params
=
parameter_map
()
)
const
=
0
;
};
};
template
<
typename
PrivateDetailTypeErasedT
>
template
<
typename
PrivateDetailTypeErasedT
>
...
@@ -173,7 +176,7 @@ struct target
...
@@ -173,7 +176,7 @@ struct target
return
private_detail_te_value
.
get_passes
(
ctx
);
return
private_detail_te_value
.
get_passes
(
ctx
);
}
}
context
get_context
()
const
override
{
return
private_detail_te_value
.
get_context
();
}
context
get_context
(
parameter_map
params
=
parameter_map
()
)
const
override
{
return
private_detail_te_value
.
get_context
(
params
);
}
PrivateDetailTypeErasedT
private_detail_te_value
;
PrivateDetailTypeErasedT
private_detail_te_value
;
};
};
...
...
src/opt/common_header.hpp
0 → 100644
View file @
029b1e64
#ifndef MIGRAPH_GUARD_RTGLIB_COMMON_HEADER_HPP
#define MIGRAPH_GUARD_RTGLIB_COMMON_HEADER_HPP
#include <migraph/program.hpp>
#include <migraph/stringutils.hpp>
#include <migraph/instruction.hpp>
#include <migraph/operators.hpp>
#include <migraph/iterator_for.hpp>
#include <migraph/pass_config.hpp>
#include <set>
#include <list>
#include <vector>
#include <queue>
namespace
migraph
{
#define MIGRAPH_DEBUG_OPT
#ifdef MIGRAPH_DEBUG_OPT
#define MIGRAPH_DEBUG(s) s
#else
#define MIGRAPH_DEBUG(s)
#endif // MIGRAPH_DEBUG_OPT
}
// namespace migraph
#endif // MIGRAPH_GUARD_RTGLIB_COMMON_HEADER_HPP
src/opt/memory_coloring.cpp
0 → 100644
View file @
029b1e64
#include <migraph/memory_coloring.hpp>
#include "memory_coloring_impl.hpp"
namespace
migraph
{
void
memory_coloring
::
apply
(
program
&
p
)
const
{
if
(
!
enabled
(
MIGRAPH_DISABLE_MEMORY_COLORING
{}))
{
memory_coloring_impl
opt
(
&
p
);
opt
.
run
();
}
}
}
// namespace migraph
src/opt/memory_coloring_impl.cpp
0 → 100644
View file @
029b1e64
#include "memory_coloring_impl.hpp"
namespace
migraph
{
void
memory_coloring_impl
::
run
()
{
MIGRAPH_DEBUG
(
dump
(
"---Before memory coloring---"
));
MIGRAPH_DEBUG
(
dump_program
());
register_operand_alias
();
build
();
if
(
num_of_lives
!=
0
)
{
MIGRAPH_DEBUG
(
dump_intervals
());
// Coloring
while
(
!
alloc_queue
.
empty
())
{
interval_ptr
interval
=
alloc_queue
.
top
();
allocate
(
interval
);
alloc_queue
.
pop
();
}
rewrite
();
MIGRAPH_DEBUG
(
verify
());
}
}
bool
memory_coloring_impl
::
allocate
(
interval_ptr
interval
)
{
shape
s
=
interval
->
result
;
std
::
size_t
size
=
s
.
bytes
();
if
(
size
==
0
)
return
false
;
std
::
size_t
element_size
=
size
/
s
.
elements
();
live_range
&
segment
=
interval
->
segment
;
int
vn
=
segment
.
vn
;
std
::
priority_queue
<
live_range
*
,
std
::
vector
<
live_range
*>
,
ordering
>
conflict_queue
;
std
::
unordered_map
<
long
long
,
live_range
*>
offset2_live
;
offset2_live
.
clear
();
if
(
conflict_table
.
find
(
vn
)
!=
conflict_table
.
end
())
{
std
::
set
<
int
>&
vn_set
=
conflict_table
[
vn
];
for
(
auto
&
iter
:
vn_set
)
{
live_range
*
range
=
live_ranges
[
iter
];
long
long
offset
=
range
->
offset
;
if
(
offset
!=
InvalidOffset
)
{
conflict_queue
.
push
(
range
);
if
(
offset2_live
.
find
(
offset
)
==
offset2_live
.
end
())
{
offset2_live
[
offset
]
=
range
;
}
else
{
live_range
*
prev
=
offset2_live
[
offset
];
assert
(
prev
->
offset
==
offset
);
if
(
prev
->
size
<
range
->
size
)
offset2_live
[
offset
]
=
range
;
}
}
}
}
long
long
offset
=
0
;
while
(
!
conflict_queue
.
empty
())
{
live_range
*
range
=
conflict_queue
.
top
();
long
long
iter_offset
=
range
->
offset
;
if
(
offset
>
iter_offset
)
{
offset
=
std
::
max
(
offset
,
iter_offset
+
range
->
size
);
}
else
if
(
offset2_live
[
iter_offset
]
==
range
)
{
if
((
iter_offset
>
offset
)
&&
(
iter_offset
-
offset
)
>=
size
)
{
break
;
}
offset
=
iter_offset
+
range
->
size
;
}
// alignment
if
((
offset
%
element_size
)
!=
0
)
offset
+=
(
element_size
-
(
offset
%
element_size
));
conflict_queue
.
pop
();
}
segment
.
offset
=
offset
;
MIGRAPH_DEBUG
(
segment
.
dump
());
required_bytes
=
std
::
max
(
required_bytes
,
offset
+
segment
.
size
);
return
true
;
}
void
memory_coloring_impl
::
build
()
{
std
::
size_t
num_of_instrs
=
p_program
->
size
();
if
(
num_of_instrs
==
0
)
return
;
int
cur_points
=
num_of_instrs
*
2
;
instruction_ref
iter
=
std
::
prev
(
p_program
->
end
());
instruction_ref
begin
=
p_program
->
begin
();
std
::
vector
<
instruction_ref
>
dead_instrs
;
std
::
set
<
int
>
live_set
;
// Build live intervals.
live_intervals
.
resize
(
num_of_instrs
);
do
{
const
instruction
*
p_iter
=
&
(
*
iter
);
interval_ptr
def_interval
=
nullptr
;
bool
is_dead
=
false
;
if
(
instr2_live
.
find
(
p_iter
)
!=
instr2_live
.
end
())
{
def_interval
=
instr2_live
[
p_iter
];
bool
is_lit
=
is_literal
(
iter
);
if
(
is_allocate
(
iter
)
||
is_lit
)
{
live_range
&
range
=
def_interval
->
segment
;
def_interval
->
result
=
iter
->
result
;
def_interval
->
is_literal
=
is_lit
;
alloc_queue
.
push
(
def_interval
);
range
.
begin
=
cur_points
;
def_interval
->
def_point
=
cur_points
;
range
.
size
=
(
iter
->
result
).
bytes
();
live_set
.
erase
(
range
.
vn
);
}
}
else
if
(
!
is_param
(
iter
)
&&
!
is_outline
(
iter
)
&&
!
is_check_context
(
iter
))
{
is_dead
=
true
;
}
int
tie_ndx
=
get_input_tie_ndx
(
iter
);
int
cnt
=
-
1
;
for
(
auto
&&
arg
:
iter
->
arguments
)
{
cnt
++
;
if
(
is_param
(
arg
)
||
is_outline
(
arg
))
{
if
(
is_output_param
(
arg
))
is_dead
=
false
;
if
(
def_interval
!=
nullptr
)
{
def_interval
->
is_live_on_entry
=
true
;
}
continue
;
}
const
instruction
*
p_arg
=
&
(
*
arg
);
if
(
cnt
==
tie_ndx
)
{
// input memory is used as this instruction's output.
// def is considered as use. Coalesce the live intervals.
assert
(
def_interval
!=
nullptr
);
def_interval
->
add_use
(
cur_points
);
instr2_live
[
p_arg
]
=
def_interval
;
}
else
if
(
instr2_live
.
find
(
p_arg
)
==
instr2_live
.
end
())
{
// First time see a use, create a live interval.
int
id
=
num_of_lives
++
;
interval_ptr
interval
=
&
(
live_intervals
[
id
]);
interval
->
id
=
id
;
interval
->
segment
.
end
=
cur_points
;
interval
->
segment
.
vn
=
++
max_value_number
;
interval
->
add_use
(
cur_points
);
instr2_live
[
p_arg
]
=
interval
;
add_conflicts
(
live_set
,
max_value_number
);
live_set
.
insert
(
max_value_number
);
live_ranges
[
max_value_number
]
=
&
(
interval
->
segment
);
earliest_end_point
=
cur_points
;
}
else
{
interval_ptr
interval
=
instr2_live
[
p_arg
];
interval
->
add_use
(
cur_points
);
assert
(
live_set
.
find
(
interval
->
id
)
!=
live_set
.
end
());
}
}
if
(
is_dead
)
dead_instrs
.
push_back
(
iter
);
cur_points
-=
2
;
iter
=
std
::
prev
(
iter
);
}
while
(
iter
!=
begin
);
}
void
memory_coloring_impl
::
register_operand_alias
()
{
operand_alias
[
"hip::allocate"
]
=
-
1
;
operand_alias
[
"@outline"
]
=
-
1
;
operand_alias
[
"check_context"
]
=
-
1
;
operand_alias
[
"@literal"
]
=
-
1
;
operand_alias
[
"@param"
]
=
-
1
;
operand_alias
[
"transpose"
]
=
0
;
operand_alias
[
"flatten"
]
=
0
;
operand_alias
[
"broadcast"
]
=
1
;
operand_alias
[
"reshape"
]
=
0
;
}
void
memory_coloring_impl
::
rewrite
()
{
instruction_ref
end
=
p_program
->
end
();
instruction_ref
scratch_param
=
end
;
std
::
vector
<
std
::
size_t
>
dims
;
dims
.
push_back
(
required_bytes
/
sizeof
(
float
));
shape
s
=
{
shape
::
float_type
,
dims
};
scratch_param
=
p_program
->
add_parameter
(
"scratch"
,
s
);
for
(
auto
ins
:
iterator_for
(
*
p_program
))
{
const
instruction
*
p_iter
=
&
(
*
ins
);
if
(
instr2_live
.
find
(
p_iter
)
!=
instr2_live
.
end
())
{
interval_ptr
interval
=
instr2_live
[
p_iter
];
if
(
interval
->
get_begin
()
==
InvalidOffset
)
continue
;
std
::
size_t
offset
=
0
;
if
(
interval
->
get_offset
()
==
InvalidOffset
)
{
assert
(
interval
->
result
.
bytes
()
==
0
);
}
else
{
offset
=
interval
->
get_offset
();
}
if
(
is_allocate
(
ins
))
{
p_program
->
replace_instruction
(
ins
,
load
{
ins
->
arguments
.
at
(
0
)
->
result
,
offset
},
scratch_param
);
}
else
if
(
is_literal
(
ins
))
{
auto
pre
=
p_program
->
add_literal
(
ins
->
lit
);
bool
pre_copy
=
(
interval
->
get_begin
()
<
earliest_end_point
)
?
true
:
false
;
p_program
->
replace_instruction
(
ins
,
write_literal
{
offset
,
pre_copy
},
scratch_param
,
pre
);
}
}
}
MIGRAPH_DEBUG
(
dump
(
"---After rewrite---"
));
MIGRAPH_DEBUG
(
dump_program
());
}
#ifdef MIGRAPH_DEBUG_OPT
// map liveness tracking point to instruction enum.
#define GET_INS_ENUM(x) (((x) > 0) ? (((x) >> 1) - 1) : InvalidOffset)
void
memory_coloring_impl
::
dump
(
const
std
::
string
str
)
{
std
::
cout
<<
str
<<
std
::
endl
;
}
void
memory_coloring_impl
::
dump_program
()
{
std
::
cout
<<
*
p_program
<<
std
::
endl
;
}
void
memory_coloring_impl
::
dump_intervals
()
{
if
(
num_of_lives
>
0
)
{
std
::
cout
<<
"---live intervals ---"
<<
std
::
endl
;
for
(
int
i
=
0
;
i
<
num_of_lives
;
++
i
)
{
live_interval
&
interval
=
live_intervals
[
i
];
interval
.
dump
();
}
std
::
cout
<<
"---conflict table---"
<<
std
::
endl
;
for
(
int
i
=
0
;
i
<=
max_value_number
;
++
i
)
{
std
::
cout
<<
" segment:"
<<
i
;
std
::
cout
<<
" =>"
;
std
::
set
<
int
>&
table
=
conflict_table
[
i
];
for
(
auto
&
iter
:
table
)
{
std
::
cout
<<
(
iter
)
<<
","
;
}
}
std
::
cout
<<
std
::
endl
;
}
}
void
memory_coloring_impl
::
verify
()
{
if
(
num_of_lives
>
0
)
{
for
(
int
i
=
0
;
i
<
num_of_lives
;
++
i
)
{
live_interval
&
interval
=
live_intervals
[
i
];
live_range
&
segment
=
interval
.
segment
;
if
(
segment
.
begin
==
InvalidOffset
)
{
assert
(
interval
.
is_live_on_entry
);
continue
;
}
if
(
segment
.
offset
==
InvalidOffset
)
{
continue
;
}
int
vn
=
segment
.
vn
;
if
(
conflict_table
.
find
(
vn
)
!=
conflict_table
.
end
())
{
std
::
set
<
int
>&
vn_set
=
conflict_table
[
vn
];
for
(
auto
&
iter
:
vn_set
)
{
live_range
*
range
=
live_ranges
[
iter
];
if
(
range
->
offset
==
InvalidOffset
)
continue
;
if
(
!
is_disjoin
(
*
range
,
segment
))
assert
(
false
);
}
}
}
}
}
void
live_range
::
dump
()
{
std
::
cout
<<
" segment:"
<<
vn
;
std
::
cout
<<
" ["
<<
GET_INS_ENUM
(
begin
)
<<
", "
<<
GET_INS_ENUM
(
end
)
<<
"]"
;
if
(
offset
!=
InvalidOffset
)
{
std
::
cout
<<
" mem:"
;
std
::
cout
<<
" ["
<<
offset
<<
","
<<
offset
+
size
-
1
<<
"]"
;
}
std
::
cout
<<
std
::
endl
;
}
void
live_interval
::
dump
()
{
std
::
cout
<<
"id:"
<<
id
;
segment
.
dump
();
std
::
cout
<<
" uses:"
;
for
(
auto
&
iter
:
use_points
)
{
std
::
cout
<<
" "
<<
GET_INS_ENUM
(
iter
)
<<
","
;
}
std
::
cout
<<
" def:"
;
std
::
cout
<<
" "
<<
GET_INS_ENUM
(
def_point
);
if
(
is_literal
)
std
::
cout
<<
" literal"
;
std
::
cout
<<
" "
<<
result
;
std
::
cout
<<
std
::
endl
;
}
#endif
}
// namespace migraph
src/opt/memory_coloring_impl.hpp
0 → 100644
View file @
029b1e64
#ifndef MIGRAPH_GUARD_RTGLIB_MEMORY_COLORING_IMPL_HPP
#define MIGRAPH_GUARD_RTGLIB_MEMORY_COLORING_IMPL_HPP
#include "common_header.hpp"
namespace
migraph
{
static
const
int
InvalidOffset
=
-
1
;
struct
live_range
{
int
begin
;
// begin point in the instruction stream.
int
end
;
// end point in the instruction stream.
long
long
offset
;
// offset to base pointer of allocated memory trunk.
int
vn
;
// value number that identifies this live_range.
long
long
size
;
// size of required memory in bytes
#ifdef MIGRAPH_DEBUG_OPT
void
dump
();
#endif
};
struct
live_interval
{
live_interval
()
:
segment
({
InvalidOffset
,
InvalidOffset
,
InvalidOffset
,
InvalidOffset
,
0
})
{
id
=
InvalidOffset
;
def_point
=
InvalidOffset
;
is_literal
=
false
;
is_live_on_entry
=
false
;
}
void
add_use
(
int
use
)
{
use_points
.
push_front
(
use
);
}
int
get_begin
()
const
{
return
segment
.
begin
;
}
int
get_end
()
const
{
return
segment
.
end
;
}
long
long
get_offset
()
const
{
return
segment
.
offset
;
}
#ifdef MIGRAPH_DEBUG_OPT
void
dump
();
#endif
live_range
segment
;
int
id
;
std
::
list
<
int
>
use_points
;
int
def_point
;
shape
result
;
bool
is_literal
;
bool
is_live_on_entry
;
};
typedef
live_interval
*
interval_ptr
;
struct
memory_coloring_impl
{
memory_coloring_impl
(
program
*
p
)
:
p_program
(
p
)
{
instr2_live
.
clear
();
live_ranges
.
clear
();
conflict_table
.
clear
();
num_of_lives
=
0
;
max_value_number
=
-
1
;
required_bytes
=
0
;
operand_alias
.
clear
();
earliest_end_point
=
-
1
;
}
bool
allocate
(
interval_ptr
);
void
add_conflicts
(
std
::
set
<
int
>&
live_set
,
int
val
)
{
for
(
auto
&
iter
:
live_set
)
{
conflict_table
[
iter
].
insert
(
val
);
conflict_table
[
val
].
insert
(
iter
);
}
}
void
build
();
void
run
();
void
register_operand_alias
();
void
rewrite
();
private:
static
bool
is_param
(
const
instruction_ref
ins
)
{
return
ins
->
op
.
name
()
==
"@param"
;
}
static
bool
is_output_param
(
const
instruction_ref
ins
)
{
return
is_param
(
ins
)
&&
any_cast
<
builtin
::
param
>
(
ins
->
op
).
parameter
==
"output"
;
}
static
bool
is_allocate
(
const
instruction_ref
ins
)
{
return
ins
->
op
.
name
()
==
"hip::allocate"
;
}
static
bool
is_outline
(
const
instruction_ref
ins
)
{
return
ins
->
op
.
name
()
==
"@outline"
;
}
static
bool
is_literal
(
const
instruction_ref
ins
)
{
return
ins
->
op
.
name
()
==
"@literal"
;
}
static
bool
is_check_context
(
const
instruction_ref
ins
)
{
return
ins
->
op
.
name
()
==
"check_context"
;
}
// get operand alias info. This is a temporary workaround.
int
get_input_tie_ndx
(
const
instruction_ref
ins
)
{
std
::
string
name
=
ins
->
op
.
name
();
if
(
operand_alias
.
find
(
name
)
!=
operand_alias
.
end
())
return
operand_alias
[
name
];
int
cnt
=
-
1
;
int
last_allocate
=
-
1
;
for
(
auto
&&
arg
:
ins
->
arguments
)
{
cnt
++
;
if
(
is_allocate
(
arg
)
||
is_output_param
(
arg
))
last_allocate
=
cnt
;
}
if
(
last_allocate
!=
-
1
)
operand_alias
[
name
]
=
last_allocate
;
else
assert
(
"unknown operand alias"
);
return
last_allocate
;
}
#ifdef MIGRAPH_DEBUG_OPT
static
bool
is_disjoin
(
live_range
&
range1
,
live_range
&
range2
)
{
if
((
range1
.
size
==
0
)
||
(
range2
.
size
==
0
))
return
false
;
long
long
end1
=
range1
.
offset
+
range1
.
size
-
1
;
long
long
end2
=
range2
.
offset
+
range2
.
size
-
1
;
return
((
end1
<
range2
.
offset
)
||
(
end2
<
range1
.
offset
));
}
void
dump
(
const
std
::
string
);
void
dump_program
();
void
dump_intervals
();
void
verify
();
#endif
struct
ordering
{
bool
operator
()(
const
interval_ptr
i1
,
const
interval_ptr
i2
)
const
{
int
len1
=
i1
->
get_end
()
-
i1
->
get_begin
();
int
len2
=
i2
->
get_end
()
-
i2
->
get_begin
();
if
(
len1
!=
len2
)
{
return
(
len1
<
len2
)
?
true
:
false
;
}
else
if
(
i1
->
result
.
bytes
()
!=
i2
->
result
.
bytes
())
{
return
(
i1
->
result
.
bytes
()
<
i2
->
result
.
bytes
())
?
true
:
false
;
}
else
{
return
i1
->
id
>
i2
->
id
;
}
}
bool
operator
()(
const
live_range
*
i1
,
const
live_range
*
i2
)
const
{
return
(
i1
->
offset
>
i2
->
offset
);
}
};
program
*
p_program
;
std
::
unordered_map
<
const
instruction
*
,
interval_ptr
>
instr2_live
;
// universe of live intervals.
std
::
vector
<
live_interval
>
live_intervals
;
// Map live range value number to live range.
std
::
unordered_map
<
int
,
live_range
*>
live_ranges
;
// Map live range value number to a set of conflicting live ranges' value numbers.
std
::
unordered_map
<
int
,
std
::
set
<
int
>>
conflict_table
;
// Priority queue for coloring.
std
::
priority_queue
<
interval_ptr
,
std
::
vector
<
interval_ptr
>
,
ordering
>
alloc_queue
;
std
::
unordered_map
<
std
::
string
,
int
>
operand_alias
;
int
num_of_lives
;
int
max_value_number
;
long
long
required_bytes
;
// The earliest program point where an live interval ends.
int
earliest_end_point
;
};
}
// namespace migraph
#endif
src/program.cpp
View file @
029b1e64
...
@@ -203,6 +203,25 @@ shape program::get_parameter_shape(std::string name) const
...
@@ -203,6 +203,25 @@ shape program::get_parameter_shape(std::string name) const
return
{};
return
{};
}
}
instruction_ref
program
::
get_parameter
(
std
::
string
name
)
const
{
auto
ins
=
std
::
find_if
(
impl
->
instructions
.
begin
(),
impl
->
instructions
.
end
(),
[
&
](
const
instruction
&
x
)
{
if
(
x
.
op
.
name
()
==
"@param"
)
{
return
any_cast
<
builtin
::
param
>
(
x
.
op
).
parameter
==
name
;
}
else
{
return
false
;
}
});
if
(
ins
!=
this
->
end
())
return
ins
;
else
return
this
->
end
();
}
std
::
unordered_map
<
std
::
string
,
shape
>
program
::
get_parameter_shapes
()
const
std
::
unordered_map
<
std
::
string
,
shape
>
program
::
get_parameter_shapes
()
const
{
{
std
::
unordered_map
<
std
::
string
,
shape
>
result
;
std
::
unordered_map
<
std
::
string
,
shape
>
result
;
...
@@ -238,10 +257,10 @@ instruction_ref program::validate() const
...
@@ -238,10 +257,10 @@ instruction_ref program::validate() const
[
&
](
const
instruction
&
i
)
{
return
!
i
.
valid
(
impl
->
instructions
.
begin
());
});
[
&
](
const
instruction
&
i
)
{
return
!
i
.
valid
(
impl
->
instructions
.
begin
());
});
}
}
void
program
::
compile
(
const
target
&
t
,
tracer
trace
)
void
program
::
compile
(
const
target
&
t
,
tracer
trace
,
parameter_map
params
)
{
{
assert
(
this
->
validate
()
==
impl
->
instructions
.
end
());
assert
(
this
->
validate
()
==
impl
->
instructions
.
end
());
this
->
impl
->
ctx
=
t
.
get_context
();
this
->
impl
->
ctx
=
t
.
get_context
(
params
);
if
(
not
trace
.
enabled
()
and
enabled
(
MIGRAPH_TRACE_COMPILE
{}))
if
(
not
trace
.
enabled
()
and
enabled
(
MIGRAPH_TRACE_COMPILE
{}))
trace
=
tracer
{
std
::
cout
};
trace
=
tracer
{
std
::
cout
};
trace
(
*
this
);
trace
(
*
this
);
...
...
src/targets/cpu/CMakeLists.txt
View file @
029b1e64
...
@@ -13,3 +13,8 @@ target_link_libraries(migraph_cpu migraph Threads::Threads)
...
@@ -13,3 +13,8 @@ target_link_libraries(migraph_cpu migraph Threads::Threads)
target_include_directories
(
migraph_cpu PUBLIC $<BUILD_INTERFACE:
${
CMAKE_CURRENT_SOURCE_DIR
}
/include>
)
target_include_directories
(
migraph_cpu PUBLIC $<BUILD_INTERFACE:
${
CMAKE_CURRENT_SOURCE_DIR
}
/include>
)
target_include_directories
(
migraph_cpu PRIVATE
${
BLAZE_INCLUDE
}
)
target_include_directories
(
migraph_cpu PRIVATE
${
BLAZE_INCLUDE
}
)
target_compile_definitions
(
migraph_cpu PRIVATE -DBLAZE_USE_CPP_THREADS
)
target_compile_definitions
(
migraph_cpu PRIVATE -DBLAZE_USE_CPP_THREADS
)
install
(
TARGETS migraph_cpu
LIBRARY DESTINATION /opt/rocm/lib
)
install
(
DIRECTORY include/migraph DESTINATION /opt/rocm/include
)
src/targets/cpu/include/migraph/cpu/context.hpp
View file @
029b1e64
#ifndef MIGRAPH_GUARD_RTGLIB_CONTEXT_HPP
#ifndef MIGRAPH_GUARD_RTGLIB_CONTEXT_HPP
#define MIGRAPH_GUARD_RTGLIB_CONTEXT_HPP
#define MIGRAPH_GUARD_RTGLIB_CONTEXT_HPP
#include <migraph/argument.hpp>
#include <unordered_map>
namespace
migraph
{
namespace
migraph
{
namespace
cpu
{
namespace
cpu
{
using
parameter_map
=
std
::
unordered_map
<
std
::
string
,
argument
>
;
struct
context
struct
context
{
{
parameter_map
params
;
void
finish
()
const
{}
void
finish
()
const
{}
};
};
...
...
src/targets/cpu/include/migraph/cpu/cpu_target.hpp
View file @
029b1e64
...
@@ -11,7 +11,7 @@ struct cpu_target
...
@@ -11,7 +11,7 @@ struct cpu_target
{
{
std
::
string
name
()
const
;
std
::
string
name
()
const
;
std
::
vector
<
pass
>
get_passes
(
migraph
::
context
&
ctx
)
const
;
std
::
vector
<
pass
>
get_passes
(
migraph
::
context
&
ctx
)
const
;
migraph
::
context
get_context
()
const
{
return
context
{};
}
migraph
::
context
get_context
(
parameter_map
params
=
parameter_map
()
)
const
{
return
context
{
params
};
}
};
};
}
// namespace cpu
}
// namespace cpu
...
...
src/targets/gpu/CMakeLists.txt
View file @
029b1e64
...
@@ -26,9 +26,19 @@ add_library(migraph_gpu
...
@@ -26,9 +26,19 @@ add_library(migraph_gpu
hip.cpp
hip.cpp
target.cpp
target.cpp
lowering.cpp
lowering.cpp
lowering_memory_coloring.cpp
write_literals.cpp
write_literals.cpp
rocblas.cpp
rocblas.cpp
)
)
rocm_clang_tidy_check
(
migraph_gpu
)
rocm_clang_tidy_check
(
migraph_gpu
)
target_link_libraries
(
migraph_gpu migraph MIOpen migraph_device roc::rocblas
)
target_link_libraries
(
migraph_gpu migraph MIOpen migraph_device roc::rocblas
)
target_include_directories
(
migraph_gpu PUBLIC $<BUILD_INTERFACE:
${
CMAKE_CURRENT_SOURCE_DIR
}
/include>
)
target_include_directories
(
migraph_gpu PUBLIC $<BUILD_INTERFACE:
${
CMAKE_CURRENT_SOURCE_DIR
}
/include>
)
install
(
TARGETS migraph_gpu
LIBRARY DESTINATION /opt/rocm/lib
)
install
(
DIRECTORY include/migraph DESTINATION /opt/rocm/include
)
install
(
TARGETS migraph_device
LIBRARY DESTINATION /opt/rocm/lib
)
install
(
DIRECTORY include/migraph DESTINATION /opt/rocm/include
)
src/targets/gpu/eliminate_workspace.cpp
View file @
029b1e64
...
@@ -6,12 +6,16 @@
...
@@ -6,12 +6,16 @@
#include <migraph/iterator_for.hpp>
#include <migraph/iterator_for.hpp>
#include <migraph/ranges.hpp>
#include <migraph/ranges.hpp>
#include <migraph/stringutils.hpp>
#include <migraph/stringutils.hpp>
#include <migraph/pass_config.hpp>
namespace
migraph
{
namespace
migraph
{
namespace
gpu
{
namespace
gpu
{
void
eliminate_workspace
::
apply
(
program
&
p
)
const
void
eliminate_workspace
::
apply
(
program
&
p
)
const
{
{
if
(
!
enabled
(
MIGRAPH_DISABLE_MEMORY_COLORING
{}))
return
;
std
::
size_t
n
=
0
;
std
::
size_t
n
=
0
;
std
::
vector
<
instruction_ref
>
allocs
;
std
::
vector
<
instruction_ref
>
allocs
;
for
(
auto
ins
:
iterator_for
(
p
))
for
(
auto
ins
:
iterator_for
(
p
))
...
...
src/targets/gpu/hip.cpp
View file @
029b1e64
...
@@ -90,6 +90,11 @@ argument from_gpu(argument arg)
...
@@ -90,6 +90,11 @@ argument from_gpu(argument arg)
void
gpu_sync
()
{
hipDeviceSynchronize
();
}
void
gpu_sync
()
{
hipDeviceSynchronize
();
}
void
copy_to_gpu
(
char
*
dst
,
const
char
*
src
,
std
::
size_t
size
)
{
hipMemcpy
(
dst
,
src
,
size
,
hipMemcpyHostToDevice
);
}
}
// namespace gpu
}
// namespace gpu
}
// namespace migraph
}
// namespace migraph
src/targets/gpu/include/migraph/gpu/context.hpp
View file @
029b1e64
...
@@ -5,13 +5,17 @@
...
@@ -5,13 +5,17 @@
#include <migraph/gpu/rocblas.hpp>
#include <migraph/gpu/rocblas.hpp>
#include <migraph/gpu/hip.hpp>
#include <migraph/gpu/hip.hpp>
#include <unordered_map>
namespace
migraph
{
namespace
migraph
{
namespace
gpu
{
namespace
gpu
{
using
parameter_map
=
std
::
unordered_map
<
std
::
string
,
argument
>
;
struct
context
struct
context
{
{
shared
<
miopen_handle
>
handle
;
shared
<
miopen_handle
>
handle
;
shared
<
rocblas_handle_ptr
>
rbhandle
;
shared
<
rocblas_handle_ptr
>
rbhandle
;
parameter_map
params
;
argument
scratch
;
std
::
vector
<
argument
>
literals
{};
std
::
vector
<
argument
>
literals
{};
void
finish
()
const
{
gpu_sync
();
}
void
finish
()
const
{
gpu_sync
();
}
};
};
...
...
src/targets/gpu/include/migraph/gpu/hip.hpp
View file @
029b1e64
...
@@ -15,6 +15,8 @@ migraph::argument from_gpu(migraph::argument arg);
...
@@ -15,6 +15,8 @@ migraph::argument from_gpu(migraph::argument arg);
void
gpu_sync
();
void
gpu_sync
();
void
copy_to_gpu
(
char
*
dst
,
const
char
*
src
,
std
::
size_t
size
);
struct
hip_allocate
struct
hip_allocate
{
{
std
::
string
tag
{};
std
::
string
tag
{};
...
@@ -30,22 +32,6 @@ struct hip_allocate
...
@@ -30,22 +32,6 @@ struct hip_allocate
}
}
};
};
struct
hip_load
{
shape
s
;
std
::
size_t
offset
=
0
;
std
::
string
name
()
const
{
return
"hip::load"
;
}
shape
compute_shape
(
const
std
::
vector
<
shape
>&
inputs
)
const
{
check_shapes
{
inputs
}.
has
(
1
);
return
s
;
}
argument
compute
(
context
&
,
const
shape
&
,
const
std
::
vector
<
argument
>&
args
)
const
{
return
{
s
,
args
[
0
].
data
()
+
offset
};
}
};
struct
hip_sync
struct
hip_sync
{
{
std
::
string
tag
{};
std
::
string
tag
{};
...
@@ -81,6 +67,21 @@ struct hip_write
...
@@ -81,6 +67,21 @@ struct hip_write
}
}
};
};
struct
hip_memcpy
{
std
::
string
name
()
const
{
return
"hip_memcpy"
;
}
shape
compute_shape
(
std
::
vector
<
shape
>
inputs
)
const
{
return
inputs
.
at
(
1
);
}
argument
compute
(
context
&
,
shape
output_shape
,
std
::
vector
<
argument
>
args
)
const
{
char
*
dst
=
args
.
at
(
0
).
data
()
+
offset
;
const
char
*
src
=
args
.
at
(
1
).
data
();
std
::
size_t
size
=
args
.
at
(
1
).
get_shape
().
bytes
();
copy_to_gpu
(
dst
,
src
,
size
);
return
{
output_shape
,
dst
};
}
std
::
size_t
offset
=
0
;
};
}
// namespace gpu
}
// namespace gpu
}
// namespace migraph
}
// namespace migraph
...
...
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