"docs/git@developer.sourcefind.cn:gaoqiong/migraphx.git" did not exist on "02f7405a6e281056bf8563263568322cf36535e7"
Commit d626a09e authored by Brian Pickrell's avatar Brian Pickrell
Browse files

added rand_uniform operation

parent 7e2a550c
##################################################################################### #####################################################################################
# The MIT License (MIT) # The MIT License (MIT)
# #
# Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. # Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved.
# #
# Permission is hereby granted, free of charge, to any person obtaining a copy # Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal # of this software and associated documentation files (the "Software"), to deal
...@@ -183,6 +183,7 @@ register_migraphx_ops( ...@@ -183,6 +183,7 @@ register_migraphx_ops(
quant_convolution quant_convolution
quant_dot quant_dot
quantizelinear quantizelinear
rand_uniform
recip recip
reduce_max reduce_max
reduce_mean reduce_mean
......
/*
* 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.
*/
/**
* Random Uniform distribution operator. Given a shape, populate it with random
* values. Calls to rand_uniform using the same randomization seed will
* always generate the same pseudo-random sequence. Seed can
* be given as a runtime argument containing a single value, or a compile-time
* attribute.
*
* Inputs: (1) the shape of the set to be populated.
* (2) randomization seed (uint32). If not given at inference time, the attribute value,
* or auto seeding, will be used.
* Attributes:
* use_auto_seed bool Have hardware generate random seed at runtime, overriding the attribute seed
* seed uint32 Randomization seed
*
* Output: Same shape.
*
*/
#ifndef MIGRAPHX_GUARD_OPERATORS_MULTINOMIAL_HPP
#define MIGRAPHX_GUARD_OPERATORS_MULTINOMIAL_HPP
#include <migraphx/check_shapes.hpp>
#include <migraphx/argument.hpp>
#include <migraphx/par_for.hpp>
#include <migraphx/reflect.hpp>
#include <random>
namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS {
namespace op {
struct rand_uniform
{
uint32_t seed = {0};
bool use_auto_seed = false;
// todo: not currently settable
float range_min = 0.0f;
float range_max = 1.0f;
// todo: integer data type(s) not yet supported
shape::type_t dtype = shape::type_t::float_type;
template <class Self, class F>
static auto reflect(Self& self, F f)
{
return pack(f(self.dtype, "dtype"),
f(self.seed, "seed"),
f(self.use_auto_seed, "use_auto_seed"));
}
std::string name() const { return "rand_uniform"; }
shape compute_shape(std::vector<shape> inputs) const
{
check_shapes{inputs, *this, true}.has(1, 2);
if(inputs.size() > 1 and inputs.at(1).type() != shape::type_t::uint32_type)
MIGRAPHX_THROW("RAND_UNIFORM: Input 2 (seed) must have type unsigned int");
auto s = inputs.front();
if(s.dynamic())
{
return s.with_type(dtype);
}
else
{
return s.with_lens(s.lens()).with_type(dtype);
}
}
argument compute(const dyn_output& dyn_out, std::vector<argument> args) const
{
argument result{dyn_out.computed_shape};
auto local_seed(seed);
if(use_auto_seed)
local_seed = std::chrono::system_clock::now().time_since_epoch().count();
else
{
if(args.size() > 1)
{
if(args.at(1).get_shape().element_space() > 0)
{
visit_all(args[1])([&](auto data) { local_seed = data[0]; });
}
}
}
// If a seed argument was not defined, use the value from the seed attribute,
// or the default.
std::mt19937 gen(local_seed);
std::uniform_real_distribution<> dis(range_min, range_max);
result.visit([&](auto output) {
std::generate(output.begin(), output.end(), [&]() { return dis(gen); });
});
return result;
}
};
} // namespace op
} // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx
#endif
...@@ -2216,6 +2216,28 @@ TEST_CASE(prefix_scan_sum_dyn_2d) ...@@ -2216,6 +2216,28 @@ TEST_CASE(prefix_scan_sum_dyn_2d)
} }
} }
TEST_CASE(rand_uniform)
{
std::vector<migraphx::shape::dynamic_dimension> dd{{5, 8}, {3, 7}};
migraphx::shape s1{migraphx::shape::float_type, dd};
expect_shape(
s1,
migraphx::make_op("rand_uniform", {{"seed", 1}}),
s1);
}
TEST_CASE(rand_uniform_2args)
{
std::vector<migraphx::shape::dynamic_dimension> dd{{5, 8}, {3, 7}};
migraphx::shape s1{migraphx::shape::float_type, dd};
migraphx::shape s2{migraphx::shape::uint32_type, dd};
expect_shape(
s1,
migraphx::make_op("rand_uniform", {{"seed", 1}}),
s1, s2);
}
TEST_CASE(quant_convolution_shape) TEST_CASE(quant_convolution_shape)
{ {
migraphx::shape output{migraphx::shape::int32_type, {4, 4, 1, 1}}; migraphx::shape output{migraphx::shape::int32_type, {4, 4, 1, 1}};
......
...@@ -6458,6 +6458,90 @@ TEST_CASE(quantizelinear) ...@@ -6458,6 +6458,90 @@ TEST_CASE(quantizelinear)
} }
} }
TEST_CASE(rand_uniform_test)
{
migraphx::program p;
auto* mm = p.get_main_module();
uint32_t seed(0);
size_t sample_size(200);
// Shape of the random data
migraphx::shape rs{migraphx::shape::float_type, {1, sample_size}};
// data tensor must be allocated at this point but does not need to be initialized.
std::vector<float> data(sample_size);
auto input = mm->add_literal(migraphx::literal(rs, data));
// Runtime randomization seed
migraphx::shape seed_shape{migraphx::shape::uint32_type, {1}};
std::vector<uint32_t> seed_data{seed};
auto seed_input = mm->add_literal(migraphx::literal(seed_shape, seed_data));
mm->add_instruction(migraphx::make_op("rand_uniform",
{
{"seed", seed},
}),
input,
seed_input);
p.compile(migraphx::make_target("ref"));
migraphx::parameter_map params0;
auto result = p.eval(params0).back();
std::vector<float> result_vec(sample_size);
result.visit([&](auto output) { result_vec.assign(output.begin(), output.end()); });
// Compare result with the STL's mt19937 generator
std::mt19937 gen(seed);
std::uniform_real_distribution<> dis(0.0, 1.0);
std::vector<float> rand_samples(sample_size);
std::generate(rand_samples.begin(), rand_samples.end(), [&]() { return dis(gen); });
EXPECT(migraphx::verify::verify_range(result_vec, rand_samples, 100000));
}
TEST_CASE(rand_uniform_dyn_test)
{
migraphx::program p;
auto* mm = p.get_main_module();
uint32_t seed(17);
size_t sample_size(200);
// Shape of the random data
migraphx::shape rs{migraphx::shape::float_type, {{1, 2}, {2, sample_size + 1}}};
auto input = mm->add_parameter("Input_1", rs);
// Runtime randomization seed
migraphx::shape seed_shape{migraphx::shape::uint32_type, {1}};
auto seed_input = mm->add_parameter("Seed", seed_shape);
mm->add_instruction(migraphx::make_op("rand_uniform",
{
{"seed", seed + 1},
}),
input,
seed_input);
p.compile(migraphx::make_target("ref"));
// Create a dummy input to hold the random data
migraphx::shape input_fixed_shape1{migraphx::shape::float_type, {sample_size}};
migraphx::parameter_map params0;
params0["Input_1"] = migraphx::argument(input_fixed_shape1);
migraphx::shape seed_fixed_shape{migraphx::shape::uint32_type, {1}};
std::vector<uint32_t> seed_data = {seed};
params0["Seed"] = migraphx::argument(seed_fixed_shape, seed_data.data());
auto result = p.eval(params0).back();
std::vector<float> result_vec(sample_size);
result.visit([&](auto output) { result_vec.assign(output.begin(), output.end()); });
// Compare result with the STL's mt19937 generator
std::mt19937 gen(seed);
std::uniform_real_distribution<> dis(0.0, 1.0);
std::vector<float> rand_samples(sample_size);
std::generate(rand_samples.begin(), rand_samples.end(), [&]() { return dis(gen); });
EXPECT(migraphx::verify::verify_range(result_vec, rand_samples, 100000));
}
TEST_CASE(recip_test) TEST_CASE(recip_test)
{ {
migraphx::program p; migraphx::program p;
......
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