Commit 8d32c6b8 authored by Paul's avatar Paul
Browse files

Merge branch 'develop' into blas_tuning

parents 23cb7917 f25606f9
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#define MIGRAPHX_GUARD_CONFIG_HPP #define MIGRAPHX_GUARD_CONFIG_HPP
#include <migraphx/export.h> #include <migraphx/export.h>
#include <ciso646>
#if !defined(MIGRAPHX_USE_CLANG_TIDY) && !defined(DOXYGEN) #if !defined(MIGRAPHX_USE_CLANG_TIDY) && !defined(DOXYGEN)
......
/* /*
* The MIT License (MIT) * The MIT License (MIT)
* *
* Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
...@@ -62,7 +62,7 @@ void convolution(Output output, T input, T weights, Padding padding, Stride stri ...@@ -62,7 +62,7 @@ void convolution(Output output, T input, T weights, Padding padding, Stride stri
shape win_shape{output_shape.type(), win_size}; shape win_shape{output_shape.type(), win_size};
double acc = 0.0; double acc = 0.0;
shape_for_each(win_shape, [&](auto idx_win) { shape_for_each(win_shape, [&](const auto& idx_win) {
auto k = idx_win[0]; auto k = idx_win[0];
const auto in_ch = group_id * wei_c + k; const auto in_ch = group_id * wei_c + k;
std::vector<std::ptrdiff_t> idx(idx_o.begin(), idx_o.end()); std::vector<std::ptrdiff_t> idx(idx_o.begin(), idx_o.end());
......
...@@ -38,12 +38,14 @@ struct dynamic_loader_impl; ...@@ -38,12 +38,14 @@ struct dynamic_loader_impl;
struct MIGRAPHX_EXPORT dynamic_loader struct MIGRAPHX_EXPORT dynamic_loader
{ {
#ifndef _WIN32
template <class T> template <class T>
static fs::path path(T* address) static fs::path path(T* address)
{ {
return path(reinterpret_cast<void*>(address)); return path(reinterpret_cast<void*>(address));
} }
static fs::path path(void* address); static fs::path path(void* address);
#endif
static optional<dynamic_loader> try_load(const fs::path& p); static optional<dynamic_loader> try_load(const fs::path& p);
......
...@@ -29,6 +29,17 @@ ...@@ -29,6 +29,17 @@
#if defined(CPPCHECK) #if defined(CPPCHECK)
#define MIGRAPHX_HAS_FILESYSTEM 1 #define MIGRAPHX_HAS_FILESYSTEM 1
#define MIGRAPHX_HAS_FILESYSTEM_TS 1 #define MIGRAPHX_HAS_FILESYSTEM_TS 1
#elif defined(_WIN32)
#if _MSC_VER >= 1920
#define MIGRAPHX_HAS_FILESYSTEM 1
#define MIGRAPHX_HAS_FILESYSTEM_TS 0
#elif _MSC_VER >= 1900
#define MIGRAPHX_HAS_FILESYSTEM 0
#define MIGRAPHX_HAS_FILESYSTEM_TS 1
#else
#define MIGRAPHX_HAS_FILESYSTEM 0
#define MIGRAPHX_HAS_FILESYSTEM_TS 0
#endif
#elif defined(__has_include) #elif defined(__has_include)
#if __has_include(<filesystem>) && __cplusplus >= 201703L #if __has_include(<filesystem>) && __cplusplus >= 201703L
#define MIGRAPHX_HAS_FILESYSTEM 1 #define MIGRAPHX_HAS_FILESYSTEM 1
......
...@@ -27,9 +27,6 @@ ...@@ -27,9 +27,6 @@
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
#include <numeric> #include <numeric>
#ifdef _MSC_VER
#include <iso646.h>
#endif
#include <migraphx/requires.hpp> #include <migraphx/requires.hpp>
#include <migraphx/config.hpp> #include <migraphx/config.hpp>
......
...@@ -48,7 +48,7 @@ constexpr T normalize(unsigned long z) ...@@ -48,7 +48,7 @@ constexpr T normalize(unsigned long z)
template <class T, MIGRAPHX_REQUIRES(is_signed<T>{} and not is_floating_point<T>{})> template <class T, MIGRAPHX_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 = 1UL << (sizeof(T) * 5); const auto max = 1ULL << (sizeof(T) * 5);
const auto half_max = max / 2; const auto half_max = max / 2;
return half_max - (z % max); return half_max - (z % max);
} }
...@@ -58,7 +58,7 @@ template <class T, ...@@ -58,7 +58,7 @@ template <class T,
not std::is_same<T, bool>{})> not std::is_same<T, bool>{})>
constexpr T normalize(unsigned long z) constexpr T normalize(unsigned long z)
{ {
const auto max = 1UL << (sizeof(T) * 5); const auto max = 1ULL << (sizeof(T) * 5);
return z % max; return z % max;
} }
......
...@@ -81,6 +81,7 @@ struct MIGRAPHX_EXPORT instruction ...@@ -81,6 +81,7 @@ struct MIGRAPHX_EXPORT instruction
const std::vector<module_ref>& module_inputs() const; const std::vector<module_ref>& module_inputs() const;
/// Where this instruction is used as an input to another instruction
const std::vector<instruction_ref>& outputs() const; const std::vector<instruction_ref>& outputs() const;
friend bool operator==(const instruction& x, const instruction& y); friend bool operator==(const instruction& x, const instruction& y);
......
/* /*
* The MIT License (MIT) * The MIT License (MIT)
* *
* Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
...@@ -27,12 +27,42 @@ ...@@ -27,12 +27,42 @@
#include <list> #include <list>
#include <functional> #include <functional>
#include <migraphx/config.hpp> #include <migraphx/config.hpp>
#include <migraphx/requires.hpp>
namespace migraphx { namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS { inline namespace MIGRAPHX_INLINE_NS {
struct instruction; struct instruction;
#if defined(_WIN32) && !defined(NDEBUG)
struct instruction_ref : std::list<instruction>::iterator
{
using instruction_iter = std::list<instruction>::iterator;
using instruction_const_iter = std::list<instruction>::const_iterator;
instruction_ref() = default;
instruction_ref(const instruction_iter& other) : instruction_iter(other) {}
template <class T,
class U,
MIGRAPHX_REQUIRES(std::is_same<T, instruction_ref>{} or
std::is_same<U, instruction_ref>{})>
friend bool operator==(const T& x, const U& y)
{
return x._Unwrapped()._Ptr == y._Unwrapped()._Ptr;
}
template <class T,
class U,
MIGRAPHX_REQUIRES(std::is_same<T, instruction_ref>{} or
std::is_same<U, instruction_ref>{})>
friend bool operator!=(const T& x, const U& y)
{
return not(x == y);
}
};
#else
using instruction_ref = std::list<instruction>::iterator; using instruction_ref = std::list<instruction>::iterator;
#endif
MIGRAPHX_EXPORT migraphx::instruction* as_address(const instruction_ref& ins) noexcept; MIGRAPHX_EXPORT migraphx::instruction* as_address(const instruction_ref& ins) noexcept;
...@@ -65,4 +95,8 @@ struct equal_to<migraphx::instruction_ref> // NOLINT ...@@ -65,4 +95,8 @@ struct equal_to<migraphx::instruction_ref> // NOLINT
} // namespace std } // namespace std
#ifdef _MSC_VER
#include <migraphx/instruction.hpp>
#endif
#endif #endif
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <migraphx/type_name.hpp> #include <migraphx/type_name.hpp>
#include <migraphx/source_location.hpp> #include <migraphx/source_location.hpp>
#include <migraphx/config.hpp> #include <migraphx/config.hpp>
#include <array>
#include <unordered_map> #include <unordered_map>
#include <unordered_set> #include <unordered_set>
...@@ -381,22 +382,24 @@ void find_matches_for(source_location location, Mod& mod, instruction_ref ins, M ...@@ -381,22 +382,24 @@ void find_matches_for(source_location location, Mod& mod, instruction_ref ins, M
const int trace = value_of(MIGRAPHX_TRACE_MATCHES{}); const int trace = value_of(MIGRAPHX_TRACE_MATCHES{});
const bool validate = enabled(MIGRAPHX_VALIDATE_MATCHES{}); const bool validate = enabled(MIGRAPHX_VALIDATE_MATCHES{});
const auto trace_filter = string_value_of(MIGRAPHX_TRACE_MATCHES_FOR{}); const auto trace_filter = string_value_of(MIGRAPHX_TRACE_MATCHES_FOR{});
const bool trace_for = not trace_filter.empty() and bool match = false;
(contains(std::string{location.file_name()}, trace_filter) or
contains(std::string{location.function_name()}, trace_filter));
bool match = false;
each_args( each_args(
[&](auto&& m) { [&](auto&& m) {
const auto& matcher_name = get_type_name(m);
const bool trace_for = not trace_filter.empty() and
(contains(std::string{location.file_name()}, trace_filter) or
contains(std::string{location.function_name()}, trace_filter) or
contains(matcher_name, trace_filter));
if(match) if(match)
return; return;
if(trace > 1 or trace_for) if(trace > 1 and trace_for)
std::cout << "Match: " << get_type_name(m) << std::endl; std::cout << "Match: " << matcher_name << std::endl;
auto r = match_instruction(get_module(mod), ins, m.matcher()); auto r = match_instruction(get_module(mod), ins, m.matcher());
if(r.result == get_module(mod).end()) if(r.result == get_module(mod).end())
return; return;
if(trace > 0 or trace_for) if(trace > 0 or trace_for)
{ {
std::cout << "Matched by " << get_type_name(m) << std::endl; std::cout << "Matched by " << matcher_name << std::endl;
get_module(mod).debug_print(ins); get_module(mod).debug_print(ins);
} }
// If its already invalid dont validate it again // If its already invalid dont validate it again
...@@ -407,7 +410,7 @@ void find_matches_for(source_location location, Mod& mod, instruction_ref ins, M ...@@ -407,7 +410,7 @@ void find_matches_for(source_location location, Mod& mod, instruction_ref ins, M
auto invalid = get_module(mod).validate(); auto invalid = get_module(mod).validate();
if(invalid != get_module(mod).end()) if(invalid != get_module(mod).end())
{ {
std::cout << "Invalid program from match: " << get_type_name(m) << std::endl; std::cout << "Invalid program from match: " << matcher_name << std::endl;
std::cout << "Invalid instructions: " << std::endl; std::cout << "Invalid instructions: " << std::endl;
get_module(mod).debug_print(invalid->inputs()); get_module(mod).debug_print(invalid->inputs());
get_module(mod).debug_print(invalid); get_module(mod).debug_print(invalid);
...@@ -621,6 +624,8 @@ MIGRAPHX_PRED_MATCHER(broadcast, instruction_ref ins) ...@@ -621,6 +624,8 @@ MIGRAPHX_PRED_MATCHER(broadcast, instruction_ref ins)
template <class... Ms> template <class... Ms>
auto skip(Ms... ms) auto skip(Ms... ms)
{ {
static_assert(((not std::is_convertible<Ms, std::string>{}) and ...),
"Use a matcher not a string for skip.");
auto m = any_of(ms...); auto m = any_of(ms...);
return make_basic_fun_matcher([=](matcher_context& ctx, instruction_ref start) { return make_basic_fun_matcher([=](matcher_context& ctx, instruction_ref start) {
return fix<optional<instruction_ref>>( return fix<optional<instruction_ref>>(
......
/* /*
* The MIT License (MIT) * The MIT License (MIT)
* *
* Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <migraphx/shape.hpp> #include <migraphx/shape.hpp>
#include <cstring> #include <cstring>
#include <vector> #include <vector>
#include <migraphx/op/normalize_attribute.hpp>
namespace migraphx { namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS { inline namespace MIGRAPHX_INLINE_NS {
...@@ -42,6 +43,38 @@ struct select_dependent_type ...@@ -42,6 +43,38 @@ struct select_dependent_type
template <class T, class... Ts> template <class T, class... Ts>
using dependent_type = typename select_dependent_type<T, Ts...>::type; using dependent_type = typename select_dependent_type<T, Ts...>::type;
/**
* Used to normalize variable input axes at model runtime.
* Example: the axes inputs of the slice operator.
*
* \param axes the axes to normalize
* \param input_shape shape of the input tensor
* \param attr_val the normalize_axes attributes from the operator
* \param prefix error message prefix
*/
MIGRAPHX_EXPORT
std::vector<int64_t> normalize_axes(const std::vector<int64_t>& axes,
const shape& input_shape,
const value& attr_val,
const std::string& prefix = "");
/**
* Used to normalize variable input axes at model runtime.
* Example: the starts and ends inputs of the slice operator.
*
* \param indices the indices to normalize
* \param axes which axes the indices apply over
* \param input_shape shape of the input tensor
* \param attr_val the normalize_axes attributes from the operator
* \param prefix error message prefix
*/
MIGRAPHX_EXPORT
std::vector<int64_t> normalize_indices(const std::vector<int64_t>& indices,
const std::vector<int64_t>& axes,
const shape& input_shape,
const value& attr_val,
const std::string& prefix = "");
MIGRAPHX_EXPORT MIGRAPHX_EXPORT
bool normalize_attributes(operation& op, const shape& input_shape); bool normalize_attributes(operation& op, const shape& input_shape);
......
...@@ -33,23 +33,69 @@ namespace migraphx { ...@@ -33,23 +33,69 @@ namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS { inline namespace MIGRAPHX_INLINE_NS {
namespace op { namespace op {
/**
* Static allocate:
* No inputs: `allocate()`
* `this.s` attribute set to the static output shape of the buffer.
*
* Dynamic allocate:
* One input: `allocate(output_dims)`
* `output_dims` are the output buffer dimensions and has a static shape.
* Either `this.s` or `this.buf_type` must be set to calculate the dynamic output shape at compute
* time. If `this.buf_type` is set, the compute_shape() of allocate at compile time will have
* dynamic_dimensions from {0, max_int} with rank = output_dims.ndim(). If `this.s` is set then the
* compute_shape() will output `this.s`; `this.s` should be a dynamic shape.
*/
struct allocate struct allocate
{ {
shape s{}; shape s{};
// for dynamic allocate to set the buffer type
shape::type_t buf_type = shape::half_type;
template <class Self, class F> template <class Self, class F>
static auto reflect(Self& self, F f) static auto reflect(Self& self, F f)
{ {
return pack(f(self.s, "shape")); return pack(f(self.s, "shape"), f(self.buf_type, "buf_type"));
} }
std::string name() const { return "allocate"; } std::string name() const { return "allocate"; }
shape compute_shape(const std::vector<shape>& inputs) const shape compute_shape(const std::vector<shape>& inputs) const
{ {
migraphx::check_shapes{inputs, *this, true}.has(0); if(s != shape())
return s; {
if(inputs.size() == 1)
{
migraphx::check_shapes{inputs, *this, false}.only_dims(1);
}
else
{
migraphx::check_shapes{inputs, *this, false}.has(0);
}
return s;
}
else
{
migraphx::check_shapes{inputs, *this, false}.has(1).only_dims(1);
const auto& out_dims = inputs.at(0);
std::size_t max_val = std::numeric_limits<std::size_t>::max();
std::vector<shape::dynamic_dimension> dyn_dims(out_dims.lens().at(0),
shape::dynamic_dimension{0, max_val});
return {buf_type, dyn_dims};
}
} }
argument compute(const shape& output_shape, const std::vector<argument>&) const argument compute(const shape& output_shape, const std::vector<argument>& args) const
{ {
return {output_shape}; if(args.empty())
{
return {output_shape};
}
else
{
std::vector<std::size_t> output_dims(output_shape.ndim());
args.at(0).visit([&](auto a) { output_dims.assign(a.begin(), a.end()); });
return {shape{buf_type, output_dims}};
}
} }
}; };
......
/* /*
* The MIT License (MIT) * The MIT License (MIT)
* *
* Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
...@@ -33,8 +33,12 @@ namespace migraphx { ...@@ -33,8 +33,12 @@ namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS { inline namespace MIGRAPHX_INLINE_NS {
namespace op { namespace op {
// Specifies where to add the "extra" cell of padding if the
// calculated padding is an odd number.
// Padding mode is default_ for fixed shape padding. // Padding mode is default_ for fixed shape padding.
// same_lower and same_upper used for dynamic padding. // same_lower and same_upper specify dynamic padding.
// The odd cell goes at the beginning of the dimension
// (same_lower) or end (same_upper).
enum padding_mode_t enum padding_mode_t
{ {
default_, // NOLINT default_, // NOLINT
......
/* /*
* The MIT License (MIT) * The MIT License (MIT)
* *
* Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
......
...@@ -68,7 +68,7 @@ struct convert : unary<convert> ...@@ -68,7 +68,7 @@ struct convert : unary<convert>
auto y = x; auto y = x;
shape::visit(type, [&](auto as) { shape::visit(type, [&](auto as) {
// clamping value between target_type's max and min doesn't work for NaNs, // clamping value between target_type's max and min doesn't work for NaNs,
if(std::isnan(x)) if(std::isnan(static_cast<double>(x)))
{ {
y = as.nan(); y = as.nan();
} }
......
/* /*
* The MIT License (MIT) * The MIT License (MIT)
* *
* Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
...@@ -206,6 +206,7 @@ struct convolution ...@@ -206,6 +206,7 @@ struct convolution
std::vector<std::size_t> new_padding; std::vector<std::size_t> new_padding;
if(padding_mode != op::padding_mode_t::default_) if(padding_mode != op::padding_mode_t::default_)
{ {
// auto-Calculate the padding sizes with calc_dyn_auto_pad
auto input_lens = args[0].get_shape().lens(); auto input_lens = args[0].get_shape().lens();
auto weights_lens = args[1].get_shape().lens(); auto weights_lens = args[1].get_shape().lens();
new_padding = new_padding =
...@@ -217,6 +218,7 @@ struct convolution ...@@ -217,6 +218,7 @@ struct convolution
} }
else else
{ {
// Use the padding that was given
new_padding = padding; new_padding = padding;
if(output_shape.dynamic()) if(output_shape.dynamic())
{ {
......
/* /*
* The MIT License (MIT) * The MIT License (MIT)
* *
* Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
...@@ -164,7 +164,7 @@ struct convolution_backwards ...@@ -164,7 +164,7 @@ struct convolution_backwards
shape win_shape{dyn_out.computed_shape.type(), win_size}; shape win_shape{dyn_out.computed_shape.type(), win_size};
par_dfor(in_n, wei_c)([&](int o, int k) { par_dfor(in_n, wei_c)([&](int o, int k) {
shape_for_each(win_shape, [&](auto idx_win) { shape_for_each(win_shape, [&](const auto& idx_win) {
const int w = idx_win[0]; const int w = idx_win[0];
auto input_dims_start = idx_win.begin() + 1; auto input_dims_start = idx_win.begin() + 1;
......
/*
* The MIT License (MIT)
*
* Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MIGRAPHX_GUARD_OPERATORS_FILL_HPP
#define MIGRAPHX_GUARD_OPERATORS_FILL_HPP
#include <migraphx/check_shapes.hpp>
#include <migraphx/dyn_output.hpp>
#include <migraphx/par_for.hpp>
namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS {
namespace op {
/**
* fill(default_value, output_buffer)
* Fill an output buffer with the given default_value.
* Note that if the default_value is a literal and the output_buffer
* has a static shape this operator can be replaced with a literal.
*/
struct fill
{
std::string name() const { return "fill"; }
shape compute_shape(std::vector<shape> inputs) const
{
check_shapes{inputs, *this, true}.has(2).same_type();
if(inputs.at(0).dynamic() or inputs.at(0).elements() != 1)
{
MIGRAPHX_THROW("FILL: default_value is dynamic or more than one element");
}
return inputs.back();
}
argument compute(const dyn_output& dyn_out, std::vector<argument> args) const
{
visit_all(args[0], args[1])([&](auto value, auto output) {
par_for(dyn_out.computed_shape.elements(), [&](auto i) { output[i] = value.front(); });
});
return args[1];
}
std::ptrdiff_t output_alias(const std::vector<shape>&) const { return 1; }
};
} // namespace op
} // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx
#endif
/* /*
* The MIT License (MIT) * The MIT License (MIT)
* *
* Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
...@@ -125,13 +125,12 @@ struct gather ...@@ -125,13 +125,12 @@ struct gather
auto out_lens = data.get_shape().lens(); auto out_lens = data.get_shape().lens();
out_lens[axis] = indices.get_shape().elements(); out_lens[axis] = indices.get_shape().elements();
migraphx::shape out_comp_shape{data.get_shape().type(), out_lens}; migraphx::shape out_comp_shape{data.get_shape().type(), out_lens};
shape_for_each(out_comp_shape, [&](const auto& out_idx) { shape_for_each(out_comp_shape, [&](const auto& out_idx_v, size_t out_idx) {
auto data_idx = out_idx; auto data_idx = out_idx_v;
auto in_index = indices[data_idx[axis]]; auto in_index = indices[data_idx[axis]];
in_index = (in_index < 0) ? in_index + axis_dim_size : in_index; in_index = (in_index < 0) ? in_index + axis_dim_size : in_index;
data_idx[axis] = in_index; data_idx[axis] = in_index;
output[out_comp_shape.index(out_idx.begin(), out_idx.end())] = output[out_idx] = data(data_idx.begin(), data_idx.end());
data(data_idx.begin(), data_idx.end());
}); });
} }
}); });
......
...@@ -35,7 +35,7 @@ struct isnan : unary<isnan> ...@@ -35,7 +35,7 @@ struct isnan : unary<isnan>
{ {
auto apply() const auto apply() const
{ {
return [](auto x) { return std::isnan(x); }; return [](auto x) { return std::isnan(static_cast<double>(x)); };
} }
std::string name() const { return "isnan"; } std::string name() const { return "isnan"; }
......
/* /*
* The MIT License (MIT) * The MIT License (MIT)
* *
* Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#ifndef MIGRAPHX_GUARD_OPERATORS_NONMAXSUPPRESSION_HPP #ifndef MIGRAPHX_GUARD_OPERATORS_NONMAXSUPPRESSION_HPP
#define MIGRAPHX_GUARD_OPERATORS_NONMAXSUPPRESSION_HPP #define MIGRAPHX_GUARD_OPERATORS_NONMAXSUPPRESSION_HPP
#include <array>
#include <cmath> #include <cmath>
#include <queue> #include <queue>
#include <cstdint> #include <cstdint>
...@@ -258,7 +259,7 @@ struct nonmaxsuppression ...@@ -258,7 +259,7 @@ struct nonmaxsuppression
selected_boxes_inside_class.reserve(max_output_shape.elements()); selected_boxes_inside_class.reserve(max_output_shape.elements());
// iterate over batches and classes // iterate over batches and classes
shape comp_s{shape::double_type, {num_batches, num_classes}}; shape comp_s{shape::double_type, {num_batches, num_classes}};
shape_for_each(comp_s, [&](auto idx) { shape_for_each(comp_s, [&](const auto& idx) {
auto batch_idx = idx[0]; auto batch_idx = idx[0];
auto class_idx = idx[1]; auto class_idx = idx[1];
// index offset for this class // index offset for this class
......
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