Skip to content

Commit

Permalink
[GPU] Type traits cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
vladimir-paramuzov committed Oct 13, 2023
1 parent 44a3255 commit d1fc752
Show file tree
Hide file tree
Showing 16 changed files with 83 additions and 154 deletions.
116 changes: 20 additions & 96 deletions src/plugins/intel_gpu/include/intel_gpu/runtime/layout.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
#include <limits>
#include <string>
#include <functional>
#include <set>

#include <openvino/core/partial_shape.hpp>
#include <openvino/core/type/element_type.hpp>
#include "openvino/core/partial_shape.hpp"
#include "openvino/core/type/element_type.hpp"
#include "openvino/core/type/element_type_traits.hpp"

#include "intel_gpu/graph/serialization/binary_buffer.hpp"
#include "intel_gpu/graph/serialization/vector_serializer.hpp"
Expand All @@ -28,33 +28,9 @@ namespace cldnn {
/// @addtogroup cpp_memory Memory description and management
/// @{

constexpr size_t float_type_mask = 0x80;
constexpr size_t uint_type_mask = 0x40;
constexpr size_t bin_type_mask = 0x20;

/// @brief Possible data types could be stored in memory.
using data_types = ov::element::Type_t;

/// Converts @ref data_types to C++ type.
template <data_types Data_Type>
struct data_type_to_type;
#ifndef DOXYGEN_SHOULD_SKIP_THIS
template <>
struct data_type_to_type<data_types::u1> { typedef uint32_t type; };
template <>
struct data_type_to_type<data_types::u8> { typedef uint8_t type; };
template <>
struct data_type_to_type<data_types::i8> { typedef int8_t type; };
template <>
struct data_type_to_type<data_types::i32> { typedef int32_t type; };
template <>
struct data_type_to_type<data_types::i64> { typedef int64_t type; };
template <>
struct data_type_to_type<data_types::f16> { typedef ov::float16 type; };
template <>
struct data_type_to_type<data_types::f32> { typedef float type; };
#endif

/// Helper class to identify key properties for data_types.
struct data_type_traits {
static size_t size_of(data_types data_type) {
Expand All @@ -72,52 +48,27 @@ struct data_type_traits {
return et.is_quantized() && et.bitwidth() == 8;
}

static size_t align_of(data_types data_type) {
switch (data_type) {
case data_types::u1:
return alignof(data_type_to_type<data_types::u1>::type);
case data_types::i8:
return alignof(data_type_to_type<data_types::i8>::type);
case data_types::u8:
return alignof(data_type_to_type<data_types::u8>::type);
case data_types::i32:
return alignof(data_type_to_type<data_types::i32>::type);
case data_types::i64:
return alignof(data_type_to_type<data_types::i64>::type);
case data_types::f16:
return alignof(data_type_to_type<data_types::f16>::type);
case data_types::f32:
return alignof(data_type_to_type<data_types::f32>::type);
default:
return size_t(1);
}
}

static std::string name(data_types data_type) {
return ov::element::Type(data_type).get_type_name();
}
static ov::element::Type max_type(ov::element::Type t1, ov::element::Type t2) {
if (t1 == ov::element::u1)
return t2;

static data_types max_type(data_types dt1, data_types dt2) {
if (dt1 == data_types::u1)
return dt2;
if (t2 == ov::element::u1)
return t1;

if (dt2 == data_types::u1)
return dt1;
if (t1.bitwidth() < t2.bitwidth())
return t2;

if (size_of(dt1) < size_of(dt2))
return dt2;
if (t1.bitwidth() > t2.bitwidth())
return t1;

if (size_of(dt1) > size_of(dt2))
return dt1;
if (t2.is_real())
return t2;

if (is_floating_point(dt2))
return dt2;

return dt1;
return t1;
}

static bool is_quantized(data_types dt) {
return is_i8_u8(dt);
static bool is_quantized(ov::element::Type t) {
return t.is_quantized();
}

template <typename T>
Expand All @@ -132,7 +83,7 @@ struct data_type_traits {
case data_types::i64:
return static_cast<T>(std::numeric_limits<int64_t>::max());
case data_types::f16:
return static_cast<T>(65504);
return static_cast<T>(std::numeric_limits<ov::float16>::max());
case data_types::f32:
return static_cast<T>(std::numeric_limits<float>::max());
default:
Expand All @@ -152,7 +103,7 @@ struct data_type_traits {
case data_types::i64:
return static_cast<T>(std::numeric_limits<int64_t>::lowest());
case data_types::f16:
return static_cast<T>(-65504);
return static_cast<T>(std::numeric_limits<ov::float16>::lowest());
case data_types::f32:
return static_cast<T>(std::numeric_limits<float>::lowest());
default:
Expand All @@ -170,44 +121,17 @@ inline data_types element_type_to_data_type(ov::element::Type t) {
switch (t) {
case ov::element::Type_t::i16:
case ov::element::Type_t::u16:
case ov::element::Type_t::f32:
case ov::element::Type_t::f64:
return cldnn::data_types::f32;
case ov::element::Type_t::f16:
return cldnn::data_types::f16;
case ov::element::Type_t::u8:
return cldnn::data_types::u8;
case ov::element::Type_t::i8:
return cldnn::data_types::i8;
case ov::element::Type_t::i32:
case ov::element::Type_t::u32:
case ov::element::Type_t::u64:
return cldnn::data_types::i32;
case ov::element::Type_t::i64:
return cldnn::data_types::i64;
case ov::element::Type_t::boolean:
return cldnn::data_types::u8;
case ov::element::Type_t::u1:
return cldnn::data_types::u1;
default:
throw std::runtime_error("Can't convert " + t.get_type_name() + " element type");
default: return t;
}
}

/// Helper function to get both data_types and format::type in a single, unique value. Useable in 'case' statement.
constexpr auto fuse(data_types dt, cldnn::format::type fmt) -> decltype(static_cast<std::underlying_type<data_types>::type>(dt) |
static_cast<std::underlying_type<format::type>::type>(fmt)) {
using dt_type = std::underlying_type<data_types>::type;
using fmt_type = std::underlying_type<cldnn::format::type>::type;
using fmt_narrow_type = int16_t;

return static_cast<fmt_type>(fmt) <= std::numeric_limits<fmt_narrow_type>::max() &&
static_cast<dt_type>(dt) <= (std::numeric_limits<dt_type>::max() >> (sizeof(fmt_narrow_type) * 8))
? (static_cast<dt_type>(dt) << (sizeof(fmt_narrow_type) * 8)) |
(static_cast<fmt_type>(fmt) >= 0 ? static_cast<fmt_narrow_type>(fmt) : static_cast<fmt_narrow_type>(-1))
: throw std::invalid_argument("data_type and/or format values are too big to be fused into single value");
}

/// @brief Represents data padding information.
struct padding {
/// @brief Filling value for padding area.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ struct ShapePredictor {
/// says if shape is successfully predicted and can be preallocated, and the second element is ov::Shape itself.
std::pair<bool, ov::Shape> predict_preallocation_shape(const std::string& id,
const ov::Shape& current_shape,
size_t dt_size,
size_t dt_bitwidth,
bool can_reuse_buffer);
bool can_preallocate(size_t desired_buffer_size);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ bool can_shuffle_features(program_node& node, stream& stream) {
if (node.is_type<convolution>()) {
auto& conv_node = node.as<convolution>();
auto& wei_node = conv_node.weights();
if (ov::element::Type(wei_node.get_output_layout().data_type).bitwidth() < 8)
return false;

return conv_node.get_groups() == 1 &&
conv_node.get_deformable_groups() == 1 && !conv_node.get_transposed() &&
Expand All @@ -32,6 +34,8 @@ bool can_shuffle_features(program_node& node, stream& stream) {
if (node.is_type<fully_connected>()) {
auto& fc_node = node.as<fully_connected>();
auto& wei_node = fc_node.weights();
if (ov::element::Type(wei_node.get_output_layout().data_type).bitwidth() < 8)
return false;

return wei_node.is_type<data>() && wei_node.is_constant() && !wei_node.is_output();
}
Expand Down
3 changes: 2 additions & 1 deletion src/plugins/intel_gpu/src/graph/impls/cpu/activation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
//

#include "openvino/core/type/element_type_traits.hpp"
#include "register.hpp"
#include "activation_inst.h"
#include "implementation_map.hpp"
Expand Down Expand Up @@ -108,7 +109,7 @@ struct activation_impl : public typed_primitive_impl<activation> {
input_host_tensors.push_back(make_tensor(params->input_layouts[i], input_mem_ptrs[i]->lock(stream, mem_lock_type::read)));

// Most of the evaluate functions expect same data type for all inputs, so we need to convert params from float
typename data_type_to_type<DT>::type param_a = static_cast<typename data_type_to_type<DT>::type>(additional_params.a);
auto param_a = static_cast<typename ov::element_type_traits<DT>::value_type>(additional_params.a);

auto input_dt = instance.get_input_layout().data_type;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -839,11 +839,11 @@ struct detection_output_impl : typed_primitive_impl<detection_output> {

std::vector<std::vector<std::pair<float, std::pair<int, int>>>> scoreIndexPairs;
if (instance.location_memory()->get_layout().data_type == data_types::f32) {
prepare_data<data_type_to_type<data_types::f32>::type>(stream, instance, bboxes, confidences, scoreIndexPairs);
generate_detections<data_type_to_type<data_types::f32>::type>(stream, instance, num_of_images, bboxes, confidences, scoreIndexPairs);
prepare_data<ov::element_type_traits<data_types::f32>::value_type>(stream, instance, bboxes, confidences, scoreIndexPairs);
generate_detections<ov::element_type_traits<data_types::f32>::value_type>(stream, instance, num_of_images, bboxes, confidences, scoreIndexPairs);
} else {
prepare_data<data_type_to_type<data_types::f16>::type>(stream, instance, bboxes, confidences, scoreIndexPairs);
generate_detections<data_type_to_type<data_types::f16>::type>(stream, instance, num_of_images, bboxes, confidences, scoreIndexPairs);
prepare_data<ov::element_type_traits<data_types::f16>::value_type>(stream, instance, bboxes, confidences, scoreIndexPairs);
generate_detections<ov::element_type_traits<data_types::f16>::value_type>(stream, instance, num_of_images, bboxes, confidences, scoreIndexPairs);
}

ev->set();
Expand Down
32 changes: 16 additions & 16 deletions src/plugins/intel_gpu/src/graph/impls/cpu/non_max_suppression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,9 @@ vector2D<bounding_box> load_boxes(stream& stream, memory::ptr mem, bool center_p
auto data_type = mem->get_layout().data_type;
switch (data_type) {
case cldnn::data_types::f16:
return load_boxes_impl<data_type_to_type<data_types::f16>::type>(stream, mem, center_point);
return load_boxes_impl<ov::element_type_traits<data_types::f16>::value_type>(stream, mem, center_point);
case cldnn::data_types::f32:
return load_boxes_impl<data_type_to_type<data_types::f32>::type>(stream, mem, center_point);
return load_boxes_impl<ov::element_type_traits<data_types::f32>::value_type>(stream, mem, center_point);
default:
throw std::runtime_error("Non max suppression - unsupported boxes data type");
}
Expand Down Expand Up @@ -186,9 +186,9 @@ vector3D<float> load_scores(stream& stream, memory::ptr mem) {
auto data_type = mem->get_layout().data_type;
switch (data_type) {
case cldnn::data_types::f16:
return load_scores_impl<data_type_to_type<data_types::f16>::type>(stream, mem);
return load_scores_impl<ov::element_type_traits<data_types::f16>::value_type>(stream, mem);
case cldnn::data_types::f32:
return load_scores_impl<data_type_to_type<data_types::f32>::type>(stream, mem);
return load_scores_impl<ov::element_type_traits<data_types::f32>::value_type>(stream, mem);
default:
throw std::runtime_error("Non max suppression - unsupported scores data type");
}
Expand All @@ -207,11 +207,11 @@ T load_scalar(stream& stream, memory::ptr mem) {
auto data_type = mem->get_layout().data_type;
switch (data_type) {
case cldnn::data_types::i32:
return load_scalar_impl<T, data_type_to_type<data_types::i32>::type>(stream, mem);
return load_scalar_impl<T, ov::element_type_traits<data_types::i32>::value_type>(stream, mem);
case cldnn::data_types::f16:
return load_scalar_impl<T, data_type_to_type<data_types::f16>::type>(stream, mem);
return load_scalar_impl<T, ov::element_type_traits<data_types::f16>::value_type>(stream, mem);
case cldnn::data_types::f32:
return load_scalar_impl<T, data_type_to_type<data_types::f32>::type>(stream, mem);
return load_scalar_impl<T, ov::element_type_traits<data_types::f32>::value_type>(stream, mem);
default:
throw std::runtime_error("Non max suppression - unsupported data type");
}
Expand Down Expand Up @@ -244,13 +244,13 @@ void store_result(stream& stream, memory::ptr mem, const std::vector<result_indi
auto data_type = mem->get_layout().data_type;
switch (data_type) {
case cldnn::data_types::i32:
store_result_impl<data_type_to_type<data_types::i32>::type>(stream, mem, result);
store_result_impl<ov::element_type_traits<data_types::i32>::value_type>(stream, mem, result);
break;
case cldnn::data_types::f16:
store_result_impl<data_type_to_type<data_types::f16>::type>(stream, mem, result);
store_result_impl<ov::element_type_traits<data_types::f16>::value_type>(stream, mem, result);
break;
case cldnn::data_types::f32:
store_result_impl<data_type_to_type<data_types::f32>::type>(stream, mem, result);
store_result_impl<ov::element_type_traits<data_types::f32>::value_type>(stream, mem, result);
break;
default:
throw std::runtime_error("Non max suppression - unsupported output data type");
Expand All @@ -261,10 +261,10 @@ void store_first_output(stream& stream, memory::ptr mem, const std::vector<resul
auto data_type = mem->get_layout().data_type;
switch (data_type) {
case cldnn::data_types::i32:
store_result_impl<data_type_to_type<data_types::i32>::type>(stream, mem, result);
store_result_impl<ov::element_type_traits<data_types::i32>::value_type>(stream, mem, result);
break;
case cldnn::data_types::i64:
store_result_impl<data_type_to_type<data_types::i32>::type>(stream, mem, result);
store_result_impl<ov::element_type_traits<data_types::i32>::value_type>(stream, mem, result);
break;
default:
throw std::runtime_error("Non max suppression - unsupported output data type");
Expand Down Expand Up @@ -298,10 +298,10 @@ void store_second_output(stream& stream, memory::ptr mem, const std::vector<resu
auto data_type = mem->get_layout().data_type;
switch (data_type) {
case cldnn::data_types::f16:
store_second_output_impl<data_type_to_type<data_types::f16>::type>(stream, mem, result);
store_second_output_impl<ov::element_type_traits<data_types::f16>::value_type>(stream, mem, result);
break;
case cldnn::data_types::f32:
store_second_output_impl<data_type_to_type<data_types::f32>::type>(stream, mem, result);
store_second_output_impl<ov::element_type_traits<data_types::f32>::value_type>(stream, mem, result);
break;
default:
throw std::runtime_error("Non max suppression - unsupported second output data type");
Expand All @@ -319,10 +319,10 @@ void store_third_output(stream& stream, memory::ptr mem, const std::vector<resul
auto data_type = mem->get_layout().data_type;
switch (data_type) {
case cldnn::data_types::i32:
store_third_output_impl<data_type_to_type<data_types::i32>::type>(stream, mem, result);
store_third_output_impl<ov::element_type_traits<data_types::i32>::value_type>(stream, mem, result);
break;
case cldnn::data_types::i64:
store_third_output_impl<data_type_to_type<data_types::i32>::type>(stream, mem, result);
store_third_output_impl<ov::element_type_traits<data_types::i32>::value_type>(stream, mem, result);
break;
default:
throw std::runtime_error("Non max suppression - unsupported third output data type");
Expand Down
Loading

0 comments on commit d1fc752

Please sign in to comment.