Unverified Commit 23cb7917 authored by Brian Pickrell's avatar Brian Pickrell Committed by GitHub
Browse files

Merge branch 'develop' into blas_tuning

parents b5fcc0bc ea32ca70
......@@ -33,6 +33,7 @@
namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS {
MIGRAPHX_EXPORT
instruction_ref insert_apply_alpha_beta(module& m,
instruction_ref pos,
const std::vector<instruction_ref>& args,
......
......@@ -42,7 +42,7 @@ inline namespace MIGRAPHX_INLINE_NS {
* or it can be owned by the argument.
*
*/
struct argument : raw_data<argument>
struct MIGRAPHX_EXPORT argument : raw_data<argument>
{
argument() = default;
......@@ -93,6 +93,16 @@ struct argument : raw_data<argument>
/// Return the ith element
argument element(std::size_t i) const;
// Keeps the same data ordering as the given container
template <class Iterator>
void fill(Iterator start, Iterator end)
{
assert(std::distance(start, end) <= m_shape.elements());
this->visit([&](auto output) {
std::copy(start, end, output.begin());
});
}
private:
void assign_buffer(std::function<char*()> d);
struct data_t
......@@ -107,9 +117,9 @@ struct argument : raw_data<argument>
data_t m_data{};
};
std::vector<shape> to_shapes(const std::vector<argument>& args);
void migraphx_to_value(value& v, const argument& a);
void migraphx_from_value(const value& v, argument& a);
MIGRAPHX_EXPORT std::vector<shape> to_shapes(const std::vector<argument>& args);
MIGRAPHX_EXPORT void migraphx_to_value(value& v, const argument& a);
MIGRAPHX_EXPORT void migraphx_from_value(const value& v, argument& a);
} // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx
......
......@@ -42,7 +42,7 @@ void any_cast()
template <class T>
struct auto_any_caster
{
T& x;
T& x; // NOLINT
template <class U>
operator U&()
......
......@@ -33,7 +33,7 @@ inline namespace MIGRAPHX_INLINE_NS {
struct module;
struct auto_contiguous
struct MIGRAPHX_EXPORT auto_contiguous
{
std::string name() const { return "auto_contiguous"; }
void apply(module& m) const;
......
......@@ -90,7 +90,17 @@ struct param
struct returns
{
std::string name() const { return "@return"; }
shape compute_shape(const std::vector<shape>&) const { return {}; }
shape compute_shape(const std::vector<shape>& arg) const
{
if(arg.empty())
return {};
else if(arg.size() == 1)
return arg[0];
else
return arg;
}
argument compute(context&, const shape&, const std::vector<argument>&) const
{
MIGRAPHX_THROW("builtin");
......
......@@ -34,21 +34,37 @@
namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS {
// Check that deduced type is incrementable, dereferencable, and comparable
template <class, class = void>
struct is_iterator
{
};
template <class T>
struct is_iterator<T,
std::void_t<decltype(++std::declval<T&>()),
decltype(*std::declval<T&>()),
decltype(std::declval<T&>() == std::declval<T&>())>> : std::true_type
{
};
template <class Iterator>
struct check_shapes
{
const shape* begin;
const shape* end;
const std::string name;
const bool dynamic_allowed;
static_assert(is_iterator<Iterator>{}, "CHECK_SHAPES: Deduced type must be an iterator");
Iterator begin;
Iterator end;
std::string name;
bool dynamic_allowed;
check_shapes(const shape* b, const shape* e, const std::string& n, const bool d = false)
check_shapes(Iterator b, Iterator e, const std::string& n, const bool d = false)
: begin(b), end(e), name(n), dynamic_allowed(d)
{
check_dynamic();
}
template <class Op>
check_shapes(const shape* b, const shape* e, const Op& op, const bool d = false)
check_shapes(Iterator b, Iterator e, const Op& op, const bool d = false)
: begin(b), end(e), name(op.name()), dynamic_allowed(d)
{
check_dynamic();
......@@ -56,7 +72,7 @@ struct check_shapes
template <class Op>
check_shapes(const std::vector<shape>& s, const Op& op, const bool d = false)
: begin(s.data()), end(s.data() + s.size()), name(op.name()), dynamic_allowed(d)
: begin(s.begin()), end(s.end()), name(op.name()), dynamic_allowed(d)
{
check_dynamic();
}
......@@ -81,8 +97,6 @@ struct check_shapes
{
if(begin == end)
return 0;
assert(begin != nullptr);
assert(end != nullptr);
return end - begin;
}
......@@ -131,8 +145,6 @@ struct check_shapes
*/
const check_shapes& only_dims(std::size_t n) const
{
assert(begin != nullptr);
assert(end != nullptr);
if(begin != end)
{
if(begin->max_lens().size() != n)
......@@ -148,8 +160,6 @@ struct check_shapes
*/
const check_shapes& max_ndims(std::size_t n) const
{
assert(begin != nullptr);
assert(end != nullptr);
if(begin != end)
{
if(begin->max_lens().size() > n)
......@@ -166,8 +176,6 @@ struct check_shapes
*/
const check_shapes& min_ndims(std::size_t n) const
{
assert(begin != nullptr);
assert(end != nullptr);
if(begin != end)
{
if(begin->max_lens().size() < n)
......@@ -330,8 +338,6 @@ struct check_shapes
{
if(begin == end)
return true;
assert(begin != nullptr);
assert(end != nullptr);
auto&& key = f(*begin);
return this->all_of([&](const shape& s) { return f(s) == key; });
}
......@@ -341,8 +347,6 @@ struct check_shapes
{
if(begin == end)
return true;
assert(begin != nullptr);
assert(end != nullptr);
return std::all_of(begin, end, p);
}
......@@ -351,17 +355,13 @@ struct check_shapes
{
if(begin == end)
return false;
assert(begin != nullptr);
assert(end != nullptr);
return std::any_of(begin, end, p);
}
const shape* get(long i) const
Iterator get(long i) const
{
if(i >= size())
MIGRAPHX_THROW(prefix() + "Accessing shape out of bounds");
assert(begin != nullptr);
assert(end != nullptr);
if(i < 0)
return end - i;
return begin + i;
......@@ -394,6 +394,11 @@ struct check_shapes
}
};
// Deduction guide for std::vector constructor
template <class Op>
check_shapes(const std::vector<shape>&, const Op&, bool d = false)
-> check_shapes<std::vector<shape>::const_iterator>;
} // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx
......
......@@ -34,22 +34,76 @@ inline namespace MIGRAPHX_INLINE_NS {
struct module;
struct operation;
/**
* Broadcasting works by comparing the shapes element-wise starting with
* the trailing (right-most) dimensions and working leftwards. This is equivalent
* to what is done in NumPy.
* example 1:
* s0 = (3,2,4,5) and s1 = (2,1,1)
* In this case we need to broadcast (:,1,1) portion of
* s1 plus broadcast the 1st dimension of s0
* giving output_lens = (3,2,4,5)
*
* example 2:
* s0 = (3,2,1,5) and s1 = (2,7,5)
* In this case we need to broadcast the (:,:,1:,:) axis
* of s0 plus the 1st dimension of s1 giving
* output_lens = (3,2,7,5)
*
* example 3:
* s0 = (4, 1, 1) and s1 = (3, 4)
* output_lens = (4, 3, 4)
*/
MIGRAPHX_EXPORT
std::vector<std::size_t> compute_broadcasted_lens(std::vector<std::size_t> s0,
std::vector<std::size_t> s1);
MIGRAPHX_EXPORT
std::vector<shape::dynamic_dimension> compute_broadcasted_dyn_dims(shape s0, shape s1);
MIGRAPHX_EXPORT
shape common_shape(const std::vector<shape>& shapes);
std::vector<instruction_ref>
/**
* @brief Compute the common (broadcasted) dimensions of a list of fixed shapes
*/
MIGRAPHX_EXPORT
std::vector<std::size_t> compute_common_lens(const std::vector<shape>& shapes);
/**
* @ brief Compute the common (broadcasted) dynamic dimensions of a list of dynamic shapes
*/
MIGRAPHX_EXPORT
std::vector<shape::dynamic_dimension> compute_common_dyn_dims(const std::vector<shape>& shapes);
/**
* @brief Creates and adds instructions to convert input arguments to common shapes and types
* by adding multi-broadcast and type convert operations. This is a utility function for creating
* operations where the shape and type of inputs need to match. It supports both dynamic and
* static-shaped arguments.
*
* @param m containing module for instruction
* @param ins insertion location in instruction list
* @param inputs instructions to use as argument list; also, the shapes
* attached to each instruction_ref are considered for broadcasting
* @return std::vector<instruction_ref> a modified argument list
*/
MIGRAPHX_EXPORT std::vector<instruction_ref>
insert_common_args(module& m, instruction_ref ins, std::vector<instruction_ref> inputs);
MIGRAPHX_EXPORT
std::vector<instruction_ref> add_common_args(module& m, std::vector<instruction_ref> inputs);
MIGRAPHX_EXPORT
instruction_ref insert_common_op(module& m,
instruction_ref ins,
const operation& op,
std::vector<instruction_ref> inputs);
/**
* @brief Wrapper for insert_common_args() which inserts operation at the end of the module.
*/
MIGRAPHX_EXPORT
instruction_ref add_common_op(module& m, const operation& op, std::vector<instruction_ref> inputs);
} // namespace MIGRAPHX_INLINE_NS
......
......@@ -40,9 +40,6 @@ struct compile_options
bool fast_math = true;
bool exhaustive_tune = false;
/// Use the split_single_dyn_dim pass
bool split_single_dyn_dim = false;
tracer trace{};
};
......
......@@ -41,7 +41,7 @@ struct src_file
std::size_t len() const { return content.second - content.first; }
};
struct src_compiler
struct MIGRAPHX_EXPORT src_compiler
{
std::string compiler = "c++";
std::string flags = "";
......
......@@ -56,7 +56,7 @@ struct concat_optimization
#ifdef TYPE_ERASED_DECLARATION
// Type-erased interface for:
struct concat_optimization
struct MIGRAPHX_EXPORT concat_optimization
{
//
std::string name() const;
......@@ -88,7 +88,7 @@ struct concat_optimization
{
using std::swap;
auto* derived = this->any_cast<PrivateDetailTypeErasedT>();
if(derived and private_detail_te_handle_mem_var.unique())
if(derived and private_detail_te_handle_mem_var.use_count() == 1)
{
*derived = std::forward<PrivateDetailTypeErasedT>(value);
}
......@@ -233,7 +233,7 @@ struct concat_optimization
private_detail_te_handle_base_type& private_detail_te_get_handle()
{
assert(private_detail_te_handle_mem_var != nullptr);
if(not private_detail_te_handle_mem_var.unique())
if(private_detail_te_handle_mem_var.use_count() > 1)
private_detail_te_handle_mem_var = private_detail_te_handle_mem_var->clone();
return *private_detail_te_handle_mem_var;
}
......
......@@ -24,6 +24,8 @@
#ifndef MIGRAPHX_GUARD_CONFIG_HPP
#define MIGRAPHX_GUARD_CONFIG_HPP
#include <migraphx/export.h>
#if !defined(MIGRAPHX_USE_CLANG_TIDY) && !defined(DOXYGEN)
#ifdef BUILD_DEV
......
......@@ -80,7 +80,7 @@ void finish_on_context(T&, any_ptr)
#ifdef TYPE_ERASED_DECLARATION
// Type-erased interface for:
struct context
struct MIGRAPHX_EXPORT context
{
// (optional)
value to_value() const;
......@@ -118,7 +118,7 @@ struct context
{
using std::swap;
auto* derived = this->any_cast<PrivateDetailTypeErasedT>();
if(derived and private_detail_te_handle_mem_var.unique())
if(derived and private_detail_te_handle_mem_var.use_count() == 1)
{
*derived = std::forward<PrivateDetailTypeErasedT>(value);
}
......@@ -373,7 +373,7 @@ struct context
private_detail_te_handle_base_type& private_detail_te_get_handle()
{
assert(private_detail_te_handle_mem_var != nullptr);
if(not private_detail_te_handle_mem_var.unique())
if(private_detail_te_handle_mem_var.use_count() > 1)
private_detail_te_handle_mem_var = private_detail_te_handle_mem_var->clone();
return *private_detail_te_handle_mem_var;
}
......
......@@ -30,7 +30,7 @@
namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS {
std::string convert_to_json(const std::string& str);
MIGRAPHX_EXPORT std::string convert_to_json(const std::string& str);
} // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx
......
......@@ -40,7 +40,7 @@ struct shape;
struct cpp_generator_impl;
struct cpp_generator
struct MIGRAPHX_EXPORT cpp_generator
{
using generate_module_callback = std::function<std::string(
instruction_ref, const std::unordered_map<instruction_ref, std::string>&)>;
......@@ -50,7 +50,7 @@ struct cpp_generator
std::string type;
};
struct function
struct MIGRAPHX_EXPORT function
{
std::vector<param> params = {};
std::string body = "";
......@@ -78,6 +78,7 @@ struct cpp_generator
function& set_types(const module& m, const std::function<std::string(shape)>& parse);
function& set_generic_types(const module& m);
function& add_generic_param(const std::string& pname);
function& unused_param(const std::string& pname);
};
cpp_generator();
......
......@@ -37,7 +37,7 @@ struct program;
/**
* Remove instructions where the output is not used.
*/
struct dead_code_elimination
struct MIGRAPHX_EXPORT dead_code_elimination
{
std::string name() const { return "dead_code_elimination"; }
void apply(module& m) const;
......
......@@ -34,15 +34,15 @@ inline namespace MIGRAPHX_INLINE_NS {
struct module;
struct dominator_info
struct MIGRAPHX_EXPORT dominator_info
{
bool strictly_dominate(instruction_ref ins1, instruction_ref ins2);
std::unordered_map<instruction_ref, instruction_ref> ins2idom;
};
dominator_info compute_dominator(module& m);
// dominator_info compute_dominator_naive(const module& m);
MIGRAPHX_EXPORT dominator_info compute_dominator(module& m);
// MIGRAPHX_EXPORT dominator_info compute_dominator_naive(const module& m);
} // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx
......
......@@ -26,6 +26,7 @@
#include <migraphx/config.hpp>
#include <migraphx/filesystem.hpp>
#include <migraphx/optional.hpp>
#include <functional>
#include <memory>
#include <vector>
......@@ -35,7 +36,7 @@ inline namespace MIGRAPHX_INLINE_NS {
struct dynamic_loader_impl;
struct dynamic_loader
struct MIGRAPHX_EXPORT dynamic_loader
{
template <class T>
static fs::path path(T* address)
......@@ -43,6 +44,9 @@ struct dynamic_loader
return path(reinterpret_cast<void*>(address));
}
static fs::path path(void* address);
static optional<dynamic_loader> try_load(const fs::path& p);
dynamic_loader() = default;
dynamic_loader(const fs::path& p);
......
......@@ -37,7 +37,7 @@ struct module;
* Remove memory allocations. This will create a parameter which is the max of all memory used in
* the program.
*/
struct eliminate_allocation
struct MIGRAPHX_EXPORT eliminate_allocation
{
std::string allocation_op{};
std::size_t alignment = 32;
......
......@@ -36,7 +36,7 @@ struct module;
/**
* Remove identical instructions.
*/
struct eliminate_common_subexpression
struct MIGRAPHX_EXPORT eliminate_common_subexpression
{
std::string name() const { return "eliminate_common_subexpression"; }
void apply(module& m) const;
......
......@@ -37,7 +37,7 @@ struct module;
/**
* Remove concat operators by having each operator can write to different chunk of memory.
*/
struct eliminate_concat
struct MIGRAPHX_EXPORT eliminate_concat
{
concat_optimization concat_opt;
std::string name() const { return "eliminate_concat"; }
......
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