Commit 8143e4fb authored by wsttiger's avatar wsttiger
Browse files

Merge branch 'master' into remove_concat

parents 0a4583b7 9ca0fbf1
...@@ -4,6 +4,12 @@ if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}") ...@@ -4,6 +4,12 @@ if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
message(FATAL_ERROR "The binary and source directroy cannot be the same") message(FATAL_ERROR "The binary and source directroy cannot be the same")
endif() endif()
# This has to be initialized before the project() command appears
# Set the default of CMAKE_BUILD_TYPE to be release, unless user specifies with -D. MSVC_IDE does not use CMAKE_BUILD_TYPE
if( NOT MSVC_IDE AND NOT CMAKE_BUILD_TYPE )
set( CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." )
endif()
project(migraphlib) project(migraphlib)
find_package(ROCM REQUIRED) find_package(ROCM REQUIRED)
......
...@@ -2,8 +2,5 @@ pfultz2/rocm-recipes ...@@ -2,8 +2,5 @@ pfultz2/rocm-recipes
pcre pcre
danmar/cppcheck@f965e5873 -DHAVE_RULES=1 danmar/cppcheck@f965e5873 -DHAVE_RULES=1
ROCm-Developer-Tools/HIP@3a41f286203968421c557338d6fb39c36f3c717c ROCm-Developer-Tools/HIP@3a41f286203968421c557338d6fb39c36f3c717c
# Needed for clang-ocl
RadeonOpenCompute/rocm-cmake@6240bb3 --build
RadeonOpenCompute/clang-ocl@799713643b5591a3b877c586ef2c7fbc012af819
# python/cpython@v3.6.6 -X autotools -H sha256:92aa914572c695c0aeb01b0a214813f414da4b51a371234df514a74761f2bb36 # python/cpython@v3.6.6 -X autotools -H sha256:92aa914572c695c0aeb01b0a214813f414da4b51a371234df514a74761f2bb36
-f requirements.txt -f requirements.txt
...@@ -14,5 +14,5 @@ gpu::target ...@@ -14,5 +14,5 @@ gpu::target
cpu::target cpu::target
----------- -----------
.. doxygenstruct:: migraph::cpu::cpu_target .. doxygenstruct:: migraph::cpu::target
...@@ -21,6 +21,9 @@ add_library(migraph ...@@ -21,6 +21,9 @@ add_library(migraph
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>)
find_path(HALF_INCLUDE_DIR half.hpp)
target_include_directories(migraph SYSTEM PUBLIC ${HALF_INCLUDE_DIR})
add_subdirectory(onnx) add_subdirectory(onnx)
add_subdirectory(targets/cpu) add_subdirectory(targets/cpu)
if(MIGRAPH_ENABLE_GPU) if(MIGRAPH_ENABLE_GPU)
......
...@@ -3,9 +3,30 @@ ...@@ -3,9 +3,30 @@
#include <migraph/instruction.hpp> #include <migraph/instruction.hpp>
#include <migraph/iterator_for.hpp> #include <migraph/iterator_for.hpp>
#include <migraph/functional.hpp> #include <migraph/functional.hpp>
#include <migraph/ranges.hpp>
namespace migraph { namespace migraph {
template <class Range, class Iterator>
std::ptrdiff_t bidistance(const Range& r, Iterator start, Iterator last)
{
auto start_forward = start;
auto start_backwards = start;
std::size_t n = 0;
while(start_forward != last and start_backwards != last)
{
n++;
if(start_forward != r.end())
start_forward++;
if(start_backwards != r.begin())
start_backwards--;
}
if(start_forward == last)
return n;
else
return -n;
}
void dead_code_elimination::apply(program& p) const void dead_code_elimination::apply(program& p) const
{ {
auto last = std::prev(p.end()); auto last = std::prev(p.end());
...@@ -16,18 +37,21 @@ void dead_code_elimination::apply(program& p) const ...@@ -16,18 +37,21 @@ void dead_code_elimination::apply(program& p) const
if(ins == p.begin()) if(ins == p.begin())
continue; continue;
const auto i = std::prev(ins); const auto i = std::prev(ins);
// Skip instruction with empty shape as output unless its a builtin
if(i->get_shape().elements() == 0 and not(i->name().front() == '@'))
continue;
// Skip the last instruction // Skip the last instruction
if(i == last) if(i == last)
break; break;
// Skip instruction with empty shape as output unless its a builtin
if(i->get_shape().elements() == 0 and not(i->name().front() == '@'))
continue;
assert(bidistance(p, i, last) > 0);
fix([&](auto self, auto leaf) { fix([&](auto self, auto leaf) {
assert(p.has_instruction(leaf)); assert(p.has_instruction(leaf));
if(leaf->outputs().empty()) if(leaf->outputs().empty())
{ {
auto args = leaf->inputs(); auto args = leaf->inputs();
leaf->clear_arguments(); leaf->clear_arguments();
assert(bidistance(p, last, leaf) < 0);
assert(leaf != ins);
p.move_instruction(leaf, p.end()); p.move_instruction(leaf, p.end());
for(auto arg : args) for(auto arg : args)
self(arg); self(arg);
......
...@@ -3,23 +3,24 @@ ...@@ -3,23 +3,24 @@
#include <migraph/argument.hpp> #include <migraph/argument.hpp>
#include <migraph/literal.hpp> #include <migraph/literal.hpp>
#include <migraph/type_traits.hpp>
#include <random> #include <random>
namespace migraph { namespace migraph {
template <class T, MIGRAPH_REQUIRES(std::is_floating_point<T>{})> template <class T, MIGRAPH_REQUIRES(is_floating_point<T>{})>
constexpr T normalize(unsigned long z) constexpr T normalize(unsigned long z)
{ {
if(z == 0) if(z == 0)
return 0; return T(0);
const auto max = 32; const auto max = 32;
const double range = max / 2; // NOLINT const double range = max / 2; // NOLINT
double result = (z % max) / range; double result = (z % max) / range;
result -= 1; result -= 1;
return result; return T(result);
} }
template <class T, MIGRAPH_REQUIRES(std::is_signed<T>{} and not std::is_floating_point<T>{})> template <class T, MIGRAPH_REQUIRES(is_signed<T>{} and not is_floating_point<T>{})>
constexpr T normalize(unsigned long z) constexpr T normalize(unsigned long z)
{ {
const auto max = std::numeric_limits<T>::max(); const auto max = std::numeric_limits<T>::max();
...@@ -27,7 +28,7 @@ constexpr T normalize(unsigned long z) ...@@ -27,7 +28,7 @@ constexpr T normalize(unsigned long z)
return half_max - (z % max); return half_max - (z % max);
} }
template <class T, MIGRAPH_REQUIRES(not std::is_signed<T>{} and std::is_integral<T>{})> template <class T, MIGRAPH_REQUIRES(not is_signed<T>{} and std::is_integral<T>{})>
constexpr T normalize(unsigned long z) constexpr T normalize(unsigned long z)
{ {
const auto max = std::numeric_limits<T>::max(); const auto max = std::numeric_limits<T>::max();
......
/*=============================================================================
Copyright (c) 2017 Paul Fultz II
half.hpp
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#ifndef MIGRAPH_GUARD_RTGLIB_HALF_HPP
#define MIGRAPH_GUARD_RTGLIB_HALF_HPP
#include <half.hpp>
namespace migraph {
using half = half_float::half;
namespace detail {
template <class T>
struct deduce
{
using type = T;
};
template <>
struct deduce<half_float::detail::expr>
{
using type = half;
};
} // namespace detail
template <class T>
using deduce = typename detail::deduce<T>::type;
} // namespace migraph
#endif
...@@ -20,10 +20,10 @@ struct literal : raw_data<literal> ...@@ -20,10 +20,10 @@ struct literal : raw_data<literal>
{ {
literal() {} literal() {}
template <class T> template <class U, class T = deduce<U>>
literal(T x) : buffer(make_shared_array<char>(sizeof(T))), m_shape(shape::get_type<T>{}) literal(U x) : buffer(make_shared_array<char>(sizeof(T))), m_shape(shape::get_type<T>{})
{ {
static_assert(std::is_trivial<T>{}, "Literals can only be trivial types"); static_assert(std::is_trivially_copyable<T>{}, "Literals can only be trivial types");
*(reinterpret_cast<T*>(buffer.get())) = x; *(reinterpret_cast<T*>(buffer.get())) = x;
} }
...@@ -31,7 +31,7 @@ struct literal : raw_data<literal> ...@@ -31,7 +31,7 @@ struct literal : raw_data<literal>
literal(const shape& s, const std::vector<T>& x) literal(const shape& s, const std::vector<T>& x)
: buffer(make_shared_array<char>(s.bytes())), m_shape(s) : buffer(make_shared_array<char>(s.bytes())), m_shape(s)
{ {
static_assert(std::is_trivial<T>{}, "Literals can only be trivial types"); static_assert(std::is_trivially_copyable<T>{}, "Literals can only be trivial types");
fill(x.begin(), x.end()); fill(x.begin(), x.end());
} }
...@@ -39,7 +39,7 @@ struct literal : raw_data<literal> ...@@ -39,7 +39,7 @@ struct literal : raw_data<literal>
literal(const shape& s, const std::initializer_list<T>& x) literal(const shape& s, const std::initializer_list<T>& x)
: buffer(make_shared_array<char>(s.bytes())), m_shape(s) : buffer(make_shared_array<char>(s.bytes())), m_shape(s)
{ {
static_assert(std::is_trivial<T>{}, "Literals can only be trivial types"); static_assert(std::is_trivially_copyable<T>{}, "Literals can only be trivial types");
fill(x.begin(), x.end()); fill(x.begin(), x.end());
} }
...@@ -101,7 +101,7 @@ literal transform(literal l, F f) ...@@ -101,7 +101,7 @@ literal transform(literal l, F f)
literal result; literal result;
l.visit([&](auto x) { l.visit([&](auto x) {
using type = std::remove_cv_t<typename decltype(x)::value_type>; using type = std::remove_cv_t<typename decltype(x)::value_type>;
std::vector<type> output(x.size(), 0.0); std::vector<type> output(x.size(), type(0));
std::transform(x.begin(), x.end(), output.begin(), f); std::transform(x.begin(), x.end(), output.begin(), f);
result = literal{l.get_shape(), output}; result = literal{l.get_shape(), output};
}); });
...@@ -115,7 +115,7 @@ literal transform(literal l1, literal l2, F f) ...@@ -115,7 +115,7 @@ literal transform(literal l1, literal l2, F f)
literal result; literal result;
visit_all(l1, l2)([&](auto x, auto y) { visit_all(l1, l2)([&](auto x, auto y) {
using type = std::remove_cv_t<typename decltype(x)::value_type>; using type = std::remove_cv_t<typename decltype(x)::value_type>;
std::vector<type> output(x.size(), 0.0); std::vector<type> output(x.size(), type(0));
std::transform(x.begin(), x.end(), y.begin(), output.begin(), f); std::transform(x.begin(), x.end(), y.begin(), output.begin(), f);
result = literal{l1.get_shape(), output}; result = literal{l1.get_shape(), output};
}); });
......
...@@ -256,7 +256,6 @@ struct operation ...@@ -256,7 +256,6 @@ struct operation
shape compute_shape(const std::vector<shape>& input) const override shape compute_shape(const std::vector<shape>& input) const override
{ {
return private_detail_te_value.compute_shape(input); return private_detail_te_value.compute_shape(input);
} }
......
...@@ -306,10 +306,6 @@ struct contiguous ...@@ -306,10 +306,6 @@ struct contiguous
check_shapes{inputs, *this}.has(1); check_shapes{inputs, *this}.has(1);
auto lens = inputs.at(0).lens(); auto lens = inputs.at(0).lens();
auto t = inputs.at(0).type(); auto t = inputs.at(0).type();
if(lens.size() < 2)
{
MIGRAPH_THROW("Number of dimensions should exceed 1");
}
return {t, lens}; return {t, lens};
} }
}; };
...@@ -582,7 +578,7 @@ struct reshape ...@@ -582,7 +578,7 @@ struct reshape
} }
}; };
struct gemm struct dot
{ {
float alpha = 1.0; float alpha = 1.0;
float beta = 0.0; float beta = 0.0;
...@@ -593,7 +589,7 @@ struct gemm ...@@ -593,7 +589,7 @@ struct gemm
return pack(f(self.alpha, "alpha"), f(self.beta, "beta")); return pack(f(self.alpha, "alpha"), f(self.beta, "beta"));
} }
std::string name() const { return "gemm"; } std::string name() const { return "dot"; }
shape compute_shape(std::vector<shape> inputs) const shape compute_shape(std::vector<shape> inputs) const
{ {
check_shapes{inputs, *this}.has(2).same_type(); check_shapes{inputs, *this}.has(2).same_type();
...@@ -766,6 +762,27 @@ struct broadcast ...@@ -766,6 +762,27 @@ struct broadcast
} }
}; };
struct scalar
{
shape scalar_bcast;
std::string name() const { return "scalar"; }
shape compute_shape(std::vector<shape> inputs) const
{
assert(check_shapes{inputs}.has(1).only_dims(1).size() == 1);
auto t = inputs.at(0).type();
auto input = inputs.at(0);
std::vector<std::size_t> strides(scalar_bcast.lens().size(), 0);
return {t, scalar_bcast.lens(), strides};
}
argument compute(context&, shape output_shape, std::vector<argument> args) const
{
return {std::move(output_shape), std::move(args.at(0).data)};
}
};
struct binary struct binary
{ {
shape compute_shape(std::vector<shape> inputs) const shape compute_shape(std::vector<shape> inputs) const
......
...@@ -45,6 +45,12 @@ bool contains(const C& c, const T& x) ...@@ -45,6 +45,12 @@ bool contains(const C& c, const T& x)
return generic_find(c, x) != c.end(); return generic_find(c, x) != c.end();
} }
template <class T>
bool contains(const std::initializer_list<T>& c, const T& x)
{
return generic_find(c, x) != c.end();
}
template <class T, class U> template <class T, class U>
bool contains(const std::initializer_list<T>& c, const U& x) bool contains(const std::initializer_list<T>& c, const U& x)
{ {
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <memory> #include <memory>
#include <migraph/errors.hpp> #include <migraph/errors.hpp>
#include <migraph/half.hpp>
namespace migraph { namespace migraph {
...@@ -19,6 +20,7 @@ struct shape ...@@ -19,6 +20,7 @@ struct shape
// Add new types here // Add new types here
// clang-format off // clang-format off
#define MIGRAPH_SHAPE_VISIT_TYPES(m) \ #define MIGRAPH_SHAPE_VISIT_TYPES(m) \
m(half_type, half) \
m(float_type, float) \ m(float_type, float) \
m(double_type, double) \ m(double_type, double) \
m(uint8_type, uint8_t) \ m(uint8_type, uint8_t) \
...@@ -92,6 +94,8 @@ struct shape ...@@ -92,6 +94,8 @@ struct shape
/// Returns true if the shape is in its standard format. That is, the shape is both packed and /// Returns true if the shape is in its standard format. That is, the shape is both packed and
/// not transposed. /// not transposed.
bool standard() const; bool standard() const;
/// Returns true if all strides are equal to 0 (scalar tensor)
bool scalar() const;
friend bool operator==(const shape& x, const shape& y); friend bool operator==(const shape& x, const shape& y);
friend bool operator!=(const shape& x, const shape& y); friend bool operator!=(const shape& x, const shape& y);
......
/*=============================================================================
Copyright (c) 2017 Paul Fultz II
type_traits.hpp
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#ifndef MIGRAPH_GUARD_RTGLIB_TYPE_TRAITS_HPP
#define MIGRAPH_GUARD_RTGLIB_TYPE_TRAITS_HPP
#include <type_traits>
#include <migraph/half.hpp>
namespace migraph {
#define MIGRAPH_DETAIL_EXTEND_TRAIT_FOR(trait, T) \
template <class X> \
struct trait : std::trait<X> \
{ \
}; \
\
template <> \
struct trait<T> : std::true_type \
{ \
};
MIGRAPH_DETAIL_EXTEND_TRAIT_FOR(is_floating_point, half)
MIGRAPH_DETAIL_EXTEND_TRAIT_FOR(is_signed, half)
MIGRAPH_DETAIL_EXTEND_TRAIT_FOR(is_arithmetic, half)
} // namespace migraph
#endif
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#include <migraph/onnx.hpp> #include <migraph/onnx.hpp>
#include <migraph/cpu/cpu_target.hpp> #include <migraph/cpu/target.hpp>
#include <migraph/gpu/target.hpp> #include <migraph/gpu/target.hpp>
#include <migraph/gpu/hip.hpp> #include <migraph/gpu/hip.hpp>
#include <migraph/generate.hpp> #include <migraph/generate.hpp>
...@@ -86,7 +86,7 @@ int main(int argc, char const* argv[]) ...@@ -86,7 +86,7 @@ int main(int argc, char const* argv[])
else else
{ {
// CPU target // CPU target
prog.compile(migraph::cpu::cpu_target{}); prog.compile(migraph::cpu::target{});
auto s = migraph::shape{migraph::shape::float_type, {1, 3, 32, 32}}; auto s = migraph::shape{migraph::shape::float_type, {1, 3, 32, 32}};
auto labels = imageset.first; auto labels = imageset.first;
auto input = imageset.second; auto input = imageset.second;
......
...@@ -50,17 +50,20 @@ struct onnx_parser ...@@ -50,17 +50,20 @@ struct onnx_parser
{ {
add_generic_op("Add", op::add{}); add_generic_op("Add", op::add{});
add_generic_op("Div", op::div{}); add_generic_op("Div", op::div{});
add_generic_op("MatMul", op::gemm{}); add_generic_op("MatMul", op::dot{});
add_generic_op("Mul", op::mul{}); add_generic_op("Mul", op::mul{});
add_generic_op("Relu", op::activation{"relu"}); add_generic_op("Relu", op::activation{"relu"});
add_generic_op("Sub", op::sub{}); add_generic_op("Sub", op::sub{});
add_generic_op("Sum", op::add{}); add_generic_op("Sum", op::add{});
add_mem_op("ImageScaler", &onnx_parser::parse_imagescaler);
add_mem_op("LeakyRelu", &onnx_parser::parse_leaky_relu); add_mem_op("LeakyRelu", &onnx_parser::parse_leaky_relu);
add_mem_op("Constant", &onnx_parser::parse_constant); add_mem_op("Constant", &onnx_parser::parse_constant);
add_mem_op("Conv", &onnx_parser::parse_conv); add_mem_op("Conv", &onnx_parser::parse_conv);
add_mem_op("MaxPool", &onnx_parser::parse_pooling); add_mem_op("MaxPool", &onnx_parser::parse_pooling);
add_mem_op("AveragePool", &onnx_parser::parse_pooling); add_mem_op("AveragePool", &onnx_parser::parse_pooling);
add_mem_op("GlobalMaxPool", &onnx_parser::parse_pooling);
add_mem_op("GlobalAveragePool", &onnx_parser::parse_pooling);
add_mem_op("Reshape", &onnx_parser::parse_reshape); add_mem_op("Reshape", &onnx_parser::parse_reshape);
add_mem_op("Flatten", &onnx_parser::parse_flatten); add_mem_op("Flatten", &onnx_parser::parse_flatten);
add_mem_op("Gemm", &onnx_parser::parse_gemm); add_mem_op("Gemm", &onnx_parser::parse_gemm);
...@@ -147,7 +150,12 @@ struct onnx_parser ...@@ -147,7 +150,12 @@ struct onnx_parser
attribute_map attributes, attribute_map attributes,
std::vector<instruction_ref> args) std::vector<instruction_ref> args)
{ {
op::pooling op{name == "MaxPool" ? "max" : "average"}; op::pooling op{ends_with(name, "MaxPool") ? "max" : "average"};
if(starts_with(name, "Global"))
{
auto lens = args.front()->get_shape().lens();
op.lengths = {lens[2], lens[3]};
}
if(contains(attributes, "pads")) if(contains(attributes, "pads"))
{ {
copy(attributes["pads"].ints(), op.padding.begin()); copy(attributes["pads"].ints(), op.padding.begin());
...@@ -274,11 +282,11 @@ struct onnx_parser ...@@ -274,11 +282,11 @@ struct onnx_parser
if(args.size() == 3) if(args.size() == 3)
{ {
uint64_t axis = 1; uint64_t axis = 1;
auto l3 = prog.add_instruction(op::gemm{alpha, beta}, l1, l2); auto l3 = prog.add_instruction(op::dot{alpha, beta}, l1, l2);
auto l4 = prog.add_instruction(op::broadcast{axis, l3->get_shape()}, args[2]); auto l4 = prog.add_instruction(op::broadcast{axis, l3->get_shape()}, args[2]);
return prog.add_instruction(op::add{}, l3, l4); return prog.add_instruction(op::add{}, l3, l4);
} }
return prog.add_instruction(op::gemm{alpha, beta}, l1, l2); return prog.add_instruction(op::dot{alpha, beta}, l1, l2);
} }
instruction_ref instruction_ref
...@@ -315,7 +323,7 @@ struct onnx_parser ...@@ -315,7 +323,7 @@ struct onnx_parser
attribute_map attributes, attribute_map attributes,
std::vector<instruction_ref> args) std::vector<instruction_ref> args)
{ {
float alpha = 0.01; float alpha = 0.01; // default alpha val for leaky relu
if(contains(attributes, "alpha")) if(contains(attributes, "alpha"))
{ {
alpha = parse_value(attributes.at("alpha")).at<float>(); alpha = parse_value(attributes.at("alpha")).at<float>();
...@@ -324,6 +332,34 @@ struct onnx_parser ...@@ -324,6 +332,34 @@ struct onnx_parser
return prog.add_instruction(op, args.front()); return prog.add_instruction(op, args.front());
} }
instruction_ref parse_imagescaler(const std::string&,
attribute_map attributes,
std::vector<instruction_ref> args)
{
float scale = 1.0;
std::vector<float> bias{};
if(contains(attributes, "scale"))
{
scale = parse_value(attributes.at("scale")).at<float>();
}
if(contains(attributes, "bias"))
{
auto&& bias_floats = attributes["bias"].floats();
bias = std::vector<float>(bias_floats.begin(), bias_floats.end());
}
auto input_shape = args.front()->get_shape();
auto scale_val = prog.add_literal(scale);
auto bias_vals = prog.add_literal(
migraph::literal{migraph::shape{migraph::shape::float_type, {bias.size()}}, bias});
auto scale_tensor = prog.add_instruction(migraph::op::scalar{input_shape}, scale_val);
auto img_scaled = prog.add_instruction(migraph::op::mul{}, args.front(), scale_tensor);
auto bias_bcast = prog.add_instruction(migraph::op::broadcast{1, input_shape}, bias_vals);
return prog.add_instruction(migraph::op::add{}, img_scaled, bias_bcast);
}
void parse_from(std::istream& is) void parse_from(std::istream& is)
{ {
onnx::ModelProto model; onnx::ModelProto model;
...@@ -555,10 +591,15 @@ struct onnx_parser ...@@ -555,10 +591,15 @@ struct onnx_parser
} }
std::vector<std::size_t> dims; std::vector<std::size_t> dims;
auto&& tensor_dims = t.tensor_type().shape().dim(); auto&& tensor_dims = t.tensor_type().shape().dim();
std::transform(tensor_dims.begin(), std::transform(
tensor_dims.end(), tensor_dims.begin(), tensor_dims.end(), std::back_inserter(dims), [](auto&& d) {
std::back_inserter(dims), if(not d.has_dim_value())
[](auto&& d) { return d.dim_value(); }); {
long default_batch_size = 1; // FIXME
return default_batch_size;
}
return d.dim_value();
});
return {shape_type, dims}; return {shape_type, dims};
} }
}; };
......
#include <migraph/onnx.hpp> #include <migraph/onnx.hpp>
#include <migraph/cpu/cpu_target.hpp> #include <migraph/cpu/target.hpp>
#include <migraph/gpu/target.hpp> #include <migraph/gpu/target.hpp>
#include <migraph/gpu/hip.hpp> #include <migraph/gpu/hip.hpp>
#include <migraph/generate.hpp> #include <migraph/generate.hpp>
...@@ -18,7 +18,7 @@ template <class F> ...@@ -18,7 +18,7 @@ template <class F>
migraph::argument run_cpu(F f) migraph::argument run_cpu(F f)
{ {
auto p = f(); auto p = f();
p.compile(migraph::cpu::cpu_target{}); p.compile(migraph::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())
{ {
......
...@@ -196,6 +196,7 @@ void memory_coloring_impl::register_operand_alias() ...@@ -196,6 +196,7 @@ void memory_coloring_impl::register_operand_alias()
operand_alias["identity"] = 0; operand_alias["identity"] = 0;
operand_alias["reshape"] = 0; operand_alias["reshape"] = 0;
operand_alias["pass"] = 0; operand_alias["pass"] = 0;
operand_alias["scalar"] = 0;
} }
void memory_coloring_impl::rewrite() void memory_coloring_impl::rewrite()
......
...@@ -427,7 +427,7 @@ void program::perf_report(std::ostream& os, std::size_t n, parameter_map params) ...@@ -427,7 +427,7 @@ void program::perf_report(std::ostream& os, std::size_t n, parameter_map params)
} }
double total_time = common_average(total_vec); double total_time = common_average(total_vec);
double rate = std::ceil(1000.0 / total_time); double rate = 1000.0 / total_time;
double overhead_time = common_average(overhead_vec); double overhead_time = common_average(overhead_vec);
double overhead_percent = overhead_time * 100.0 / total_time; double overhead_percent = overhead_time * 100.0 / total_time;
double total_instruction_time = 0.0; double total_instruction_time = 0.0;
......
...@@ -29,8 +29,8 @@ struct shape_impl ...@@ -29,8 +29,8 @@ struct shape_impl
: m_type(t), m_lens(std::move(l)), m_strides(std::move(s)) : m_type(t), m_lens(std::move(l)), m_strides(std::move(s))
{ {
assert(m_lens.size() == m_strides.size()); assert(m_lens.size() == m_strides.size());
assert(std::any_of(m_strides.begin(), m_strides.end(), [](auto x) { return x > 0; }) and // assert(std::any_of(m_strides.begin(), m_strides.end(), [](auto x) { return x > 0; }) and
"At least one stride must be non-zero"); // "At least one stride must be non-zero");
m_standard = this->elements() == this->element_space() and m_standard = this->elements() == this->element_space() and
std::is_sorted(m_strides.rbegin(), m_strides.rend()); std::is_sorted(m_strides.rbegin(), m_strides.rend());
} }
...@@ -153,6 +153,13 @@ bool shape::broadcasted() const ...@@ -153,6 +153,13 @@ bool shape::broadcasted() const
std::multiplies<std::size_t>()) == 0; std::multiplies<std::size_t>()) == 0;
} }
bool shape::scalar() const
{
assert(this->lens().size() == this->strides().size());
// if any stride > 0, then accumulate will return false
return std::accumulate(this->strides().begin(), this->strides().end(), std::size_t(0)) == 0;
}
bool shape::standard() const { return impl->m_standard; } bool shape::standard() const { return impl->m_standard; }
std::size_t shape::element_space() const { return impl->element_space(); } std::size_t shape::element_space() const { return impl->element_space(); }
......
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