Unverified Commit 9d3fb0b5 authored by Ted Themistokleous's avatar Ted Themistokleous Committed by GitHub
Browse files

Merge branch 'develop' into enable_navi_32_ci

parents 9c91c08d aeb9f78c
...@@ -150,8 +150,8 @@ insert_common_args(module& m, instruction_ref ins, std::vector<instruction_ref> ...@@ -150,8 +150,8 @@ insert_common_args(module& m, instruction_ref ins, std::vector<instruction_ref>
auto c_type = compute_common_types(input_shapes); auto c_type = compute_common_types(input_shapes);
auto c_dyn_dims = compute_common_dyn_dims(input_shapes); auto c_dyn_dims = compute_common_dyn_dims(input_shapes);
// following should work for a static or dynamic shape auto s0 = inputs[0]->get_shape();
if(inputs[0]->get_shape().dyn_dims() != c_dyn_dims) if(not s0.dynamic() or s0.dyn_dims() != c_dyn_dims)
{ {
inputs[0] = m.insert_instruction( inputs[0] = m.insert_instruction(
ins, make_op("multibroadcast", {{"out_dyn_dims", to_value(c_dyn_dims)}}), inputs); ins, make_op("multibroadcast", {{"out_dyn_dims", to_value(c_dyn_dims)}}), inputs);
...@@ -159,7 +159,8 @@ insert_common_args(module& m, instruction_ref ins, std::vector<instruction_ref> ...@@ -159,7 +159,8 @@ insert_common_args(module& m, instruction_ref ins, std::vector<instruction_ref>
std::transform(inputs.begin() + 1, inputs.end(), inputs.begin() + 1, [&](auto input) { std::transform(inputs.begin() + 1, inputs.end(), inputs.begin() + 1, [&](auto input) {
// uses previous input to avoid recalculating the common shape from the // uses previous input to avoid recalculating the common shape from the
// full set of input shapes at runtime // full set of input shapes at runtime
if(input->get_shape().dyn_dims() != c_dyn_dims) auto s = input->get_shape();
if(not s.dynamic() or s.dyn_dims() != c_dyn_dims)
{ {
return m.insert_instruction( return m.insert_instruction(
ins, ins,
......
...@@ -32,18 +32,20 @@ add_executable(driver ...@@ -32,18 +32,20 @@ add_executable(driver
marker_roctx.cpp marker_roctx.cpp
) )
set_target_properties(driver PROPERTIES OUTPUT_NAME migraphx-driver) set_target_properties(driver PROPERTIES OUTPUT_NAME migraphx-driver)
# Copy driver for backwards compatibility if(NOT WIN32)
add_custom_command( # Copy driver for backwards compatibility (Linux only)
add_custom_command(
TARGET driver TARGET driver
POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy
$<TARGET_FILE:driver> $<TARGET_FILE:driver>
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/driver ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/driver
BYPRODUCTS ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/driver BYPRODUCTS ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/driver
) )
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/driver) set_directory_properties(PROPERTIES ADDITIONAL_CLEAN_FILES ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/driver)
endif()
rocm_clang_tidy_check(driver) rocm_clang_tidy_check(driver)
target_link_libraries(driver migraphx_all_targets migraphx_onnx migraphx_tf) target_link_libraries(driver migraphx_all_targets migraphx_onnx migraphx_tf migraphx_py)
rocm_install_targets( rocm_install_targets(
TARGETS driver TARGETS driver
......
...@@ -342,7 +342,19 @@ struct argument_parser ...@@ -342,7 +342,19 @@ struct argument_parser
if(params.empty()) if(params.empty())
throw std::runtime_error("No argument passed."); throw std::runtime_error("No argument passed.");
if(not fs::exists(params.back())) if(not fs::exists(params.back()))
throw std::runtime_error("Path does not exists: " + params.back()); throw std::runtime_error("Path does not exist: " + params.back());
});
}
MIGRAPHX_DRIVER_STATIC auto matches(const std::unordered_set<std::string>& names)
{
return validate([=](auto&, auto&, auto& params) {
for(const auto& p : params)
{
if(names.count(p) == 0)
throw std::runtime_error("Invalid argument: " + p + ". Valid arguments are {" +
to_string_range(names) + "}");
}
}); });
} }
...@@ -570,8 +582,7 @@ struct argument_parser ...@@ -570,8 +582,7 @@ struct argument_parser
continue; continue;
if(flag[0] != '-') if(flag[0] != '-')
continue; continue;
auto d = std::ptrdiff_t d = levenshtein_distance(flag, input);
levenshtein_distance(flag.begin(), flag.end(), input.begin(), input.end());
if(d < result.distance) if(d < result.distance)
result = result_t{&arg, flag, input, d}; result = result_t{&arg, flag, input, d};
} }
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <migraphx/tf.hpp> #include <migraphx/tf.hpp>
#include <migraphx/onnx.hpp> #include <migraphx/onnx.hpp>
#include <migraphx/py.hpp>
#include <migraphx/stringutils.hpp> #include <migraphx/stringutils.hpp>
#include <migraphx/convert_to_json.hpp> #include <migraphx/convert_to_json.hpp>
#include <migraphx/load_save.hpp> #include <migraphx/load_save.hpp>
...@@ -81,6 +82,7 @@ struct loader ...@@ -81,6 +82,7 @@ struct loader
{"--model"}, {"--model"},
ap.help("Load model"), ap.help("Load model"),
ap.type("resnet50|inceptionv3|alexnet"), ap.type("resnet50|inceptionv3|alexnet"),
ap.matches({"resnet50", "inceptionv3", "alexnet"}),
ap.group("input")); ap.group("input"));
ap(file_type, {"--onnx"}, ap.help("Load as onnx"), ap.set_value("onnx")); ap(file_type, {"--onnx"}, ap.help("Load as onnx"), ap.set_value("onnx"));
ap(file_type, {"--tf"}, ap.help("Load as tensorflow"), ap.set_value("tf")); ap(file_type, {"--tf"}, ap.help("Load as tensorflow"), ap.set_value("tf"));
...@@ -241,6 +243,20 @@ struct loader ...@@ -241,6 +243,20 @@ struct loader
return options; return options;
} }
static std::string get_file_type(const std::string& file)
{
if(ends_with(file, ".onnx"))
return "onnx";
else if(ends_with(file, ".pb"))
return "tf";
else if(ends_with(file, ".json"))
return "json";
else if(ends_with(file, ".py"))
return "py";
else
return "migraphx";
}
program load() program load()
{ {
program p; program p;
...@@ -248,14 +264,7 @@ struct loader ...@@ -248,14 +264,7 @@ struct loader
{ {
if(file_type.empty()) if(file_type.empty())
{ {
if(ends_with(file, ".onnx")) file_type = get_file_type(file);
file_type = "onnx";
else if(ends_with(file, ".pb"))
file_type = "tf";
else if(ends_with(file, ".json"))
file_type = "json";
else
file_type = "migraphx";
} }
std::cout << "Reading: " << file << std::endl; std::cout << "Reading: " << file << std::endl;
if(file_type == "onnx") if(file_type == "onnx")
...@@ -272,6 +281,10 @@ struct loader ...@@ -272,6 +281,10 @@ struct loader
options.format = "json"; options.format = "json";
p = migraphx::load(file, options); p = migraphx::load(file, options);
} }
else if(file_type == "py")
{
p = migraphx::load_py(file);
}
else if(file_type == "migraphx") else if(file_type == "migraphx")
{ {
p = migraphx::load(file); p = migraphx::load(file);
...@@ -757,7 +770,7 @@ struct main_command ...@@ -757,7 +770,7 @@ struct main_command
{ {
std::cout << "'" << color::fg_yellow << wrong_commands.front() << color::reset std::cout << "'" << color::fg_yellow << wrong_commands.front() << color::reset
<< "' is not a valid command." << std::endl; << "' is not a valid command." << std::endl;
std::cout << get_command_help("Available commands:") << std::endl; std::cout << get_command_help("Available commands:");
} }
else else
{ {
......
...@@ -48,7 +48,7 @@ struct dynamic_loader_impl ...@@ -48,7 +48,7 @@ struct dynamic_loader_impl
#pragma GCC diagnostic ignored "-Wignored-attributes" #pragma GCC diagnostic ignored "-Wignored-attributes"
#endif #endif
dynamic_loader_impl(const fs::path& p, std::shared_ptr<tmp_dir> t = nullptr) dynamic_loader_impl(const fs::path& p, std::shared_ptr<tmp_dir> t = nullptr)
: handle(dlopen(p.string().c_str(), RTLD_LAZY), : handle(dlopen(p.string().c_str(), RTLD_GLOBAL | RTLD_NOW),
manage_deleter<decltype(&dlclose), &dlclose>{}), manage_deleter<decltype(&dlclose), &dlclose>{}),
temp(std::move(t)) temp(std::move(t))
{ {
...@@ -81,6 +81,18 @@ fs::path dynamic_loader::path(void* address) ...@@ -81,6 +81,18 @@ fs::path dynamic_loader::path(void* address)
return p; return p;
} }
optional<dynamic_loader> dynamic_loader::try_load(const fs::path& p)
{
try
{
return dynamic_loader{p};
}
catch(const std::exception&)
{
return nullopt;
}
}
dynamic_loader::dynamic_loader(const fs::path& p) : impl(std::make_shared<dynamic_loader_impl>(p)) dynamic_loader::dynamic_loader(const fs::path& p) : impl(std::make_shared<dynamic_loader_impl>(p))
{ {
} }
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
namespace migraphx { namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS { inline namespace MIGRAPHX_INLINE_NS {
argument fill_argument(shape s, unsigned long value) argument fill_argument(shape s, double value)
{ {
argument result; argument result;
if(s.type() == shape::tuple_type) if(s.type() == shape::tuple_type)
......
...@@ -32,7 +32,7 @@ inline namespace MIGRAPHX_INLINE_NS { ...@@ -32,7 +32,7 @@ inline namespace MIGRAPHX_INLINE_NS {
struct module; struct module;
struct adjust_allocation struct MIGRAPHX_EXPORT adjust_allocation
{ {
allocation_model model; allocation_model model;
std::string name() const { return "adjust_allocation"; } std::string name() const { return "adjust_allocation"; }
......
...@@ -90,6 +90,43 @@ levenshtein_distance(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterat ...@@ -90,6 +90,43 @@ levenshtein_distance(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterat
return std::ptrdiff_t{1} + std::min({x1, x2, x3}); return std::ptrdiff_t{1} + std::min({x1, x2, x3});
} }
inline size_t levenshtein_distance(const std::string& s1, const std::string& s2)
{
const size_t l1 = s1.length();
const size_t l2 = s2.length();
if(l1 < l2)
levenshtein_distance(s2, s1);
std::vector<size_t> d(l2 + 1);
for(size_t j = 1; j <= l2; j++)
d[j] = j;
for(size_t i = 1; i <= l1; i++)
{
size_t prev_cost = d[0];
d[0] = i;
for(size_t j = 1; j <= l2; j++)
{
if(s1[i - 1] == s2[j - 1])
{
d[j] = prev_cost;
}
else
{
size_t cost_insert_or_delete = std::min(d[j - 1], d[j]);
size_t cost_substitute = prev_cost;
prev_cost = d[j];
d[j] = std::min(cost_substitute, cost_insert_or_delete) + 1;
}
}
}
return d[l2];
}
} // namespace MIGRAPHX_INLINE_NS } // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx } // namespace migraphx
......
...@@ -60,7 +60,7 @@ struct allocation_model ...@@ -60,7 +60,7 @@ struct allocation_model
#ifdef TYPE_ERASED_DECLARATION #ifdef TYPE_ERASED_DECLARATION
// Type-erased interface for: // Type-erased interface for:
struct allocation_model struct MIGRAPHX_EXPORT allocation_model
{ {
// //
std::string name() const; std::string name() const;
...@@ -96,7 +96,7 @@ struct allocation_model ...@@ -96,7 +96,7 @@ struct allocation_model
{ {
using std::swap; using std::swap;
auto* derived = this->any_cast<PrivateDetailTypeErasedT>(); 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); *derived = std::forward<PrivateDetailTypeErasedT>(value);
} }
...@@ -267,7 +267,7 @@ struct allocation_model ...@@ -267,7 +267,7 @@ struct allocation_model
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); 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(); 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;
} }
......
...@@ -39,7 +39,8 @@ struct stream_race ...@@ -39,7 +39,8 @@ struct stream_race
instruction_ref before; instruction_ref before;
}; };
std::vector<stream_race> analyze_streams(const module& m, const stream_model& strmm); MIGRAPHX_EXPORT std::vector<stream_race> analyze_streams(const module& m,
const stream_model& strmm);
} // namespace MIGRAPHX_INLINE_NS } // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx } // namespace migraphx
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
namespace migraphx { namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS { inline namespace MIGRAPHX_INLINE_NS {
MIGRAPHX_EXPORT
instruction_ref insert_apply_alpha_beta(module& m, instruction_ref insert_apply_alpha_beta(module& m,
instruction_ref pos, instruction_ref pos,
const std::vector<instruction_ref>& args, const std::vector<instruction_ref>& args,
......
...@@ -42,7 +42,7 @@ inline namespace MIGRAPHX_INLINE_NS { ...@@ -42,7 +42,7 @@ inline namespace MIGRAPHX_INLINE_NS {
* or it can be owned by the argument. * or it can be owned by the argument.
* *
*/ */
struct argument : raw_data<argument> struct MIGRAPHX_EXPORT argument : raw_data<argument>
{ {
argument() = default; argument() = default;
...@@ -93,6 +93,16 @@ struct argument : raw_data<argument> ...@@ -93,6 +93,16 @@ struct argument : raw_data<argument>
/// Return the ith element /// Return the ith element
argument element(std::size_t i) const; 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: private:
void assign_buffer(std::function<char*()> d); void assign_buffer(std::function<char*()> d);
struct data_t struct data_t
...@@ -107,9 +117,9 @@ struct argument : raw_data<argument> ...@@ -107,9 +117,9 @@ struct argument : raw_data<argument>
data_t m_data{}; data_t m_data{};
}; };
std::vector<shape> to_shapes(const std::vector<argument>& args); MIGRAPHX_EXPORT std::vector<shape> to_shapes(const std::vector<argument>& args);
void migraphx_to_value(value& v, const argument& a); MIGRAPHX_EXPORT void migraphx_to_value(value& v, const argument& a);
void migraphx_from_value(const value& v, argument& a); MIGRAPHX_EXPORT void migraphx_from_value(const value& v, argument& a);
} // namespace MIGRAPHX_INLINE_NS } // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx } // namespace migraphx
......
...@@ -33,7 +33,7 @@ inline namespace MIGRAPHX_INLINE_NS { ...@@ -33,7 +33,7 @@ inline namespace MIGRAPHX_INLINE_NS {
struct module; struct module;
struct auto_contiguous struct MIGRAPHX_EXPORT auto_contiguous
{ {
std::string name() const { return "auto_contiguous"; } std::string name() const { return "auto_contiguous"; }
void apply(module& m) const; void apply(module& m) const;
......
...@@ -90,7 +90,17 @@ struct param ...@@ -90,7 +90,17 @@ struct param
struct returns struct returns
{ {
std::string name() const { return "@return"; } 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 argument compute(context&, const shape&, const std::vector<argument>&) const
{ {
MIGRAPHX_THROW("builtin"); MIGRAPHX_THROW("builtin");
......
...@@ -54,21 +54,26 @@ struct operation; ...@@ -54,21 +54,26 @@ struct operation;
* s0 = (4, 1, 1) and s1 = (3, 4) * s0 = (4, 1, 1) and s1 = (3, 4)
* output_lens = (4, 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> compute_broadcasted_lens(std::vector<std::size_t> s0,
std::vector<std::size_t> s1); std::vector<std::size_t> s1);
MIGRAPHX_EXPORT
std::vector<shape::dynamic_dimension> compute_broadcasted_dyn_dims(shape s0, shape s1); std::vector<shape::dynamic_dimension> compute_broadcasted_dyn_dims(shape s0, shape s1);
MIGRAPHX_EXPORT
shape common_shape(const std::vector<shape>& shapes); shape common_shape(const std::vector<shape>& shapes);
/** /**
* @brief Compute the common (broadcasted) dimensions of a list of fixed shapes * @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); 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 * @ 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); std::vector<shape::dynamic_dimension> compute_common_dyn_dims(const std::vector<shape>& shapes);
/** /**
...@@ -83,11 +88,13 @@ std::vector<shape::dynamic_dimension> compute_common_dyn_dims(const std::vector< ...@@ -83,11 +88,13 @@ std::vector<shape::dynamic_dimension> compute_common_dyn_dims(const std::vector<
* attached to each instruction_ref are considered for broadcasting * attached to each instruction_ref are considered for broadcasting
* @return std::vector<instruction_ref> a modified argument list * @return std::vector<instruction_ref> a modified argument list
*/ */
std::vector<instruction_ref> MIGRAPHX_EXPORT std::vector<instruction_ref>
insert_common_args(module& m, instruction_ref ins, std::vector<instruction_ref> inputs); 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); 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 insert_common_op(module& m,
instruction_ref ins, instruction_ref ins,
const operation& op, const operation& op,
...@@ -96,6 +103,7 @@ instruction_ref insert_common_op(module& m, ...@@ -96,6 +103,7 @@ instruction_ref insert_common_op(module& m,
/** /**
* @brief Wrapper for insert_common_args() which inserts operation at the end of the module. * @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); instruction_ref add_common_op(module& m, const operation& op, std::vector<instruction_ref> inputs);
} // namespace MIGRAPHX_INLINE_NS } // namespace MIGRAPHX_INLINE_NS
......
...@@ -41,7 +41,7 @@ struct src_file ...@@ -41,7 +41,7 @@ struct src_file
std::size_t len() const { return content.second - content.first; } std::size_t len() const { return content.second - content.first; }
}; };
struct src_compiler struct MIGRAPHX_EXPORT src_compiler
{ {
std::string compiler = "c++"; std::string compiler = "c++";
std::string flags = ""; std::string flags = "";
......
...@@ -56,7 +56,7 @@ struct concat_optimization ...@@ -56,7 +56,7 @@ struct concat_optimization
#ifdef TYPE_ERASED_DECLARATION #ifdef TYPE_ERASED_DECLARATION
// Type-erased interface for: // Type-erased interface for:
struct concat_optimization struct MIGRAPHX_EXPORT concat_optimization
{ {
// //
std::string name() const; std::string name() const;
...@@ -88,7 +88,7 @@ struct concat_optimization ...@@ -88,7 +88,7 @@ struct concat_optimization
{ {
using std::swap; using std::swap;
auto* derived = this->any_cast<PrivateDetailTypeErasedT>(); 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); *derived = std::forward<PrivateDetailTypeErasedT>(value);
} }
...@@ -233,7 +233,7 @@ struct concat_optimization ...@@ -233,7 +233,7 @@ struct concat_optimization
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); 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(); 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;
} }
......
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
#ifndef MIGRAPHX_GUARD_CONFIG_HPP #ifndef MIGRAPHX_GUARD_CONFIG_HPP
#define MIGRAPHX_GUARD_CONFIG_HPP #define MIGRAPHX_GUARD_CONFIG_HPP
#include <migraphx/export.h>
#if !defined(MIGRAPHX_USE_CLANG_TIDY) && !defined(DOXYGEN) #if !defined(MIGRAPHX_USE_CLANG_TIDY) && !defined(DOXYGEN)
#ifdef BUILD_DEV #ifdef BUILD_DEV
......
...@@ -80,7 +80,7 @@ void finish_on_context(T&, any_ptr) ...@@ -80,7 +80,7 @@ void finish_on_context(T&, any_ptr)
#ifdef TYPE_ERASED_DECLARATION #ifdef TYPE_ERASED_DECLARATION
// Type-erased interface for: // Type-erased interface for:
struct context struct MIGRAPHX_EXPORT context
{ {
// (optional) // (optional)
value to_value() const; value to_value() const;
...@@ -118,7 +118,7 @@ struct context ...@@ -118,7 +118,7 @@ struct context
{ {
using std::swap; using std::swap;
auto* derived = this->any_cast<PrivateDetailTypeErasedT>(); 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); *derived = std::forward<PrivateDetailTypeErasedT>(value);
} }
...@@ -373,7 +373,7 @@ struct context ...@@ -373,7 +373,7 @@ struct context
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); 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(); 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;
} }
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
namespace migraphx { namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS { 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_INLINE_NS
} // namespace migraphx } // namespace migraphx
......
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