[GPU] Use int64_t type for axis in softmax (#12287)

This commit is contained in:
Roman Lyamin
2022-07-26 13:21:43 +04:00
committed by GitHub
parent 72509ec041
commit e2da32721b
20 changed files with 157 additions and 617 deletions

View File

@@ -232,6 +232,7 @@ REGISTER_FACTORY(v8, RandomUniform)
REGISTER_FACTORY(v8, MaxPool);
REGISTER_FACTORY(v8, AdaptiveAvgPool);
REGISTER_FACTORY(v8, AdaptiveMaxPool);
REGISTER_FACTORY(v8, Softmax);
// ------------------------------ Supported v9 ops ------------------------------ //
REGISTER_FACTORY(v9, SoftSign)

View File

@@ -25,24 +25,13 @@ namespace cldnn {
struct softmax : public primitive_base<softmax> {
CLDNN_DECLARE_PRIMITIVE(softmax)
/// @brief Enum type to specify softmax's normalization scope (see #dimension).
enum dimension_t {
normalize_b,
normalize_f,
normalize_x,
normalize_y,
normalize_z,
normalize_fyx,
normalize_all
};
/// @brief Constructs softmax primitive.
/// @param id This primitive id.
/// @param input Input primitive id.
/// @param dimension Defines a scope of normalization (see #dimension).
/// @param dimension Defines a scope of normalization
softmax(const primitive_id& id,
const primitive_id& input,
const dimension_t dimension = normalize_fyx,
const int64_t dimension = 1,
const primitive_id& ext_prim_id = "",
const padding& output_padding = padding())
: primitive_base(id, {input}, ext_prim_id, output_padding), dimension(dimension) {}
@@ -51,13 +40,12 @@ struct softmax : public primitive_base<softmax> {
/// @details
/// Being given a 4-dimensional input, which consists of b,f,y,x dimensions, softmax normalizes data which are divided into multiple independent sets.
/// Specific behaviour is determined by this parameter, as follows:
/// - when set to @link softmax::dimension_t softmax::normalize_x @endlink each input row is normalized independently,
/// - when set to @link softmax::dimension_t softmax::normalize_y @endlink each input column is normalized independently,
/// - when set to @link softmax::dimension_t softmax::normalize_z @endlink each input z-coordinate is normalized independently,
/// - when set to @link softmax::dimension_t softmax::normalize_f @endlink each in-depth vector of input is normalized independently,
/// - when set to @link softmax::dimension_t softmax::normalize_fyx @endlink each 3d image within input is normalized independently,
/// - when set to @link softmax::dimension_t softmax::normalize_all @endlink everything is normalized,
dimension_t dimension;
/// - when softmax dimension is set to 0 (b dim) each batch vector of input is normalized independently,
/// - when softmax dimension is set to 1 (f dim) each in-depth vector of input is normalized independently,
/// - when softmax dimension is set to 2 (y dim) each input column is normalized independently,
/// - when softmax dimension is set to 3 (x dim) each input row is normalized independently.
int64_t dimension;
};
/// @}
/// @}

View File

@@ -925,7 +925,7 @@ void prepare_primitive_fusing::fuse_simple_primitives(program &p) {
should_fuse |= input_data.is_type<scale>() && quantize_node.get_scale_shift_opt();
should_fuse |= input_data.is_type<softmax>() &&
input_data.as<softmax>().get_primitive()->dimension == softmax::dimension_t::normalize_f &&
input_data.as<softmax>().get_primitive()->dimension == 1 &&
per_tensor_values;

View File

@@ -13,6 +13,28 @@
namespace cldnn {
namespace ocl {
static inline kernel_selector::softmax_dim GetSoftmaxDim(int64_t axis, size_t rank) {
if (axis < 0) {
axis += rank;
}
switch (axis) {
case 0: return kernel_selector::softmax_dim::BATCH;
case 1: return kernel_selector::softmax_dim::FEATURE;
case 2:
if (rank > 4)
return kernel_selector::softmax_dim::Z;
else
return kernel_selector::softmax_dim::Y;
case 3:
if (rank > 4)
return kernel_selector::softmax_dim::Y;
else
return kernel_selector::softmax_dim::X;
case 4: return kernel_selector::softmax_dim::X;
default: IE_THROW() << "Invalid softmax axis " << axis;
}
}
struct softmax_impl : typed_primitive_impl_ocl<softmax> {
using parent = typed_primitive_impl_ocl<softmax>;
using parent::parent;
@@ -26,49 +48,10 @@ struct softmax_impl : typed_primitive_impl_ocl<softmax> {
auto sm_optional_params =
get_default_optional_params<kernel_selector::softmax_optional_params>(arg.get_program());
auto& input = sm_params.inputs[0];
auto& output = sm_params.outputs[0];
const auto primitive = arg.get_primitive();
switch (primitive->dimension) {
case softmax::normalize_x:
sm_params.dim = kernel_selector::softmax_dim::X;
break;
case softmax::normalize_y:
sm_params.dim = kernel_selector::softmax_dim::Y;
break;
case softmax::normalize_fyx:
// Flatten fused with softmax
input = input.FlattenFeatureAndSpatials();
output = output.FlattenFeatureAndSpatials();
sm_params.dim = kernel_selector::softmax_dim::FEATURE;
break;
case softmax::normalize_b:
sm_params.dim = kernel_selector::softmax_dim::BATCH;
break;
case softmax::normalize_f:
sm_params.dim = kernel_selector::softmax_dim::FEATURE;
break;
case softmax::normalize_z:
sm_params.dim = kernel_selector::softmax_dim::Z;
break;
case softmax::normalize_all:
input = input.FlattenEverything();
output = output.FlattenEverything();
sm_params.dim = kernel_selector::softmax_dim::FEATURE;
break;
default:
throw std::runtime_error("Wrong API - no such softmax");
}
size_t rank = arg.get_output_layout().get_rank();
sm_params.dim = GetSoftmaxDim(primitive->dimension, rank);
auto& kernel_selector = kernel_selector::softmax_kernel_selector::Instance();
auto best_kernels = kernel_selector.GetBestKernels(sm_params, sm_optional_params);

View File

@@ -873,7 +873,7 @@ void program_node::init_onednn_primitive_attributes() {
auto node = cldnn_post_ops[idx].node;
if (node->is_type<activation>()) {
auto fused_desc = node->as<activation>().get_primitive();;
auto fused_desc = node->as<activation>().get_primitive();
if (fused_desc->activation_function == cldnn::activation_func::relu_negative_slope
&& !fused_desc->additional_params_input.empty()) {
auto dep_idx = cldnn_post_ops[idx].dep_start_idx;

View File

@@ -31,6 +31,10 @@ std::string softmax_inst::to_string(softmax_node const& node) {
std::stringstream primitive_description;
json_composite softmax_info;
softmax_info.add("dimension", desc->dimension);
node_info->add("softmax_info", softmax_info);
node_info->dump(primitive_description);
return primitive_description.str();

View File

@@ -27,8 +27,8 @@ KernelsPriority ExperimentalDetectronGenerateProposalsSingleImageRef::GetKernels
}
bool ExperimentalDetectronGenerateProposalsSingleImageRef::Validate(const Params& p, const optional_params& o) const {
if (p.GetType() != KernelType::EXPERIMENTAL_DETECTRON_GENERATE_PROPOSALS_SINGLE_IMAGE
|| o.GetType() != KernelType::EXPERIMENTAL_DETECTRON_GENERATE_PROPOSALS_SINGLE_IMAGE) {
if (p.GetType() != KernelType::EXPERIMENTAL_DETECTRON_GENERATE_PROPOSALS_SINGLE_IMAGE ||
o.GetType() != KernelType::EXPERIMENTAL_DETECTRON_GENERATE_PROPOSALS_SINGLE_IMAGE) {
return false;
}
return true;

View File

@@ -77,7 +77,7 @@ static inline std::vector<std::string> GetDefaultOrder(size_t size) {
}
static inline std::string GetAxisName(size_t size, size_t axis) {
std::vector<std::string> axis_names;;
std::vector<std::string> axis_names;
if (size <= 4) {
axis_names = {"BATCH", "FEATURE", "Y", "X"};
} else if (size == 5) {

View File

@@ -19,7 +19,7 @@ KERNEL(convolution)(
const uint group_x = (uint)get_group_id(0) * OUT_BLOCK_WIDTH;
const uint group_y = (uint)get_group_id(1) * OUT_BLOCK_HEIGHT;
const uint f = ((uint)get_group_id(2) * SIMD_SIZE * OUT_BLOCK_DEPTH) % OUTPUT_FEATURE_NUM;
const uint b = ((uint)get_group_id(2) * SIMD_SIZE * OUT_BLOCK_DEPTH) / OUTPUT_FEATURE_NUM;;
const uint b = ((uint)get_group_id(2) * SIMD_SIZE * OUT_BLOCK_DEPTH) / OUTPUT_FEATURE_NUM;
const uint ifm_part = get_sub_group_id();
uint ifm_offset = ifm_part* OUT_BLOCK_DEPTH/2;
@@ -167,10 +167,10 @@ KERNEL(convolution)(
dotProd0[2 + OUT_BLOCK_WIDTH * (br + OUT_BLOCK_HEIGHT * bd)] += tmp[2];
dotProd0[3 + OUT_BLOCK_WIDTH * (br + OUT_BLOCK_HEIGHT * bd)] += tmp[3];
dotProd0[0 + OUT_BLOCK_WIDTH * (br + OUT_BLOCK_HEIGHT * bd)] = ACTIVATION(dotProd0[0 + OUT_BLOCK_WIDTH * (br + OUT_BLOCK_HEIGHT * bd)], ACTIVATION_PARAMS);;
dotProd0[1 + OUT_BLOCK_WIDTH * (br + OUT_BLOCK_HEIGHT * bd)] = ACTIVATION(dotProd0[1 + OUT_BLOCK_WIDTH * (br + OUT_BLOCK_HEIGHT * bd)], ACTIVATION_PARAMS);;
dotProd0[2 + OUT_BLOCK_WIDTH * (br + OUT_BLOCK_HEIGHT * bd)] = ACTIVATION(dotProd0[2 + OUT_BLOCK_WIDTH * (br + OUT_BLOCK_HEIGHT * bd)], ACTIVATION_PARAMS);;
dotProd0[3 + OUT_BLOCK_WIDTH * (br + OUT_BLOCK_HEIGHT * bd)] = ACTIVATION(dotProd0[3 + OUT_BLOCK_WIDTH * (br + OUT_BLOCK_HEIGHT * bd)], ACTIVATION_PARAMS);;
dotProd0[0 + OUT_BLOCK_WIDTH * (br + OUT_BLOCK_HEIGHT * bd)] = ACTIVATION(dotProd0[0 + OUT_BLOCK_WIDTH * (br + OUT_BLOCK_HEIGHT * bd)], ACTIVATION_PARAMS);
dotProd0[1 + OUT_BLOCK_WIDTH * (br + OUT_BLOCK_HEIGHT * bd)] = ACTIVATION(dotProd0[1 + OUT_BLOCK_WIDTH * (br + OUT_BLOCK_HEIGHT * bd)], ACTIVATION_PARAMS);
dotProd0[2 + OUT_BLOCK_WIDTH * (br + OUT_BLOCK_HEIGHT * bd)] = ACTIVATION(dotProd0[2 + OUT_BLOCK_WIDTH * (br + OUT_BLOCK_HEIGHT * bd)], ACTIVATION_PARAMS);
dotProd0[3 + OUT_BLOCK_WIDTH * (br + OUT_BLOCK_HEIGHT * bd)] = ACTIVATION(dotProd0[3 + OUT_BLOCK_WIDTH * (br + OUT_BLOCK_HEIGHT * bd)], ACTIVATION_PARAMS);
width_offset += 4;
#endif
@@ -178,7 +178,7 @@ KERNEL(convolution)(
for(uint bc = width_offset; bc < OUT_BLOCK_WIDTH; bc++)
{
dotProd0[bc + OUT_BLOCK_WIDTH * (br + OUT_BLOCK_HEIGHT * bd)] += slm_vals[bc + OUT_BLOCK_WIDTH * (get_sub_group_local_id() + SIMD_SIZE * (br + OUT_BLOCK_HEIGHT * (bd + ifm_offset) ))];
dotProd0[bc + OUT_BLOCK_WIDTH * (br + OUT_BLOCK_HEIGHT * bd)] = ACTIVATION(dotProd0[bc + OUT_BLOCK_WIDTH * (br + OUT_BLOCK_HEIGHT * bd)], ACTIVATION_PARAMS);;
dotProd0[bc + OUT_BLOCK_WIDTH * (br + OUT_BLOCK_HEIGHT * bd)] = ACTIVATION(dotProd0[bc + OUT_BLOCK_WIDTH * (br + OUT_BLOCK_HEIGHT * bd)], ACTIVATION_PARAMS);
}
}
}

View File

@@ -66,6 +66,6 @@ KERNEL (fully_connected_gpu_yxfn)(
output[output_idx] = res;
#else
output[output_idx] = ACTIVATION(result, ACTIVATION_PARAMS);;
output[output_idx] = ACTIVATION(result, ACTIVATION_PARAMS);
#endif
}

View File

@@ -108,7 +108,7 @@ KERNEL(pooling_gpu_b_fs_yx_fsv4)(
result[0] = FUNC_CALL(apply_pooling)(result[0], TO_ACCUMULATOR_TYPE(ch4_data[0]));
result[1] = FUNC_CALL(apply_pooling)(result[1], TO_ACCUMULATOR_TYPE(ch4_data[1]));
result[2] = FUNC_CALL(apply_pooling)(result[2], TO_ACCUMULATOR_TYPE(ch4_data[2]));
result[3] = FUNC_CALL(apply_pooling)(result[3], TO_ACCUMULATOR_TYPE(ch4_data[3]));;
result[3] = FUNC_CALL(apply_pooling)(result[3], TO_ACCUMULATOR_TYPE(ch4_data[3]));
input_idx += IN_X_PITCH;
}

View File

@@ -90,7 +90,7 @@ KERNEL(reverse_ref)(
#if INPUT0_DIMS >= 5
else if (axis[i] == Z_INDEX) {
printf("outputZ %d", OUTPUT_SIZE_Z);
z = OUTPUT_SIZE_Z - z- 1;
z = OUTPUT_SIZE_Z - z - 1;
}
#if INPUT0_DIMS == 6
else if (axis[i] == W_INDEX) {

View File

@@ -41,7 +41,7 @@ KERNEL(softmax)(
ACCUMULATOR_TYPE denominator = 0.0;
for (uint cls = 0; cls < INPUT0_CLASS_NUM; ++cls)
{
data[cls] = native_exp(data[cls] - max_value);;
data[cls] = native_exp(data[cls] - max_value);
denominator += data[cls];
}

View File

@@ -14,34 +14,33 @@
namespace ov {
namespace intel_gpu {
static cldnn::softmax::dimension_t GetSoftmaxAxis(int64_t axis, size_t rank) {
switch (axis) {
case 0: return cldnn::softmax::normalize_b;
case 1: return cldnn::softmax::normalize_f;
case 2:
if (rank > 4)
return cldnn::softmax::normalize_z;
else
return cldnn::softmax::normalize_y;
case 3:
if (rank > 4)
return cldnn::softmax::normalize_y;
else
return cldnn::softmax::normalize_x;
case 4:
return cldnn::softmax::normalize_x;
default: IE_THROW() << "Invalid softmax axis " << axis;
}
return cldnn::softmax::normalize_fyx;
}
static void CreateSoftmaxOp(Program& p, const std::shared_ptr<ngraph::op::v1::Softmax>& op) {
p.ValidateInputs(op, {1});
auto inputPrimitives = p.GetInputPrimitiveIDs(op);
std::string layerName = layer_type_name_ID(op);
auto softmaxPrim = cldnn::softmax(layerName,
inputPrimitives[0],
GetSoftmaxAxis(op->get_axis(), op->get_input_shape(0).size()),
op->get_axis(),
op->get_friendly_name());
p.AddPrimitive(softmaxPrim);
p.AddPrimitiveToProfiler(op);
}
static void CreateSoftmaxOp(Program& p, const std::shared_ptr<ngraph::op::v8::Softmax>& op) {
p.ValidateInputs(op, {1});
auto inputPrimitives = p.GetInputPrimitiveIDs(op);
std::string layerName = layer_type_name_ID(op);
int64_t axis = op->get_axis();
size_t rank = op->get_input_shape(0).size();
if (axis < 0)
axis += rank;
if (axis < 0 || axis >= static_cast<int64_t>(rank))
IE_THROW() << "Softmax axis is not correspond to number of dimensions";
auto softmaxPrim = cldnn::softmax(layerName,
inputPrimitives[0],
axis,
op->get_friendly_name());
p.AddPrimitive(softmaxPrim);
p.AddPrimitiveToProfiler(op);
@@ -59,7 +58,7 @@ static void CreateLogSoftmaxOp(Program& p, const std::shared_ptr<ngraph::op::v5:
auto softmaxPrim = cldnn::softmax(layerNameSoftmax,
inputPrimitives[0],
GetSoftmaxAxis(static_cast<size_t>(axis), op->get_input_shape(0).size()),
axis,
op->get_friendly_name());
auto logPrim = cldnn::activation(layerName, layerNameSoftmax, cldnn::activation_func::log, {(0.0F), (0.0F)}, op->get_friendly_name());
@@ -71,6 +70,7 @@ static void CreateLogSoftmaxOp(Program& p, const std::shared_ptr<ngraph::op::v5:
}
REGISTER_FACTORY_IMPL(v1, Softmax);
REGISTER_FACTORY_IMPL(v8, Softmax);
REGISTER_FACTORY_IMPL(v5, LogSoftmax);
} // namespace intel_gpu

View File

@@ -399,7 +399,7 @@ QueryNetworkResult Plugin::QueryNetwork(const CNNNetwork& network,
auto ops = func->get_ordered_ops();
//Mark removed nodes as supported
std::unordered_set<std::string> supported = GetRemovedNodes(function, func);;
std::unordered_set<std::string> supported = GetRemovedNodes(function, func);
std::unordered_set<std::string> unsupported;
std::unordered_set<std::string> supportedNotOriginal;
@@ -599,7 +599,7 @@ Parameter Plugin::GetConfig(const std::string& name, const std::map<std::string,
} else if (name == ov::num_streams) {
return ov::util::from_string(val, ov::num_streams);
} else if (name == ov::hint::num_requests) {
auto temp = ov::util::from_string(val, ov::hint::num_requests);;
auto temp = ov::util::from_string(val, ov::hint::num_requests);
return temp;
} else if (name == ov::device::id) {
return ov::util::from_string(val, ov::device::id);

View File

@@ -74,6 +74,7 @@
#include <transformations/op_conversions/simplify_ctc_greedy_decoder_seq_len.hpp>
#include "transformations/op_conversions/softmax_decomposition.hpp"
#include <transformations/op_conversions/gelu7_downgrade.hpp>
#include <transformations/op_conversions/convert_softmax_downgrade.hpp>
#include <transformations/convert_precision.hpp>
#include <transformations/init_node_info.hpp>
#include <transformations/rt_info/fused_names_attribute.hpp>
@@ -321,6 +322,7 @@ void TransformationsPipeline::apply(std::shared_ptr<ov::Model> func) {
pass_config->disable<ngraph::pass::ConvertBroadcast3>();
pass_config->disable<ngraph::pass::WeightsDequantizeToFakeQuantize>();
pass_config->disable<ngraph::pass::SimplifyCTCGreedyDecoderSeqLen>();
pass_config->disable<ngraph::pass::ConvertSoftMax8ToSoftMax1>();
pass_config->enable<ngraph::pass::ConvertGather8ToGather7>();
if (!config.enable_loop_unrolling) {

View File

@@ -22,7 +22,7 @@ struct softmax_test_params {
tensor in_shape;
data_types data_type;
format input_format;
softmax::dimension_t dimension;
int64_t dimension;
data_types default_type;
format default_format;
size_t expected_fused_primitives;
@@ -65,13 +65,11 @@ public:
/* ----------------------------------------------------------------------------------------------------- */
/* ---------------------------------------- SoftMax cases ---------------------------------------------- */
/* ----------------------------------------------------------------------------------------------------- */
#define CASE_SOFTMAX_FP32_1 {1, 15, 4, 5}, data_types::f32, format::bfyx, softmax::dimension_t::normalize_f, data_types::f32, format::bfyx
#define CASE_SOFTMAX_FP32_2 {1, 15, 4, 5}, data_types::f32, format::bfyx, softmax::dimension_t::normalize_x, data_types::f32, format::bfyx
#define CASE_SOFTMAX_FP32_3 {1, 15, 4, 5}, data_types::f32, format::bfyx, softmax::dimension_t::normalize_fyx, data_types::f32, format::bfyx
#define CASE_SOFTMAX_FP32_1 {1, 15, 4, 5}, data_types::f32, format::bfyx, 1, data_types::f32, format::bfyx
#define CASE_SOFTMAX_FP32_2 {1, 15, 4, 5}, data_types::f32, format::bfyx, 3, data_types::f32, format::bfyx
#define CASE_SOFTMAX_FP16_1 {1, 15, 4, 5}, data_types::f16, format::bfyx, softmax::dimension_t::normalize_f, data_types::f16, format::bfyx
#define CASE_SOFTMAX_FP16_2 {1, 15, 4, 5}, data_types::f16, format::bfyx, softmax::dimension_t::normalize_x, data_types::f16, format::bfyx
#define CASE_SOFTMAX_FP16_3 {1, 15, 4, 5}, data_types::f16, format::bfyx, softmax::dimension_t::normalize_fyx, data_types::f16, format::bfyx
#define CASE_SOFTMAX_FP16_1 {1, 15, 4, 5}, data_types::f16, format::bfyx, 1, data_types::f16, format::bfyx
#define CASE_SOFTMAX_FP16_2 {1, 15, 4, 5}, data_types::f16, format::bfyx, 3, data_types::f16, format::bfyx
class softmax_quantize : public SoftmaxPrimitiveFusingTest {};
TEST_P(softmax_quantize, basic) {
@@ -94,11 +92,9 @@ INSTANTIATE_TEST_SUITE_P(fusings_gpu, softmax_quantize,
::testing::ValuesIn(std::vector<softmax_test_params>{
softmax_test_params{ CASE_SOFTMAX_FP32_1, 2, 3 },
softmax_test_params{ CASE_SOFTMAX_FP32_2, 3, 3 },
softmax_test_params{ CASE_SOFTMAX_FP32_3, 3, 3 },
softmax_test_params{ CASE_SOFTMAX_FP16_1, 2, 3 },
softmax_test_params{ CASE_SOFTMAX_FP16_2, 3, 3 },
softmax_test_params{ CASE_SOFTMAX_FP16_3, 3, 3 },
}));
class softmax_quantize_fusing_through : public SoftmaxPrimitiveFusingTest {};

View File

@@ -31,7 +31,7 @@ TEST(experimental_detectron_topk_rois_gpu_fp32, check_set_indices_layer) {
{3, 1});
const std::string input_rois_id = "InputRois";
const std::string input_indices_id = "InputIndices";;
const std::string input_indices_id = "InputIndices";
const std::string experimental_detectron_topk_rois_id = "experimental_detectron_topk_rois";
topology topology;
topology.add(input_layout(input_rois_id, roi_input->get_layout()));

View File

@@ -1536,7 +1536,7 @@ TEST(reorder_gpu_opt, mean_mul)
cldnn::mem_lock<float> ptr(output, get_test_stream());
float* a_ptr = answers;
for (auto& val : ptr)
EXPECT_FLOAT_EQ(*(a_ptr++), val);;
EXPECT_FLOAT_EQ(*(a_ptr++), val);
}
@@ -1571,7 +1571,7 @@ TEST(reorder_gpu_opt, mean_div)
cldnn::mem_lock<float> ptr(output, get_test_stream());
float* a_ptr = answers;
for (auto& val : ptr)
EXPECT_FLOAT_EQ(*(a_ptr++), val);;
EXPECT_FLOAT_EQ(*(a_ptr++), val);
}
@@ -1602,7 +1602,7 @@ TEST(reorder_gpu_opt, mean_mul_val)
cldnn::mem_lock<float> ptr(output, get_test_stream());
float* a_ptr = answers;
for (auto& val : ptr)
EXPECT_FLOAT_EQ(*(a_ptr++), val);;
EXPECT_FLOAT_EQ(*(a_ptr++), val);
}
TEST(reorder_gpu_opt, mean_mul_val_float_to_int)

View File

@@ -68,7 +68,7 @@ TEST_F(softmax_gpu_xb_f32_test_fixture, input_same_values) {
set_values(input, in_b);
network network(engine, topology(input_layout("input", input->get_layout()), softmax("softmax", "input")));
network network(engine, topology(input_layout("input", input->get_layout()), softmax("softmax", "input", 3)));
network.set_input_data("input", input);
auto outputs = network.execute();
@@ -78,8 +78,7 @@ TEST_F(softmax_gpu_xb_f32_test_fixture, input_same_values) {
auto output_prim = outputs.begin()->second.get_memory();
cldnn::mem_lock<float> output_ptr(output_prim, get_test_stream());
for (uint32_t i = 0; i < out_size; i++)
{
for (uint32_t i = 0; i < out_size; i++) {
out_buffer[i] = output_ptr[i];
}
compare_out_buffer_with_expected();
@@ -98,7 +97,7 @@ TEST_F(softmax_gpu_xb_f32_test_fixture, input_same_values_batch_wise) {
for(size_t i = 0; i < out_size; ++i)
expected_buffer[i] = 0.1f;
network network(engine, topology(input_layout("input", input->get_layout()), softmax("softmax", "input")));
network network(engine, topology(input_layout("input", input->get_layout()), softmax("softmax", "input", 3)));
network.set_input_data("input", input);
auto outputs = network.execute();
@@ -108,8 +107,7 @@ TEST_F(softmax_gpu_xb_f32_test_fixture, input_same_values_batch_wise) {
auto output_prim = outputs.begin()->second.get_memory();
cldnn::mem_lock<float> output_ptr(output_prim, get_test_stream());
for (uint32_t i = 0; i < out_size; i++)
{
for (uint32_t i = 0; i < out_size; i++) {
out_buffer[i] = output_ptr[i];
}
compare_out_buffer_with_expected_batch_wise();
@@ -153,7 +151,7 @@ TEST_F(softmax_gpu_xb_f32_test_fixture, values_batch_wise) {
for(size_t i = 0; i < out_size; ++i)
out_buffer[i] = NAN;
network network(engine, topology(input_layout("input", input->get_layout()), softmax("softmax", "input")));
network network(engine, topology(input_layout("input", input->get_layout()), softmax("softmax", "input", 3)));
network.set_input_data("input", input);
auto outputs = network.execute();
@@ -163,96 +161,22 @@ TEST_F(softmax_gpu_xb_f32_test_fixture, values_batch_wise) {
auto output_prim = outputs.begin()->second.get_memory();
cldnn::mem_lock<float> output_ptr(output_prim, get_test_stream());
for (uint32_t i = 0; i < out_size; i++)
{
for (uint32_t i = 0; i < out_size; i++) {
out_buffer[i] = output_ptr[i];
}
compare_out_buffer_with_expected_batch_wise();
}
TEST(softmax_gpu_bfyx_f32, normalize_fyx) {
// Input : 2x3x2x2
static const int32_t x_size = 2, y_size = 2, feature_num = 3,
batch_num = 2, buf_size = x_size*y_size * batch_num * feature_num;
auto& engine = get_test_engine();
auto input = engine.allocate_memory({ data_types::f32, format::bfyx,{ batch_num, feature_num, x_size , y_size } });
topology topology;
topology.add(input_layout("input", input->get_layout()));
topology.add(softmax("softmax", "input"));
set_values(input, { //bfyx
//y0x0 y0x1 y1x0 y1x1
/*b0f0*/0.1f, -0.1f, 0.9f, 1.5f,
/*b0f1*/0.2f, 0.2f, -10.f, 5.2f,
/*b1f2*/0.2f, 0.2f, -10.f, 5.2f,
/*b1f0*/3.f, 0.5f, 7.f, 12.f,
/*b1f1*/4.f, 0.5f, 8.f, 8.2f,
/*b1f2*/0.2f, 0.2f, -10.f, 5.2f
});
float expected_max_values[2] = {
0.481618381f, 0.953259517f
};
network network(engine, topology);
network.set_input_data("input", input);
auto outputs = network.execute();
EXPECT_EQ(outputs.size(), size_t(1));
EXPECT_EQ(outputs.begin()->first, "softmax");
auto output = outputs.at("softmax").get_memory();
cldnn::mem_lock<float> output_ptr(output, get_test_stream());
float out_buffer[buf_size];
for (uint32_t i = 0; i < buf_size; i++)
{
out_buffer[i] = output_ptr[i];
}
float sum = 0;
float expected_sum = 1.0f;
float temp_max = 0;
int max_value_buffer_index = 0;
for (uint32_t i = 0; i < batch_num; i++) //this for loops will sum results in a batch per feature, we expect that: sum = 1.0f
{
for (uint32_t j = 0; j < y_size; j++)
{
for (uint32_t k = 0; k < x_size; k++)
{
for (uint32_t l = 0; l < feature_num; l++)
{
int index = i * feature_num * x_size * y_size + j * x_size + k + l * x_size * y_size;
sum += out_buffer[index];
if (out_buffer[index] >= temp_max)
{
temp_max = out_buffer[index];
}
}
}
}
EXPECT_EQ(true, are_equal(sum, expected_sum));
sum = 0.0f;
EXPECT_EQ(true, are_equal(temp_max, expected_max_values[max_value_buffer_index]));
temp_max = 0;
max_value_buffer_index++;
}
}
TEST(softmax_gpu_bfyx_f32, normalize_y) {
// Input : 2x3x2x2
static const int32_t x_size = 2, y_size = 2, feature_num = 3,
batch_num = 2, buf_size = x_size*y_size * batch_num * feature_num;
auto& engine = get_test_engine();
auto input = engine.allocate_memory({ data_types::f32, format::bfyx,{ batch_num, feature_num, x_size , y_size } });
auto input = engine.allocate_memory({ data_types::f32, format::bfyx, { batch_num, feature_num, x_size, y_size } });
topology topology;
topology.add(input_layout("input", input->get_layout()));
topology.add(softmax("softmax", "input", softmax::normalize_y));
topology.add(softmax("softmax", "input", 2));
vector<float> input_vec = {
//y0x0 y0x1 y1x0 y1x1
@@ -297,33 +221,25 @@ TEST(softmax_gpu_bfyx_f32, normalize_y) {
auto output = outputs.at("softmax").get_memory();
cldnn::mem_lock<float> output_ptr(output, get_test_stream());
float out_buffer[buf_size];
for (uint32_t i = 0; i < buf_size; i++)
{
for (uint32_t i = 0; i < buf_size; i++) {
out_buffer[i] = output_ptr[i];
}
float temp_max = 0;
float expected_sum = 1.0f;
int max_value_buffer_index = 0;
for (uint32_t i = 0; i < batch_num; i++) //this for loops will sum results in a batch per feature, we expect that: sum = 1.0f
{
for (uint32_t l = 0; l < feature_num; l++)
{
for (uint32_t k = 0; k < x_size; k++)
{
for (uint32_t i = 0; i < batch_num; i++) { //this for loops will sum results in a batch per feature, we expect that: sum = 1.0f
for (uint32_t l = 0; l < feature_num; l++) {
for (uint32_t k = 0; k < x_size; k++) {
float sum = 0.0f;
for (uint32_t j = 0; j < y_size; j++)
{
for (uint32_t j = 0; j < y_size; j++) {
int index = i * feature_num * x_size * y_size +
l * x_size * y_size +
j * x_size +
k;
if (out_buffer[index] >= temp_max)
{
l * x_size * y_size +
j * x_size +
k;
if (out_buffer[index] >= temp_max) {
temp_max = out_buffer[index];
}
sum += out_buffer[index];
}
EXPECT_EQ(true, are_equal(temp_max, expected_max_values[max_value_buffer_index]));
@@ -343,10 +259,10 @@ TEST(softmax_gpu_bfyx_f32, normalize_f) {
batch_num = 2, buf_size = x_size*y_size * batch_num * feature_num;
auto& engine = get_test_engine();
auto input = engine.allocate_memory({ data_types::f32, format::bfyx,{ batch_num, feature_num, x_size , y_size } });
auto input = engine.allocate_memory({ data_types::f32, format::bfyx, { batch_num, feature_num, x_size, y_size } });
topology topology;
topology.add(input_layout("input", input->get_layout()));
topology.add(softmax("softmax", "input", softmax::normalize_f));
topology.add(softmax("softmax", "input", 1));
vector<float> input_vec = {
//y0x0 y0x1 y1x0 y1x1
@@ -385,33 +301,25 @@ TEST(softmax_gpu_bfyx_f32, normalize_f) {
auto output = outputs.at("softmax").get_memory();
cldnn::mem_lock<float> output_ptr(output, get_test_stream());
float out_buffer[buf_size];
for (uint32_t i = 0; i < buf_size; i++)
{
for (uint32_t i = 0; i < buf_size; i++) {
out_buffer[i] = output_ptr[i];
}
float temp_max = 0;
float expected_sum = 1.0f;
int max_value_buffer_index = 0;
for (uint32_t i = 0; i < batch_num; i++) //this for loops will sum results in a batch per feature, we expect that: sum = 1.0f
{
for (uint32_t j = 0; j < y_size; j++)
{
for (uint32_t k = 0; k < x_size; k++)
{
for (uint32_t i = 0; i < batch_num; i++) { //this for loops will sum results in a batch per feature, we expect that: sum = 1.0f
for (uint32_t j = 0; j < y_size; j++) {
for (uint32_t k = 0; k < x_size; k++) {
float sum = 0.0f;
for (uint32_t l = 0; l < feature_num; l++)
{
for (uint32_t l = 0; l < feature_num; l++) {
int index = i * feature_num * x_size * y_size +
l * x_size * y_size +
j * x_size +
k;
if (out_buffer[index] >= temp_max)
{
l * x_size * y_size +
j * x_size +
k;
if (out_buffer[index] >= temp_max) {
temp_max = out_buffer[index];
}
sum += out_buffer[index];
}
EXPECT_EQ(true, are_equal(temp_max, expected_max_values[max_value_buffer_index]));
@@ -425,93 +333,16 @@ TEST(softmax_gpu_bfyx_f32, normalize_f) {
}
}
TEST(softmax_gpu_yxfb_f32, normalize_f) {
static const int32_t x_size = 1, y_size = 2, feature_num = 1,
batch_num = 12, buf_size = x_size*y_size * batch_num * feature_num;
auto& engine = get_test_engine();
auto input = engine.allocate_memory({ data_types::f32, format::yxfb,{ batch_num, feature_num, y_size , x_size } });
topology topology;
topology.add(input_layout("input", input->get_layout()));
topology.add(softmax("softmax", "input", softmax::normalize_fyx));
set_values(input, { //yxfb
//f0b0 f0b1 f0b2 f0b3 f0b4 f0b5 f0b6 f0b7 f0b8 f0b9 f0b10 f0b11
/*y0x0*/ 0.1f, -0.1f, 0.9f, 1.5f, 0.15f, -0.01f, 0.19f, 0.45f, 0.41f, -0.12f, 0.39f, 0.65f,
/*y1x0*/ 0.2f, 0.2f, -10.f, 5.2f, 0.01f, 0.015f, 0.29f, 0.05f, 0.41f, -0.31f, 0.29f, 1.35f
});
float expected_max_values[batch_num * feature_num * x_size] = {
0.524979174f,
0.574442506f,
0.999981523f,
0.975872993f,
0.534942925f,
0.506249666f,
0.524979174f,
0.598687649f,
0.500000000f,
0.547357619f,
0.524979174f,
0.668187797f
};
network network(engine, topology);
network.set_input_data("input", input);
auto outputs = network.execute();
EXPECT_EQ(outputs.size(), size_t(1));
EXPECT_EQ(outputs.begin()->first, "softmax");
auto output = outputs.at("softmax").get_memory();
cldnn::mem_lock<float> output_ptr(output, get_test_stream());
float out_buffer[buf_size];
for (uint32_t i = 0; i < buf_size; i++)
{
out_buffer[i] = output_ptr[i];
}
float expected_sum = 1.0f;
float temp_max = 0;
for (uint32_t b = 0; b < batch_num; b++)
{
for (uint32_t f = 0; f < feature_num; f++)
{
for (uint32_t x = 0; x < x_size; x++)
{
float sum = 0.0f;
for (uint32_t y = 0; y < y_size; y++)
{
int index = b + y * batch_num + f * feature_num + x * x_size;
if (out_buffer[index] >= temp_max)
{
temp_max = out_buffer[index];
}
sum += out_buffer[index];
}
EXPECT_EQ(true, are_equal(temp_max, expected_max_values[b * feature_num * x_size + f * x_size + x]));
temp_max = 0;
EXPECT_EQ(true, are_equal(sum, expected_sum));
sum = 0.0f;
}
}
}
}
TEST(softmax_gpu_bfzyx_f32, normalize_z) {
// Input : 2x3x2x2x2
static const int32_t x_size = 2, y_size = 2, z_size = 2, feature_num = 3,
batch_num = 2, buf_size = x_size *y_size * z_size * batch_num * feature_num;
auto& engine = get_test_engine();
auto input = engine.allocate_memory({ data_types::f32, format::bfzyx,{ batch_num, feature_num, x_size , y_size, z_size } });
auto input = engine.allocate_memory({ data_types::f32, format::bfzyx, { batch_num, feature_num, x_size, y_size, z_size } });
topology topology;
topology.add(input_layout("input", input->get_layout()));
topology.add(softmax("softmax", "input", softmax::normalize_z));
topology.add(softmax("softmax", "input", 2));
vector<float> input_vec = {
// z0y0x0 z0y0x1 z0y1x0 z0y1x1 z1y0x0 z1y0x1 z1y1x0 z1y1x1
@@ -551,36 +382,27 @@ TEST(softmax_gpu_bfzyx_f32, normalize_z) {
auto output = outputs.at("softmax").get_memory();
cldnn::mem_lock<float> output_ptr(output, get_test_stream());
float out_buffer[buf_size];
for (uint32_t i = 0; i < buf_size; i++)
{
for (uint32_t i = 0; i < buf_size; i++) {
out_buffer[i] = output_ptr[i];
}
float temp_max = 0;
float expected_sum = 1.0f;
int max_value_buffer_index = 0;
for (uint32_t i = 0; i < batch_num; i++)
{
for (uint32_t l = 0; l < feature_num; l++)
{
for (uint32_t j = 0; j < y_size; j++)
{
for (uint32_t k = 0; k < x_size; k++)
{
for (uint32_t i = 0; i < batch_num; i++) {
for (uint32_t l = 0; l < feature_num; l++) {
for (uint32_t j = 0; j < y_size; j++) {
for (uint32_t k = 0; k < x_size; k++) {
float sum = 0.0f;
for (uint32_t m = 0; m < z_size; m++)
{
for (uint32_t m = 0; m < z_size; m++) {
int index = i * feature_num * x_size * y_size * z_size +
l * x_size * y_size * z_size +
m * x_size * y_size +
j * x_size +
k;
if (out_buffer[index] >= temp_max)
{
l * x_size * y_size * z_size +
m * x_size * y_size +
j * x_size +
k;
if (out_buffer[index] >= temp_max) {
temp_max = out_buffer[index];
}
sum += out_buffer[index];
}
EXPECT_EQ(true, are_equal(temp_max, expected_max_values[max_value_buffer_index]));
@@ -594,242 +416,16 @@ TEST(softmax_gpu_bfzyx_f32, normalize_z) {
}
}
TEST(softmax_gpu_bfyx_f32, normalize_all) {
// Input : 2x3x2x2
static const int32_t x_size = 2, y_size = 2, feature_num = 3,
batch_num = 2, buf_size = x_size * y_size * batch_num * feature_num;
auto& engine = get_test_engine();
auto input = engine.allocate_memory({data_types::f32, format::bfyx, {batch_num, feature_num, x_size, y_size}});
topology topology;
topology.add(input_layout("input", input->get_layout()));
topology.add(softmax("softmax", "input", softmax::normalize_all));
set_values(input, {//bfyx
// y0x0 y0x1 y1x0 y1x1
/*b0f0*/ 0.1f, -0.1f, 0.9f, 1.5f,
/*b0f1*/ 0.2f, 0.2f, -10.f, 5.2f,
/*b0f2*/ 0.2f, 0.2f, -10.f, 5.2f,
/*b1f0*/ 3.f, 0.5f, 7.f, 12.f,
/*b1f1*/ 4.f, 0.5f, 8.f, 8.2f,
/*b1f2*/ 0.2f, 0.2f, -10.f, 5.2f});
network network(engine, topology);
network.set_input_data("input", input);
auto outputs = network.execute();
EXPECT_EQ(outputs.size(), size_t(1));
EXPECT_EQ(outputs.begin()->first, "softmax");
auto output = outputs.at("softmax").get_memory();
cldnn::mem_lock<float> output_ptr(output, get_test_stream());
float sum = 0.0f;
float expected_sum = 1.0f;
for (uint32_t i = 0; i < buf_size; i++) {
sum += output_ptr[i];
}
EXPECT_EQ(true, are_equal(sum, expected_sum));
}
TEST(softmax_gpu_yxfb_f32, normalize_all) {
// Input : 2x2x3x2
static const int32_t x_size = 2, y_size = 2, feature_num = 3,
batch_num = 2, buf_size = x_size * y_size * batch_num * feature_num;
auto& engine = get_test_engine();
auto input = engine.allocate_memory({data_types::f32, format::yxfb, {y_size, x_size, feature_num, batch_num}});
topology topology;
topology.add(input_layout("input", input->get_layout()));
topology.add(softmax("softmax", "input", softmax::normalize_all));
set_values(input, {//yxfb
// f0b0 f0b1 f1b0 f1b1
/*y0x0*/ 0.1f, -0.1f, 0.9f, 1.5f,
/*y0x1*/ 0.2f, 0.2f, -10.f, 5.2f,
/*y0x2*/ 0.2f, 0.2f, -10.f, 5.2f,
/*y1x0*/ 3.f, 0.5f, 7.f, 12.f,
/*y1x1*/ 4.f, 0.5f, 8.f, 8.2f,
/*y1x2*/ 0.2f, 0.2f, -10.f, 5.2f});
network network(engine, topology);
network.set_input_data("input", input);
auto outputs = network.execute();
EXPECT_EQ(outputs.size(), size_t(1));
EXPECT_EQ(outputs.begin()->first, "softmax");
auto output = outputs.at("softmax").get_memory();
cldnn::mem_lock<float> output_ptr(output, get_test_stream());
float sum = 0.0f;
float expected_sum = 1.0f;
for (uint32_t i = 0; i < buf_size; i++) {
sum += output_ptr[i];
}
EXPECT_EQ(true, are_equal(sum, expected_sum));
}
TEST(softmax_gpu_bfzyx_f32, normalize_all) {
// Input : 2x3x2x2x2
static const int32_t x_size = 2, y_size = 2, z_size = 2, feature_num = 3,
batch_num = 2, buf_size = x_size * y_size * z_size * batch_num * feature_num;
auto& engine = get_test_engine();
auto input = engine.allocate_memory({data_types::f32, format::bfzyx, {batch_num, feature_num, x_size, y_size, z_size}});
topology topology;
topology.add(input_layout("input", input->get_layout()));
topology.add(softmax("softmax", "input", softmax::normalize_all));
set_values(input, {// z0y0x0 z0y0x1 z0y1x0 z0y1x1 z1y0x0 z1y0x1 z1y1x0 z1y1x1
/*b0f0*/ 0.1f, -0.1f, 0.9f, 1.5f, 0.2f, -0.2f, 0.9f, 2.5f,
/*b0f1*/ 0.2f, 0.2f, -10.f, 5.2f, 0.3f, 0.1f, -11.f, 6.2f,
/*b0f2*/ 0.2f, 0.2f, -10.f, 5.2f, 0.1f, 0.3f, -9.f, 4.2f,
/*b1f0*/ 3.f, 0.5f, 7.f, 12.f, 5.f, 0.1f, 6.f, 22.f,
/*b1f1*/ 4.f, 0.5f, 8.f, 8.2f, 2.2f, 0.3f, 6.f, 5.2f,
/*b1f2*/ 0.2f, 0.2f, -10.f, 5.2f, 1.2f, 0.3f, -12.f, 2.2f});
network network(engine, topology);
network.set_input_data("input", input);
auto outputs = network.execute();
EXPECT_EQ(outputs.size(), size_t(1));
EXPECT_EQ(outputs.begin()->first, "softmax");
auto output = outputs.at("softmax").get_memory();
cldnn::mem_lock<float> output_ptr(output, get_test_stream());
float sum = 0.0f;
float expected_sum = 1.0f;
for (uint32_t i = 0; i < buf_size; i++) {
sum += output_ptr[i];
}
EXPECT_EQ(true, are_equal(sum, expected_sum));
}
TEST(softmax_gpu_bfyx_f16, normalize_all) {
// Input : 2x3x2x2
static const int32_t x_size = 2, y_size = 2, feature_num = 3,
batch_num = 2, buf_size = x_size * y_size * batch_num * feature_num;
auto& engine = get_test_engine();
auto input = engine.allocate_memory({data_types::f16, format::bfyx, {batch_num, feature_num, x_size, y_size}});
topology topology;
topology.add(input_layout("input", input->get_layout()));
topology.add(softmax("softmax", "input", softmax::normalize_all));
set_values(input, {//bfyx
// y0x0 y0x1 y1x0 y1x1
/*b0f0*/ FLOAT16(0.1f), FLOAT16(-0.1f), FLOAT16(0.9f), FLOAT16(1.5f),
/*b0f1*/ FLOAT16(0.2f), FLOAT16(0.2f), FLOAT16(-10.f), FLOAT16(5.2f),
/*b0f2*/ FLOAT16(0.2f), FLOAT16(0.2f), FLOAT16(-10.f), FLOAT16(5.2f),
/*b1f0*/ FLOAT16(3.f), FLOAT16(0.5f), FLOAT16(7.f), FLOAT16(12.f),
/*b1f1*/ FLOAT16(4.f), FLOAT16(0.5f), FLOAT16(8.f), FLOAT16(8.2f),
/*b1f2*/ FLOAT16(0.2f), FLOAT16(0.2f), FLOAT16(-10.f), FLOAT16(5.2f)});
network network(engine, topology);
network.set_input_data("input", input);
auto outputs = network.execute();
EXPECT_EQ(outputs.size(), size_t(1));
EXPECT_EQ(outputs.begin()->first, "softmax");
auto output = outputs.at("softmax").get_memory();
cldnn::mem_lock<uint16_t> output_ptr(output, get_test_stream());
float sum = 0.0f;
float expected_sum = 1.0f;
for (uint32_t i = 0; i < buf_size; i++) {
sum += float16_to_float32(output_ptr[i]);
}
ASSERT_NEAR(sum, expected_sum, 0.001);
}
TEST(softmax_gpu_yxfb_f16, normalize_all) {
// Input : 2x2x3x2
static const int32_t x_size = 2, y_size = 2, feature_num = 3,
batch_num = 2, buf_size = x_size * y_size * batch_num * feature_num;
auto& engine = get_test_engine();
auto input = engine.allocate_memory({data_types::f16, format::yxfb, {y_size, x_size, feature_num, batch_num}});
topology topology;
topology.add(input_layout("input", input->get_layout()));
topology.add(softmax("softmax", "input", softmax::normalize_all));
set_values(input, {//yxfb
// f0b0 f0b1 f1b0 f1b1
/*y0x0*/ FLOAT16(0.1f), FLOAT16(-0.1f), FLOAT16(0.9f), FLOAT16(1.5f),
/*y0x1*/ FLOAT16(0.2f), FLOAT16(0.2f), FLOAT16(-10.f), FLOAT16(5.2f),
/*y0x2*/ FLOAT16(0.2f), FLOAT16(0.2f), FLOAT16(-10.f), FLOAT16(5.2f),
/*y1x0*/ FLOAT16(3.f), FLOAT16(0.5f), FLOAT16(7.f), FLOAT16(12.f),
/*y1x1*/ FLOAT16(4.f), FLOAT16(0.5f), FLOAT16(8.f), FLOAT16(8.2f),
/*y1x2*/ FLOAT16(0.2f), FLOAT16(0.2f), FLOAT16(-10.f), FLOAT16(5.2f)});
network network(engine, topology);
network.set_input_data("input", input);
auto outputs = network.execute();
EXPECT_EQ(outputs.size(), size_t(1));
EXPECT_EQ(outputs.begin()->first, "softmax");
auto output = outputs.at("softmax").get_memory();
cldnn::mem_lock<uint16_t> output_ptr(output, get_test_stream());
float sum = 0.0f;
float expected_sum = 1.0f;
for (uint32_t i = 0; i < buf_size; i++) {
sum += float16_to_float32(output_ptr[i]);
}
ASSERT_NEAR(sum, expected_sum, 0.001);
}
TEST(softmax_gpu_bfzyx_f16, normalize_all) {
// Input : 2x3x2x2x2
static const int32_t x_size = 2, y_size = 2, z_size = 2, feature_num = 3,
batch_num = 2, buf_size = x_size * y_size * z_size * batch_num * feature_num;
auto& engine = get_test_engine();
auto input = engine.allocate_memory({data_types::f16, format::bfzyx, {batch_num, feature_num, x_size, y_size, z_size}});
topology topology;
topology.add(input_layout("input", input->get_layout()));
topology.add(softmax("softmax", "input", softmax::normalize_all));
set_values(input, {// z0y0x0 z0y0x1 z0y1x0 z0y1x1 z1y0x0 z1y0x1 z1y1x0 z1y1x1
/*b0f0*/ FLOAT16(0.1f), FLOAT16(-0.1f), FLOAT16(0.9f), FLOAT16(1.5f), FLOAT16(0.2f), FLOAT16(-0.2f), FLOAT16(0.9f), FLOAT16(2.5f),
/*b0f1*/ FLOAT16(0.2f), FLOAT16(0.2f), FLOAT16(-10.f), FLOAT16(5.2f), FLOAT16(0.3f), FLOAT16(0.1f), FLOAT16(-11.f), FLOAT16(6.2f),
/*b0f2*/ FLOAT16(0.2f), FLOAT16(0.2f), FLOAT16(-10.f), FLOAT16(5.2f), FLOAT16(0.1f), FLOAT16(0.3f), FLOAT16(-9.f), FLOAT16(4.2f),
/*b1f0*/ FLOAT16(3.f), FLOAT16(0.5f), FLOAT16(7.f), FLOAT16(12.f), FLOAT16(5.f), FLOAT16(0.1f), FLOAT16(6.f), FLOAT16(22.f),
/*b1f1*/ FLOAT16(4.f), FLOAT16(0.5f), FLOAT16(8.f), FLOAT16(8.2f), FLOAT16(2.2f), FLOAT16(0.3f), FLOAT16(6.f), FLOAT16(5.2f),
/*b1f2*/ FLOAT16(0.2f), FLOAT16(0.2f), FLOAT16(-10.f), FLOAT16(5.2f), FLOAT16(1.2f), FLOAT16(0.3f), FLOAT16(-12.f), FLOAT16(2.2f)});
network network(engine, topology);
network.set_input_data("input", input);
auto outputs = network.execute();
EXPECT_EQ(outputs.size(), size_t(1));
EXPECT_EQ(outputs.begin()->first, "softmax");
auto output = outputs.at("softmax").get_memory();
cldnn::mem_lock<uint16_t> output_ptr(output, get_test_stream());
float sum = 0.0f;
float expected_sum = 1.0f;
for (uint32_t i = 0; i < buf_size; i++) {
sum += float16_to_float32(output_ptr[i]);
}
ASSERT_NEAR(sum, expected_sum, 0.001);
}
TEST(softmax_gpu_bfyx_f32, normalize_b) {
// Input : 3x2x2x2
static const int32_t x_size = 2, y_size = 2, feature_num = 2,
batch_num = 3, buf_size = x_size*y_size * batch_num * feature_num;
auto& engine = get_test_engine();
auto input = engine.allocate_memory({ data_types::f32, format::bfyx,{ batch_num, feature_num, x_size , y_size } });
auto input = engine.allocate_memory({ data_types::f32, format::bfyx, { batch_num, feature_num, x_size, y_size } });
topology topology;
topology.add(input_layout("input", input->get_layout()));
topology.add(softmax("softmax", "input", softmax::normalize_b));
topology.add(softmax("softmax", "input", 0));
vector<float> input_vec = {
// y0x0 y0x1 y1x0 y1x1
@@ -869,33 +465,25 @@ TEST(softmax_gpu_bfyx_f32, normalize_b) {
auto output = outputs.at("softmax").get_memory();
cldnn::mem_lock<float> output_ptr(output, get_test_stream());
float out_buffer[buf_size];
for (uint32_t i = 0; i < buf_size; i++)
{
for (uint32_t i = 0; i < buf_size; i++) {
out_buffer[i] = output_ptr[i];
}
float temp_max = 0;
float expected_sum = 1.0f;
int max_value_buffer_index = 0;
for (uint32_t i = 0; i < feature_num; i++) //this for loops will sum results in a batch per feature, we expect that: sum = 1.0f
{
for (uint32_t j = 0; j < y_size; j++)
{
for (uint32_t k = 0; k < x_size; k++)
{
for (uint32_t i = 0; i < feature_num; i++) { //this for loops will sum results in a batch per feature, we expect that: sum = 1.0f
for (uint32_t j = 0; j < y_size; j++) {
for (uint32_t k = 0; k < x_size; k++) {
float sum = 0.0f;
for (uint32_t l = 0; l < batch_num; l++)
{
for (uint32_t l = 0; l < batch_num; l++) {
int index = l * feature_num * x_size * y_size +
i * x_size * y_size +
j * x_size +
k;
if (out_buffer[index] >= temp_max)
{
if (out_buffer[index] >= temp_max) {
temp_max = out_buffer[index];
}
sum += out_buffer[index];
}
EXPECT_EQ(true, are_equal(temp_max, expected_max_values[max_value_buffer_index]));
@@ -932,24 +520,19 @@ class softmax_test : public tests::generic_test
{
public:
softmax_test() : tests::generic_test()
{
}
softmax_test() : tests::generic_test() {}
void SetUp() override
{
void SetUp() override {
max_ulps_diff_allowed = 6;
}
static void TearDownTestCase()
{
static void TearDownTestCase() {
all_layer_params.clear();
all_generic_params.clear();
}
static std::vector<std::shared_ptr<cldnn::primitive>> generate_specific_test_params()
{
all_layer_params.emplace_back(new softmax("softmax", "input0", softmax::normalize_f));
static std::vector<std::shared_ptr<cldnn::primitive>> generate_specific_test_params() {
all_layer_params.emplace_back(new softmax("softmax", "input0", 1));
//The test checks only valid combinations.
//TODO: add more combinations.
@@ -957,21 +540,18 @@ public:
return all_layer_params;
}
static std::vector<std::shared_ptr<tests::test_params>> generate_generic_test_params()
{
static std::vector<std::shared_ptr<tests::test_params>> generate_generic_test_params() {
return generic_test::generate_generic_test_params(all_generic_params);
}
bool is_format_supported(cldnn::format format) override
{
bool is_format_supported(cldnn::format format) override {
return
format == cldnn::format::yxfb ||
format == cldnn::format::bfyx;
}
template<typename Type>
memory::ptr generate_reference_typed(const std::vector<memory::ptr> & inputs)
{
memory::ptr generate_reference_typed(const std::vector<memory::ptr>& inputs) {
assert(inputs.size() == 1);
const memory::ptr input = inputs[0];
@@ -1003,12 +583,10 @@ public:
for (int n = 0; n < in0_b; ++n)
for (int y = 0; y < in0_h; ++y)
for (int x = 0; x < in0_w; ++x)
{
for (int x = 0; x < in0_w; ++x) {
float max_val = -std::numeric_limits<float>::infinity();
for (int c = 0; c < in0_f; ++c)
{
for (int c = 0; c < in0_f; ++c) {
const size_t in0_idx = get_linear_index(input->get_layout(), n, c, y, x, input_desc);
max_val = std::max(max_val, static_cast<float>(in0_mem[in0_idx]));
@@ -1016,8 +594,7 @@ public:
float Z = 0;
for (int c = 0; c < in0_f; ++c)
{
for (int c = 0; c < in0_f; ++c) {
const size_t in0_idx = get_linear_index(input->get_layout(), n, c, y, x, input_desc);
float tmp = static_cast<float>((Type)std::exp(static_cast<float>(in0_mem[in0_idx]) - max_val));
@@ -1025,8 +602,7 @@ public:
cached_exp_vals[c] = tmp;
}
for (int c = 0; c < in0_f; ++c)
{
for (int c = 0; c < in0_f; ++c) {
const size_t out_idx = get_linear_index(output->get_layout(), n, c, y, x, input_desc);
out_mem[out_idx] = (Type)(cached_exp_vals[c] / Z);
}
@@ -1035,23 +611,18 @@ public:
return output;
}
virtual memory::ptr generate_reference(const std::vector<memory::ptr> & inputs) override
{
if (generic_params->data_type == data_types::f32)
{
virtual memory::ptr generate_reference(const std::vector<memory::ptr>& inputs) override {
if (generic_params->data_type == data_types::f32) {
return generate_reference_typed<float>(inputs);
}
else
{
} else {
return generate_reference_typed<FLOAT16>(inputs);
}
}
static std::string custom_param_name(const ::testing::TestParamInfo<std::tuple<std::shared_ptr<tests::test_params>, std::shared_ptr<cldnn::primitive>>>& info)
{
static std::string custom_param_name(const ::testing::TestParamInfo<std::tuple<std::shared_ptr<tests::test_params>, std::shared_ptr<cldnn::primitive>>>& info) {
std::stringstream res;
const auto & p = std::get<0>(info.param);
const auto& p = std::get<0>(info.param);
assert (p->data_type == data_types::f32 ||
p->data_type == data_types::f16);
@@ -1059,13 +630,11 @@ public:
res << info.index
<< "_" << (p->data_type == data_types::f32 ? "f32" : "f16");
for (unsigned i = 0; i < p->input_layouts.size(); ++i)
{
for (unsigned i = 0; i < p->input_layouts.size(); ++i) {
const auto chans = format::traits(p->fmt).order;
res << "_" << "Input" << i;
for (unsigned int j = 0; j < p->input_layouts[i].get_tensor().sizes(p->fmt).size(); ++j)
{
for (unsigned int j = 0; j < p->input_layouts[i].get_tensor().sizes(p->fmt).size(); ++j) {
res << chans[j] << p->input_layouts[i].get_tensor().sizes(p->fmt)[j];
}
}
@@ -1074,17 +643,14 @@ public:
}
private:
static std::vector<std::shared_ptr<tests::test_params>> all_generic_params;
static std::vector<std::shared_ptr<cldnn::primitive>> all_layer_params;
};
std::vector<std::shared_ptr<cldnn::primitive>> softmax_test::all_layer_params = {};
std::vector<std::shared_ptr<tests::test_params>> softmax_test::all_generic_params = {};
TEST_P(softmax_test, SOFTMAX)
{
TEST_P(softmax_test, SOFTMAX) {
run_single_test();
}