Commit 06fb0905 authored by Scott Thornton's avatar Scott Thornton
Browse files

Added MNIST test for cpu target

parents 0a59f103 cff16121
#include <rtg/literal.hpp> #include <migraph/literal.hpp>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include "test.hpp" #include "test.hpp"
void literal_test() void literal_test()
{ {
EXPECT(rtg::literal{1} == rtg::literal{1}); EXPECT(migraph::literal{1} == migraph::literal{1});
EXPECT(rtg::literal{1} != rtg::literal{2}); EXPECT(migraph::literal{1} != migraph::literal{2});
EXPECT(rtg::literal{} == rtg::literal{}); EXPECT(migraph::literal{} == migraph::literal{});
EXPECT(rtg::literal{} != rtg::literal{2}); EXPECT(migraph::literal{} != migraph::literal{2});
rtg::literal l1{1}; migraph::literal l1{1};
rtg::literal l2 = l1; // NOLINT migraph::literal l2 = l1; // NOLINT
EXPECT(l1 == l2); EXPECT(l1 == l2);
EXPECT(l1.at<int>(0) == 1); EXPECT(l1.at<int>(0) == 1);
EXPECT(!l1.empty()); EXPECT(!l1.empty());
EXPECT(!l2.empty()); EXPECT(!l2.empty());
rtg::literal l3{}; migraph::literal l3{};
rtg::literal l4{}; migraph::literal l4{};
EXPECT(l3 == l4); EXPECT(l3 == l4);
EXPECT(l3.empty()); EXPECT(l3.empty());
EXPECT(l4.empty()); EXPECT(l4.empty());
...@@ -27,7 +27,7 @@ void literal_test() ...@@ -27,7 +27,7 @@ void literal_test()
void literal_os1() void literal_os1()
{ {
rtg::literal l{1}; migraph::literal l{1};
std::stringstream ss; std::stringstream ss;
ss << l; ss << l;
EXPECT(ss.str() == "1"); EXPECT(ss.str() == "1");
...@@ -35,7 +35,7 @@ void literal_os1() ...@@ -35,7 +35,7 @@ void literal_os1()
void literal_os2() void literal_os2()
{ {
rtg::literal l{}; migraph::literal l{};
std::stringstream ss; std::stringstream ss;
ss << l; ss << l;
EXPECT(ss.str().empty()); EXPECT(ss.str().empty());
...@@ -43,8 +43,8 @@ void literal_os2() ...@@ -43,8 +43,8 @@ void literal_os2()
void literal_os3() void literal_os3()
{ {
rtg::shape s{rtg::shape::int64_type, {3}}; migraph::shape s{migraph::shape::int64_type, {3}};
rtg::literal l{s, {1, 2, 3}}; migraph::literal l{s, {1, 2, 3}};
std::stringstream ss; std::stringstream ss;
ss << l; ss << l;
EXPECT(ss.str() == "1, 2, 3"); EXPECT(ss.str() == "1, 2, 3");
......
#include <rtg/program.hpp> #include <migraph/program.hpp>
#include <rtg/operators.hpp> #include <migraph/operators.hpp>
#include <rtg/generate.hpp> #include <migraph/generate.hpp>
#include <rtg/cpu/cpu_target.hpp> #include <migraph/cpu/cpu_target.hpp>
#include <rtg/miopen/miopen_target.hpp> #include <migraph/miopen/miopen_target.hpp>
#include <rtg/manage_ptr.hpp> #include <migraph/miopen/miopen.hpp>
#include <migraph/miopen/hip.hpp>
#include <migraph/manage_ptr.hpp>
#include <miopen/miopen.h> #include <miopen/miopen.h>
#include "test.hpp" #include "test.hpp"
#include "verify.hpp" #include "verify.hpp"
using hip_ptr = RTG_MANAGE_PTR(void, hipFree); template <class V>
using miopen_handle = RTG_MANAGE_PTR(miopenHandle_t, miopenDestroy); migraph::argument run_cpu()
template <class Result, class F, class... Ts>
Result make_obj(F f, Ts... xs)
{ {
typename Result::pointer x = nullptr; V v;
auto status = f(&x, xs...); auto p = v.create_program();
Result r{x}; p.compile(migraph::cpu::cpu_target{});
if(status != miopenStatusSuccess) return p.eval(v.create_params());
RTG_THROW("MIOpen call failed");
return r;
} }
hip_ptr hip_allocate(std::size_t sz) template <class V>
migraph::argument run_gpu()
{ {
void* result; V v;
// TODO: Check status auto p = v.create_program();
hipMalloc(&result, sz); p.compile(migraph::miopen::miopen_target{});
return hip_ptr{result};
auto m = v.create_params();
for(auto&& e : m)
{
e.second = migraph::miopen::to_gpu(e.second);
}
m["output"] =
migraph::miopen::to_gpu(migraph::generate_argument(p.get_parameter_shape("output")));
return migraph::miopen::from_gpu(p.eval(m));
} }
template <class T> template <class V>
hip_ptr write(const T& x) void verify_program()
{ {
using type = typename T::value_type; auto cpu_arg = run_cpu<V>();
auto size = x.size() * sizeof(type); auto gpu_arg = run_gpu<V>();
auto result = hip_allocate(size); visit_all(cpu_arg, gpu_arg)([](auto cpu, auto gpu) { EXPECT(test::verify_range(cpu, gpu)); });
// TODO: Check status
hipMemcpy(result.get(), x.data(), size, hipMemcpyHostToDevice);
return result;
} }
template <class T> struct test_add
std::vector<T> read(const void* x, std::size_t sz)
{ {
std::vector<T> result(sz); migraph::program create_program() const
// TODO: Check status {
hipMemcpy(result.data(), x, sz * sizeof(T), hipMemcpyDeviceToHost); migraph::program p;
return result; migraph::shape s{migraph::shape::float_type, {3}};
} auto x = p.add_parameter("x", s);
auto y = p.add_parameter("y", s);
p.add_instruction(migraph::add{}, x, y);
return p;
}
migraph::program::parameter_map create_params() const
{
migraph::program::parameter_map m;
m["x"] = migraph::generate_argument({migraph::shape::float_type, {3}});
m["y"] = migraph::generate_argument({migraph::shape::float_type, {3}});
return m;
}
};
rtg::program create_program() struct test_add_broadcast
{ {
rtg::program p; migraph::program create_program() const
auto input = p.add_parameter("x", rtg::shape{rtg::shape::float_type, {4, 3, 3, 3}}); {
auto weights = p.add_parameter("w", rtg::shape{rtg::shape::float_type, {4, 3, 3, 3}}); migraph::program p;
auto conv = p.add_instruction(rtg::convolution{}, input, weights); migraph::shape s{migraph::shape::float_type, {3}};
p.add_instruction(rtg::activation{"relu"}, conv); auto x = p.add_parameter("x", {migraph::shape::float_type, {2, 2, 3}});
return p; auto y = p.add_parameter("y", {migraph::shape::float_type, {2, 2}});
} auto by = p.add_instruction(migraph::broadcast{0}, x, y);
p.add_instruction(migraph::add{}, x, by);
return p;
}
migraph::program::parameter_map create_params() const
{
migraph::program::parameter_map m;
m["x"] = migraph::generate_argument({migraph::shape::float_type, {2, 2, 3}});
m["y"] = migraph::generate_argument({migraph::shape::float_type, {2, 2}});
return m;
}
};
// TODO: Move to header struct test_conv_relu
rtg::argument get_tensor_argument_gpu(rtg::shape s)
{ {
auto v = rtg::generate_tensor_data<float>(s); migraph::program create_program() const
auto p = rtg::share(write(v)); {
return {s, [p]() mutable { return reinterpret_cast<char*>(p.get()); }}; migraph::program p;
} auto input = p.add_parameter("x", migraph::shape{migraph::shape::float_type, {4, 3, 3, 3}});
auto weights =
p.add_parameter("w", migraph::shape{migraph::shape::float_type, {4, 3, 3, 3}});
auto conv = p.add_instruction(migraph::convolution{}, input, weights);
p.add_instruction(migraph::activation{"relu"}, conv);
return p;
}
migraph::program::parameter_map create_params() const
{
migraph::program::parameter_map m;
m["x"] = migraph::generate_argument({migraph::shape::float_type, {4, 3, 3, 3}});
m["w"] = migraph::generate_argument({migraph::shape::float_type, {4, 3, 3, 3}});
return m;
}
};
std::vector<float> cpu() struct test_conv_pooling
{ {
std::vector<float> result; migraph::program create_program() const
auto p = create_program(); {
auto x = rtg::generate_argument({rtg::shape::float_type, {4, 3, 3, 3}}); migraph::program p;
auto w = rtg::generate_argument({rtg::shape::float_type, {4, 3, 3, 3}}); auto input =
p.compile(rtg::cpu::cpu_target{}); p.add_parameter("x", migraph::shape{migraph::shape::float_type, {4, 3, 32, 32}});
auto r = p.eval({{"x", x}, {"w", w}}); auto weights =
auto output = r.get<float>(); p.add_parameter("w", migraph::shape{migraph::shape::float_type, {4, 3, 3, 3}});
result.assign(output.begin(), output.end()); auto conv = p.add_instruction(migraph::convolution{}, input, weights);
return result; auto pooling = p.add_instruction(migraph::pooling{"max"}, conv);
} p.add_instruction(migraph::activation{"relu"}, pooling);
return p;
}
migraph::program::parameter_map create_params() const
{
migraph::program::parameter_map m;
m["x"] = migraph::generate_argument({migraph::shape::float_type, {4, 3, 32, 32}});
m["w"] = migraph::generate_argument({migraph::shape::float_type, {4, 3, 3, 3}});
return m;
}
};
std::vector<float> gpu() struct test_gemm
{ {
std::vector<float> result; migraph::program create_program() const
auto p = create_program(); {
auto x = get_tensor_argument_gpu({rtg::shape::float_type, {4, 3, 3, 3}}); migraph::program p;
auto w = get_tensor_argument_gpu({rtg::shape::float_type, {4, 3, 3, 3}}); auto a = p.add_parameter("a", migraph::shape{migraph::shape::float_type, {4, 5}});
p.compile(rtg::miopen::miopen_target{}); auto b = p.add_parameter("b", migraph::shape{migraph::shape::float_type, {5, 3}});
auto y = get_tensor_argument_gpu(p.get_parameter_shape("output")); p.add_instruction(migraph::gemm{}, a, b);
auto handle = make_obj<miopen_handle>(&miopenCreate); return p;
auto r = p.eval( }
{{"x", x}, {"w", w}, {"output", y}, {"handle", {rtg::shape::any_type, handle.get()}}});
result = read<float>(r.data(), r.get_shape().elements()); migraph::program::parameter_map create_params() const
return result; {
} migraph::program::parameter_map m;
m["a"] = migraph::generate_argument({migraph::shape::float_type, {4, 5}});
m["b"] = migraph::generate_argument({migraph::shape::float_type, {5, 3}});
return m;
}
};
void test1() int main()
{ {
auto x = cpu(); verify_program<test_add>();
auto y = gpu(); verify_program<test_add_broadcast>();
EXPECT(test::verify_range(x, y)); verify_program<test_conv_relu>();
verify_program<test_conv_pooling>();
verify_program<test_gemm>();
} }
int main() { test1(); }
#include <rtg/operation.hpp> #include <migraph/operation.hpp>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include "test.hpp" #include "test.hpp"
...@@ -8,10 +8,14 @@ struct simple_operation ...@@ -8,10 +8,14 @@ struct simple_operation
{ {
int data = 1; int data = 1;
std::string name() const { return "simple"; } std::string name() const { return "simple"; }
rtg::shape compute_shape(std::vector<rtg::shape>) const { RTG_THROW("not computable"); } migraph::shape compute_shape(std::vector<migraph::shape>) const
rtg::argument compute(rtg::shape, std::vector<rtg::argument>) const
{ {
RTG_THROW("not computable"); MIGRAPH_THROW("not computable");
}
migraph::argument
compute(migraph::context&, migraph::shape, std::vector<migraph::argument>) const
{
MIGRAPH_THROW("not computable");
} }
friend std::ostream& operator<<(std::ostream& os, const simple_operation& op) friend std::ostream& operator<<(std::ostream& os, const simple_operation& op)
{ {
...@@ -23,18 +27,22 @@ struct simple_operation ...@@ -23,18 +27,22 @@ struct simple_operation
struct simple_operation_no_print struct simple_operation_no_print
{ {
std::string name() const { return "simple"; } std::string name() const { return "simple"; }
rtg::shape compute_shape(std::vector<rtg::shape>) const { RTG_THROW("not computable"); } migraph::shape compute_shape(std::vector<migraph::shape>) const
rtg::argument compute(rtg::shape, std::vector<rtg::argument>) const {
MIGRAPH_THROW("not computable");
}
migraph::argument
compute(migraph::context&, migraph::shape, std::vector<migraph::argument>) const
{ {
RTG_THROW("not computable"); MIGRAPH_THROW("not computable");
} }
}; };
void operation_copy_test() void operation_copy_test()
{ {
simple_operation s{}; simple_operation s{};
rtg::operation op1 = s; // NOLINT migraph::operation op1 = s; // NOLINT
rtg::operation op2 = op1; // NOLINT migraph::operation op2 = op1; // NOLINT
EXPECT(s.name() == op1.name()); EXPECT(s.name() == op1.name());
EXPECT(op2.name() == op1.name()); EXPECT(op2.name() == op1.name());
} }
...@@ -45,18 +53,18 @@ struct not_operation ...@@ -45,18 +53,18 @@ struct not_operation
void operation_any_cast() void operation_any_cast()
{ {
rtg::operation op1 = simple_operation{}; migraph::operation op1 = simple_operation{};
EXPECT(rtg::any_cast<simple_operation>(op1).data == 1); EXPECT(migraph::any_cast<simple_operation>(op1).data == 1);
EXPECT(rtg::any_cast<not_operation*>(&op1) == nullptr); EXPECT(migraph::any_cast<not_operation*>(&op1) == nullptr);
EXPECT(test::throws([&] { rtg::any_cast<not_operation&>(op1); })); EXPECT(test::throws([&] { migraph::any_cast<not_operation&>(op1); }));
rtg::operation op2 = simple_operation{2}; migraph::operation op2 = simple_operation{2};
EXPECT(rtg::any_cast<simple_operation>(op2).data == 2); EXPECT(migraph::any_cast<simple_operation>(op2).data == 2);
EXPECT(rtg::any_cast<not_operation*>(&op2) == nullptr); EXPECT(migraph::any_cast<not_operation*>(&op2) == nullptr);
} }
void operation_print() void operation_print()
{ {
rtg::operation op = simple_operation{}; migraph::operation op = simple_operation{};
std::stringstream ss; std::stringstream ss;
ss << op; ss << op;
std::string s = ss.str(); std::string s = ss.str();
...@@ -65,7 +73,7 @@ void operation_print() ...@@ -65,7 +73,7 @@ void operation_print()
void operation_default_print() void operation_default_print()
{ {
rtg::operation op = simple_operation_no_print{}; migraph::operation op = simple_operation_no_print{};
std::stringstream ss; std::stringstream ss;
ss << op; ss << op;
std::string s = ss.str(); std::string s = ss.str();
......
#include <rtg/shape.hpp> #include <migraph/shape.hpp>
#include <array> #include <array>
#include <algorithm> #include <algorithm>
#include <numeric> #include <numeric>
...@@ -7,25 +7,25 @@ ...@@ -7,25 +7,25 @@
void test_shape_assign() void test_shape_assign()
{ {
rtg::shape s1{rtg::shape::float_type, {100, 32, 8, 8}}; migraph::shape s1{migraph::shape::float_type, {100, 32, 8, 8}};
rtg::shape s2 = s1; // NOLINT migraph::shape s2 = s1; // NOLINT
EXPECT(s1 == s2); EXPECT(s1 == s2);
EXPECT(!(s1 != s2)); EXPECT(!(s1 != s2));
} }
void test_shape_default() void test_shape_default()
{ {
rtg::shape s1{}; migraph::shape s1{};
rtg::shape s2{}; migraph::shape s2{};
EXPECT(s1 == s2); EXPECT(s1 == s2);
EXPECT(!(s1 != s2)); EXPECT(!(s1 != s2));
} }
void test_shape4() void test_shape4()
{ {
rtg::shape s{rtg::shape::float_type, {100, 32, 8, 8}}; migraph::shape s{migraph::shape::float_type, {100, 32, 8, 8}};
EXPECT(s.packed()); EXPECT(s.packed());
EXPECT(s.type() == rtg::shape::float_type); EXPECT(s.type() == migraph::shape::float_type);
EXPECT(s.lens()[0] == 100); EXPECT(s.lens()[0] == 100);
EXPECT(s.lens()[1] == 32); EXPECT(s.lens()[1] == 32);
EXPECT(s.lens()[2] == 8); EXPECT(s.lens()[2] == 8);
...@@ -67,9 +67,9 @@ void test_shape4_nonpacked() ...@@ -67,9 +67,9 @@ void test_shape4_nonpacked()
strides.rbegin() + 1, strides.rbegin() + 1,
std::multiplies<std::size_t>()); std::multiplies<std::size_t>());
rtg::shape s{rtg::shape::float_type, lens, strides}; migraph::shape s{migraph::shape::float_type, lens, strides};
EXPECT(!s.packed()); EXPECT(!s.packed());
EXPECT(s.type() == rtg::shape::float_type); EXPECT(s.type() == migraph::shape::float_type);
EXPECT(s.lens()[0] == 100); EXPECT(s.lens()[0] == 100);
EXPECT(s.lens()[1] == 32); EXPECT(s.lens()[1] == 32);
EXPECT(s.lens()[2] == 8); EXPECT(s.lens()[2] == 8);
......
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
ls -1 $DIR/include/ | xargs -n 1 -P $(nproc) -I{} -t bash -c "python $DIR/te.py $DIR/include/{} | clang-format-5.0 -style=file > $DIR/../src/include/rtg/{}" ls -1 $DIR/include/ | xargs -n 1 -P $(nproc) -I{} -t bash -c "python3.6 $DIR/te.py $DIR/include/{} | clang-format-5.0 -style=file > $DIR/../src/include/migraph/{}"
#ifndef MIGRAPH_GUARD_CONTEXT_HPP
#define MIGRAPH_GUARD_CONTEXT_HPP
namespace migraph {
<%
interface('context')
%>
} // namespace migraph
#endif
#ifndef RTG_GUARD_RTGLIB_OPERAND_HPP #ifndef MIGRAPH_GUARD_MIGRAPHLIB_OPERAND_HPP
#define RTG_GUARD_RTGLIB_OPERAND_HPP #define MIGRAPH_GUARD_MIGRAPHLIB_OPERAND_HPP
#include <string> #include <string>
#include <functional> #include <functional>
#include <memory> #include <memory>
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
#include <rtg/shape.hpp> #include <migraph/shape.hpp>
#include <rtg/argument.hpp> #include <migraph/argument.hpp>
#include <migraph/context.hpp>
namespace rtg { namespace migraph {
namespace operation_stream { namespace operation_stream {
...@@ -25,11 +26,11 @@ auto operator<<(std::ostream& os, const T& x) -> decltype(os << x.name()) ...@@ -25,11 +26,11 @@ auto operator<<(std::ostream& os, const T& x) -> decltype(os << x.name())
interface('operation', interface('operation',
virtual('name', returns='std::string', const=True), virtual('name', returns='std::string', const=True),
virtual('compute_shape', returns='shape', input='std::vector<shape>', const=True), virtual('compute_shape', returns='shape', input='std::vector<shape>', const=True),
virtual('compute', returns='argument', output='shape', input='std::vector<argument>', const=True), virtual('compute', returns='argument', ctx='context&', output='shape', input='std::vector<argument>', const=True),
friend('operator<<', returns='std::ostream &', os='std::ostream &', op='const operation &', using='rtg::operation_stream::operator<<') friend('operator<<', returns='std::ostream &', os='std::ostream &', op='const operation &', using='migraph::operation_stream::operator<<')
) )
%> %>
} // namespace rtg } // namespace migraph
#endif #endif
#ifndef RTG_GUARD_RTGLIB_TARGET_HPP #ifndef MIGRAPH_GUARD_MIGRAPHLIB_TARGET_HPP
#define RTG_GUARD_RTGLIB_TARGET_HPP #define MIGRAPH_GUARD_MIGRAPHLIB_TARGET_HPP
#include <string> #include <string>
#include <functional> #include <functional>
#include <memory> #include <memory>
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
#include <migraph/context.hpp>
namespace rtg { namespace migraph {
struct program; struct program;
<% <%
interface('target', interface('target',
virtual('name', returns='std::string', const=True), virtual('name', returns='std::string', const=True),
virtual('apply', returns='void', p='program &', const=True) virtual('apply', returns='void', p='program &', const=True),
virtual('get_context', returns='context', const=True)
) )
%> %>
} // namespace rtg } // namespace migraph
#endif #endif
...@@ -63,6 +63,12 @@ struct ${struct_name} ...@@ -63,6 +63,12 @@ struct ${struct_name}
nullptr; nullptr;
} }
const std::type_info& type_id() const
{
if(private_detail_te_handle_empty()) return typeid(std::nullptr_t);
else return private_detail_te_get_handle().type();
}
${nonvirtual_members} ${nonvirtual_members}
private: private:
...@@ -118,11 +124,20 @@ private: ...@@ -118,11 +124,20 @@ private:
{} {}
}; };
bool private_detail_te_handle_empty() const
{
return private_detail_te_handle_mem_var == nullptr;
}
const private_detail_te_handle_base_type & private_detail_te_get_handle () const const private_detail_te_handle_base_type & private_detail_te_get_handle () const
{ return *private_detail_te_handle_mem_var; } {
assert(private_detail_te_handle_mem_var != nullptr);
return *private_detail_te_handle_mem_var;
}
private_detail_te_handle_base_type & private_detail_te_get_handle () private_detail_te_handle_base_type & private_detail_te_get_handle ()
{ {
assert(private_detail_te_handle_mem_var != nullptr);
if (!private_detail_te_handle_mem_var.unique()) if (!private_detail_te_handle_mem_var.unique())
private_detail_te_handle_mem_var = private_detail_te_handle_mem_var->clone(); private_detail_te_handle_mem_var = private_detail_te_handle_mem_var->clone();
return *private_detail_te_handle_mem_var; return *private_detail_te_handle_mem_var;
......
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