mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-18 17:14:26 +03:00
aaa
This commit is contained in:
parent
b8ce179b7e
commit
c031a9185f
@ -13,7 +13,7 @@ SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
|||||||
|
|
||||||
project(migraphx_py)
|
project(migraphx_py)
|
||||||
|
|
||||||
include_directories(/opt/rocm/include)
|
include_directories(/opt/rocm/include /opt/rocm/lib)
|
||||||
|
|
||||||
find_package(pybind11 REQUIRED)
|
find_package(pybind11 REQUIRED)
|
||||||
pybind11_add_module(migraphx migraphx_py.cpp)
|
pybind11_add_module(migraphx migraphx_py.cpp)
|
||||||
|
|||||||
@ -1,70 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2022 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.
|
|
||||||
*/
|
|
||||||
#include <migraphx/adjust_allocation.hpp>
|
|
||||||
#include <migraphx/instruction.hpp>
|
|
||||||
#include <migraphx/program.hpp>
|
|
||||||
#include <migraphx/make_op.hpp>
|
|
||||||
#include <migraphx/iterator_for.hpp>
|
|
||||||
#include <migraphx/ranges.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
void adjust_allocation::apply(module& m) const
|
|
||||||
{
|
|
||||||
for(auto ins : iterator_for(m))
|
|
||||||
{
|
|
||||||
// skip instruction with no input
|
|
||||||
if(ins->inputs().empty())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Skip target-independent operators
|
|
||||||
if(ins->get_operator().is_context_free())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
auto alias_ins = instruction::get_output_alias(ins, true);
|
|
||||||
if(alias_ins->name() != model.name() and alias_ins->name() != "@param")
|
|
||||||
continue;
|
|
||||||
// shape allocated is different from actual shape
|
|
||||||
// of the instruction, reallocate and replace the previous one
|
|
||||||
if(alias_ins->get_shape() == ins->get_shape())
|
|
||||||
continue;
|
|
||||||
auto alloc_ins = m.insert_instruction(ins, model.allocate(ins->get_shape()));
|
|
||||||
m.replace_instruction(alias_ins, alloc_ins);
|
|
||||||
// If the memory is an output parameter then copy the memory to the parameter
|
|
||||||
if(alias_ins->name() == "@param")
|
|
||||||
{
|
|
||||||
auto copy = m.insert_instruction(std::next(ins), make_op(model.copy()), ins, alias_ins);
|
|
||||||
auto tail = range(std::next(copy), m.end());
|
|
||||||
for(auto i : iterator_for(tail))
|
|
||||||
{
|
|
||||||
if(contains(i->inputs(), ins))
|
|
||||||
instruction::replace_argument(i, ins, copy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,114 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2022 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.
|
|
||||||
*/
|
|
||||||
#include <migraphx/analyze_streams.hpp>
|
|
||||||
#include <migraphx/program.hpp>
|
|
||||||
#include <migraphx/iterator_for.hpp>
|
|
||||||
#include <migraphx/ranges.hpp>
|
|
||||||
#include <migraphx/instruction.hpp>
|
|
||||||
#include <migraphx/errors.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
bool happens_before(const std::vector<std::size_t>& e1, const std::vector<std::size_t>& e2)
|
|
||||||
{
|
|
||||||
return std::equal(e1.begin(), e1.end(), e2.begin(), e2.end(), std::less_equal<>{}) and
|
|
||||||
not std::equal(e1.begin(), e1.end(), e2.begin(), e2.end(), std::greater_equal<>{});
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<stream_race> analyze_streams(const module& m, const stream_model& strmm)
|
|
||||||
{
|
|
||||||
using vector_clock = std::vector<std::size_t>;
|
|
||||||
std::vector<stream_race> races;
|
|
||||||
auto nstream = strmm.get_nstream();
|
|
||||||
std::vector<vector_clock> vclock(nstream, vector_clock(nstream));
|
|
||||||
std::unordered_map<instruction_ref, vector_clock> timestamp;
|
|
||||||
std::unordered_map<std::size_t, vector_clock> events;
|
|
||||||
for(auto ins : iterator_for(m))
|
|
||||||
{
|
|
||||||
if(not strmm.has_stream(ins))
|
|
||||||
continue;
|
|
||||||
std::size_t s = strmm.get_stream(ins);
|
|
||||||
assert(s < nstream);
|
|
||||||
assert(vclock.size() == nstream);
|
|
||||||
assert(vclock[s].size() == nstream);
|
|
||||||
if(strmm.is_record(ins))
|
|
||||||
{
|
|
||||||
vclock[s][s]++;
|
|
||||||
auto event = strmm.get_event_id(ins);
|
|
||||||
events[event] = vclock[s];
|
|
||||||
}
|
|
||||||
else if(strmm.is_wait(ins))
|
|
||||||
{
|
|
||||||
auto event = strmm.get_event_id(ins);
|
|
||||||
if(not contains(events, event))
|
|
||||||
MIGRAPHX_THROW("Event is waited on before being recorded: " +
|
|
||||||
std::to_string(event));
|
|
||||||
auto payload = events.at(event);
|
|
||||||
assert(vclock[s].size() == payload.size());
|
|
||||||
std::transform(vclock[s].begin(),
|
|
||||||
vclock[s].end(),
|
|
||||||
payload.begin(),
|
|
||||||
vclock[s].begin(),
|
|
||||||
[&](auto x, auto y) { return std::max(x, y); });
|
|
||||||
vclock[s][s]++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
vclock[s][s]++;
|
|
||||||
}
|
|
||||||
timestamp[ins] = vclock[s];
|
|
||||||
}
|
|
||||||
for(auto ins : iterator_for(m))
|
|
||||||
{
|
|
||||||
if(not strmm.has_stream(ins))
|
|
||||||
continue;
|
|
||||||
if(ins->inputs().empty())
|
|
||||||
continue;
|
|
||||||
std::size_t s = strmm.get_stream(ins);
|
|
||||||
// Find inputs from different streams
|
|
||||||
std::vector<instruction_ref> inputs;
|
|
||||||
fix([&](auto self, auto start) {
|
|
||||||
for(auto input : start->inputs())
|
|
||||||
{
|
|
||||||
if(not strmm.has_stream(input))
|
|
||||||
self(input);
|
|
||||||
else if(strmm.get_stream(input) != s)
|
|
||||||
inputs.push_back(input);
|
|
||||||
}
|
|
||||||
})(ins);
|
|
||||||
auto it = std::find_if(inputs.begin(), inputs.end(), [&](auto input) {
|
|
||||||
return not happens_before(timestamp.at(input), timestamp.at(ins));
|
|
||||||
});
|
|
||||||
if(it != inputs.end())
|
|
||||||
{
|
|
||||||
races.push_back({ins, *it});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return races;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,46 +0,0 @@
|
|||||||
#####################################################################################
|
|
||||||
# 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.
|
|
||||||
#####################################################################################
|
|
||||||
|
|
||||||
add_library(migraphx_c
|
|
||||||
api.cpp
|
|
||||||
)
|
|
||||||
set_target_properties(migraphx_c PROPERTIES EXPORT_NAME c)
|
|
||||||
migraphx_generate_export_header(migraphx_c DIRECTORY migraphx/api)
|
|
||||||
|
|
||||||
# migraphx_c is stable API interface library. SO version of this should be
|
|
||||||
# bumped when binary compatibility is broken.
|
|
||||||
rocm_set_soversion(migraphx_c 3.0)
|
|
||||||
|
|
||||||
if(BUILD_TESTING)
|
|
||||||
target_compile_definitions(migraphx_c PRIVATE MIGRAPHX_BUILD_TESTING)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
rocm_clang_tidy_check(migraphx_c)
|
|
||||||
target_link_libraries(migraphx_c PRIVATE migraphx migraphx_tf migraphx_onnx)
|
|
||||||
|
|
||||||
rocm_install_targets(
|
|
||||||
TARGETS migraphx_c
|
|
||||||
INCLUDE
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
|
||||||
)
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,684 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2025 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_C_API_MIGRAPHX_H
|
|
||||||
#define MIGRAPHX_GUARD_C_API_MIGRAPHX_H
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include <migraphx/api/export.h>
|
|
||||||
|
|
||||||
// Add new types here
|
|
||||||
// clang-format off
|
|
||||||
#define MIGRAPHX_SHAPE_VISIT_TYPES(m) \
|
|
||||||
m(bool_type, bool) \
|
|
||||||
m(half_type, half) \
|
|
||||||
m(float_type, float) \
|
|
||||||
m(double_type, double) \
|
|
||||||
m(uint8_type, uint8_t) \
|
|
||||||
m(int8_type, int8_t) \
|
|
||||||
m(uint16_type, uint16_t) \
|
|
||||||
m(int16_type, int16_t) \
|
|
||||||
m(int32_type, int32_t) \
|
|
||||||
m(int64_type, int64_t) \
|
|
||||||
m(uint32_type, uint32_t) \
|
|
||||||
m(uint64_type, uint64_t) \
|
|
||||||
m(fp8e4m3fnuz_type, migraphx::fp8::fp8e4m3fnuz) \
|
|
||||||
m(fp8e4m3fn_type, migraphx::fp8::fp8e4m3fn) \
|
|
||||||
m(fp8e5m2_type, migraphx::fp8::fp8e5m2) \
|
|
||||||
m(bf16_type, bf16) \
|
|
||||||
m(fp8e5m2fnuz_type, migraphx::fp8::fp8e5m2fnuz)
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// return code, more to be added later
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
migraphx_status_success = 0,
|
|
||||||
migraphx_status_bad_param = 1,
|
|
||||||
migraphx_status_unknown_target = 3,
|
|
||||||
migraphx_status_unknown_error = 4,
|
|
||||||
|
|
||||||
} migraphx_status;
|
|
||||||
|
|
||||||
#define MIGRAPHX_SHAPE_GENERATE_ENUM_TYPES(x, t) migraphx_shape_##x,
|
|
||||||
/// An enum to represent the different data type inputs
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
migraphx_shape_tuple_type,
|
|
||||||
MIGRAPHX_SHAPE_VISIT_TYPES(MIGRAPHX_SHAPE_GENERATE_ENUM_TYPES)
|
|
||||||
} migraphx_shape_datatype_t;
|
|
||||||
#undef MIGRAPHX_SHAPE_GENERATE_ENUM_TYPES
|
|
||||||
|
|
||||||
typedef struct migraphx_optimals* migraphx_optimals_t;
|
|
||||||
typedef const struct migraphx_optimals* const_migraphx_optimals_t;
|
|
||||||
|
|
||||||
typedef struct migraphx_dynamic_dimension* migraphx_dynamic_dimension_t;
|
|
||||||
typedef const struct migraphx_dynamic_dimension* const_migraphx_dynamic_dimension_t;
|
|
||||||
|
|
||||||
typedef struct migraphx_dynamic_dimensions* migraphx_dynamic_dimensions_t;
|
|
||||||
typedef const struct migraphx_dynamic_dimensions* const_migraphx_dynamic_dimensions_t;
|
|
||||||
|
|
||||||
typedef struct migraphx_shape* migraphx_shape_t;
|
|
||||||
typedef const struct migraphx_shape* const_migraphx_shape_t;
|
|
||||||
|
|
||||||
typedef struct migraphx_argument* migraphx_argument_t;
|
|
||||||
typedef const struct migraphx_argument* const_migraphx_argument_t;
|
|
||||||
|
|
||||||
typedef struct migraphx_target* migraphx_target_t;
|
|
||||||
typedef const struct migraphx_target* const_migraphx_target_t;
|
|
||||||
|
|
||||||
typedef struct migraphx_program_parameter_shapes* migraphx_program_parameter_shapes_t;
|
|
||||||
typedef const struct migraphx_program_parameter_shapes* const_migraphx_program_parameter_shapes_t;
|
|
||||||
|
|
||||||
typedef struct migraphx_program_parameters* migraphx_program_parameters_t;
|
|
||||||
typedef const struct migraphx_program_parameters* const_migraphx_program_parameters_t;
|
|
||||||
|
|
||||||
typedef struct migraphx_arguments* migraphx_arguments_t;
|
|
||||||
typedef const struct migraphx_arguments* const_migraphx_arguments_t;
|
|
||||||
|
|
||||||
typedef struct migraphx_shapes* migraphx_shapes_t;
|
|
||||||
typedef const struct migraphx_shapes* const_migraphx_shapes_t;
|
|
||||||
|
|
||||||
typedef struct migraphx_instruction* migraphx_instruction_t;
|
|
||||||
typedef const struct migraphx_instruction* const_migraphx_instruction_t;
|
|
||||||
|
|
||||||
typedef struct migraphx_instructions* migraphx_instructions_t;
|
|
||||||
typedef const struct migraphx_instructions* const_migraphx_instructions_t;
|
|
||||||
|
|
||||||
typedef struct migraphx_modules* migraphx_modules_t;
|
|
||||||
typedef const struct migraphx_modules* const_migraphx_modules_t;
|
|
||||||
|
|
||||||
typedef struct migraphx_module* migraphx_module_t;
|
|
||||||
typedef const struct migraphx_module* const_migraphx_module_t;
|
|
||||||
|
|
||||||
typedef struct migraphx_program* migraphx_program_t;
|
|
||||||
typedef const struct migraphx_program* const_migraphx_program_t;
|
|
||||||
|
|
||||||
typedef struct migraphx_operation* migraphx_operation_t;
|
|
||||||
typedef const struct migraphx_operation* const_migraphx_operation_t;
|
|
||||||
|
|
||||||
typedef struct migraphx_onnx_options* migraphx_onnx_options_t;
|
|
||||||
typedef const struct migraphx_onnx_options* const_migraphx_onnx_options_t;
|
|
||||||
|
|
||||||
typedef struct migraphx_file_options* migraphx_file_options_t;
|
|
||||||
typedef const struct migraphx_file_options* const_migraphx_file_options_t;
|
|
||||||
|
|
||||||
typedef struct migraphx_compile_options* migraphx_compile_options_t;
|
|
||||||
typedef const struct migraphx_compile_options* const_migraphx_compile_options_t;
|
|
||||||
|
|
||||||
typedef struct migraphx_tf_options* migraphx_tf_options_t;
|
|
||||||
typedef const struct migraphx_tf_options* const_migraphx_tf_options_t;
|
|
||||||
|
|
||||||
typedef struct migraphx_quantize_op_names* migraphx_quantize_op_names_t;
|
|
||||||
typedef const struct migraphx_quantize_op_names* const_migraphx_quantize_op_names_t;
|
|
||||||
|
|
||||||
typedef struct migraphx_quantize_int8_options* migraphx_quantize_int8_options_t;
|
|
||||||
typedef const struct migraphx_quantize_int8_options* const_migraphx_quantize_int8_options_t;
|
|
||||||
|
|
||||||
typedef struct migraphx_quantize_fp8_options* migraphx_quantize_fp8_options_t;
|
|
||||||
typedef const struct migraphx_quantize_fp8_options* const_migraphx_quantize_fp8_options_t;
|
|
||||||
|
|
||||||
typedef struct migraphx_context* migraphx_context_t;
|
|
||||||
typedef const struct migraphx_context* const_migraphx_context_t;
|
|
||||||
|
|
||||||
typedef struct migraphx_experimental_custom_op* migraphx_experimental_custom_op_t;
|
|
||||||
typedef const struct migraphx_experimental_custom_op* const_migraphx_experimental_custom_op_t;
|
|
||||||
|
|
||||||
typedef migraphx_status (*migraphx_experimental_custom_op_compute)(migraphx_argument_t out,
|
|
||||||
void* obj,
|
|
||||||
char* exception_msg,
|
|
||||||
size_t exception_msg_size,
|
|
||||||
migraphx_context_t ctx,
|
|
||||||
migraphx_shape_t output,
|
|
||||||
migraphx_arguments_t inputs);
|
|
||||||
|
|
||||||
typedef migraphx_status (*migraphx_experimental_custom_op_compute_shape)(migraphx_shape_t out,
|
|
||||||
void* obj,
|
|
||||||
char* exception_msg,
|
|
||||||
size_t exception_msg_size,
|
|
||||||
migraphx_shapes_t inputs);
|
|
||||||
|
|
||||||
typedef migraphx_status (*migraphx_experimental_custom_op_output_alias)(size_t* out,
|
|
||||||
size_t* out_size,
|
|
||||||
void* obj,
|
|
||||||
char* exception_msg,
|
|
||||||
size_t exception_msg_size,
|
|
||||||
migraphx_shapes_t inputs);
|
|
||||||
|
|
||||||
typedef migraphx_status (*migraphx_experimental_custom_op_runs_on_offload_target)(
|
|
||||||
bool* out, void* obj, char* exception_msg, size_t exception_msg_size);
|
|
||||||
|
|
||||||
typedef migraphx_status (*migraphx_experimental_custom_op_copy)(void** out, void* input);
|
|
||||||
|
|
||||||
typedef migraphx_status (*migraphx_experimental_custom_op_delete)(void* input);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_optimals_destroy(migraphx_optimals_t optimals);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_optimals_assign_to(migraphx_optimals_t output,
|
|
||||||
const_migraphx_optimals_t input);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_optimals_create(migraphx_optimals_t* optimals,
|
|
||||||
const size_t* ptr,
|
|
||||||
size_t size);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_dynamic_dimension_destroy(migraphx_dynamic_dimension_t dynamic_dimension);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_dynamic_dimension_assign_to(
|
|
||||||
migraphx_dynamic_dimension_t output, const_migraphx_dynamic_dimension_t input);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_dynamic_dimension_create_min_max(
|
|
||||||
migraphx_dynamic_dimension_t* dynamic_dimension, size_t min, size_t max);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_dynamic_dimension_create_min_max_optimals(migraphx_dynamic_dimension_t* dynamic_dimension,
|
|
||||||
size_t min,
|
|
||||||
size_t max,
|
|
||||||
migraphx_optimals_t optimals);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_dynamic_dimension_is_fixed(
|
|
||||||
bool* out, const_migraphx_dynamic_dimension_t dynamic_dimension);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_dynamic_dimension_equal(bool* out,
|
|
||||||
const_migraphx_dynamic_dimension_t dynamic_dimension,
|
|
||||||
const_migraphx_dynamic_dimension_t x);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_dynamic_dimensions_destroy(migraphx_dynamic_dimensions_t dynamic_dimensions);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_dynamic_dimensions_assign_to(
|
|
||||||
migraphx_dynamic_dimensions_t output, const_migraphx_dynamic_dimensions_t input);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_dynamic_dimensions_create(migraphx_dynamic_dimensions_t* dynamic_dimensions,
|
|
||||||
const const_migraphx_dynamic_dimension_t* ptr,
|
|
||||||
size_t size);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_dynamic_dimensions_size(size_t* out, migraphx_dynamic_dimensions_t dynamic_dimensions);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_dynamic_dimensions_get(const_migraphx_dynamic_dimension_t* out,
|
|
||||||
migraphx_dynamic_dimensions_t dynamic_dimensions,
|
|
||||||
size_t idx);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_shape_destroy(migraphx_shape_t shape);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_shape_assign_to(migraphx_shape_t output,
|
|
||||||
const_migraphx_shape_t input);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_shape_create(migraphx_shape_t* shape,
|
|
||||||
migraphx_shape_datatype_t type,
|
|
||||||
size_t* lengths,
|
|
||||||
size_t lengths_size);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_shape_create_with_strides(migraphx_shape_t* shape,
|
|
||||||
migraphx_shape_datatype_t type,
|
|
||||||
size_t* lengths,
|
|
||||||
size_t lengths_size,
|
|
||||||
size_t* strides,
|
|
||||||
size_t strides_size);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_shape_create_scalar(migraphx_shape_t* shape,
|
|
||||||
migraphx_shape_datatype_t type);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_shape_create_dynamic(migraphx_shape_t* shape,
|
|
||||||
migraphx_shape_datatype_t type,
|
|
||||||
migraphx_dynamic_dimensions_t dims);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_shape_lengths(const size_t** out,
|
|
||||||
size_t* out_size,
|
|
||||||
const_migraphx_shape_t shape);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_shape_strides(const size_t** out,
|
|
||||||
size_t* out_size,
|
|
||||||
const_migraphx_shape_t shape);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_shape_dyn_dims(migraphx_dynamic_dimensions_t* out,
|
|
||||||
const_migraphx_shape_t shape);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_shape_type(migraphx_shape_datatype_t* out,
|
|
||||||
const_migraphx_shape_t shape);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_shape_elements(size_t* out,
|
|
||||||
const_migraphx_shape_t shape);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_shape_bytes(size_t* out, const_migraphx_shape_t shape);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_shape_ndim(size_t* out, const_migraphx_shape_t shape);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_shape_equal(bool* out,
|
|
||||||
const_migraphx_shape_t shape,
|
|
||||||
const_migraphx_shape_t x);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_shape_standard(bool* out, const_migraphx_shape_t shape);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_shape_dynamic(bool* out, const_migraphx_shape_t shape);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_shape_index(size_t* out,
|
|
||||||
const_migraphx_shape_t shape,
|
|
||||||
size_t i);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_argument_destroy(migraphx_argument_t argument);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_argument_assign_to(migraphx_argument_t output,
|
|
||||||
const_migraphx_argument_t input);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_argument_create(migraphx_argument_t* argument,
|
|
||||||
const_migraphx_shape_t shape,
|
|
||||||
void* buffer);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_argument_create_empty(migraphx_argument_t* argument,
|
|
||||||
const_migraphx_shape_t shape);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_argument_shape(const_migraphx_shape_t* out,
|
|
||||||
const_migraphx_argument_t argument);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_argument_buffer(char** out,
|
|
||||||
const_migraphx_argument_t argument);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_argument_equal(bool* out,
|
|
||||||
const_migraphx_argument_t argument,
|
|
||||||
const_migraphx_argument_t x);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_argument_generate(migraphx_argument_t* out,
|
|
||||||
const_migraphx_shape_t s,
|
|
||||||
size_t seed);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_target_destroy(migraphx_target_t target);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_target_assign_to(migraphx_target_t output,
|
|
||||||
const_migraphx_target_t input);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_target_create(migraphx_target_t* target,
|
|
||||||
const char* name);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_program_parameter_shapes_destroy(
|
|
||||||
migraphx_program_parameter_shapes_t program_parameter_shapes);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_program_parameter_shapes_assign_to(
|
|
||||||
migraphx_program_parameter_shapes_t output, const_migraphx_program_parameter_shapes_t input);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_program_parameter_shapes_size(
|
|
||||||
size_t* out, migraphx_program_parameter_shapes_t program_parameter_shapes);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_program_parameter_shapes_get(const_migraphx_shape_t* out,
|
|
||||||
migraphx_program_parameter_shapes_t program_parameter_shapes,
|
|
||||||
const char* name);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_program_parameter_shapes_names(
|
|
||||||
const char** out, migraphx_program_parameter_shapes_t program_parameter_shapes);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_program_parameters_destroy(migraphx_program_parameters_t program_parameters);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_program_parameters_assign_to(
|
|
||||||
migraphx_program_parameters_t output, const_migraphx_program_parameters_t input);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_program_parameters_create(migraphx_program_parameters_t* program_parameters);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_program_parameters_add(migraphx_program_parameters_t program_parameters,
|
|
||||||
const char* name,
|
|
||||||
const_migraphx_argument_t argument);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_arguments_destroy(migraphx_arguments_t arguments);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_arguments_assign_to(migraphx_arguments_t output,
|
|
||||||
const_migraphx_arguments_t input);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_arguments_size(size_t* out,
|
|
||||||
migraphx_arguments_t arguments);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_arguments_get(const_migraphx_argument_t* out,
|
|
||||||
migraphx_arguments_t arguments,
|
|
||||||
size_t idx);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_shapes_destroy(migraphx_shapes_t shapes);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_shapes_assign_to(migraphx_shapes_t output,
|
|
||||||
const_migraphx_shapes_t input);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_shapes_size(size_t* out, migraphx_shapes_t shapes);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_shapes_get(const_migraphx_shape_t* out,
|
|
||||||
migraphx_shapes_t shapes,
|
|
||||||
size_t idx);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_instruction_destroy(migraphx_instruction_t instruction);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_instruction_assign_to(migraphx_instruction_t output, const_migraphx_instruction_t input);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_instructions_destroy(migraphx_instructions_t instructions);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_instructions_assign_to(
|
|
||||||
migraphx_instructions_t output, const_migraphx_instructions_t input);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_instructions_create(
|
|
||||||
migraphx_instructions_t* instructions, const const_migraphx_instruction_t* ptr, size_t size);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_modules_destroy(migraphx_modules_t modules);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_modules_assign_to(migraphx_modules_t output,
|
|
||||||
const_migraphx_modules_t input);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_modules_create(migraphx_modules_t* modules,
|
|
||||||
migraphx_module_t* ptr,
|
|
||||||
size_t size);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_module_create(migraphx_module_t* module, char* name);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_module_print(const_migraphx_module_t module);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_module_add_instruction(migraphx_instruction_t* out,
|
|
||||||
migraphx_module_t module,
|
|
||||||
migraphx_operation_t op,
|
|
||||||
migraphx_instructions_t args);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_module_add_instruction_with_mod_args(migraphx_instruction_t* out,
|
|
||||||
migraphx_module_t module,
|
|
||||||
migraphx_operation_t op,
|
|
||||||
migraphx_instructions_t args,
|
|
||||||
migraphx_modules_t module_refs);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_module_add_literal(migraphx_instruction_t* out,
|
|
||||||
migraphx_module_t module,
|
|
||||||
const_migraphx_shape_t shape,
|
|
||||||
const char* buffer);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_module_add_parameter(migraphx_instruction_t* out,
|
|
||||||
migraphx_module_t module,
|
|
||||||
const char* name,
|
|
||||||
const_migraphx_shape_t shape);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_module_add_return(migraphx_instruction_t* out,
|
|
||||||
migraphx_module_t module,
|
|
||||||
migraphx_instructions_t args);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_module_add_allocation(migraphx_instruction_t* out,
|
|
||||||
migraphx_module_t module,
|
|
||||||
const_migraphx_shape_t s);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_program_destroy(migraphx_program_t program);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_program_assign_to(migraphx_program_t output,
|
|
||||||
const_migraphx_program_t input);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_program_create(migraphx_program_t* program);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_program_get_main_module(migraphx_module_t* out,
|
|
||||||
migraphx_program_t program);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_program_create_module(migraphx_module_t* out,
|
|
||||||
migraphx_program_t program,
|
|
||||||
const char* name);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_program_compile(migraphx_program_t program,
|
|
||||||
migraphx_target_t target,
|
|
||||||
migraphx_compile_options_t options);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_program_get_parameter_shapes(
|
|
||||||
migraphx_program_parameter_shapes_t* out, migraphx_program_t program);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_program_get_output_shapes(migraphx_shapes_t* out,
|
|
||||||
migraphx_program_t program);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_program_print(const_migraphx_program_t program);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_program_sort(migraphx_program_t program);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_program_run(migraphx_arguments_t* out,
|
|
||||||
migraphx_program_t program,
|
|
||||||
migraphx_program_parameters_t params);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_program_run_async(migraphx_arguments_t* out,
|
|
||||||
migraphx_program_t program,
|
|
||||||
migraphx_program_parameters_t params,
|
|
||||||
void* s,
|
|
||||||
const char* name);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_program_equal(bool* out,
|
|
||||||
const_migraphx_program_t program,
|
|
||||||
const_migraphx_program_t x);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_program_experimental_get_context(
|
|
||||||
migraphx_context_t* out, const_migraphx_program_t program);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_operation_destroy(migraphx_operation_t operation);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_operation_assign_to(migraphx_operation_t output,
|
|
||||||
const_migraphx_operation_t input);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_operation_create(migraphx_operation_t* operation,
|
|
||||||
const char* name,
|
|
||||||
const char* attributes,
|
|
||||||
...);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_operation_name(char* out,
|
|
||||||
size_t out_size,
|
|
||||||
migraphx_operation_t operation);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_load(migraphx_program_t* out,
|
|
||||||
const char* name,
|
|
||||||
migraphx_file_options_t options);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_save(migraphx_program_t p,
|
|
||||||
const char* name,
|
|
||||||
migraphx_file_options_t options);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_onnx_options_destroy(migraphx_onnx_options_t onnx_options);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_onnx_options_assign_to(
|
|
||||||
migraphx_onnx_options_t output, const_migraphx_onnx_options_t input);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_onnx_options_create(migraphx_onnx_options_t* onnx_options);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_onnx_options_set_input_parameter_shape(
|
|
||||||
migraphx_onnx_options_t onnx_options, const char* name, size_t* dims, size_t dims_size);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_onnx_options_set_dyn_input_parameter_shape(
|
|
||||||
migraphx_onnx_options_t onnx_options, const char* name, migraphx_dynamic_dimensions_t dims);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_onnx_options_set_default_dim_value(migraphx_onnx_options_t onnx_options, size_t value);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_onnx_options_set_default_dyn_dim_value(
|
|
||||||
migraphx_onnx_options_t onnx_options, const_migraphx_dynamic_dimension_t dd);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_onnx_options_set_default_loop_iterations(
|
|
||||||
migraphx_onnx_options_t onnx_options, int64_t value);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_onnx_options_set_limit_loop_iterations(
|
|
||||||
migraphx_onnx_options_t onnx_options, int64_t value);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_onnx_options_set_external_data_path(
|
|
||||||
migraphx_onnx_options_t onnx_options, const char* external_data_path);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_file_options_destroy(migraphx_file_options_t file_options);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_file_options_assign_to(
|
|
||||||
migraphx_file_options_t output, const_migraphx_file_options_t input);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_file_options_create(migraphx_file_options_t* file_options);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_file_options_set_file_format(migraphx_file_options_t file_options, const char* format);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_compile_options_destroy(migraphx_compile_options_t compile_options);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_compile_options_assign_to(
|
|
||||||
migraphx_compile_options_t output, const_migraphx_compile_options_t input);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_compile_options_create(migraphx_compile_options_t* compile_options);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_compile_options_set_offload_copy(migraphx_compile_options_t compile_options, bool value);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_compile_options_set_fast_math(migraphx_compile_options_t compile_options, bool value);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_compile_options_set_exhaustive_tune_flag(
|
|
||||||
migraphx_compile_options_t compile_options, bool value);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_parse_onnx(migraphx_program_t* out,
|
|
||||||
const char* name,
|
|
||||||
migraphx_onnx_options_t options);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_parse_onnx_buffer(migraphx_program_t* out,
|
|
||||||
const void* data,
|
|
||||||
size_t size,
|
|
||||||
migraphx_onnx_options_t options);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_tf_options_destroy(migraphx_tf_options_t tf_options);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_tf_options_assign_to(migraphx_tf_options_t output,
|
|
||||||
const_migraphx_tf_options_t input);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_tf_options_create(migraphx_tf_options_t* tf_options);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_tf_options_set_nhwc(migraphx_tf_options_t tf_options,
|
|
||||||
bool is_nhwc);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_tf_options_set_input_parameter_shape(
|
|
||||||
migraphx_tf_options_t tf_options, const char* name, size_t* dims, size_t dims_size);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_tf_options_set_default_dim_value(migraphx_tf_options_t tf_options, size_t value);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_tf_options_set_output_names(
|
|
||||||
migraphx_tf_options_t tf_options, const char** names, size_t names_size);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_parse_tf(migraphx_program_t* out,
|
|
||||||
const char* name,
|
|
||||||
migraphx_tf_options_t options);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_quantize_op_names_destroy(migraphx_quantize_op_names_t quantize_op_names);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_quantize_op_names_assign_to(
|
|
||||||
migraphx_quantize_op_names_t output, const_migraphx_quantize_op_names_t input);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_quantize_op_names_create(migraphx_quantize_op_names_t* quantize_op_names);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_quantize_op_names_add(migraphx_quantize_op_names_t quantize_op_names, const char* name);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_quantize_fp16_with_op_names(migraphx_program_t prog, migraphx_quantize_op_names_t name);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_quantize_fp16(migraphx_program_t prog);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_quantize_int8_options_destroy(migraphx_quantize_int8_options_t quantize_int8_options);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_quantize_int8_options_assign_to(
|
|
||||||
migraphx_quantize_int8_options_t output, const_migraphx_quantize_int8_options_t input);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_quantize_int8_options_create(migraphx_quantize_int8_options_t* quantize_int8_options);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_quantize_int8_options_add_op_name(
|
|
||||||
migraphx_quantize_int8_options_t quantize_int8_options, const char* name);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_quantize_int8_options_add_calibration_data(
|
|
||||||
migraphx_quantize_int8_options_t quantize_int8_options, migraphx_program_parameters_t data);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_quantize_int8(migraphx_program_t prog,
|
|
||||||
migraphx_target_t target,
|
|
||||||
migraphx_quantize_int8_options_t options);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_quantize_fp8_options_destroy(migraphx_quantize_fp8_options_t quantize_fp8_options);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_quantize_fp8_options_assign_to(
|
|
||||||
migraphx_quantize_fp8_options_t output, const_migraphx_quantize_fp8_options_t input);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_quantize_fp8_options_create(migraphx_quantize_fp8_options_t* quantize_fp8_options);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_quantize_fp8_options_add_calibration_data(
|
|
||||||
migraphx_quantize_fp8_options_t quantize_fp8_options, migraphx_program_parameters_t data);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_quantize_fp8(migraphx_program_t prog,
|
|
||||||
migraphx_target_t target,
|
|
||||||
migraphx_quantize_fp8_options_t options);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_context_finish(const_migraphx_context_t context);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_context_get_queue(void** out,
|
|
||||||
migraphx_context_t context);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_experimental_custom_op_destroy(migraphx_experimental_custom_op_t experimental_custom_op);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_experimental_custom_op_assign_to(
|
|
||||||
migraphx_experimental_custom_op_t output, const_migraphx_experimental_custom_op_t input);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_experimental_custom_op_create(migraphx_experimental_custom_op_t* experimental_custom_op,
|
|
||||||
void* obj,
|
|
||||||
migraphx_experimental_custom_op_copy c,
|
|
||||||
migraphx_experimental_custom_op_delete d,
|
|
||||||
const char* obj_typename,
|
|
||||||
const char* name);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_experimental_custom_op_set_compute(
|
|
||||||
migraphx_experimental_custom_op_t obj, migraphx_experimental_custom_op_compute input);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_experimental_custom_op_set_compute_shape(
|
|
||||||
migraphx_experimental_custom_op_t obj, migraphx_experimental_custom_op_compute_shape input);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_experimental_custom_op_set_output_alias(
|
|
||||||
migraphx_experimental_custom_op_t obj, migraphx_experimental_custom_op_output_alias input);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status migraphx_experimental_custom_op_set_runs_on_offload_target(
|
|
||||||
migraphx_experimental_custom_op_t obj,
|
|
||||||
migraphx_experimental_custom_op_runs_on_offload_target input);
|
|
||||||
|
|
||||||
MIGRAPHX_C_EXPORT migraphx_status
|
|
||||||
migraphx_experimental_custom_op_register(migraphx_experimental_custom_op_t experimental_custom_op);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,510 +0,0 @@
|
|||||||
#####################################################################################
|
|
||||||
# The MIT License (MIT)
|
|
||||||
#
|
|
||||||
# Copyright (c) 2015-2025 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.
|
|
||||||
#####################################################################################
|
|
||||||
import api
|
|
||||||
|
|
||||||
|
|
||||||
def bad_param_error(msg):
|
|
||||||
return 'MIGRAPHX_THROW(migraphx_status_bad_param, "{}")'.format(msg)
|
|
||||||
|
|
||||||
|
|
||||||
api.error_type = 'migraphx_status'
|
|
||||||
api.success_type = 'migraphx_status_success'
|
|
||||||
api.try_wrap = 'migraphx::try_'
|
|
||||||
api.bad_param_error = bad_param_error
|
|
||||||
|
|
||||||
|
|
||||||
@api.cwrap('migraphx::shape::type_t')
|
|
||||||
def shape_type_wrap(p):
|
|
||||||
if p.returns:
|
|
||||||
p.add_param('migraphx_shape_datatype_t *')
|
|
||||||
p.bad_param('${name} == nullptr', 'Null pointer')
|
|
||||||
p.write = ['*${name} = migraphx::to_shape_type(${result})']
|
|
||||||
else:
|
|
||||||
p.add_param('migraphx_shape_datatype_t')
|
|
||||||
p.read = 'migraphx::to_shape_type(${name})'
|
|
||||||
|
|
||||||
|
|
||||||
def auto_handle(*args, **kwargs):
|
|
||||||
def with_handle(f):
|
|
||||||
return api.handle('migraphx_' + f.__name__, 'migraphx::' + f.__name__,
|
|
||||||
*args, **kwargs)(f)
|
|
||||||
|
|
||||||
return with_handle
|
|
||||||
|
|
||||||
|
|
||||||
@api.handle('migraphx_optimals', 'std::set<size_t>')
|
|
||||||
def optimals(h):
|
|
||||||
h.constructor('create',
|
|
||||||
api.params(ptr='const size_t*', size='size_t'),
|
|
||||||
fname='migraphx::make_set<size_t>')
|
|
||||||
|
|
||||||
|
|
||||||
@api.handle('migraphx_dynamic_dimension', 'migraphx::shape::dynamic_dimension')
|
|
||||||
def dynamic_dimension(h):
|
|
||||||
h.constructor('create_min_max', api.params(min='size_t', max='size_t'))
|
|
||||||
h.constructor(
|
|
||||||
'create_min_max_optimals',
|
|
||||||
api.params(min='size_t', max='size_t', optimals='std::set<size_t>'))
|
|
||||||
h.method('is_fixed', returns='bool', const=True)
|
|
||||||
h.method('equal',
|
|
||||||
api.params(x='const migraphx::shape::dynamic_dimension&'),
|
|
||||||
invoke='migraphx::equal($@)',
|
|
||||||
returns='bool',
|
|
||||||
const=True)
|
|
||||||
|
|
||||||
|
|
||||||
@api.handle('migraphx_dynamic_dimensions',
|
|
||||||
'std::vector<migraphx::shape::dynamic_dimension>')
|
|
||||||
def dynamic_dimensions(h):
|
|
||||||
h.constructor(
|
|
||||||
'create',
|
|
||||||
api.params(ptr='const const_migraphx_dynamic_dimension_t*',
|
|
||||||
size='size_t'),
|
|
||||||
fname='migraphx::to_obj_vector<const_migraphx_dynamic_dimension_t>')
|
|
||||||
h.method('size', returns='size_t')
|
|
||||||
h.method('get',
|
|
||||||
api.params(idx='size_t'),
|
|
||||||
fname='at',
|
|
||||||
cpp_name='operator[]',
|
|
||||||
returns='const migraphx::shape::dynamic_dimension&')
|
|
||||||
|
|
||||||
|
|
||||||
@auto_handle()
|
|
||||||
def shape(h):
|
|
||||||
h.constructor(
|
|
||||||
'create',
|
|
||||||
api.params(type='migraphx::shape::type_t',
|
|
||||||
lengths='std::vector<size_t>'))
|
|
||||||
h.constructor(
|
|
||||||
'create_with_strides',
|
|
||||||
api.params(type='migraphx::shape::type_t',
|
|
||||||
lengths='std::vector<size_t>',
|
|
||||||
strides='std::vector<size_t>'))
|
|
||||||
h.constructor('create_scalar', api.params(type='migraphx::shape::type_t'))
|
|
||||||
h.constructor(
|
|
||||||
'create_dynamic',
|
|
||||||
api.params(type='migraphx::shape::type_t',
|
|
||||||
dims='std::vector<migraphx::shape::dynamic_dimension>'))
|
|
||||||
h.method('lengths',
|
|
||||||
fname='lens',
|
|
||||||
returns='const std::vector<size_t>&',
|
|
||||||
const=True)
|
|
||||||
h.method('strides', returns='const std::vector<size_t>&', const=True)
|
|
||||||
h.method('dyn_dims',
|
|
||||||
returns='std::vector<migraphx::shape::dynamic_dimension>',
|
|
||||||
const=True)
|
|
||||||
h.method('type', returns='migraphx::shape::type_t', const=True)
|
|
||||||
h.method('elements', returns='size_t', const=True)
|
|
||||||
h.method('bytes', returns='size_t', const=True)
|
|
||||||
h.method('ndim', returns='size_t', const=True)
|
|
||||||
h.method('equal',
|
|
||||||
api.params(x='const migraphx::shape&'),
|
|
||||||
invoke='migraphx::equal($@)',
|
|
||||||
returns='bool',
|
|
||||||
const=True)
|
|
||||||
h.method('standard', returns='bool', const=True)
|
|
||||||
h.method('dynamic', returns='bool', const=True)
|
|
||||||
h.method('index', api.params(i='size_t'), returns='size_t', const=True)
|
|
||||||
|
|
||||||
|
|
||||||
@auto_handle()
|
|
||||||
def argument(h):
|
|
||||||
h.constructor('create',
|
|
||||||
api.params(shape='const migraphx::shape&', buffer='void*'))
|
|
||||||
h.constructor('create_empty', api.params(shape='const migraphx::shape&'))
|
|
||||||
h.method('shape',
|
|
||||||
fname='get_shape',
|
|
||||||
cpp_name='get_shape',
|
|
||||||
returns='const migraphx::shape&',
|
|
||||||
const=True)
|
|
||||||
h.method('buffer',
|
|
||||||
fname='data',
|
|
||||||
cpp_name='data',
|
|
||||||
returns='char*',
|
|
||||||
const=True)
|
|
||||||
h.method('equal',
|
|
||||||
api.params(x='const migraphx::argument&'),
|
|
||||||
invoke='migraphx::equal($@)',
|
|
||||||
returns='bool',
|
|
||||||
const=True)
|
|
||||||
|
|
||||||
|
|
||||||
api.add_function('migraphx_argument_generate',
|
|
||||||
api.params(s='const migraphx::shape&', seed='size_t'),
|
|
||||||
fname='migraphx::generate_argument',
|
|
||||||
returns='migraphx::argument')
|
|
||||||
|
|
||||||
|
|
||||||
@auto_handle()
|
|
||||||
def target(h):
|
|
||||||
h.constructor('create',
|
|
||||||
api.params(name='const char*'),
|
|
||||||
fname='migraphx::get_target')
|
|
||||||
|
|
||||||
|
|
||||||
@api.handle('migraphx_program_parameter_shapes',
|
|
||||||
'std::unordered_map<std::string, migraphx::shape>')
|
|
||||||
def program_parameter_shapes(h):
|
|
||||||
h.method('size', returns='size_t')
|
|
||||||
h.method('get',
|
|
||||||
api.params(name='const char*'),
|
|
||||||
fname='at',
|
|
||||||
cpp_name='operator[]',
|
|
||||||
returns='const migraphx::shape&')
|
|
||||||
h.method('names',
|
|
||||||
invoke='migraphx::get_names(${program_parameter_shapes})',
|
|
||||||
returns='std::vector<const char*>')
|
|
||||||
|
|
||||||
|
|
||||||
@api.handle('migraphx_program_parameters',
|
|
||||||
'std::unordered_map<std::string, migraphx::argument>')
|
|
||||||
def program_parameters(h):
|
|
||||||
h.constructor('create')
|
|
||||||
h.method('add',
|
|
||||||
api.params(name='const char*',
|
|
||||||
argument='const migraphx::argument&'),
|
|
||||||
invoke='${program_parameters}[${name}] = ${argument}')
|
|
||||||
|
|
||||||
|
|
||||||
@api.handle('migraphx_arguments', 'std::vector<migraphx::argument>')
|
|
||||||
def arguments(h):
|
|
||||||
h.method('size', returns='size_t')
|
|
||||||
h.method('get',
|
|
||||||
api.params(idx='size_t'),
|
|
||||||
fname='at',
|
|
||||||
cpp_name='operator[]',
|
|
||||||
returns='const migraphx::argument&')
|
|
||||||
|
|
||||||
|
|
||||||
@api.handle('migraphx_shapes', 'std::vector<migraphx::shape>')
|
|
||||||
def shapes(h):
|
|
||||||
h.method('size', returns='size_t')
|
|
||||||
h.method('get',
|
|
||||||
api.params(idx='size_t'),
|
|
||||||
fname='at',
|
|
||||||
cpp_name='operator[]',
|
|
||||||
returns='const migraphx::shape&')
|
|
||||||
|
|
||||||
|
|
||||||
@api.handle('migraphx_instruction', 'migraphx::instruction_ref')
|
|
||||||
def instruction(h):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
@api.handle('migraphx_instructions', 'std::vector<migraphx::instruction_ref>')
|
|
||||||
def instructions(h):
|
|
||||||
h.constructor(
|
|
||||||
'create',
|
|
||||||
api.params(ptr='const const_migraphx_instruction_t*', size='size_t'),
|
|
||||||
fname='migraphx::to_obj_vector<const_migraphx_instruction_t>')
|
|
||||||
|
|
||||||
|
|
||||||
@api.handle('migraphx_modules', 'std::vector<migraphx::module*>')
|
|
||||||
def modules(h):
|
|
||||||
h.constructor('create',
|
|
||||||
api.params(ptr='migraphx_module_t*', size='size_t'),
|
|
||||||
fname='migraphx::to_objptr_vector<migraphx::module*>')
|
|
||||||
|
|
||||||
|
|
||||||
@auto_handle(ref=True)
|
|
||||||
def module(h):
|
|
||||||
h.constructor('create', api.params(name='std::string'))
|
|
||||||
h.method('print', invoke='migraphx::print_module($@)', const=True)
|
|
||||||
h.method('add_instruction',
|
|
||||||
api.params(op='migraphx::operation',
|
|
||||||
args='std::vector<migraphx::instruction_ref>'),
|
|
||||||
returns='migraphx::instruction_ref')
|
|
||||||
h.method('add_instruction_with_mod_args',
|
|
||||||
api.params(op='migraphx::operation',
|
|
||||||
args='std::vector<migraphx::instruction_ref>',
|
|
||||||
module_refs='std::vector<migraphx::module*>'),
|
|
||||||
fname='add_instruction',
|
|
||||||
returns='migraphx::instruction_ref')
|
|
||||||
h.method('add_literal',
|
|
||||||
api.params(shape='const migraphx::shape&', buffer='const char*'),
|
|
||||||
returns='migraphx::instruction_ref')
|
|
||||||
h.method('add_parameter',
|
|
||||||
api.params(name='const char*', shape='const migraphx::shape&'),
|
|
||||||
returns='migraphx::instruction_ref')
|
|
||||||
h.method('add_return',
|
|
||||||
api.params(args='std::vector<migraphx::instruction_ref>'),
|
|
||||||
returns='migraphx::instruction_ref')
|
|
||||||
h.method('add_allocation',
|
|
||||||
api.params(s='const migraphx::shape&'),
|
|
||||||
invoke='migraphx::add_allocation($@)',
|
|
||||||
returns='migraphx::instruction_ref')
|
|
||||||
|
|
||||||
|
|
||||||
@auto_handle()
|
|
||||||
def program(h):
|
|
||||||
h.constructor('create')
|
|
||||||
h.method('get_main_module', returns='migraphx::module*')
|
|
||||||
h.method('create_module',
|
|
||||||
api.params(name='const char*'),
|
|
||||||
returns='migraphx::module*')
|
|
||||||
h.method(
|
|
||||||
'compile',
|
|
||||||
api.params(target='migraphx::target',
|
|
||||||
options='migraphx::compile_options'))
|
|
||||||
h.method('get_parameter_shapes',
|
|
||||||
returns='std::unordered_map<std::string, migraphx::shape>')
|
|
||||||
h.method('get_output_shapes',
|
|
||||||
invoke='migraphx::get_output_shapes($@)',
|
|
||||||
returns='std::vector<migraphx::shape>')
|
|
||||||
h.method('print', invoke='migraphx::print_program($@)', const=True)
|
|
||||||
h.method('sort')
|
|
||||||
h.method('run',
|
|
||||||
api.params(
|
|
||||||
params='std::unordered_map<std::string, migraphx::argument>'),
|
|
||||||
invoke='migraphx::run($@)',
|
|
||||||
returns='std::vector<migraphx::argument>')
|
|
||||||
h.method('run_async',
|
|
||||||
api.params(
|
|
||||||
params='std::unordered_map<std::string, migraphx::argument>',
|
|
||||||
s='void*',
|
|
||||||
name='const char *'),
|
|
||||||
invoke='migraphx::run_async($@)',
|
|
||||||
returns='std::vector<migraphx::argument>')
|
|
||||||
h.method('equal',
|
|
||||||
api.params(x='const migraphx::program&'),
|
|
||||||
invoke='migraphx::equal($@)',
|
|
||||||
returns='bool',
|
|
||||||
const=True)
|
|
||||||
h.method('experimental_get_context',
|
|
||||||
invoke='migraphx::get_context($@)',
|
|
||||||
const=True,
|
|
||||||
returns='migraphx::context')
|
|
||||||
|
|
||||||
|
|
||||||
@auto_handle()
|
|
||||||
def operation(h):
|
|
||||||
h.constructor('create',
|
|
||||||
api.params(name='const char*',
|
|
||||||
attributes='const char*',
|
|
||||||
vlist='...'),
|
|
||||||
fname='migraphx::create_op')
|
|
||||||
h.method('name', returns='std::string')
|
|
||||||
|
|
||||||
|
|
||||||
api.add_function('migraphx_load',
|
|
||||||
api.params(name='const char*',
|
|
||||||
options='migraphx::file_options'),
|
|
||||||
fname='migraphx::load',
|
|
||||||
returns='migraphx::program')
|
|
||||||
|
|
||||||
api.add_function('migraphx_save',
|
|
||||||
api.params(p='migraphx::program&',
|
|
||||||
name='const char*',
|
|
||||||
options='migraphx::file_options'),
|
|
||||||
fname='migraphx::save')
|
|
||||||
|
|
||||||
|
|
||||||
@auto_handle()
|
|
||||||
def onnx_options(h):
|
|
||||||
h.constructor('create')
|
|
||||||
h.method(
|
|
||||||
'set_input_parameter_shape',
|
|
||||||
api.params(name='const char*', dims='std::vector<size_t>'),
|
|
||||||
invoke='migraphx::set_input_parameter_shape($@)',
|
|
||||||
)
|
|
||||||
h.method(
|
|
||||||
'set_dyn_input_parameter_shape',
|
|
||||||
api.params(name='const char*',
|
|
||||||
dims='std::vector<migraphx::shape::dynamic_dimension>'),
|
|
||||||
invoke='migraphx::set_dyn_input_parameter_shape($@)',
|
|
||||||
)
|
|
||||||
h.method(
|
|
||||||
'set_default_dim_value',
|
|
||||||
api.params(value='size_t'),
|
|
||||||
invoke='migraphx::set_default_dim_value($@)',
|
|
||||||
)
|
|
||||||
h.method(
|
|
||||||
'set_default_dyn_dim_value',
|
|
||||||
api.params(dd='const migraphx::shape::dynamic_dimension&'),
|
|
||||||
invoke='migraphx::set_default_dyn_dim_value($@)',
|
|
||||||
)
|
|
||||||
h.method(
|
|
||||||
'set_default_loop_iterations',
|
|
||||||
api.params(value='int64_t'),
|
|
||||||
invoke='migraphx::set_default_loop_iterations($@)',
|
|
||||||
)
|
|
||||||
h.method(
|
|
||||||
'set_limit_loop_iterations',
|
|
||||||
api.params(value='int64_t'),
|
|
||||||
invoke='migraphx::set_limit_loop_iterations($@)',
|
|
||||||
)
|
|
||||||
h.method(
|
|
||||||
'set_external_data_path',
|
|
||||||
api.params(external_data_path='const char*'),
|
|
||||||
invoke='migraphx::set_external_data_path($@)',
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@auto_handle()
|
|
||||||
def file_options(h):
|
|
||||||
h.constructor('create')
|
|
||||||
h.method('set_file_format',
|
|
||||||
api.params(format='const char*'),
|
|
||||||
invoke='migraphx::set_file_format($@)')
|
|
||||||
|
|
||||||
|
|
||||||
@auto_handle()
|
|
||||||
def compile_options(h):
|
|
||||||
h.constructor('create')
|
|
||||||
h.method('set_offload_copy',
|
|
||||||
api.params(value='bool'),
|
|
||||||
invoke='migraphx::set_offload_copy($@)')
|
|
||||||
h.method('set_fast_math',
|
|
||||||
api.params(value='bool'),
|
|
||||||
invoke='migraphx::set_fast_math($@)')
|
|
||||||
h.method('set_exhaustive_tune_flag',
|
|
||||||
api.params(value='bool'),
|
|
||||||
invoke='migraphx::set_exhaustive_tune_flag($@)')
|
|
||||||
|
|
||||||
|
|
||||||
api.add_function('migraphx_parse_onnx',
|
|
||||||
api.params(name='const char*',
|
|
||||||
options='migraphx::onnx_options'),
|
|
||||||
fname='migraphx::parse_onnx',
|
|
||||||
returns='migraphx::program')
|
|
||||||
|
|
||||||
api.add_function('migraphx_parse_onnx_buffer',
|
|
||||||
api.params(data='const void*',
|
|
||||||
size='size_t',
|
|
||||||
options='migraphx::onnx_options'),
|
|
||||||
fname='migraphx::parse_onnx_buffer',
|
|
||||||
returns='migraphx::program')
|
|
||||||
|
|
||||||
|
|
||||||
@auto_handle()
|
|
||||||
def tf_options(h):
|
|
||||||
h.constructor('create')
|
|
||||||
h.method(
|
|
||||||
'set_nhwc',
|
|
||||||
api.params(is_nhwc='bool'),
|
|
||||||
invoke='migraphx::set_nhwc($@)',
|
|
||||||
)
|
|
||||||
h.method(
|
|
||||||
'set_input_parameter_shape',
|
|
||||||
api.params(name='const char*', dims='std::vector<size_t>'),
|
|
||||||
invoke='migraphx::set_input_parameter_shape($@)',
|
|
||||||
)
|
|
||||||
h.method(
|
|
||||||
'set_default_dim_value',
|
|
||||||
api.params(value='size_t'),
|
|
||||||
invoke='migraphx::set_default_dim_value($@)',
|
|
||||||
)
|
|
||||||
h.method(
|
|
||||||
'set_output_names',
|
|
||||||
api.params(names='std::vector<const char*>'),
|
|
||||||
invoke='migraphx::set_output_names($@)',
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
api.add_function('migraphx_parse_tf',
|
|
||||||
api.params(name='const char*',
|
|
||||||
options='migraphx::tf_options'),
|
|
||||||
fname='migraphx::parse_tf',
|
|
||||||
returns='migraphx::program')
|
|
||||||
|
|
||||||
|
|
||||||
@api.handle('migraphx_quantize_op_names', 'std::vector<std::string>')
|
|
||||||
def quantize_op_names(h):
|
|
||||||
h.constructor('create')
|
|
||||||
h.method('add', api.params(name='const char*'), fname='push_back')
|
|
||||||
|
|
||||||
|
|
||||||
api.add_function('migraphx_quantize_fp16_with_op_names',
|
|
||||||
api.params(prog='migraphx::program&',
|
|
||||||
name='std::vector<std::string>&'),
|
|
||||||
fname='migraphx::quantize_fp16_with_op_names')
|
|
||||||
|
|
||||||
api.add_function('migraphx_quantize_fp16',
|
|
||||||
api.params(prog='migraphx::program&'),
|
|
||||||
fname='migraphx::quantize_fp16')
|
|
||||||
|
|
||||||
|
|
||||||
@auto_handle()
|
|
||||||
def quantize_int8_options(h):
|
|
||||||
h.constructor('create')
|
|
||||||
h.method(
|
|
||||||
'add_op_name',
|
|
||||||
api.params(name='const char*'),
|
|
||||||
invoke='migraphx::add_op_name($@)',
|
|
||||||
)
|
|
||||||
h.method(
|
|
||||||
'add_calibration_data',
|
|
||||||
api.params(data='std::unordered_map<std::string, migraphx::argument>'),
|
|
||||||
invoke='migraphx::add_calibration_data($@)',
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
api.add_function('migraphx_quantize_int8',
|
|
||||||
api.params(prog='migraphx::program&',
|
|
||||||
target='migraphx::target',
|
|
||||||
options='migraphx::quantize_int8_options'),
|
|
||||||
fname='migraphx::quantize_int8_wrap')
|
|
||||||
|
|
||||||
|
|
||||||
@auto_handle()
|
|
||||||
def quantize_fp8_options(h):
|
|
||||||
h.constructor('create')
|
|
||||||
h.method(
|
|
||||||
'add_calibration_data',
|
|
||||||
api.params(data='std::unordered_map<std::string, migraphx::argument>'),
|
|
||||||
invoke='migraphx::add_calibration_data($@)',
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
api.add_function('migraphx_quantize_fp8',
|
|
||||||
api.params(prog='migraphx::program&',
|
|
||||||
target='migraphx::target',
|
|
||||||
options='migraphx::quantize_fp8_options'),
|
|
||||||
fname='migraphx::quantize_fp8_wrap')
|
|
||||||
|
|
||||||
|
|
||||||
@auto_handle(ref=True)
|
|
||||||
def context(h):
|
|
||||||
h.method('finish', const=True)
|
|
||||||
h.method('get_queue', returns='void*', fname='get_queue().unsafe_get')
|
|
||||||
|
|
||||||
|
|
||||||
@api.interface('migraphx_experimental_custom_op',
|
|
||||||
'migraphx::experimental_custom_op')
|
|
||||||
def experimental_custom_op(h):
|
|
||||||
h.constructor('create',
|
|
||||||
api.params(obj_typename='const char*', name='const char*'))
|
|
||||||
h.virtual('compute',
|
|
||||||
api.params(ctx='migraphx::context',
|
|
||||||
output='migraphx::shape',
|
|
||||||
inputs='std::vector<migraphx::argument>'),
|
|
||||||
returns='migraphx::argument')
|
|
||||||
h.virtual('compute_shape',
|
|
||||||
api.params(inputs='std::vector<migraphx::shape>'),
|
|
||||||
returns='migraphx::shape')
|
|
||||||
h.virtual('output_alias',
|
|
||||||
api.params(inputs='std::vector<migraphx::shape>'),
|
|
||||||
returns='std::vector<size_t>')
|
|
||||||
h.virtual('runs_on_offload_target', returns='bool')
|
|
||||||
h.method('register', invoke='migraphx::register_custom_op($@)')
|
|
||||||
@ -1,79 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2025 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.
|
|
||||||
*/
|
|
||||||
#include <migraphx/instruction.hpp>
|
|
||||||
#include <migraphx/make_op.hpp>
|
|
||||||
#include <migraphx/common.hpp>
|
|
||||||
#include <migraphx/apply_alpha_beta.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
instruction_ref insert_apply_alpha_beta(module& m,
|
|
||||||
instruction_ref pos,
|
|
||||||
const std::vector<instruction_ref>& args,
|
|
||||||
const operation& op,
|
|
||||||
const literal& alpha,
|
|
||||||
const literal& beta)
|
|
||||||
{
|
|
||||||
auto a = args[0];
|
|
||||||
auto b = args[1];
|
|
||||||
auto input_type = a->get_shape().type();
|
|
||||||
if(not float_equal(alpha.at<float>(0), 1.0))
|
|
||||||
{
|
|
||||||
auto alpha_literal = m.add_literal(alpha);
|
|
||||||
a = insert_common_op(m, pos, migraphx::make_op("mul"), {alpha_literal, a});
|
|
||||||
if(a->get_shape().type() != input_type)
|
|
||||||
{
|
|
||||||
a = m.insert_instruction(pos, make_op("convert", {{"target_type", input_type}}), a);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
auto op_res = m.insert_instruction(pos, op, a, b);
|
|
||||||
if(args.size() == 3)
|
|
||||||
{
|
|
||||||
if(not float_equal(beta.at<float>(0), 0.0) and args[2]->get_shape().elements() > 0)
|
|
||||||
{
|
|
||||||
auto out_lens = op_res->get_shape().lens();
|
|
||||||
auto c = args[2];
|
|
||||||
auto c_lens = c->get_shape().lens();
|
|
||||||
input_type = c->get_shape().type();
|
|
||||||
if(out_lens != c_lens)
|
|
||||||
{
|
|
||||||
c = m.insert_instruction(
|
|
||||||
pos, migraphx::make_op("multibroadcast", {{"out_lens", out_lens}}), args[2]);
|
|
||||||
}
|
|
||||||
auto beta_literal = m.add_literal(beta);
|
|
||||||
auto beta_c = insert_common_op(m, pos, migraphx::make_op("mul"), {c, beta_literal});
|
|
||||||
if(beta_c->get_shape().type() != input_type)
|
|
||||||
{
|
|
||||||
beta_c = m.insert_instruction(
|
|
||||||
pos, migraphx::make_op("convert", {{"target_type", input_type}}), beta_c);
|
|
||||||
}
|
|
||||||
return m.insert_instruction(pos, migraphx::make_op("add"), op_res, beta_c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return op_res;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,210 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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.
|
|
||||||
*/
|
|
||||||
#include <migraphx/argument.hpp>
|
|
||||||
#include <migraphx/functional.hpp>
|
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
argument::argument(const shape& s) : m_shape(s)
|
|
||||||
{
|
|
||||||
auto buffer = make_shared_array<char>(s.bytes());
|
|
||||||
assign_buffer({[=]() mutable { return buffer.get(); }});
|
|
||||||
}
|
|
||||||
|
|
||||||
argument::argument(shape s, std::nullptr_t)
|
|
||||||
: m_shape(std::move(s)), m_data({[] { return nullptr; }})
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
argument::argument(const shape& s, const argument::data_t& d) : m_shape(s), m_data(d) {}
|
|
||||||
|
|
||||||
void argument::assign_buffer(std::function<char*()> d)
|
|
||||||
{
|
|
||||||
const shape& s = m_shape;
|
|
||||||
if(s.type() != shape::tuple_type)
|
|
||||||
{
|
|
||||||
m_data = {std::move(d)};
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Collect all shapes
|
|
||||||
std::unordered_map<std::size_t, shape> shapes;
|
|
||||||
{
|
|
||||||
std::size_t i = 0;
|
|
||||||
fix([&](auto self, auto ss) {
|
|
||||||
if(ss.sub_shapes().empty())
|
|
||||||
{
|
|
||||||
shapes[i] = ss;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for(auto&& child : ss.sub_shapes())
|
|
||||||
self(child);
|
|
||||||
}
|
|
||||||
})(s);
|
|
||||||
}
|
|
||||||
// Sort by type size
|
|
||||||
std::vector<std::size_t> order(shapes.size());
|
|
||||||
std::iota(order.begin(), order.end(), 0);
|
|
||||||
std::sort(order.begin(), order.end(), by(std::greater<>{}, [&](auto i) {
|
|
||||||
return shapes[i].type_size();
|
|
||||||
}));
|
|
||||||
// Compute offsets
|
|
||||||
std::unordered_map<std::size_t, std::size_t> offsets;
|
|
||||||
std::size_t offset = 0;
|
|
||||||
for(auto i : order)
|
|
||||||
{
|
|
||||||
offsets[i] = offset;
|
|
||||||
offset += shapes[i].bytes();
|
|
||||||
}
|
|
||||||
assert(offset == s.bytes());
|
|
||||||
|
|
||||||
std::size_t i = 0;
|
|
||||||
m_data = fix<data_t>([&](auto self, auto ss) {
|
|
||||||
data_t result;
|
|
||||||
if(ss.sub_shapes().empty())
|
|
||||||
{
|
|
||||||
auto n = offsets[i];
|
|
||||||
result = {[d, n]() mutable { return d() + n; }};
|
|
||||||
i++;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
std::vector<data_t> subs;
|
|
||||||
std::transform(ss.sub_shapes().begin(),
|
|
||||||
ss.sub_shapes().end(),
|
|
||||||
std::back_inserter(subs),
|
|
||||||
[&](auto child) { return self(child); });
|
|
||||||
result.sub = subs;
|
|
||||||
return result;
|
|
||||||
})(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<argument> flatten(const std::vector<argument>& args)
|
|
||||||
{
|
|
||||||
std::vector<argument> result;
|
|
||||||
for(const auto& arg : args)
|
|
||||||
{
|
|
||||||
if(arg.get_shape().type() == shape::tuple_type)
|
|
||||||
{
|
|
||||||
auto subs = flatten(arg.get_sub_objects());
|
|
||||||
result.insert(result.end(), subs.begin(), subs.end());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result.push_back(arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<shape> to_shapes(const std::vector<argument>& args)
|
|
||||||
{
|
|
||||||
std::vector<shape> shapes;
|
|
||||||
std::transform(args.begin(), args.end(), std::back_inserter(shapes), [](auto&& arg) {
|
|
||||||
return arg.get_shape();
|
|
||||||
});
|
|
||||||
return shapes;
|
|
||||||
}
|
|
||||||
|
|
||||||
argument::argument(const std::vector<argument>& args)
|
|
||||||
: m_shape(to_shapes(args)), m_data(data_t::from_args(args))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
char* argument::data() const
|
|
||||||
{
|
|
||||||
assert(m_shape.type() != shape::tuple_type);
|
|
||||||
assert(not this->empty());
|
|
||||||
return m_data.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool argument::empty() const { return not m_data.get and m_data.sub.empty(); }
|
|
||||||
|
|
||||||
const shape& argument::get_shape() const { return this->m_shape; }
|
|
||||||
|
|
||||||
argument argument::reshape(const shape& s) const
|
|
||||||
{
|
|
||||||
assert(s.element_space() <= this->get_shape().element_space());
|
|
||||||
return {s, this->m_data};
|
|
||||||
}
|
|
||||||
|
|
||||||
argument::data_t argument::data_t::share() const
|
|
||||||
{
|
|
||||||
data_t result;
|
|
||||||
if(this->get)
|
|
||||||
{
|
|
||||||
auto self = std::make_shared<data_t>(*this);
|
|
||||||
result.get = [self]() mutable { return self->get(); };
|
|
||||||
}
|
|
||||||
std::transform(sub.begin(), sub.end(), std::back_inserter(result.sub), [](const auto& d) {
|
|
||||||
return d.share();
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
argument::data_t argument::data_t::from_args(const std::vector<argument>& args)
|
|
||||||
{
|
|
||||||
data_t result;
|
|
||||||
std::transform(args.begin(), args.end(), std::back_inserter(result.sub), [](auto&& arg) {
|
|
||||||
return arg.m_data;
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
argument argument::copy() const
|
|
||||||
{
|
|
||||||
argument result{this->get_shape()};
|
|
||||||
auto* src = this->data();
|
|
||||||
std::copy(src, src + this->get_shape().bytes(), result.data());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
argument argument::share() const { return {m_shape, m_data.share()}; }
|
|
||||||
|
|
||||||
std::vector<argument> argument::get_sub_objects() const
|
|
||||||
{
|
|
||||||
std::vector<argument> result;
|
|
||||||
assert(m_shape.sub_shapes().size() == m_data.sub.size());
|
|
||||||
std::transform(m_shape.sub_shapes().begin(),
|
|
||||||
m_shape.sub_shapes().end(),
|
|
||||||
m_data.sub.begin(),
|
|
||||||
std::back_inserter(result),
|
|
||||||
[](auto&& s, auto&& d) {
|
|
||||||
return argument{s, d};
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
argument argument::element(std::size_t i) const
|
|
||||||
{
|
|
||||||
assert(this->get_shape().sub_shapes().empty());
|
|
||||||
auto idx = this->get_shape().index(i);
|
|
||||||
auto offset = this->get_shape().type_size() * idx;
|
|
||||||
return argument{shape{this->get_shape().type()}, this->data() + offset};
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,80 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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.
|
|
||||||
*/
|
|
||||||
#include <migraphx/auto_contiguous.hpp>
|
|
||||||
#include <migraphx/program.hpp>
|
|
||||||
#include <migraphx/instruction.hpp>
|
|
||||||
#include <migraphx/make_op.hpp>
|
|
||||||
#include <migraphx/iterator_for.hpp>
|
|
||||||
#include <migraphx/ranges.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
void auto_contiguous::apply(module& m) const
|
|
||||||
{
|
|
||||||
std::string key = "require_std_shape";
|
|
||||||
for(auto ins : reverse_iterator_for(m))
|
|
||||||
{
|
|
||||||
auto&& attr = ins->get_operator().attributes();
|
|
||||||
if((attr.get(key, false)))
|
|
||||||
{
|
|
||||||
auto args = ins->inputs();
|
|
||||||
auto new_args = args;
|
|
||||||
std::transform(args.begin(), args.end(), new_args.begin(), [&](auto in) {
|
|
||||||
if(in->name() == "contiguous")
|
|
||||||
{
|
|
||||||
return in;
|
|
||||||
}
|
|
||||||
return m.insert_instruction(ins, make_op("contiguous"), in);
|
|
||||||
});
|
|
||||||
|
|
||||||
if(new_args != args)
|
|
||||||
{
|
|
||||||
m.replace_instruction(ins, ins->get_operator(), new_args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto last = std::prev(m.end());
|
|
||||||
for(auto ins : iterator_for(m))
|
|
||||||
{
|
|
||||||
if(contains({"layout", "@return"}, ins->name()))
|
|
||||||
continue;
|
|
||||||
// for last instruction that is NOT a return
|
|
||||||
if(ins->outputs().empty() and ins != last)
|
|
||||||
continue;
|
|
||||||
shape s = ins->get_shape();
|
|
||||||
// If s is not standard layout or has out of sequence strides, insert "contiguous" op
|
|
||||||
// to make a standard shape
|
|
||||||
if(not s.dynamic() and (not s.standard() or s.normalize_standard() != s) and
|
|
||||||
s.elements() > 1)
|
|
||||||
{
|
|
||||||
auto c = m.insert_instruction(std::next(ins), make_op("contiguous"), ins);
|
|
||||||
m.replace_instruction(ins, c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,82 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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.
|
|
||||||
*/
|
|
||||||
#include <migraphx/autocast_fp8.hpp>
|
|
||||||
#include <migraphx/instruction.hpp>
|
|
||||||
#include <migraphx/iterator_for.hpp>
|
|
||||||
#include <migraphx/make_op.hpp>
|
|
||||||
#include <migraphx/program.hpp>
|
|
||||||
#include <migraphx/ranges.hpp>
|
|
||||||
#include <migraphx/fp8_types.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
void autocast_fp8_pass::apply(module& m) const
|
|
||||||
{
|
|
||||||
std::vector<instruction_ref> remove_parameters;
|
|
||||||
for(auto ins : iterator_for(m))
|
|
||||||
{
|
|
||||||
const auto& ins_name = ins->name();
|
|
||||||
if(ins_name == "@param" and contains(fp8_types{}.get(), ins->get_shape().type()))
|
|
||||||
{
|
|
||||||
shape::type_t fp8_type = ins->get_shape().type();
|
|
||||||
migraphx::shape new_shape = ins->get_shape().with_type(target_type);
|
|
||||||
std::string param_name = ins->get_operator().to_value()["parameter"].to<std::string>();
|
|
||||||
m.rename_parameter(ins, param_name + "_old");
|
|
||||||
auto new_param = m.add_parameter(param_name, new_shape);
|
|
||||||
auto new_ins = m.insert_instruction(
|
|
||||||
ins,
|
|
||||||
migraphx::make_op("convert", {{"target_type", migraphx::to_value(fp8_type)}}),
|
|
||||||
new_param);
|
|
||||||
m.replace_instruction(ins, new_ins);
|
|
||||||
remove_parameters.push_back(ins);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ins_name == "@return")
|
|
||||||
{
|
|
||||||
std::vector<instruction_ref> inputs = ins->inputs();
|
|
||||||
std::vector<instruction_ref> new_inputs;
|
|
||||||
std::transform(
|
|
||||||
inputs.begin(), inputs.end(), std::back_inserter(new_inputs), [&](auto i) {
|
|
||||||
if(contains(fp8_types{}.get(), i->get_shape().type()))
|
|
||||||
{
|
|
||||||
return m.insert_instruction(
|
|
||||||
ins,
|
|
||||||
migraphx::make_op("convert",
|
|
||||||
{{"target_type", migraphx::to_value(target_type)}}),
|
|
||||||
i);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return i;
|
|
||||||
});
|
|
||||||
m.replace_return({new_inputs});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Remove unused parameters with fp8 type
|
|
||||||
for(const auto& i : remove_parameters)
|
|
||||||
m.remove_instruction(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,81 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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.
|
|
||||||
*/
|
|
||||||
#include <migraphx/base64.hpp>
|
|
||||||
#include <vector>
|
|
||||||
#include <array>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
using byte = unsigned char;
|
|
||||||
|
|
||||||
std::array<char, 64> constexpr b64_chars{
|
|
||||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
|
||||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
|
|
||||||
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
|
||||||
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};
|
|
||||||
|
|
||||||
/// base64 encoder snippet altered from https://stackoverflow.com/a/37109258
|
|
||||||
std::string encode(const std::vector<byte>& buf)
|
|
||||||
{
|
|
||||||
std::size_t len = buf.size();
|
|
||||||
std::vector<byte> res_vec((len + 2) / 3 * 4, '=');
|
|
||||||
std::size_t j = 0;
|
|
||||||
std::size_t remaining = len % 3;
|
|
||||||
const size_t last = len - remaining;
|
|
||||||
|
|
||||||
for(size_t i = 0; i < last; i += 3)
|
|
||||||
{
|
|
||||||
std::size_t n = static_cast<std::size_t>(buf.at(i)) << 16u |
|
|
||||||
static_cast<std::size_t>(buf.at(i + 1)) << 8u |
|
|
||||||
static_cast<std::size_t>(buf.at(i + 2));
|
|
||||||
res_vec.at(j++) = b64_chars.at(n >> 18u);
|
|
||||||
res_vec.at(j++) = b64_chars.at(n >> 12u & 0x3Fu);
|
|
||||||
res_vec.at(j++) = b64_chars.at(n >> 6u & 0x3Fu);
|
|
||||||
res_vec.at(j++) = b64_chars.at(n & 0x3Fu);
|
|
||||||
}
|
|
||||||
// Set padding
|
|
||||||
if(remaining != 0)
|
|
||||||
{
|
|
||||||
std::size_t n = --remaining == 0 ? static_cast<std::size_t>(buf.at(last))
|
|
||||||
: static_cast<std::size_t>(buf.at(last)) << 8u |
|
|
||||||
static_cast<std::size_t>(buf.at(last + 1));
|
|
||||||
res_vec.at(j++) = b64_chars.at(remaining == 0 ? n >> 2u : n >> 10u & 0x3Fu);
|
|
||||||
res_vec.at(j++) = b64_chars.at(remaining == 0 ? n << 4u & 0x3Fu : n >> 4u & 0x03Fu);
|
|
||||||
res_vec.at(j++) = remaining == 0 ? '=' : b64_chars.at(n << 2u & 0x3Fu);
|
|
||||||
}
|
|
||||||
return {res_vec.begin(), res_vec.end()};
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
std::string base64_encode(const std::string& str)
|
|
||||||
{
|
|
||||||
return encode(std::vector<byte>(str.begin(), str.end()));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,254 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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.
|
|
||||||
*/
|
|
||||||
#include <migraphx/common.hpp>
|
|
||||||
#include <migraphx/module.hpp>
|
|
||||||
#include <migraphx/make_op.hpp>
|
|
||||||
#include <migraphx/algorithm.hpp>
|
|
||||||
#include <migraphx/stringutils.hpp>
|
|
||||||
#include <migraphx/instruction.hpp>
|
|
||||||
#include <migraphx/ranges.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
std::vector<std::size_t> compute_broadcasted_lens(std::vector<std::size_t> s0,
|
|
||||||
std::vector<std::size_t> s1)
|
|
||||||
{
|
|
||||||
if(s0 == s1)
|
|
||||||
return s0;
|
|
||||||
if(s0.size() > s1.size())
|
|
||||||
s0.swap(s1);
|
|
||||||
std::vector<std::size_t> out_lens(s1);
|
|
||||||
auto offset = s1.size() - s0.size();
|
|
||||||
std::transform(
|
|
||||||
s0.begin(), s0.end(), s1.begin() + offset, out_lens.begin() + offset, [&](auto a, auto b) {
|
|
||||||
if(a != b and a != 1 and b != 1)
|
|
||||||
{
|
|
||||||
MIGRAPHX_THROW("COMPUTE_BROADCASTLEN: shape {" + migraphx::to_string_range(s0) +
|
|
||||||
"} and {" + migraphx::to_string_range(s1) + "} mismatch!");
|
|
||||||
}
|
|
||||||
return std::max(a, b);
|
|
||||||
});
|
|
||||||
return out_lens;
|
|
||||||
}
|
|
||||||
std::vector<shape::dynamic_dimension>
|
|
||||||
compute_broadcasted_dyn_dims(std::vector<shape::dynamic_dimension> dds0,
|
|
||||||
std::vector<shape::dynamic_dimension> dds1)
|
|
||||||
{
|
|
||||||
if(dds0.size() > dds1.size())
|
|
||||||
{
|
|
||||||
std::swap(dds0, dds1);
|
|
||||||
}
|
|
||||||
auto offset = dds1.size() - dds0.size();
|
|
||||||
std::vector<shape::dynamic_dimension> out_dims(dds1);
|
|
||||||
std::transform(dds0.cbegin(),
|
|
||||||
dds0.cend(),
|
|
||||||
dds1.cbegin() + offset,
|
|
||||||
out_dims.begin() + offset,
|
|
||||||
[&](auto a, auto b) {
|
|
||||||
if(a == b or b == 1)
|
|
||||||
{
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
else if(a == 1)
|
|
||||||
{
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto intersect = a.intersection(b);
|
|
||||||
if(intersect.has_value())
|
|
||||||
{
|
|
||||||
return intersect.value();
|
|
||||||
}
|
|
||||||
MIGRAPHX_THROW("COMPUTE_BROADCASTED_DYN_DIMS: dynamic shapes {" +
|
|
||||||
migraphx::to_string_range(dds0) + "} and {" +
|
|
||||||
migraphx::to_string_range(dds1) + "} mismatch!");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return out_dims;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<shape::dynamic_dimension> compute_broadcasted_dyn_dims(shape s0, shape s1)
|
|
||||||
{
|
|
||||||
// change both shapes to dynamic_dimension representation
|
|
||||||
s0 = s0.to_dynamic();
|
|
||||||
s1 = s1.to_dynamic();
|
|
||||||
return compute_broadcasted_dyn_dims(s0.dyn_dims(), s1.dyn_dims());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<shape::dynamic_dimension> compute_common_dyn_dims(const std::vector<shape>& shapes)
|
|
||||||
{
|
|
||||||
auto ret_shape = shapes.at(0);
|
|
||||||
std::for_each(shapes.cbegin() + 1, shapes.cend(), [&](auto s) {
|
|
||||||
ret_shape = shape{ret_shape.type(), compute_broadcasted_dyn_dims(ret_shape, s)};
|
|
||||||
});
|
|
||||||
return ret_shape.dyn_dims();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::size_t> compute_common_lens(const std::vector<shape>& shapes)
|
|
||||||
{
|
|
||||||
assert(not shapes.empty());
|
|
||||||
assert(
|
|
||||||
std::none_of(shapes.cbegin(), shapes.cend(), [](auto shape) { return shape.dynamic(); }));
|
|
||||||
return transform_accumulate(shapes.begin() + 1,
|
|
||||||
shapes.end(),
|
|
||||||
shapes.front().lens(),
|
|
||||||
&compute_broadcasted_lens,
|
|
||||||
[](auto s) { return s.lens(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
shape::type_t compute_common_type(shape::type_t t1, shape::type_t t2)
|
|
||||||
{
|
|
||||||
if(t1 == t2)
|
|
||||||
return t1;
|
|
||||||
shape::type_t result;
|
|
||||||
shape::visit(t1, [&](auto x) {
|
|
||||||
shape::visit(t2, [&](auto y) {
|
|
||||||
// Workaround broken warning on gcc 5
|
|
||||||
(void)x;
|
|
||||||
(void)y;
|
|
||||||
using type = std::common_type_t<decltype(x()), decltype(y())>;
|
|
||||||
result = shape::get_type<type>{};
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
shape::type_t compute_common_types(const std::vector<shape>& shapes)
|
|
||||||
{
|
|
||||||
assert(not shapes.empty());
|
|
||||||
return transform_accumulate(
|
|
||||||
shapes.begin() + 1, shapes.end(), shapes.front().type(), &compute_common_type, [&](auto s) {
|
|
||||||
return s.type();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
shape common_shape(const std::vector<shape>& shapes)
|
|
||||||
{
|
|
||||||
if(shapes.empty())
|
|
||||||
return {};
|
|
||||||
return {compute_common_types(shapes), compute_common_lens(shapes)};
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<instruction_ref> insert_common_args(module& m,
|
|
||||||
instruction_ref ins,
|
|
||||||
std::vector<instruction_ref> inputs,
|
|
||||||
common_options options)
|
|
||||||
{
|
|
||||||
if(std::any_of(
|
|
||||||
inputs.cbegin(), inputs.cend(), [](auto input) { return input->get_shape().dynamic(); }))
|
|
||||||
{
|
|
||||||
auto input_shapes = to_shapes(inputs);
|
|
||||||
if(options.common_lens)
|
|
||||||
{
|
|
||||||
auto c_dyn_dims = compute_common_dyn_dims(input_shapes);
|
|
||||||
|
|
||||||
auto s0 = inputs[0]->get_shape();
|
|
||||||
// always add both multibroadcast instructions for dynamic shapes
|
|
||||||
inputs[0] = m.insert_instruction(
|
|
||||||
ins, make_op("multibroadcast", {{"out_dyn_dims", to_value(c_dyn_dims)}}), inputs);
|
|
||||||
std::transform(inputs.begin() + 1, inputs.end(), inputs.begin() + 1, [&](auto input) {
|
|
||||||
// uses previous input to avoid recalculating the common shape from the
|
|
||||||
// full set of input shapes at runtime
|
|
||||||
auto s = input->get_shape();
|
|
||||||
return m.insert_instruction(
|
|
||||||
ins,
|
|
||||||
make_op("multibroadcast", {{"out_dyn_dims", to_value(c_dyn_dims)}}),
|
|
||||||
input,
|
|
||||||
inputs[0]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if(options.common_type)
|
|
||||||
{
|
|
||||||
auto c_type = compute_common_types(input_shapes);
|
|
||||||
std::transform(inputs.begin(), inputs.end(), inputs.begin(), [&](auto input) {
|
|
||||||
if(input->get_shape().type() != c_type)
|
|
||||||
{
|
|
||||||
input = m.insert_instruction(
|
|
||||||
ins, make_op("convert", {{"target_type", c_type}}), input);
|
|
||||||
}
|
|
||||||
return input;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto common = common_shape(to_shapes(inputs));
|
|
||||||
std::transform(inputs.begin(), inputs.end(), inputs.begin(), [&](auto input) {
|
|
||||||
if(options.common_lens and input->get_shape().lens() != common.lens())
|
|
||||||
{
|
|
||||||
input = m.insert_instruction(
|
|
||||||
ins, make_op("multibroadcast", {{"out_lens", common.lens()}}), input);
|
|
||||||
}
|
|
||||||
if(options.common_type and input->get_shape().type() != common.type())
|
|
||||||
{
|
|
||||||
input = m.insert_instruction(
|
|
||||||
ins, make_op("convert", {{"target_type", common.type()}}), input);
|
|
||||||
}
|
|
||||||
return input;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return inputs;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<instruction_ref>
|
|
||||||
add_common_args(module& m, std::vector<instruction_ref> inputs, common_options options)
|
|
||||||
{
|
|
||||||
return insert_common_args(m, m.end(), std::move(inputs), options);
|
|
||||||
}
|
|
||||||
|
|
||||||
instruction_ref insert_common_op(module& m,
|
|
||||||
instruction_ref ins,
|
|
||||||
const operation& op,
|
|
||||||
std::vector<instruction_ref> inputs,
|
|
||||||
common_options options)
|
|
||||||
{
|
|
||||||
return m.insert_instruction(ins, op, insert_common_args(m, ins, std::move(inputs), options));
|
|
||||||
}
|
|
||||||
|
|
||||||
instruction_ref add_common_op(module& m,
|
|
||||||
const operation& op,
|
|
||||||
std::vector<instruction_ref> inputs,
|
|
||||||
common_options options)
|
|
||||||
{
|
|
||||||
return insert_common_op(m, m.end(), op, std::move(inputs), options);
|
|
||||||
}
|
|
||||||
|
|
||||||
shape make_bcast_shape(const shape& input_shape, const std::vector<std::size_t>& bcast_lens)
|
|
||||||
{
|
|
||||||
assert(not input_shape.dynamic());
|
|
||||||
auto offset = bcast_lens.size() - input_shape.ndim();
|
|
||||||
std::vector<size_t> bcast_strides(bcast_lens.size(), 0);
|
|
||||||
for(std::ptrdiff_t i : reverse(range(input_shape.ndim())))
|
|
||||||
{
|
|
||||||
if(bcast_lens.at(i + offset) == input_shape.lens()[i])
|
|
||||||
{
|
|
||||||
bcast_strides.at(i + offset) = input_shape.strides()[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return shape{input_shape.type(), bcast_lens, bcast_strides};
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,203 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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.
|
|
||||||
*/
|
|
||||||
#include <migraphx/common_dims.hpp>
|
|
||||||
#include <migraphx/ranges.hpp>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cassert>
|
|
||||||
#include <numeric>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
template <class Iterator>
|
|
||||||
static auto compute_end_dim(Iterator start, Iterator last, std::size_t dim)
|
|
||||||
{
|
|
||||||
std::size_t x = 1;
|
|
||||||
auto it = std::find_if(start, last, [&](auto i) {
|
|
||||||
x *= i;
|
|
||||||
return x > dim;
|
|
||||||
});
|
|
||||||
if(x < dim)
|
|
||||||
return start;
|
|
||||||
return it;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct common_dim_state
|
|
||||||
{
|
|
||||||
common_dim_state(const std::vector<std::size_t>& pdims,
|
|
||||||
std::vector<std::vector<std::size_t>>& paxes_map)
|
|
||||||
: dims(&pdims), axes_map(&paxes_map), it(dims->begin())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
const std::vector<std::size_t>* dims = nullptr;
|
|
||||||
std::vector<std::vector<std::size_t>>* axes_map = nullptr;
|
|
||||||
std::vector<std::size_t>::const_iterator it{};
|
|
||||||
std::size_t rem = 1;
|
|
||||||
std::size_t get() const { return *it / rem; }
|
|
||||||
bool is_end() const { return it == dims->end(); }
|
|
||||||
void next(std::size_t i = 1) { it += i; }
|
|
||||||
auto dims_for(std::size_t d) const
|
|
||||||
{
|
|
||||||
auto dim_end = compute_end_dim(it, dims->end(), d);
|
|
||||||
return range(it, dim_end);
|
|
||||||
}
|
|
||||||
void add_axes(std::size_t naxes, std::size_t start) MIGRAPHX_TIDY_CONST
|
|
||||||
{
|
|
||||||
auto axes = compute_axes(naxes, start);
|
|
||||||
axes_map->push_back(std::move(axes));
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_multi_axes(std::size_t naxes, std::size_t start) MIGRAPHX_TIDY_CONST
|
|
||||||
{
|
|
||||||
auto axes = compute_axes(naxes, start);
|
|
||||||
std::transform(axes.begin(),
|
|
||||||
axes.end(),
|
|
||||||
std::back_inserter(*axes_map),
|
|
||||||
[&](auto axis) -> std::vector<std::size_t> { return {axis}; });
|
|
||||||
}
|
|
||||||
std::vector<std::size_t> compute_axes(std::size_t naxes, std::size_t start) const
|
|
||||||
{
|
|
||||||
if(rem != 1)
|
|
||||||
{
|
|
||||||
assert(start > 0);
|
|
||||||
naxes++;
|
|
||||||
start--;
|
|
||||||
}
|
|
||||||
std::vector<std::size_t> axes(naxes);
|
|
||||||
std::iota(axes.begin(), axes.end(), start);
|
|
||||||
return axes;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static bool compute_common_dim(std::vector<std::size_t>& cd_dims,
|
|
||||||
common_dim_state& state1,
|
|
||||||
common_dim_state& state2)
|
|
||||||
{
|
|
||||||
assert(state1.get() < state2.get());
|
|
||||||
auto d2 = state2.get();
|
|
||||||
auto dims = state1.dims_for(d2);
|
|
||||||
auto n = elements(dims);
|
|
||||||
auto naxes = distance(dims);
|
|
||||||
if(naxes == 0)
|
|
||||||
return false;
|
|
||||||
// If not divisible then we can't compute a common dim
|
|
||||||
if((d2 % n) != 0)
|
|
||||||
return false;
|
|
||||||
auto rem = d2 / n;
|
|
||||||
state1.add_multi_axes(naxes, cd_dims.size());
|
|
||||||
state2.add_axes(rem == 1 ? naxes : naxes + 1, cd_dims.size());
|
|
||||||
|
|
||||||
state1.rem = rem;
|
|
||||||
state2.rem = 1;
|
|
||||||
|
|
||||||
cd_dims.insert(cd_dims.end(), dims.begin(), dims.end());
|
|
||||||
if(state1.rem != 1)
|
|
||||||
cd_dims.push_back(state1.rem);
|
|
||||||
state1.next(distance(dims));
|
|
||||||
state2.next();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
common_dims common_dims::compute(const std::vector<std::size_t>& dims1,
|
|
||||||
const std::vector<std::size_t>& dims2)
|
|
||||||
{
|
|
||||||
assert(elements(dims1) > 0);
|
|
||||||
assert(elements(dims1) == elements(dims2));
|
|
||||||
common_dims cd;
|
|
||||||
common_dim_state state1{dims1, cd.axes_map1};
|
|
||||||
common_dim_state state2{dims2, cd.axes_map2};
|
|
||||||
while(not state1.is_end() and not state2.is_end())
|
|
||||||
{
|
|
||||||
auto d1 = state1.get();
|
|
||||||
auto d2 = state2.get();
|
|
||||||
if(d1 == d2)
|
|
||||||
{
|
|
||||||
state1.add_axes(1, cd.dims.size());
|
|
||||||
state2.add_axes(1, cd.dims.size());
|
|
||||||
state1.rem = 1;
|
|
||||||
state2.rem = 1;
|
|
||||||
cd.dims.push_back(d1);
|
|
||||||
state1.next();
|
|
||||||
state2.next();
|
|
||||||
}
|
|
||||||
else if(d1 < d2)
|
|
||||||
{
|
|
||||||
if(not compute_common_dim(cd.dims, state1, state2))
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
else // if(d1 > d2)
|
|
||||||
{
|
|
||||||
if(not compute_common_dim(cd.dims, state2, state1))
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert(elements(dims1) == elements(cd.dims));
|
|
||||||
return cd;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<std::vector<std::size_t>>* common_dims::get_axes_map(std::size_t n) const
|
|
||||||
{
|
|
||||||
if(axes_map1.size() == n)
|
|
||||||
return &axes_map1;
|
|
||||||
if(axes_map2.size() == n)
|
|
||||||
return &axes_map2;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::size_t>
|
|
||||||
common_dims::get_dimensions_for(const std::vector<std::size_t>& idims) const
|
|
||||||
{
|
|
||||||
if(dims.size() == idims.size())
|
|
||||||
return idims;
|
|
||||||
if(elements(dims) == elements(idims))
|
|
||||||
return dims;
|
|
||||||
// Bail for now since its ambiguous which axes map can be used
|
|
||||||
// TODO: Check for similiarity
|
|
||||||
if(axes_map1.size() == axes_map2.size())
|
|
||||||
return {};
|
|
||||||
const auto* axes_map = get_axes_map(idims.size());
|
|
||||||
if(axes_map == nullptr)
|
|
||||||
return {};
|
|
||||||
auto xdims = dims;
|
|
||||||
for(auto i : range(axes_map->size()))
|
|
||||||
{
|
|
||||||
auto dim = idims[i];
|
|
||||||
const auto& axes = (*axes_map)[i];
|
|
||||||
if(axes.size() == 1)
|
|
||||||
{
|
|
||||||
xdims[axes.front()] = dim;
|
|
||||||
}
|
|
||||||
else if(dim == 1)
|
|
||||||
{
|
|
||||||
for(auto axis : axes)
|
|
||||||
xdims[axis] = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(elements(xdims) == elements(idims))
|
|
||||||
return xdims;
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,76 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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.
|
|
||||||
*/
|
|
||||||
#include <migraphx/compile_src.hpp>
|
|
||||||
#include <migraphx/file_buffer.hpp>
|
|
||||||
#include <migraphx/tmp_dir.hpp>
|
|
||||||
#include <migraphx/stringutils.hpp>
|
|
||||||
#include <migraphx/errors.hpp>
|
|
||||||
#include <migraphx/fileutils.hpp>
|
|
||||||
#include <vector>
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
std::vector<char> src_compiler::compile(const std::vector<src_file>& srcs) const
|
|
||||||
{
|
|
||||||
assert(not srcs.empty());
|
|
||||||
tmp_dir td{"compile"};
|
|
||||||
std::vector<std::string> params{flags};
|
|
||||||
|
|
||||||
params.emplace_back("-I.");
|
|
||||||
|
|
||||||
auto out = output;
|
|
||||||
|
|
||||||
for(const auto& src : srcs)
|
|
||||||
{
|
|
||||||
fs::path full_path = td.path / src.path;
|
|
||||||
fs::path parent_path = full_path.parent_path();
|
|
||||||
fs::create_directories(parent_path);
|
|
||||||
write_buffer(full_path, src.content.data(), src.content.size());
|
|
||||||
if(src.path.extension().string() == ".cpp")
|
|
||||||
{
|
|
||||||
params.emplace_back(src.path.filename().string());
|
|
||||||
if(out.empty())
|
|
||||||
out = src.path.stem().string() + out_ext;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
params.emplace_back("-o " + out);
|
|
||||||
|
|
||||||
std::vector<std::string> args;
|
|
||||||
if(not launcher.empty())
|
|
||||||
args.push_back(compiler.string());
|
|
||||||
args.insert(args.end(), params.begin(), params.end());
|
|
||||||
td.execute(launcher.empty() ? compiler : launcher, args);
|
|
||||||
|
|
||||||
auto out_path = td.path / out;
|
|
||||||
if(not fs::exists(out_path))
|
|
||||||
MIGRAPHX_THROW("Output file missing: " + out);
|
|
||||||
|
|
||||||
return read_buffer(out_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,105 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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.
|
|
||||||
*/
|
|
||||||
#include <algorithm>
|
|
||||||
#include <string>
|
|
||||||
#include <sstream>
|
|
||||||
#include <migraphx/errors.hpp>
|
|
||||||
#include <migraphx/ranges.hpp>
|
|
||||||
#include <migraphx/convert_to_json.hpp>
|
|
||||||
#include <migraphx/stringutils.hpp>
|
|
||||||
#include <migraphx/lexing.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
std::vector<std::string_view> json_tokenize(const std::string& s)
|
|
||||||
{
|
|
||||||
std::vector<lexer> lexers;
|
|
||||||
|
|
||||||
// Quote
|
|
||||||
lexers.push_back([](const char* start, const char* end) {
|
|
||||||
if(*start != '\"')
|
|
||||||
return start;
|
|
||||||
++start;
|
|
||||||
while((start != end) and (*start != '\"'))
|
|
||||||
{
|
|
||||||
if(*start == '\\')
|
|
||||||
start++;
|
|
||||||
start++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ++start;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Line comments
|
|
||||||
lexers.push_back([](const char* start, const char* end) {
|
|
||||||
if(*start == '#')
|
|
||||||
start++;
|
|
||||||
else if((start + 1) < end and start[0] == '/' and start[1] == '/')
|
|
||||||
start += 2;
|
|
||||||
else
|
|
||||||
return start;
|
|
||||||
return std::find_if(start, end, [&](char c) { return c == '\n'; });
|
|
||||||
});
|
|
||||||
|
|
||||||
// Whitespace
|
|
||||||
lexers.push_back(lex_while(&isspace));
|
|
||||||
|
|
||||||
// Punctation
|
|
||||||
lexers.push_back(lex_if(&ispunct));
|
|
||||||
|
|
||||||
// Identifier/number
|
|
||||||
lexers.push_back(lex_while([](char c) {
|
|
||||||
return (isalnum(c) != 0 or contains({'_', '.', '+'}, c));
|
|
||||||
}));
|
|
||||||
|
|
||||||
return tokenize(s.data(), s.data() + s.length(), lexers);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string convert_to_json(const std::string& str)
|
|
||||||
{
|
|
||||||
auto tokens = json_tokenize(str);
|
|
||||||
std::stringstream ss;
|
|
||||||
|
|
||||||
for(auto& token : tokens)
|
|
||||||
{
|
|
||||||
std::string s(token);
|
|
||||||
if(starts_with(s, "#") or starts_with(s, "//"))
|
|
||||||
continue;
|
|
||||||
if(std::isalpha(s.front()) != 0 and
|
|
||||||
not contains({"null", "nan", "true", "false", "inf"}, s))
|
|
||||||
{
|
|
||||||
ss << "\"" << s << "\"";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ss << s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,284 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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.
|
|
||||||
*/
|
|
||||||
#include <migraphx/cpp_generator.hpp>
|
|
||||||
#include <migraphx/module.hpp>
|
|
||||||
#include <migraphx/operation.hpp>
|
|
||||||
#include <migraphx/ranges.hpp>
|
|
||||||
#include <migraphx/instruction.hpp>
|
|
||||||
#include <migraphx/builtin.hpp>
|
|
||||||
#include <migraphx/stringutils.hpp>
|
|
||||||
#include <migraphx/iterator_for.hpp>
|
|
||||||
#include <map>
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
cpp_generator::function&
|
|
||||||
cpp_generator::function::set_body(const module& m, const cpp_generator::generate_module_callback& g)
|
|
||||||
{
|
|
||||||
const std::string prefix = "zz";
|
|
||||||
std::unordered_map<migraphx::instruction_ref, std::string> names;
|
|
||||||
std::stringstream ss;
|
|
||||||
|
|
||||||
auto return_ins = std::prev(m.end());
|
|
||||||
|
|
||||||
for(auto ins : iterator_for(m))
|
|
||||||
{
|
|
||||||
ss << "// " << ins->get_operator() << " -> " << ins->get_shape() << "\n";
|
|
||||||
if(ins->name() == "@param")
|
|
||||||
{
|
|
||||||
names[ins] = to_c_id(
|
|
||||||
migraphx::any_cast<migraphx::builtin::param>(ins->get_operator()).parameter);
|
|
||||||
}
|
|
||||||
else if(ins->name() == "@return")
|
|
||||||
{
|
|
||||||
names[ins] = prefix + "return";
|
|
||||||
ss << "auto " << names[ins] << " = " << g(ins, names) << ";\n";
|
|
||||||
return_ins = ins;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::string n = prefix + std::to_string(names.size());
|
|
||||||
names[ins] = n;
|
|
||||||
ss << "auto " << n << " = " << g(ins, names) << ";\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ss << "return " << names.at(return_ins) << ";\n";
|
|
||||||
body = ss.str();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
cpp_generator::function& cpp_generator::function::set_types(const module& m)
|
|
||||||
{
|
|
||||||
return cpp_generator::function::set_types(m, [](auto s) { return shape::cpp_type(s.type()); });
|
|
||||||
}
|
|
||||||
cpp_generator::function&
|
|
||||||
cpp_generator::function::set_types(const module& m, const std::function<std::string(shape)>& parse)
|
|
||||||
{
|
|
||||||
this->params.clear();
|
|
||||||
auto pmap = m.get_parameter_shapes();
|
|
||||||
std::map<std::string, shape> input_map(pmap.begin(), pmap.end());
|
|
||||||
std::transform(
|
|
||||||
input_map.begin(), input_map.end(), std::back_inserter(this->params), [&](auto&& p) {
|
|
||||||
return param{p.first, parse(p.second)};
|
|
||||||
});
|
|
||||||
auto output_shapes = m.get_output_shapes();
|
|
||||||
assert(not output_shapes.empty());
|
|
||||||
this->return_type = parse(output_shapes.front());
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
cpp_generator::function& cpp_generator::function::set_generic_types(const module& m)
|
|
||||||
{
|
|
||||||
this->params.clear();
|
|
||||||
auto pmap = m.get_parameter_shapes();
|
|
||||||
std::map<std::string, shape> input_map(pmap.begin(), pmap.end());
|
|
||||||
std::transform(
|
|
||||||
input_map.begin(), input_map.end(), std::back_inserter(this->params), [&](auto&& p) {
|
|
||||||
return param{p.first, "T" + to_c_id(p.first)};
|
|
||||||
});
|
|
||||||
|
|
||||||
std::transform(input_map.begin(),
|
|
||||||
input_map.end(),
|
|
||||||
std::back_inserter(this->tparams),
|
|
||||||
[&](auto&& p) { return "class T" + to_c_id(p.first); });
|
|
||||||
this->return_type = "auto";
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
cpp_generator::function& cpp_generator::function::unused_param(const std::string& pname)
|
|
||||||
{
|
|
||||||
body.insert(0, "(void)" + pname + ";\n");
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
cpp_generator::function& cpp_generator::function::add_generic_param(const std::string& pname)
|
|
||||||
{
|
|
||||||
params.push_back({pname, "T" + pname});
|
|
||||||
tparams.push_back("class T" + pname);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct cpp_generator_impl
|
|
||||||
{
|
|
||||||
std::stringstream fs{};
|
|
||||||
std::size_t function_count = 0;
|
|
||||||
std::function<std::string(std::string)> fmap = nullptr;
|
|
||||||
std::function<std::string(shape)> fresult = nullptr;
|
|
||||||
std::unordered_map<std::string, std::string> point_op_map = {};
|
|
||||||
bool always_return_tuple = false;
|
|
||||||
};
|
|
||||||
cpp_generator::cpp_generator() : impl(std::make_unique<cpp_generator_impl>()) {}
|
|
||||||
|
|
||||||
cpp_generator::cpp_generator(cpp_generator&&) noexcept = default;
|
|
||||||
|
|
||||||
cpp_generator& cpp_generator::operator=(cpp_generator rhs)
|
|
||||||
{
|
|
||||||
std::swap(impl, rhs.impl);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
cpp_generator::~cpp_generator() noexcept = default;
|
|
||||||
|
|
||||||
void cpp_generator::fmap(const std::function<std::string(std::string)>& f) { impl->fmap = f; }
|
|
||||||
|
|
||||||
void cpp_generator::fresult(const std::function<std::string(shape)>& f) { impl->fresult = f; }
|
|
||||||
|
|
||||||
void cpp_generator::always_return_tuple(bool b) { impl->always_return_tuple = b; }
|
|
||||||
|
|
||||||
void cpp_generator::add_point_op(const std::string& op_name, const std::string& code)
|
|
||||||
{
|
|
||||||
impl->point_op_map[op_name] = code;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string cpp_generator::generate_point_op(const operation& op,
|
|
||||||
const std::vector<std::string>& args)
|
|
||||||
{
|
|
||||||
auto v = op.to_value();
|
|
||||||
std::string code;
|
|
||||||
if(contains(impl->point_op_map, op.name()))
|
|
||||||
{
|
|
||||||
code = impl->point_op_map.at(op.name());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto attributes = op.attributes();
|
|
||||||
if(not attributes.contains("point_op"))
|
|
||||||
MIGRAPHX_THROW("op is missing point_op attribute: " + op.name());
|
|
||||||
code = attributes["point_op"].to<std::string>();
|
|
||||||
}
|
|
||||||
return interpolate_string(code, [&](auto start, auto last) -> std::string {
|
|
||||||
auto key = trim({start, last});
|
|
||||||
if(key.empty())
|
|
||||||
MIGRAPHX_THROW("Empty parameter");
|
|
||||||
std::string fselector = "function:";
|
|
||||||
if(starts_with(key, fselector))
|
|
||||||
{
|
|
||||||
auto fname = key.substr(fselector.size());
|
|
||||||
if(impl->fmap == nullptr)
|
|
||||||
return fname;
|
|
||||||
else
|
|
||||||
return impl->fmap(fname);
|
|
||||||
}
|
|
||||||
else if(with_char(::isdigit)(key[0]))
|
|
||||||
{
|
|
||||||
auto i = std::stoul(key);
|
|
||||||
if(i >= args.size())
|
|
||||||
MIGRAPHX_THROW("Invalid argument index: " + key);
|
|
||||||
return args.at(i);
|
|
||||||
}
|
|
||||||
else if(v.contains(key))
|
|
||||||
{
|
|
||||||
return v[key].template to<std::string>();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string cpp_generator::str() const { return impl->fs.str(); }
|
|
||||||
|
|
||||||
cpp_generator::function cpp_generator::generate_module(const module& m,
|
|
||||||
const generate_module_callback& g)
|
|
||||||
{
|
|
||||||
function f;
|
|
||||||
f.set_name(to_c_id(m.name()))
|
|
||||||
.set_types(m)
|
|
||||||
.set_body(m, [&](instruction_ref ins, const auto& names) -> std::string {
|
|
||||||
if(ins->name() == "@literal")
|
|
||||||
{
|
|
||||||
std::string string_literal;
|
|
||||||
ins->get_literal().visit([&](auto v) {
|
|
||||||
assert(v.size() == 1);
|
|
||||||
auto x = v.front();
|
|
||||||
if(std::isinf(static_cast<double>(x)))
|
|
||||||
{
|
|
||||||
string_literal = "__builtin_huge_val()";
|
|
||||||
if(x < 0)
|
|
||||||
string_literal = "-__builtin_huge_val()";
|
|
||||||
}
|
|
||||||
else if(std::isnan(static_cast<double>(x)))
|
|
||||||
string_literal = "__builtin_nan(\"0\")";
|
|
||||||
else
|
|
||||||
string_literal = ins->get_literal().to_string();
|
|
||||||
});
|
|
||||||
return shape::cpp_type(ins->get_shape().type()) + "(" + string_literal + ")";
|
|
||||||
}
|
|
||||||
if(ins->name() == "@return")
|
|
||||||
{
|
|
||||||
// TODO: Customize the make_tuple call
|
|
||||||
if(impl->always_return_tuple or ins->inputs().size() != 1)
|
|
||||||
return "make_tuple(" + join_strings(to_args(ins->inputs(), names), ", ") + ")";
|
|
||||||
return names.at(ins->inputs().front());
|
|
||||||
}
|
|
||||||
auto s = g(ins, names);
|
|
||||||
if(impl->fresult)
|
|
||||||
return impl->fresult(ins->get_shape()) + '(' + s + ')';
|
|
||||||
else
|
|
||||||
return s;
|
|
||||||
});
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string>
|
|
||||||
cpp_generator::to_args(const std::vector<instruction_ref>& inputs,
|
|
||||||
const std::unordered_map<instruction_ref, std::string>& names)
|
|
||||||
{
|
|
||||||
std::vector<std::string> args;
|
|
||||||
std::transform(inputs.begin(), inputs.end(), std::back_inserter(args), [&](auto i) {
|
|
||||||
return names.at(i);
|
|
||||||
});
|
|
||||||
return args;
|
|
||||||
}
|
|
||||||
|
|
||||||
cpp_generator::function cpp_generator::generate_module(const module& m)
|
|
||||||
{
|
|
||||||
return this->generate_module(m, [&](auto ins, const auto& names) {
|
|
||||||
return this->generate_point_op(ins->get_operator(), to_args(ins->inputs(), names));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string cpp_generator::create_function(const cpp_generator::function& f)
|
|
||||||
{
|
|
||||||
impl->function_count++;
|
|
||||||
if(not f.tparams.empty())
|
|
||||||
impl->fs << "template<" << join_strings(f.tparams, ", ") << ">\n";
|
|
||||||
std::string name = f.name.empty() ? "f" + std::to_string(impl->function_count) : f.name;
|
|
||||||
impl->fs << join_strings(f.attributes, " ") << " " << f.return_type << " " << name;
|
|
||||||
char delim = '(';
|
|
||||||
if(f.params.empty())
|
|
||||||
impl->fs << delim;
|
|
||||||
for(auto&& p : f.params)
|
|
||||||
{
|
|
||||||
impl->fs << delim << p.type << " " << to_c_id(p.name);
|
|
||||||
delim = ',';
|
|
||||||
}
|
|
||||||
impl->fs << ") {\n" << f.body << "\n}\n";
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,86 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
#include <migraphx/dead_code_elimination.hpp>
|
|
||||||
#include <migraphx/program.hpp>
|
|
||||||
#include <migraphx/instruction.hpp>
|
|
||||||
#include <migraphx/iterator_for.hpp>
|
|
||||||
#include <migraphx/functional.hpp>
|
|
||||||
#include <migraphx/ranges.hpp>
|
|
||||||
#include <migraphx/stringutils.hpp>
|
|
||||||
#include <unordered_set>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
void dead_code_elimination::apply(program& p) const { p.remove_unused_modules(); }
|
|
||||||
|
|
||||||
void dead_code_elimination::apply(module& m) const
|
|
||||||
{
|
|
||||||
auto last = std::prev(m.end());
|
|
||||||
for(auto ins : iterator_for(m))
|
|
||||||
{
|
|
||||||
// Skip the first instruction, since we always process the previous
|
|
||||||
// instruction
|
|
||||||
if(ins == m.begin())
|
|
||||||
continue;
|
|
||||||
const auto i = std::prev(ins);
|
|
||||||
// Skip the last instruction
|
|
||||||
if(i == last)
|
|
||||||
break;
|
|
||||||
// Skip instruction with empty shape as output unless its [dynamic, builtin, undefined,
|
|
||||||
// identity, allocate or tuple_type]
|
|
||||||
if((not i->get_shape().dynamic() and
|
|
||||||
(i->get_shape().elements() == 0 and
|
|
||||||
i->get_shape().type() != migraphx::shape::tuple_type)) and
|
|
||||||
not(i->name().front() == '@') and not contains({"identity", "allocate"}, i->name()) and
|
|
||||||
not i->is_undefined())
|
|
||||||
continue;
|
|
||||||
assert(std::distance(m.begin(), i) <= std::distance(m.begin(), last));
|
|
||||||
std::unordered_set<instruction_ref> visited;
|
|
||||||
fix([&](auto self, auto leaf) {
|
|
||||||
if(not m.has_instruction(leaf))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(leaf->outputs().empty())
|
|
||||||
{
|
|
||||||
// Dont visit inputs twice
|
|
||||||
if(not visited.insert(leaf).second)
|
|
||||||
return;
|
|
||||||
std::unordered_set<instruction_ref> args(leaf->inputs().begin(),
|
|
||||||
leaf->inputs().end());
|
|
||||||
leaf->clear_arguments();
|
|
||||||
assert(std::distance(m.begin(), leaf) < std::distance(m.begin(), last));
|
|
||||||
assert(leaf != ins);
|
|
||||||
if(leaf->name() != "@param")
|
|
||||||
m.move_instruction(leaf, m.end());
|
|
||||||
for(auto arg : args)
|
|
||||||
self(arg);
|
|
||||||
}
|
|
||||||
})(i);
|
|
||||||
}
|
|
||||||
m.remove_instructions(std::next(last), m.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,100 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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.
|
|
||||||
*/
|
|
||||||
#include <migraphx/dom_info.hpp>
|
|
||||||
#include <migraphx/program.hpp>
|
|
||||||
#include <migraphx/iterator_for.hpp>
|
|
||||||
#include <migraphx/erase.hpp>
|
|
||||||
#include <migraphx/ranges.hpp>
|
|
||||||
#include <unordered_set>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
bool dominator_info::strictly_dominate(instruction_ref ins1, instruction_ref ins2) const
|
|
||||||
{
|
|
||||||
if(ins1 == ins2)
|
|
||||||
return false;
|
|
||||||
auto iter = ins2idom.find(ins2);
|
|
||||||
while(iter != ins2idom.end())
|
|
||||||
{
|
|
||||||
if(ins1 == iter->second)
|
|
||||||
return true;
|
|
||||||
assert(iter != ins2idom.find(iter->second));
|
|
||||||
iter = ins2idom.find(iter->second);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct module_visitor
|
|
||||||
{
|
|
||||||
const module* mm;
|
|
||||||
const module& get_nodes() const { return *mm; }
|
|
||||||
|
|
||||||
const std::vector<instruction_ref>& get_children(instruction_ref ins) { return ins->inputs(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Visitor>
|
|
||||||
dominator_info compute_dominator_generic(Visitor v)
|
|
||||||
{
|
|
||||||
dominator_info info;
|
|
||||||
std::unordered_map<instruction_ref, std::unordered_set<instruction_ref>> instr2_doms;
|
|
||||||
for(instruction_ref ins : iterator_for(v.get_nodes()))
|
|
||||||
{
|
|
||||||
const std::vector<instruction_ref>& children = v.get_children(ins);
|
|
||||||
if(children.size() == 1)
|
|
||||||
{
|
|
||||||
info.ins2idom[ins] = children.front();
|
|
||||||
instr2_doms[ins] = instr2_doms[children.front()];
|
|
||||||
}
|
|
||||||
else if(children.size() > 1)
|
|
||||||
{
|
|
||||||
auto&& doms = instr2_doms[ins];
|
|
||||||
|
|
||||||
doms = instr2_doms[children.front()];
|
|
||||||
std::for_each(children.begin() + 1, children.end(), [&](instruction_ref child) {
|
|
||||||
auto&& child_doms = instr2_doms[child];
|
|
||||||
erase_if(doms, [&](auto x) { return not contains(child_doms, x); });
|
|
||||||
});
|
|
||||||
auto iter = std::find_if(doms.begin(), doms.end(), [&](auto dom1) {
|
|
||||||
return std::none_of(doms.begin(), doms.end(), [&](auto dom2) {
|
|
||||||
if(dom1 == dom2)
|
|
||||||
return false;
|
|
||||||
return info.strictly_dominate(dom1, dom2);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
if(iter != doms.end())
|
|
||||||
info.ins2idom[ins] = *iter;
|
|
||||||
}
|
|
||||||
instr2_doms[ins].insert(ins);
|
|
||||||
}
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
dominator_info compute_dominator(const module& m)
|
|
||||||
{
|
|
||||||
return compute_dominator_generic(module_visitor{&m});
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,60 +0,0 @@
|
|||||||
#####################################################################################
|
|
||||||
# The MIT License (MIT)
|
|
||||||
#
|
|
||||||
# Copyright (c) 2015-2024 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.
|
|
||||||
#####################################################################################
|
|
||||||
|
|
||||||
add_executable(driver
|
|
||||||
main.cpp
|
|
||||||
verify.cpp
|
|
||||||
passes.cpp
|
|
||||||
mlir.cpp
|
|
||||||
models.cpp
|
|
||||||
perf.cpp
|
|
||||||
marker_roctx.cpp
|
|
||||||
)
|
|
||||||
set_target_properties(driver PROPERTIES OUTPUT_NAME migraphx-driver)
|
|
||||||
if(NOT WIN32)
|
|
||||||
# Copy driver for backwards compatibility (Linux only)
|
|
||||||
add_custom_command(
|
|
||||||
TARGET driver
|
|
||||||
POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy
|
|
||||||
$<TARGET_FILE:driver>
|
|
||||||
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/driver
|
|
||||||
BYPRODUCTS ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/driver
|
|
||||||
)
|
|
||||||
set_directory_properties(PROPERTIES ADDITIONAL_CLEAN_FILES ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/driver)
|
|
||||||
endif()
|
|
||||||
rocm_clang_tidy_check(driver)
|
|
||||||
|
|
||||||
file(STRINGS "${CMAKE_SOURCE_DIR}/test/onnx/.onnxrt-commit" String_output)
|
|
||||||
target_compile_definitions(driver PUBLIC MIGRAPHX_ORT_SHA1="${String_output}")
|
|
||||||
|
|
||||||
target_link_libraries(driver migraphx_all_targets migraphx_onnx migraphx_tf)
|
|
||||||
|
|
||||||
if(MIGRAPHX_ENABLE_PYTHON)
|
|
||||||
target_link_libraries(driver migraphx_py)
|
|
||||||
target_compile_definitions(driver PRIVATE MIGRAPHX_ENABLE_PYTHON)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
rocm_install_targets(
|
|
||||||
TARGETS driver
|
|
||||||
)
|
|
||||||
@ -1,748 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2025 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_RTGLIB_ARGUMENT_PARSER_HPP
|
|
||||||
#define MIGRAPHX_GUARD_RTGLIB_ARGUMENT_PARSER_HPP
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <functional>
|
|
||||||
#include <iostream>
|
|
||||||
#include <list>
|
|
||||||
#include <set>
|
|
||||||
#include <string>
|
|
||||||
#include <sstream>
|
|
||||||
#include <type_traits>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <unordered_set>
|
|
||||||
#include <utility>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
#include <migraphx/requires.hpp>
|
|
||||||
#include <migraphx/type_name.hpp>
|
|
||||||
#include <migraphx/functional.hpp>
|
|
||||||
#include <migraphx/filesystem.hpp>
|
|
||||||
#include <migraphx/stringutils.hpp>
|
|
||||||
#include <migraphx/algorithm.hpp>
|
|
||||||
#include <migraphx/ranges.hpp>
|
|
||||||
#include <migraphx/rank.hpp>
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
namespace driver {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
#ifdef MIGRAPHX_USE_CLANG_TIDY
|
|
||||||
#define MIGRAPHX_DRIVER_STATIC
|
|
||||||
#else
|
|
||||||
#define MIGRAPHX_DRIVER_STATIC static
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
using bare = std::remove_cv_t<std::remove_reference_t<T>>;
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
auto is_container(int, T&& x) -> decltype(x.insert(x.end(), *x.begin()), std::true_type{});
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
std::false_type is_container(float, T&&);
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
struct is_container : decltype(detail::is_container(int(0), std::declval<T>()))
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
using is_multi_value =
|
|
||||||
std::integral_constant<bool, (is_container<T>{} and not std::is_convertible<T, std::string>{})>;
|
|
||||||
|
|
||||||
enum class color
|
|
||||||
{
|
|
||||||
reset = 0,
|
|
||||||
bold = 1,
|
|
||||||
underlined = 4,
|
|
||||||
fg_red = 31,
|
|
||||||
fg_green = 32,
|
|
||||||
fg_yellow = 33,
|
|
||||||
fg_blue = 34,
|
|
||||||
fg_default = 39,
|
|
||||||
bg_red = 41,
|
|
||||||
bg_green = 42,
|
|
||||||
bg_yellow = 43,
|
|
||||||
bg_blue = 44,
|
|
||||||
bg_default = 49
|
|
||||||
};
|
|
||||||
inline std::ostream& operator<<(std::ostream& os, const color& c)
|
|
||||||
{
|
|
||||||
#ifndef _WIN32
|
|
||||||
static const bool use_color = isatty(STDOUT_FILENO) != 0;
|
|
||||||
if(use_color)
|
|
||||||
return os << "\033[" << static_cast<std::size_t>(c) << "m";
|
|
||||||
#else
|
|
||||||
(void)c;
|
|
||||||
#endif
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::string colorize(color c, const std::string& s)
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << c << s << color::reset;
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
struct type_name
|
|
||||||
{
|
|
||||||
static const std::string& apply() { return migraphx::get_type_name<T>(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct type_name<std::string>
|
|
||||||
{
|
|
||||||
static const std::string& apply()
|
|
||||||
{
|
|
||||||
static const std::string name = "std::string";
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
struct type_name<std::vector<T>>
|
|
||||||
{
|
|
||||||
static const std::string& apply()
|
|
||||||
{
|
|
||||||
static const std::string name = "std::vector<" + type_name<T>::apply() + ">";
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
struct value_parser
|
|
||||||
{
|
|
||||||
template <MIGRAPHX_REQUIRES(not std::is_enum<T>{} and not is_multi_value<T>{})>
|
|
||||||
static T apply(const std::string& x)
|
|
||||||
{
|
|
||||||
// handle whitespace in string
|
|
||||||
if constexpr(std::is_same<T, std::string>{})
|
|
||||||
{
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
T result;
|
|
||||||
std::stringstream ss;
|
|
||||||
ss.str(x);
|
|
||||||
ss >> result;
|
|
||||||
if(ss.fail())
|
|
||||||
throw std::runtime_error("Failed to parse '" + x + "' as " + type_name<T>::apply());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <MIGRAPHX_REQUIRES(std::is_enum<T>{} and not is_multi_value<T>{})>
|
|
||||||
static T apply(const std::string& x)
|
|
||||||
{
|
|
||||||
std::ptrdiff_t i;
|
|
||||||
std::stringstream ss;
|
|
||||||
ss.str(x);
|
|
||||||
ss >> i;
|
|
||||||
if(ss.fail())
|
|
||||||
throw std::runtime_error("Failed to parse '" + x + "' as " + type_name<T>::apply());
|
|
||||||
return static_cast<T>(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <MIGRAPHX_REQUIRES(is_multi_value<T>{} and not std::is_enum<T>{})>
|
|
||||||
static T apply(const std::string& x)
|
|
||||||
{
|
|
||||||
T result;
|
|
||||||
using value_type = typename T::value_type;
|
|
||||||
result.insert(result.end(), value_parser<value_type>::apply(x));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// version for std::optional object
|
|
||||||
template <class T>
|
|
||||||
struct value_parser<std::optional<T>>
|
|
||||||
{
|
|
||||||
static T apply(const std::string& x) { return value_parser<T>::apply(x); }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct argument_parser
|
|
||||||
{
|
|
||||||
struct argument
|
|
||||||
{
|
|
||||||
using action_function =
|
|
||||||
std::function<bool(argument_parser&, const std::vector<std::string>&)>;
|
|
||||||
using validate_function =
|
|
||||||
std::function<void(const argument_parser&, const std::vector<std::string>&)>;
|
|
||||||
std::vector<std::string> flags;
|
|
||||||
action_function action{};
|
|
||||||
std::string type = "";
|
|
||||||
std::string help = "";
|
|
||||||
std::string metavar = "";
|
|
||||||
std::string default_value = "";
|
|
||||||
std::string group = "";
|
|
||||||
unsigned nargs = 1;
|
|
||||||
bool required = false;
|
|
||||||
std::vector<validate_function> validations{};
|
|
||||||
|
|
||||||
std::string usage(const std::string& flag) const
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
if(flag.empty())
|
|
||||||
{
|
|
||||||
ss << metavar;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ss << flag;
|
|
||||||
if(not type.empty())
|
|
||||||
ss << " [" << type << "]";
|
|
||||||
}
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
std::string usage() const
|
|
||||||
{
|
|
||||||
if(flags.empty())
|
|
||||||
return usage("");
|
|
||||||
return usage(flags.front());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T, MIGRAPHX_REQUIRES(is_multi_value<T>{})>
|
|
||||||
std::string as_string_value(const T& x)
|
|
||||||
{
|
|
||||||
return to_string_range(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
auto as_string_value(rank<1>, const T& x) -> decltype(to_string(x))
|
|
||||||
{
|
|
||||||
return to_string(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
std::string as_string_value(rank<0>, const T&)
|
|
||||||
{
|
|
||||||
throw std::runtime_error("Can't convert to string");
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, MIGRAPHX_REQUIRES(not is_multi_value<T>{})>
|
|
||||||
std::string as_string_value(const T& x)
|
|
||||||
{
|
|
||||||
return as_string_value(rank<1>{}, x);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class... Fs>
|
|
||||||
void operator()(T& x, const std::vector<std::string>& flags, Fs... fs)
|
|
||||||
{
|
|
||||||
arguments.push_back({flags, [&](auto&&, const std::vector<std::string>& params) {
|
|
||||||
if(params.empty())
|
|
||||||
throw std::runtime_error("Flag with no value.");
|
|
||||||
if(not is_multi_value<T>{} and params.size() > 1)
|
|
||||||
throw std::runtime_error("Too many arguments passed.");
|
|
||||||
x = value_parser<T>::apply(params.back());
|
|
||||||
return false;
|
|
||||||
}});
|
|
||||||
|
|
||||||
argument& arg = arguments.back();
|
|
||||||
arg.type = type_name<T>::apply();
|
|
||||||
migraphx::each_args([&](auto f) { f(x, arg); }, fs...);
|
|
||||||
if(not arg.default_value.empty() and arg.nargs > 0)
|
|
||||||
arg.default_value = as_string_value(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... Fs>
|
|
||||||
void operator()(std::nullptr_t x, std::vector<std::string> flags, Fs... fs)
|
|
||||||
{
|
|
||||||
arguments.push_back({std::move(flags)});
|
|
||||||
|
|
||||||
argument& arg = arguments.back();
|
|
||||||
arg.type = "";
|
|
||||||
arg.nargs = 0;
|
|
||||||
migraphx::each_args([&](auto f) { f(x, arg); }, fs...);
|
|
||||||
}
|
|
||||||
|
|
||||||
MIGRAPHX_DRIVER_STATIC auto nargs(unsigned n = 1)
|
|
||||||
{
|
|
||||||
return [=](auto&&, auto& arg) { arg.nargs = n; };
|
|
||||||
}
|
|
||||||
|
|
||||||
MIGRAPHX_DRIVER_STATIC auto required()
|
|
||||||
{
|
|
||||||
return [=](auto&&, auto& arg) { arg.required = true; };
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class F>
|
|
||||||
MIGRAPHX_DRIVER_STATIC auto write_action(F f)
|
|
||||||
{
|
|
||||||
return [=](auto& x, auto& arg) {
|
|
||||||
arg.action = [&, f](auto& self, const std::vector<std::string>& params) {
|
|
||||||
f(self, x, params);
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class F>
|
|
||||||
MIGRAPHX_DRIVER_STATIC auto do_action(F f)
|
|
||||||
{
|
|
||||||
return [=](auto&, auto& arg) {
|
|
||||||
arg.nargs = 0;
|
|
||||||
arg.action = [&, f](auto& self, const std::vector<std::string>&) {
|
|
||||||
f(self);
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
MIGRAPHX_DRIVER_STATIC auto append()
|
|
||||||
{
|
|
||||||
return write_action([](auto&, auto& x, auto& params) {
|
|
||||||
using type = typename bare<decltype(params)>::value_type;
|
|
||||||
std::transform(params.begin(),
|
|
||||||
params.end(),
|
|
||||||
std::inserter(x, x.end()),
|
|
||||||
[](std::string y) { return value_parser<type>::apply(y); });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class F>
|
|
||||||
MIGRAPHX_DRIVER_STATIC auto validate(F f)
|
|
||||||
{
|
|
||||||
return [=](const auto& x, auto& arg) {
|
|
||||||
arg.validations.push_back(
|
|
||||||
[&, f](auto& self, const std::vector<std::string>& params) { f(self, x, params); });
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
MIGRAPHX_DRIVER_STATIC auto file_exist()
|
|
||||||
{
|
|
||||||
return validate([](auto&, auto&, const auto& params) {
|
|
||||||
if(params.empty())
|
|
||||||
throw std::runtime_error("No argument passed.");
|
|
||||||
if(not fs::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&, const auto& params) {
|
|
||||||
auto invalid_param = std::find_if(
|
|
||||||
params.begin(), params.end(), [&](const auto& p) { return names.count(p) == 0; });
|
|
||||||
if(invalid_param != params.end())
|
|
||||||
throw std::runtime_error("Invalid argument: " + *invalid_param +
|
|
||||||
". Valid arguments are {" + to_string_range(names) + "}");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class F>
|
|
||||||
argument* find_argument(F f)
|
|
||||||
{
|
|
||||||
auto it = std::find_if(arguments.begin(), arguments.end(), f);
|
|
||||||
if(it == arguments.end())
|
|
||||||
return nullptr;
|
|
||||||
return std::addressof(*it);
|
|
||||||
}
|
|
||||||
template <class F>
|
|
||||||
bool has_argument(F f)
|
|
||||||
{
|
|
||||||
return find_argument(f) != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class F>
|
|
||||||
std::vector<argument*> find_arguments(F f)
|
|
||||||
{
|
|
||||||
std::vector<argument*> result;
|
|
||||||
for(auto& arg : arguments)
|
|
||||||
{
|
|
||||||
if(not f(arg))
|
|
||||||
continue;
|
|
||||||
result.push_back(&arg);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<argument*> get_group_arguments(const std::string& group)
|
|
||||||
{
|
|
||||||
return find_arguments([&](const auto& arg) { return arg.group == group; });
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<argument*> get_required_arguments()
|
|
||||||
{
|
|
||||||
return find_arguments([&](const auto& arg) { return arg.required; });
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class SequenceContainer>
|
|
||||||
std::vector<std::string> get_argument_usages(SequenceContainer args)
|
|
||||||
{
|
|
||||||
std::vector<std::string> usage_flags;
|
|
||||||
std::unordered_set<std::string> found_groups;
|
|
||||||
// Remove arguments that belong to a group
|
|
||||||
auto it = std::remove_if(args.begin(), args.end(), [&](const argument* arg) {
|
|
||||||
if(arg->group.empty())
|
|
||||||
return false;
|
|
||||||
found_groups.insert(arg->group);
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
args.erase(it, args.end());
|
|
||||||
transform(found_groups, std::back_inserter(usage_flags), [&](auto&& group) {
|
|
||||||
std::vector<std::string> either_flags;
|
|
||||||
transform(get_group_arguments(group), std::back_inserter(either_flags), [](auto* arg) {
|
|
||||||
return arg->usage();
|
|
||||||
});
|
|
||||||
return "(" + join_strings(either_flags, "|") + ")";
|
|
||||||
});
|
|
||||||
transform(args, std::back_inserter(usage_flags), [&](auto* arg) { return arg->usage(); });
|
|
||||||
return usage_flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto show_help(const std::string& msg = "")
|
|
||||||
{
|
|
||||||
return do_action([=](auto& self) {
|
|
||||||
argument* input_argument =
|
|
||||||
self.find_argument([](const auto& arg) { return arg.flags.empty(); });
|
|
||||||
auto required_usages = get_argument_usages(get_required_arguments());
|
|
||||||
if(required_usages.empty() and input_argument)
|
|
||||||
required_usages.push_back(input_argument->metavar);
|
|
||||||
required_usages.insert(required_usages.begin(), "<options>");
|
|
||||||
print_usage(required_usages);
|
|
||||||
std::cout << std::endl;
|
|
||||||
if(self.find_argument([](const auto& arg) { return arg.nargs == 0; }))
|
|
||||||
{
|
|
||||||
std::cout << color::fg_yellow << "FLAGS:" << color::reset << std::endl;
|
|
||||||
std::cout << std::endl;
|
|
||||||
for(auto&& arg : self.arguments)
|
|
||||||
{
|
|
||||||
if(arg.nargs != 0)
|
|
||||||
continue;
|
|
||||||
const int col_align = 35;
|
|
||||||
std::string prefix = " ";
|
|
||||||
int len = 0;
|
|
||||||
std::cout << color::fg_green;
|
|
||||||
for(const std::string& a : arg.flags)
|
|
||||||
{
|
|
||||||
len += prefix.length() + a.length();
|
|
||||||
std::cout << prefix;
|
|
||||||
std::cout << a;
|
|
||||||
prefix = ", ";
|
|
||||||
}
|
|
||||||
std::cout << color::reset;
|
|
||||||
int spaces = col_align - len;
|
|
||||||
if(spaces < 0)
|
|
||||||
{
|
|
||||||
std::cout << std::endl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for(int i = 0; i < spaces; i++)
|
|
||||||
std::cout << " ";
|
|
||||||
}
|
|
||||||
std::cout << arg.help << std::endl;
|
|
||||||
}
|
|
||||||
std::cout << std::endl;
|
|
||||||
}
|
|
||||||
if(self.find_argument([](const auto& arg) { return arg.nargs != 0; }))
|
|
||||||
{
|
|
||||||
std::cout << color::fg_yellow << "OPTIONS:" << color::reset << std::endl;
|
|
||||||
for(auto&& arg : self.arguments)
|
|
||||||
{
|
|
||||||
if(arg.nargs == 0)
|
|
||||||
continue;
|
|
||||||
std::cout << std::endl;
|
|
||||||
std::string prefix = " ";
|
|
||||||
std::cout << color::fg_green;
|
|
||||||
if(arg.flags.empty())
|
|
||||||
{
|
|
||||||
std::cout << prefix;
|
|
||||||
std::cout << arg.metavar;
|
|
||||||
}
|
|
||||||
for(const std::string& a : arg.flags)
|
|
||||||
{
|
|
||||||
std::cout << prefix;
|
|
||||||
std::cout << a;
|
|
||||||
prefix = ", ";
|
|
||||||
}
|
|
||||||
std::cout << color::reset;
|
|
||||||
if(not arg.type.empty())
|
|
||||||
{
|
|
||||||
std::cout << " [" << color::fg_blue << arg.type << color::reset << "]";
|
|
||||||
if(not arg.default_value.empty())
|
|
||||||
std::cout << " (Default: " << arg.default_value << ")";
|
|
||||||
}
|
|
||||||
std::cout << std::endl;
|
|
||||||
std::cout << " " << arg.help << std::endl;
|
|
||||||
}
|
|
||||||
std::cout << std::endl;
|
|
||||||
}
|
|
||||||
if(not msg.empty())
|
|
||||||
std::cout << msg << std::endl;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
MIGRAPHX_DRIVER_STATIC auto help(const std::string& help)
|
|
||||||
{
|
|
||||||
return [=](auto&, auto& arg) { arg.help = help; };
|
|
||||||
}
|
|
||||||
|
|
||||||
MIGRAPHX_DRIVER_STATIC auto metavar(const std::string& metavar)
|
|
||||||
{
|
|
||||||
return [=](auto&, auto& arg) { arg.metavar = metavar; };
|
|
||||||
}
|
|
||||||
|
|
||||||
MIGRAPHX_DRIVER_STATIC auto type(const std::string& type)
|
|
||||||
{
|
|
||||||
return [=](auto&, auto& arg) { arg.type = type; };
|
|
||||||
}
|
|
||||||
|
|
||||||
MIGRAPHX_DRIVER_STATIC auto group(const std::string& group)
|
|
||||||
{
|
|
||||||
return [=](auto&, auto& arg) { arg.group = group; };
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
MIGRAPHX_DRIVER_STATIC auto set_value(T value)
|
|
||||||
{
|
|
||||||
return [=](auto& x, auto& arg) {
|
|
||||||
arg.nargs = 0;
|
|
||||||
arg.type = "";
|
|
||||||
arg.action = [&, value](auto&, const std::vector<std::string>&) {
|
|
||||||
x = value;
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
void set_exe_name_to(T& x)
|
|
||||||
{
|
|
||||||
actions.push_back([&](const auto& self) { x = self.exe_name; });
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_try_help()
|
|
||||||
{
|
|
||||||
if(has_argument([](const auto& a) { return contains(a.flags, "--help"); }))
|
|
||||||
{
|
|
||||||
std::cout << std::endl;
|
|
||||||
std::cout << "For more information try '" << color::fg_green << "--help" << color::reset
|
|
||||||
<< "'" << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_usage(const std::vector<std::string>& flags) const
|
|
||||||
{
|
|
||||||
std::cout << color::fg_yellow << "USAGE:" << color::reset << std::endl;
|
|
||||||
std::cout << " " << exe_name << " ";
|
|
||||||
std::cout << join_strings(flags, " ") << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto spellcheck(const std::vector<std::string>& inputs)
|
|
||||||
{
|
|
||||||
struct result_t
|
|
||||||
{
|
|
||||||
const argument* arg = nullptr;
|
|
||||||
std::string correct = "";
|
|
||||||
std::string incorrect = "";
|
|
||||||
std::ptrdiff_t distance = std::numeric_limits<std::ptrdiff_t>::max();
|
|
||||||
};
|
|
||||||
result_t result;
|
|
||||||
for(const auto& input : inputs)
|
|
||||||
{
|
|
||||||
if(input.empty())
|
|
||||||
continue;
|
|
||||||
if(input[0] != '-')
|
|
||||||
continue;
|
|
||||||
for(const auto& arg : arguments)
|
|
||||||
{
|
|
||||||
for(const auto& flag : arg.flags)
|
|
||||||
{
|
|
||||||
if(flag.empty())
|
|
||||||
continue;
|
|
||||||
if(flag[0] != '-')
|
|
||||||
continue;
|
|
||||||
std::ptrdiff_t d = levenshtein_distance(flag, input);
|
|
||||||
if(d < result.distance)
|
|
||||||
result = result_t{&arg, flag, input, d};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
run_action(const argument& arg, const std::string& flag, const std::vector<std::string>& inputs)
|
|
||||||
{
|
|
||||||
std::string msg = "";
|
|
||||||
try
|
|
||||||
{
|
|
||||||
for(const auto& v : arg.validations)
|
|
||||||
v(*this, inputs);
|
|
||||||
return arg.action(*this, inputs);
|
|
||||||
}
|
|
||||||
catch(const std::exception& e)
|
|
||||||
{
|
|
||||||
msg = e.what();
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
msg = "unknown exception";
|
|
||||||
}
|
|
||||||
std::cout << color::fg_red << color::bold << "error: " << color::reset;
|
|
||||||
auto sc = spellcheck(inputs);
|
|
||||||
if(sc.distance < 5)
|
|
||||||
{
|
|
||||||
std::cout << "Found argument '" << color::fg_yellow << sc.incorrect << color::reset
|
|
||||||
<< "'"
|
|
||||||
<< " which wasn't expected, or isn't valid in this context" << std::endl;
|
|
||||||
std::cout << " "
|
|
||||||
<< "Did you mean " << color::fg_green << sc.correct << color::reset << "?"
|
|
||||||
<< std::endl;
|
|
||||||
std::cout << std::endl;
|
|
||||||
print_usage({sc.arg->usage(sc.correct)});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const auto& flag_name = flag.empty() ? arg.metavar : flag;
|
|
||||||
std::cout << "Invalid input to '" << color::fg_yellow;
|
|
||||||
std::cout << arg.usage(flag_name);
|
|
||||||
std::cout << color::reset << "'" << std::endl;
|
|
||||||
std::cout << " " << msg << std::endl;
|
|
||||||
std::cout << std::endl;
|
|
||||||
print_usage({arg.usage()});
|
|
||||||
}
|
|
||||||
std::cout << std::endl;
|
|
||||||
print_try_help();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool parse(std::vector<std::string> args)
|
|
||||||
{
|
|
||||||
std::unordered_map<std::string, unsigned> keywords;
|
|
||||||
for(auto&& arg : arguments)
|
|
||||||
{
|
|
||||||
for(auto&& flag : arg.flags)
|
|
||||||
keywords[flag] = arg.nargs + 1;
|
|
||||||
}
|
|
||||||
auto arg_map =
|
|
||||||
generic_parse(std::move(args), [&](const std::string& x) { return keywords[x]; });
|
|
||||||
std::list<const argument*> missing_arguments;
|
|
||||||
std::unordered_set<std::string> groups_used;
|
|
||||||
for(auto&& arg : arguments)
|
|
||||||
{
|
|
||||||
bool used = false;
|
|
||||||
auto flags = arg.flags;
|
|
||||||
if(flags.empty())
|
|
||||||
flags = {""};
|
|
||||||
for(auto&& flag : flags)
|
|
||||||
{
|
|
||||||
if(arg_map.count(flag) > 0)
|
|
||||||
{
|
|
||||||
if(run_action(arg, flag, arg_map[flag]))
|
|
||||||
return true;
|
|
||||||
used = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(used and not arg.group.empty())
|
|
||||||
groups_used.insert(arg.group);
|
|
||||||
if(arg.required and not used)
|
|
||||||
missing_arguments.push_back(&arg);
|
|
||||||
}
|
|
||||||
// Remove arguments from a group that is being used
|
|
||||||
missing_arguments.remove_if(
|
|
||||||
[&](const argument* arg) { return groups_used.count(arg->group); });
|
|
||||||
if(not missing_arguments.empty())
|
|
||||||
{
|
|
||||||
std::cout << color::fg_red << color::bold << "error: " << color::reset;
|
|
||||||
std::cout << "The following required arguments were not provided:" << std::endl;
|
|
||||||
std::cout << " " << color::fg_red
|
|
||||||
<< join_strings(get_argument_usages(std::move(missing_arguments)), " ")
|
|
||||||
<< color::reset << std::endl;
|
|
||||||
std::cout << std::endl;
|
|
||||||
auto required_usages = get_argument_usages(get_required_arguments());
|
|
||||||
print_usage(required_usages);
|
|
||||||
print_try_help();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
for(auto&& action : actions)
|
|
||||||
action(*this);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_exe_name(const std::string& s) { exe_name = s; }
|
|
||||||
|
|
||||||
const std::string& get_exe_name() const { return exe_name; }
|
|
||||||
|
|
||||||
using string_map = std::unordered_map<std::string, std::vector<std::string>>;
|
|
||||||
template <class IsKeyword>
|
|
||||||
static string_map generic_parse(std::vector<std::string> as, IsKeyword is_keyword)
|
|
||||||
{
|
|
||||||
string_map result;
|
|
||||||
|
|
||||||
std::string flag;
|
|
||||||
bool clear = false;
|
|
||||||
for(auto&& x : as)
|
|
||||||
{
|
|
||||||
auto k = is_keyword(x);
|
|
||||||
if(k > 0)
|
|
||||||
{
|
|
||||||
flag = x;
|
|
||||||
result[flag]; // Ensure the flag exists
|
|
||||||
if(k == 1)
|
|
||||||
flag = "";
|
|
||||||
else if(k == 2)
|
|
||||||
clear = true;
|
|
||||||
else
|
|
||||||
clear = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result[flag].push_back(x);
|
|
||||||
if(clear)
|
|
||||||
flag = "";
|
|
||||||
clear = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::list<argument> arguments;
|
|
||||||
std::string exe_name = "";
|
|
||||||
std::vector<std::function<void(argument_parser&)>> actions;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace driver
|
|
||||||
} // namespace migraphx
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,116 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2022 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_RTGLIB_COMMAND_HPP
|
|
||||||
#define MIGRAPHX_GUARD_RTGLIB_COMMAND_HPP
|
|
||||||
|
|
||||||
#include "argument_parser.hpp"
|
|
||||||
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
#include <migraphx/type_name.hpp>
|
|
||||||
#include <migraphx/stringutils.hpp>
|
|
||||||
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <utility>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
namespace driver {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
inline auto& get_commands()
|
|
||||||
{
|
|
||||||
// NOLINTNEXTLINE
|
|
||||||
static std::unordered_map<
|
|
||||||
std::string,
|
|
||||||
std::function<void(const std::string& exe_name, std::vector<std::string> args)>>
|
|
||||||
m;
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
std::string compute_command_name()
|
|
||||||
{
|
|
||||||
static const std::string& tname = get_type_name<T>();
|
|
||||||
auto name = tname.substr(tname.rfind("::") + 2);
|
|
||||||
if(ends_with(name, "_command"))
|
|
||||||
name = name.substr(0, name.size() - 8);
|
|
||||||
if(ends_with(name, "_cmd"))
|
|
||||||
name = name.substr(0, name.size() - 4);
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
const std::string& command_name()
|
|
||||||
{
|
|
||||||
static const std::string& name = compute_command_name<T>();
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
void run_command(const std::string& exe_name, std::vector<std::string> args, bool add_help = false)
|
|
||||||
{
|
|
||||||
T x;
|
|
||||||
argument_parser ap;
|
|
||||||
ap.set_exe_name(exe_name + " " + command_name<T>());
|
|
||||||
if(add_help)
|
|
||||||
ap(nullptr, {"-h", "--help"}, ap.help("Show help"), ap.show_help());
|
|
||||||
x.parse(ap);
|
|
||||||
if(ap.parse(std::move(args)))
|
|
||||||
return;
|
|
||||||
x.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
int auto_register_command()
|
|
||||||
{
|
|
||||||
auto& m = get_commands();
|
|
||||||
m[command_name<T>()] = [](const std::string& exe_name, std::vector<std::string> args) {
|
|
||||||
run_command<T>(exe_name, args, true);
|
|
||||||
};
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
struct command
|
|
||||||
{
|
|
||||||
static const int static_register;
|
|
||||||
// This typedef ensures that the static member will be instantiated if
|
|
||||||
// the class itself is instantiated
|
|
||||||
using static_register_type =
|
|
||||||
std::integral_constant<decltype(&static_register), &static_register>;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef __clang__
|
|
||||||
#pragma clang diagnostic push
|
|
||||||
#pragma clang diagnostic ignored "-Wglobal-constructors"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
const int command<T>::static_register = auto_register_command<T>(); // NOLINT
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace driver
|
|
||||||
} // namespace migraphx
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,969 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "verify.hpp"
|
|
||||||
#include "verify_options.hpp"
|
|
||||||
#include "argument_parser.hpp"
|
|
||||||
#include "command.hpp"
|
|
||||||
#include "mlir.hpp"
|
|
||||||
#include "precision.hpp"
|
|
||||||
#include "passes.hpp"
|
|
||||||
#include "perf.hpp"
|
|
||||||
#include "models.hpp"
|
|
||||||
#include "marker_roctx.hpp"
|
|
||||||
|
|
||||||
#include <migraphx/tf.hpp>
|
|
||||||
#include <migraphx/onnx.hpp>
|
|
||||||
#ifdef MIGRAPHX_ENABLE_PYTHON
|
|
||||||
#include <migraphx/py.hpp>
|
|
||||||
#endif
|
|
||||||
#include <migraphx/stringutils.hpp>
|
|
||||||
#include <migraphx/convert_to_json.hpp>
|
|
||||||
#include <migraphx/load_save.hpp>
|
|
||||||
#include <migraphx/json.hpp>
|
|
||||||
#include <migraphx/version.h>
|
|
||||||
|
|
||||||
#include <migraphx/dead_code_elimination.hpp>
|
|
||||||
#include <migraphx/eliminate_identity.hpp>
|
|
||||||
#include <migraphx/eliminate_pad.hpp>
|
|
||||||
#include <migraphx/generate.hpp>
|
|
||||||
#include <migraphx/pass_manager.hpp>
|
|
||||||
#include <migraphx/propagate_constant.hpp>
|
|
||||||
#include <migraphx/quantization.hpp>
|
|
||||||
#include <migraphx/register_op.hpp>
|
|
||||||
#include <migraphx/simplify_algebra.hpp>
|
|
||||||
#include <migraphx/simplify_reshapes.hpp>
|
|
||||||
#include <migraphx/register_target.hpp>
|
|
||||||
|
|
||||||
#include <migraphx/netron_output.hpp>
|
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
namespace driver {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
inline std::string get_version()
|
|
||||||
{
|
|
||||||
return "MIGraphX Version: " + std::to_string(MIGRAPHX_VERSION_MAJOR) + "." +
|
|
||||||
std::to_string(MIGRAPHX_VERSION_MINOR) + "." + std::to_string(MIGRAPHX_VERSION_PATCH) +
|
|
||||||
"." MIGRAPHX_VERSION_TWEAK;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct loader
|
|
||||||
{
|
|
||||||
std::string file;
|
|
||||||
std::string file_type;
|
|
||||||
unsigned batch = 1;
|
|
||||||
bool is_nhwc = true;
|
|
||||||
bool is_test = false;
|
|
||||||
unsigned trim = 0;
|
|
||||||
bool optimize = false;
|
|
||||||
bool mlir = false;
|
|
||||||
bool skip_unknown_operators = false;
|
|
||||||
bool brief = false;
|
|
||||||
std::string output_type;
|
|
||||||
std::string output;
|
|
||||||
std::string default_dyn_dim;
|
|
||||||
std::vector<std::string> param_dims;
|
|
||||||
std::vector<std::string> dim_params;
|
|
||||||
std::vector<std::string> dyn_param_dims;
|
|
||||||
std::vector<std::string> output_names;
|
|
||||||
std::vector<std::string> passes;
|
|
||||||
|
|
||||||
void parse(argument_parser& ap)
|
|
||||||
{
|
|
||||||
ap(file, {}, ap.metavar("<input file>"), ap.file_exist(), ap.required(), ap.group("input"));
|
|
||||||
ap(is_test,
|
|
||||||
{"--test"},
|
|
||||||
ap.help("Run a single GEMM to test MIGraphX"),
|
|
||||||
ap.set_value(true),
|
|
||||||
ap.group("input"));
|
|
||||||
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, {"--migraphx"}, ap.help("Load as MIGraphX"), ap.set_value("migraphx"));
|
|
||||||
ap(file_type, {"--migraphx-json"}, ap.help("Load as MIGraphX JSON"), ap.set_value("json"));
|
|
||||||
ap(batch,
|
|
||||||
{"--batch"},
|
|
||||||
ap.help("For a static model, sets default_dim_value size (commonly batch size). For a "
|
|
||||||
"dynamic batch model, sets the batch "
|
|
||||||
"size at runtime."));
|
|
||||||
ap(is_nhwc, {"--nhwc"}, ap.help("Treat tensorflow format as nhwc"), ap.set_value(true));
|
|
||||||
ap(skip_unknown_operators,
|
|
||||||
{"--skip-unknown-operators"},
|
|
||||||
ap.help("Skip unknown operators when parsing and continue to parse."),
|
|
||||||
ap.set_value(true));
|
|
||||||
ap(is_nhwc, {"--nchw"}, ap.help("Treat tensorflow format as nchw"), ap.set_value(false));
|
|
||||||
ap(trim, {"--trim", "-t"}, ap.help("Trim instructions from the end"));
|
|
||||||
ap(param_dims,
|
|
||||||
{"--input-dim"},
|
|
||||||
ap.help("Dim of a parameter (format: \"@name d1 d2 dn\")"),
|
|
||||||
ap.append(),
|
|
||||||
ap.nargs(2));
|
|
||||||
ap(dim_params,
|
|
||||||
{"--dim-param"},
|
|
||||||
ap.help("Symbolic parameter dimension name (fixed / dynamic) - "
|
|
||||||
"(fixed format): \"@dim_param_name\" \"x\" / "
|
|
||||||
"(dynamic format): \"@dim_param_name\" \"{min:x, max:y, optimals:[o1,o2]}\""),
|
|
||||||
ap.append(),
|
|
||||||
ap.nargs(2));
|
|
||||||
ap(dyn_param_dims,
|
|
||||||
{"--dyn-input-dim"},
|
|
||||||
ap.help("Dynamic dimensions of a parameter (format: \"@name_1\" \"[{min:x, max:y, "
|
|
||||||
"optimals:[o1,o2,...]}, dim2,dim3, ...]\", \"@name_2\", ... You can supply a "
|
|
||||||
"single integer value for a dimension to specify it as fixed."),
|
|
||||||
ap.append(),
|
|
||||||
ap.nargs(2));
|
|
||||||
ap(default_dyn_dim,
|
|
||||||
{"--default-dyn-dim"},
|
|
||||||
ap.help("Default dynamic dimension (format: \"{min:x, max:y, optimals:[o1,o2]}\")."));
|
|
||||||
ap(output_names,
|
|
||||||
{"--output-names"},
|
|
||||||
ap.help("Names of node output (format: \"name_1 name_2 name_n\")"),
|
|
||||||
ap.append(),
|
|
||||||
ap.nargs(2));
|
|
||||||
ap(optimize, {"--optimize", "-O"}, ap.help("Optimize when reading"), ap.set_value(true));
|
|
||||||
ap(mlir, {"--mlir"}, ap.help("Offload everything to mlir"), ap.set_value(true));
|
|
||||||
ap(passes, {"--apply-pass", "-p"}, ap.help("Passes to apply to model"), ap.append());
|
|
||||||
ap(output_type,
|
|
||||||
{"--graphviz", "-g"},
|
|
||||||
ap.help("Print out a graphviz representation."),
|
|
||||||
ap.set_value("graphviz"));
|
|
||||||
ap(brief, {"--brief"}, ap.help("Make the output brief."), ap.set_value(true));
|
|
||||||
ap(output_type,
|
|
||||||
{"--cpp"},
|
|
||||||
ap.help("Print out the program as C++ program."),
|
|
||||||
ap.set_value("cpp"));
|
|
||||||
ap(output_type,
|
|
||||||
{"--python", "--py"},
|
|
||||||
ap.help("Print out the program as python program."),
|
|
||||||
ap.set_value("py"));
|
|
||||||
ap(output_type, {"--json"}, ap.help("Print out program as json."), ap.set_value("json"));
|
|
||||||
ap(output_type,
|
|
||||||
{"--text"},
|
|
||||||
ap.help("Print out program in text format."),
|
|
||||||
ap.set_value("text"));
|
|
||||||
ap(output_type,
|
|
||||||
{"--binary"},
|
|
||||||
ap.help("Print out program in binary format."),
|
|
||||||
ap.set_value("binary"));
|
|
||||||
ap(output_type,
|
|
||||||
{"--netron"},
|
|
||||||
ap.help("Print out program as Netron readable json."),
|
|
||||||
ap.set_value("netron"));
|
|
||||||
ap(output, {"--output", "-o"}, ap.help("Output to file."));
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto parse_param_dims(const std::vector<std::string>& param_dims_info)
|
|
||||||
{
|
|
||||||
std::unordered_map<std::string, std::vector<std::size_t>> map_input_dims;
|
|
||||||
std::string name = "";
|
|
||||||
for(auto&& x : param_dims_info)
|
|
||||||
{
|
|
||||||
if(x[0] == '@')
|
|
||||||
{
|
|
||||||
name = x.substr(1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
map_input_dims[name].push_back(value_parser<std::size_t>::apply(x));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return map_input_dims;
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto parse_dyn_dims_json(const std::string& dd_json)
|
|
||||||
{
|
|
||||||
// expecting a json string like "[{min:1,max:64,optimals:[1,2,4,8]},3,224,224]"
|
|
||||||
auto v = from_json_string(convert_to_json(dd_json));
|
|
||||||
std::vector<migraphx::shape::dynamic_dimension> dyn_dims;
|
|
||||||
std::transform(v.begin(), v.end(), std::back_inserter(dyn_dims), [&](auto x) {
|
|
||||||
if(x.is_object())
|
|
||||||
return from_value<migraphx::shape::dynamic_dimension>(x);
|
|
||||||
auto d = x.template to<std::size_t>();
|
|
||||||
return migraphx::shape::dynamic_dimension{d, d};
|
|
||||||
});
|
|
||||||
return dyn_dims;
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto parse_dyn_dims_map(const std::vector<std::string>& param_dyn_dims)
|
|
||||||
{
|
|
||||||
// expecting vector of strings formatted like
|
|
||||||
// {"@param_name_0", "dd_json_0", "@param_name_1", "dd_json_1", ...}
|
|
||||||
std::unordered_map<std::string, std::vector<shape::dynamic_dimension>> map_dyn_input_dims;
|
|
||||||
std::string name = "";
|
|
||||||
for(auto&& x : param_dyn_dims)
|
|
||||||
{
|
|
||||||
if(x[0] == '@')
|
|
||||||
{
|
|
||||||
name = x.substr(1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
map_dyn_input_dims[name] = parse_dyn_dims_json(x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return map_dyn_input_dims;
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto parse_dim_params(const std::vector<std::string>& dim_params_info)
|
|
||||||
{
|
|
||||||
std::unordered_map<std::string, shape::dynamic_dimension> map_dim_params;
|
|
||||||
std::string name = "";
|
|
||||||
for(auto&& x : dim_params_info)
|
|
||||||
{
|
|
||||||
if(x[0] == '@')
|
|
||||||
{
|
|
||||||
name = x.substr(1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(std::all_of(x.begin(), x.end(), [](char ch) {
|
|
||||||
return std::isdigit(static_cast<unsigned char>(ch));
|
|
||||||
}))
|
|
||||||
map_dim_params[name] = {std::stoul(x), std::stoul(x)};
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto dyn_dim = parse_dyn_dims_json(x);
|
|
||||||
if(dyn_dim.size() != 1)
|
|
||||||
MIGRAPHX_THROW("dim_param must only specifiy one dimension");
|
|
||||||
map_dim_params[name] = dyn_dim.front();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return map_dim_params;
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto parse_output_names(const std::vector<std::string>& output_names_info)
|
|
||||||
{
|
|
||||||
std::vector<std::string> output_node_names;
|
|
||||||
std::transform(output_names_info.begin(),
|
|
||||||
output_names_info.end(),
|
|
||||||
std::back_inserter(output_node_names),
|
|
||||||
[&](auto x) { return value_parser<std::string>::apply(x); });
|
|
||||||
|
|
||||||
return output_node_names;
|
|
||||||
}
|
|
||||||
|
|
||||||
tf_options get_tf_options() const
|
|
||||||
{
|
|
||||||
auto map_input_dims = parse_param_dims(param_dims);
|
|
||||||
auto output_node_names = parse_output_names(output_names);
|
|
||||||
tf_options options;
|
|
||||||
options.is_nhwc = is_nhwc;
|
|
||||||
options.batch_size = batch;
|
|
||||||
options.map_input_dims = map_input_dims;
|
|
||||||
options.output_node_names = output_node_names;
|
|
||||||
return options;
|
|
||||||
}
|
|
||||||
|
|
||||||
onnx_options get_onnx_options() const
|
|
||||||
{
|
|
||||||
auto map_input_dims = parse_param_dims(param_dims);
|
|
||||||
auto map_dyn_input_dims = parse_dyn_dims_map(dyn_param_dims);
|
|
||||||
auto map_dim_params = parse_dim_params(dim_params);
|
|
||||||
onnx_options options;
|
|
||||||
if(default_dyn_dim.empty())
|
|
||||||
{
|
|
||||||
options.default_dim_value = batch;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto v = from_json_string(convert_to_json(default_dyn_dim));
|
|
||||||
options.default_dyn_dim_value = from_value<migraphx::shape::dynamic_dimension>(v);
|
|
||||||
}
|
|
||||||
options.skip_unknown_operators = skip_unknown_operators;
|
|
||||||
options.print_program_on_error = true;
|
|
||||||
options.map_input_dims = map_input_dims;
|
|
||||||
options.map_dyn_input_dims = map_dyn_input_dims;
|
|
||||||
options.dim_params = map_dim_params;
|
|
||||||
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 p;
|
|
||||||
if(is_test)
|
|
||||||
{
|
|
||||||
p = test_gemm();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(file_type.empty())
|
|
||||||
{
|
|
||||||
file_type = get_file_type(file);
|
|
||||||
}
|
|
||||||
std::cout << "Reading: " << file << std::endl;
|
|
||||||
if(file_type == "onnx")
|
|
||||||
{
|
|
||||||
p = parse_onnx(file, get_onnx_options());
|
|
||||||
}
|
|
||||||
else if(file_type == "tf")
|
|
||||||
{
|
|
||||||
p = parse_tf(file, get_tf_options());
|
|
||||||
}
|
|
||||||
else if(file_type == "json")
|
|
||||||
{
|
|
||||||
file_options options;
|
|
||||||
options.format = "json";
|
|
||||||
p = migraphx::load(file, options);
|
|
||||||
}
|
|
||||||
#ifdef MIGRAPHX_ENABLE_PYTHON
|
|
||||||
else if(file_type == "py")
|
|
||||||
{
|
|
||||||
p = migraphx::load_py(file);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else if(file_type == "migraphx")
|
|
||||||
{
|
|
||||||
p = migraphx::load(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(trim > 0)
|
|
||||||
{
|
|
||||||
auto* mm = p.get_main_module();
|
|
||||||
auto last = std::prev(mm->end(), trim);
|
|
||||||
mm->remove_instructions(last, mm->end());
|
|
||||||
}
|
|
||||||
// Remove unused variable when exporting to cpp
|
|
||||||
if(output_type == "cpp")
|
|
||||||
migraphx::run_passes(*p.get_main_module(), {migraphx::dead_code_elimination{}});
|
|
||||||
if(optimize)
|
|
||||||
{
|
|
||||||
migraphx::run_passes(*p.get_main_module(),
|
|
||||||
{
|
|
||||||
migraphx::eliminate_identity{},
|
|
||||||
migraphx::dead_code_elimination{},
|
|
||||||
migraphx::simplify_algebra{},
|
|
||||||
migraphx::dead_code_elimination{},
|
|
||||||
migraphx::simplify_reshapes{},
|
|
||||||
migraphx::dead_code_elimination{},
|
|
||||||
migraphx::propagate_constant{},
|
|
||||||
migraphx::dead_code_elimination{},
|
|
||||||
migraphx::eliminate_pad{},
|
|
||||||
migraphx::dead_code_elimination{},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if(not passes.empty())
|
|
||||||
migraphx::run_passes(p, get_passes(passes));
|
|
||||||
if(mlir)
|
|
||||||
offload_to_mlir(p);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void write(std::ostream& os, const std::vector<char>& buffer)
|
|
||||||
{
|
|
||||||
os.write(buffer.data(), buffer.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
void save(const program& p) const
|
|
||||||
{
|
|
||||||
auto* os = &std::cout;
|
|
||||||
std::ofstream fs;
|
|
||||||
if(not output.empty())
|
|
||||||
{
|
|
||||||
fs.open(output, std::ios::binary);
|
|
||||||
os = &fs;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string type = output_type;
|
|
||||||
if(type.empty())
|
|
||||||
{
|
|
||||||
if(output.empty())
|
|
||||||
type = "text";
|
|
||||||
else
|
|
||||||
type = "binary";
|
|
||||||
}
|
|
||||||
|
|
||||||
if(type == "py")
|
|
||||||
p.print_py(*os);
|
|
||||||
else if(type == "cpp")
|
|
||||||
p.print_cpp(*os);
|
|
||||||
else if(type == "graphviz")
|
|
||||||
p.print_graph(*os, brief);
|
|
||||||
else if(type == "text")
|
|
||||||
*os << p << std::endl;
|
|
||||||
else if(type == "json")
|
|
||||||
*os << to_json_string(p.to_value()) << std::endl;
|
|
||||||
else if(type == "binary")
|
|
||||||
write(*os, save_buffer(p));
|
|
||||||
else if(type == "netron")
|
|
||||||
*os << make_netron_output(p) << std::endl;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct program_params
|
|
||||||
{
|
|
||||||
std::vector<std::string> fill0{};
|
|
||||||
std::vector<std::string> fill1{};
|
|
||||||
void parse(argument_parser& ap)
|
|
||||||
{
|
|
||||||
ap(fill0, {"--fill0"}, ap.help("Fill parameter with 0s"), ap.append(), ap.nargs(2));
|
|
||||||
ap(fill1, {"--fill1"}, ap.help("Fill parameter with 1s"), ap.append(), ap.nargs(2));
|
|
||||||
}
|
|
||||||
|
|
||||||
auto generate(const program& p, const target& t, bool offload, unsigned batch)
|
|
||||||
{
|
|
||||||
parameter_map m;
|
|
||||||
auto param_shapes = p.get_parameter_shapes();
|
|
||||||
std::unordered_map<std::string, shape> static_param_shapes;
|
|
||||||
std::transform(
|
|
||||||
param_shapes.cbegin(),
|
|
||||||
param_shapes.cend(),
|
|
||||||
std::inserter(static_param_shapes, static_param_shapes.end()),
|
|
||||||
[&](const auto& x) { return std::make_pair(x.first, x.second.to_static(batch)); });
|
|
||||||
for(auto&& s : fill0)
|
|
||||||
m[s] = fill_argument(static_param_shapes.at(s), 0);
|
|
||||||
for(auto&& s : fill1)
|
|
||||||
m[s] = fill_argument(static_param_shapes.at(s), 1);
|
|
||||||
fill_param_map(m, static_param_shapes, t, offload);
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct compiler_target
|
|
||||||
{
|
|
||||||
#ifdef HAVE_GPU
|
|
||||||
std::string target_name = "gpu";
|
|
||||||
#elif defined(HAVE_CPU)
|
|
||||||
std::string target_name = "cpu";
|
|
||||||
#elif defined(HAVE_FPGA)
|
|
||||||
std::string target_name = "fpga";
|
|
||||||
#else
|
|
||||||
std::string target_name = "ref";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void parse(argument_parser& ap)
|
|
||||||
{
|
|
||||||
ap(target_name, {"--gpu"}, ap.help("Compile on the gpu"), ap.set_value("gpu"));
|
|
||||||
ap(target_name, {"--cpu"}, ap.help("Compile on the cpu"), ap.set_value("cpu"));
|
|
||||||
ap(target_name,
|
|
||||||
{"--ref"},
|
|
||||||
ap.help("Compile on the reference implementation"),
|
|
||||||
ap.set_value("ref"));
|
|
||||||
}
|
|
||||||
|
|
||||||
target get_target() const { return make_target(target_name); }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct compiler
|
|
||||||
{
|
|
||||||
loader l;
|
|
||||||
program_params parameters;
|
|
||||||
compiler_target ct;
|
|
||||||
compile_options co;
|
|
||||||
bool to_fp16 = false;
|
|
||||||
bool to_bf16 = false;
|
|
||||||
bool to_fp8 = false;
|
|
||||||
bool to_int8 = false;
|
|
||||||
bool to_int4 = false;
|
|
||||||
|
|
||||||
std::vector<std::string> fill0;
|
|
||||||
std::vector<std::string> fill1;
|
|
||||||
void parse(argument_parser& ap)
|
|
||||||
{
|
|
||||||
l.parse(ap);
|
|
||||||
parameters.parse(ap);
|
|
||||||
ct.parse(ap);
|
|
||||||
ap(co.offload_copy,
|
|
||||||
{"--enable-offload-copy"},
|
|
||||||
ap.help("Enable implicit offload copying"),
|
|
||||||
ap.set_value(true));
|
|
||||||
ap(co.fast_math,
|
|
||||||
{"--disable-fast-math"},
|
|
||||||
ap.help("Disable fast math optimization"),
|
|
||||||
ap.set_value(false));
|
|
||||||
ap(co.exhaustive_tune,
|
|
||||||
{"--exhaustive-tune"},
|
|
||||||
ap.help("Exhastively search for best tuning parameters for kernels"),
|
|
||||||
ap.set_value(true));
|
|
||||||
ap(to_fp16, {"--fp16"}, ap.help("Quantize for fp16"), ap.set_value(true));
|
|
||||||
ap(to_bf16, {"--bf16"}, ap.help("Quantize for bf16"), ap.set_value(true));
|
|
||||||
ap(to_int8, {"--int8"}, ap.help("Quantize for int8"), ap.set_value(true));
|
|
||||||
ap(to_fp8, {"--fp8"}, ap.help("Quantize for fp8"), ap.set_value(true));
|
|
||||||
ap(to_int4, {"--int4-weights"}, ap.help("Quantize weights for int4"), ap.set_value(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
auto params(const program& p)
|
|
||||||
{
|
|
||||||
return parameters.generate(p, ct.get_target(), co.offload_copy, l.batch);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto host_params(const program& p)
|
|
||||||
{
|
|
||||||
return parameters.generate(p, ct.get_target(), true, l.batch);
|
|
||||||
}
|
|
||||||
|
|
||||||
program compile()
|
|
||||||
{
|
|
||||||
auto p = l.load();
|
|
||||||
// Dont compile if its already been compiled
|
|
||||||
|
|
||||||
if(p.is_compiled())
|
|
||||||
{
|
|
||||||
if(ct.target_name == "gpu")
|
|
||||||
{
|
|
||||||
if(is_offload_copy_set(p) and not co.offload_copy)
|
|
||||||
{
|
|
||||||
std::cout
|
|
||||||
<< "[WARNING]: MIGraphX program was likely compiled with offload_copy "
|
|
||||||
"set, Try "
|
|
||||||
"passing "
|
|
||||||
"`--enable-offload-copy` if program run fails.\n";
|
|
||||||
}
|
|
||||||
else if(not is_offload_copy_set(p) and co.offload_copy)
|
|
||||||
{
|
|
||||||
std::cout << "[WARNING]: MIGraphX program was likely compiled without "
|
|
||||||
"offload_copy set, Try "
|
|
||||||
"removing "
|
|
||||||
"`--enable-offload-copy` if program run "
|
|
||||||
"fails.\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
auto t = ct.get_target();
|
|
||||||
if(to_fp16)
|
|
||||||
{
|
|
||||||
quantize_fp16(p);
|
|
||||||
}
|
|
||||||
if(to_bf16)
|
|
||||||
{
|
|
||||||
quantize_bf16(p);
|
|
||||||
}
|
|
||||||
if(to_int8)
|
|
||||||
{
|
|
||||||
quantize_int8(p, t, {host_params(p)});
|
|
||||||
}
|
|
||||||
if(to_fp8)
|
|
||||||
{
|
|
||||||
quantize_fp8(p, t, {host_params(p)});
|
|
||||||
}
|
|
||||||
if(to_int4)
|
|
||||||
{
|
|
||||||
quantize_int4_weights(p);
|
|
||||||
}
|
|
||||||
p.compile(t, co);
|
|
||||||
l.save(p);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct read : command<read>
|
|
||||||
{
|
|
||||||
loader l;
|
|
||||||
void parse(argument_parser& ap) { l.parse(ap); }
|
|
||||||
|
|
||||||
void run()
|
|
||||||
{
|
|
||||||
auto p = l.load();
|
|
||||||
l.save(p);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct params : command<params>
|
|
||||||
{
|
|
||||||
loader l;
|
|
||||||
void parse(argument_parser& ap) { l.parse(ap); }
|
|
||||||
|
|
||||||
void run()
|
|
||||||
{
|
|
||||||
auto p = l.load();
|
|
||||||
for(auto&& param : p.get_parameter_shapes())
|
|
||||||
std::cout << param.first << ": " << param.second << std::endl;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct verify : command<verify>
|
|
||||||
{
|
|
||||||
compiler c;
|
|
||||||
std::optional<double> rms_tol;
|
|
||||||
std::optional<double> atol;
|
|
||||||
std::optional<double> rtol;
|
|
||||||
bool per_instruction = false;
|
|
||||||
bool reduce = false;
|
|
||||||
bool bisect = false;
|
|
||||||
verify_options vo;
|
|
||||||
void parse(argument_parser& ap)
|
|
||||||
{
|
|
||||||
c.parse(ap);
|
|
||||||
ap(rms_tol, {"--rms-tol"}, ap.help("Tolerance for the RMS error"));
|
|
||||||
ap(atol, {"--atol"}, ap.help("Tolerance for the elementwise absolute difference"));
|
|
||||||
ap(rtol, {"--rtol"}, ap.help("Tolerance for the elementwise relative difference"));
|
|
||||||
ap(per_instruction,
|
|
||||||
{"-i", "--per-instruction"},
|
|
||||||
ap.help("Verify each instruction"),
|
|
||||||
ap.set_value(true));
|
|
||||||
ap(reduce, {"-r", "--reduce"}, ap.help("Reduce program and verify"), ap.set_value(true));
|
|
||||||
ap(bisect, {"-b", "--bisect"}, ap.help("Bisect program and verify"), ap.set_value(true));
|
|
||||||
ap(vo.ref_use_double,
|
|
||||||
{"--ref-use-double"},
|
|
||||||
ap.help("Convert floating point values to double on ref"),
|
|
||||||
ap.set_value(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
void run()
|
|
||||||
{
|
|
||||||
auto p = c.l.load();
|
|
||||||
c.l.save(p);
|
|
||||||
std::cout << p << std::endl;
|
|
||||||
|
|
||||||
auto t = c.ct.get_target();
|
|
||||||
auto m = c.parameters.generate(p, t, true, c.l.batch);
|
|
||||||
|
|
||||||
if(c.to_fp16)
|
|
||||||
{
|
|
||||||
vo.quantize = precision::fp16;
|
|
||||||
}
|
|
||||||
if(c.to_bf16)
|
|
||||||
{
|
|
||||||
vo.quantize = precision::bf16;
|
|
||||||
}
|
|
||||||
if(c.to_int8)
|
|
||||||
{
|
|
||||||
vo.quantize = precision::int8;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto tols = get_tolerances(p, vo, rms_tol, atol, rtol);
|
|
||||||
std::cout << "rms_tol: " << tols.rms_tol << std::endl;
|
|
||||||
std::cout << "atol: " << tols.atol << std::endl;
|
|
||||||
std::cout << "rtol: " << tols.rtol << std::endl;
|
|
||||||
|
|
||||||
if(per_instruction)
|
|
||||||
{
|
|
||||||
verify_instructions(p, t, c.co, vo, tols);
|
|
||||||
}
|
|
||||||
else if(reduce)
|
|
||||||
{
|
|
||||||
verify_reduced_program(p, t, c.co, vo, m, tols);
|
|
||||||
}
|
|
||||||
else if(bisect)
|
|
||||||
{
|
|
||||||
verify_bisected_program(p, t, c.co, vo, m, tols);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
verify_program(c.l.file, p, t, c.co, vo, m, tols);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct compile : command<compile>
|
|
||||||
{
|
|
||||||
compiler c;
|
|
||||||
void parse(argument_parser& ap) { c.parse(ap); }
|
|
||||||
|
|
||||||
void run()
|
|
||||||
{
|
|
||||||
std::cout << "Compiling ... " << std::endl;
|
|
||||||
c.compile();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct run_cmd : command<run_cmd>
|
|
||||||
{
|
|
||||||
compiler c;
|
|
||||||
void parse(argument_parser& ap) { c.parse(ap); }
|
|
||||||
|
|
||||||
void run()
|
|
||||||
{
|
|
||||||
std::cout << "Compiling ... " << std::endl;
|
|
||||||
auto p = c.compile();
|
|
||||||
std::cout << "Allocating params ... " << std::endl;
|
|
||||||
auto m = c.params(p);
|
|
||||||
p.eval(m);
|
|
||||||
std::cout << p << std::endl;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct time_cmd : command<time_cmd>
|
|
||||||
{
|
|
||||||
compiler c;
|
|
||||||
unsigned n = 100;
|
|
||||||
void parse(argument_parser& ap)
|
|
||||||
{
|
|
||||||
ap(n, {"--iterations", "-n"}, ap.help("Number of iterations to run."));
|
|
||||||
c.parse(ap);
|
|
||||||
}
|
|
||||||
|
|
||||||
void run()
|
|
||||||
{
|
|
||||||
std::cout << "Compiling ... " << std::endl;
|
|
||||||
auto p = c.compile();
|
|
||||||
std::cout << "Allocating params ... " << std::endl;
|
|
||||||
auto m = c.params(p);
|
|
||||||
std::cout << "Running ... " << std::endl;
|
|
||||||
double t = time_run(p, m, n);
|
|
||||||
std::cout << "Total time: " << t << "ms" << std::endl;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct perf : command<perf>
|
|
||||||
{
|
|
||||||
compiler c;
|
|
||||||
unsigned n = 100;
|
|
||||||
bool detailed = false;
|
|
||||||
void parse(argument_parser& ap)
|
|
||||||
{
|
|
||||||
c.parse(ap);
|
|
||||||
ap(n, {"--iterations", "-n"}, ap.help("Number of iterations to run for perf report"));
|
|
||||||
ap(detailed,
|
|
||||||
{"--detailed", "-d"},
|
|
||||||
ap.help("Show a more detailed summary report"),
|
|
||||||
ap.set_value(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
void run()
|
|
||||||
{
|
|
||||||
std::cout << "Compiling ... " << std::endl;
|
|
||||||
auto p = c.compile();
|
|
||||||
std::cout << "Allocating params ... " << std::endl;
|
|
||||||
auto m = c.params(p);
|
|
||||||
std::cout << "Running performance report ... " << std::endl;
|
|
||||||
p.perf_report(std::cout, n, m, c.l.batch, detailed);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct roctx : command<roctx>
|
|
||||||
{
|
|
||||||
compiler c;
|
|
||||||
void parse(argument_parser& ap) { c.parse(ap); }
|
|
||||||
|
|
||||||
void run()
|
|
||||||
{
|
|
||||||
std::cout << "Compiling ... " << std::endl;
|
|
||||||
auto p = c.compile();
|
|
||||||
std::cout << "Allocating params ... " << std::endl;
|
|
||||||
auto m = c.params(p);
|
|
||||||
std::cout << "rocTX:\tLoading rocTX library..." << std::endl;
|
|
||||||
auto rtx = create_marker_roctx();
|
|
||||||
p.mark(m, std::move(rtx));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct op : command<op>
|
|
||||||
{
|
|
||||||
bool show_ops = false;
|
|
||||||
std::string op_name{};
|
|
||||||
void parse(argument_parser& ap)
|
|
||||||
{
|
|
||||||
ap(op_name, {}, ap.metavar("<MIGraphX operator name>"));
|
|
||||||
ap(show_ops,
|
|
||||||
{"--list", "-l"},
|
|
||||||
ap.help("List all the operators of MIGraphX"),
|
|
||||||
ap.set_value(true));
|
|
||||||
}
|
|
||||||
void run() const
|
|
||||||
{
|
|
||||||
if(show_ops)
|
|
||||||
{
|
|
||||||
for(const auto& name : get_operators())
|
|
||||||
std::cout << name << std::endl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto op = load_op(op_name);
|
|
||||||
std::cout << op_name << ": " << std::endl;
|
|
||||||
std::cout << to_pretty_json_string(op.to_value()) << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct onnx : command<onnx>
|
|
||||||
{
|
|
||||||
bool show_ops = false;
|
|
||||||
void parse(argument_parser& ap)
|
|
||||||
{
|
|
||||||
ap(show_ops,
|
|
||||||
{"--list", "-l"},
|
|
||||||
ap.help("List all onnx operators supported by MIGraphX"),
|
|
||||||
ap.set_value(true));
|
|
||||||
}
|
|
||||||
void run() const
|
|
||||||
{
|
|
||||||
if(show_ops)
|
|
||||||
{
|
|
||||||
for(const auto& name : get_onnx_operators())
|
|
||||||
std::cout << name << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct tf : command<tf>
|
|
||||||
{
|
|
||||||
bool show_ops = false;
|
|
||||||
void parse(argument_parser& ap)
|
|
||||||
{
|
|
||||||
ap(show_ops,
|
|
||||||
{"--list", "-l"},
|
|
||||||
ap.help("List all tf operators supported by MIGraphX"),
|
|
||||||
ap.set_value(true));
|
|
||||||
}
|
|
||||||
void run() const
|
|
||||||
{
|
|
||||||
if(show_ops)
|
|
||||||
{
|
|
||||||
for(const auto& name : get_tf_operators())
|
|
||||||
std::cout << name << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct main_command
|
|
||||||
{
|
|
||||||
static std::string get_command_help(const std::string& title = colorize(color::fg_yellow,
|
|
||||||
"COMMANDS:"))
|
|
||||||
{
|
|
||||||
std::string result = title + "\n";
|
|
||||||
std::vector<std::string> commands(get_commands().size());
|
|
||||||
std::transform(get_commands().begin(),
|
|
||||||
get_commands().end(),
|
|
||||||
commands.begin(),
|
|
||||||
[](const auto& p) { return colorize(color::fg_green, p.first); });
|
|
||||||
std::sort(commands.begin(), commands.end());
|
|
||||||
return std::accumulate(commands.begin(), commands.end(), result, [](auto r, auto&& s) {
|
|
||||||
return r + " " + s + "\n";
|
|
||||||
});
|
|
||||||
}
|
|
||||||
void parse(argument_parser& ap)
|
|
||||||
{
|
|
||||||
std::string version_str = get_version();
|
|
||||||
ap(wrong_commands, {}, ap.metavar("<command>"), ap.append());
|
|
||||||
ap(nullptr, {"-h", "--help"}, ap.help("Show help"), ap.show_help(get_command_help()));
|
|
||||||
ap(nullptr,
|
|
||||||
{"-v", "--version"},
|
|
||||||
ap.help("Show MIGraphX version"),
|
|
||||||
ap.show_help(version_str));
|
|
||||||
ap(nullptr, {"--ort-sha"}, ap.help("Show MIGraphX onnx runtime SHA"));
|
|
||||||
|
|
||||||
// Trim command off of exe name
|
|
||||||
ap.set_exe_name(ap.get_exe_name().substr(0, ap.get_exe_name().size() - 5));
|
|
||||||
ap.set_exe_name_to(exe_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> wrong_commands{};
|
|
||||||
std::string exe_name = "<exe>";
|
|
||||||
|
|
||||||
void run()
|
|
||||||
{
|
|
||||||
std::cout << color::fg_red << color::bold << "error: " << color::reset;
|
|
||||||
auto it = std::find_if(wrong_commands.begin(), wrong_commands.end(), [](const auto& c) {
|
|
||||||
return get_commands().count(c) > 0;
|
|
||||||
});
|
|
||||||
if(it == wrong_commands.end())
|
|
||||||
{
|
|
||||||
std::cout << "'" << color::fg_yellow << wrong_commands.front() << color::reset
|
|
||||||
<< "' is not a valid command." << std::endl;
|
|
||||||
std::cout << get_command_help("Available commands:");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cout << "command '" << color::fg_yellow << *it << color::reset
|
|
||||||
<< "' must be first argument" << std::endl;
|
|
||||||
std::cout << std::endl;
|
|
||||||
|
|
||||||
std::cout << color::fg_yellow << "USAGE:" << color::reset << std::endl;
|
|
||||||
std::cout << " " << exe_name << " " << *it << " <options>" << std::endl;
|
|
||||||
}
|
|
||||||
std::cout << std::endl;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace driver
|
|
||||||
} // namespace migraphx
|
|
||||||
|
|
||||||
using namespace migraphx::driver; // NOLINT
|
|
||||||
int main(int argc, const char* argv[], const char* envp[])
|
|
||||||
{
|
|
||||||
std::vector<std::string> args(argv + 1, argv + argc);
|
|
||||||
// no argument, print the help infomration by default
|
|
||||||
if(args.empty())
|
|
||||||
{
|
|
||||||
args.push_back("-h");
|
|
||||||
}
|
|
||||||
|
|
||||||
auto&& m = get_commands();
|
|
||||||
auto cmd = args.front();
|
|
||||||
|
|
||||||
if(cmd == "--ort-sha")
|
|
||||||
{
|
|
||||||
std::cout << MIGRAPHX_ORT_SHA1 << std::endl;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if(cmd == "-v" or cmd == "--version")
|
|
||||||
{
|
|
||||||
std::cout << get_version() << std::endl;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(m.count(cmd) > 0)
|
|
||||||
{
|
|
||||||
std::string driver_invocation =
|
|
||||||
std::string(argv[0]) + " " + migraphx::to_string_range(args, " ");
|
|
||||||
std::cout << "Running [ " << get_version() << " ]: " << driver_invocation << std::endl;
|
|
||||||
|
|
||||||
for(const char** env = envp; *env != nullptr; ++env)
|
|
||||||
{
|
|
||||||
std::string env_var(*env);
|
|
||||||
size_t pos = env_var.find('=');
|
|
||||||
if(pos != std::string::npos)
|
|
||||||
{
|
|
||||||
std::string key = env_var.substr(0, pos);
|
|
||||||
if(key.find("MIGRAPHX") != std::string::npos)
|
|
||||||
{
|
|
||||||
std::cout << env_var << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m.at(cmd)(argv[0],
|
|
||||||
{args.begin() + 1, args.end()}); // run driver command found in commands map
|
|
||||||
|
|
||||||
std::cout << "[ " << get_version() << " ] Complete: " << driver_invocation << std::endl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
run_command<main_command>(argv[0], args);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@ -1,72 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2022 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.
|
|
||||||
*/
|
|
||||||
#include "marker_roctx.hpp"
|
|
||||||
|
|
||||||
#include <migraphx/dynamic_loader.hpp>
|
|
||||||
#include <migraphx/instruction.hpp>
|
|
||||||
#include <migraphx/instruction_ref.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
namespace driver {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
class marker_roctx
|
|
||||||
{
|
|
||||||
std::function<void(const char*)> sym_roctx_mark;
|
|
||||||
std::function<uint64_t(const char*)> sym_roctx_range_start;
|
|
||||||
std::function<void(uint64_t)> sym_roctx_range_stop;
|
|
||||||
|
|
||||||
std::function<int(const char*)> sym_roctx_range_push;
|
|
||||||
std::function<int()> sym_roctx_range_pop;
|
|
||||||
|
|
||||||
uint64_t range_id = 0;
|
|
||||||
|
|
||||||
public:
|
|
||||||
marker_roctx()
|
|
||||||
{
|
|
||||||
dynamic_loader lib = migraphx::dynamic_loader{"libroctx64.so"};
|
|
||||||
sym_roctx_mark = lib.get_function<void(const char*)>("roctxMarkA");
|
|
||||||
sym_roctx_range_start = lib.get_function<uint64_t(const char*)>("roctxRangeStartA");
|
|
||||||
sym_roctx_range_stop = lib.get_function<void(uint64_t)>("roctxRangeStop");
|
|
||||||
|
|
||||||
sym_roctx_range_push = lib.get_function<int(const char*)>("roctxRangePushA");
|
|
||||||
sym_roctx_range_pop = lib.get_function<int()>("roctxRangePop");
|
|
||||||
|
|
||||||
sym_roctx_mark("rocTX marker created.");
|
|
||||||
}
|
|
||||||
|
|
||||||
void mark_start(instruction_ref ins_ref)
|
|
||||||
{
|
|
||||||
std::string text = "Marker start: " + ins_ref->name();
|
|
||||||
sym_roctx_range_push(text.c_str());
|
|
||||||
}
|
|
||||||
void mark_stop(instruction_ref) { sym_roctx_range_pop(); }
|
|
||||||
void mark_start(const program&) { range_id = sym_roctx_range_start("0"); }
|
|
||||||
void mark_stop(const program&) { sym_roctx_range_stop(range_id); }
|
|
||||||
};
|
|
||||||
|
|
||||||
marker create_marker_roctx() { return marker_roctx(); }
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace driver
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2022 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_RTGLIB_MARKER_ROCTX_HPP
|
|
||||||
#define MIGRAPHX_GUARD_RTGLIB_MARKER_ROCTX_HPP
|
|
||||||
|
|
||||||
#include <migraphx/marker.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
namespace driver {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
marker create_marker_roctx();
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace driver
|
|
||||||
} // namespace migraphx
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,59 +0,0 @@
|
|||||||
#include "mlir.hpp"
|
|
||||||
#include <migraphx/module.hpp>
|
|
||||||
#include <migraphx/make_op.hpp>
|
|
||||||
#include <migraphx/iterator_for.hpp>
|
|
||||||
#include <migraphx/ranges.hpp>
|
|
||||||
#include <migraphx/instruction.hpp>
|
|
||||||
#include <migraphx/param_utils.hpp>
|
|
||||||
#include <migraphx/dead_code_elimination.hpp>
|
|
||||||
#include <migraphx/pass_manager.hpp>
|
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
namespace driver {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
void offload_to_mlir(program& p)
|
|
||||||
{
|
|
||||||
auto* mm = p.get_main_module();
|
|
||||||
auto* mlirm = p.create_module("mlir");
|
|
||||||
mlirm->set_bypass();
|
|
||||||
std::vector<instruction_ref> inputs;
|
|
||||||
copy_if(iterator_for(*mm), std::back_inserter(inputs), [&](instruction_ref ins) {
|
|
||||||
if(ins->name() == "@param")
|
|
||||||
return true;
|
|
||||||
if(ins->name() == "@literal")
|
|
||||||
return ins->get_shape().elements() != 1;
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
std::unordered_map<instruction_ref, instruction_ref> map_ins;
|
|
||||||
std::size_t n = 0;
|
|
||||||
for(auto ins : inputs)
|
|
||||||
{
|
|
||||||
map_ins[ins] = mlirm->add_parameter(param_name(n++), ins->get_shape().as_standard());
|
|
||||||
}
|
|
||||||
|
|
||||||
auto mlir_last = mlirm->add_instructions(mm, &map_ins);
|
|
||||||
mlirm->add_return(mlir_last);
|
|
||||||
|
|
||||||
auto last = std::prev(mm->end());
|
|
||||||
auto mlir_op = mm->insert_instruction(last, make_op("gpu::mlir_op"), inputs, {mlirm});
|
|
||||||
if(mlir_last.size() > 1)
|
|
||||||
{
|
|
||||||
std::vector<instruction_ref> outputs;
|
|
||||||
transform(range(mlir_last.size()), std::back_inserter(outputs), [&](auto i) {
|
|
||||||
return mm->insert_instruction(last, make_op("get_tuple_elem", {{"index", i}}), mlir_op);
|
|
||||||
});
|
|
||||||
mm->replace_return(outputs);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mm->replace_return({mlir_op});
|
|
||||||
}
|
|
||||||
run_passes(*mm, {dead_code_elimination{}});
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace driver
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
#ifndef MIGRAPHX_GUARD_DRIVER_MLIR_HPP
|
|
||||||
#define MIGRAPHX_GUARD_DRIVER_MLIR_HPP
|
|
||||||
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
#include <migraphx/program.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
namespace driver {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
void offload_to_mlir(program& p);
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace driver
|
|
||||||
} // namespace migraphx
|
|
||||||
#endif // MIGRAPHX_GUARD_DRIVER_MLIR_HPP
|
|
||||||
@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "models.hpp"
|
|
||||||
#include <migraphx/program.hpp>
|
|
||||||
#include <migraphx/make_op.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
namespace driver {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
migraphx::program test_gemm()
|
|
||||||
{
|
|
||||||
migraphx::program p;
|
|
||||||
auto* mm = p.get_main_module();
|
|
||||||
auto a = mm->add_parameter("a", migraphx::shape{migraphx::shape::float_type, {4, 5}});
|
|
||||||
auto b = mm->add_parameter("b", migraphx::shape{migraphx::shape::float_type, {5, 3}});
|
|
||||||
mm->add_instruction(migraphx::make_op("dot"), a, b);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace driver
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <migraphx/program.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
namespace driver {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
migraphx::program test_gemm();
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace driver
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,113 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "passes.hpp"
|
|
||||||
|
|
||||||
#include <migraphx/auto_contiguous.hpp>
|
|
||||||
#include <migraphx/dead_code_elimination.hpp>
|
|
||||||
#include <migraphx/eliminate_allocation.hpp>
|
|
||||||
#include <migraphx/eliminate_common_subexpression.hpp>
|
|
||||||
#include <migraphx/eliminate_concat.hpp>
|
|
||||||
#include <migraphx/eliminate_contiguous.hpp>
|
|
||||||
#include <migraphx/eliminate_data_type.hpp>
|
|
||||||
#include <migraphx/eliminate_identity.hpp>
|
|
||||||
#include <migraphx/eliminate_pad.hpp>
|
|
||||||
#include <migraphx/fuse_pointwise.hpp>
|
|
||||||
#include <migraphx/fuse_reduce.hpp>
|
|
||||||
#include <migraphx/inline_module.hpp>
|
|
||||||
#include <migraphx/insert_pad.hpp>
|
|
||||||
#include <migraphx/normalize_ops.hpp>
|
|
||||||
#include <migraphx/optimize_module.hpp>
|
|
||||||
#include <migraphx/promote_literals.hpp>
|
|
||||||
#include <migraphx/propagate_constant.hpp>
|
|
||||||
#include <migraphx/rewrite_gelu.hpp>
|
|
||||||
#include <migraphx/rewrite_pooling.hpp>
|
|
||||||
#include <migraphx/rewrite_quantization.hpp>
|
|
||||||
#include <migraphx/rewrite_rnn.hpp>
|
|
||||||
#include <migraphx/simplify_algebra.hpp>
|
|
||||||
#include <migraphx/simplify_dyn_ops.hpp>
|
|
||||||
#include <migraphx/simplify_qdq.hpp>
|
|
||||||
#include <migraphx/simplify_reshapes.hpp>
|
|
||||||
|
|
||||||
#include <migraphx/ranges.hpp>
|
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
namespace driver {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
std::unordered_map<std::string, pass> create_passes_lookup()
|
|
||||||
{
|
|
||||||
std::unordered_map<std::string, pass> result;
|
|
||||||
// clang-format off
|
|
||||||
std::initializer_list<pass> passes = {
|
|
||||||
auto_contiguous{},
|
|
||||||
dead_code_elimination{},
|
|
||||||
eliminate_allocation{},
|
|
||||||
eliminate_common_subexpression{},
|
|
||||||
eliminate_concat{},
|
|
||||||
eliminate_contiguous{},
|
|
||||||
eliminate_data_type{},
|
|
||||||
eliminate_identity{},
|
|
||||||
eliminate_pad{},
|
|
||||||
fuse_pointwise{},
|
|
||||||
fuse_reduce{},
|
|
||||||
inline_module{},
|
|
||||||
insert_pad{},
|
|
||||||
normalize_ops{},
|
|
||||||
optimize_module{},
|
|
||||||
promote_literals{},
|
|
||||||
propagate_constant{},
|
|
||||||
rewrite_gelu{},
|
|
||||||
rewrite_pooling{},
|
|
||||||
rewrite_quantization{},
|
|
||||||
rewrite_rnn{},
|
|
||||||
simplify_algebra{},
|
|
||||||
simplify_dyn_ops{},
|
|
||||||
simplify_qdq{},
|
|
||||||
simplify_reshapes{},
|
|
||||||
};
|
|
||||||
// clang-format on
|
|
||||||
for(const auto& pass : passes)
|
|
||||||
result[pass.name()] = pass;
|
|
||||||
result["eliminate_dead_code"] = dead_code_elimination{};
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<pass> get_passes(const std::vector<std::string>& names)
|
|
||||||
{
|
|
||||||
std::vector<pass> result;
|
|
||||||
static const std::unordered_map<std::string, pass> lookup = create_passes_lookup();
|
|
||||||
std::transform(
|
|
||||||
names.begin(), names.end(), std::back_inserter(result), [](const std::string& name) {
|
|
||||||
if(not contains(lookup, name))
|
|
||||||
MIGRAPHX_THROW("Unknown pass: " + name);
|
|
||||||
return lookup.at(name);
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace driver
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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_DRIVER_PASSES_HPP
|
|
||||||
#define MIGRAPHX_GUARD_DRIVER_PASSES_HPP
|
|
||||||
|
|
||||||
#include <migraphx/pass.hpp>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
namespace driver {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
std::vector<pass> get_passes(const std::vector<std::string>& names);
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace driver
|
|
||||||
} // namespace migraphx
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,157 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2025 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.
|
|
||||||
*/
|
|
||||||
#include "perf.hpp"
|
|
||||||
|
|
||||||
#include <migraphx/generate.hpp>
|
|
||||||
#include <migraphx/instruction.hpp>
|
|
||||||
#include <migraphx/instruction_ref.hpp>
|
|
||||||
#include <migraphx/register_target.hpp>
|
|
||||||
#include <migraphx/ranges.hpp>
|
|
||||||
#include <migraphx/time.hpp>
|
|
||||||
#ifdef HAVE_GPU
|
|
||||||
#include <migraphx/gpu/hip.hpp>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
namespace driver {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
using milliseconds = std::chrono::duration<double, std::milli>;
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
auto get_hash(const T& x)
|
|
||||||
{
|
|
||||||
return std::hash<T>{}(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
parameter_map fill_param_map(parameter_map& m,
|
|
||||||
const std::unordered_map<std::string, shape>& param_shapes,
|
|
||||||
const target& t,
|
|
||||||
bool offload)
|
|
||||||
{
|
|
||||||
for(auto&& x : param_shapes)
|
|
||||||
{
|
|
||||||
argument& arg = m[x.first];
|
|
||||||
if(arg.empty())
|
|
||||||
{
|
|
||||||
assert(not x.second.dynamic());
|
|
||||||
arg = generate_argument(x.second, get_hash(x.first), random_mode::random);
|
|
||||||
}
|
|
||||||
if(not offload)
|
|
||||||
arg = t.copy_to(arg);
|
|
||||||
}
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
parameter_map create_param_map(const program& p, const target& t, bool offload)
|
|
||||||
{
|
|
||||||
parameter_map m;
|
|
||||||
for(auto&& x : p.get_parameter_shapes())
|
|
||||||
{
|
|
||||||
auto arg = generate_argument(x.second, get_hash(x.first), random_mode::random);
|
|
||||||
if(offload)
|
|
||||||
m[x.first] = arg;
|
|
||||||
else
|
|
||||||
m[x.first] = t.copy_to(arg);
|
|
||||||
}
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
parameter_map create_param_map(const program& p, bool gpu)
|
|
||||||
{
|
|
||||||
parameter_map m;
|
|
||||||
for(auto&& x : p.get_parameter_shapes())
|
|
||||||
{
|
|
||||||
#ifdef HAVE_GPU
|
|
||||||
if(gpu)
|
|
||||||
m[x.first] =
|
|
||||||
gpu::to_gpu(generate_argument(x.second, get_hash(x.first), random_mode::random));
|
|
||||||
else
|
|
||||||
#else
|
|
||||||
(void)gpu;
|
|
||||||
#endif
|
|
||||||
m[x.first] = generate_argument(x.second, get_hash(x.first), random_mode::random);
|
|
||||||
}
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
target get_target(bool gpu)
|
|
||||||
{
|
|
||||||
if(gpu)
|
|
||||||
return make_target("gpu");
|
|
||||||
else
|
|
||||||
return make_target("cpu");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_offload_copy_set(const program& p)
|
|
||||||
{
|
|
||||||
assert(p.is_compiled());
|
|
||||||
const module* mm = p.get_main_module();
|
|
||||||
std::vector<std::string> param_names = mm->get_parameter_names();
|
|
||||||
std::unordered_set<instruction_ref> param_ins;
|
|
||||||
std::transform(param_names.begin(),
|
|
||||||
param_names.end(),
|
|
||||||
std::inserter(param_ins, param_ins.begin()),
|
|
||||||
[&](const auto& i) { return mm->get_parameter(i); });
|
|
||||||
for(const auto& i : *mm)
|
|
||||||
{
|
|
||||||
if(i.name() == "hip::copy_to_gpu")
|
|
||||||
{
|
|
||||||
auto copy_arg = instruction::get_output_alias(i.inputs().front(), true);
|
|
||||||
param_ins.erase(copy_arg);
|
|
||||||
}
|
|
||||||
else if(i.name() == "@return")
|
|
||||||
{
|
|
||||||
auto return_args = i.inputs();
|
|
||||||
for(const auto& j : return_args)
|
|
||||||
{
|
|
||||||
auto alias_ins = instruction::get_output_alias(j, true);
|
|
||||||
if((alias_ins->name() == "@param" and param_ins.erase(alias_ins) == 0) or
|
|
||||||
(alias_ins->name() != "hip::copy_from_gpu"))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return param_ins.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
double time_run(const program& p, const parameter_map& m, int n)
|
|
||||||
{
|
|
||||||
// Run once without timing
|
|
||||||
p.eval(m);
|
|
||||||
p.finish();
|
|
||||||
double total = time<milliseconds>([&] {
|
|
||||||
for(auto i : range(n))
|
|
||||||
{
|
|
||||||
(void)i;
|
|
||||||
p.eval(m);
|
|
||||||
}
|
|
||||||
p.finish();
|
|
||||||
});
|
|
||||||
return total / n;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace driver
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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_RTGLIB_PERF_HPP
|
|
||||||
#define MIGRAPHX_GUARD_RTGLIB_PERF_HPP
|
|
||||||
|
|
||||||
#include <migraphx/program.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
namespace driver {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
parameter_map fill_param_map(parameter_map& m,
|
|
||||||
const std::unordered_map<std::string, shape>& param_shapes,
|
|
||||||
const target& t,
|
|
||||||
bool offload = false);
|
|
||||||
parameter_map create_param_map(const program& p, const target& t, bool offload = false);
|
|
||||||
|
|
||||||
parameter_map fill_param_map(parameter_map& m, const program& p, bool gpu);
|
|
||||||
parameter_map create_param_map(const program& p, bool gpu = true);
|
|
||||||
target get_target(bool gpu);
|
|
||||||
/**
|
|
||||||
* @brief Checks if MIGraphX program compiled for "GPU" has offload_copy set of not. This is
|
|
||||||
intended to print a HINT for the users and would not always correctly classify compiled program as
|
|
||||||
with or without offload_copy in all cases.
|
|
||||||
|
|
||||||
* @param p Compiled MIGraphX program for GPU backend
|
|
||||||
* @return true if program is classified as compiled with "offload_copy" set
|
|
||||||
*/
|
|
||||||
bool is_offload_copy_set(const program& p);
|
|
||||||
|
|
||||||
double time_run(const program& p, const parameter_map& m, int n = 100);
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace driver
|
|
||||||
} // namespace migraphx
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2022 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_RTGLIB_PRECISION_HPP
|
|
||||||
#define MIGRAPHX_GUARD_RTGLIB_PRECISION_HPP
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
namespace driver {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
enum class precision
|
|
||||||
{
|
|
||||||
fp32,
|
|
||||||
fp16,
|
|
||||||
bf16,
|
|
||||||
int8
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace driver
|
|
||||||
} // namespace migraphx
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,340 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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.
|
|
||||||
*/
|
|
||||||
#include "verify.hpp"
|
|
||||||
#include "perf.hpp"
|
|
||||||
|
|
||||||
#include <migraphx/register_target.hpp>
|
|
||||||
#include <migraphx/generate.hpp>
|
|
||||||
#include <migraphx/verify_args.hpp>
|
|
||||||
#include <migraphx/instruction.hpp>
|
|
||||||
#include <migraphx/compile_options.hpp>
|
|
||||||
#include <migraphx/quantization.hpp>
|
|
||||||
#include <migraphx/ranges.hpp>
|
|
||||||
#include <migraphx/fp_to_double.hpp>
|
|
||||||
#include <migraphx/iterator_for.hpp>
|
|
||||||
#include <migraphx/stringutils.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
namespace driver {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gives tolerances based on user input (`rms_tol`, `atol`, `rtol` parameters) and defaults.
|
|
||||||
* Sets to fp16 tolerances if `quantize` input is fp16 or any fp16 instruction in found in the
|
|
||||||
* model.
|
|
||||||
*/
|
|
||||||
verify::tolerance get_tolerances(const program& p,
|
|
||||||
verify_options vo,
|
|
||||||
std::optional<double> rms_tol,
|
|
||||||
std::optional<double> atol,
|
|
||||||
std::optional<double> rtol)
|
|
||||||
{
|
|
||||||
bool has_16bit = any_of(p.get_modules(), [](auto&& m) {
|
|
||||||
return any_of(*m, [](auto&& ins) {
|
|
||||||
return (ins.get_shape().type() == shape::half_type or
|
|
||||||
ins.get_shape().type() == shape::bf16_type);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
migraphx::verify::tolerance result{};
|
|
||||||
if(has_16bit or vo.quantize == precision::fp16 or vo.quantize == precision::bf16)
|
|
||||||
{
|
|
||||||
result.rms_tol = 8e-2;
|
|
||||||
result.atol = 4e-2;
|
|
||||||
result.rtol = 4e-2;
|
|
||||||
}
|
|
||||||
if(rms_tol)
|
|
||||||
{
|
|
||||||
result.rms_tol = *rms_tol;
|
|
||||||
}
|
|
||||||
if(atol)
|
|
||||||
{
|
|
||||||
result.atol = *atol;
|
|
||||||
}
|
|
||||||
if(rtol)
|
|
||||||
{
|
|
||||||
result.rtol = *rtol;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<argument> run_ref(program p,
|
|
||||||
const compile_options& options,
|
|
||||||
const verify_options& vo,
|
|
||||||
const parameter_map& inputs)
|
|
||||||
{
|
|
||||||
if(vo.ref_use_double)
|
|
||||||
{
|
|
||||||
run_passes(p, {fp_to_double{}});
|
|
||||||
}
|
|
||||||
p.compile(migraphx::make_target("ref"), options);
|
|
||||||
auto out = p.eval(inputs);
|
|
||||||
std::cout << p << std::endl;
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<argument> run_target(program p,
|
|
||||||
const target& t,
|
|
||||||
const compile_options& options,
|
|
||||||
const verify_options& vo,
|
|
||||||
const parameter_map& inputs)
|
|
||||||
{
|
|
||||||
if(vo.quantize == precision::fp16)
|
|
||||||
{
|
|
||||||
quantize_fp16(p);
|
|
||||||
}
|
|
||||||
if(vo.quantize == precision::bf16)
|
|
||||||
{
|
|
||||||
quantize_bf16(p);
|
|
||||||
}
|
|
||||||
p.compile(t, options);
|
|
||||||
|
|
||||||
parameter_map m;
|
|
||||||
for(auto&& x : p.get_parameter_shapes())
|
|
||||||
{
|
|
||||||
auto arg = inputs.count(x.first) == 0 ? generate_argument(x.second) : inputs.at(x.first);
|
|
||||||
m[x.first] = options.offload_copy ? arg : t.copy_to(arg);
|
|
||||||
}
|
|
||||||
auto gpu_out = p.eval(m);
|
|
||||||
std::vector<argument> output(gpu_out.size());
|
|
||||||
std::cout << p << std::endl;
|
|
||||||
std::transform(gpu_out.begin(), gpu_out.end(), output.begin(), [&](auto& argu) {
|
|
||||||
return options.offload_copy ? argu : t.copy_from(argu);
|
|
||||||
});
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool verify_program(const std::string& name,
|
|
||||||
const program& p,
|
|
||||||
const target& t,
|
|
||||||
compile_options options,
|
|
||||||
verify_options vo,
|
|
||||||
const parameter_map& inputs,
|
|
||||||
verify::tolerance tols)
|
|
||||||
{
|
|
||||||
auto ref_outs = run_ref(p, options, vo, inputs);
|
|
||||||
auto target_outs = run_target(p, t, options, vo, inputs);
|
|
||||||
|
|
||||||
std::size_t output_num = ref_outs.size();
|
|
||||||
bool passed = true;
|
|
||||||
for(std::size_t i = 0; i < output_num; ++i)
|
|
||||||
{
|
|
||||||
if(ref_outs[i].get_shape().type() != target_outs[i].get_shape().type() or
|
|
||||||
ref_outs[i].get_shape().lens() != target_outs[i].get_shape().lens())
|
|
||||||
{
|
|
||||||
std::cout << "FAILED: " << name << std::endl;
|
|
||||||
std::cout << "Shape mismatch {" << ref_outs[i].get_shape() << "} != {"
|
|
||||||
<< target_outs[i].get_shape() << "}" << std::endl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
passed &= verify_args(name, target_outs[i], verify::expected{ref_outs[i]}, tols);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(passed)
|
|
||||||
std::cout << "MIGraphX verification passed successfully." << std::endl;
|
|
||||||
return passed;
|
|
||||||
}
|
|
||||||
|
|
||||||
void verify_instructions(const program& prog,
|
|
||||||
const target& t,
|
|
||||||
compile_options options,
|
|
||||||
verify_options vo,
|
|
||||||
verify::tolerance tols)
|
|
||||||
{
|
|
||||||
const auto* mm_prog = prog.get_main_module();
|
|
||||||
for(auto&& ins : (*mm_prog))
|
|
||||||
{
|
|
||||||
if(ins.name().front() == '@')
|
|
||||||
continue;
|
|
||||||
if(ins.name() == "broadcast")
|
|
||||||
continue;
|
|
||||||
if(ins.name() == "transpose")
|
|
||||||
continue;
|
|
||||||
if(ins.name() == "reshape")
|
|
||||||
continue;
|
|
||||||
if(ins.name() == "undefined")
|
|
||||||
continue;
|
|
||||||
program p;
|
|
||||||
auto* mm_p = p.get_main_module();
|
|
||||||
std::vector<instruction_ref> inputs;
|
|
||||||
for(auto&& arg : ins.inputs())
|
|
||||||
{
|
|
||||||
if(arg->name() == "@literal")
|
|
||||||
inputs.push_back(mm_p->add_literal(arg->get_literal()));
|
|
||||||
else
|
|
||||||
inputs.push_back(
|
|
||||||
mm_p->add_parameter(std::to_string(inputs.size()), arg->get_shape()));
|
|
||||||
}
|
|
||||||
mm_p->add_instruction(ins.get_operator(), inputs);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
std::cout << "Verify: " << ins.name() << std::endl;
|
|
||||||
std::cout << p << std::endl;
|
|
||||||
verify_program(ins.name(), p, t, options, vo, create_param_map(p, false), tols);
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
std::cout << "Instruction " << ins.name() << " threw an exception." << std::endl;
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool verify_reduced(program p,
|
|
||||||
int n,
|
|
||||||
const target& t,
|
|
||||||
compile_options options,
|
|
||||||
verify_options vo,
|
|
||||||
const parameter_map& inputs,
|
|
||||||
verify::tolerance tols)
|
|
||||||
{
|
|
||||||
auto* mm = p.get_main_module();
|
|
||||||
auto last = std::prev(mm->end(), n);
|
|
||||||
mm->remove_instructions(last, mm->end());
|
|
||||||
std::cout << "Verify: " << n << std::endl;
|
|
||||||
std::cout << p << std::endl;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return verify_program(std::to_string(n), p, t, options, vo, inputs, tols);
|
|
||||||
}
|
|
||||||
catch(const std::exception& e)
|
|
||||||
{
|
|
||||||
std::cout << "FAILED: " << n << std::endl;
|
|
||||||
std::cout << "Exception: " << e.what() << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void verify_reduced_program(const program& p,
|
|
||||||
const target& t,
|
|
||||||
compile_options options,
|
|
||||||
verify_options vo,
|
|
||||||
const parameter_map& inputs,
|
|
||||||
verify::tolerance tols)
|
|
||||||
{
|
|
||||||
const auto* mm = p.get_main_module();
|
|
||||||
auto n = std::distance(mm->begin(), mm->end());
|
|
||||||
std::cout << "Verify steps: " << n << std::endl;
|
|
||||||
for(std::size_t i = 1; i < n; i++)
|
|
||||||
{
|
|
||||||
auto last = std::prev(mm->end(), i + 1);
|
|
||||||
if(contains({"@literal", "@param"}, last->name()))
|
|
||||||
{
|
|
||||||
std::cout << "Skip: " << i << std::endl;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
verify_reduced(p, i, t, options, vo, inputs, tols);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::unordered_map<instruction_ref, std::size_t> accumulate_weights(instruction_ref last)
|
|
||||||
{
|
|
||||||
std::unordered_map<instruction_ref, std::size_t> weights;
|
|
||||||
fix<std::size_t>([&](auto self, auto ins) -> std::size_t {
|
|
||||||
if(not contains(weights, ins))
|
|
||||||
{
|
|
||||||
if(ins->can_eval())
|
|
||||||
return 0;
|
|
||||||
std::size_t weight = 1;
|
|
||||||
weights[ins] = std::accumulate(
|
|
||||||
ins->inputs().begin(),
|
|
||||||
ins->inputs().end(),
|
|
||||||
weight,
|
|
||||||
[&](std::size_t w, instruction_ref i) -> std::size_t { return w + self(i); });
|
|
||||||
}
|
|
||||||
return weights[ins];
|
|
||||||
})(last);
|
|
||||||
return weights;
|
|
||||||
}
|
|
||||||
|
|
||||||
static optional<instruction_ref>
|
|
||||||
get_parent(const std::unordered_map<instruction_ref, std::size_t>& weights, instruction_ref ins)
|
|
||||||
{
|
|
||||||
if(ins->inputs().empty())
|
|
||||||
return nullopt;
|
|
||||||
auto next = std::max_element(ins->inputs().begin(),
|
|
||||||
ins->inputs().end(),
|
|
||||||
by(std::less<>{}, [&](instruction_ref input) -> std::size_t {
|
|
||||||
if(not contains(weights, input))
|
|
||||||
return 0;
|
|
||||||
return weights.at(input);
|
|
||||||
}));
|
|
||||||
return *next;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::vector<std::size_t> find_trim_instructions(const module& m)
|
|
||||||
{
|
|
||||||
std::vector<std::size_t> result;
|
|
||||||
auto last = std::prev(m.end());
|
|
||||||
auto weights = accumulate_weights(last);
|
|
||||||
auto next = get_parent(weights, last);
|
|
||||||
std::size_t i = 0;
|
|
||||||
while(auto parent = get_parent(weights, *next))
|
|
||||||
{
|
|
||||||
i += std::distance(*parent, *next);
|
|
||||||
result.push_back(i + 1);
|
|
||||||
next = parent;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void verify_bisected_program(const program& p,
|
|
||||||
const target& t,
|
|
||||||
compile_options options,
|
|
||||||
verify_options vo,
|
|
||||||
const parameter_map& inputs,
|
|
||||||
verify::tolerance tols)
|
|
||||||
{
|
|
||||||
const auto* mm = p.get_main_module();
|
|
||||||
|
|
||||||
std::vector<std::size_t> trims = find_trim_instructions(*mm);
|
|
||||||
std::int64_t right = trims.size();
|
|
||||||
std::int64_t left = 0;
|
|
||||||
std::int64_t failed = -1;
|
|
||||||
|
|
||||||
while(left <= right)
|
|
||||||
{
|
|
||||||
std::int64_t mid = left + (right - left) / 2;
|
|
||||||
assert(mid < trims.size() and mid >= 0);
|
|
||||||
std::int64_t trim = trims.rbegin()[mid];
|
|
||||||
bool passed = verify_reduced(p, trim, t, options, vo, inputs, tols);
|
|
||||||
if(passed)
|
|
||||||
{
|
|
||||||
left = mid + 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
failed = trim;
|
|
||||||
right = mid - 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(failed > 0)
|
|
||||||
{
|
|
||||||
std::cout << "Failure starts at: " << failed << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace driver
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,70 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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_RTGLIB_DRIVER_VERIFY_HPP
|
|
||||||
#define MIGRAPHX_GUARD_RTGLIB_DRIVER_VERIFY_HPP
|
|
||||||
|
|
||||||
#include "verify_options.hpp"
|
|
||||||
#include <migraphx/program.hpp>
|
|
||||||
#include <migraphx/verify.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
namespace driver {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
verify::tolerance get_tolerances(const program& p,
|
|
||||||
verify_options vo,
|
|
||||||
std::optional<double> rms_tol,
|
|
||||||
std::optional<double> atol,
|
|
||||||
std::optional<double> rtol);
|
|
||||||
|
|
||||||
bool verify_program(const std::string& name,
|
|
||||||
const program& p,
|
|
||||||
const target& t,
|
|
||||||
compile_options options = compile_options{},
|
|
||||||
verify_options vo = verify_options{},
|
|
||||||
const parameter_map& inputs = {},
|
|
||||||
verify::tolerance tols = verify::tolerance{});
|
|
||||||
void verify_instructions(const program& prog,
|
|
||||||
const target& t,
|
|
||||||
compile_options options = compile_options{},
|
|
||||||
verify_options vo = verify_options{},
|
|
||||||
verify::tolerance tols = verify::tolerance{});
|
|
||||||
void verify_reduced_program(const program& p,
|
|
||||||
const target& t,
|
|
||||||
compile_options options = compile_options{},
|
|
||||||
verify_options vo = verify_options{},
|
|
||||||
const parameter_map& inputs = {},
|
|
||||||
verify::tolerance tols = verify::tolerance{});
|
|
||||||
void verify_bisected_program(const program& p,
|
|
||||||
const target& t,
|
|
||||||
compile_options options = compile_options{},
|
|
||||||
verify_options vo = verify_options{},
|
|
||||||
const parameter_map& inputs = {},
|
|
||||||
verify::tolerance tols = verify::tolerance{});
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace driver
|
|
||||||
} // namespace migraphx
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,48 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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_RTGLIB_DRIVER_VERIFY_OPTIONS_HPP
|
|
||||||
#define MIGRAPHX_GUARD_RTGLIB_DRIVER_VERIFY_OPTIONS_HPP
|
|
||||||
|
|
||||||
#include "precision.hpp"
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
namespace driver {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
struct verify_options
|
|
||||||
{
|
|
||||||
/// Quantization precision
|
|
||||||
precision quantize = precision::fp32;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts floating point values to double on the ref target.
|
|
||||||
*/
|
|
||||||
bool ref_use_double = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace driver
|
|
||||||
} // namespace migraphx
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,203 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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.
|
|
||||||
*/
|
|
||||||
#include <migraphx/manage_ptr.hpp>
|
|
||||||
#include <migraphx/dynamic_loader.hpp>
|
|
||||||
#include <migraphx/errors.hpp>
|
|
||||||
#include <migraphx/file_buffer.hpp>
|
|
||||||
#include <migraphx/tmp_dir.hpp>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
// cppcheck-suppress definePrefix
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
|
||||||
#include <Windows.h>
|
|
||||||
#else
|
|
||||||
#include <dlfcn.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
|
|
||||||
void check_load_error(bool flush = false)
|
|
||||||
{
|
|
||||||
char* error_msg = dlerror();
|
|
||||||
if(not flush and error_msg != nullptr)
|
|
||||||
MIGRAPHX_THROW("Dynamic loading or symbol lookup failed with " + std::string(error_msg));
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dynamic_loader_impl
|
|
||||||
{
|
|
||||||
dynamic_loader_impl() = default;
|
|
||||||
|
|
||||||
#if defined(__GNUC__) && !defined(__clang__)
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wignored-attributes"
|
|
||||||
#endif
|
|
||||||
dynamic_loader_impl(const fs::path& p, std::shared_ptr<tmp_dir> t = nullptr)
|
|
||||||
: handle(dlopen(p.string().c_str(), RTLD_GLOBAL | RTLD_NOW),
|
|
||||||
manage_deleter<decltype(&dlclose), &dlclose>{}),
|
|
||||||
temp(std::move(t))
|
|
||||||
{
|
|
||||||
check_load_error();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(__GNUC__) && !defined(__clang__)
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static std::shared_ptr<dynamic_loader_impl> from_buffer(const char* image, std::size_t size)
|
|
||||||
{
|
|
||||||
auto t = std::make_shared<tmp_dir>("dloader");
|
|
||||||
auto f = t->path / "libtmp.so";
|
|
||||||
write_buffer(f, image, size);
|
|
||||||
return std::make_shared<dynamic_loader_impl>(f, t);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<void> handle = nullptr;
|
|
||||||
std::shared_ptr<tmp_dir> temp = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
fs::path dynamic_loader::path(void* address)
|
|
||||||
{
|
|
||||||
fs::path p;
|
|
||||||
Dl_info info;
|
|
||||||
// Find the location of .so
|
|
||||||
if(dladdr(address, &info) != 0)
|
|
||||||
p = info.dli_fname;
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
struct dynamic_loader_impl
|
|
||||||
{
|
|
||||||
dynamic_loader_impl() = default;
|
|
||||||
dynamic_loader_impl(const fs::path& p, tmp_dir t = {})
|
|
||||||
: handle{LoadLibrary(p.string().c_str())}, temp{std::move(t)}
|
|
||||||
{
|
|
||||||
if(handle == nullptr)
|
|
||||||
{
|
|
||||||
MIGRAPHX_THROW("Error loading DLL: " + p.string() + " (" +
|
|
||||||
std::to_string(GetLastError()) + ")");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dynamic_loader_impl(const dynamic_loader_impl&) = delete;
|
|
||||||
dynamic_loader_impl& operator=(const dynamic_loader_impl&) = delete;
|
|
||||||
|
|
||||||
dynamic_loader_impl(dynamic_loader_impl&&) = default;
|
|
||||||
|
|
||||||
~dynamic_loader_impl()
|
|
||||||
{
|
|
||||||
if(handle != nullptr)
|
|
||||||
{
|
|
||||||
FreeLibrary(handle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::shared_ptr<dynamic_loader_impl> from_buffer(const char* image, std::size_t size)
|
|
||||||
{
|
|
||||||
auto t = tmp_dir{"migx-dynload"};
|
|
||||||
auto f = t.path / "tmp.dll";
|
|
||||||
write_buffer(f, image, size);
|
|
||||||
return std::make_shared<dynamic_loader_impl>(f, std::move(t));
|
|
||||||
}
|
|
||||||
|
|
||||||
HMODULE handle = nullptr;
|
|
||||||
tmp_dir temp;
|
|
||||||
};
|
|
||||||
|
|
||||||
fs::path dynamic_loader::path(void* address)
|
|
||||||
{
|
|
||||||
HMODULE module = nullptr;
|
|
||||||
if(GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
|
|
||||||
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
|
|
||||||
static_cast<LPCSTR>(address),
|
|
||||||
&module) == 0)
|
|
||||||
{
|
|
||||||
auto err = GetLastError();
|
|
||||||
MIGRAPHX_THROW("Unable to obtain module handle, error = " + std::to_string(err));
|
|
||||||
}
|
|
||||||
TCHAR buffer[MAX_PATH];
|
|
||||||
if(GetModuleFileName(module, buffer, sizeof(buffer)) == 0)
|
|
||||||
{
|
|
||||||
auto err = GetLastError();
|
|
||||||
MIGRAPHX_THROW("Unable to read module file path, error = " + std::to_string(err));
|
|
||||||
}
|
|
||||||
if(GetLastError() == ERROR_INSUFFICIENT_BUFFER)
|
|
||||||
{
|
|
||||||
MIGRAPHX_THROW("Buffer too small (" + std::to_string(MAX_PATH) + ") to hold the path");
|
|
||||||
}
|
|
||||||
return {buffer};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
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 char* image, std::size_t size)
|
|
||||||
: impl(dynamic_loader_impl::from_buffer(image, size))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
dynamic_loader::dynamic_loader(const std::vector<char>& buffer)
|
|
||||||
: impl(dynamic_loader_impl::from_buffer(buffer.data(), buffer.size()))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<void> dynamic_loader::get_symbol(const std::string& name) const
|
|
||||||
{
|
|
||||||
#ifndef _WIN32
|
|
||||||
// flush any previous error messages
|
|
||||||
check_load_error(true);
|
|
||||||
void* symbol = dlsym(impl->handle.get(), name.c_str());
|
|
||||||
if(symbol == nullptr)
|
|
||||||
check_load_error();
|
|
||||||
return {impl, symbol};
|
|
||||||
#else
|
|
||||||
FARPROC addr = GetProcAddress(impl->handle, name.c_str());
|
|
||||||
if(addr == nullptr)
|
|
||||||
MIGRAPHX_THROW("Symbol not found: " + name + " (" + std::to_string(GetLastError()) + ")");
|
|
||||||
return {impl, reinterpret_cast<void*>(addr)};
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,66 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
#include <migraphx/eliminate_allocation.hpp>
|
|
||||||
#include <migraphx/program.hpp>
|
|
||||||
#include <migraphx/instruction.hpp>
|
|
||||||
#include <migraphx/iterator_for.hpp>
|
|
||||||
#include <migraphx/ranges.hpp>
|
|
||||||
#include <migraphx/stringutils.hpp>
|
|
||||||
#include <migraphx/serialize.hpp>
|
|
||||||
#include <migraphx/make_op.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
void eliminate_allocation::apply(module& m) const
|
|
||||||
{
|
|
||||||
assert(alignment > 0);
|
|
||||||
|
|
||||||
std::size_t n = 0;
|
|
||||||
std::vector<std::pair<instruction_ref, std::size_t>> allocs;
|
|
||||||
for(auto ins : iterator_for(m))
|
|
||||||
{
|
|
||||||
if(ins->name() != allocation_op)
|
|
||||||
continue;
|
|
||||||
allocs.emplace_back(ins, n);
|
|
||||||
std::size_t size = ins->get_shape().bytes();
|
|
||||||
std::size_t padding = (alignment - (size % alignment)) % alignment;
|
|
||||||
n += size + padding;
|
|
||||||
}
|
|
||||||
if(n > 0)
|
|
||||||
{
|
|
||||||
auto mem = m.add_parameter("memory", shape{shape::int8_type, {n}});
|
|
||||||
for(auto&& pp : allocs)
|
|
||||||
{
|
|
||||||
auto ins = pp.first;
|
|
||||||
auto s = ins->get_shape();
|
|
||||||
auto offset = pp.second;
|
|
||||||
m.replace_instruction(
|
|
||||||
ins, make_op("load", {{"shape", to_value(s)}, {"offset", offset}}), mem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,76 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2022 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.
|
|
||||||
*/
|
|
||||||
#include <migraphx/eliminate_common_subexpression.hpp>
|
|
||||||
#include <migraphx/program.hpp>
|
|
||||||
#include <migraphx/instruction.hpp>
|
|
||||||
#include <migraphx/iterator_for.hpp>
|
|
||||||
#include <migraphx/ranges.hpp>
|
|
||||||
#include <migraphx/functional.hpp>
|
|
||||||
|
|
||||||
#include <unordered_set>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
template <class Range>
|
|
||||||
void cse_range(module& m, Range&& r)
|
|
||||||
{
|
|
||||||
std::unordered_multimap<std::string, instruction_ref> instructions;
|
|
||||||
std::unordered_set<instruction_ref> processed_ins;
|
|
||||||
for(auto ins : r)
|
|
||||||
{
|
|
||||||
// Skip dead instructions
|
|
||||||
if(ins->outputs().empty())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Find instruction with the same name
|
|
||||||
auto found_instructions = range(instructions.equal_range(ins->name()));
|
|
||||||
for(const auto& pp : found_instructions)
|
|
||||||
{
|
|
||||||
auto eq = pp.second;
|
|
||||||
if(contains(processed_ins, eq))
|
|
||||||
continue;
|
|
||||||
if(*eq != *ins)
|
|
||||||
continue;
|
|
||||||
m.replace_instruction(ins, eq);
|
|
||||||
processed_ins.emplace(ins);
|
|
||||||
std::vector<instruction_ref> outputs;
|
|
||||||
std::copy_if(eq->outputs().begin(),
|
|
||||||
eq->outputs().end(),
|
|
||||||
std::back_inserter(outputs),
|
|
||||||
[&](auto x) { return m.has_instruction(x); });
|
|
||||||
|
|
||||||
std::sort(outputs.begin(), outputs.end(), [&](auto x, auto y) {
|
|
||||||
return std::distance(eq, x) < std::distance(eq, y);
|
|
||||||
});
|
|
||||||
cse_range(m, outputs);
|
|
||||||
}
|
|
||||||
instructions.emplace(ins->name(), ins);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void eliminate_common_subexpression::apply(module& m) const { cse_range(m, iterator_for(m)); }
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,110 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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.
|
|
||||||
*/
|
|
||||||
#include <iterator>
|
|
||||||
#include <migraphx/eliminate_concat.hpp>
|
|
||||||
#include <migraphx/program.hpp>
|
|
||||||
#include <migraphx/instruction.hpp>
|
|
||||||
#include <migraphx/op/load.hpp>
|
|
||||||
#include <migraphx/op/identity.hpp>
|
|
||||||
#include <migraphx/iterator_for.hpp>
|
|
||||||
#include <migraphx/ranges.hpp>
|
|
||||||
#include <migraphx/make_op.hpp>
|
|
||||||
|
|
||||||
#include <migraphx/dfor.hpp>
|
|
||||||
#include <migraphx/tune_axis.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
void eliminate_concat::apply(module& m) const
|
|
||||||
{
|
|
||||||
for(auto ins : iterator_for(m))
|
|
||||||
{
|
|
||||||
auto concat_op = concat_opt.get_concat(ins->get_operator());
|
|
||||||
// Look for the concat operator
|
|
||||||
if(not concat_op.has_value())
|
|
||||||
continue;
|
|
||||||
// If any inputs are builtin or context free then abort
|
|
||||||
// If any inputs are used more than once, then abort since there could
|
|
||||||
// be errors due to aliasing
|
|
||||||
if(std::any_of(ins->inputs().begin(), ins->inputs().end(), [](auto arg) {
|
|
||||||
return arg->name().front() == '@' or
|
|
||||||
(arg->get_operator().is_context_free() and
|
|
||||||
not contains({"concat", "identity"}, arg->name())) or
|
|
||||||
arg->outputs().size() > 1;
|
|
||||||
}))
|
|
||||||
continue;
|
|
||||||
// We can only do this optimization when concat axis is either the leftmost
|
|
||||||
// axis OR the sizes to the left of this axis are all equal to 1
|
|
||||||
// Since we've already checked that the non-axis dimensions are identical
|
|
||||||
// we only need to check the first input
|
|
||||||
auto lens = ins->inputs().front()->get_shape().lens();
|
|
||||||
std::size_t axis_index = tune_axis(lens.size(), concat_op->axis, concat_op->name());
|
|
||||||
if(axis_index == 0 or
|
|
||||||
std::all_of(lens.begin(), lens.begin() + axis_index, [](auto x) { return x == 1; }))
|
|
||||||
{
|
|
||||||
// Last input should be an allocation
|
|
||||||
auto last = ins->inputs().back();
|
|
||||||
if(last->name() != concat_opt.allocate())
|
|
||||||
continue;
|
|
||||||
// Where are the allocations for the tensors to be concatenated?
|
|
||||||
std::vector<instruction_ref> allocations;
|
|
||||||
|
|
||||||
std::transform(
|
|
||||||
ins->inputs().begin(),
|
|
||||||
std::prev(ins->inputs().end()),
|
|
||||||
std::back_inserter(allocations),
|
|
||||||
[&](instruction_ref x) { return instruction::get_output_alias(x, true); });
|
|
||||||
|
|
||||||
if(std::any_of(allocations.begin(), allocations.end(), [&](auto x) {
|
|
||||||
return x->name() != concat_opt.allocate();
|
|
||||||
}))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Need to sort the allocations, so that we know where to
|
|
||||||
// insert the "super"-allocation
|
|
||||||
auto sorted_allocations = allocations;
|
|
||||||
std::sort(sorted_allocations.begin(),
|
|
||||||
sorted_allocations.end(),
|
|
||||||
[&](instruction_ref x, instruction_ref y) {
|
|
||||||
return std::distance(m.begin(), x) < std::distance(m.begin(), y);
|
|
||||||
});
|
|
||||||
// Move "super" allocation to the front
|
|
||||||
auto first = sorted_allocations.front();
|
|
||||||
auto super = m.move_instruction(last, first);
|
|
||||||
// Replace each allocation with a load
|
|
||||||
std::size_t offset = 0;
|
|
||||||
for(auto alloc : allocations)
|
|
||||||
{
|
|
||||||
op::load op{alloc->get_shape(), offset};
|
|
||||||
m.replace_instruction(alloc, op, {super});
|
|
||||||
offset += alloc->get_shape().bytes();
|
|
||||||
}
|
|
||||||
std::vector<instruction_ref> args = {super};
|
|
||||||
std::copy(ins->inputs().begin(), ins->inputs().end() - 1, std::back_inserter(args));
|
|
||||||
m.replace_instruction(ins, migraphx::make_op("identity"), args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,195 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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.
|
|
||||||
*/
|
|
||||||
#include <migraphx/eliminate_contiguous.hpp>
|
|
||||||
#include <migraphx/program.hpp>
|
|
||||||
#include <migraphx/instruction.hpp>
|
|
||||||
#include <migraphx/iterator_for.hpp>
|
|
||||||
#include <migraphx/ranges.hpp>
|
|
||||||
#include <migraphx/stringutils.hpp>
|
|
||||||
#include <migraphx/op/contiguous.hpp>
|
|
||||||
#include <migraphx/op/identity.hpp>
|
|
||||||
#include <migraphx/par_for.hpp>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
MIGRAPHX_DECLARE_ENV_VAR(MIGRAPHX_TRACE_ELIMINATE_CONTIGUOUS)
|
|
||||||
|
|
||||||
static bool try_compute_shape(instruction_ref ins,
|
|
||||||
const std::vector<shape>& inputs,
|
|
||||||
const std::vector<module_ref>& mods)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
shape new_shape = ins->get_operator().compute_shape(inputs, mods);
|
|
||||||
|
|
||||||
// Cannot tell if a dynamic shape will need to be made contiguous
|
|
||||||
if(new_shape.dynamic())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the output shape is a standard shape, no need to try its output
|
|
||||||
if(new_shape.standard())
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if no changes for the shape, the contiguous can also be removed
|
|
||||||
if(new_shape == ins->get_shape())
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto outputs = ins->outputs();
|
|
||||||
// If the current instruction has no output, it means it is the last
|
|
||||||
// instruction and generates a non-standard output shape, and the last
|
|
||||||
// output shape is different from the case with the contiguous operator
|
|
||||||
if(outputs.empty())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(auto output : outputs)
|
|
||||||
{
|
|
||||||
auto args = output->inputs();
|
|
||||||
std::vector<shape> input_shapes(args.size());
|
|
||||||
std::transform(args.begin(), args.end(), input_shapes.begin(), [&](auto& arg) {
|
|
||||||
return (arg == ins) ? new_shape : arg->get_shape();
|
|
||||||
});
|
|
||||||
|
|
||||||
if(not try_compute_shape(output, input_shapes, output->module_inputs()))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(const std::exception& e)
|
|
||||||
{
|
|
||||||
if(enabled(MIGRAPHX_TRACE_ELIMINATE_CONTIGUOUS{}))
|
|
||||||
{
|
|
||||||
std::cout << "Exception: " << e.what() << std::endl;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
if(enabled(MIGRAPHX_TRACE_ELIMINATE_CONTIGUOUS{}))
|
|
||||||
{
|
|
||||||
std::cout << "Unknown exception" << std::endl;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool try_compute_shape(instruction_ref ins,
|
|
||||||
const std::vector<instruction_ref>& args,
|
|
||||||
const std::vector<module_ref>& mods)
|
|
||||||
{
|
|
||||||
auto inputs = to_shapes(args);
|
|
||||||
return try_compute_shape(ins, inputs, mods);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class F>
|
|
||||||
static void remove_contiguous(const std::string& op_name, module& m, F f)
|
|
||||||
{
|
|
||||||
auto last = std::prev(m.end());
|
|
||||||
std::vector<instruction_ref> const_instructions;
|
|
||||||
|
|
||||||
for(auto ins : iterator_for(m))
|
|
||||||
{
|
|
||||||
// return instruction should have inputs with standard shape
|
|
||||||
if(ins->name() == "@return")
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if(ins != last and ins->outputs().empty())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if(not f(ins))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
auto args = ins->inputs();
|
|
||||||
auto mod_args = ins->module_inputs();
|
|
||||||
|
|
||||||
for(auto arg : ins->inputs())
|
|
||||||
{
|
|
||||||
if(arg->name() != op_name)
|
|
||||||
continue;
|
|
||||||
if(enabled(MIGRAPHX_TRACE_ELIMINATE_CONTIGUOUS{}))
|
|
||||||
{
|
|
||||||
std::cout << "eliminate_contiguous: ";
|
|
||||||
m.debug_print(ins);
|
|
||||||
}
|
|
||||||
auto prev = arg->inputs().front();
|
|
||||||
// create copy of args each time as they are modified inside the loop
|
|
||||||
auto new_args = ins->inputs();
|
|
||||||
replace(new_args, arg, prev);
|
|
||||||
if(try_compute_shape(ins, new_args, mod_args))
|
|
||||||
{
|
|
||||||
instruction::replace_argument(ins, arg, prev);
|
|
||||||
}
|
|
||||||
else if(prev->can_eval())
|
|
||||||
{
|
|
||||||
const_instructions.push_back(arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Perform static contiguous evaluations in parallel
|
|
||||||
std::vector<argument> literals(const_instructions.size());
|
|
||||||
par_for(const_instructions.size(), 1, [&](const auto i) {
|
|
||||||
auto c = op::contiguous{};
|
|
||||||
auto prev = const_instructions[i]->inputs().front();
|
|
||||||
// compute the output contiguous shape from the previous instruction shape
|
|
||||||
shape computed_shape = c.compute_shape({prev->get_shape()});
|
|
||||||
const std::vector<argument>& prev_eval = {prev->eval()};
|
|
||||||
// prev_eval should not be used in make_compute_output_shape() as computed_shape is static
|
|
||||||
auto co_shape = make_compute_output_shape(pack(c, computed_shape, prev_eval));
|
|
||||||
literals[i] = c.compute(co_shape, prev_eval);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Replace static contiguous operations with a literal
|
|
||||||
for(size_t i = 0; i < const_instructions.size(); i++)
|
|
||||||
{
|
|
||||||
auto l = m.add_literal(literals[i].get_shape(), literals[i].data());
|
|
||||||
m.replace_instruction(const_instructions[i], l);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void eliminate_contiguous::apply(module& m) const
|
|
||||||
{
|
|
||||||
// Skip contiguous from splits first
|
|
||||||
remove_contiguous(op_name, m, [](auto ins) {
|
|
||||||
if(ins->name() != "slice")
|
|
||||||
return true;
|
|
||||||
return (ins->inputs().front()->outputs().size() == 1);
|
|
||||||
});
|
|
||||||
remove_contiguous(op_name, m, [](auto) { return true; });
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,81 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
,*
|
|
||||||
* Copyright (c) 2015-2024 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.
|
|
||||||
*/
|
|
||||||
#include <migraphx/eliminate_convert.hpp>
|
|
||||||
#include <migraphx/module.hpp>
|
|
||||||
#include <migraphx/instruction.hpp>
|
|
||||||
#include <migraphx/make_op.hpp>
|
|
||||||
#include <migraphx/matcher.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Matches with some sequence of sequential convert instructions.
|
|
||||||
* If input to the sequence of converts has the same shape as the last convert,
|
|
||||||
* replace last convert with the input.
|
|
||||||
* If input to the sequence is not the same shape as the last convert,
|
|
||||||
* replace last convert with convert from the input to the last shape.
|
|
||||||
*/
|
|
||||||
struct find_nested_convert
|
|
||||||
{
|
|
||||||
auto matcher() const { return match::name("convert")(match::arg(0)(match::name("convert"))); }
|
|
||||||
|
|
||||||
void apply(module& m, const match::matcher_result& mr) const
|
|
||||||
{
|
|
||||||
auto matched_ins = mr.result;
|
|
||||||
auto prev_convert = matched_ins->inputs().front();
|
|
||||||
auto input = prev_convert->inputs().front();
|
|
||||||
while(input->name() == "convert")
|
|
||||||
{
|
|
||||||
input = input->inputs().front();
|
|
||||||
}
|
|
||||||
if(matched_ins->get_shape() == input->get_shape())
|
|
||||||
{
|
|
||||||
m.replace_instruction(matched_ins, input);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m.replace_instruction(matched_ins, matched_ins->get_operator(), input);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct find_nop_converts
|
|
||||||
{
|
|
||||||
auto matcher() const { return match::name("convert")(match::same_shape(match::arg(0))); }
|
|
||||||
|
|
||||||
void apply(module& m, const match::matcher_result& mr) const
|
|
||||||
{
|
|
||||||
auto ins = mr.result;
|
|
||||||
m.replace_instruction(ins, ins->inputs().front());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void eliminate_convert::apply(module& m) const
|
|
||||||
{
|
|
||||||
match::find_matches(m, find_nested_convert{}, find_nop_converts{});
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,127 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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.
|
|
||||||
*/
|
|
||||||
#include <migraphx/eliminate_data_type.hpp>
|
|
||||||
#include <migraphx/module.hpp>
|
|
||||||
#include <migraphx/iterator_for.hpp>
|
|
||||||
#include <migraphx/make_op.hpp>
|
|
||||||
#include <migraphx/instruction.hpp>
|
|
||||||
#include <migraphx/ranges.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
void insert_convert_to_supported_type(module& m,
|
|
||||||
instruction_ref ins,
|
|
||||||
migraphx::shape::type_t target_type,
|
|
||||||
std::set<migraphx::shape::type_t> unsupported_types)
|
|
||||||
{
|
|
||||||
migraphx::shape::type_t orig_type = ins->get_shape().type();
|
|
||||||
std::vector<instruction_ref> inputs = ins->inputs();
|
|
||||||
std::transform(inputs.begin(), inputs.end(), inputs.begin(), [&](const auto& i) {
|
|
||||||
if(contains(unsupported_types, i->get_shape().type()))
|
|
||||||
{
|
|
||||||
return m.insert_instruction(
|
|
||||||
ins,
|
|
||||||
migraphx::make_op("convert", {{"target_type", migraphx::to_value(target_type)}}),
|
|
||||||
i);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// if no change
|
|
||||||
if(inputs == ins->inputs())
|
|
||||||
return;
|
|
||||||
auto op = ins->get_operator();
|
|
||||||
auto attributes = op.attributes();
|
|
||||||
if(attributes.contains("general_data_type"))
|
|
||||||
{
|
|
||||||
op = make_op(attributes["general_data_type"].to<std::string>(), op.to_value());
|
|
||||||
}
|
|
||||||
auto new_ins = m.insert_instruction(ins, op, inputs);
|
|
||||||
if(orig_type == shape::tuple_type)
|
|
||||||
{
|
|
||||||
auto orig_outs = ins->outputs();
|
|
||||||
if(not std::all_of(orig_outs.begin(), orig_outs.end(), [&](const auto out_ins) {
|
|
||||||
return out_ins->name() == "get_tuple_elem";
|
|
||||||
}))
|
|
||||||
MIGRAPHX_THROW(
|
|
||||||
"eliminate_data_type: Instruction with tuple output doesn't have all its "
|
|
||||||
"usages as get_tuple_elem instruction");
|
|
||||||
|
|
||||||
std::transform(
|
|
||||||
orig_outs.begin(), orig_outs.end(), orig_outs.begin(), [&](const auto out_ins) {
|
|
||||||
auto gte_ins = m.insert_instruction(ins, out_ins->get_operator(), new_ins);
|
|
||||||
auto orig_out_type = out_ins->get_shape().type();
|
|
||||||
if(contains(unsupported_types, orig_out_type))
|
|
||||||
{
|
|
||||||
auto gte_convert = m.insert_instruction(
|
|
||||||
ins, make_op("convert", {{"target_type", orig_out_type}}), gte_ins);
|
|
||||||
return m.replace_instruction(out_ins, gte_convert);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return m.replace_instruction(out_ins, gte_ins);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto convert_back_ins = m.insert_instruction(
|
|
||||||
ins,
|
|
||||||
migraphx::make_op("convert", {{"target_type", migraphx::to_value(orig_type)}}),
|
|
||||||
new_ins);
|
|
||||||
m.replace_instruction(ins, convert_back_ins);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void eliminate_data_type::apply(module& m) const
|
|
||||||
{
|
|
||||||
static const std::vector<std::string> skip_op_names = {"convert",
|
|
||||||
"get_tuple_elem",
|
|
||||||
"if",
|
|
||||||
"loop",
|
|
||||||
"roialign",
|
|
||||||
"nonmaxsuppression",
|
|
||||||
"scatternd_add",
|
|
||||||
"scatternd_mul",
|
|
||||||
"scatternd_none",
|
|
||||||
"select_module"};
|
|
||||||
if(unsupported_types.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
for(auto ins : iterator_for(m))
|
|
||||||
{
|
|
||||||
if(ins->name()[0] == '@')
|
|
||||||
continue;
|
|
||||||
if(contains(skip_op_names, ins->name()) and not contains(unsupported_ops, ins->name()))
|
|
||||||
continue;
|
|
||||||
if(contains(unsupported_ops, "all") or contains(unsupported_ops, ins->name()))
|
|
||||||
insert_convert_to_supported_type(m, ins, target_type, unsupported_types);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,70 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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.
|
|
||||||
*/
|
|
||||||
#include <migraphx/eliminate_identity.hpp>
|
|
||||||
#include <migraphx/program.hpp>
|
|
||||||
#include <migraphx/instruction.hpp>
|
|
||||||
#include <migraphx/iterator_for.hpp>
|
|
||||||
#include <migraphx/stringutils.hpp>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
void eliminate_identity::apply(module& m) const
|
|
||||||
{
|
|
||||||
auto last = std::prev(m.end());
|
|
||||||
for(auto ins : iterator_for(m))
|
|
||||||
{
|
|
||||||
// Skip the first instruction, since we always process the previous
|
|
||||||
// instruction
|
|
||||||
if(ins == m.begin())
|
|
||||||
continue;
|
|
||||||
const auto i = std::prev(ins);
|
|
||||||
|
|
||||||
if(i->name() == "identity")
|
|
||||||
{
|
|
||||||
m.replace_instruction(i, i->inputs().front());
|
|
||||||
m.move_instruction(i, m.end());
|
|
||||||
}
|
|
||||||
if(ins == last)
|
|
||||||
{
|
|
||||||
if(ins->name() == "identity")
|
|
||||||
{
|
|
||||||
const instruction_ref& identity_input = ins->inputs().front();
|
|
||||||
if(identity_input->outputs().size() == 1)
|
|
||||||
{
|
|
||||||
m.move_instruction(identity_input, last);
|
|
||||||
// since this is the last instruction, removing it only
|
|
||||||
// requires changing "last" and calling remove below
|
|
||||||
last = std::prev(last);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m.remove_instructions(std::next(last), m.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,114 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2022 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.
|
|
||||||
*/
|
|
||||||
#include <migraphx/eliminate_pad.hpp>
|
|
||||||
#include <migraphx/program.hpp>
|
|
||||||
#include <migraphx/instruction.hpp>
|
|
||||||
#include <migraphx/op/convolution.hpp>
|
|
||||||
#include <migraphx/op/im2col.hpp>
|
|
||||||
#include <migraphx/op/pooling.hpp>
|
|
||||||
#include <migraphx/op/pad.hpp>
|
|
||||||
#include <migraphx/make_op.hpp>
|
|
||||||
#include <migraphx/iterator_for.hpp>
|
|
||||||
#include <migraphx/stringutils.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
static void update_op(const instruction_ref& input, const instruction_ref& ins, module& m)
|
|
||||||
{
|
|
||||||
auto pad_op = any_cast<op::pad>(input->get_operator());
|
|
||||||
|
|
||||||
auto kdims = input->get_shape().lens().size() - 2;
|
|
||||||
auto kdims_it = pad_op.pads.begin() + 2;
|
|
||||||
|
|
||||||
std::vector<size_t> pads_l(kdims_it, kdims_it + kdims);
|
|
||||||
std::vector<size_t> pads_r(kdims_it + kdims + 2, pad_op.pads.end());
|
|
||||||
|
|
||||||
auto op = ins->get_operator();
|
|
||||||
std::vector<size_t> padding(kdims * 2, 0);
|
|
||||||
|
|
||||||
std::transform(
|
|
||||||
pads_l.begin(), pads_l.end(), padding.begin(), padding.begin(), std::plus<size_t>());
|
|
||||||
std::transform(pads_r.begin(),
|
|
||||||
pads_r.end(),
|
|
||||||
padding.begin() + kdims,
|
|
||||||
padding.begin() + kdims,
|
|
||||||
std::plus<size_t>());
|
|
||||||
|
|
||||||
op.from_value({{"padding", padding}});
|
|
||||||
|
|
||||||
std::vector<instruction_ref> new_inputs{ins->inputs()};
|
|
||||||
new_inputs.front() = input->inputs().front();
|
|
||||||
|
|
||||||
m.replace_instruction(ins, op, new_inputs);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void update_pooling(const instruction_ref& input, const instruction_ref& ins, module& m)
|
|
||||||
{
|
|
||||||
auto op = any_cast<op::pooling>(ins->get_operator());
|
|
||||||
if(op.mode == op::pooling_mode::average)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto pad_op = any_cast<op::pad>(input->get_operator());
|
|
||||||
|
|
||||||
auto kdims = input->get_shape().lens().size() - 2;
|
|
||||||
auto kdims_it = pad_op.pads.begin() + 2;
|
|
||||||
|
|
||||||
std::vector<size_t> pads_l(kdims_it, kdims_it + kdims);
|
|
||||||
std::vector<size_t> pads_r(kdims_it + kdims + 2, pad_op.pads.end());
|
|
||||||
|
|
||||||
std::transform(
|
|
||||||
pads_l.begin(), pads_l.end(), op.padding.begin(), op.padding.begin(), std::plus<size_t>());
|
|
||||||
std::transform(pads_r.begin(),
|
|
||||||
pads_r.end(),
|
|
||||||
op.padding.begin() + kdims,
|
|
||||||
op.padding.begin() + kdims,
|
|
||||||
std::plus<size_t>());
|
|
||||||
|
|
||||||
std::vector<instruction_ref> new_inputs{ins->inputs()};
|
|
||||||
new_inputs.front() = input->inputs().front();
|
|
||||||
|
|
||||||
m.replace_instruction(ins, op, new_inputs);
|
|
||||||
}
|
|
||||||
|
|
||||||
void eliminate_pad::apply(module& m) const
|
|
||||||
{
|
|
||||||
for(auto ins : iterator_for(m))
|
|
||||||
{
|
|
||||||
const std::string& op_name = ins->name();
|
|
||||||
if(op_name != "convolution" and op_name != "im2col" and op_name != "pooling")
|
|
||||||
continue;
|
|
||||||
auto input = ins->inputs().front();
|
|
||||||
if(input->name() != "pad")
|
|
||||||
continue;
|
|
||||||
if(op_name == "convolution" or op_name == "im2col")
|
|
||||||
update_op(input, ins, m);
|
|
||||||
else if(op_name == "pooling")
|
|
||||||
update_pooling(input, ins, m);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,73 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2022 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.
|
|
||||||
*/
|
|
||||||
#include <migraphx/env.hpp>
|
|
||||||
#include <migraphx/ranges.hpp>
|
|
||||||
#include <cstdlib>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
bool enabled(const char* name)
|
|
||||||
{
|
|
||||||
auto e = env(name);
|
|
||||||
if(e.empty())
|
|
||||||
return false;
|
|
||||||
return contains({"1", "enable", "enabled", "yes", "true"}, e.front());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool disabled(const char* name)
|
|
||||||
{
|
|
||||||
auto e = env(name);
|
|
||||||
if(e.empty())
|
|
||||||
return false;
|
|
||||||
return contains({"0", "disable", "disabled", "no", "false"}, e.front());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t value_of(const char* name, std::size_t fallback)
|
|
||||||
{
|
|
||||||
auto e = env(name);
|
|
||||||
if(e.empty())
|
|
||||||
return fallback;
|
|
||||||
return std::stoul(e.front());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string string_value_of(const char* name, std::string fallback)
|
|
||||||
{
|
|
||||||
auto e = env(name);
|
|
||||||
if(e.empty())
|
|
||||||
return fallback;
|
|
||||||
return e.front();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> env(const char* name)
|
|
||||||
{
|
|
||||||
auto* p = std::getenv(name);
|
|
||||||
if(p == nullptr)
|
|
||||||
return {};
|
|
||||||
else
|
|
||||||
return {{p}};
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,85 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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.
|
|
||||||
*/
|
|
||||||
#include <migraphx/file_buffer.hpp>
|
|
||||||
#include <migraphx/errors.hpp>
|
|
||||||
#include <migraphx/fileutils.hpp>
|
|
||||||
#include <fstream>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
T generic_read_file(const fs::path& filename, size_t offset = 0, size_t nbytes = 0)
|
|
||||||
{
|
|
||||||
std::ifstream is(filename, std::ios::binary | std::ios::ate);
|
|
||||||
if(not is.is_open())
|
|
||||||
MIGRAPHX_THROW("Failure opening file: " + filename);
|
|
||||||
if(nbytes == 0)
|
|
||||||
{
|
|
||||||
// if there is a non-zero offset and nbytes is not set,
|
|
||||||
// calculate size of remaining bytes to read
|
|
||||||
nbytes = is.tellg();
|
|
||||||
if(offset > nbytes)
|
|
||||||
MIGRAPHX_THROW("offset is larger than file size");
|
|
||||||
nbytes -= offset;
|
|
||||||
}
|
|
||||||
if(nbytes < 1)
|
|
||||||
MIGRAPHX_THROW("Invalid size for: " + filename);
|
|
||||||
is.seekg(offset, std::ios::beg);
|
|
||||||
|
|
||||||
T buffer(nbytes, 0);
|
|
||||||
if(not is.read(&buffer[0], nbytes))
|
|
||||||
MIGRAPHX_THROW("Error reading file: " + filename);
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<char> read_buffer(const fs::path& filename, size_t offset, size_t nbytes)
|
|
||||||
{
|
|
||||||
return generic_read_file<std::vector<char>>(filename, offset, nbytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string read_string(const fs::path& filename)
|
|
||||||
{
|
|
||||||
return generic_read_file<std::string>(filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
void write_string(const fs::path& filename, const std::string& buffer)
|
|
||||||
{
|
|
||||||
write_buffer(filename, buffer.data(), buffer.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
void write_buffer(const fs::path& filename, const char* buffer, std::size_t size)
|
|
||||||
{
|
|
||||||
std::ofstream os(filename, std::ios::out | std::ios::binary);
|
|
||||||
os.write(buffer, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void write_buffer(const fs::path& filename, const std::vector<char>& buffer)
|
|
||||||
{
|
|
||||||
write_buffer(filename, buffer.data(), buffer.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,70 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <migraphx/fileutils.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
constexpr std::string_view executable_postfix{".exe"};
|
|
||||||
constexpr std::string_view library_prefix{""};
|
|
||||||
constexpr std::string_view library_postfix{".dll"};
|
|
||||||
constexpr std::string_view static_library_postfix{".lib"};
|
|
||||||
constexpr std::string_view object_file_postfix{".obj"};
|
|
||||||
#else
|
|
||||||
constexpr std::string_view executable_postfix{""};
|
|
||||||
constexpr std::string_view library_prefix{"lib"};
|
|
||||||
constexpr std::string_view library_postfix{".so"};
|
|
||||||
constexpr std::string_view static_library_postfix{".a"};
|
|
||||||
constexpr std::string_view object_file_postfix{".o"};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
fs::path make_executable_filename(std::string_view name)
|
|
||||||
{
|
|
||||||
return std::string{name}.append(executable_postfix);
|
|
||||||
}
|
|
||||||
|
|
||||||
fs::path make_shared_object_filename(std::string_view name)
|
|
||||||
{
|
|
||||||
return std::string{library_prefix}.append(name).append(library_postfix);
|
|
||||||
}
|
|
||||||
|
|
||||||
fs::path make_object_file_filename(std::string_view name)
|
|
||||||
{
|
|
||||||
return std::string{name}.append(object_file_postfix);
|
|
||||||
}
|
|
||||||
|
|
||||||
fs::path make_static_library_filename(std::string_view name)
|
|
||||||
{
|
|
||||||
return std::string{library_prefix}.append(name).append(static_library_postfix);
|
|
||||||
}
|
|
||||||
|
|
||||||
fs::path append_extension(const fs::path& path, std::string_view ext)
|
|
||||||
{
|
|
||||||
return fs::path{path}.replace_extension(path.extension().string().append(ext));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,178 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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.
|
|
||||||
*/
|
|
||||||
#include <migraphx/fp8_ocp_to_fnuz.hpp>
|
|
||||||
#include <migraphx/matcher.hpp>
|
|
||||||
#include <migraphx/make_op.hpp>
|
|
||||||
#include <migraphx/dead_code_elimination.hpp>
|
|
||||||
#include <migraphx/pass_manager.hpp>
|
|
||||||
#include <migraphx/match/dq_helpers.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
using fp8::fp8e4m3fnuz;
|
|
||||||
|
|
||||||
std::unordered_set<std::string> get_quantizable_op_names()
|
|
||||||
{
|
|
||||||
static std::unordered_set<std::string> s = {"convolution", "dot"};
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct match_fp8ocp_convert_to_fp8fnuz
|
|
||||||
{
|
|
||||||
auto matcher() const
|
|
||||||
{
|
|
||||||
auto dq1 = match::arg(0)(
|
|
||||||
skip_post_dq_ops(match::dequantizelinear_op("scale1", "zp1").bind("dq1")));
|
|
||||||
auto dq2 = match::arg(1)(
|
|
||||||
skip_post_dq_ops(match::dequantizelinear_op("scale2", "zp2").bind("dq2")));
|
|
||||||
return match::name(get_quantizable_op_names())(dq1, dq2);
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto bit_cast_and_handle_specials(module& m,
|
|
||||||
const instruction_ref dq,
|
|
||||||
const instruction_ref x,
|
|
||||||
const instruction_ref bits_0x80_lit,
|
|
||||||
const instruction_ref bits_0x7f_lit,
|
|
||||||
const instruction_ref bits_0xff_lit,
|
|
||||||
const instruction_ref bits_0x00_lit)
|
|
||||||
{
|
|
||||||
auto x_lens = x->get_shape().lens();
|
|
||||||
auto cast_input = m.insert_instruction(
|
|
||||||
dq, make_op("bit_cast", {{"target_type", shape::fp8e4m3fnuz_type}}), x);
|
|
||||||
auto mb_bits_0x80_lit = m.insert_instruction(
|
|
||||||
dq, make_op("multibroadcast", {{"out_lens", x_lens}}), bits_0x80_lit);
|
|
||||||
auto mb_bits_0x7f_lit = m.insert_instruction(
|
|
||||||
dq, make_op("multibroadcast", {{"out_lens", x_lens}}), bits_0x7f_lit);
|
|
||||||
auto mb_bits_0xff_lit = m.insert_instruction(
|
|
||||||
dq, make_op("multibroadcast", {{"out_lens", x_lens}}), bits_0xff_lit);
|
|
||||||
auto mb_zero_lit = m.insert_instruction(
|
|
||||||
dq, make_op("multibroadcast", {{"out_lens", x_lens}}), bits_0x00_lit);
|
|
||||||
// negative zero in fp8e4m3fn to zero in fp8e4m3fnuz
|
|
||||||
// a == 0x80 ? 0x0 : a
|
|
||||||
auto is_neg_zero = m.insert_instruction(dq, make_op("equal"), cast_input, mb_bits_0x80_lit);
|
|
||||||
auto ret = m.insert_instruction(dq, make_op("where"), is_neg_zero, mb_zero_lit, cast_input);
|
|
||||||
|
|
||||||
// positive and negative NaN in fp8e4m3fn to NaN in fp8e4m3fnuz
|
|
||||||
// (a == 0x7f or a == 0xff) ? 0x80 : a
|
|
||||||
auto eq_0x7f = m.insert_instruction(dq, make_op("equal"), ret, mb_bits_0x7f_lit);
|
|
||||||
|
|
||||||
auto eq_0xff = m.insert_instruction(dq, make_op("equal"), ret, mb_bits_0xff_lit);
|
|
||||||
|
|
||||||
auto cond = m.insert_instruction(dq, make_op("logical_or"), eq_0x7f, eq_0xff);
|
|
||||||
ret = m.insert_instruction(dq, make_op("where"), cond, mb_bits_0x80_lit, ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the same broadcast instructions after adjusted scales or
|
|
||||||
// adjusted zero points from after the originals. Similar to
|
|
||||||
// propagate_quantized_ins in simplify_qdq.
|
|
||||||
static auto propagate_broadcasts(module& m,
|
|
||||||
const instruction_ref adj,
|
|
||||||
const instruction_ref ori,
|
|
||||||
const instruction_ref start,
|
|
||||||
const instruction_ref insert_pt)
|
|
||||||
{
|
|
||||||
auto prev_ins = start;
|
|
||||||
std::vector<instruction_ref> ins_between;
|
|
||||||
// matcher skips continguous, multi/broadcasts and transposes, collect all those
|
|
||||||
// instructions
|
|
||||||
while(prev_ins != ori)
|
|
||||||
{
|
|
||||||
ins_between.push_back(prev_ins);
|
|
||||||
prev_ins = prev_ins->inputs().front();
|
|
||||||
}
|
|
||||||
auto ret = adj;
|
|
||||||
for(auto ins : reverse_iterator_for(ins_between))
|
|
||||||
{
|
|
||||||
ret = m.insert_instruction(insert_pt, (*ins)->get_operator(), {ret});
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto cast_to_fnuz(module& m,
|
|
||||||
const instruction_ref dq,
|
|
||||||
const instruction_ref input,
|
|
||||||
const instruction_ref dq_scale,
|
|
||||||
const instruction_ref dq_zp)
|
|
||||||
{
|
|
||||||
auto x = input;
|
|
||||||
std::vector<fp8e4m3fnuz> bits_0x80 = {fp8e4m3fnuz(0x80, fp8e4m3fnuz::from_bits())};
|
|
||||||
auto bits_0x80_lit = m.add_literal(shape{shape::fp8e4m3fnuz_type, {1}, {0}}, bits_0x80);
|
|
||||||
|
|
||||||
std::vector<fp8e4m3fnuz> bits_0x7f = {fp8e4m3fnuz(0x7f, fp8e4m3fnuz::from_bits())};
|
|
||||||
auto bits_0x7f_lit = m.add_literal(shape{shape::fp8e4m3fnuz_type, {1}, {0}}, bits_0x7f);
|
|
||||||
|
|
||||||
std::vector<fp8e4m3fnuz> bits_0xff = {fp8e4m3fnuz(0xff, fp8e4m3fnuz::from_bits())};
|
|
||||||
auto bits_0xff_lit = m.add_literal(shape{shape::fp8e4m3fnuz_type, {1}, {0}}, bits_0xff);
|
|
||||||
|
|
||||||
std::vector<fp8e4m3fnuz> bits_0x00 = {fp8e4m3fnuz(0x00, fp8e4m3fnuz::from_bits())};
|
|
||||||
auto bits_0x00_lit = m.add_literal(shape{shape::fp8e4m3fnuz_type, {1}, {0}}, bits_0x00);
|
|
||||||
|
|
||||||
x = bit_cast_and_handle_specials(
|
|
||||||
m, dq, x, bits_0x80_lit, bits_0x7f_lit, bits_0xff_lit, bits_0x00_lit);
|
|
||||||
auto adj_dq_zp = bit_cast_and_handle_specials(
|
|
||||||
m, dq, dq_zp, bits_0x80_lit, bits_0x7f_lit, bits_0xff_lit, bits_0x00_lit);
|
|
||||||
|
|
||||||
// adj_scale = 2 * scale
|
|
||||||
auto two_lit = m.add_literal(literal{shape{dq_scale->get_shape().type()}, {2}});
|
|
||||||
two_lit = m.insert_instruction(
|
|
||||||
dq, make_op("multibroadcast", {{"out_lens", dq_scale->get_shape().lens()}}), two_lit);
|
|
||||||
auto adj_dq_scale = m.insert_instruction(dq, make_op("mul"), dq_scale, two_lit);
|
|
||||||
|
|
||||||
adj_dq_scale = propagate_broadcasts(m, adj_dq_scale, dq_scale, dq->inputs().at(1), dq);
|
|
||||||
adj_dq_zp = propagate_broadcasts(m, adj_dq_zp, dq_zp, dq->inputs().at(2), dq);
|
|
||||||
m.replace_instruction(dq, make_op("dequantizelinear"), x, adj_dq_scale, adj_dq_zp);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto apply(module& m, const match::matcher_result& r) const
|
|
||||||
{
|
|
||||||
auto dq1 = r.instructions["dq1"];
|
|
||||||
auto dq2 = r.instructions["dq2"];
|
|
||||||
auto scale1 = r.instructions["scale1"];
|
|
||||||
auto scale2 = r.instructions["scale2"];
|
|
||||||
auto zp1 = r.instructions["zp1"];
|
|
||||||
auto zp2 = r.instructions["zp2"];
|
|
||||||
|
|
||||||
std::set<migraphx::shape::type_t> supported_types = {migraphx::shape::fp8e4m3fn_type};
|
|
||||||
if(not contains(supported_types, dq1->inputs().front()->get_shape().type()) or
|
|
||||||
not contains(supported_types, dq2->inputs().front()->get_shape().type()))
|
|
||||||
return;
|
|
||||||
|
|
||||||
cast_to_fnuz(m, dq1, dq1->inputs().front(), scale1, zp1);
|
|
||||||
cast_to_fnuz(m, dq2, dq2->inputs().front(), scale2, zp2);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
void fp8_ocp_to_fnuz::apply(module_pass_manager& mpm) const
|
|
||||||
{
|
|
||||||
module_ref mm = &mpm.get_module();
|
|
||||||
match::find_matches(*mm, match_fp8ocp_convert_to_fp8fnuz{});
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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.
|
|
||||||
*/
|
|
||||||
#include <migraphx/fp_to_double.hpp>
|
|
||||||
#include <migraphx/eliminate_data_type.hpp>
|
|
||||||
#include <migraphx/eliminate_convert.hpp>
|
|
||||||
#include <migraphx/dead_code_elimination.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
void fp_to_double::apply(module_pass_manager& mpm) const
|
|
||||||
{
|
|
||||||
mpm.run_pass(eliminate_data_type{convert_fp_types, shape::type_t::double_type});
|
|
||||||
mpm.run_pass(eliminate_convert{});
|
|
||||||
mpm.run_pass(migraphx::dead_code_elimination{});
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,242 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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.
|
|
||||||
*/
|
|
||||||
#include <migraphx/fuse_concat.hpp>
|
|
||||||
#include <migraphx/pass_manager.hpp>
|
|
||||||
#include <migraphx/module.hpp>
|
|
||||||
#include <migraphx/dead_code_elimination.hpp>
|
|
||||||
#include <migraphx/algorithm.hpp>
|
|
||||||
#include <migraphx/check_shapes.hpp>
|
|
||||||
#include <migraphx/instruction.hpp>
|
|
||||||
#include <migraphx/matcher.hpp>
|
|
||||||
#include <migraphx/make_op.hpp>
|
|
||||||
#include <migraphx/register_op.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
unsigned int get_noop_counter()
|
|
||||||
{
|
|
||||||
static unsigned int counter = 0;
|
|
||||||
return counter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct fused_concat
|
|
||||||
{
|
|
||||||
int64_t axis = 0;
|
|
||||||
|
|
||||||
std::string name() const { return "fused_concat"; }
|
|
||||||
|
|
||||||
template <class Self, class F>
|
|
||||||
static auto reflect(Self& self, F f)
|
|
||||||
{
|
|
||||||
return pack(f(self.axis, "axis"));
|
|
||||||
}
|
|
||||||
|
|
||||||
shape compute_shape(std::vector<shape> inputs, const std::vector<module_ref>& mods) const
|
|
||||||
{
|
|
||||||
check_shapes{inputs, *this}.same_ndims();
|
|
||||||
// original concat can have multiple inputs. Let's say it has `n` input args.
|
|
||||||
// Each of those `n` input args are converted into pointwise modules that take atleast 1
|
|
||||||
// input parameter. Fused concat will have `n+1` module arguments. `n+1`th module is the
|
|
||||||
// post pointwise module which can take 0 or more input arguments.
|
|
||||||
if((inputs.size() + 1) < mods.size())
|
|
||||||
MIGRAPHX_THROW("FUSED_CONCAT: Missing fused modules inputs parameters");
|
|
||||||
auto input_iter = inputs.begin();
|
|
||||||
std::vector<shape> concat_inputs;
|
|
||||||
for(module_ref mod : range(mods.begin(), mods.end() - 1))
|
|
||||||
{
|
|
||||||
concat_inputs.push_back(*input_iter);
|
|
||||||
input_iter += mod->get_parameter_names().size();
|
|
||||||
}
|
|
||||||
module_ref post_mod = mods.back();
|
|
||||||
// post_mod has one input argument that is result of concat and will get generated from
|
|
||||||
// pre-mods internally. Therefore deduct 1 from post_mod params while asserting.
|
|
||||||
assert(input_iter + post_mod->get_parameter_names().size() - 1 == inputs.end());
|
|
||||||
auto type = std::prev(post_mod->end())->get_shape().type();
|
|
||||||
const auto& first_shape_lens = concat_inputs.front().lens();
|
|
||||||
auto mismatch_it =
|
|
||||||
std::find_if_not(concat_inputs.begin() + 1, concat_inputs.end(), [&](auto s) {
|
|
||||||
const auto& lens = s.lens();
|
|
||||||
return std::equal(lens.begin(),
|
|
||||||
lens.begin() + axis,
|
|
||||||
first_shape_lens.begin(),
|
|
||||||
first_shape_lens.begin() + axis) and
|
|
||||||
std::equal(lens.begin() + axis + 1,
|
|
||||||
lens.end(),
|
|
||||||
first_shape_lens.begin() + axis + 1,
|
|
||||||
first_shape_lens.end());
|
|
||||||
});
|
|
||||||
if(mismatch_it != concat_inputs.end())
|
|
||||||
MIGRAPHX_THROW("FUSED_CONCAT: all input dimensions should match along non-axis of " +
|
|
||||||
std::to_string(axis) + ": {" + to_string_range(first_shape_lens) +
|
|
||||||
"} != {" + to_string_range(mismatch_it->lens()) + "}");
|
|
||||||
|
|
||||||
std::size_t new_dim_axis = transform_accumulate(
|
|
||||||
concat_inputs.begin(), concat_inputs.end(), 0, std::plus<>{}, [&](const auto& input) {
|
|
||||||
return input.lens()[axis];
|
|
||||||
});
|
|
||||||
auto new_lens = concat_inputs.front().lens();
|
|
||||||
new_lens[axis] = new_dim_axis;
|
|
||||||
return shape::from_permutation(type, new_lens, find_permutation(inputs));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
MIGRAPHX_REGISTER_OP(fused_concat);
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
struct find_concat_pointwise
|
|
||||||
{
|
|
||||||
auto matcher() const
|
|
||||||
{
|
|
||||||
auto pointwise_used_once = match::name("pointwise")(match::used_once());
|
|
||||||
return match::name("concat")(match::used_once(),
|
|
||||||
match::any_of[match::inputs()](pointwise_used_once));
|
|
||||||
}
|
|
||||||
|
|
||||||
void apply(module_pass_manager& mpm, const match::matcher_result& r) const
|
|
||||||
{
|
|
||||||
auto concat_ins = r.result;
|
|
||||||
|
|
||||||
std::vector<instruction_ref> inputs;
|
|
||||||
size_t num_noops = 0;
|
|
||||||
for(auto input : concat_ins->inputs())
|
|
||||||
{
|
|
||||||
if(input->name() == "pointwise" and input->outputs().size() == 1)
|
|
||||||
{
|
|
||||||
inputs.insert(inputs.end(), input->inputs().begin(), input->inputs().end());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
num_noops++;
|
|
||||||
inputs.push_back(input);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(num_noops > std::max(size_t{1}, concat_ins->inputs().size() / 4))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::vector<module_ref> module_inputs;
|
|
||||||
std::transform(concat_ins->inputs().begin(),
|
|
||||||
concat_ins->inputs().end(),
|
|
||||||
std::back_inserter(module_inputs),
|
|
||||||
[&](instruction_ref input) {
|
|
||||||
if(input->name() == "pointwise" and input->outputs().size() == 1)
|
|
||||||
{
|
|
||||||
auto* pm = input->module_inputs().front();
|
|
||||||
return mpm.create_module("concat:" + pm->name(), *pm);
|
|
||||||
}
|
|
||||||
auto* pm = mpm.create_module("concat:noop" +
|
|
||||||
std::to_string(get_noop_counter()));
|
|
||||||
auto x = pm->add_parameter("x0", shape{input->get_shape().type()});
|
|
||||||
pm->add_return({x});
|
|
||||||
return pm;
|
|
||||||
});
|
|
||||||
auto* post_pm = mpm.create_module("noop:concat" + std::to_string(get_noop_counter()));
|
|
||||||
auto x = post_pm->add_parameter("!x0", shape{concat_ins->get_shape().type()});
|
|
||||||
post_pm->add_return({x});
|
|
||||||
module_inputs.push_back(post_pm);
|
|
||||||
mpm.get_module().replace_instruction(
|
|
||||||
concat_ins,
|
|
||||||
make_op("fused_concat", concat_ins->normalized_operator().to_value()),
|
|
||||||
inputs,
|
|
||||||
module_inputs);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct find_pointwise_concat_pointwise
|
|
||||||
{
|
|
||||||
auto matcher() const
|
|
||||||
{
|
|
||||||
auto pointwise = match::name("pointwise")(match::used_once());
|
|
||||||
auto concat =
|
|
||||||
match::name("concat")(match::used_once(), match::any_of[match::inputs()](pointwise));
|
|
||||||
return match::name("pointwise")(match::any_of[match::inputs()](concat.bind("concat")));
|
|
||||||
}
|
|
||||||
|
|
||||||
void apply(module_pass_manager& mpm, const match::matcher_result& r) const
|
|
||||||
{
|
|
||||||
auto ins = r.result;
|
|
||||||
auto concat_ins = r.instructions["concat"];
|
|
||||||
|
|
||||||
auto concat_arg = std::find(ins->inputs().begin(), ins->inputs().end(), concat_ins) -
|
|
||||||
ins->inputs().begin();
|
|
||||||
std::vector<instruction_ref> inputs;
|
|
||||||
for(auto input : concat_ins->inputs())
|
|
||||||
{
|
|
||||||
if(input->name() == "pointwise" and input->outputs().size() == 1)
|
|
||||||
inputs.insert(inputs.end(), input->inputs().begin(), input->inputs().end());
|
|
||||||
else
|
|
||||||
inputs.push_back(input);
|
|
||||||
}
|
|
||||||
std::copy_if(ins->inputs().begin(),
|
|
||||||
ins->inputs().end(),
|
|
||||||
std::back_inserter(inputs),
|
|
||||||
[&](auto input) { return input != concat_ins; });
|
|
||||||
|
|
||||||
std::vector<module_ref> module_inputs;
|
|
||||||
std::transform(concat_ins->inputs().begin(),
|
|
||||||
concat_ins->inputs().end(),
|
|
||||||
std::back_inserter(module_inputs),
|
|
||||||
[&](instruction_ref input) {
|
|
||||||
if(input->name() == "pointwise" and input->outputs().size() == 1)
|
|
||||||
{
|
|
||||||
auto* pm = input->module_inputs().front();
|
|
||||||
return mpm.create_module("concat:" + pm->name(), *pm);
|
|
||||||
}
|
|
||||||
auto* pm = mpm.create_module("concat:noop" +
|
|
||||||
std::to_string(get_noop_counter()));
|
|
||||||
auto x = pm->add_parameter("x0", shape{input->get_shape().type()});
|
|
||||||
pm->add_return({x});
|
|
||||||
return pm;
|
|
||||||
});
|
|
||||||
|
|
||||||
auto* post_pm = ins->module_inputs().front();
|
|
||||||
auto* rm = mpm.create_module(post_pm->name() + ":concat", *post_pm);
|
|
||||||
std::vector<std::string> names = rm->get_parameter_names();
|
|
||||||
std::sort(names.begin(), names.end());
|
|
||||||
auto concat_param_name = names[concat_arg];
|
|
||||||
auto concat_param = rm->get_parameter(concat_param_name);
|
|
||||||
auto param = rm->add_parameter("!" + concat_param_name, concat_param->get_shape());
|
|
||||||
rm->replace_instruction(concat_param, param);
|
|
||||||
rm->remove_instruction(concat_param);
|
|
||||||
|
|
||||||
module_inputs.push_back(rm);
|
|
||||||
mpm.get_module().replace_instruction(
|
|
||||||
ins,
|
|
||||||
make_op("fused_concat", concat_ins->normalized_operator().to_value()),
|
|
||||||
inputs,
|
|
||||||
module_inputs);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
void fuse_concat::apply(module_pass_manager& mpm) const
|
|
||||||
{
|
|
||||||
match::find_matches(mpm, find_pointwise_concat_pointwise{});
|
|
||||||
mpm.run_pass(migraphx::dead_code_elimination{});
|
|
||||||
match::find_matches(mpm, find_concat_pointwise{});
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,262 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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.
|
|
||||||
*/
|
|
||||||
#include <migraphx/fuse_pointwise.hpp>
|
|
||||||
#include <migraphx/pass_manager.hpp>
|
|
||||||
#include <migraphx/eliminate_identity.hpp>
|
|
||||||
#include <migraphx/dead_code_elimination.hpp>
|
|
||||||
#include <migraphx/instruction.hpp>
|
|
||||||
#include <migraphx/program.hpp>
|
|
||||||
#include <migraphx/make_op.hpp>
|
|
||||||
#include <migraphx/iterator_for.hpp>
|
|
||||||
#include <migraphx/ranges.hpp>
|
|
||||||
#include <migraphx/matcher.hpp>
|
|
||||||
#include <migraphx/param_utils.hpp>
|
|
||||||
#include <migraphx/rewrite_reshapes.hpp>
|
|
||||||
#include <iterator>
|
|
||||||
|
|
||||||
MIGRAPHX_DECLARE_ENV_VAR(MIGRAPHX_DISABLE_POINTWISE_FUSION)
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
static literal get_scalar(instruction_ref ins)
|
|
||||||
{
|
|
||||||
if(contains({"contiguous", "broadcast", "multibroadcast"}, ins->name()))
|
|
||||||
return get_scalar(ins->inputs().front());
|
|
||||||
const auto& s = ins->get_shape();
|
|
||||||
if(s.elements() != 1 and not(s.scalar()))
|
|
||||||
return {};
|
|
||||||
if(not ins->can_eval())
|
|
||||||
return {};
|
|
||||||
auto e = ins->eval();
|
|
||||||
literal r{};
|
|
||||||
// needed for bool as visit_at invokes as() which promotes bool to int8
|
|
||||||
// Without this we'll break type checks for logical ops that are fused.
|
|
||||||
if(e.get_shape().type() == shape::bool_type)
|
|
||||||
{
|
|
||||||
r = literal{e.at<bool>()};
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
e.visit_at([&](auto x) { r = literal{x}; });
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void create_pointwise_modules(module_pass_manager& mpm)
|
|
||||||
{
|
|
||||||
std::size_t n = 0;
|
|
||||||
for(auto ins : iterator_for(mpm.get_module()))
|
|
||||||
{
|
|
||||||
if(not ins->get_operator().attributes().get("pointwise", false))
|
|
||||||
continue;
|
|
||||||
if(ins->get_operator().name() == "layout")
|
|
||||||
continue;
|
|
||||||
auto* pm = mpm.create_module(mpm.get_module().name() + ":pointwise" + std::to_string(n++));
|
|
||||||
pm->set_bypass();
|
|
||||||
|
|
||||||
std::unordered_map<instruction_ref, instruction_ref> param_map;
|
|
||||||
std::vector<instruction_ref> pointwise_inputs;
|
|
||||||
std::size_t i = 0;
|
|
||||||
|
|
||||||
for(auto input : ins->inputs())
|
|
||||||
{
|
|
||||||
if(contains(param_map, input))
|
|
||||||
continue;
|
|
||||||
auto scalar = get_scalar(input);
|
|
||||||
if(scalar.empty())
|
|
||||||
{
|
|
||||||
pointwise_inputs.push_back(input);
|
|
||||||
param_map[input] =
|
|
||||||
pm->add_parameter(param_name(i), shape{input->get_shape().type()});
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
param_map[input] = pm->add_literal(scalar);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't create pointwise module if no inputs are detected
|
|
||||||
if(pointwise_inputs.empty())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
std::vector<instruction_ref> inputs;
|
|
||||||
std::transform(ins->inputs().begin(),
|
|
||||||
ins->inputs().end(),
|
|
||||||
std::back_inserter(inputs),
|
|
||||||
[&](auto input) { return param_map[input]; });
|
|
||||||
auto r = pm->add_instruction(ins->get_operator(), inputs);
|
|
||||||
pm->add_return({r});
|
|
||||||
|
|
||||||
mpm.get_module().replace_instruction(ins, make_op("pointwise"), pointwise_inputs, {pm});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static module::with_inputs append_pointwise_module(instruction_ref ins, instruction_ref output)
|
|
||||||
{
|
|
||||||
assert(contains(output->inputs(), ins));
|
|
||||||
module pm = *ins->module_inputs().at(0);
|
|
||||||
module_ref xm = output->module_inputs().at(0);
|
|
||||||
|
|
||||||
auto last = std::prev(pm.end());
|
|
||||||
assert(last->name() == "@return");
|
|
||||||
assert(last->inputs().size() == 1);
|
|
||||||
|
|
||||||
assert(pm.get_parameter_names().size() == ins->inputs().size());
|
|
||||||
assert(xm->get_parameter_names().size() == output->inputs().size());
|
|
||||||
|
|
||||||
std::vector<instruction_ref> inputs = ins->inputs();
|
|
||||||
std::unordered_map<instruction_ref, instruction_ref> map_ins;
|
|
||||||
std::unordered_map<instruction_ref, instruction_ref> input_map;
|
|
||||||
// Copy inputs to input_map
|
|
||||||
for(auto i : range(inputs.size()))
|
|
||||||
{
|
|
||||||
auto input = inputs[i];
|
|
||||||
auto param = pm.get_parameter(param_name(i));
|
|
||||||
assert(param != pm.end());
|
|
||||||
input_map[input] = param;
|
|
||||||
}
|
|
||||||
// Add the new parameter and additional inputs
|
|
||||||
for(auto i : range(output->inputs().size()))
|
|
||||||
{
|
|
||||||
auto input = output->inputs()[i];
|
|
||||||
auto param = xm->get_parameter(param_name(i));
|
|
||||||
assert(param != xm->end());
|
|
||||||
if(input == ins)
|
|
||||||
{
|
|
||||||
map_ins[param] = last->inputs().front();
|
|
||||||
input_map[input] = map_ins[param];
|
|
||||||
}
|
|
||||||
// Avoid duplicate paramter inputs
|
|
||||||
else if(contains(input_map, input))
|
|
||||||
{
|
|
||||||
map_ins[param] = input_map[input];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
map_ins[param] =
|
|
||||||
pm.add_parameter(param_name(inputs.size()), {input->get_shape().type()});
|
|
||||||
inputs.push_back(input);
|
|
||||||
input_map[input] = map_ins[param];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pm.replace_return(pm.insert_instructions(last, xm, &map_ins));
|
|
||||||
return {std::move(pm), inputs};
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool find_pointwise_modules(module_pass_manager& mpm)
|
|
||||||
{
|
|
||||||
bool changed = false;
|
|
||||||
auto last = std::prev(mpm.get_module().end());
|
|
||||||
for(auto ins : iterator_for(mpm.get_module()))
|
|
||||||
{
|
|
||||||
if(ins->name() != "pointwise")
|
|
||||||
continue;
|
|
||||||
if(ins->outputs().empty() and ins != last)
|
|
||||||
continue;
|
|
||||||
auto it = std::find_if(ins->inputs().begin(), ins->inputs().end(), [&](auto i) {
|
|
||||||
return i->name() == "pointwise" and i->outputs().size() == 1;
|
|
||||||
});
|
|
||||||
if(it == ins->inputs().end())
|
|
||||||
continue;
|
|
||||||
auto input = *it;
|
|
||||||
|
|
||||||
auto fused = append_pointwise_module(input, ins);
|
|
||||||
auto name = fused.mod.name();
|
|
||||||
mpm.rename_module(name, name + ":" + ins->module_inputs().front()->name() + "-deleted");
|
|
||||||
auto* new_pm = mpm.create_module(name, std::move(fused.mod));
|
|
||||||
mpm.get_module().replace_instruction(ins, input->get_operator(), fused.inputs, {new_pm});
|
|
||||||
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
return changed;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
struct pointwise_reshape : rewrite_reshapes_base
|
|
||||||
{
|
|
||||||
static std::string name() { return "pointwise"; }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct pointwise_broadcast_pointwise
|
|
||||||
{
|
|
||||||
auto matcher() const
|
|
||||||
{
|
|
||||||
auto broadcast_pointwise =
|
|
||||||
match::name("multibroadcast")(
|
|
||||||
match::used_once(),
|
|
||||||
match::args(match::name("pointwise")(match::used_once()).bind("x")))
|
|
||||||
.bind("broadcast");
|
|
||||||
return match::name("pointwise")(match::any_of[match::inputs()](broadcast_pointwise));
|
|
||||||
}
|
|
||||||
|
|
||||||
void apply(module& m, const match::matcher_result& r) const
|
|
||||||
{
|
|
||||||
auto broadcast_ins = r.instructions["broadcast"];
|
|
||||||
auto x_ins = r.instructions["x"];
|
|
||||||
|
|
||||||
auto broadcast = broadcast_ins->get_operator();
|
|
||||||
|
|
||||||
auto x_inputs = x_ins->inputs();
|
|
||||||
std::transform(x_inputs.begin(), x_inputs.end(), x_inputs.begin(), [&](auto input) {
|
|
||||||
return m.insert_instruction(broadcast_ins, broadcast, input);
|
|
||||||
});
|
|
||||||
|
|
||||||
m.replace_instruction(
|
|
||||||
broadcast_ins, x_ins->get_operator(), x_inputs, x_ins->module_inputs());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
static void rewrite_broadcasts(module_pass_manager& mpm)
|
|
||||||
{
|
|
||||||
match::find_matches(mpm.get_module(), pointwise_broadcast_pointwise{});
|
|
||||||
mpm.run_pass(dead_code_elimination{});
|
|
||||||
}
|
|
||||||
|
|
||||||
void fuse_pointwise::apply(module_pass_manager& mpm) const
|
|
||||||
{
|
|
||||||
mpm.run_pass(eliminate_identity{});
|
|
||||||
create_pointwise_modules(mpm);
|
|
||||||
mpm.run_pass(dead_code_elimination{});
|
|
||||||
if(enabled(MIGRAPHX_DISABLE_POINTWISE_FUSION{}))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for(int i = 0; i < 8; i++)
|
|
||||||
{
|
|
||||||
if(enable_rewrite_reshapes)
|
|
||||||
mpm.run_pass(rewrite_reshapes<pointwise_reshape>{});
|
|
||||||
if(enable_rewrite_broadcasts)
|
|
||||||
rewrite_broadcasts(mpm);
|
|
||||||
if(not find_pointwise_modules(mpm))
|
|
||||||
break;
|
|
||||||
mpm.run_pass(dead_code_elimination{});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,55 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#include <migraphx/fuse_pointwise_reduce.hpp>
|
|
||||||
#include <migraphx/pass_manager.hpp>
|
|
||||||
#include <migraphx/fuse_pointwise.hpp>
|
|
||||||
#include <migraphx/fuse_reduce.hpp>
|
|
||||||
#include <migraphx/split_reduce.hpp>
|
|
||||||
#include <migraphx/env.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
MIGRAPHX_DECLARE_ENV_VAR(MIGRAPHX_SPLIT_REDUCE_SIZE);
|
|
||||||
|
|
||||||
static std::size_t get_split_size(std::size_t default_split)
|
|
||||||
{
|
|
||||||
std::string value = string_value_of(MIGRAPHX_SPLIT_REDUCE_SIZE{});
|
|
||||||
if(value.empty())
|
|
||||||
return default_split;
|
|
||||||
return std::stoul(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void fuse_pointwise_reduce::apply(module_pass_manager& mpm) const
|
|
||||||
{
|
|
||||||
mpm.run_pass(fuse_pointwise{.enable_rewrite_reshapes = false});
|
|
||||||
mpm.run_pass(fuse_reduce{.enable_rewrite_reshapes = false});
|
|
||||||
mpm.run_pass(fuse_pointwise{.enable_rewrite_reshapes = true});
|
|
||||||
mpm.run_pass(fuse_reduce{.enable_rewrite_reshapes = true});
|
|
||||||
mpm.run_pass(split_reduce{.split_size = get_split_size(split_size)});
|
|
||||||
mpm.run_pass(fuse_pointwise{.enable_rewrite_broadcasts = true});
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,440 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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.
|
|
||||||
*/
|
|
||||||
#include <migraphx/fuse_reduce.hpp>
|
|
||||||
#include <migraphx/check_shapes.hpp>
|
|
||||||
#include <migraphx/dead_code_elimination.hpp>
|
|
||||||
#include <migraphx/eliminate_common_subexpression.hpp>
|
|
||||||
#include <migraphx/instruction.hpp>
|
|
||||||
#include <migraphx/iterator_for.hpp>
|
|
||||||
#include <migraphx/make_op.hpp>
|
|
||||||
#include <migraphx/matcher.hpp>
|
|
||||||
#include <migraphx/pass_manager.hpp>
|
|
||||||
#include <migraphx/program.hpp>
|
|
||||||
#include <migraphx/ranges.hpp>
|
|
||||||
#include <migraphx/register_op.hpp>
|
|
||||||
#include <migraphx/rewrite_reshapes.hpp>
|
|
||||||
#include <migraphx/param_utils.hpp>
|
|
||||||
#include <iterator>
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
MIGRAPHX_DECLARE_ENV_VAR(MIGRAPHX_DISABLE_REDUCE_FUSION)
|
|
||||||
|
|
||||||
struct fused_reduce
|
|
||||||
{
|
|
||||||
std::vector<std::int64_t> axes{};
|
|
||||||
|
|
||||||
template <class Self, class F>
|
|
||||||
static auto reflect(Self& self, F f)
|
|
||||||
{
|
|
||||||
return pack(f(self.axes, "axes"));
|
|
||||||
}
|
|
||||||
|
|
||||||
shape compute_shape(const std::vector<shape>& inputs, std::vector<module_ref> mods) const
|
|
||||||
{
|
|
||||||
if(mods.size() != 1)
|
|
||||||
MIGRAPHX_THROW("should have one submodule.");
|
|
||||||
const auto* sm = mods.front();
|
|
||||||
if(sm->get_output_shapes().size() != 1)
|
|
||||||
MIGRAPHX_THROW("Only one output supported");
|
|
||||||
if(not sm->bypass())
|
|
||||||
MIGRAPHX_THROW("fused_reduce: bypass flag is not set");
|
|
||||||
auto names = sm->get_parameter_names();
|
|
||||||
check_shapes{inputs, *this}.has(names.size()).same_ndims();
|
|
||||||
std::sort(names.begin(), names.end());
|
|
||||||
auto shapes = sm->get_parameter_shapes();
|
|
||||||
// Check dimension matches for each input
|
|
||||||
if(not equal(names, inputs, [&](const auto& name, const auto& input) {
|
|
||||||
return shapes.at(name).lens() == input.lens();
|
|
||||||
}))
|
|
||||||
MIGRAPHX_THROW("Input dimension does not match the submodule.");
|
|
||||||
|
|
||||||
return shape::from_permutation(sm->get_output_shapes().front().type(),
|
|
||||||
sm->get_output_shapes().front().lens(),
|
|
||||||
find_permutation(inputs));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string name() const { return "fused_reduce"; }
|
|
||||||
};
|
|
||||||
MIGRAPHX_REGISTER_OP(fused_reduce);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Predicate matcher checks that input and output shapes have the same rank. This is assumed
|
|
||||||
* for broadcast instructions for these fusions.
|
|
||||||
*/
|
|
||||||
MIGRAPHX_PRED_MATCHER(input_output_ndim_match, instruction_ref ins)
|
|
||||||
{
|
|
||||||
auto input_shape = ins->inputs().front()->get_shape();
|
|
||||||
auto output_shape = ins->get_shape();
|
|
||||||
return input_shape.ndim() == output_shape.ndim();
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto
|
|
||||||
insert_module_in_submodule(module_ref sm,
|
|
||||||
instruction_ref ins,
|
|
||||||
std::unordered_map<instruction_ref, instruction_ref>* map_ins = nullptr,
|
|
||||||
module::inserter insert = nullptr)
|
|
||||||
{
|
|
||||||
assert(ins->module_inputs().size() == 1);
|
|
||||||
return sm->fuse(*ins->module_inputs().front(), ins->inputs(), map_ins, std::move(insert));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void create_reduce_modules(module_pass_manager& mpm)
|
|
||||||
{
|
|
||||||
std::size_t n = 0;
|
|
||||||
for(auto ins : iterator_for(mpm.get_module()))
|
|
||||||
{
|
|
||||||
if(not ins->get_operator().attributes().get("reduce", false))
|
|
||||||
continue;
|
|
||||||
if(ins->inputs().size() != 1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
auto* rm =
|
|
||||||
mpm.create_module(mpm.get_module().name() + ":" + ins->name() + std::to_string(n++));
|
|
||||||
rm->set_bypass();
|
|
||||||
|
|
||||||
rm->add_return(rm->fuse({ins}));
|
|
||||||
auto v = ins->get_operator().to_value();
|
|
||||||
mpm.get_module().replace_instruction(
|
|
||||||
ins, make_op("fused_reduce", {{"axes", v["axes"]}}), ins->inputs(), {rm});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
instruction_ref get_broadcast_output(instruction_ref broadcast)
|
|
||||||
{
|
|
||||||
if(broadcast->outputs().size() != 1)
|
|
||||||
return broadcast;
|
|
||||||
auto output = broadcast->outputs().front();
|
|
||||||
if(output->name() == "contiguous")
|
|
||||||
return get_broadcast_output(output);
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
MIGRAPHX_PRED_MATCHER(used_once_except_broadcast, instruction_ref ins)
|
|
||||||
{
|
|
||||||
if(ins->outputs().size() == 1)
|
|
||||||
return true;
|
|
||||||
if(ins->outputs().size() == 2)
|
|
||||||
{
|
|
||||||
auto is_broadcast = [](instruction_ref output) {
|
|
||||||
return contains(output->name(), "broadcast");
|
|
||||||
};
|
|
||||||
auto broadcast = std::find_if(ins->outputs().begin(), ins->outputs().end(), is_broadcast);
|
|
||||||
if(broadcast == ins->outputs().end())
|
|
||||||
return false;
|
|
||||||
auto non_broadcast =
|
|
||||||
std::find_if_not(ins->outputs().begin(), ins->outputs().end(), is_broadcast);
|
|
||||||
if(non_broadcast == ins->outputs().end())
|
|
||||||
return false;
|
|
||||||
auto output = get_broadcast_output(*broadcast);
|
|
||||||
return output == *non_broadcast;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
template <class... Ms>
|
|
||||||
static auto match_broadcast(Ms... ms)
|
|
||||||
{
|
|
||||||
return match::skip(match::name("contiguous"))(
|
|
||||||
match::name("multibroadcast")(
|
|
||||||
match::arg(0)(ms...), match::used_once(), input_output_ndim_match())
|
|
||||||
.bind("broadcast"))
|
|
||||||
.bind("final_broadcast");
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... Ms>
|
|
||||||
static auto any_input(Ms... ms)
|
|
||||||
{
|
|
||||||
return match::any_of[match::inputs()](match::any(ms...).bind("input"));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_valid_broadcast(const instruction_ref b, const std::vector<size_t>& reduce_axes)
|
|
||||||
{
|
|
||||||
std::vector<size_t> broadcast_axes;
|
|
||||||
auto bstrides = b->get_shape().strides();
|
|
||||||
|
|
||||||
for(size_t i = 0; i < bstrides.size(); ++i)
|
|
||||||
{
|
|
||||||
if(bstrides.at(i) == 0)
|
|
||||||
broadcast_axes.push_back(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
return broadcast_axes == reduce_axes;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class M>
|
|
||||||
static auto match_broadcast_axes(M m)
|
|
||||||
{
|
|
||||||
return match::make_basic_fun_matcher(
|
|
||||||
[=](match::matcher_context& ctx, instruction_ref ins) -> optional<instruction_ref> {
|
|
||||||
optional<instruction_ref> result = m.match(ctx, ins);
|
|
||||||
if(contains(ctx.instructions, "broadcast"))
|
|
||||||
{
|
|
||||||
instruction_ref reduce;
|
|
||||||
if(ins->get_operator().name() == "fused_reduce")
|
|
||||||
{
|
|
||||||
reduce = ins;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
assert(contains(ctx.instructions, "reduce"));
|
|
||||||
reduce = ctx.instructions["reduce"];
|
|
||||||
}
|
|
||||||
auto axes = reduce->get_operator().to_value().at("axes").to_vector<size_t>();
|
|
||||||
auto broadcast = ctx.instructions["broadcast"];
|
|
||||||
if(not is_valid_broadcast(broadcast, axes))
|
|
||||||
return nullopt;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto match_broadcastable_input(const std::string& op, const std::string& name)
|
|
||||||
{
|
|
||||||
auto match_op = match::name(op)(used_once_except_broadcast()).bind(name);
|
|
||||||
auto match_op_input = any_input(match_op, match::used_once());
|
|
||||||
auto broadcast_match_op_input = any_input(match_broadcast(match_op), match::used_once());
|
|
||||||
return match::any_of(match_op_input, match_broadcast_axes(broadcast_match_op_input));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void finalize_reduce_module(module_ref m)
|
|
||||||
{
|
|
||||||
eliminate_common_subexpression{}.apply(*m);
|
|
||||||
dead_code_elimination{}.apply(*m);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
struct find_pointwise_reduce
|
|
||||||
{
|
|
||||||
auto matcher() const
|
|
||||||
{
|
|
||||||
// fused_reduce instruction with pointwise inputs.
|
|
||||||
return match::name("fused_reduce")(match_broadcastable_input("pointwise", "pointwise"));
|
|
||||||
}
|
|
||||||
|
|
||||||
void apply(module_pass_manager& mpm, const match::matcher_result& r) const
|
|
||||||
{
|
|
||||||
auto reduce = r.result;
|
|
||||||
auto input = r.instructions["pointwise"];
|
|
||||||
const auto* pm = input->module_inputs().front();
|
|
||||||
const auto* old_rm = reduce->module_inputs().front();
|
|
||||||
|
|
||||||
auto* rm = mpm.create_module(pm->name() + ":" + old_rm->name());
|
|
||||||
rm->set_bypass();
|
|
||||||
std::unordered_map<instruction_ref, instruction_ref> map_ins;
|
|
||||||
// Insert pointwise
|
|
||||||
auto rins = rm->fuse({input}, &map_ins).front();
|
|
||||||
map_ins[input] = rins;
|
|
||||||
|
|
||||||
if(contains(r.instructions, "broadcast"))
|
|
||||||
{
|
|
||||||
auto broadcast = r.instructions["broadcast"];
|
|
||||||
auto fbroadcast = r.instructions["final_broadcast"];
|
|
||||||
map_ins[broadcast] = rm->fuse({broadcast}, &map_ins).front();
|
|
||||||
if(fbroadcast != broadcast)
|
|
||||||
map_ins[fbroadcast] = map_ins[broadcast];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert fused_reduce
|
|
||||||
rm->add_return(insert_module_in_submodule(rm, reduce, &map_ins));
|
|
||||||
finalize_reduce_module(rm);
|
|
||||||
|
|
||||||
auto new_inputs = find_inputs(map_ins, &mpm.get_module(), rm);
|
|
||||||
mpm.get_module().replace_instruction(reduce, reduce->get_operator(), new_inputs, {rm});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct find_reduce_pointwise
|
|
||||||
{
|
|
||||||
|
|
||||||
auto matcher() const
|
|
||||||
{
|
|
||||||
return match::name("pointwise")(match_broadcastable_input("fused_reduce", "reduce"));
|
|
||||||
}
|
|
||||||
|
|
||||||
void apply(module_pass_manager& mpm, const match::matcher_result& r) const
|
|
||||||
{
|
|
||||||
auto pw = r.result;
|
|
||||||
auto reduce = r.instructions["reduce"];
|
|
||||||
auto input = r.instructions["input"];
|
|
||||||
|
|
||||||
const auto* pm = pw->module_inputs().front();
|
|
||||||
const auto* old_rm = reduce->module_inputs().front();
|
|
||||||
auto* rm = mpm.create_module(old_rm->name() + ":" + pm->name());
|
|
||||||
rm->set_bypass();
|
|
||||||
std::unordered_map<instruction_ref, instruction_ref> map_ins;
|
|
||||||
// Copy module instructions
|
|
||||||
insert_module_in_submodule(rm, reduce, &map_ins);
|
|
||||||
if(contains(r.instructions, "broadcast"))
|
|
||||||
{
|
|
||||||
auto broadcast = r.instructions["broadcast"];
|
|
||||||
map_ins[broadcast->inputs().front()] = rm->get_returns().front();
|
|
||||||
auto bout = rm->fuse({broadcast}, &map_ins);
|
|
||||||
map_ins[input] = bout.front();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
map_ins[input] = rm->get_returns().front();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto out = rm->fuse({pw}, &map_ins);
|
|
||||||
rm->replace_return(out);
|
|
||||||
finalize_reduce_module(rm);
|
|
||||||
|
|
||||||
auto new_inputs = find_inputs(map_ins, &mpm.get_module(), rm);
|
|
||||||
mpm.get_module().replace_instruction(pw, reduce->get_operator(), new_inputs, {rm});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct find_reduce_reduce
|
|
||||||
{
|
|
||||||
auto matcher() const
|
|
||||||
{
|
|
||||||
return match::name("fused_reduce")(match_broadcastable_input("fused_reduce", "reduce"));
|
|
||||||
}
|
|
||||||
|
|
||||||
void apply(module_pass_manager& mpm, const match::matcher_result& r) const
|
|
||||||
{
|
|
||||||
auto reduce1 = r.result;
|
|
||||||
auto reduce2 = r.instructions["reduce"];
|
|
||||||
auto input = r.instructions["input"];
|
|
||||||
|
|
||||||
if(reduce1->get_operator() != reduce2->get_operator())
|
|
||||||
return;
|
|
||||||
|
|
||||||
const auto* rm1 = reduce1->module_inputs().front();
|
|
||||||
const auto* rm2 = reduce2->module_inputs().front();
|
|
||||||
auto* rm = mpm.create_module(rm1->name() + ":" + rm2->name());
|
|
||||||
rm->set_bypass();
|
|
||||||
|
|
||||||
std::unordered_map<instruction_ref, instruction_ref> map_ins;
|
|
||||||
// Copy reduce1 instructions
|
|
||||||
insert_module_in_submodule(rm, reduce2, &map_ins);
|
|
||||||
if(contains(r.instructions, "broadcast"))
|
|
||||||
{
|
|
||||||
auto broadcast = r.instructions["broadcast"];
|
|
||||||
map_ins[broadcast->inputs().front()] = rm->get_returns().front();
|
|
||||||
auto bout = rm->fuse({broadcast}, &map_ins);
|
|
||||||
map_ins[input] = bout.front();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
map_ins[input] = rm->get_returns().front();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto out = insert_module_in_submodule(rm, reduce1, &map_ins);
|
|
||||||
rm->replace_return(out);
|
|
||||||
finalize_reduce_module(rm);
|
|
||||||
|
|
||||||
auto new_inputs = find_inputs(map_ins, &mpm.get_module(), rm);
|
|
||||||
mpm.get_module().replace_instruction(reduce1, reduce1->get_operator(), new_inputs, {rm});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct reduce_reshape : rewrite_reshapes_base
|
|
||||||
{
|
|
||||||
static std::string name() { return "fused_reduce"; }
|
|
||||||
|
|
||||||
template <class Transform>
|
|
||||||
static auto transform_op(Transform t)
|
|
||||||
{
|
|
||||||
return [=](module& m,
|
|
||||||
instruction_ref ins,
|
|
||||||
const operation& op,
|
|
||||||
const std::vector<instruction_ref>& inputs,
|
|
||||||
const std::vector<module_ref>& mod_args) {
|
|
||||||
auto new_op = t(op);
|
|
||||||
return m.insert_instruction(ins, new_op, inputs, mod_args);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class AxesMap>
|
|
||||||
static instruction_ref insert(module_pass_manager& mpm,
|
|
||||||
instruction_ref ins,
|
|
||||||
const std::vector<instruction_ref>& inputs,
|
|
||||||
const AxesMap& am)
|
|
||||||
{
|
|
||||||
auto op = any_cast<fused_reduce>(ins->get_operator());
|
|
||||||
std::vector<int64_t> axes;
|
|
||||||
for(auto axis : op.axes)
|
|
||||||
{
|
|
||||||
auto new_axes = am.at(axis);
|
|
||||||
axes.insert(axes.end(), new_axes.begin(), new_axes.end());
|
|
||||||
}
|
|
||||||
std::sort(axes.begin(), axes.end());
|
|
||||||
auto dims = base_dims(inputs);
|
|
||||||
auto* oldm = ins->module_inputs().front();
|
|
||||||
auto* sm = mpm.create_module(oldm->name() + "_reshape");
|
|
||||||
sm->set_bypass();
|
|
||||||
auto outs = sm->fuse(*oldm, inputs, nullptr, transform_op([&](const operation& sop) {
|
|
||||||
if(contains(sop.name(), "reduce"))
|
|
||||||
return make_op(sop.name(), {{"axes", axes}});
|
|
||||||
if(sop.name() == "multibroadcast")
|
|
||||||
return make_op("multibroadcast", {{"out_lens", dims}});
|
|
||||||
assert(sop.name() == "pointwise");
|
|
||||||
return sop;
|
|
||||||
}));
|
|
||||||
sm->add_return(outs);
|
|
||||||
return mpm.get_module().insert_instruction(ins, fused_reduce{axes}, inputs, {sm});
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::vector<std::size_t> base_dims(const std::vector<instruction_ref>& inputs)
|
|
||||||
{
|
|
||||||
auto input = std::max_element(inputs.begin(), inputs.end(), by(std::less<>{}, [](auto i) {
|
|
||||||
return i->get_shape().elements();
|
|
||||||
}));
|
|
||||||
return (*input)->get_shape().lens();
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::vector<std::size_t> base_dims(instruction_ref ins)
|
|
||||||
{
|
|
||||||
return base_dims(ins->inputs());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
void fuse_reduce::apply(module_pass_manager& mpm) const
|
|
||||||
{
|
|
||||||
if(enabled(MIGRAPHX_DISABLE_REDUCE_FUSION{}))
|
|
||||||
return;
|
|
||||||
create_reduce_modules(mpm);
|
|
||||||
mpm.run_pass(dead_code_elimination{});
|
|
||||||
for(int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
if(enable_rewrite_reshapes)
|
|
||||||
mpm.run_pass(rewrite_reshapes<reduce_reshape>{});
|
|
||||||
match::find_matches(
|
|
||||||
mpm, find_reduce_pointwise{}, find_pointwise_reduce{}, find_reduce_reduce{});
|
|
||||||
mpm.run_pass(dead_code_elimination{});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,106 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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.
|
|
||||||
*/
|
|
||||||
#include <migraphx/generate.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
argument fill_argument(shape s, double value)
|
|
||||||
{
|
|
||||||
argument result;
|
|
||||||
if(s.type() == shape::tuple_type)
|
|
||||||
{
|
|
||||||
std::vector<argument> sub_args;
|
|
||||||
const auto& sub_ss = s.sub_shapes();
|
|
||||||
std::transform(sub_ss.begin(), sub_ss.end(), std::back_inserter(sub_args), [&](auto ss) {
|
|
||||||
return fill_argument(ss, value);
|
|
||||||
});
|
|
||||||
|
|
||||||
result = argument(sub_args);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
s.visit_type([&](auto as) {
|
|
||||||
using type = typename decltype(as)::type;
|
|
||||||
auto v = fill_tensor_data<type>(s, value);
|
|
||||||
result = {s, v};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
argument generate_argument(shape s, unsigned long seed, random_mode m)
|
|
||||||
{
|
|
||||||
argument result;
|
|
||||||
if(s.type() == shape::tuple_type)
|
|
||||||
{
|
|
||||||
const auto& sub_ss = s.sub_shapes();
|
|
||||||
std::vector<argument> sub_args;
|
|
||||||
std::transform(sub_ss.begin(), sub_ss.end(), std::back_inserter(sub_args), [&](auto ss) {
|
|
||||||
return generate_argument(ss, seed, m);
|
|
||||||
});
|
|
||||||
|
|
||||||
result = argument(sub_args);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
s.visit_type([&](auto as) {
|
|
||||||
// we use char type to store bool type internally, so bool_type
|
|
||||||
// needs special processing to generate data
|
|
||||||
if(s.type() == shape::bool_type)
|
|
||||||
{
|
|
||||||
auto v = generate_tensor_data<bool>(s, seed, m);
|
|
||||||
result = {s, v};
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
using type = typename decltype(as)::type;
|
|
||||||
auto v = generate_tensor_data<type>(s, seed, m);
|
|
||||||
result = {s, v};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
literal generate_literal(shape s, unsigned long seed)
|
|
||||||
{
|
|
||||||
literal result;
|
|
||||||
s.visit_type([&](auto as) {
|
|
||||||
using type = typename decltype(as)::type;
|
|
||||||
auto v = generate_tensor_data<type>(s, seed);
|
|
||||||
result = {s, reinterpret_cast<char*>(v.get())};
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Move to literal.cpp
|
|
||||||
literal abs(literal l)
|
|
||||||
{
|
|
||||||
return transform(std::move(l), [](auto x) { return std::fabs(x); });
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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_RTGLIB_ADJUST_ALLOCATION_HPP
|
|
||||||
#define MIGRAPHX_GUARD_RTGLIB_ADJUST_ALLOCATION_HPP
|
|
||||||
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
#include <migraphx/allocation_model.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
struct module;
|
|
||||||
|
|
||||||
struct MIGRAPHX_EXPORT adjust_allocation
|
|
||||||
{
|
|
||||||
allocation_model model;
|
|
||||||
std::string name() const { return "adjust_allocation"; }
|
|
||||||
void apply(module& m) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,205 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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_RTGLIB_ALGORITHM_HPP
|
|
||||||
#define MIGRAPHX_GUARD_RTGLIB_ALGORITHM_HPP
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cassert>
|
|
||||||
#include <numeric>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
template <class Iterator, class Output, class Predicate, class F>
|
|
||||||
void transform_if(Iterator start, Iterator last, Output out, Predicate pred, F f)
|
|
||||||
{
|
|
||||||
while(start != last)
|
|
||||||
{
|
|
||||||
if(pred(*start))
|
|
||||||
{
|
|
||||||
*out = f(*start);
|
|
||||||
++out;
|
|
||||||
}
|
|
||||||
++start;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Similiar to std::accumulate but a projection can be applied to the elements first
|
|
||||||
template <class Iterator, class T, class BinaryOp, class UnaryOp>
|
|
||||||
T transform_accumulate(Iterator first, Iterator last, T init, BinaryOp binop, UnaryOp unaryop)
|
|
||||||
{
|
|
||||||
return std::inner_product(
|
|
||||||
first, last, first, init, binop, [&](auto&& x, auto&&) { return unaryop(x); });
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Similiar to std::partial_sum but a projection can be applied to the elements first
|
|
||||||
template <class Iterator, class OutputIterator, class BinaryOperation, class UnaryOp>
|
|
||||||
OutputIterator transform_partial_sum(
|
|
||||||
Iterator first, Iterator last, OutputIterator d_first, BinaryOperation binop, UnaryOp unaryop)
|
|
||||||
{
|
|
||||||
if(first == last)
|
|
||||||
return d_first;
|
|
||||||
|
|
||||||
auto acc = unaryop(*first);
|
|
||||||
*d_first = acc;
|
|
||||||
|
|
||||||
while(++first != last)
|
|
||||||
{
|
|
||||||
acc = binop(std::move(acc), unaryop(*first));
|
|
||||||
*++d_first = acc;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ++d_first;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Iterator, class Output, class Predicate>
|
|
||||||
void group_by(Iterator start, Iterator last, Output out, Predicate pred)
|
|
||||||
{
|
|
||||||
while(start != last)
|
|
||||||
{
|
|
||||||
auto it = std::partition(start, last, [&](auto&& x) { return pred(x, *start); });
|
|
||||||
out(start, it);
|
|
||||||
start = it;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Iterator, class Output, class Predicate>
|
|
||||||
void group_unique(Iterator start, Iterator last, Output out, Predicate pred)
|
|
||||||
{
|
|
||||||
while(start != last)
|
|
||||||
{
|
|
||||||
auto it = std::find_if(start, last, [&](auto&& x) { return not pred(*start, x); });
|
|
||||||
out(start, it);
|
|
||||||
start = it;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Iterator, class Predicate, class Output>
|
|
||||||
void group_find(Iterator start, Iterator last, Predicate pred, Output out)
|
|
||||||
{
|
|
||||||
start = std::find_if(start, last, pred);
|
|
||||||
while(start != last)
|
|
||||||
{
|
|
||||||
auto it = std::find_if_not(start, last, pred);
|
|
||||||
out(start, it);
|
|
||||||
start = std::find_if(it, last, pred);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Similiar to std::remove_if but instead pass adjacent pairs to the predicate
|
|
||||||
template <class Iterator, class Predicate>
|
|
||||||
Iterator adjacent_remove_if(Iterator first, Iterator last, Predicate p)
|
|
||||||
{
|
|
||||||
first = std::adjacent_find(first, last, p);
|
|
||||||
if(first == last)
|
|
||||||
return first;
|
|
||||||
auto i = first;
|
|
||||||
while(std::next(++i) != last)
|
|
||||||
{
|
|
||||||
if(not p(*i, *std::next(i)))
|
|
||||||
{
|
|
||||||
*first = std::move(*i);
|
|
||||||
++first;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*first = std::move(*i);
|
|
||||||
++first;
|
|
||||||
return first;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Similiar to std::for_each but instead pass adjacent pairs to the function
|
|
||||||
template <class Iterator, class F>
|
|
||||||
Iterator adjacent_for_each(Iterator first, Iterator last, F f)
|
|
||||||
{
|
|
||||||
if(first == last)
|
|
||||||
return last;
|
|
||||||
|
|
||||||
Iterator next = first;
|
|
||||||
++next;
|
|
||||||
|
|
||||||
for(; next != last; ++next, ++first)
|
|
||||||
f(*first, *next);
|
|
||||||
|
|
||||||
return last;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Iterator1, class Iterator2>
|
|
||||||
std::ptrdiff_t
|
|
||||||
levenshtein_distance(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2)
|
|
||||||
{
|
|
||||||
if(first1 == last1)
|
|
||||||
return std::distance(first2, last2);
|
|
||||||
if(first2 == last2)
|
|
||||||
return std::distance(first1, last1);
|
|
||||||
if(*first1 == *first2)
|
|
||||||
return levenshtein_distance(std::next(first1), last1, std::next(first2), last2);
|
|
||||||
auto x1 = levenshtein_distance(std::next(first1), last1, std::next(first2), last2);
|
|
||||||
auto x2 = levenshtein_distance(first1, last1, std::next(first2), last2);
|
|
||||||
auto x3 = levenshtein_distance(std::next(first1), last1, first2, last2);
|
|
||||||
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);
|
|
||||||
|
|
||||||
std::iota(d.begin(), d.end(), 0);
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,352 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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_ALLOCATION_MODEL_HPP
|
|
||||||
#define MIGRAPHX_GUARD_ALLOCATION_MODEL_HPP
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <string>
|
|
||||||
#include <functional>
|
|
||||||
#include <memory>
|
|
||||||
#include <type_traits>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
#include <migraphx/operation.hpp>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
#ifdef DOXYGEN
|
|
||||||
|
|
||||||
/// An interface for target-dependent allocation
|
|
||||||
struct allocation_model
|
|
||||||
{
|
|
||||||
/// A name of the target-dependent allocate operator
|
|
||||||
std::string name() const;
|
|
||||||
/// A name of the target-dependent copy operator
|
|
||||||
std::string copy() const;
|
|
||||||
/// Create an allocation operator for the given shape
|
|
||||||
operation allocate(const shape& s) const;
|
|
||||||
/// Create a preallocated operator for the given shape
|
|
||||||
operation preallocate(const shape& s, const std::string& id) const;
|
|
||||||
/// Check if outputs are to be inserted
|
|
||||||
bool needs_out_params() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#ifdef TYPE_ERASED_DECLARATION
|
|
||||||
|
|
||||||
// Type-erased interface for:
|
|
||||||
struct MIGRAPHX_EXPORT allocation_model
|
|
||||||
{
|
|
||||||
//
|
|
||||||
std::string name() const;
|
|
||||||
//
|
|
||||||
std::string copy() const;
|
|
||||||
//
|
|
||||||
operation allocate(const shape& s) const;
|
|
||||||
//
|
|
||||||
operation preallocate(const shape& s, std::string id) const;
|
|
||||||
//
|
|
||||||
bool needs_out_params() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
struct allocation_model
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
template <class PrivateDetailTypeErasedT>
|
|
||||||
struct private_te_unwrap_reference
|
|
||||||
{
|
|
||||||
using type = PrivateDetailTypeErasedT;
|
|
||||||
};
|
|
||||||
template <class PrivateDetailTypeErasedT>
|
|
||||||
struct private_te_unwrap_reference<std::reference_wrapper<PrivateDetailTypeErasedT>>
|
|
||||||
{
|
|
||||||
using type = PrivateDetailTypeErasedT;
|
|
||||||
};
|
|
||||||
template <class PrivateDetailTypeErasedT>
|
|
||||||
using private_te_pure = typename std::remove_cv<
|
|
||||||
typename std::remove_reference<PrivateDetailTypeErasedT>::type>::type;
|
|
||||||
|
|
||||||
template <class PrivateDetailTypeErasedT>
|
|
||||||
using private_te_constraints_impl =
|
|
||||||
decltype(std::declval<PrivateDetailTypeErasedT>().name(),
|
|
||||||
std::declval<PrivateDetailTypeErasedT>().copy(),
|
|
||||||
std::declval<PrivateDetailTypeErasedT>().allocate(std::declval<const shape&>()),
|
|
||||||
std::declval<PrivateDetailTypeErasedT>().preallocate(std::declval<const shape&>(),
|
|
||||||
std::declval<std::string>()),
|
|
||||||
std::declval<PrivateDetailTypeErasedT>().needs_out_params(),
|
|
||||||
void());
|
|
||||||
|
|
||||||
template <class PrivateDetailTypeErasedT>
|
|
||||||
using private_te_constraints = private_te_constraints_impl<
|
|
||||||
typename private_te_unwrap_reference<private_te_pure<PrivateDetailTypeErasedT>>::type>;
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Constructors
|
|
||||||
allocation_model() = default;
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename PrivateDetailTypeErasedT,
|
|
||||||
typename = private_te_constraints<PrivateDetailTypeErasedT>,
|
|
||||||
typename = typename std::enable_if<
|
|
||||||
not std::is_same<private_te_pure<PrivateDetailTypeErasedT>, allocation_model>{}>::type>
|
|
||||||
allocation_model(PrivateDetailTypeErasedT&& value)
|
|
||||||
: private_detail_te_handle_mem_var(
|
|
||||||
std::make_shared<
|
|
||||||
private_detail_te_handle_type<private_te_pure<PrivateDetailTypeErasedT>>>(
|
|
||||||
std::forward<PrivateDetailTypeErasedT>(value)))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assignment
|
|
||||||
template <
|
|
||||||
typename PrivateDetailTypeErasedT,
|
|
||||||
typename = private_te_constraints<PrivateDetailTypeErasedT>,
|
|
||||||
typename = typename std::enable_if<
|
|
||||||
not std::is_same<private_te_pure<PrivateDetailTypeErasedT>, allocation_model>{}>::type>
|
|
||||||
allocation_model& operator=(PrivateDetailTypeErasedT&& value)
|
|
||||||
{
|
|
||||||
using std::swap;
|
|
||||||
auto* derived = this->any_cast<private_te_pure<PrivateDetailTypeErasedT>>();
|
|
||||||
if(derived and private_detail_te_handle_mem_var.use_count() == 1)
|
|
||||||
{
|
|
||||||
*derived = std::forward<PrivateDetailTypeErasedT>(value);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
allocation_model rhs(value);
|
|
||||||
swap(private_detail_te_handle_mem_var, rhs.private_detail_te_handle_mem_var);
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cast
|
|
||||||
template <typename PrivateDetailTypeErasedT>
|
|
||||||
PrivateDetailTypeErasedT* any_cast()
|
|
||||||
{
|
|
||||||
return this->type_id() == typeid(PrivateDetailTypeErasedT)
|
|
||||||
? std::addressof(static_cast<private_detail_te_handle_type<
|
|
||||||
typename std::remove_cv<PrivateDetailTypeErasedT>::type>&>(
|
|
||||||
private_detail_te_get_handle())
|
|
||||||
.private_detail_te_value)
|
|
||||||
: nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename PrivateDetailTypeErasedT>
|
|
||||||
const typename std::remove_cv<PrivateDetailTypeErasedT>::type* any_cast() const
|
|
||||||
{
|
|
||||||
return this->type_id() == typeid(PrivateDetailTypeErasedT)
|
|
||||||
? std::addressof(static_cast<const private_detail_te_handle_type<
|
|
||||||
typename std::remove_cv<PrivateDetailTypeErasedT>::type>&>(
|
|
||||||
private_detail_te_get_handle())
|
|
||||||
.private_detail_te_value)
|
|
||||||
: 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string name() const
|
|
||||||
{
|
|
||||||
assert((*this).private_detail_te_handle_mem_var);
|
|
||||||
return (*this).private_detail_te_get_handle().name();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string copy() const
|
|
||||||
{
|
|
||||||
assert((*this).private_detail_te_handle_mem_var);
|
|
||||||
return (*this).private_detail_te_get_handle().copy();
|
|
||||||
}
|
|
||||||
|
|
||||||
operation allocate(const shape& s) const
|
|
||||||
{
|
|
||||||
assert((*this).private_detail_te_handle_mem_var);
|
|
||||||
return (*this).private_detail_te_get_handle().allocate(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
operation preallocate(const shape& s, std::string id) const
|
|
||||||
{
|
|
||||||
assert((*this).private_detail_te_handle_mem_var);
|
|
||||||
return (*this).private_detail_te_get_handle().preallocate(s, std::move(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool needs_out_params() const
|
|
||||||
{
|
|
||||||
assert((*this).private_detail_te_handle_mem_var);
|
|
||||||
return (*this).private_detail_te_get_handle().needs_out_params();
|
|
||||||
}
|
|
||||||
|
|
||||||
friend bool is_shared(const allocation_model& private_detail_x,
|
|
||||||
const allocation_model& private_detail_y)
|
|
||||||
{
|
|
||||||
return private_detail_x.private_detail_te_handle_mem_var ==
|
|
||||||
private_detail_y.private_detail_te_handle_mem_var;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct private_detail_te_handle_base_type
|
|
||||||
{
|
|
||||||
virtual ~private_detail_te_handle_base_type() {}
|
|
||||||
virtual std::shared_ptr<private_detail_te_handle_base_type> clone() const = 0;
|
|
||||||
virtual const std::type_info& type() const = 0;
|
|
||||||
|
|
||||||
virtual std::string name() const = 0;
|
|
||||||
virtual std::string copy() const = 0;
|
|
||||||
virtual operation allocate(const shape& s) const = 0;
|
|
||||||
virtual operation preallocate(const shape& s, std::string id) const = 0;
|
|
||||||
virtual bool needs_out_params() const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename PrivateDetailTypeErasedT>
|
|
||||||
struct private_detail_te_handle_type : private_detail_te_handle_base_type
|
|
||||||
{
|
|
||||||
template <typename PrivateDetailTypeErasedU = PrivateDetailTypeErasedT>
|
|
||||||
private_detail_te_handle_type(
|
|
||||||
PrivateDetailTypeErasedT value,
|
|
||||||
typename std::enable_if<std::is_reference<PrivateDetailTypeErasedU>::value>::type* =
|
|
||||||
nullptr)
|
|
||||||
: private_detail_te_value(value)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename PrivateDetailTypeErasedU = PrivateDetailTypeErasedT>
|
|
||||||
private_detail_te_handle_type(
|
|
||||||
PrivateDetailTypeErasedT value,
|
|
||||||
typename std::enable_if<not std::is_reference<PrivateDetailTypeErasedU>::value,
|
|
||||||
int>::type* = nullptr) noexcept
|
|
||||||
: private_detail_te_value(std::move(value))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<private_detail_te_handle_base_type> clone() const override
|
|
||||||
{
|
|
||||||
return std::make_shared<private_detail_te_handle_type>(private_detail_te_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::type_info& type() const override { return typeid(private_detail_te_value); }
|
|
||||||
|
|
||||||
std::string name() const override { return private_detail_te_value.name(); }
|
|
||||||
|
|
||||||
std::string copy() const override { return private_detail_te_value.copy(); }
|
|
||||||
|
|
||||||
operation allocate(const shape& s) const override
|
|
||||||
{
|
|
||||||
|
|
||||||
return private_detail_te_value.allocate(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
operation preallocate(const shape& s, std::string id) const override
|
|
||||||
{
|
|
||||||
|
|
||||||
return private_detail_te_value.preallocate(s, std::move(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool needs_out_params() const override
|
|
||||||
{
|
|
||||||
|
|
||||||
return private_detail_te_value.needs_out_params();
|
|
||||||
}
|
|
||||||
|
|
||||||
PrivateDetailTypeErasedT private_detail_te_value;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename PrivateDetailTypeErasedT>
|
|
||||||
struct private_detail_te_handle_type<std::reference_wrapper<PrivateDetailTypeErasedT>>
|
|
||||||
: private_detail_te_handle_type<PrivateDetailTypeErasedT&>
|
|
||||||
{
|
|
||||||
private_detail_te_handle_type(std::reference_wrapper<PrivateDetailTypeErasedT> ref)
|
|
||||||
: private_detail_te_handle_type<PrivateDetailTypeErasedT&>(ref.get())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
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
|
|
||||||
{
|
|
||||||
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()
|
|
||||||
{
|
|
||||||
assert(private_detail_te_handle_mem_var != nullptr);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<private_detail_te_handle_base_type> private_detail_te_handle_mem_var;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ValueType>
|
|
||||||
inline const ValueType* any_cast(const allocation_model* x)
|
|
||||||
{
|
|
||||||
return x->any_cast<ValueType>();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ValueType>
|
|
||||||
inline ValueType* any_cast(allocation_model* x)
|
|
||||||
{
|
|
||||||
return x->any_cast<ValueType>();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ValueType>
|
|
||||||
inline ValueType& any_cast(allocation_model& x)
|
|
||||||
{
|
|
||||||
auto* y = x.any_cast<typename std::remove_reference<ValueType>::type>();
|
|
||||||
if(y == nullptr)
|
|
||||||
throw std::bad_cast();
|
|
||||||
return *y;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ValueType>
|
|
||||||
inline const ValueType& any_cast(const allocation_model& x)
|
|
||||||
{
|
|
||||||
const auto* y = x.any_cast<typename std::remove_reference<ValueType>::type>();
|
|
||||||
if(y == nullptr)
|
|
||||||
throw std::bad_cast();
|
|
||||||
return *y;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,48 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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_RTGLIB_ANALYZE_STREAMS_HPP
|
|
||||||
#define MIGRAPHX_GUARD_RTGLIB_ANALYZE_STREAMS_HPP
|
|
||||||
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
#include <migraphx/stream_model.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
struct module;
|
|
||||||
|
|
||||||
struct stream_race
|
|
||||||
{
|
|
||||||
instruction_ref ins;
|
|
||||||
// The instruction that should before
|
|
||||||
instruction_ref before;
|
|
||||||
};
|
|
||||||
|
|
||||||
MIGRAPHX_EXPORT std::vector<stream_race> analyze_streams(const module& m,
|
|
||||||
const stream_model& strmm);
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,84 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2022 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_MIGRAPHX_ANY_PTR_HPP
|
|
||||||
#define MIGRAPHX_GUARD_MIGRAPHX_ANY_PTR_HPP
|
|
||||||
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
#include <migraphx/optional.hpp>
|
|
||||||
#include <migraphx/errors.hpp>
|
|
||||||
#include <migraphx/type_name.hpp>
|
|
||||||
#include <cassert>
|
|
||||||
#include <string_view>
|
|
||||||
#include <typeindex>
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
struct any_ptr
|
|
||||||
{
|
|
||||||
any_ptr() = default;
|
|
||||||
template <class T>
|
|
||||||
any_ptr(T* p) : ptr(p), ti(typeid(T*)), name(get_name<T*>())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
any_ptr(void* p, std::string_view pname) : ptr(p), name(pname) {}
|
|
||||||
|
|
||||||
void* get(std::string_view n) const
|
|
||||||
{
|
|
||||||
if(name != n)
|
|
||||||
MIGRAPHX_THROW("any_ptr: type mismatch: " + std::string{name} +
|
|
||||||
" != " + std::string{n});
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
T get() const
|
|
||||||
{
|
|
||||||
static_assert(std::is_pointer<T>{}, "Must be a pointer");
|
|
||||||
assert(ptr != nullptr);
|
|
||||||
if(ti and std::type_index{typeid(T)} != *ti)
|
|
||||||
MIGRAPHX_THROW("any_ptr: type mismatch: " + std::string{name} + " != " + get_name<T>());
|
|
||||||
else if(name != get_name<T>())
|
|
||||||
MIGRAPHX_THROW("any_ptr: type mismatch: " + std::string{name} + " != " + get_name<T>());
|
|
||||||
return reinterpret_cast<T>(ptr);
|
|
||||||
}
|
|
||||||
void* unsafe_get() const { return ptr; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
void* ptr = nullptr;
|
|
||||||
optional<std::type_index> ti = nullopt;
|
|
||||||
std::string_view name = "";
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
static const std::string& get_name()
|
|
||||||
{
|
|
||||||
return get_type_name<std::remove_cv_t<std::remove_pointer_t<T>>>();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
#endif // MIGRAPHX_GUARD_MIGRAPHX_ANY_PTR_HPP
|
|
||||||
@ -1,67 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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_MIGRAPHX_APPLY_ALPHA_BETA_HPP
|
|
||||||
#define MIGRAPHX_GUARD_MIGRAPHX_APPLY_ALPHA_BETA_HPP
|
|
||||||
|
|
||||||
#include "migraphx/make_op.hpp"
|
|
||||||
#include "migraphx/normalize_attributes.hpp"
|
|
||||||
#include "migraphx/operation.hpp"
|
|
||||||
#include <migraphx/instruction_ref.hpp>
|
|
||||||
#include <migraphx/module.hpp>
|
|
||||||
|
|
||||||
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,
|
|
||||||
const operation& op,
|
|
||||||
const literal& alpha,
|
|
||||||
const literal& beta);
|
|
||||||
|
|
||||||
template <typename T = float>
|
|
||||||
instruction_ref insert_apply_alpha_beta(module& m,
|
|
||||||
instruction_ref pos,
|
|
||||||
const std::vector<instruction_ref>& args,
|
|
||||||
const operation& op,
|
|
||||||
T alpha = 1,
|
|
||||||
T beta = 0)
|
|
||||||
{
|
|
||||||
return insert_apply_alpha_beta(m, pos, args, op, literal{T{alpha}}, literal{T{beta}});
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T = float>
|
|
||||||
instruction_ref add_apply_alpha_beta(module& m,
|
|
||||||
const std::vector<instruction_ref>& args,
|
|
||||||
const operation& op,
|
|
||||||
T alpha = 1,
|
|
||||||
T beta = 0)
|
|
||||||
{
|
|
||||||
return insert_apply_alpha_beta(m, m.end(), args, op, alpha, beta);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
#endif // MIGRAPHX_GUARD_APPLY_ALPHA_BETA_HPP
|
|
||||||
@ -1,130 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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_MIGRAPHLIB_ARGUMENT_HPP
|
|
||||||
#define MIGRAPHX_GUARD_MIGRAPHLIB_ARGUMENT_HPP
|
|
||||||
|
|
||||||
#include <migraphx/shape.hpp>
|
|
||||||
#include <migraphx/raw_data.hpp>
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
#include <migraphx/make_shared_array.hpp>
|
|
||||||
#include <functional>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
// clang-format off
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Arguments passed to instructions
|
|
||||||
*
|
|
||||||
* An `argument` can represent a raw buffer of data that either be referenced from another element
|
|
||||||
* or it can be owned by the argument.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
struct MIGRAPHX_EXPORT argument : raw_data<argument>
|
|
||||||
{
|
|
||||||
argument() = default;
|
|
||||||
|
|
||||||
explicit argument(const shape& s);
|
|
||||||
|
|
||||||
template <class F, MIGRAPHX_REQUIRES(std::is_pointer<decltype(std::declval<F>()())>{})>
|
|
||||||
argument(shape s, F d)
|
|
||||||
: m_shape(std::move(s))
|
|
||||||
|
|
||||||
{
|
|
||||||
assign_buffer([f = std::move(d)]() mutable { return reinterpret_cast<char*>(f()); });
|
|
||||||
}
|
|
||||||
template <class T>
|
|
||||||
argument(shape s, T* d)
|
|
||||||
: m_shape(std::move(s))
|
|
||||||
{
|
|
||||||
assign_buffer([d] { return reinterpret_cast<char*>(d); });
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
argument(shape s, std::shared_ptr<T> d)
|
|
||||||
: m_shape(std::move(s))
|
|
||||||
{
|
|
||||||
assign_buffer([d] { return reinterpret_cast<char*>(d.get()); });
|
|
||||||
}
|
|
||||||
|
|
||||||
argument(shape s, std::nullptr_t);
|
|
||||||
|
|
||||||
argument(const std::vector<argument>& args);
|
|
||||||
|
|
||||||
/// Provides a raw pointer to the data
|
|
||||||
char* data() const;
|
|
||||||
|
|
||||||
/// Whether data is available
|
|
||||||
bool empty() const;
|
|
||||||
|
|
||||||
const shape& get_shape() const;
|
|
||||||
|
|
||||||
argument reshape(const shape& s) const;
|
|
||||||
|
|
||||||
argument copy() const;
|
|
||||||
|
|
||||||
/// Make copy of the argument that is always sharing the data
|
|
||||||
argument share() const;
|
|
||||||
|
|
||||||
std::vector<argument> get_sub_objects() const;
|
|
||||||
|
|
||||||
/// 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
|
|
||||||
{
|
|
||||||
std::function<char*()> get = nullptr;
|
|
||||||
std::vector<data_t> sub = {};
|
|
||||||
data_t share() const;
|
|
||||||
static data_t from_args(const std::vector<argument>& args);
|
|
||||||
};
|
|
||||||
argument(const shape& s, const data_t& d);
|
|
||||||
shape m_shape;
|
|
||||||
data_t m_data{};
|
|
||||||
};
|
|
||||||
|
|
||||||
MIGRAPHX_EXPORT std::vector<argument> flatten(const std::vector<argument>& args);
|
|
||||||
|
|
||||||
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
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,98 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2022 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_RTGLIB_ARRAY_HPP
|
|
||||||
#define MIGRAPHX_GUARD_RTGLIB_ARRAY_HPP
|
|
||||||
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
#include <migraphx/functional.hpp>
|
|
||||||
#include <migraphx/requires.hpp>
|
|
||||||
#include <type_traits>
|
|
||||||
#include <array>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template <class R, class...>
|
|
||||||
struct array_type
|
|
||||||
{
|
|
||||||
using type = R;
|
|
||||||
};
|
|
||||||
template <class... Ts>
|
|
||||||
struct array_type<void, Ts...> : std::common_type<Ts...>
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class R, class... Ts>
|
|
||||||
using array_type_t = typename array_type<R, Ts...>::type;
|
|
||||||
|
|
||||||
template <class T, std::size_t N, std::size_t... I>
|
|
||||||
constexpr std::array<std::remove_cv_t<T>, N> to_array_impl(T (&a)[N], seq<I...>)
|
|
||||||
{
|
|
||||||
return {{a[I]...}};
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
template <class Result = void, class... Ts, MIGRAPHX_REQUIRES((sizeof...(Ts) > 0))>
|
|
||||||
constexpr std::array<detail::array_type_t<Result, Ts...>, sizeof...(Ts)> make_array(Ts&&... xs)
|
|
||||||
{
|
|
||||||
return {static_cast<detail::array_type_t<Result, Ts...>>(std::forward<Ts>(xs))...};
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr std::array<int, 0> make_array() { return {}; }
|
|
||||||
|
|
||||||
template <class T, std::size_t N>
|
|
||||||
constexpr auto to_array(T (&a)[N])
|
|
||||||
{
|
|
||||||
return detail::to_array_impl(a, detail::gens<N>{});
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template <std::size_t Offset = 0, class Array, std::size_t... I>
|
|
||||||
constexpr auto rearray_impl(Array a, seq<I...>)
|
|
||||||
{
|
|
||||||
return make_array(a[I + Offset]...);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
template <class T, std::size_t N>
|
|
||||||
constexpr auto pop_front(std::array<T, N> a)
|
|
||||||
{
|
|
||||||
return detail::rearray_impl(a, detail::gens<N - 1>{});
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, std::size_t N>
|
|
||||||
constexpr auto pop_back(std::array<T, N> a)
|
|
||||||
{
|
|
||||||
return detail::rearray_impl<1>(a, detail::gens<N - 1>{});
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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_RTGLIB_AS_NUMBER_HPP
|
|
||||||
#define MIGRAPHX_GUARD_RTGLIB_AS_NUMBER_HPP
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
T as_number(T x)
|
|
||||||
{
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
inline int32_t as_number(int8_t x) { return static_cast<int32_t>(x); }
|
|
||||||
inline uint32_t as_number(uint8_t x) { return static_cast<uint32_t>(x); }
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
#endif // MIGRAPHX_GUARD_RTGLIB_AS_NUMBER_HPP
|
|
||||||
@ -1,61 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2022 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_MIGRAPHX_ASSERT_HPP
|
|
||||||
#define MIGRAPHX_GUARD_MIGRAPHX_ASSERT_HPP
|
|
||||||
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
template <class F>
|
|
||||||
auto abort_on_throw(F f) -> decltype(f())
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return f();
|
|
||||||
}
|
|
||||||
catch(const std::exception& e)
|
|
||||||
{
|
|
||||||
std::cerr << e.what() << std::endl;
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
std::cerr << "Unknown exception" << std::endl;
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifdef NDEBUG
|
|
||||||
#define MIGRAPHX_ASSERT_NO_THROW(...) __VA_ARGS__
|
|
||||||
#else
|
|
||||||
#define MIGRAPHX_ASSERT_NO_THROW(...) \
|
|
||||||
migraphx::abort_on_throw([&]() -> decltype(__VA_ARGS__) { return __VA_ARGS__; })
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
#endif // MIGRAPHX_GUARD_MIGRAPHX_ASSERT_HPP
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2022 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_RTGLIB_ASSIGNMENT_OPTIONS_HPP
|
|
||||||
#define MIGRAPHX_GUARD_RTGLIB_ASSIGNMENT_OPTIONS_HPP
|
|
||||||
|
|
||||||
#include <migraphx/support_metric.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
struct assignment_options
|
|
||||||
{
|
|
||||||
support_metric metric = support_metric::latency;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
|
|
||||||
#endif // MIGRAPHX_GUARD_RTGLIB_ASSIGNMENT_OPTIONS_HPP
|
|
||||||
@ -1,67 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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_RTGLIB_AUTO_ANY_CAST_HPP
|
|
||||||
#define MIGRAPHX_GUARD_RTGLIB_AUTO_ANY_CAST_HPP
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
// Forward declare any_cast
|
|
||||||
template <class T>
|
|
||||||
const T& any_cast(const T&);
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template <class U>
|
|
||||||
void any_cast()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
struct auto_any_caster
|
|
||||||
{
|
|
||||||
T& x; // NOLINT
|
|
||||||
|
|
||||||
template <class U>
|
|
||||||
operator U&()
|
|
||||||
{
|
|
||||||
return any_cast<U>(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
operator T&() { return x; }
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
detail::auto_any_caster<T> auto_any_cast(T& x)
|
|
||||||
{
|
|
||||||
return {x};
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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_RTGLIB_AUTO_CONTIGOUS_HPP
|
|
||||||
#define MIGRAPHX_GUARD_RTGLIB_AUTO_CONTIGOUS_HPP
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <migraphx/instruction_ref.hpp>
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
struct module;
|
|
||||||
|
|
||||||
struct MIGRAPHX_EXPORT auto_contiguous
|
|
||||||
{
|
|
||||||
std::string name() const { return "auto_contiguous"; }
|
|
||||||
void apply(module& m) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,72 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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_RTGLIB_AUTO_REGISTER_HPP
|
|
||||||
#define MIGRAPHX_GUARD_RTGLIB_AUTO_REGISTER_HPP
|
|
||||||
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
template <class Action, class T>
|
|
||||||
int auto_register_action()
|
|
||||||
{
|
|
||||||
Action::template apply<T>();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Action, class T>
|
|
||||||
struct auto_register
|
|
||||||
{
|
|
||||||
const static int static_register;
|
|
||||||
// This typedef ensures that the static member will be instantiated if
|
|
||||||
// the class itself is instantiated
|
|
||||||
using static_register_type =
|
|
||||||
std::integral_constant<decltype(&static_register), &static_register>;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef __clang__
|
|
||||||
#pragma clang diagnostic push
|
|
||||||
#pragma clang diagnostic ignored "-Wglobal-constructors"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <class Action, class T>
|
|
||||||
const int auto_register<Action, T>::static_register = auto_register_action<Action, T>(); // NOLINT
|
|
||||||
|
|
||||||
#ifdef __clang__
|
|
||||||
#pragma clang diagnostic pop
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MIGRAPHX_AUTO_REGISTER_NAME_DETAIL(x) migraphx_auto_register_##x
|
|
||||||
#define MIGRAPHX_AUTO_REGISTER_NAME(x) MIGRAPHX_AUTO_REGISTER_NAME_DETAIL(x)
|
|
||||||
// NOLINTNEXTLINE
|
|
||||||
#define MIGRAPHX_AUTO_REGISTER(...) \
|
|
||||||
[[maybe_unused]] void MIGRAPHX_AUTO_REGISTER_NAME(__LINE__)( \
|
|
||||||
migraphx::auto_register<__VA_ARGS__> x = migraphx::auto_register<__VA_ARGS__>{});
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,48 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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_AMDMIGRAPHX_AUTOCAST_FP8_HPP
|
|
||||||
#define MIGRAPHX_GUARD_AMDMIGRAPHX_AUTOCAST_FP8_HPP
|
|
||||||
|
|
||||||
#include <migraphx/shape.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
struct program;
|
|
||||||
struct module;
|
|
||||||
|
|
||||||
/**
|
|
||||||
This pass will convert model with fp8 input parameter to model with fp32
|
|
||||||
input parameter and internally add casts to fp8 for those converted params.*/
|
|
||||||
struct MIGRAPHX_EXPORT autocast_fp8_pass
|
|
||||||
{
|
|
||||||
shape::type_t target_type = migraphx::shape::float_type;
|
|
||||||
std::string name() const { return "autocast_fp8_pass"; }
|
|
||||||
void apply(module& m) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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_RTGLIB_BASE64_HPP
|
|
||||||
#define MIGRAPHX_GUARD_RTGLIB_BASE64_HPP
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
/// encode string to base64
|
|
||||||
std::string MIGRAPHX_EXPORT base64_encode(const std::string& str);
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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_RTGLIB_BF16_HPP
|
|
||||||
#define MIGRAPHX_GUARD_RTGLIB_BF16_HPP
|
|
||||||
|
|
||||||
#include <migraphx/generic_float.hpp>
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
using bf16 = migraphx::generic_float<7, 8>;
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,57 +0,0 @@
|
|||||||
/* ************************************************************************
|
|
||||||
* 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 cop-
|
|
||||||
* ies 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 IM-
|
|
||||||
* PLIED, 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 CONNE-
|
|
||||||
* CTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* ************************************************************************ */
|
|
||||||
#ifndef MIGRAPHX_GUARD_RTGLIB_BITCAST_HPP
|
|
||||||
#define MIGRAPHX_GUARD_RTGLIB_BITCAST_HPP
|
|
||||||
#include <type_traits>
|
|
||||||
#if defined(__GNUC__) && !defined(__clang__)
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
|
|
||||||
#pragma GCC diagnostic ignored "-Wduplicated-branches"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <migraphx/requires.hpp>
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
|
|
||||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
|
||||||
#define MIGRAPHX_CONST_FOLD(x) (__builtin_constant_p(x) ? (x) : (x))
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
template <typename To,
|
|
||||||
typename From,
|
|
||||||
MIGRAPHX_REQUIRES(std::is_trivially_copyable<To>{} and
|
|
||||||
std::is_trivially_copyable<From>{})>
|
|
||||||
inline constexpr To bit_cast(From fr) noexcept
|
|
||||||
{
|
|
||||||
static_assert(sizeof(To) == sizeof(From));
|
|
||||||
#if defined(__GNUC__) and !defined(__clang__)
|
|
||||||
return MIGRAPHX_CONST_FOLD(*reinterpret_cast<To*>(&fr));
|
|
||||||
#else
|
|
||||||
return __builtin_bit_cast(To, fr);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
#if defined(__GNUC__) && !defined(__clang__)
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
#endif
|
|
||||||
#endif // MIGRAPHX_GUARD_RTGLIB_BITCAST_HPP
|
|
||||||
@ -1,95 +0,0 @@
|
|||||||
#ifndef MIGRAPHX_GUARD_MIGRAPHX_BIT_SIGNAL_HPP
|
|
||||||
#define MIGRAPHX_GUARD_MIGRAPHX_BIT_SIGNAL_HPP
|
|
||||||
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
#include <migraphx/ranges.hpp>
|
|
||||||
#include <migraphx/errors.hpp>
|
|
||||||
#include <bitset>
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
/// Observer pattern for keeping track of if something has changed or been
|
|
||||||
/// updated. Can have up to `N` different subscribers. Use by creating a
|
|
||||||
/// `bit_signal` and adding subscribers with `bit_signal.subscribe()`. Use
|
|
||||||
/// `bit_signal.notify()` to set that subscribers should be notified. Get the
|
|
||||||
/// status of the subscription by checking the `slot` returned by
|
|
||||||
/// `bit_signal.subscribe()`.
|
|
||||||
template <std::size_t N>
|
|
||||||
struct bit_signal
|
|
||||||
{
|
|
||||||
std::bitset<N> slots;
|
|
||||||
std::bitset<N> allocated;
|
|
||||||
|
|
||||||
struct slot
|
|
||||||
{
|
|
||||||
bit_signal* handler = nullptr;
|
|
||||||
std::size_t i = N;
|
|
||||||
|
|
||||||
slot() = default;
|
|
||||||
|
|
||||||
slot(bit_signal* h, std::size_t x) : handler(h), i(x) {}
|
|
||||||
|
|
||||||
slot(slot&& rhs) noexcept : handler(rhs.handler), i(rhs.i)
|
|
||||||
{
|
|
||||||
rhs.handler = nullptr;
|
|
||||||
rhs.i = N;
|
|
||||||
}
|
|
||||||
|
|
||||||
slot(const slot& rhs) : handler(rhs.handler), i(rhs.handler->allocate()) {}
|
|
||||||
|
|
||||||
slot& operator=(slot rhs)
|
|
||||||
{
|
|
||||||
std::swap(handler, rhs.handler);
|
|
||||||
std::swap(i, rhs.i);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
~slot() noexcept
|
|
||||||
{
|
|
||||||
if(valid())
|
|
||||||
handler->deallocate(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool valid() const { return i < N and handler != nullptr; }
|
|
||||||
|
|
||||||
bool triggered() const
|
|
||||||
{
|
|
||||||
assert(valid());
|
|
||||||
return handler->triggered(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
operator bool() const { return triggered(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
slot subscribe() { return {this, allocate()}; }
|
|
||||||
|
|
||||||
std::size_t allocate()
|
|
||||||
{
|
|
||||||
auto i = *find_if(range(N), [&](auto x) { return not allocated[x]; });
|
|
||||||
if(i == N)
|
|
||||||
MIGRAPHX_THROW("Too many signals allocated");
|
|
||||||
slots[i] = false;
|
|
||||||
allocated[i] = true;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
void deallocate(std::size_t i) { allocated[i] = false; }
|
|
||||||
|
|
||||||
void notify() { slots.set(); }
|
|
||||||
|
|
||||||
bool triggered(std::size_t i) const { return slots[i]; }
|
|
||||||
|
|
||||||
void clear()
|
|
||||||
{
|
|
||||||
slots.reset();
|
|
||||||
allocated.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t nslots() const { return allocated.count(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
#endif // MIGRAPHX_GUARD_MIGRAPHX_BIT_SIGNAL_HPP
|
|
||||||
@ -1,114 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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_BUILTIN_HPP
|
|
||||||
#define MIGRAPHX_GUARD_BUILTIN_HPP
|
|
||||||
|
|
||||||
#include <migraphx/context.hpp>
|
|
||||||
#include <migraphx/errors.hpp>
|
|
||||||
#include <migraphx/argument.hpp>
|
|
||||||
#include <migraphx/reflect.hpp>
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
namespace builtin {
|
|
||||||
|
|
||||||
struct literal
|
|
||||||
{
|
|
||||||
std::string name() const { return "@literal"; }
|
|
||||||
shape compute_shape(const std::vector<shape>&) const { MIGRAPHX_THROW("builtin"); }
|
|
||||||
argument compute(context&, const shape&, const std::vector<argument>&) const
|
|
||||||
{
|
|
||||||
MIGRAPHX_THROW("builtin");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct outline
|
|
||||||
{
|
|
||||||
shape s;
|
|
||||||
|
|
||||||
template <class Self, class F>
|
|
||||||
static auto reflect(Self& self, F f)
|
|
||||||
{
|
|
||||||
return pack(f(self.s, "shape"));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string name() const { return "@outline"; }
|
|
||||||
shape compute_shape(const std::vector<shape>&) const { return s; }
|
|
||||||
argument compute(context&, const shape&, const std::vector<argument>&) const
|
|
||||||
{
|
|
||||||
MIGRAPHX_THROW("builtin");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct param
|
|
||||||
{
|
|
||||||
std::string parameter;
|
|
||||||
uint32_t order = 0;
|
|
||||||
|
|
||||||
template <class Self, class F>
|
|
||||||
static auto reflect(Self& self, F f)
|
|
||||||
{
|
|
||||||
return pack(f(self.parameter, "parameter"));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string name() const { return "@param"; }
|
|
||||||
shape compute_shape(const std::vector<shape>&) const { MIGRAPHX_THROW("builtin"); }
|
|
||||||
argument compute(context&, const shape&, const std::vector<argument>&) const
|
|
||||||
{
|
|
||||||
MIGRAPHX_THROW("builtin");
|
|
||||||
}
|
|
||||||
friend std::ostream& operator<<(std::ostream& os, const param& op)
|
|
||||||
{
|
|
||||||
os << op.name() << ":" << op.parameter;
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct returns
|
|
||||||
{
|
|
||||||
std::string name() const { return "@return"; }
|
|
||||||
|
|
||||||
shape compute_shape(const std::vector<shape>& arg) const
|
|
||||||
{
|
|
||||||
if(arg.empty())
|
|
||||||
return {};
|
|
||||||
else if(arg.size() == 1)
|
|
||||||
return arg[0];
|
|
||||||
else
|
|
||||||
return shape(arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
argument compute(context&, const shape&, const std::vector<argument>&) const
|
|
||||||
{
|
|
||||||
MIGRAPHX_THROW("builtin");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace builtin
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,87 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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_RTGLIB_CHECK_CONTEXT_HPP
|
|
||||||
#define MIGRAPHX_GUARD_RTGLIB_CHECK_CONTEXT_HPP
|
|
||||||
|
|
||||||
#include <migraphx/program.hpp>
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
#include <migraphx/register_op.hpp>
|
|
||||||
#include <migraphx/stringutils.hpp>
|
|
||||||
#include <migraphx/ranges.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
struct check_context
|
|
||||||
{
|
|
||||||
struct op : auto_register_op<op>
|
|
||||||
{
|
|
||||||
static std::string compute_op_name()
|
|
||||||
{
|
|
||||||
const auto& op_type_name = get_type_name<T>();
|
|
||||||
const auto& split_name = split_string(op_type_name, ':');
|
|
||||||
std::vector<std::string> name_without_version = {"check_context"};
|
|
||||||
// op_type_name would contain internal namespace name with version_x_y_z
|
|
||||||
// remove version and construct op_name such as check_context::migraphx::gpu::context
|
|
||||||
std::copy_if(
|
|
||||||
split_name.begin(),
|
|
||||||
split_name.end(),
|
|
||||||
std::back_inserter(name_without_version),
|
|
||||||
[&](const auto& i) { return not i.empty() and not contains(i, "version"); });
|
|
||||||
return join_strings(name_without_version, "::");
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string name() const
|
|
||||||
{
|
|
||||||
static auto op_name = compute_op_name();
|
|
||||||
return op_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
shape compute_shape(const std::vector<shape>&) const { return {}; }
|
|
||||||
argument compute(context& ctx, const shape&, const std::vector<argument>&) const
|
|
||||||
{
|
|
||||||
this->check(ctx);
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
void finalize(context& ctx, const shape&, const std::vector<shape>&) const
|
|
||||||
{
|
|
||||||
this->check(ctx);
|
|
||||||
}
|
|
||||||
void check(context& ctx) const
|
|
||||||
{
|
|
||||||
T* x = any_cast<T>(&ctx);
|
|
||||||
if(x == nullptr)
|
|
||||||
MIGRAPHX_THROW(std::string("Unexpected context type: ") + ctx.type_id().name());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string name() const { return "check_context"; }
|
|
||||||
void apply(module& m) const { m.insert_instruction(m.begin(), op{}); }
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,431 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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_RTGLIB_CHECK_SHAPES_HPP
|
|
||||||
#define MIGRAPHX_GUARD_RTGLIB_CHECK_SHAPES_HPP
|
|
||||||
|
|
||||||
#include <migraphx/permutation.hpp>
|
|
||||||
#include <migraphx/shape.hpp>
|
|
||||||
#include <migraphx/ranges.hpp>
|
|
||||||
#include <migraphx/stringutils.hpp>
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
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
|
|
||||||
{
|
|
||||||
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(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(Iterator b, Iterator e, const Op& op, const bool d = false)
|
|
||||||
: begin(b), end(e), name(op.name()), dynamic_allowed(d)
|
|
||||||
{
|
|
||||||
check_dynamic();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Op, MIGRAPHX_REQUIRES(not std::is_convertible<Op, std::string>{})>
|
|
||||||
check_shapes(const std::vector<shape>& s, const Op& op, const bool d = false)
|
|
||||||
: begin(s.begin()), end(s.end()), name(op.name()), dynamic_allowed(d)
|
|
||||||
{
|
|
||||||
check_dynamic();
|
|
||||||
}
|
|
||||||
|
|
||||||
check_shapes(const std::vector<shape>& s, const std::string& n, const bool d = false)
|
|
||||||
: begin(s.begin()), end(s.end()), name(n), dynamic_allowed(d)
|
|
||||||
{
|
|
||||||
check_dynamic();
|
|
||||||
}
|
|
||||||
|
|
||||||
void check_dynamic() const
|
|
||||||
{
|
|
||||||
if(not dynamic_allowed and this->any_of([&](const shape& s) { return s.dynamic(); }))
|
|
||||||
{
|
|
||||||
MIGRAPHX_THROW(prefix() + "Dynamic shapes not supported");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string prefix() const
|
|
||||||
{
|
|
||||||
if(name.empty())
|
|
||||||
return "";
|
|
||||||
else
|
|
||||||
return name + ": ";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t size() const
|
|
||||||
{
|
|
||||||
if(begin == end)
|
|
||||||
return 0;
|
|
||||||
return end - begin;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Require the number of shape objects to equal to one of the
|
|
||||||
* given sizes.
|
|
||||||
* \param ns template parameter pack of sizes to check against
|
|
||||||
*/
|
|
||||||
template <class... Ts>
|
|
||||||
const check_shapes& has(Ts... ns) const
|
|
||||||
{
|
|
||||||
if(migraphx::none_of({ns...}, [&](auto i) { return this->size() == i; }))
|
|
||||||
MIGRAPHX_THROW(prefix() + "Wrong number of arguments: expected " +
|
|
||||||
to_string_range({ns...}) + " but given " + std::to_string(size()));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Require the number of shape objects to equal at least a given amount. Use this
|
|
||||||
* method for ops that can take any number (variadic) of inputs.
|
|
||||||
* \param n min. number of shapes
|
|
||||||
*/
|
|
||||||
const check_shapes& has_at_least(std::size_t n) const
|
|
||||||
{
|
|
||||||
if(this->size() < n)
|
|
||||||
MIGRAPHX_THROW(prefix() + "Wrong number of arguments: expected at least " +
|
|
||||||
to_string(n) + " but given " + std::to_string(size()));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Require all shapes to have the same number of elements.
|
|
||||||
* \param n number of
|
|
||||||
*/
|
|
||||||
const check_shapes& nelements(std::size_t n) const
|
|
||||||
{
|
|
||||||
if(not this->all_of([&](const shape& s) { return s.elements() == n; }))
|
|
||||||
MIGRAPHX_THROW(prefix() + "Shapes must have only " + std::to_string(n) + " elements");
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Check that the first shape has exactly n dimensions.
|
|
||||||
* Do nothing if the container is empty.
|
|
||||||
* \param n number of dimensions
|
|
||||||
*/
|
|
||||||
const check_shapes& only_dims(std::size_t n) const
|
|
||||||
{
|
|
||||||
if(begin != end)
|
|
||||||
{
|
|
||||||
if(begin->ndim() != n)
|
|
||||||
MIGRAPHX_THROW(prefix() + "Only " + std::to_string(n) + "d supported");
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Check that the first shape has a maximum of n dimensions.
|
|
||||||
* Do nothing if the container is empty.
|
|
||||||
* \param n number of dimensions
|
|
||||||
*/
|
|
||||||
const check_shapes& max_ndims(std::size_t n) const
|
|
||||||
{
|
|
||||||
if(begin != end)
|
|
||||||
{
|
|
||||||
if(begin->ndim() > n)
|
|
||||||
MIGRAPHX_THROW(prefix() + "Shape must have at most " + std::to_string(n) +
|
|
||||||
" dimensions");
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Check that the first shape has a minimum of n dimensions.
|
|
||||||
* Do nothing if the container is empty.
|
|
||||||
* \param n number of dimensions
|
|
||||||
*/
|
|
||||||
const check_shapes& min_ndims(std::size_t n) const
|
|
||||||
{
|
|
||||||
if(begin != end)
|
|
||||||
{
|
|
||||||
if(begin->ndim() < n)
|
|
||||||
MIGRAPHX_THROW(prefix() + "Shape must have at least " + std::to_string(n) +
|
|
||||||
" dimensions");
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Check all shapes have the same shape.
|
|
||||||
*/
|
|
||||||
const check_shapes& same_shape() const
|
|
||||||
{
|
|
||||||
if(not this->same([](const shape& s) { return s; }))
|
|
||||||
MIGRAPHX_THROW(prefix() + "Shapes do not match");
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Check all shapes have the same type.
|
|
||||||
*/
|
|
||||||
const check_shapes& same_type() const
|
|
||||||
{
|
|
||||||
if(not this->same([](const shape& s) { return s.type(); }))
|
|
||||||
MIGRAPHX_THROW(prefix() + "Types do not match");
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Check all shapes have the same lens.
|
|
||||||
*/
|
|
||||||
const check_shapes& same_dims() const
|
|
||||||
{
|
|
||||||
if(not this->same([](const shape& s) { return s.max_lens(); }))
|
|
||||||
MIGRAPHX_THROW(prefix() + "Dimensions do not match");
|
|
||||||
if(this->any_of([&](const shape& s) { return s.dynamic(); }))
|
|
||||||
if(not this->same([](const shape& s) { return s.min_lens(); }))
|
|
||||||
MIGRAPHX_THROW(prefix() + "Min dynamic dimensions do not match");
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Check all shapes have the same number of dimensions.
|
|
||||||
*/
|
|
||||||
const check_shapes& same_ndims() const
|
|
||||||
{
|
|
||||||
if(not this->same([](const shape& s) { return s.ndim(); }))
|
|
||||||
MIGRAPHX_THROW(prefix() + "Number of dimensions do not match");
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Check all shapes have the same layout.
|
|
||||||
*/
|
|
||||||
const check_shapes& same_layout() const
|
|
||||||
{
|
|
||||||
if(not this->same([](const shape& s) { return find_permutation(s); }))
|
|
||||||
MIGRAPHX_THROW(prefix() + "Layouts do not match");
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Check all shapes are standard.
|
|
||||||
*/
|
|
||||||
const check_shapes& standard() const
|
|
||||||
{
|
|
||||||
if(not this->all_of([](const shape& s) { return s.standard(); }))
|
|
||||||
MIGRAPHX_THROW(prefix() + "Shapes are not in standard layout");
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Check all shapes are scalar.
|
|
||||||
*/
|
|
||||||
const check_shapes& scalar() const
|
|
||||||
{
|
|
||||||
if(not this->all_of([](const shape& s) { return s.scalar(); }))
|
|
||||||
MIGRAPHX_THROW(prefix() + "Shapes are not a scalar");
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Check all shapes are standard or scalar.
|
|
||||||
*/
|
|
||||||
const check_shapes& standard_or_scalar() const
|
|
||||||
{
|
|
||||||
if(not this->all_of([](const shape& s) { return s.standard() or s.scalar(); }))
|
|
||||||
MIGRAPHX_THROW(prefix() + "Shapes are not a scalar or in standard layout");
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Check all shapes are packed.
|
|
||||||
*/
|
|
||||||
const check_shapes& packed() const
|
|
||||||
{
|
|
||||||
if(not this->all_of([](const shape& s) { return s.packed(); }))
|
|
||||||
MIGRAPHX_THROW(prefix() + "Shapes are not packed");
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Check all shapes are packed with certain layouts
|
|
||||||
*/
|
|
||||||
const check_shapes&
|
|
||||||
packed_layouts(const std::initializer_list<std::vector<int64_t>>& layouts) const
|
|
||||||
{
|
|
||||||
if(not this->all_of([&](const shape& s) {
|
|
||||||
return s.packed() and contains(layouts, find_permutation(s));
|
|
||||||
}))
|
|
||||||
MIGRAPHX_THROW(prefix() + "Shapes are not packed with correct layout");
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Check all shapes are packed or broadcasted.
|
|
||||||
*/
|
|
||||||
const check_shapes& packed_or_broadcasted() const
|
|
||||||
{
|
|
||||||
if(not this->all_of([](const shape& s) { return s.packed() or s.broadcasted(); }))
|
|
||||||
MIGRAPHX_THROW(prefix() + "Shapes are not packed nor broadcasted");
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Check all shapes are tuples.
|
|
||||||
*/
|
|
||||||
const check_shapes& tuple_type() const
|
|
||||||
{
|
|
||||||
if(not this->all_of([](const shape& s) { return s.type() == shape::tuple_type; }))
|
|
||||||
MIGRAPHX_THROW(prefix() + "Shapes are not tuple!");
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Check all shapes are not transposed.
|
|
||||||
*/
|
|
||||||
const check_shapes& not_transposed() const
|
|
||||||
{
|
|
||||||
if(not this->all_of([](const shape& s) { return not s.transposed(); }))
|
|
||||||
MIGRAPHX_THROW(prefix() + "Shapes are transposed");
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Check all shapes are not broadcasted.
|
|
||||||
*/
|
|
||||||
const check_shapes& not_broadcasted() const
|
|
||||||
{
|
|
||||||
if(not this->all_of([](const shape& s) { return s.standard() or not s.broadcasted(); }))
|
|
||||||
MIGRAPHX_THROW(prefix() + "Shapes are broadcasted");
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Check all shapes have the same n elements.
|
|
||||||
* \param n number of elements
|
|
||||||
*/
|
|
||||||
const check_shapes& elements(std::size_t n) const
|
|
||||||
{
|
|
||||||
if(not this->all_of([&](const shape& s) { return s.elements() == n; }))
|
|
||||||
MIGRAPHX_THROW(prefix() + "Wrong number of elements");
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Check the batches of all the shapes do not have transposed strides.
|
|
||||||
*/
|
|
||||||
const check_shapes& batch_not_transposed() const
|
|
||||||
{
|
|
||||||
if(not this->all_of(
|
|
||||||
[&](const shape& s) { return batch_not_transposed_strides(s.strides()); }))
|
|
||||||
MIGRAPHX_THROW(prefix() + "Batch size is transposed");
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class F>
|
|
||||||
bool same(F f) const
|
|
||||||
{
|
|
||||||
if(begin == end)
|
|
||||||
return true;
|
|
||||||
auto&& key = f(*begin);
|
|
||||||
return this->all_of([&](const shape& s) { return f(s) == key; });
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Predicate>
|
|
||||||
bool all_of(Predicate p) const
|
|
||||||
{
|
|
||||||
if(begin == end)
|
|
||||||
return true;
|
|
||||||
return std::all_of(begin, end, p);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Predicate>
|
|
||||||
bool any_of(Predicate p) const
|
|
||||||
{
|
|
||||||
if(begin == end)
|
|
||||||
return false;
|
|
||||||
return std::any_of(begin, end, p);
|
|
||||||
}
|
|
||||||
|
|
||||||
Iterator get(long i) const
|
|
||||||
{
|
|
||||||
if(i >= size())
|
|
||||||
MIGRAPHX_THROW(prefix() + "Accessing shape out of bounds");
|
|
||||||
if(i < 0)
|
|
||||||
return end - i;
|
|
||||||
return begin + i;
|
|
||||||
}
|
|
||||||
|
|
||||||
check_shapes slice(long start) const { return {get(start), end, name}; }
|
|
||||||
|
|
||||||
check_shapes slice(long start, long last) const { return {get(start), get(last), name}; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
static bool batch_not_transposed_strides(const std::vector<std::size_t>& strides)
|
|
||||||
{
|
|
||||||
if(strides.size() <= 2)
|
|
||||||
return true;
|
|
||||||
auto dim_0 = strides.size() - 2;
|
|
||||||
auto matrix_size = std::max(strides[dim_0], strides[dim_0 + 1]);
|
|
||||||
std::vector<std::size_t> batch(strides.begin(), strides.begin() + dim_0);
|
|
||||||
if(std::all_of(batch.begin(), batch.end(), [&](auto i) { return (i < matrix_size); }))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(std::adjacent_find(batch.begin(), batch.end(), [&](auto i, auto j) {
|
|
||||||
return (i < j or i < matrix_size or j < matrix_size);
|
|
||||||
}) != batch.end())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 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
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,48 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2022 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_RTGLIB_CLAMP_HPP
|
|
||||||
#define MIGRAPHX_GUARD_RTGLIB_CLAMP_HPP
|
|
||||||
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
#include <migraphx/float_equal.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
template <class U, class T>
|
|
||||||
U pad_clamp(T x)
|
|
||||||
{
|
|
||||||
if(float_equal(x, std::numeric_limits<T>::lowest()))
|
|
||||||
return std::numeric_limits<U>::lowest();
|
|
||||||
if(float_equal(x, std::numeric_limits<T>::max()))
|
|
||||||
return std::numeric_limits<U>::max();
|
|
||||||
return (x < std::numeric_limits<U>::lowest())
|
|
||||||
? std::numeric_limits<U>::lowest()
|
|
||||||
: (std::numeric_limits<U>::max() < x) ? std::numeric_limits<U>::max() : U(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,72 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2022 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_RTGLIB_CLONEABLE_HPP
|
|
||||||
#define MIGRAPHX_GUARD_RTGLIB_CLONEABLE_HPP
|
|
||||||
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
template <typename Base>
|
|
||||||
struct cloneable
|
|
||||||
{
|
|
||||||
friend Base;
|
|
||||||
|
|
||||||
virtual std::shared_ptr<Base> clone() = 0;
|
|
||||||
|
|
||||||
template <typename Derived>
|
|
||||||
struct derive : Base
|
|
||||||
{
|
|
||||||
friend Derived;
|
|
||||||
|
|
||||||
std::shared_ptr<Base> clone() override
|
|
||||||
{
|
|
||||||
return std::make_shared<Derived>(static_cast<const Derived&>(*this));
|
|
||||||
}
|
|
||||||
template <typename... Args>
|
|
||||||
derive(Args&&... args) : Base(std::forward<Args>(args)...)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct share : Base, std::enable_shared_from_this<Base>
|
|
||||||
{
|
|
||||||
std::shared_ptr<Base> clone() override { return this->shared_from_this(); }
|
|
||||||
template <typename... Args>
|
|
||||||
share(Args&&... args) : Base(std::forward<Args>(args)...)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
cloneable() = default;
|
|
||||||
cloneable(const cloneable&) = default;
|
|
||||||
cloneable& operator=(const cloneable&) = default;
|
|
||||||
virtual ~cloneable() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,158 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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_MIGRAPHX_COMMON_HPP
|
|
||||||
#define MIGRAPHX_GUARD_MIGRAPHX_COMMON_HPP
|
|
||||||
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
#include <migraphx/shape.hpp>
|
|
||||||
#include <migraphx/instruction_ref.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
struct module;
|
|
||||||
struct operation;
|
|
||||||
|
|
||||||
struct common_options
|
|
||||||
{
|
|
||||||
bool common_type = true;
|
|
||||||
bool common_lens = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Broadcasting for two vectors of dynamic_dimensions.
|
|
||||||
* Compares `dynamic_dimension` objects from the trailing (right-most) dimension and working
|
|
||||||
* leftwards.
|
|
||||||
*
|
|
||||||
* Rules for broadcasting dynamic_dimension:
|
|
||||||
* If the same `dynamic_dimension`, return either.
|
|
||||||
* If one of the `dynamic_dimension`s is 1, return the other one.
|
|
||||||
* If the `dynamic_dimension`s have an intersection, return the intersection.
|
|
||||||
* Explanation:
|
|
||||||
* For the shape to be broadcastable at runtime (when the dimensions are constant) the dimensions
|
|
||||||
* must be the same. The only way for the dimensions to be the same is if the output dimension is
|
|
||||||
* the intersection of the ranges.
|
|
||||||
* In practice, we will mostly see this case for handling unknown dynamic_dimensions like {0,
|
|
||||||
* max_int}. Else, throw an error.
|
|
||||||
*
|
|
||||||
* There is a contrived edge case for ranges that include 1 but are not a fixed {1, 1}.
|
|
||||||
* That case is not supported.
|
|
||||||
*/
|
|
||||||
MIGRAPHX_EXPORT
|
|
||||||
std::vector<shape::dynamic_dimension>
|
|
||||||
compute_broadcasted_dyn_dims(std::vector<shape::dynamic_dimension> dds0,
|
|
||||||
std::vector<shape::dynamic_dimension> dds1);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @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,
|
|
||||||
common_options options = {});
|
|
||||||
|
|
||||||
MIGRAPHX_EXPORT
|
|
||||||
std::vector<instruction_ref>
|
|
||||||
add_common_args(module& m, std::vector<instruction_ref> inputs, common_options options = {});
|
|
||||||
|
|
||||||
MIGRAPHX_EXPORT
|
|
||||||
instruction_ref insert_common_op(module& m,
|
|
||||||
instruction_ref ins,
|
|
||||||
const operation& op,
|
|
||||||
std::vector<instruction_ref> inputs,
|
|
||||||
common_options options = {});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @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,
|
|
||||||
common_options options = {});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the broadcasted shape with the given input_shape and broadcasted dimensions.
|
|
||||||
*
|
|
||||||
* @param input_shape static shape to broadcast
|
|
||||||
* @param bcast_lens dimensions to broadcast to
|
|
||||||
* @return broadcasted shape with calculated strides
|
|
||||||
*/
|
|
||||||
MIGRAPHX_EXPORT
|
|
||||||
shape make_bcast_shape(const shape& input_shape, const std::vector<std::size_t>& bcast_lens);
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
#endif // MIGRAPHX_GUARD_MIGRAPHX_COMMON_HPP
|
|
||||||
@ -1,64 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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_MIGRAPHX_COMMON_DIMS_HPP
|
|
||||||
#define MIGRAPHX_GUARD_MIGRAPHX_COMMON_DIMS_HPP
|
|
||||||
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <functional>
|
|
||||||
#include <numeric>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
/// This will compute a higher dimensional space that will preserve the axes
|
|
||||||
/// for both sets of dimensions. Two axes_maps are provided for each of the
|
|
||||||
/// dims that will map the axis to the axes that are used by the result of
|
|
||||||
/// common_dims.
|
|
||||||
struct MIGRAPHX_EXPORT common_dims
|
|
||||||
{
|
|
||||||
static common_dims compute(const std::vector<std::size_t>& dims1,
|
|
||||||
const std::vector<std::size_t>& dims2);
|
|
||||||
|
|
||||||
/// Map the dimensions into the common higher dimensional space. The
|
|
||||||
/// dimension doesnt need to have the same number of elements as the
|
|
||||||
/// common dimension.
|
|
||||||
std::vector<std::size_t> get_dimensions_for(const std::vector<std::size_t>& idims) const;
|
|
||||||
/// Get the corresponding axes map based on the rank of tensor
|
|
||||||
const std::vector<std::vector<std::size_t>>* get_axes_map(std::size_t n) const;
|
|
||||||
std::vector<std::size_t> dims;
|
|
||||||
std::vector<std::vector<std::size_t>> axes_map1;
|
|
||||||
std::vector<std::vector<std::size_t>> axes_map2;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Range>
|
|
||||||
auto elements(const Range& r)
|
|
||||||
{
|
|
||||||
return std::accumulate(r.begin(), r.end(), std::size_t{1}, std::multiplies<>{});
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
#endif // MIGRAPHX_GUARD_MIGRAPHX_COMMON_DIMS_HPP
|
|
||||||
@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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_RTGLIB_COMPILE_OPTIONS_HPP
|
|
||||||
#define MIGRAPHX_GUARD_RTGLIB_COMPILE_OPTIONS_HPP
|
|
||||||
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
#include <migraphx/tracer.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
struct compile_options
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Have MIGX allocate memory for parameters and add instructions
|
|
||||||
* to copy parameters and output to/from an offload device like a GPU.
|
|
||||||
*/
|
|
||||||
bool offload_copy = false;
|
|
||||||
|
|
||||||
bool fast_math = true;
|
|
||||||
bool exhaustive_tune = false;
|
|
||||||
|
|
||||||
tracer trace{};
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,71 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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_MIGRAPHX_COMPILE_SRC_HPP
|
|
||||||
#define MIGRAPHX_GUARD_MIGRAPHX_COMPILE_SRC_HPP
|
|
||||||
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
#include <migraphx/filesystem.hpp>
|
|
||||||
#include <functional>
|
|
||||||
#include <string>
|
|
||||||
#include <utility>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
struct src_file
|
|
||||||
{
|
|
||||||
fs::path path;
|
|
||||||
std::string_view content;
|
|
||||||
|
|
||||||
src_file() = default;
|
|
||||||
src_file(fs::path file_path, std::string_view file_content)
|
|
||||||
: path{std::move(file_path)}, content{file_content}
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit src_file(const std::pair<std::string_view, std::string_view>& pair)
|
|
||||||
: path{pair.first}, content{pair.second}
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MIGRAPHX_EXPORT src_compiler
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
fs::path compiler = MIGRAPHX_CXX_COMPILER;
|
|
||||||
#else
|
|
||||||
fs::path compiler = "c++";
|
|
||||||
#endif
|
|
||||||
std::vector<std::string> flags = {};
|
|
||||||
fs::path output = {};
|
|
||||||
fs::path launcher = {};
|
|
||||||
std::string out_ext = ".o";
|
|
||||||
std::function<fs::path(fs::path)> process = nullptr;
|
|
||||||
std::vector<char> compile(const std::vector<src_file>& srcs) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
#endif // MIGRAPHX_GUARD_MIGRAPHX_COMPILE_SRC_HPP
|
|
||||||
@ -1,303 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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_CONCAT_OPT_HPP
|
|
||||||
#define MIGRAPHX_GUARD_CONCAT_OPT_HPP
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <string>
|
|
||||||
#include <functional>
|
|
||||||
#include <memory>
|
|
||||||
#include <type_traits>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include <migraphx/operation.hpp>
|
|
||||||
#include <migraphx/op/concat.hpp>
|
|
||||||
#include <migraphx/optional.hpp>
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
#ifdef DOXYGEN
|
|
||||||
|
|
||||||
/// An interface for target-dependent optimization for the concat instruction
|
|
||||||
struct concat_optimization
|
|
||||||
{
|
|
||||||
/// A name of the target-dependent allocate operator
|
|
||||||
std::string allocate() const;
|
|
||||||
/// Return the target-independent concat operator
|
|
||||||
optional<op::concat> get_concat(const operation& op) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#ifdef TYPE_ERASED_DECLARATION
|
|
||||||
|
|
||||||
// Type-erased interface for:
|
|
||||||
struct MIGRAPHX_EXPORT concat_optimization
|
|
||||||
{
|
|
||||||
//
|
|
||||||
std::string allocate() const;
|
|
||||||
//
|
|
||||||
optional<op::concat> get_concat(const operation& op) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
struct concat_optimization
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
template <class PrivateDetailTypeErasedT>
|
|
||||||
struct private_te_unwrap_reference
|
|
||||||
{
|
|
||||||
using type = PrivateDetailTypeErasedT;
|
|
||||||
};
|
|
||||||
template <class PrivateDetailTypeErasedT>
|
|
||||||
struct private_te_unwrap_reference<std::reference_wrapper<PrivateDetailTypeErasedT>>
|
|
||||||
{
|
|
||||||
using type = PrivateDetailTypeErasedT;
|
|
||||||
};
|
|
||||||
template <class PrivateDetailTypeErasedT>
|
|
||||||
using private_te_pure = typename std::remove_cv<
|
|
||||||
typename std::remove_reference<PrivateDetailTypeErasedT>::type>::type;
|
|
||||||
|
|
||||||
template <class PrivateDetailTypeErasedT>
|
|
||||||
using private_te_constraints_impl =
|
|
||||||
decltype(std::declval<PrivateDetailTypeErasedT>().allocate(),
|
|
||||||
std::declval<PrivateDetailTypeErasedT>().get_concat(
|
|
||||||
std::declval<const operation&>()),
|
|
||||||
void());
|
|
||||||
|
|
||||||
template <class PrivateDetailTypeErasedT>
|
|
||||||
using private_te_constraints = private_te_constraints_impl<
|
|
||||||
typename private_te_unwrap_reference<private_te_pure<PrivateDetailTypeErasedT>>::type>;
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Constructors
|
|
||||||
concat_optimization() = default;
|
|
||||||
|
|
||||||
template <typename PrivateDetailTypeErasedT,
|
|
||||||
typename = private_te_constraints<PrivateDetailTypeErasedT>,
|
|
||||||
typename = typename std::enable_if<
|
|
||||||
not std::is_same<private_te_pure<PrivateDetailTypeErasedT>,
|
|
||||||
concat_optimization>{}>::type>
|
|
||||||
concat_optimization(PrivateDetailTypeErasedT&& value)
|
|
||||||
: private_detail_te_handle_mem_var(
|
|
||||||
std::make_shared<
|
|
||||||
private_detail_te_handle_type<private_te_pure<PrivateDetailTypeErasedT>>>(
|
|
||||||
std::forward<PrivateDetailTypeErasedT>(value)))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assignment
|
|
||||||
template <typename PrivateDetailTypeErasedT,
|
|
||||||
typename = private_te_constraints<PrivateDetailTypeErasedT>,
|
|
||||||
typename = typename std::enable_if<
|
|
||||||
not std::is_same<private_te_pure<PrivateDetailTypeErasedT>,
|
|
||||||
concat_optimization>{}>::type>
|
|
||||||
concat_optimization& operator=(PrivateDetailTypeErasedT&& value)
|
|
||||||
{
|
|
||||||
using std::swap;
|
|
||||||
auto* derived = this->any_cast<private_te_pure<PrivateDetailTypeErasedT>>();
|
|
||||||
if(derived and private_detail_te_handle_mem_var.use_count() == 1)
|
|
||||||
{
|
|
||||||
*derived = std::forward<PrivateDetailTypeErasedT>(value);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
concat_optimization rhs(value);
|
|
||||||
swap(private_detail_te_handle_mem_var, rhs.private_detail_te_handle_mem_var);
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cast
|
|
||||||
template <typename PrivateDetailTypeErasedT>
|
|
||||||
PrivateDetailTypeErasedT* any_cast()
|
|
||||||
{
|
|
||||||
return this->type_id() == typeid(PrivateDetailTypeErasedT)
|
|
||||||
? std::addressof(static_cast<private_detail_te_handle_type<
|
|
||||||
typename std::remove_cv<PrivateDetailTypeErasedT>::type>&>(
|
|
||||||
private_detail_te_get_handle())
|
|
||||||
.private_detail_te_value)
|
|
||||||
: nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename PrivateDetailTypeErasedT>
|
|
||||||
const typename std::remove_cv<PrivateDetailTypeErasedT>::type* any_cast() const
|
|
||||||
{
|
|
||||||
return this->type_id() == typeid(PrivateDetailTypeErasedT)
|
|
||||||
? std::addressof(static_cast<const private_detail_te_handle_type<
|
|
||||||
typename std::remove_cv<PrivateDetailTypeErasedT>::type>&>(
|
|
||||||
private_detail_te_get_handle())
|
|
||||||
.private_detail_te_value)
|
|
||||||
: 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string allocate() const
|
|
||||||
{
|
|
||||||
assert((*this).private_detail_te_handle_mem_var);
|
|
||||||
return (*this).private_detail_te_get_handle().allocate();
|
|
||||||
}
|
|
||||||
|
|
||||||
optional<op::concat> get_concat(const operation& op) const
|
|
||||||
{
|
|
||||||
assert((*this).private_detail_te_handle_mem_var);
|
|
||||||
return (*this).private_detail_te_get_handle().get_concat(op);
|
|
||||||
}
|
|
||||||
|
|
||||||
friend bool is_shared(const concat_optimization& private_detail_x,
|
|
||||||
const concat_optimization& private_detail_y)
|
|
||||||
{
|
|
||||||
return private_detail_x.private_detail_te_handle_mem_var ==
|
|
||||||
private_detail_y.private_detail_te_handle_mem_var;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct private_detail_te_handle_base_type
|
|
||||||
{
|
|
||||||
virtual ~private_detail_te_handle_base_type() {}
|
|
||||||
virtual std::shared_ptr<private_detail_te_handle_base_type> clone() const = 0;
|
|
||||||
virtual const std::type_info& type() const = 0;
|
|
||||||
|
|
||||||
virtual std::string allocate() const = 0;
|
|
||||||
virtual optional<op::concat> get_concat(const operation& op) const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename PrivateDetailTypeErasedT>
|
|
||||||
struct private_detail_te_handle_type : private_detail_te_handle_base_type
|
|
||||||
{
|
|
||||||
template <typename PrivateDetailTypeErasedU = PrivateDetailTypeErasedT>
|
|
||||||
private_detail_te_handle_type(
|
|
||||||
PrivateDetailTypeErasedT value,
|
|
||||||
typename std::enable_if<std::is_reference<PrivateDetailTypeErasedU>::value>::type* =
|
|
||||||
nullptr)
|
|
||||||
: private_detail_te_value(value)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename PrivateDetailTypeErasedU = PrivateDetailTypeErasedT>
|
|
||||||
private_detail_te_handle_type(
|
|
||||||
PrivateDetailTypeErasedT value,
|
|
||||||
typename std::enable_if<not std::is_reference<PrivateDetailTypeErasedU>::value,
|
|
||||||
int>::type* = nullptr) noexcept
|
|
||||||
: private_detail_te_value(std::move(value))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<private_detail_te_handle_base_type> clone() const override
|
|
||||||
{
|
|
||||||
return std::make_shared<private_detail_te_handle_type>(private_detail_te_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::type_info& type() const override { return typeid(private_detail_te_value); }
|
|
||||||
|
|
||||||
std::string allocate() const override { return private_detail_te_value.allocate(); }
|
|
||||||
|
|
||||||
optional<op::concat> get_concat(const operation& op) const override
|
|
||||||
{
|
|
||||||
|
|
||||||
return private_detail_te_value.get_concat(op);
|
|
||||||
}
|
|
||||||
|
|
||||||
PrivateDetailTypeErasedT private_detail_te_value;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename PrivateDetailTypeErasedT>
|
|
||||||
struct private_detail_te_handle_type<std::reference_wrapper<PrivateDetailTypeErasedT>>
|
|
||||||
: private_detail_te_handle_type<PrivateDetailTypeErasedT&>
|
|
||||||
{
|
|
||||||
private_detail_te_handle_type(std::reference_wrapper<PrivateDetailTypeErasedT> ref)
|
|
||||||
: private_detail_te_handle_type<PrivateDetailTypeErasedT&>(ref.get())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
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
|
|
||||||
{
|
|
||||||
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()
|
|
||||||
{
|
|
||||||
assert(private_detail_te_handle_mem_var != nullptr);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<private_detail_te_handle_base_type> private_detail_te_handle_mem_var;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ValueType>
|
|
||||||
inline const ValueType* any_cast(const concat_optimization* x)
|
|
||||||
{
|
|
||||||
return x->any_cast<ValueType>();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ValueType>
|
|
||||||
inline ValueType* any_cast(concat_optimization* x)
|
|
||||||
{
|
|
||||||
return x->any_cast<ValueType>();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ValueType>
|
|
||||||
inline ValueType& any_cast(concat_optimization& x)
|
|
||||||
{
|
|
||||||
auto* y = x.any_cast<typename std::remove_reference<ValueType>::type>();
|
|
||||||
if(y == nullptr)
|
|
||||||
throw std::bad_cast();
|
|
||||||
return *y;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ValueType>
|
|
||||||
inline const ValueType& any_cast(const concat_optimization& x)
|
|
||||||
{
|
|
||||||
const auto* y = x.any_cast<typename std::remove_reference<ValueType>::type>();
|
|
||||||
if(y == nullptr)
|
|
||||||
throw std::bad_cast();
|
|
||||||
return *y;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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_CONFIG_HPP
|
|
||||||
#define MIGRAPHX_GUARD_CONFIG_HPP
|
|
||||||
|
|
||||||
#include <migraphx/export.h>
|
|
||||||
#include <ciso646>
|
|
||||||
|
|
||||||
#if !defined(MIGRAPHX_USE_CLANG_TIDY) && !defined(DOXYGEN)
|
|
||||||
|
|
||||||
#ifdef BUILD_DEV
|
|
||||||
#define MIGRAPHX_INLINE_NS version_1
|
|
||||||
#else
|
|
||||||
#include <migraphx/version.h>
|
|
||||||
|
|
||||||
#define MIGRAPHX_VERSION_PRIMITIVE_CONCAT(x, y) x##_##y
|
|
||||||
#define MIGRAPHX_VERSION_CONCAT(x, y) MIGRAPHX_VERSION_PRIMITIVE_CONCAT(x, y)
|
|
||||||
|
|
||||||
#define MIGRAPHX_VERSION \
|
|
||||||
MIGRAPHX_VERSION_CONCAT( \
|
|
||||||
MIGRAPHX_VERSION_CONCAT(MIGRAPHX_VERSION_MAJOR, MIGRAPHX_VERSION_MINOR), \
|
|
||||||
MIGRAPHX_VERSION_PATCH)
|
|
||||||
|
|
||||||
#define MIGRAPHX_INLINE_NS MIGRAPHX_VERSION_CONCAT(version, MIGRAPHX_VERSION)
|
|
||||||
#endif // build_dev
|
|
||||||
#endif // clang_tidy
|
|
||||||
|
|
||||||
#ifdef DOXYGEN
|
|
||||||
#define MIGRAPHX_INLINE_NS internal
|
|
||||||
#endif // doxygen
|
|
||||||
|
|
||||||
#ifdef MIGRAPHX_USE_CLANG_TIDY
|
|
||||||
#define MIGRAPHX_TIDY_CONST const
|
|
||||||
#else
|
|
||||||
#define MIGRAPHX_TIDY_CONST
|
|
||||||
#endif // tidy_const
|
|
||||||
#endif // clang_tidy
|
|
||||||
@ -1,466 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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_CONTEXT_HPP
|
|
||||||
#define MIGRAPHX_GUARD_CONTEXT_HPP
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <string>
|
|
||||||
#include <functional>
|
|
||||||
#include <memory>
|
|
||||||
#include <type_traits>
|
|
||||||
#include <utility>
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
#include <migraphx/value.hpp>
|
|
||||||
#include <migraphx/any_ptr.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
#ifdef DOXYGEN
|
|
||||||
|
|
||||||
/// A context is used to store internal data for a `target`. A context is
|
|
||||||
/// constructed by a target during compilation and passed to the operations
|
|
||||||
/// during `eval`.
|
|
||||||
struct context
|
|
||||||
{
|
|
||||||
/// Wait for any tasks in the context to complete
|
|
||||||
void finish() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
value to_value_context(const T&)
|
|
||||||
{
|
|
||||||
return value{};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
void from_value_context(T&, const value&)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
any_ptr get_queue_context(T&)
|
|
||||||
{
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
void wait_for_context(T&, any_ptr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
void finish_on_context(T&, any_ptr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef TYPE_ERASED_DECLARATION
|
|
||||||
|
|
||||||
// Type-erased interface for:
|
|
||||||
struct MIGRAPHX_EXPORT context
|
|
||||||
{
|
|
||||||
// (optional)
|
|
||||||
value to_value() const;
|
|
||||||
// (optional)
|
|
||||||
void from_value(const value& v);
|
|
||||||
// (optional)
|
|
||||||
any_ptr get_queue();
|
|
||||||
// (optional)
|
|
||||||
void wait_for(any_ptr queue);
|
|
||||||
// (optional)
|
|
||||||
void finish_on(any_ptr queue);
|
|
||||||
//
|
|
||||||
void finish() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
struct context
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
template <class T>
|
|
||||||
static auto private_detail_te_default_to_value(char, T&& private_detail_te_self)
|
|
||||||
-> decltype(private_detail_te_self.to_value())
|
|
||||||
{
|
|
||||||
return private_detail_te_self.to_value();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
static value private_detail_te_default_to_value(float, T&& private_detail_te_self)
|
|
||||||
{
|
|
||||||
return to_value_context(private_detail_te_self);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
static auto
|
|
||||||
private_detail_te_default_from_value(char, T&& private_detail_te_self, const value& v)
|
|
||||||
-> decltype(private_detail_te_self.from_value(v))
|
|
||||||
{
|
|
||||||
private_detail_te_self.from_value(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
static void
|
|
||||||
private_detail_te_default_from_value(float, T&& private_detail_te_self, const value& v)
|
|
||||||
{
|
|
||||||
from_value_context(private_detail_te_self, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
static auto private_detail_te_default_get_queue(char, T&& private_detail_te_self)
|
|
||||||
-> decltype(private_detail_te_self.get_queue())
|
|
||||||
{
|
|
||||||
return private_detail_te_self.get_queue();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
static any_ptr private_detail_te_default_get_queue(float, T&& private_detail_te_self)
|
|
||||||
{
|
|
||||||
return get_queue_context(private_detail_te_self);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
static auto private_detail_te_default_wait_for(char, T&& private_detail_te_self, any_ptr queue)
|
|
||||||
-> decltype(private_detail_te_self.wait_for(queue))
|
|
||||||
{
|
|
||||||
private_detail_te_self.wait_for(queue);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
static void private_detail_te_default_wait_for(float, T&& private_detail_te_self, any_ptr queue)
|
|
||||||
{
|
|
||||||
wait_for_context(private_detail_te_self, queue);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
static auto private_detail_te_default_finish_on(char, T&& private_detail_te_self, any_ptr queue)
|
|
||||||
-> decltype(private_detail_te_self.finish_on(queue))
|
|
||||||
{
|
|
||||||
private_detail_te_self.finish_on(queue);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
static void
|
|
||||||
private_detail_te_default_finish_on(float, T&& private_detail_te_self, any_ptr queue)
|
|
||||||
{
|
|
||||||
finish_on_context(private_detail_te_self, queue);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class PrivateDetailTypeErasedT>
|
|
||||||
struct private_te_unwrap_reference
|
|
||||||
{
|
|
||||||
using type = PrivateDetailTypeErasedT;
|
|
||||||
};
|
|
||||||
template <class PrivateDetailTypeErasedT>
|
|
||||||
struct private_te_unwrap_reference<std::reference_wrapper<PrivateDetailTypeErasedT>>
|
|
||||||
{
|
|
||||||
using type = PrivateDetailTypeErasedT;
|
|
||||||
};
|
|
||||||
template <class PrivateDetailTypeErasedT>
|
|
||||||
using private_te_pure = typename std::remove_cv<
|
|
||||||
typename std::remove_reference<PrivateDetailTypeErasedT>::type>::type;
|
|
||||||
|
|
||||||
template <class PrivateDetailTypeErasedT>
|
|
||||||
using private_te_constraints_impl =
|
|
||||||
decltype(private_detail_te_default_to_value(char(0),
|
|
||||||
std::declval<PrivateDetailTypeErasedT>()),
|
|
||||||
private_detail_te_default_from_value(char(0),
|
|
||||||
std::declval<PrivateDetailTypeErasedT>(),
|
|
||||||
std::declval<const value&>()),
|
|
||||||
private_detail_te_default_get_queue(char(0),
|
|
||||||
std::declval<PrivateDetailTypeErasedT>()),
|
|
||||||
private_detail_te_default_wait_for(
|
|
||||||
char(0), std::declval<PrivateDetailTypeErasedT>(), std::declval<any_ptr>()),
|
|
||||||
private_detail_te_default_finish_on(
|
|
||||||
char(0), std::declval<PrivateDetailTypeErasedT>(), std::declval<any_ptr>()),
|
|
||||||
std::declval<PrivateDetailTypeErasedT>().finish(),
|
|
||||||
void());
|
|
||||||
|
|
||||||
template <class PrivateDetailTypeErasedT>
|
|
||||||
using private_te_constraints = private_te_constraints_impl<
|
|
||||||
typename private_te_unwrap_reference<private_te_pure<PrivateDetailTypeErasedT>>::type>;
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Constructors
|
|
||||||
context() = default;
|
|
||||||
|
|
||||||
template <typename PrivateDetailTypeErasedT,
|
|
||||||
typename = private_te_constraints<PrivateDetailTypeErasedT>,
|
|
||||||
typename = typename std::enable_if<
|
|
||||||
not std::is_same<private_te_pure<PrivateDetailTypeErasedT>, context>{}>::type>
|
|
||||||
context(PrivateDetailTypeErasedT&& value)
|
|
||||||
: private_detail_te_handle_mem_var(
|
|
||||||
std::make_shared<
|
|
||||||
private_detail_te_handle_type<private_te_pure<PrivateDetailTypeErasedT>>>(
|
|
||||||
std::forward<PrivateDetailTypeErasedT>(value)))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assignment
|
|
||||||
template <typename PrivateDetailTypeErasedT,
|
|
||||||
typename = private_te_constraints<PrivateDetailTypeErasedT>,
|
|
||||||
typename = typename std::enable_if<
|
|
||||||
not std::is_same<private_te_pure<PrivateDetailTypeErasedT>, context>{}>::type>
|
|
||||||
context& operator=(PrivateDetailTypeErasedT&& value)
|
|
||||||
{
|
|
||||||
using std::swap;
|
|
||||||
auto* derived = this->any_cast<private_te_pure<PrivateDetailTypeErasedT>>();
|
|
||||||
if(derived and private_detail_te_handle_mem_var.use_count() == 1)
|
|
||||||
{
|
|
||||||
*derived = std::forward<PrivateDetailTypeErasedT>(value);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
context rhs(value);
|
|
||||||
swap(private_detail_te_handle_mem_var, rhs.private_detail_te_handle_mem_var);
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cast
|
|
||||||
template <typename PrivateDetailTypeErasedT>
|
|
||||||
PrivateDetailTypeErasedT* any_cast()
|
|
||||||
{
|
|
||||||
return this->type_id() == typeid(PrivateDetailTypeErasedT)
|
|
||||||
? std::addressof(static_cast<private_detail_te_handle_type<
|
|
||||||
typename std::remove_cv<PrivateDetailTypeErasedT>::type>&>(
|
|
||||||
private_detail_te_get_handle())
|
|
||||||
.private_detail_te_value)
|
|
||||||
: nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename PrivateDetailTypeErasedT>
|
|
||||||
const typename std::remove_cv<PrivateDetailTypeErasedT>::type* any_cast() const
|
|
||||||
{
|
|
||||||
return this->type_id() == typeid(PrivateDetailTypeErasedT)
|
|
||||||
? std::addressof(static_cast<const private_detail_te_handle_type<
|
|
||||||
typename std::remove_cv<PrivateDetailTypeErasedT>::type>&>(
|
|
||||||
private_detail_te_get_handle())
|
|
||||||
.private_detail_te_value)
|
|
||||||
: 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
value to_value() const
|
|
||||||
{
|
|
||||||
assert((*this).private_detail_te_handle_mem_var);
|
|
||||||
return (*this).private_detail_te_get_handle().to_value();
|
|
||||||
}
|
|
||||||
|
|
||||||
void from_value(const value& v)
|
|
||||||
{
|
|
||||||
assert((*this).private_detail_te_handle_mem_var);
|
|
||||||
(*this).private_detail_te_get_handle().from_value(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
any_ptr get_queue()
|
|
||||||
{
|
|
||||||
assert((*this).private_detail_te_handle_mem_var);
|
|
||||||
return (*this).private_detail_te_get_handle().get_queue();
|
|
||||||
}
|
|
||||||
|
|
||||||
void wait_for(any_ptr queue)
|
|
||||||
{
|
|
||||||
assert((*this).private_detail_te_handle_mem_var);
|
|
||||||
(*this).private_detail_te_get_handle().wait_for(queue);
|
|
||||||
}
|
|
||||||
|
|
||||||
void finish_on(any_ptr queue)
|
|
||||||
{
|
|
||||||
assert((*this).private_detail_te_handle_mem_var);
|
|
||||||
(*this).private_detail_te_get_handle().finish_on(queue);
|
|
||||||
}
|
|
||||||
|
|
||||||
void finish() const
|
|
||||||
{
|
|
||||||
assert((*this).private_detail_te_handle_mem_var);
|
|
||||||
(*this).private_detail_te_get_handle().finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
friend bool is_shared(const context& private_detail_x, const context& private_detail_y)
|
|
||||||
{
|
|
||||||
return private_detail_x.private_detail_te_handle_mem_var ==
|
|
||||||
private_detail_y.private_detail_te_handle_mem_var;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct private_detail_te_handle_base_type
|
|
||||||
{
|
|
||||||
virtual ~private_detail_te_handle_base_type() {}
|
|
||||||
virtual std::shared_ptr<private_detail_te_handle_base_type> clone() const = 0;
|
|
||||||
virtual const std::type_info& type() const = 0;
|
|
||||||
|
|
||||||
virtual value to_value() const = 0;
|
|
||||||
virtual void from_value(const value& v) = 0;
|
|
||||||
virtual any_ptr get_queue() = 0;
|
|
||||||
virtual void wait_for(any_ptr queue) = 0;
|
|
||||||
virtual void finish_on(any_ptr queue) = 0;
|
|
||||||
virtual void finish() const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename PrivateDetailTypeErasedT>
|
|
||||||
struct private_detail_te_handle_type : private_detail_te_handle_base_type
|
|
||||||
{
|
|
||||||
template <typename PrivateDetailTypeErasedU = PrivateDetailTypeErasedT>
|
|
||||||
private_detail_te_handle_type(
|
|
||||||
PrivateDetailTypeErasedT value,
|
|
||||||
typename std::enable_if<std::is_reference<PrivateDetailTypeErasedU>::value>::type* =
|
|
||||||
nullptr)
|
|
||||||
: private_detail_te_value(value)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename PrivateDetailTypeErasedU = PrivateDetailTypeErasedT>
|
|
||||||
private_detail_te_handle_type(
|
|
||||||
PrivateDetailTypeErasedT value,
|
|
||||||
typename std::enable_if<not std::is_reference<PrivateDetailTypeErasedU>::value,
|
|
||||||
int>::type* = nullptr) noexcept
|
|
||||||
: private_detail_te_value(std::move(value))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<private_detail_te_handle_base_type> clone() const override
|
|
||||||
{
|
|
||||||
return std::make_shared<private_detail_te_handle_type>(private_detail_te_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::type_info& type() const override { return typeid(private_detail_te_value); }
|
|
||||||
|
|
||||||
value to_value() const override
|
|
||||||
{
|
|
||||||
|
|
||||||
return private_detail_te_default_to_value(char(0), private_detail_te_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void from_value(const value& v) override
|
|
||||||
{
|
|
||||||
|
|
||||||
private_detail_te_default_from_value(char(0), private_detail_te_value, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
any_ptr get_queue() override
|
|
||||||
{
|
|
||||||
|
|
||||||
return private_detail_te_default_get_queue(char(0), private_detail_te_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void wait_for(any_ptr queue) override
|
|
||||||
{
|
|
||||||
|
|
||||||
private_detail_te_default_wait_for(char(0), private_detail_te_value, queue);
|
|
||||||
}
|
|
||||||
|
|
||||||
void finish_on(any_ptr queue) override
|
|
||||||
{
|
|
||||||
|
|
||||||
private_detail_te_default_finish_on(char(0), private_detail_te_value, queue);
|
|
||||||
}
|
|
||||||
|
|
||||||
void finish() const override { private_detail_te_value.finish(); }
|
|
||||||
|
|
||||||
PrivateDetailTypeErasedT private_detail_te_value;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename PrivateDetailTypeErasedT>
|
|
||||||
struct private_detail_te_handle_type<std::reference_wrapper<PrivateDetailTypeErasedT>>
|
|
||||||
: private_detail_te_handle_type<PrivateDetailTypeErasedT&>
|
|
||||||
{
|
|
||||||
private_detail_te_handle_type(std::reference_wrapper<PrivateDetailTypeErasedT> ref)
|
|
||||||
: private_detail_te_handle_type<PrivateDetailTypeErasedT&>(ref.get())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
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
|
|
||||||
{
|
|
||||||
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()
|
|
||||||
{
|
|
||||||
assert(private_detail_te_handle_mem_var != nullptr);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<private_detail_te_handle_base_type> private_detail_te_handle_mem_var;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ValueType>
|
|
||||||
inline const ValueType* any_cast(const context* x)
|
|
||||||
{
|
|
||||||
return x->any_cast<ValueType>();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ValueType>
|
|
||||||
inline ValueType* any_cast(context* x)
|
|
||||||
{
|
|
||||||
return x->any_cast<ValueType>();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ValueType>
|
|
||||||
inline ValueType& any_cast(context& x)
|
|
||||||
{
|
|
||||||
auto* y = x.any_cast<typename std::remove_reference<ValueType>::type>();
|
|
||||||
if(y == nullptr)
|
|
||||||
throw std::bad_cast();
|
|
||||||
return *y;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ValueType>
|
|
||||||
inline const ValueType& any_cast(const context& x)
|
|
||||||
{
|
|
||||||
const auto* y = x.any_cast<typename std::remove_reference<ValueType>::type>();
|
|
||||||
if(y == nullptr)
|
|
||||||
throw std::bad_cast();
|
|
||||||
return *y;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
inline void migraphx_to_value(value& v, const context& ctx) { v = ctx.to_value(); }
|
|
||||||
|
|
||||||
inline void migraphx_from_value(const value& v, context& ctx) { ctx.from_value(v); }
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,38 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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_MIGRAPHLIB_CONVERT_TO_JSON_HPP
|
|
||||||
#define MIGRAPHX_GUARD_MIGRAPHLIB_CONVERT_TO_JSON_HPP
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
MIGRAPHX_EXPORT std::string convert_to_json(const std::string& str);
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,103 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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_RTGLIB_CONVOLUTION_HPP
|
|
||||||
#define MIGRAPHX_GUARD_RTGLIB_CONVOLUTION_HPP
|
|
||||||
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
#include <migraphx/dfor.hpp>
|
|
||||||
#include <migraphx/par_for.hpp>
|
|
||||||
#include <migraphx/shape_for_each.hpp>
|
|
||||||
#include <migraphx/tensor_view.hpp>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
template <class Output, class T, class Padding, class Stride, class Dilation>
|
|
||||||
void convolution(
|
|
||||||
Output output, T input, T weights, Padding padding, Stride stride, Dilation dilation, int group)
|
|
||||||
{
|
|
||||||
auto output_shape = output.get_shape();
|
|
||||||
auto in_lens = input.get_shape().lens();
|
|
||||||
|
|
||||||
auto wei_lens = weights.get_shape().lens();
|
|
||||||
auto wei_n = wei_lens[0];
|
|
||||||
auto wei_c = wei_lens[1];
|
|
||||||
std::vector<std::size_t> win_size(wei_lens.begin() + 1, wei_lens.end());
|
|
||||||
|
|
||||||
par_for(output_shape.elements(), [&](auto i) {
|
|
||||||
auto idx_o = output_shape.multi(i);
|
|
||||||
auto w = idx_o[1];
|
|
||||||
auto n_dim = idx_o.size();
|
|
||||||
|
|
||||||
std::vector<std::ptrdiff_t> win_start;
|
|
||||||
for(std::size_t dim = 2; dim < n_dim; ++dim)
|
|
||||||
{
|
|
||||||
auto d_2 = dim - 2;
|
|
||||||
win_start.push_back(std::ptrdiff_t(idx_o[dim] * stride[d_2]) -
|
|
||||||
std::ptrdiff_t(padding[d_2]));
|
|
||||||
}
|
|
||||||
const auto group_id = w / (wei_n / group);
|
|
||||||
|
|
||||||
shape win_shape{output_shape.type(), win_size};
|
|
||||||
|
|
||||||
double acc = 0.0;
|
|
||||||
shape_for_each(win_shape, [&](const auto& idx_win) {
|
|
||||||
auto k = idx_win[0];
|
|
||||||
const auto in_ch = group_id * wei_c + k;
|
|
||||||
std::vector<std::ptrdiff_t> idx(idx_o.begin(), idx_o.end());
|
|
||||||
idx[1] = in_ch;
|
|
||||||
std::vector<std::ptrdiff_t> idx_dil(idx_win.size() - 1);
|
|
||||||
std::transform(idx_win.cbegin() + 1,
|
|
||||||
idx_win.cend(),
|
|
||||||
dilation.cbegin(),
|
|
||||||
idx_dil.begin(),
|
|
||||||
[](std::ptrdiff_t ii, std::ptrdiff_t d) { return d * ii; });
|
|
||||||
std::transform(idx_dil.begin(),
|
|
||||||
idx_dil.end(),
|
|
||||||
win_start.begin(),
|
|
||||||
idx.begin() + 2,
|
|
||||||
[](std::ptrdiff_t ii, std::ptrdiff_t jj) { return ii + jj; });
|
|
||||||
std::vector<std::ptrdiff_t> idx_wei(idx_o.size());
|
|
||||||
idx_wei[0] = w;
|
|
||||||
std::copy(idx_win.begin(), idx_win.end(), idx_wei.begin() + 1);
|
|
||||||
if(std::all_of(idx.begin() + 2, idx.end(), [&](auto ii) { return ii >= 0; }) and
|
|
||||||
std::equal(idx.begin(),
|
|
||||||
idx.end(),
|
|
||||||
in_lens.begin(),
|
|
||||||
in_lens.end(),
|
|
||||||
std::less<std::ptrdiff_t>{}))
|
|
||||||
{
|
|
||||||
acc += input(idx.begin(), idx.end()) * weights(idx_wei.begin(), idx_wei.end());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
output[i] = acc;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,63 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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_MIGRAPHX_COPY_ASSIGNABLE_FUNCTION_HPP
|
|
||||||
#define MIGRAPHX_GUARD_MIGRAPHX_COPY_ASSIGNABLE_FUNCTION_HPP
|
|
||||||
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
#include <migraphx/optional.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
template <class F>
|
|
||||||
struct copy_assignable_function_wrapper
|
|
||||||
{
|
|
||||||
optional<F> f;
|
|
||||||
|
|
||||||
copy_assignable_function_wrapper(F pf) : f(std::move(pf)) {}
|
|
||||||
copy_assignable_function_wrapper(const copy_assignable_function_wrapper& other) = default;
|
|
||||||
copy_assignable_function_wrapper(copy_assignable_function_wrapper&& other) noexcept = default;
|
|
||||||
copy_assignable_function_wrapper& operator=(copy_assignable_function_wrapper other)
|
|
||||||
{
|
|
||||||
f.reset();
|
|
||||||
if(other.f.has_value())
|
|
||||||
f.emplace(std::move(*other.f));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... Ts>
|
|
||||||
auto operator()(Ts&&... xs) const -> decltype((*f)(std::forward<Ts>(xs)...))
|
|
||||||
{
|
|
||||||
return (*f)(std::forward<Ts>(xs)...);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class F>
|
|
||||||
using copy_assignable_function =
|
|
||||||
std::conditional_t<std::is_copy_assignable<F>{}, F, copy_assignable_function_wrapper<F>>;
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
#endif // MIGRAPHX_GUARD_MIGRAPHX_COPY_ASSIGNABLE_FUNCTION_HPP
|
|
||||||
@ -1,122 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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_MIGRAPHX_CPP_GENERATOR_HPP
|
|
||||||
#define MIGRAPHX_GUARD_MIGRAPHX_CPP_GENERATOR_HPP
|
|
||||||
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
#include <migraphx/instruction_ref.hpp>
|
|
||||||
#include <string>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <vector>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
struct operation;
|
|
||||||
struct module;
|
|
||||||
struct shape;
|
|
||||||
|
|
||||||
struct cpp_generator_impl;
|
|
||||||
|
|
||||||
struct MIGRAPHX_EXPORT cpp_generator
|
|
||||||
{
|
|
||||||
using generate_module_callback = std::function<std::string(
|
|
||||||
instruction_ref, const std::unordered_map<instruction_ref, std::string>&)>;
|
|
||||||
struct param
|
|
||||||
{
|
|
||||||
std::string name;
|
|
||||||
std::string type;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MIGRAPHX_EXPORT function
|
|
||||||
{
|
|
||||||
std::vector<param> params = {};
|
|
||||||
std::string body = "";
|
|
||||||
std::string return_type = "void";
|
|
||||||
std::string name = "";
|
|
||||||
std::vector<std::string> attributes = {};
|
|
||||||
std::vector<std::string> tparams = {};
|
|
||||||
function& set_body(const module& m, const generate_module_callback& g);
|
|
||||||
function& set_body(const std::string& s)
|
|
||||||
{
|
|
||||||
body = s;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
function& set_name(const std::string& s)
|
|
||||||
{
|
|
||||||
name = s;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
function& set_attributes(std::vector<std::string> attrs)
|
|
||||||
{
|
|
||||||
attributes = std::move(attrs);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
function& set_types(const module& m);
|
|
||||||
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();
|
|
||||||
|
|
||||||
// move constructor
|
|
||||||
cpp_generator(cpp_generator&&) noexcept;
|
|
||||||
|
|
||||||
// copy assignment operator
|
|
||||||
cpp_generator& operator=(cpp_generator rhs);
|
|
||||||
|
|
||||||
~cpp_generator() noexcept;
|
|
||||||
|
|
||||||
void fmap(const std::function<std::string(std::string)>& f);
|
|
||||||
|
|
||||||
void fresult(const std::function<std::string(shape)>& f);
|
|
||||||
|
|
||||||
void always_return_tuple(bool b = true);
|
|
||||||
|
|
||||||
void add_point_op(const std::string& op_name, const std::string& code);
|
|
||||||
|
|
||||||
std::string generate_point_op(const operation& op, const std::vector<std::string>& args);
|
|
||||||
|
|
||||||
std::string str() const;
|
|
||||||
|
|
||||||
function generate_module(const module& m, const generate_module_callback& g);
|
|
||||||
|
|
||||||
function generate_module(const module& m);
|
|
||||||
|
|
||||||
std::string create_function(const function& f);
|
|
||||||
|
|
||||||
static std::vector<std::string>
|
|
||||||
to_args(const std::vector<instruction_ref>& inputs,
|
|
||||||
const std::unordered_map<instruction_ref, std::string>& names);
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::unique_ptr<cpp_generator_impl> impl;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
#endif // MIGRAPHX_GUARD_MIGRAPHX_CPP_GENERATOR_HPP
|
|
||||||
@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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_RTGLIB_DEAD_CODE_ELIMINATION_HPP
|
|
||||||
#define MIGRAPHX_GUARD_RTGLIB_DEAD_CODE_ELIMINATION_HPP
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <migraphx/instruction_ref.hpp>
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
struct module;
|
|
||||||
struct program;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove instructions where the output is not used.
|
|
||||||
*/
|
|
||||||
struct MIGRAPHX_EXPORT dead_code_elimination
|
|
||||||
{
|
|
||||||
std::string name() const { return "dead_code_elimination"; }
|
|
||||||
void apply(module& m) const;
|
|
||||||
void apply(program& p) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,52 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2022 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_MIGRAPHLIB_DFOR_HPP
|
|
||||||
#define MIGRAPHX_GUARD_MIGRAPHLIB_DFOR_HPP
|
|
||||||
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
// Multidimensional for loop
|
|
||||||
inline auto dfor()
|
|
||||||
{
|
|
||||||
return [](auto f) { f(); };
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class... Ts>
|
|
||||||
auto dfor(T x, Ts... xs)
|
|
||||||
{
|
|
||||||
return [=](auto f) {
|
|
||||||
for(T i = 0; i < x; i++)
|
|
||||||
{
|
|
||||||
dfor(xs...)([&](Ts... is) { f(i, is...); });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2024 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_RTGLIB_DOM_INFO_HPP
|
|
||||||
#define MIGRAPHX_GUARD_RTGLIB_DOM_INFO_HPP
|
|
||||||
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
#include <migraphx/instruction.hpp>
|
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
struct module;
|
|
||||||
|
|
||||||
struct MIGRAPHX_EXPORT dominator_info
|
|
||||||
{
|
|
||||||
bool strictly_dominate(instruction_ref ins1, instruction_ref ins2) const;
|
|
||||||
|
|
||||||
std::unordered_map<instruction_ref, instruction_ref> ins2idom;
|
|
||||||
};
|
|
||||||
|
|
||||||
MIGRAPHX_EXPORT dominator_info compute_dominator(const module& m);
|
|
||||||
// MIGRAPHX_EXPORT dominator_info compute_dominator_naive(const module& m);
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,75 +0,0 @@
|
|||||||
/*
|
|
||||||
* The MIT License (MIT)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2022 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_MIGRAPHLIB_DYN_OUTPUT_HPP
|
|
||||||
#define MIGRAPHX_GUARD_MIGRAPHLIB_DYN_OUTPUT_HPP
|
|
||||||
|
|
||||||
#include <migraphx/shape.hpp>
|
|
||||||
#include <migraphx/argument.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
struct dyn_output
|
|
||||||
{
|
|
||||||
// original shape from the instruction
|
|
||||||
shape ins_shape;
|
|
||||||
// shape computed at eval time using input arguments
|
|
||||||
shape computed_shape;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle dynamic and static shape at evaluation time.
|
|
||||||
* If converted to shape type, returns original ins_shape.
|
|
||||||
* If converted to dyn_output type, will compute an output shape using the input arguments.
|
|
||||||
*/
|
|
||||||
template <class F>
|
|
||||||
struct compute_output_shape
|
|
||||||
{
|
|
||||||
F ins_inputs;
|
|
||||||
|
|
||||||
operator dyn_output() const
|
|
||||||
{
|
|
||||||
return ins_inputs([](const auto& x, shape ins_shape, const std::vector<argument>& inputs) {
|
|
||||||
if(ins_shape.dynamic())
|
|
||||||
return dyn_output{ins_shape, compute_shape(x, to_shapes(inputs))};
|
|
||||||
return dyn_output{ins_shape, ins_shape};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
operator shape() const
|
|
||||||
{
|
|
||||||
return ins_inputs(
|
|
||||||
[](const auto&, shape ins_shape, const std::vector<argument>&) { return ins_shape; });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class F>
|
|
||||||
compute_output_shape<F> make_compute_output_shape(F f)
|
|
||||||
{
|
|
||||||
return {f};
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
#endif
|
|
||||||
@ -1,75 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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_MIGRAPHX_DYNAMIC_LOADER_HPP
|
|
||||||
#define MIGRAPHX_GUARD_MIGRAPHX_DYNAMIC_LOADER_HPP
|
|
||||||
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
#include <migraphx/filesystem.hpp>
|
|
||||||
#include <migraphx/optional.hpp>
|
|
||||||
#include <functional>
|
|
||||||
#include <memory>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
struct dynamic_loader_impl;
|
|
||||||
|
|
||||||
struct MIGRAPHX_EXPORT dynamic_loader
|
|
||||||
{
|
|
||||||
template <class T>
|
|
||||||
static fs::path path(T* address)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
|
|
||||||
dynamic_loader(const char* image, std::size_t size);
|
|
||||||
|
|
||||||
dynamic_loader(const std::vector<char>& buffer);
|
|
||||||
|
|
||||||
std::shared_ptr<void> get_symbol(const std::string& name) const;
|
|
||||||
|
|
||||||
template <class F>
|
|
||||||
std::function<F> get_function(const std::string& name) const
|
|
||||||
{
|
|
||||||
auto s = get_symbol(name);
|
|
||||||
return [=](auto&&... xs) -> decltype(auto) {
|
|
||||||
auto f = reinterpret_cast<std::add_pointer_t<F>>(s.get());
|
|
||||||
return f(std::forward<decltype(xs)>(xs)...);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::shared_ptr<dynamic_loader_impl> impl;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
#endif // MIGRAPHX_GUARD_MIGRAPHX_DYNAMIC_LOADER_HPP
|
|
||||||
@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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_RTGLIB_ELIMINATE_ALLOCATION_HPP
|
|
||||||
#define MIGRAPHX_GUARD_RTGLIB_ELIMINATE_ALLOCATION_HPP
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <migraphx/instruction_ref.hpp>
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
struct module;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove memory allocations. This will create a parameter which is the max of all memory used in
|
|
||||||
* the program.
|
|
||||||
*/
|
|
||||||
struct MIGRAPHX_EXPORT eliminate_allocation
|
|
||||||
{
|
|
||||||
std::string allocation_op{};
|
|
||||||
std::size_t alignment = 32;
|
|
||||||
std::string name() const { return "eliminate_allocation"; }
|
|
||||||
void apply(module& m) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,48 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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_RTGLIB_COMMON_SUBEXPRESSION_ELIMINATION_HPP
|
|
||||||
#define MIGRAPHX_GUARD_RTGLIB_COMMON_SUBEXPRESSION_ELIMINATION_HPP
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <migraphx/instruction_ref.hpp>
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
struct module;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove identical instructions.
|
|
||||||
*/
|
|
||||||
struct MIGRAPHX_EXPORT eliminate_common_subexpression
|
|
||||||
{
|
|
||||||
std::string name() const { return "eliminate_common_subexpression"; }
|
|
||||||
void apply(module& m) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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_RTGLIB_ELIMINATE_CONCAT_HPP
|
|
||||||
#define MIGRAPHX_GUARD_RTGLIB_ELIMINATE_CONCAT_HPP
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <migraphx/instruction_ref.hpp>
|
|
||||||
#include <migraphx/concat_opt.hpp>
|
|
||||||
#include <migraphx/config.hpp>
|
|
||||||
|
|
||||||
namespace migraphx {
|
|
||||||
inline namespace MIGRAPHX_INLINE_NS {
|
|
||||||
|
|
||||||
struct module;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove concat operators by having each operator can write to different chunk of memory.
|
|
||||||
*/
|
|
||||||
struct MIGRAPHX_EXPORT eliminate_concat
|
|
||||||
{
|
|
||||||
concat_optimization concat_opt;
|
|
||||||
std::string name() const { return "eliminate_concat"; }
|
|
||||||
void apply(module& m) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace MIGRAPHX_INLINE_NS
|
|
||||||
} // namespace migraphx
|
|
||||||
|
|
||||||
#endif
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user