Commit 4f778e9f authored by Paul's avatar Paul
Browse files

Add tracer

parent 3ea86a4d
...@@ -10,7 +10,7 @@ namespace migraph { ...@@ -10,7 +10,7 @@ namespace migraph {
template <class T> template <class T>
struct xorshf96_generator struct xorshf96_generator
{ {
unsigned long max = 31; long max = 16;
unsigned long x = 123456789; unsigned long x = 123456789;
unsigned long y = 362436069; unsigned long y = 362436069;
unsigned long z = 521288629; unsigned long z = 521288629;
...@@ -26,7 +26,7 @@ struct xorshf96_generator ...@@ -26,7 +26,7 @@ struct xorshf96_generator
y = z; y = z;
z = t ^ x ^ y; z = t ^ x ^ y;
return z % max; return z % max - (max + 1);
} }
}; };
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <migraph/builtin.hpp> #include <migraph/builtin.hpp>
#include <migraph/instruction_ref.hpp> #include <migraph/instruction_ref.hpp>
#include <migraph/target.hpp> #include <migraph/target.hpp>
#include <migraph/tracer.hpp>
#include <algorithm> #include <algorithm>
#include <iostream> #include <iostream>
...@@ -88,7 +89,7 @@ struct program ...@@ -88,7 +89,7 @@ struct program
instruction_ref validate() const; instruction_ref validate() const;
void compile(const target& t); void compile(const target& t, tracer trace = tracer{});
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;
......
...@@ -94,13 +94,13 @@ struct tensor_view ...@@ -94,13 +94,13 @@ struct tensor_view
// TODO: Add iterators so it can handle nonstandard tensors // TODO: Add iterators so it can handle nonstandard tensors
T* begin() T* begin()
{ {
assert(this->m_shape.standard()); assert(this->m_shape.standard() or this->empty());
return m_data; return m_data;
} }
T* end() T* end()
{ {
assert(this->m_shape.standard()); assert(this->m_shape.standard() or this->empty());
if(this->empty()) if(this->empty())
return m_data; return m_data;
else else
...@@ -109,13 +109,13 @@ struct tensor_view ...@@ -109,13 +109,13 @@ struct tensor_view
const T* begin() const const T* begin() const
{ {
assert(this->m_shape.standard()); assert(this->m_shape.standard() or this->empty());
return m_data; return m_data;
} }
const T* end() const const T* end() const
{ {
assert(this->m_shape.standard()); assert(this->m_shape.standard() or this->empty());
if(this->empty()) if(this->empty())
return m_data; return m_data;
else else
......
#ifndef MIGRAPH_GUARD_RTGLIB_TRACER_HPP
#define MIGRAPH_GUARD_RTGLIB_TRACER_HPP
#include <ostream>
namespace migraph {
struct swallow
{
template<class... Ts>
swallow(Ts&&...)
{}
};
struct tracer
{
tracer()
{}
tracer(std::ostream& s) : os(&s)
{}
bool enabled() const
{
return os != nullptr;
}
template<class... Ts>
void operator()(const Ts&... xs) const
{
if(os != nullptr)
{
swallow{*os << xs...};
*os << std::endl;
}
}
private:
std::ostream * os = nullptr;
};
} // namespace migraph
#endif
...@@ -237,23 +237,21 @@ instruction_ref program::validate() const ...@@ -237,23 +237,21 @@ 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) void program::compile(const target& t, tracer trace)
{ {
assert(this->validate() == impl->instructions.end()); assert(this->validate() == impl->instructions.end());
this->impl->ctx = t.get_context(); this->impl->ctx = t.get_context();
if(enabled(MIGRAPH_TRACE_COMPILE{})) if(not trace.enabled() and enabled(MIGRAPH_TRACE_COMPILE{}))
std::cout << *this << std::endl << std::endl; trace = tracer{std::cout};
; trace(*this);
trace();
for(auto&& p : t.get_passes(this->impl->ctx)) for(auto&& p : t.get_passes(this->impl->ctx))
{ {
if(enabled(MIGRAPH_TRACE_COMPILE{})) trace("Pass: ", p.name());
std::cout << "Pass: " << p.name() << std::endl;
p.apply(*this); p.apply(*this);
if(enabled(MIGRAPH_TRACE_COMPILE{})) trace(*this);
std::cout << *this << std::endl;
#ifndef NDEBUG #ifndef NDEBUG
if(enabled(MIGRAPH_TRACE_COMPILE{})) trace("Validate ...");
std::cout << "Validate ..." << std::endl;
auto invalid = this->validate(); auto invalid = this->validate();
if(invalid != impl->instructions.end()) if(invalid != impl->instructions.end())
{ {
...@@ -261,8 +259,7 @@ void program::compile(const target& t) ...@@ -261,8 +259,7 @@ void program::compile(const target& t)
MIGRAPH_THROW(p.name() + " pass produces invalid program at instruction " + MIGRAPH_THROW(p.name() + " pass produces invalid program at instruction " +
std::to_string(index) + ": " + invalid->op.name()); std::to_string(index) + ": " + invalid->op.name());
} }
if(enabled(MIGRAPH_TRACE_COMPILE{})) trace();
std::cout << std::endl;
#endif #endif
} }
auto invalid = this->validate(); auto invalid = this->validate();
......
...@@ -212,6 +212,7 @@ struct cpu_contiguous ...@@ -212,6 +212,7 @@ struct cpu_contiguous
shape compute_shape(const std::vector<shape>& inputs) const { return op.compute_shape(inputs); } shape compute_shape(const std::vector<shape>& inputs) const { return op.compute_shape(inputs); }
argument compute(context&, const shape& output_shape, std::vector<argument> args) const argument compute(context&, const shape& output_shape, std::vector<argument> args) const
{ {
assert(output_shape.standard());
argument result{output_shape}; argument result{output_shape};
visit_all(result, args[0])([&](auto output, auto input) { visit_all(result, args[0])([&](auto output, auto input) {
shape_for_each(output.get_shape(), [&](const auto& idx) { shape_for_each(output.get_shape(), [&](const auto& idx) {
......
...@@ -250,6 +250,8 @@ struct miopen_contiguous ...@@ -250,6 +250,8 @@ struct miopen_contiguous
} }
argument compute(context&, shape output_shape, const std::vector<argument>& args) const argument compute(context&, shape output_shape, const std::vector<argument>& args) const
{ {
assert(output_shape == args[1].get_shape());
assert(output_shape.standard());
hip_contiguous(std::move(output_shape), args.at(0), args.at(1)); hip_contiguous(std::move(output_shape), args.at(0), args.at(1));
return args.at(1); return args.at(1);
} }
......
...@@ -24,13 +24,17 @@ ...@@ -24,13 +24,17 @@
// An improved async, that doesn't block // An improved async, that doesn't block
template <class Function> template <class Function>
std::future<typename std::result_of<Function()>::type> detach_async(Function&& f) std::future<typename std::result_of<Function()>::type> detach_async(Function&& f, bool parallel=true)
{ {
if(parallel){
using result_type = typename std::result_of<Function()>::type; using result_type = typename std::result_of<Function()>::type;
std::packaged_task<result_type()> task(std::forward<Function>(f)); std::packaged_task<result_type()> task(std::forward<Function>(f));
auto fut = task.get_future(); auto fut = task.get_future();
std::thread(std::move(task)).detach(); std::thread(std::move(task)).detach();
return std::move(fut); return std::move(fut);
} else {
return std::async(std::launch::deferred, std::move(f));
}
} }
struct auto_print struct auto_print
...@@ -50,13 +54,26 @@ struct auto_print ...@@ -50,13 +54,26 @@ struct auto_print
}; };
std::array<std::function<void()>, 2> auto_print::handlers = {}; std::array<std::function<void()>, 2> auto_print::handlers = {};
void compile_check(migraph::program& p, migraph::target t)
{
auto name = t.name();
auto s = p.get_shape();
std::stringstream ss;
p.compile(std::move(t), migraph::tracer{ss});
if(p.get_shape() != s)
{
std::cout << ss.str() << std::endl;
throw std::runtime_error("Compiling program with " + name + " alters its shape");
}
}
template <class V> template <class V>
migraph::argument run_cpu() migraph::argument run_cpu()
{ {
V v; V v;
auto p = v.create_program(); auto p = v.create_program();
auto_print pp{p, 0}; auto_print pp{p, 0};
p.compile(migraph::cpu::cpu_target{}); compile_check(p, migraph::cpu::cpu_target{});
migraph::program::parameter_map m; migraph::program::parameter_map m;
for(auto&& x : p.get_parameter_shapes()) for(auto&& x : p.get_parameter_shapes())
{ {
...@@ -71,7 +88,7 @@ migraph::argument run_gpu() ...@@ -71,7 +88,7 @@ migraph::argument run_gpu()
V v; V v;
auto p = v.create_program(); auto p = v.create_program();
auto_print pp{p, 1}; auto_print pp{p, 1};
p.compile(migraph::gpu::target{}); compile_check(p, migraph::gpu::target{});
migraph::program::parameter_map m; migraph::program::parameter_map m;
for(auto&& x : p.get_parameter_shapes()) for(auto&& x : p.get_parameter_shapes())
...@@ -255,6 +272,7 @@ struct test_contiguous ...@@ -255,6 +272,7 @@ struct test_contiguous
migraph::shape s{migraph::shape::float_type, {4, 4, 4, 3}, {48, 4, 1, 16}}; migraph::shape s{migraph::shape::float_type, {4, 4, 4, 3}, {48, 4, 1, 16}};
auto x = p.add_parameter("x", s); auto x = p.add_parameter("x", s);
p.add_instruction(migraph::contiguous{}, x); p.add_instruction(migraph::contiguous{}, x);
EXPECT(p.get_shape().standard());
return p; return p;
} }
}; };
......
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