"IMG/vscode:/vscode.git/clone" did not exist on "1b5aa9c61dd5e3828df475044834bf849d0da9b6"
Unverified Commit 250d3c87 authored by Chris Austen's avatar Chris Austen Committed by GitHub
Browse files

Merge branch 'develop' into ck-flash-attn

parents 135eb63e f3939b99
/*
* 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/common_dims.hpp>
#include <test.hpp>
using axes_map = std::vector<std::vector<std::size_t>>;
TEST_CASE(common_d1_less)
{
auto cd = migraphx::common_dims::compute({2, 32, 40, 8}, {2, 1280, 8});
EXPECT(cd.dims == std::vector<std::size_t>{2, 32, 40, 8});
EXPECT(cd.axes_map1 == axes_map{{0}, {1}, {2}, {3}});
EXPECT(cd.axes_map2 == axes_map{{0}, {1, 2}, {3}});
}
TEST_CASE(common1)
{
auto cd = migraphx::common_dims::compute({2, 32, 2560}, {2, 1280, 8, 8});
EXPECT(cd.dims == std::vector<std::size_t>{2, 32, 40, 8, 8});
EXPECT(cd.axes_map1 == axes_map{{0}, {1}, {2, 3, 4}});
EXPECT(cd.axes_map2 == axes_map{{0}, {1, 2}, {3}, {4}});
}
TEST_CASE(common2)
{
auto cd = migraphx::common_dims::compute({2, 1280, 8, 8}, {2, 32, 2560});
EXPECT(cd.dims == std::vector<std::size_t>{2, 32, 40, 8, 8});
EXPECT(cd.axes_map1 == axes_map{{0}, {1, 2}, {3}, {4}});
EXPECT(cd.axes_map2 == axes_map{{0}, {1}, {2, 3, 4}});
}
TEST_CASE(common_error1)
{
auto cd = migraphx::common_dims::compute({6, 35}, {3, 7, 2, 5});
EXPECT(cd.dims.empty());
}
TEST_CASE(common_error2)
{
auto cd = migraphx::common_dims::compute({3, 7, 2, 5}, {6, 35});
EXPECT(cd.dims.empty());
}
int main(int argc, const char* argv[]) { test::run(argc, argv); }
...@@ -112,7 +112,10 @@ TEST_CASE_REGISTER(test_limits<double, int>); ...@@ -112,7 +112,10 @@ TEST_CASE_REGISTER(test_limits<double, int>);
TEST_CASE_REGISTER(test_limits<double, migraphx::half>); TEST_CASE_REGISTER(test_limits<double, migraphx::half>);
TEST_CASE_REGISTER(test_limits<float, int>); TEST_CASE_REGISTER(test_limits<float, int>);
TEST_CASE_REGISTER(test_limits<int, migraphx::half>); TEST_CASE_REGISTER(test_limits<int, migraphx::half>);
#ifndef _WIN32
// On Windows, types int and long have the same min and max values.
TEST_CASE_REGISTER(test_limits<long, int>); TEST_CASE_REGISTER(test_limits<long, int>);
#endif
TEST_CASE_REGISTER(test_limits<long, char>); TEST_CASE_REGISTER(test_limits<long, char>);
int main(int argc, const char* argv[]) { test::run(argc, argv); } int main(int argc, const char* argv[]) { test::run(argc, argv); }
...@@ -21,8 +21,9 @@ ...@@ -21,8 +21,9 @@
* 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/dead_code_elimination.hpp>
#include <migraphx/fuse_pointwise.hpp> #include <migraphx/fuse_pointwise.hpp>
#include <migraphx/dead_code_elimination.hpp>
#include <migraphx/eliminate_contiguous.hpp>
#include <migraphx/instruction.hpp> #include <migraphx/instruction.hpp>
#include <migraphx/pass_manager.hpp> #include <migraphx/pass_manager.hpp>
#include <migraphx/program.hpp> #include <migraphx/program.hpp>
...@@ -361,4 +362,154 @@ TEST_CASE(no_input) ...@@ -361,4 +362,154 @@ TEST_CASE(no_input)
EXPECT(p == p2); EXPECT(p == p2);
} }
TEST_CASE(add_reshape_add)
{
migraphx::shape s1{migraphx::shape::float_type, {3, 10, 16}};
migraphx::shape s2{migraphx::shape::float_type, {3, 40, 2, 2}};
migraphx::shape s3{migraphx::shape::float_type, {3, 10, 4, 2, 2}};
migraphx::program p1;
{
auto* mm = p1.get_main_module();
auto x = mm->add_parameter("x", s1);
auto y = mm->add_parameter("y", s1);
auto z = mm->add_parameter("z", s2);
auto add1 = mm->add_instruction(migraphx::make_op("add"), x, y);
auto reshape =
mm->add_instruction(migraphx::make_op("reshape", {{"dims", s2.lens()}}), add1);
auto add2 = mm->add_instruction(migraphx::make_op("add"), reshape, z);
mm->add_return({add2});
}
run_pass(p1);
migraphx::program p2;
{
auto* mm = p2.get_main_module();
auto x = mm->add_parameter("x", s1);
auto y = mm->add_parameter("y", s1);
auto z = mm->add_parameter("z", s2);
auto x2 = mm->add_instruction(migraphx::make_op("reshape", {{"dims", s3.lens()}}), x);
auto y2 = mm->add_instruction(migraphx::make_op("reshape", {{"dims", s3.lens()}}), y);
auto z2 = mm->add_instruction(migraphx::make_op("reshape", {{"dims", s3.lens()}}), z);
auto fadd =
add_pointwise(p2, "main:pointwise0", {x2, y2, z2}, [=](auto* pm, const auto& inputs) {
auto add1 = pm->add_instruction(migraphx::make_op("add"), inputs[0], inputs[1]);
return pm->add_instruction(migraphx::make_op("add"), add1, inputs[2]);
});
auto reshape =
mm->add_instruction(migraphx::make_op("reshape", {{"dims", s2.lens()}}), fadd);
mm->add_return({reshape});
}
EXPECT(p1.sort() == p2.sort());
}
TEST_CASE(add_reshape_add_nonstandard)
{
migraphx::shape s1 =
migraphx::shape::from_permutation(migraphx::shape::float_type, {3, 10, 16}, {2, 0, 1});
migraphx::shape s2{migraphx::shape::float_type, {3, 40, 2, 2}};
migraphx::shape s3{migraphx::shape::float_type, {3, 10, 4, 2, 2}};
migraphx::program p1;
{
auto* mm = p1.get_main_module();
auto x = mm->add_parameter("x", s1);
auto y = mm->add_parameter("y", s1);
auto z = mm->add_parameter("z", s2);
auto add1 = mm->add_instruction(migraphx::make_op("add"), x, y);
auto c = mm->add_instruction(migraphx::make_op("contiguous"), add1);
auto reshape = mm->add_instruction(migraphx::make_op("reshape", {{"dims", s2.lens()}}), c);
auto add2 = mm->add_instruction(migraphx::make_op("add"), reshape, z);
mm->add_return({add2});
}
run_pass(p1);
migraphx::program p2;
{
auto* mm = p2.get_main_module();
auto x = mm->add_parameter("x", s1);
auto y = mm->add_parameter("y", s1);
auto z = mm->add_parameter("z", s2);
auto cx = mm->add_instruction(migraphx::make_op("contiguous"), x);
auto cy = mm->add_instruction(migraphx::make_op("contiguous"), y);
auto x2 = mm->add_instruction(migraphx::make_op("reshape", {{"dims", s3.lens()}}), cx);
auto y2 = mm->add_instruction(migraphx::make_op("reshape", {{"dims", s3.lens()}}), cy);
auto z2 = mm->add_instruction(migraphx::make_op("reshape", {{"dims", s3.lens()}}), z);
auto fadd =
add_pointwise(p2, "main:pointwise0", {x2, y2, z2}, [=](auto* pm, const auto& inputs) {
auto add1 = pm->add_instruction(migraphx::make_op("add"), inputs[0], inputs[1]);
return pm->add_instruction(migraphx::make_op("add"), add1, inputs[2]);
});
auto reshape =
mm->add_instruction(migraphx::make_op("reshape", {{"dims", s2.lens()}}), fadd);
mm->add_return({reshape});
}
EXPECT(p1.sort() == p2.sort());
}
TEST_CASE(add_unsqueeze_add_nonstandard)
{
migraphx::shape s1 =
migraphx::shape::from_permutation(migraphx::shape::float_type, {3, 10, 16}, {2, 0, 1});
migraphx::shape s2{migraphx::shape::float_type, {3, 10, 1, 16}};
migraphx::program p1;
{
auto* mm = p1.get_main_module();
auto x = mm->add_parameter("x", s1);
auto y = mm->add_parameter("y", s1);
auto z = mm->add_parameter("z", s2);
auto add1 = mm->add_instruction(migraphx::make_op("add"), x, y);
auto unsqueeze = mm->add_instruction(migraphx::make_op("unsqueeze", {{"axes", {2}}}), add1);
auto add2 = mm->add_instruction(migraphx::make_op("add"), unsqueeze, z);
mm->add_return({add2});
}
run_pass(p1);
migraphx::program p2;
{
auto* mm = p2.get_main_module();
auto x = mm->add_parameter("x", s1);
auto y = mm->add_parameter("y", s1);
auto z = mm->add_parameter("z", s2);
auto cx = mm->add_instruction(migraphx::make_op("contiguous"), x);
auto cy = mm->add_instruction(migraphx::make_op("contiguous"), y);
auto x2 = mm->add_instruction(migraphx::make_op("reshape", {{"dims", s2.lens()}}), cx);
auto y2 = mm->add_instruction(migraphx::make_op("reshape", {{"dims", s2.lens()}}), cy);
auto fadd =
add_pointwise(p2, "main:pointwise0", {x2, y2, z}, [=](auto* pm, const auto& inputs) {
auto add1 = pm->add_instruction(migraphx::make_op("add"), inputs[0], inputs[1]);
return pm->add_instruction(migraphx::make_op("add"), add1, inputs[2]);
});
mm->add_return({fadd});
}
EXPECT(p1.sort() == p2.sort());
}
TEST_CASE(add_reshape_add_error)
{
migraphx::shape s1{migraphx::shape::float_type, {6, 35}};
migraphx::shape s2{migraphx::shape::float_type, {3, 7, 2, 5}};
migraphx::program p1;
{
auto* mm = p1.get_main_module();
auto x = mm->add_parameter("x", s1);
auto y = mm->add_parameter("y", s1);
auto z = mm->add_parameter("z", s2);
auto add1 = mm->add_instruction(migraphx::make_op("add"), x, y);
auto reshape =
mm->add_instruction(migraphx::make_op("reshape", {{"dims", s2.lens()}}), add1);
auto add2 = mm->add_instruction(migraphx::make_op("add"), reshape, z);
mm->add_return({add2});
}
run_pass(p1);
migraphx::program p2;
{
auto* mm = p2.get_main_module();
auto x = mm->add_parameter("x", s1);
auto y = mm->add_parameter("y", s1);
auto z = mm->add_parameter("z", s2);
auto fadd1 = add_pointwise(p2, "main:pointwise0", {x, y}, single_pointwise("add"));
auto reshape =
mm->add_instruction(migraphx::make_op("reshape", {{"dims", s2.lens()}}), fadd1);
auto fadd2 = add_pointwise(p2, "main:pointwise1", {reshape, z}, single_pointwise("add"));
mm->add_return({fadd2});
}
EXPECT(p1.sort() == p2.sort());
}
int main(int argc, const char* argv[]) { test::run(argc, argv); } int main(int argc, const char* argv[]) { test::run(argc, argv); }
...@@ -80,7 +80,7 @@ TEST_CASE(mul_literal_round_test) ...@@ -80,7 +80,7 @@ TEST_CASE(mul_literal_round_test)
migraphx::target gpu_t = migraphx::make_target("gpu"); migraphx::target gpu_t = migraphx::make_target("gpu");
run_prog(p, gpu_t, m, gpu_result); run_prog(p, gpu_t, m, gpu_result);
EXPECT(migraphx::verify::verify_range(ref_result, gpu_result)); EXPECT(migraphx::verify::verify_rms_range(gpu_result, ref_result));
} }
int main(int argc, const char* argv[]) { test::run(argc, argv); } int main(int argc, const char* argv[]) { test::run(argc, argv); }
/*
* 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 "make_precompile_op.hpp"
#include <migraphx/dead_code_elimination.hpp>
#include <migraphx/gpu/fuse_ops.hpp>
#include <migraphx/pass_manager.hpp>
#include <migraphx/instruction.hpp>
#include <migraphx/program.hpp>
#include <basic_ops.hpp>
#include <migraphx/make_op.hpp>
#include <test.hpp>
#include <pointwise.hpp>
void run_pass(migraphx::program& p)
{
migraphx::run_passes(p, {migraphx::gpu::fuse_ops{}, migraphx::dead_code_elimination{}});
}
TEST_CASE(layernorm_pointwise)
{
migraphx::shape s{migraphx::shape::float_type, {2, 3, 4}};
auto create_program = [=](bool first_arg_layernorm) {
migraphx::program p;
auto* mm = p.get_main_module();
auto x = mm->add_parameter("x", s);
auto y = mm->add_parameter("y", s);
auto z = mm->add_parameter("z", s);
auto alloc = migraphx::make_op("allocate", {{"shape", to_value(s)}});
auto alloc_ins = mm->add_instruction(alloc);
auto* pw_add1 =
create_pointwise_module(p, "main:pointwise0", {x, y}, single_pointwise("add"));
auto add1 =
mm->add_instruction(make_precompile_op("pointwise"), {x, y, alloc_ins}, {pw_add1});
auto alloc_ins2 = mm->add_instruction(alloc);
auto layernorm_ins =
mm->add_instruction(make_precompile_op("gpu::prelayernorm"), add1, alloc_ins2);
std::vector<migraphx::instruction_ref> pw_inputs = {layernorm_ins, z};
if(not first_arg_layernorm)
{
pw_inputs = {z, layernorm_ins};
}
auto* pw_add2 =
create_pointwise_module(p, "main:pointwise1", pw_inputs, single_pointwise("add"));
auto alloc_ins3 = mm->add_instruction(alloc);
pw_inputs.push_back(alloc_ins3);
auto add2 = mm->add_instruction(make_precompile_op("pointwise"), pw_inputs, {pw_add2});
mm->add_return({add2});
return p;
};
auto create_fused_program = [=]() {
migraphx::program p;
auto* mm = p.get_main_module();
auto x = mm->add_parameter("x", s);
auto y = mm->add_parameter("y", s);
auto z = mm->add_parameter("z", s);
auto alloc = migraphx::make_op("allocate", {{"shape", to_value(s)}});
auto alloc_ins = mm->add_instruction(alloc);
auto* pw_add1 =
create_pointwise_module(p, "main:pointwise0", {x, y}, single_pointwise("add"));
auto add1 =
mm->add_instruction(make_precompile_op("pointwise"), {x, y, alloc_ins}, {pw_add1});
auto alloc_ins2 = mm->add_instruction(alloc);
auto* pw_add2 =
create_pointwise_module(p, "main:pointwise1", {x, z}, single_pointwise("add"));
auto layernorm_ins = mm->add_instruction(
make_precompile_op("gpu::prelayernorm"), {add1, z, alloc_ins2}, {pw_add2});
mm->add_return({layernorm_ins});
return p;
};
{
migraphx::program p1 = create_program(true);
run_pass(p1);
migraphx::program p2 = create_fused_program();
EXPECT(p1 == p2);
}
{
migraphx::program p1 = create_program(false);
run_pass(p1);
migraphx::program p2 = create_fused_program();
EXPECT(p1 == p2);
}
}
int main(int argc, const char* argv[]) { test::run(argc, argv); }
...@@ -218,6 +218,15 @@ TEST_CASE(compile_warnings) ...@@ -218,6 +218,15 @@ TEST_CASE(compile_warnings)
#endif #endif
} }
TEST_CASE(has_flags)
{
EXPECT(migraphx::gpu::hip_has_flags({"--std=c++17"}));
EXPECT(not migraphx::gpu::hip_has_flags({"--non-existent-flag-to-test-in-migraphx"}));
EXPECT(migraphx::gpu::hip_has_flags({"-Wunused-parameter"}));
EXPECT(not migraphx::gpu::hip_has_flags(
{"-Wnon-existent-warnings-flag-to-test-in-migraphx", "-Werror"}));
}
TEST_CASE(code_object_hip) TEST_CASE(code_object_hip)
{ {
auto binaries = migraphx::gpu::compile_hip_src( auto binaries = migraphx::gpu::compile_hip_src(
......
...@@ -53,7 +53,6 @@ TEST_CASE(host_same_buffer_copy) ...@@ -53,7 +53,6 @@ TEST_CASE(host_same_buffer_copy)
migraphx::parameter_map pp; migraphx::parameter_map pp;
std::vector<float> a_vec(ss.elements(), -1); std::vector<float> a_vec(ss.elements(), -1);
std::vector<float> b_vec(ss.elements(), 2); std::vector<float> b_vec(ss.elements(), 2);
std::vector<float> c_vec(ss.elements(), 0);
pp["a"] = migraphx::argument(ss, a_vec.data()); pp["a"] = migraphx::argument(ss, a_vec.data());
pp["b"] = migraphx::argument(ss, b_vec.data()); pp["b"] = migraphx::argument(ss, b_vec.data());
std::vector<float> gpu_result; std::vector<float> gpu_result;
...@@ -64,7 +63,8 @@ TEST_CASE(host_same_buffer_copy) ...@@ -64,7 +63,8 @@ TEST_CASE(host_same_buffer_copy)
auto result = p.eval(pp).back(); auto result = p.eval(pp).back();
std::vector<float> results_vector(ss.elements(), -1); std::vector<float> results_vector(ss.elements(), -1);
result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); }); result.visit([&](auto output) { results_vector.assign(output.begin(), output.end()); });
EXPECT(migraphx::verify::verify_range(c_vec, results_vector)); std::vector<float> gold_vec(ss.elements(), 0);
EXPECT(migraphx::verify::verify_rms_range(results_vector, gold_vec));
} }
TEST_CASE(arguments_lifetime) TEST_CASE(arguments_lifetime)
......
...@@ -133,7 +133,8 @@ bool verify_mlir(const migraphx::module& mmlir) ...@@ -133,7 +133,8 @@ bool verify_mlir(const migraphx::module& mmlir)
auto inputs = generate_params(ref); auto inputs = generate_params(ref);
auto mlir = create_program_from_mlir(mmlir); auto mlir = create_program_from_mlir(mmlir);
return migraphx::verify_args("mlir", run_ref(ref, inputs), run_gpu(mlir, inputs)); return migraphx::verify_args_with_tolerance(
"mlir", run_gpu(mlir, inputs), migraphx::verify::expected{run_ref(ref, inputs)});
} }
TEST_CASE(conv) TEST_CASE(conv)
......
...@@ -40,7 +40,6 @@ ...@@ -40,7 +40,6 @@
TEST_CASE(gpu_target_copy) TEST_CASE(gpu_target_copy)
{ {
migraphx::target gpu_t = migraphx::make_target("gpu"); migraphx::target gpu_t = migraphx::make_target("gpu");
migraphx::target ref_t = migraphx::make_target("ref");
migraphx::shape s{migraphx::shape::int8_type, {2, 3, 4, 5}}; migraphx::shape s{migraphx::shape::int8_type, {2, 3, 4, 5}};
auto ref_arg_orig = migraphx::generate_argument(s, 0x123456L); auto ref_arg_orig = migraphx::generate_argument(s, 0x123456L);
...@@ -52,7 +51,7 @@ TEST_CASE(gpu_target_copy) ...@@ -52,7 +51,7 @@ TEST_CASE(gpu_target_copy)
std::vector<int8_t> val_final; std::vector<int8_t> val_final;
ref_arg_final.visit([&](auto v) { val_final.assign(v.begin(), v.end()); }); ref_arg_final.visit([&](auto v) { val_final.assign(v.begin(), v.end()); });
EXPECT(migraphx::verify::verify_range(val_orig, val_final)); EXPECT(migraphx::verify::verify_rms_range(val_orig, val_final));
} }
TEST_CASE(int8_quantization) TEST_CASE(int8_quantization)
...@@ -118,9 +117,12 @@ TEST_CASE(int8_quantization) ...@@ -118,9 +117,12 @@ TEST_CASE(int8_quantization)
// the regular pipeline uses the rewrite_quantization in the much // the regular pipeline uses the rewrite_quantization in the much
// earlier stage. // earlier stage.
if(migraphx::gpu::mlir_enabled()) if(migraphx::gpu::mlir_enabled())
EXPECT(migraphx::verify::verify_range(ref_result, gpu_result, 1e5)); EXPECT(migraphx::verify::verify_range_with_tolerance(
gpu_result,
migraphx::verify::expected{ref_result},
migraphx::verify::tolerance{0.01}));
else else
EXPECT(migraphx::verify::verify_range(ref_result, gpu_result)); EXPECT(migraphx::verify::verify_rms_range(gpu_result, ref_result));
} }
} }
......
...@@ -24,16 +24,16 @@ ...@@ -24,16 +24,16 @@
#ifndef MIGRAPHX_GUARD_TEST_INCLUDE_POINTWISE_HPP #ifndef MIGRAPHX_GUARD_TEST_INCLUDE_POINTWISE_HPP
#define MIGRAPHX_GUARD_TEST_INCLUDE_POINTWISE_HPP #define MIGRAPHX_GUARD_TEST_INCLUDE_POINTWISE_HPP
#include <migraphx/instruction_ref.hpp>
#include <migraphx/program.hpp> #include <migraphx/program.hpp>
#include <migraphx/module.hpp> #include <migraphx/module.hpp>
#include <migraphx/make_op.hpp> #include <migraphx/make_op.hpp>
template <class F> template <class F>
migraphx::instruction_ref add_pointwise(migraphx::program& p, migraphx::module_ref create_pointwise_module(migraphx::program& p,
migraphx::module_ref mm, const std::string& name,
const std::string& name, std::vector<migraphx::instruction_ref> inputs,
std::vector<migraphx::instruction_ref> inputs, F f)
F f)
{ {
auto* pm = p.create_module(name); auto* pm = p.create_module(name);
pm->set_bypass(); pm->set_bypass();
...@@ -44,6 +44,17 @@ migraphx::instruction_ref add_pointwise(migraphx::program& p, ...@@ -44,6 +44,17 @@ migraphx::instruction_ref add_pointwise(migraphx::program& p,
}); });
auto r = f(pm, params); auto r = f(pm, params);
pm->add_return({r}); pm->add_return({r});
return pm;
}
template <class F>
migraphx::instruction_ref add_pointwise(migraphx::program& p,
migraphx::module_ref mm,
const std::string& name,
std::vector<migraphx::instruction_ref> inputs,
F f)
{
auto* pm = create_pointwise_module(p, name, inputs, f);
return mm->add_instruction(migraphx::make_op("pointwise"), inputs, {pm}); return mm->add_instruction(migraphx::make_op("pointwise"), inputs, {pm});
} }
......
...@@ -25,13 +25,37 @@ ...@@ -25,13 +25,37 @@
#include <migraphx/value.hpp> #include <migraphx/value.hpp>
#include <msgpack.hpp> #include <msgpack.hpp>
#include <map> #include <map>
#include <numeric>
#include "test.hpp" #include "test.hpp"
template <class T, MIGRAPHX_REQUIRES(not std::is_base_of<std::vector<std::uint8_t>, T>{})>
void write_msgpack(std::ostream& os, const T& src)
{
msgpack::pack(os, src);
}
void write_msgpack(std::ostream& os, const std::vector<std::uint8_t>& src)
{
const auto limit = std::numeric_limits<uint32_t>::max() - 1;
std::vector<std::vector<std::uint8_t>> chunks;
if(src.size() > limit)
{
// Only test two chunks
assert(std::distance(src.begin() + limit, src.end()) < limit);
chunks.emplace_back(src.begin(), src.begin() + limit);
chunks.emplace_back(src.begin() + limit, src.end());
}
else
{
chunks = {src};
}
write_msgpack(os, chunks);
}
template <class T> template <class T>
std::vector<char> msgpack_buffer(const T& src) std::vector<char> msgpack_buffer(const T& src)
{ {
std::stringstream buffer; std::stringstream buffer;
msgpack::pack(buffer, src); write_msgpack(buffer, src);
buffer.seekg(0); buffer.seekg(0);
std::string str = buffer.str(); std::string str = buffer.str();
return std::vector<char>(str.data(), str.data() + str.size()); // NOLINT return std::vector<char>(str.data(), str.data() + str.size()); // NOLINT
...@@ -147,4 +171,51 @@ TEST_CASE(test_msgpack_array_class) ...@@ -147,4 +171,51 @@ TEST_CASE(test_msgpack_array_class)
EXPECT(migraphx::from_msgpack(buffer) == v); EXPECT(migraphx::from_msgpack(buffer) == v);
} }
TEST_CASE(test_msgpack_binary)
{
migraphx::value::binary bin{64};
std::iota(bin.begin(), bin.end(), 1);
auto buffer = migraphx::to_msgpack(bin);
EXPECT(buffer == msgpack_buffer(bin));
EXPECT(migraphx::from_msgpack(buffer) == bin);
}
#ifndef MIGRAPHX_DISABLE_LARGE_BUFFER_TESTS
TEST_CASE(test_msgpack_large_binary1)
{
const std::size_t n = 4LL * 1024 * 1024 * 1024 + 2;
const char fill_value = 2;
migraphx::value v;
{
std::vector<char> buffer;
{
migraphx::value::binary bin{n};
std::fill(bin.begin(), bin.begin() + n / 2, fill_value);
std::fill(bin.begin() + n / 2, bin.end(), fill_value + 1);
buffer = migraphx::to_msgpack(std::move(bin));
}
v = migraphx::from_msgpack(buffer);
}
EXPECT(v.is_binary());
EXPECT(v.get_binary().size() == n);
EXPECT(std::all_of(v.get_binary().begin(), v.get_binary().begin() + n / 2, [](auto c) {
return c == fill_value;
}));
EXPECT(std::all_of(v.get_binary().begin() + n / 2, v.get_binary().end(), [](auto c) {
return c == fill_value + 1;
}));
}
TEST_CASE(test_msgpack_binary2)
{
const std::size_t n = 4LL * 1024 * 1024 * 1024 + 2;
migraphx::value::binary bin{n};
std::size_t i = 0;
std::generate(bin.begin(), bin.end(), [&] {
i++;
return i % 256;
});
EXPECT(migraphx::to_msgpack(bin) == msgpack_buffer(bin));
}
#endif
int main(int argc, const char* argv[]) { test::run(argc, argv); } int main(int argc, const char* argv[]) { test::run(argc, argv); }
a476dbf430ac8315550474a78d47bf182f202d7c 6d7bc2a097a1a08541cd0d4628831c79ab8092d5
constant_no_attributes_test:)
"Constantconstant_no_attributes_testB
\ No newline at end of file
constant_value_int_test:7
"Constant*
value_int@ constant_value_int_testB
\ No newline at end of file
constant_value_ints_test:=
!"Constant*
value_ints@@@ constant_value_ints_testB
\ No newline at end of file
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