Commit 117ae108 authored by Paul's avatar Paul
Browse files

Add test for eliminate allocation

parent 530e1b9d
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
add_library(migraph add_library(migraph
auto_contiguous.cpp auto_contiguous.cpp
dead_code_elimination.cpp dead_code_elimination.cpp
eliminate_allocation.cpp
eliminate_contiguous.cpp eliminate_contiguous.cpp
fwd_conv_batchnorm_rewrite.cpp fwd_conv_batchnorm_rewrite.cpp
env.cpp env.cpp
......
#include <migraph/gpu/eliminate_allocation.hpp> #include <migraph/eliminate_allocation.hpp>
#include <migraph/gpu/hip.hpp>
#include <migraph/program.hpp> #include <migraph/program.hpp>
#include <migraph/instruction.hpp> #include <migraph/instruction.hpp>
#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>
namespace migraph { namespace migraph {
namespace gpu {
void eliminate_allocation::apply(program& p) const void eliminate_allocation::apply(program& p) const
{ {
assert(alignment > 0);
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))
{ {
if(ins->op.name() != "hip::allocate") if(ins->op.name() != allocation_op)
continue; continue;
allocs.emplace_back(ins, n); allocs.emplace_back(ins, n);
std::size_t size = ins->get_shape().bytes(); std::size_t size = ins->get_shape().bytes();
n += size + (size % 32); std::size_t padding = (alignment - (size % alignment)) % alignment;
n += size + padding;
} }
auto mem = p.add_parameter("memory", shape{shape::int8_type, {n}}); auto mem = p.add_parameter("memory", shape{shape::int8_type, {n}});
for(auto&& pp : allocs) for(auto&& pp : allocs)
...@@ -28,8 +27,7 @@ void eliminate_allocation::apply(program& p) const ...@@ -28,8 +27,7 @@ void eliminate_allocation::apply(program& p) const
auto ins = pp.first; auto ins = pp.first;
auto s = ins->get_shape(); auto s = ins->get_shape();
auto offset = pp.second; auto offset = pp.second;
p.replace_instruction(ins, hip_load{s, offset}, mem); p.replace_instruction(ins, load{s, offset}, mem);
} }
} }
} // namespace gpu
} // namespace migraph } // namespace migraph
...@@ -7,14 +7,13 @@ ...@@ -7,14 +7,13 @@
namespace migraph { namespace migraph {
struct program; struct program;
namespace gpu {
struct eliminate_allocation struct eliminate_allocation
{ {
std::string allocation_op{};
std::size_t alignment = 32;
std::string name() const { return "eliminate_allocation"; } std::string name() const { return "eliminate_allocation"; }
void apply(program& p) const; void apply(program& p) const;
}; };
} // namespace gpu
} // namespace migraph } // namespace migraph
#endif #endif
...@@ -534,6 +534,22 @@ struct div : binary ...@@ -534,6 +534,22 @@ struct div : binary
std::string name() const { return "div"; } std::string name() const { return "div"; }
}; };
struct load
{
shape s;
std::size_t offset = 0;
std::string name() const { return "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 outline struct outline
{ {
shape s; shape s;
......
...@@ -21,7 +21,6 @@ target_include_directories(migraph_device PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRE ...@@ -21,7 +21,6 @@ target_include_directories(migraph_device PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRE
target_include_directories(migraph_device PRIVATE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/device/include>) target_include_directories(migraph_device PRIVATE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/device/include>)
add_library(migraph_gpu add_library(migraph_gpu
eliminate_allocation.cpp
eliminate_workspace.cpp eliminate_workspace.cpp
fuse_ops.cpp fuse_ops.cpp
hip.cpp hip.cpp
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
#include <migraph/gpu/write_literals.hpp> #include <migraph/gpu/write_literals.hpp>
#include <migraph/gpu/context.hpp> #include <migraph/gpu/context.hpp>
#include <migraph/gpu/eliminate_workspace.hpp> #include <migraph/gpu/eliminate_workspace.hpp>
#include <migraph/gpu/eliminate_allocation.hpp> #include <migraph/eliminate_allocation.hpp>
#include <migraph/gpu/fuse_ops.hpp> #include <migraph/gpu/fuse_ops.hpp>
#include <migraph/check_context.hpp> #include <migraph/check_context.hpp>
#include <migraph/auto_contiguous.hpp> #include <migraph/auto_contiguous.hpp>
...@@ -34,7 +34,7 @@ std::vector<pass> target::get_passes(migraph::context& gctx) const ...@@ -34,7 +34,7 @@ std::vector<pass> target::get_passes(migraph::context& gctx) const
eliminate_contiguous{}, eliminate_contiguous{},
dead_code_elimination{}, dead_code_elimination{},
write_literals{&ctx}, write_literals{&ctx},
eliminate_allocation{}, eliminate_allocation{""},
check_context<context>{}, check_context<context>{},
dead_code_elimination{} dead_code_elimination{}
}; };
......
#include <migraph/eliminate_allocation.hpp>
#include <migraph/dead_code_elimination.hpp>
#include <migraph/operators.hpp>
#include <basic_ops.hpp>
#include <test.hpp>
struct eliminate_allocation_target
{
std::size_t align = 32;
std::string name() const { return "eliminate_allocation"; }
std::vector<migraph::pass> get_passes(migraph::context&) const
{
return {migraph::eliminate_allocation{"allocate", align}, migraph::dead_code_elimination{}};
}
migraph::context get_context() const { return {}; }
};
struct allocate
{
migraph::shape s{};
std::string name() const { return "allocate"; }
migraph::shape compute_shape(const std::vector<migraph::shape>& inputs) const
{
migraph::check_shapes{inputs}.has(0);
return s;
}
migraph::argument compute(migraph::context&, const migraph::shape& output_shape, const std::vector<migraph::argument>&) const
{
return {output_shape};
}
};
void basic()
{
migraph::program p;
auto a1 = p.add_instruction(allocate{migraph::shape{migraph::shape::float_type, {8}}});
auto p1 = p.add_instruction(pass_op{}, a1);
auto a2 = p.add_instruction(allocate{migraph::shape{migraph::shape::float_type, {40}}});
auto p2 = p.add_instruction(pass_op{}, a2, p1);
auto a3 = p.add_instruction(allocate{migraph::shape{migraph::shape::float_type, {200}}});
p.add_instruction(pass_op{}, a3, p2);
p.compile(eliminate_allocation_target{});
EXPECT(p.get_shape() == migraph::shape{migraph::shape::float_type, {200}});
EXPECT(p.get_parameter_shape("memory").bytes() == (8*4 + 40*4 + 200*4));
}
void aligned()
{
migraph::program p;
auto a1 = p.add_instruction(allocate{migraph::shape{migraph::shape::float_type, {1}}});
auto p1 = p.add_instruction(pass_op{}, a1);
auto a2 = p.add_instruction(allocate{migraph::shape{migraph::shape::float_type, {2}}});
auto p2 = p.add_instruction(pass_op{}, a2, p1);
auto a3 = p.add_instruction(allocate{migraph::shape{migraph::shape::float_type, {200}}});
p.add_instruction(pass_op{}, a3, p2);
p.compile(eliminate_allocation_target{});
EXPECT(p.get_shape() == migraph::shape{migraph::shape::float_type, {200}});
EXPECT(p.get_parameter_shape("memory").bytes() == (32 + 32 + 200*4));
}
void unaligned()
{
migraph::program p;
auto a1 = p.add_instruction(allocate{migraph::shape{migraph::shape::float_type, {1}}});
auto p1 = p.add_instruction(pass_op{}, a1);
auto a2 = p.add_instruction(allocate{migraph::shape{migraph::shape::float_type, {2}}});
auto p2 = p.add_instruction(pass_op{}, a2, p1);
auto a3 = p.add_instruction(allocate{migraph::shape{migraph::shape::float_type, {200}}});
p.add_instruction(pass_op{}, a3, p2);
p.compile(eliminate_allocation_target{1});
EXPECT(p.get_shape() == migraph::shape{migraph::shape::float_type, {200}});
EXPECT(p.get_parameter_shape("memory").bytes() == (1*4 + 2*4 + 200*4));
}
void float_aligned()
{
migraph::program p;
auto a1 = p.add_instruction(allocate{migraph::shape{migraph::shape::float_type, {1}}});
auto p1 = p.add_instruction(pass_op{}, a1);
auto a2 = p.add_instruction(allocate{migraph::shape{migraph::shape::float_type, {2}}});
auto p2 = p.add_instruction(pass_op{}, a2, p1);
auto a3 = p.add_instruction(allocate{migraph::shape{migraph::shape::float_type, {200}}});
p.add_instruction(pass_op{}, a3, p2);
p.compile(eliminate_allocation_target{4});
EXPECT(p.get_shape() == migraph::shape{migraph::shape::float_type, {200}});
EXPECT(p.get_parameter_shape("memory").bytes() == (1*4 + 2*4 + 200*4));
}
int main()
{
basic();
aligned();
unaligned();
float_aligned();
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment