Unverified Commit 818e6e53 authored by Paul Fultz II's avatar Paul Fultz II Committed by GitHub
Browse files

Merge branch 'develop' into mlir-c

parents d716c516 cb18b0b5
...@@ -44,7 +44,7 @@ struct shape ...@@ -44,7 +44,7 @@ struct shape
constexpr auto element_space() const { return _c<Strides{}.dot(Lens{} - 1) + 1>; } constexpr auto element_space() const { return _c<Strides{}.dot(Lens{} - 1) + 1>; }
constexpr auto packed() const { return elements() == element_space(); } constexpr auto packed() const { return not skips() and elements() == element_space(); }
constexpr auto broadcasted() const { return _c<Strides{}.product() == 0>; } constexpr auto broadcasted() const { return _c<Strides{}.product() == 0>; }
constexpr auto transposed() const constexpr auto transposed() const
{ {
...@@ -53,16 +53,9 @@ struct shape ...@@ -53,16 +53,9 @@ struct shape
if(shape{}.broadcasted()) if(shape{}.broadcasted())
{ {
index_array s{}; index_array s{};
index_int j = 0; auto out = copy_if(
for(index_int i = 0; i < s.size(); i++) lstrides.begin(), lstrides.end(), s.begin(), [](auto x) { return x != 0; });
{ return not is_sorted(s.begin(), out, greater{});
if(lstrides[i] != 0)
{
s[j] = lstrides[i];
j++;
}
}
return not is_sorted(s.begin(), s.begin() + j, greater{});
} }
else else
{ {
...@@ -70,6 +63,13 @@ struct shape ...@@ -70,6 +63,13 @@ struct shape
} }
}); });
} }
constexpr auto skips() const
{
return return_c([] {
auto lstrides = Strides{};
return none_of(lstrides.begin(), lstrides.end(), [](auto x) { return x == 1; });
});
}
constexpr auto standard() const { return packed() and not transposed(); } constexpr auto standard() const { return packed() and not transposed(); }
...@@ -86,26 +86,34 @@ struct shape ...@@ -86,26 +86,34 @@ struct shape
constexpr index_int index(index_int i) const constexpr index_int index(index_int i) const
{ {
if(this->standard()) if(this->standard())
{
MIGRAPHX_ASSERT(i == compute_index(i));
return i; return i;
}
else else
{ {
const auto rank = this->lens.size(); return compute_index(i);
index_int s = 1;
index_int result = 0;
for(index_int j = 0; j < rank; j++)
{
const index_int k = rank - j - 1;
const index_int stride = this->strides[k];
const index_int len = this->lens[k];
const index_int slen = s * len;
const index_int idx = (i % slen) / s;
result += stride * idx;
s = slen;
}
return result;
} }
} }
constexpr index_int compute_index(index_int i) const
{
const auto rank = this->lens.size();
index_int s = 1;
index_int result = 0;
for(index_int j = 0; j < rank; j++)
{
const index_int k = rank - j - 1;
const index_int stride = this->strides[k];
const index_int len = this->lens[k];
const index_int slen = s * len;
const index_int idx = (i % slen) / s;
result += stride * idx;
s = slen;
}
return result;
}
/// Convert single index into a multi-index /// Convert single index into a multi-index
constexpr index_array multi(index_int idx) const constexpr index_array multi(index_int idx) const
{ {
......
...@@ -53,7 +53,6 @@ ...@@ -53,7 +53,6 @@
#include <migraphx/gpu/compile_ops.hpp> #include <migraphx/gpu/compile_ops.hpp>
#include <migraphx/gpu/concat_gpu_opt.hpp> #include <migraphx/gpu/concat_gpu_opt.hpp>
#include <migraphx/gpu/context.hpp> #include <migraphx/gpu/context.hpp>
#include <migraphx/gpu/eliminate_workspace.hpp>
#include <migraphx/gpu/fuse_mlir.hpp> #include <migraphx/gpu/fuse_mlir.hpp>
#include <migraphx/gpu/fuse_ops.hpp> #include <migraphx/gpu/fuse_ops.hpp>
#include <migraphx/gpu/prefuse_ops.hpp> #include <migraphx/gpu/prefuse_ops.hpp>
...@@ -152,7 +151,6 @@ std::vector<pass> target::get_passes(migraphx::context& gctx, const compile_opti ...@@ -152,7 +151,6 @@ std::vector<pass> target::get_passes(migraphx::context& gctx, const compile_opti
sync_device{}, sync_device{},
preallocate_param{"scratch", gpu_allocation_model{}}, preallocate_param{"scratch", gpu_allocation_model{}},
dead_code_elimination{}, dead_code_elimination{},
eliminate_workspace{},
eliminate_allocation{"hip::allocate"}, eliminate_allocation{"hip::allocate"},
check_context<context>{}, check_context<context>{},
normalize_ops{}, normalize_ops{},
......
...@@ -34,16 +34,18 @@ endfunction() ...@@ -34,16 +34,18 @@ endfunction()
add_api_test(array_base test_array_base.cpp ${TEST_ONNX_DIR}) add_api_test(array_base test_array_base.cpp ${TEST_ONNX_DIR})
add_api_test(assign test_assign.cpp ${TEST_ONNX_DIR}) add_api_test(assign test_assign.cpp ${TEST_ONNX_DIR})
add_api_test(custom_op test_custom_op.cpp ${TEST_ONNX_DIR})
add_api_test(compile_options test_compile_options.cpp ${TEST_ONNX_DIR}) add_api_test(compile_options test_compile_options.cpp ${TEST_ONNX_DIR})
add_api_test(lookup test_lookup.cpp ${TEST_ONNX_DIR}) add_api_test(lookup test_lookup.cpp ${TEST_ONNX_DIR})
add_api_test(module_construct test_module_construct.cpp ${TEST_ONNX_DIR}) add_api_test(module_construct test_module_construct.cpp ${TEST_ONNX_DIR})
add_api_test(ref test_cpu.cpp ${TEST_ONNX_DIR}) add_api_test(ref test_cpu.cpp ${TEST_ONNX_DIR})
add_api_test(save_load test_save_load.cpp ${TEST_ONNX_DIR}) add_api_test(save_load test_save_load.cpp ${TEST_ONNX_DIR})
add_api_test(op test_op_construct.cpp ${TEST_ONNX_DIR}) add_api_test(op test_op_construct.cpp ${TEST_ONNX_DIR})
add_api_test(custom_op test_custom_op.cpp ${TEST_ONNX_DIR})
add_api_test(tf_parser test_tf_parser.cpp ${TEST_TF_DIR}) add_api_test(tf_parser test_tf_parser.cpp ${TEST_TF_DIR})
# GPU-based tests # GPU-based tests
if(MIGRAPHX_ENABLE_GPU) if(MIGRAPHX_ENABLE_GPU)
add_api_test(gpu test_gpu.cpp ${TEST_ONNX_DIR}) add_api_test(gpu test_gpu.cpp ${TEST_ONNX_DIR})
target_link_libraries(test_api_gpu migraphx_gpu) target_link_libraries(test_api_gpu migraphx_gpu)
add_api_test(custom_op_gpu test_custom_op_gpu.cpp ${TEST_ONNX_DIR})
target_link_libraries(test_api_custom_op_gpu migraphx_gpu)
endif() endif()
...@@ -21,26 +21,66 @@ ...@@ -21,26 +21,66 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#include <algorithm>
#include <cmath>
#include <migraphx/migraphx.h> #include <migraphx/migraphx.h>
#include <migraphx/migraphx.hpp> #include <migraphx/migraphx.hpp>
#include "test.hpp" #include "test.hpp"
struct simple_custom_op final : migraphx::experimental_custom_op_base struct sigmoid_custom_op final : migraphx::experimental_custom_op_base
{ {
virtual std::string name() const override { return "simple_custom_op"; } virtual std::string name() const override { return "sigmoid_custom_op"; }
virtual migraphx::argument
compute(migraphx::context, migraphx::shape, migraphx::arguments inputs) const override
{
auto* output_ptr = reinterpret_cast<float*>(inputs[1].data());
auto input_vec = inputs[0].as_vector<float>();
std::transform(input_vec.begin(), input_vec.end(), output_ptr, [](auto x) {
return 1.f / (1.f + std::exp(-x));
});
return inputs[1];
}
virtual migraphx::shape compute_shape(migraphx::shapes inputs) const override virtual migraphx::shape compute_shape(migraphx::shapes inputs) const override
{ {
return inputs.front(); CHECK(inputs.size() == 2);
CHECK(inputs[0].lengths().size() == 1);
CHECK(inputs[0].type() == migraphx_shape_float_type);
CHECK(bool{inputs[0] == inputs[1]});
return inputs.back();
} }
}; };
TEST_CASE(register_custom_op) TEST_CASE(register_custom_op)
{ {
simple_custom_op simple_op; sigmoid_custom_op sigmoid_op;
migraphx::register_experimental_custom_op(simple_op); migraphx::register_experimental_custom_op(sigmoid_op);
auto op = migraphx::operation("sigmoid_custom_op");
EXPECT(op.name() == "sigmoid_custom_op");
}
auto op = migraphx::operation("simple_custom_op"); TEST_CASE(run_sigmoid_custom_op)
EXPECT(op.name() == "simple_custom_op"); {
migraphx::program p;
migraphx::shape s{migraphx_shape_float_type, {12}};
migraphx::module m = p.get_main_module();
auto x = m.add_parameter("x", s);
auto alloc = m.add_allocation(s);
auto custom_kernel = m.add_instruction(migraphx::operation("sigmoid_custom_op"), {x, alloc});
p.compile(migraphx::target("ref"));
// run program
migraphx::program_parameters pp;
auto param_shapes = p.get_parameter_shapes();
migraphx::argument input_arg = migraphx::argument::generate(param_shapes["x"]);
pp.add("x", input_arg);
auto results = p.eval(pp);
auto result = results[0];
auto expected_result = input_arg.as_vector<float>();
std::transform(expected_result.begin(),
expected_result.end(),
expected_result.begin(),
[](auto y) { return 1.f / (1.f + std::exp(-y)); });
EXPECT(bool{result == migraphx::argument(s, expected_result.data())});
} }
int main(int argc, const char* argv[]) { test::run(argc, argv); } int main(int argc, const char* argv[]) { test::run(argc, argv); }
...@@ -21,47 +21,68 @@ ...@@ -21,47 +21,68 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#include <migraphx/gpu/eliminate_workspace.hpp> #include <hip/hip_runtime_api.h>
#include <migraphx/gpu/hip.hpp> #include <migraphx/migraphx.h>
#include <migraphx/program.hpp> #include <migraphx/migraphx.hpp>
#include <migraphx/instruction.hpp> #include "test.hpp"
#include <migraphx/iterator_for.hpp>
#include <migraphx/ranges.hpp>
#include <migraphx/stringutils.hpp>
#include <migraphx/pass_config.hpp>
namespace migraphx { #define MIGRAPHX_HIP_ASSERT(x) (EXPECT(x == hipSuccess))
inline namespace MIGRAPHX_INLINE_NS { struct simple_custom_op final : migraphx::experimental_custom_op_base
namespace gpu {
void eliminate_workspace::apply(module& m) const
{ {
std::size_t n = 0; virtual std::string name() const override { return "simple_custom_op"; }
std::vector<instruction_ref> allocs; virtual migraphx::argument
for(auto ins : iterator_for(m)) compute(migraphx::context ctx, migraphx::shape, migraphx::arguments inputs) const override
{ {
if(ins->outputs().size() != 1) // sets first half size_bytes of the input 0, and rest of the half bytes are copied.
continue; int* h_output = nullptr;
if(ins->name() != "hip::allocate") auto* d_output = reinterpret_cast<int*>(inputs[0].data());
continue; auto input_bytes = inputs[0].get_shape().bytes();
auto&& a = any_cast<hip_allocate>(ins->get_operator()); auto* output_ptr = inputs[1].data();
if(a.tag == "workspace") auto copy_bytes = input_bytes / 2;
{ MIGRAPHX_HIP_ASSERT(hipSetDevice(0));
n = std::max(n, ins->get_shape().bytes()); MIGRAPHX_HIP_ASSERT(hipHostMalloc(&h_output, input_bytes));
allocs.push_back(ins); MIGRAPHX_HIP_ASSERT(hipMemcpyAsync(
} h_output, d_output, input_bytes, hipMemcpyDeviceToHost, ctx.get_queue<hipStream_t>()));
MIGRAPHX_HIP_ASSERT(hipDeviceSynchronize());
MIGRAPHX_HIP_ASSERT(hipMemset(h_output, 0, copy_bytes));
MIGRAPHX_HIP_ASSERT(hipDeviceSynchronize());
MIGRAPHX_HIP_ASSERT(hipMemcpy(output_ptr, h_output, input_bytes, hipMemcpyHostToDevice));
MIGRAPHX_HIP_ASSERT(hipDeviceSynchronize());
MIGRAPHX_HIP_ASSERT(hipHostFree(h_output));
return inputs[1];
} }
if(n > 0)
virtual migraphx::shape compute_shape(migraphx::shapes inputs) const override
{ {
auto ws = m.add_parameter("workspace", shape{shape::int8_type, {n}}); return inputs.back();
for(auto&& a : allocs)
{
m.replace_instruction(a, ws);
m.remove_instruction(a);
}
} }
};
TEST_CASE(run_simple_custom_op)
{
simple_custom_op simple_op;
migraphx::register_experimental_custom_op(simple_op);
migraphx::program p;
migraphx::shape s{migraphx_shape_int32_type, {4, 3}};
migraphx::module m = p.get_main_module();
auto x = m.add_parameter("x", s);
auto neg = m.add_instruction(migraphx::operation("neg"), x);
auto alloc = m.add_allocation(s);
auto custom_kernel = m.add_instruction(migraphx::operation("simple_custom_op"), {neg, alloc});
auto relu = m.add_instruction(migraphx::operation("relu"), custom_kernel);
m.add_return({relu});
migraphx::compile_options options;
options.set_offload_copy();
p.compile(migraphx::target("gpu"), options);
migraphx::program_parameters pp;
std::vector<int> x_data(12, -3);
pp.add("x", migraphx::argument(s, x_data.data()));
auto results = p.eval(pp);
auto result = results[0];
auto result_vec = result.as_vector<int>();
std::vector<int> expected_result(12, 0);
std::fill(expected_result.begin() + 6, expected_result.end(), 3);
EXPECT(bool{result == migraphx::argument(s, expected_result.data())});
} }
} // namespace gpu int main(int argc, const char* argv[]) { test::run(argc, argv); }
} // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx
...@@ -92,13 +92,7 @@ TEST_CASE(if_pl_test) ...@@ -92,13 +92,7 @@ TEST_CASE(if_pl_test)
auto outputs = p.eval(pp); auto outputs = p.eval(pp);
auto output = outputs[0]; auto output = outputs[0];
auto lens = output.get_shape().lengths(); return output.as_vector<float>();
auto elem_num =
std::accumulate(lens.begin(), lens.end(), 1, std::multiplies<std::size_t>());
float* data_ptr = reinterpret_cast<float*>(output.data());
std::vector<float> ret(data_ptr, data_ptr + elem_num);
return ret;
}; };
// then branch // then branch
...@@ -141,18 +135,11 @@ TEST_CASE(loop_test) ...@@ -141,18 +135,11 @@ TEST_CASE(loop_test)
auto outputs = p.eval(pp); auto outputs = p.eval(pp);
auto output = outputs[0]; auto output = outputs[0];
auto lens = output.get_shape().lengths();
auto elem_num =
std::accumulate(lens.begin(), lens.end(), 1, std::multiplies<std::size_t>());
float* data_ptr = reinterpret_cast<float*>(output.data());
std::vector<std::vector<float>> ret; std::vector<std::vector<float>> ret;
ret.push_back({data_ptr, data_ptr + elem_num}); ret.push_back(output.as_vector<float>());
output = outputs[1]; output = outputs[1];
lens = output.get_shape().lengths(); ret.push_back(output.as_vector<float>());
elem_num = std::accumulate(lens.begin(), lens.end(), 1, std::multiplies<std::size_t>());
data_ptr = reinterpret_cast<float*>(output.data());
ret.push_back({data_ptr, data_ptr + elem_num});
return ret; return ret;
}; };
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
*/ */
#include <migraphx/reduce_dims.hpp> #include <migraphx/reduce_dims.hpp>
#include <migraphx/permutation.hpp> #include <migraphx/permutation.hpp>
#include <migraphx/ranges.hpp>
#include "test.hpp" #include "test.hpp"
migraphx::shape make_shape(std::vector<std::size_t> lens) migraphx::shape make_shape(std::vector<std::size_t> lens)
...@@ -35,6 +36,21 @@ migraphx::shape make_shape(std::vector<std::size_t> lens, std::vector<std::size_ ...@@ -35,6 +36,21 @@ migraphx::shape make_shape(std::vector<std::size_t> lens, std::vector<std::size_
return {migraphx::shape::float_type, std::move(lens), std::move(strides)}; return {migraphx::shape::float_type, std::move(lens), std::move(strides)};
} }
bool verify_shape(const migraphx::shape& s1, const migraphx::shape& s2)
{
if(s1.elements() != s2.elements())
return false;
return migraphx::all_of(migraphx::range(s1.elements()),
[&](auto i) { return s1.index(i) == s2.index(i); });
}
template <class Range1, class Range2>
bool verify_shapes(const Range1& r1, const Range2& r2)
{
return migraphx::equal(
r1, r2, [](const auto& s1, const auto& s2) { return verify_shape(s1, s2); });
}
TEST_CASE(same_standard) TEST_CASE(same_standard)
{ {
auto is = make_shape({64, 3, 7, 7}); auto is = make_shape({64, 3, 7, 7});
...@@ -42,7 +58,7 @@ TEST_CASE(same_standard) ...@@ -42,7 +58,7 @@ TEST_CASE(same_standard)
std::vector<migraphx::shape> ishapes = {is, is, is}; std::vector<migraphx::shape> ishapes = {is, is, is};
std::vector<migraphx::shape> eshapes = {os, os, os}; std::vector<migraphx::shape> eshapes = {os, os, os};
auto rshapes = migraphx::reduce_dims(ishapes); auto rshapes = migraphx::reduce_dims(ishapes);
EXPECT(verify_shapes(ishapes, rshapes));
EXPECT(eshapes == rshapes); EXPECT(eshapes == rshapes);
} }
...@@ -53,7 +69,7 @@ TEST_CASE(same_broadcast1) ...@@ -53,7 +69,7 @@ TEST_CASE(same_broadcast1)
std::vector<migraphx::shape> ishapes = {is, make_shape({64, 3, 7, 7}, {0, 1, 0, 0}), is}; std::vector<migraphx::shape> ishapes = {is, make_shape({64, 3, 7, 7}, {0, 1, 0, 0}), is};
std::vector<migraphx::shape> eshapes = {os, make_shape({64, 3, 7 * 7}, {0, 1, 0}), os}; std::vector<migraphx::shape> eshapes = {os, make_shape({64, 3, 7 * 7}, {0, 1, 0}), os};
auto rshapes = migraphx::reduce_dims(ishapes); auto rshapes = migraphx::reduce_dims(ishapes);
EXPECT(verify_shapes(ishapes, rshapes));
EXPECT(eshapes == rshapes); EXPECT(eshapes == rshapes);
} }
...@@ -64,7 +80,7 @@ TEST_CASE(same_broadcast2) ...@@ -64,7 +80,7 @@ TEST_CASE(same_broadcast2)
std::vector<migraphx::shape> ishapes = {is, make_shape({64, 3, 8, 7, 7}, {0, 8, 1, 0, 0}), is}; std::vector<migraphx::shape> ishapes = {is, make_shape({64, 3, 8, 7, 7}, {0, 8, 1, 0, 0}), is};
std::vector<migraphx::shape> eshapes = {os, make_shape({64, 8 * 3, 7 * 7}, {0, 1, 0}), os}; std::vector<migraphx::shape> eshapes = {os, make_shape({64, 8 * 3, 7 * 7}, {0, 1, 0}), os};
auto rshapes = migraphx::reduce_dims(ishapes); auto rshapes = migraphx::reduce_dims(ishapes);
EXPECT(verify_shapes(ishapes, rshapes));
EXPECT(eshapes == rshapes); EXPECT(eshapes == rshapes);
} }
...@@ -75,7 +91,7 @@ TEST_CASE(same_transposed) ...@@ -75,7 +91,7 @@ TEST_CASE(same_transposed)
std::vector<migraphx::shape> ishapes = {is, migraphx::reorder_shape(is, {0, 1, 3, 2}), is}; std::vector<migraphx::shape> ishapes = {is, migraphx::reorder_shape(is, {0, 1, 3, 2}), is};
std::vector<migraphx::shape> eshapes = {os, migraphx::reorder_shape(os, {0, 2, 1}), os}; std::vector<migraphx::shape> eshapes = {os, migraphx::reorder_shape(os, {0, 2, 1}), os};
auto rshapes = migraphx::reduce_dims(ishapes); auto rshapes = migraphx::reduce_dims(ishapes);
EXPECT(verify_shapes(ishapes, rshapes));
EXPECT(eshapes == rshapes); EXPECT(eshapes == rshapes);
} }
...@@ -86,7 +102,7 @@ TEST_CASE(different_masked1) ...@@ -86,7 +102,7 @@ TEST_CASE(different_masked1)
std::vector<migraphx::shape> ishapes = {is, make_shape({1, 3, 1, 1}), is}; std::vector<migraphx::shape> ishapes = {is, make_shape({1, 3, 1, 1}), is};
std::vector<migraphx::shape> eshapes = {os, make_shape({1, 3, 1}), os}; std::vector<migraphx::shape> eshapes = {os, make_shape({1, 3, 1}), os};
auto rshapes = migraphx::reduce_dims(ishapes); auto rshapes = migraphx::reduce_dims(ishapes);
EXPECT(verify_shapes(ishapes, rshapes));
EXPECT(eshapes == rshapes); EXPECT(eshapes == rshapes);
} }
...@@ -98,7 +114,7 @@ TEST_CASE(different_masked2) ...@@ -98,7 +114,7 @@ TEST_CASE(different_masked2)
is, make_shape({1, 3, 1, 1}), make_shape({64, 1, 7, 7})}; is, make_shape({1, 3, 1, 1}), make_shape({64, 1, 7, 7})};
std::vector<migraphx::shape> eshapes = {os, make_shape({1, 3, 1}), make_shape({64, 1, 7 * 7})}; std::vector<migraphx::shape> eshapes = {os, make_shape({1, 3, 1}), make_shape({64, 1, 7 * 7})};
auto rshapes = migraphx::reduce_dims(ishapes); auto rshapes = migraphx::reduce_dims(ishapes);
EXPECT(verify_shapes(ishapes, rshapes));
EXPECT(eshapes == rshapes); EXPECT(eshapes == rshapes);
} }
...@@ -128,7 +144,7 @@ TEST_CASE(transposed1) ...@@ -128,7 +144,7 @@ TEST_CASE(transposed1)
std::vector<migraphx::shape> eshapes = { std::vector<migraphx::shape> eshapes = {
make_shape({8, 28, 4, 56 * 56}), make_shape({8, 28, 4, 56 * 56}, {351232, 3136, 87808, 1})}; make_shape({8, 28, 4, 56 * 56}), make_shape({8, 28, 4, 56 * 56}, {351232, 3136, 87808, 1})};
auto rshapes = migraphx::reduce_dims(ishapes); auto rshapes = migraphx::reduce_dims(ishapes);
EXPECT(verify_shapes(ishapes, rshapes));
EXPECT(eshapes == rshapes); EXPECT(eshapes == rshapes);
} }
...@@ -137,6 +153,7 @@ TEST_CASE(non_packed_empty1) ...@@ -137,6 +153,7 @@ TEST_CASE(non_packed_empty1)
std::vector<migraphx::shape> ishapes = {make_shape({1, 12}, {589824, 64})}; std::vector<migraphx::shape> ishapes = {make_shape({1, 12}, {589824, 64})};
std::vector<migraphx::shape> eshapes = {make_shape({12}, {64})}; std::vector<migraphx::shape> eshapes = {make_shape({12}, {64})};
auto rshapes = migraphx::reduce_dims(ishapes); auto rshapes = migraphx::reduce_dims(ishapes);
EXPECT(verify_shapes(ishapes, rshapes));
EXPECT(eshapes == rshapes); EXPECT(eshapes == rshapes);
} }
...@@ -145,6 +162,7 @@ TEST_CASE(non_packed_empty2) ...@@ -145,6 +162,7 @@ TEST_CASE(non_packed_empty2)
std::vector<migraphx::shape> ishapes = {make_shape({12, 1}, {64, 589824})}; std::vector<migraphx::shape> ishapes = {make_shape({12, 1}, {64, 589824})};
std::vector<migraphx::shape> eshapes = {make_shape({12}, {64})}; std::vector<migraphx::shape> eshapes = {make_shape({12}, {64})};
auto rshapes = migraphx::reduce_dims(ishapes); auto rshapes = migraphx::reduce_dims(ishapes);
EXPECT(verify_shapes(ishapes, rshapes));
EXPECT(eshapes == rshapes); EXPECT(eshapes == rshapes);
} }
...@@ -155,6 +173,16 @@ TEST_CASE(single_dim) ...@@ -155,6 +173,16 @@ TEST_CASE(single_dim)
EXPECT(ishapes == rshapes); EXPECT(ishapes == rshapes);
} }
TEST_CASE(step_broadcast_transpose)
{
std::vector<migraphx::shape> ishapes = {make_shape({1, 2, 2, 1}, {0, 0, 3, 6}),
make_shape({1, 2, 2, 1}, {4, 2, 1, 1})};
std::vector<migraphx::shape> eshapes = {make_shape({2, 2}, {0, 3}), make_shape({2, 2}, {2, 1})};
auto rshapes = migraphx::reduce_dims(ishapes);
EXPECT(verify_shapes(ishapes, rshapes));
EXPECT(eshapes == rshapes);
}
TEST_CASE(empty) TEST_CASE(empty)
{ {
auto rshapes = migraphx::reduce_dims({}); auto rshapes = migraphx::reduce_dims({});
......
...@@ -200,6 +200,15 @@ TEST_CASE(test_shape_broadcasted5) ...@@ -200,6 +200,15 @@ TEST_CASE(test_shape_broadcasted5)
EXPECT(s.broadcasted()); EXPECT(s.broadcasted());
} }
TEST_CASE(test_shape_step_broadcasted)
{
migraphx::shape s{migraphx::shape::float_type, {2, 2}, {0, 3}};
EXPECT(not s.standard());
EXPECT(not s.packed());
EXPECT(not s.transposed());
EXPECT(s.broadcasted());
}
TEST_CASE(test_shape_default_copy) TEST_CASE(test_shape_default_copy)
{ {
migraphx::shape s1{}; migraphx::shape s1{};
......
...@@ -236,6 +236,11 @@ void print_program(const program& p) { std::cout << p << std::endl; } ...@@ -236,6 +236,11 @@ void print_program(const program& p) { std::cout << p << std::endl; }
void print_module(const module& m) { std::cout << m << std::endl; } void print_module(const module& m) { std::cout << m << std::endl; }
migraphx::instruction_ref add_allocation(module& m, const migraphx::shape& s)
{
return m.add_instruction(migraphx::make_op("allocate", {{"shape", migraphx::to_value(s)}}), {});
}
struct experimental_custom_op struct experimental_custom_op
{ {
std::string name; std::string name;
...@@ -260,7 +265,12 @@ struct custom_operation ...@@ -260,7 +265,12 @@ struct custom_operation
return op.compute_shape(std::move(inputs)); return op.compute_shape(std::move(inputs));
} }
argument compute(const std::vector<argument>&) const { MIGRAPHX_THROW("Not computable"); } // TODO: Compute method with module_args
argument
compute(migraphx::context ctx, migraphx::shape output_shape, std::vector<argument> inputs) const
{
return op.compute(std::move(ctx), std::move(output_shape), std::move(inputs));
}
}; };
template <class CustomOp> template <class CustomOp>
......
#!/usr/bin/env python3
#####################################################################################
# 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.
#####################################################################################
import subprocess
import sys
debug = False
# The filetypes we want to check for that are stamped
# LICENSE is included here as it SHOULD have a liscence in it otherwise flag it as unstamped
supported_file_types = (".cpp", ".hpp", ".h", ".ipynb", ".py", ".txt", ".sh",
".bsh", "LICENSE", ".cmake")
#add general stuff we shouldn't stamp and any exceptions here
unsupported_file_types = [
".onnx", ".pb", ".rst", ".jpg", ".jpeg", ".proto", ".md", ".clang",
".weight", ".ini", ".json", ".docker", ".git", ".rules", ".yml"
]
specificIgnores = ("digits.txt", "Dockerfile", "Jenkinsfile", "")
def hasKeySequence(inputfile, key_message):
result = False
if key_message in inputfile:
result = True
return result
#Simple just open and write stuff to each file with the license stamp
def openAndCheckFile(filename):
result = False
#open save old contents and append things here
if debug is True:
print("Open", filename, end='')
try:
file = open(filename, 'r')
except OSError as e:
if debug is True:
print(str(e) + "....Open Error: Skipping file ")
file.close()
return
else:
with file as contents:
try:
save = contents.read()
hasAmdLic = hasKeySequence(
save, "Advanced Micro Devices, Inc. All rights reserved")
#Check if we have a licence stamp already
if hasAmdLic is True:
if debug is True:
print("....Already Stamped: Skipping file ")
contents.close()
result = True
except UnicodeDecodeError as eu:
if debug is True:
print(str(eu) + "...Skipping binary file ")
contents.close()
result = True
return result
# Deterine if filename is desired in the fileTuple past in
def check_filename(filename, fileTuple):
supported = False
for key in fileTuple:
if key in filename:
supported = True
break
return supported
def main():
unsupported_file_types.extend(specificIgnores)
#Get a list of all the tracked files in our git repo
proc = subprocess.run("git ls-files --exclude-standard",
shell=True,
stdout=subprocess.PIPE)
fileList = proc.stdout.decode().split('\n')
if debug is True:
print("Target file list:\n" + str(fileList))
unsupportedFiles = []
unstampedFiles = []
unknownFiles = []
for file in fileList:
supported = check_filename(file, supported_file_types)
if supported is True:
isStamped = openAndCheckFile(file)
if isStamped is False:
unstampedFiles.append(file)
else:
unsupported = check_filename(file, unsupported_file_types)
if unsupported is True:
unsupportedFiles.append(file)
else:
unknownFiles.append(file)
#Do a bunch of checks based on our file lists
if len(unstampedFiles) > 0:
print("Error: The following " + str(len(unstampedFiles)) +
" files are currently without a license:")
print(str(unstampedFiles))
sys.exit(1)
if len(unknownFiles) > 0:
print("Error: The following " + str(len(unknownFiles)) +
" files not handled:")
print(str(unknownFiles))
sys.exit(2)
sys.exit(0)
if __name__ == "__main__":
main()
...@@ -32,32 +32,28 @@ debug = False ...@@ -32,32 +32,28 @@ debug = False
def getipynb_markdownBlockAsList(): def getipynb_markdownBlockAsList():
markdownBlock = [ markdownBlock = [
'\t{\n' '\t{\n'
'\t\t"cell_type": "code",\n', '\t\t"cell_type": "code",\n', '\t\t"execution_count": null,\n',
'\t\t"metadata": {},\n', '\t\t"metadata": {},\n', '\t\t"outputs": [],\n', '\t\t"source": [\n',
'\t\t"source": [\n', '\t\t\t\"# The MIT License (MIT)\\n\",\n', '\t\t\t\"#\\n\",\n',
'\t\t\t\"# The MIT License (MIT)\",\n', '\t\t\t\"# Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved.\\n\",\n',
'\t\t\t\"#\",\n', '\t\t\t\"#\\n\",\n',
'\t\t\t\"# Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved.\",\n', '\t\t\t\"# Permission is hereby granted, free of charge, to any person obtaining a copy\\n\",\n',
'\t\t\t\"#\",\n', '\t\t\t\"# of this software and associated documentation files (the \'Software\'), to deal\\n\",\n',
'\t\t\t\"# Permission is hereby granted, free of charge, to any person obtaining a copy\",\n', '\t\t\t\"# in the Software without restriction, including without limitation the rights\\n\",\n',
'\t\t\t\"# of this software and associated documentation files (the \'Software\'), to deal\",\n', '\t\t\t\"# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n\",\n',
'\t\t\t\"# in the Software without restriction, including without limitation the rights\",\n', '\t\t\t\"# copies of the Software, and to permit persons to whom the Software is\\n\",\n',
'\t\t\t\"# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\",\n', '\t\t\t\"# furnished to do so, subject to the following conditions:\\n\",\n',
'\t\t\t\"# copies of the Software, and to permit persons to whom the Software is\",\n', '\t\t\t\"#\\n\",\n',
'\t\t\t\"# furnished to do so, subject to the following conditions:\",\n', '\t\t\t\"# The above copyright notice and this permission notice shall be included in\\n\",\n',
'\t\t\t\"#\",\n', '\t\t\t\"# all copies or substantial portions of the Software.\\n\",\n',
'\t\t\t\"# The above copyright notice and this permission notice shall be included in\",\n', '\t\t\t\"#\\n\",\n',
'\t\t\t\"# all copies or substantial portions of the Software.\",\n', '\t\t\t\"# THE SOFTWARE IS PROVIDED \'AS IS\', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n\",\n',
'\t\t\t\"#\",\n', '\t\t\t\"# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n\",\n',
'\t\t\t\"# THE SOFTWARE IS PROVIDED \'AS IS\', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\",\n', '\t\t\t\"# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\\n\",\n',
'\t\t\t\"# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\",\n', '\t\t\t\"# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n\",\n',
'\t\t\t\"# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\",\n', '\t\t\t\"# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n\",\n',
'\t\t\t\"# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\",\n', '\t\t\t\"# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\\n\",\n',
'\t\t\t\"# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\",\n', '\t\t\t\"# THE SOFTWARE.\\n\"\n', '\t\t]\n', '\t},'
'\t\t\t\"# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\",\n',
'\t\t\t\"# THE SOFTWARE.\"\n',
'\t\t]\n',
'\t},\n',
] ]
return markdownBlock return markdownBlock
...@@ -210,7 +206,8 @@ def getDelimiter(filename): ...@@ -210,7 +206,8 @@ def getDelimiter(filename):
".py": "#", ".py": "#",
".txt": "#", ".txt": "#",
".bsh": "#", ".bsh": "#",
".sh": "#" ".sh": "#",
".cmake": "#"
} }
listOfKeys = delimiterDict.keys() listOfKeys = delimiterDict.keys()
delimiter = None delimiter = None
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment