Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move api set_element_type() & set_tensor_type() from public to private #22645

Closed
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
169 changes: 169 additions & 0 deletions bk/tensor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#include "openvino/core/descriptor/tensor.hpp"
zhaixuejun1993 marked this conversation as resolved.
Show resolved Hide resolved

#include "openvino/core/except.hpp"
#include "openvino/core/node.hpp"
#include "openvino/op/util/symbolic_info.hpp"

ov::descriptor::Tensor::Tensor(const element::Type& element_type,
const PartialShape& pshape,
const std::unordered_set<std::string>& names)
: m_element_type(element_type),
m_partial_shape(pshape),
m_shape_changed(true) {
set_names(names);
}

ov::descriptor::Tensor::Tensor(const element::Type& element_type, const PartialShape& pshape, const std::string& name)
: m_element_type(element_type),
m_partial_shape(pshape),
m_shape_changed(true) {
m_name_it = m_names.cend();
}

ov::descriptor::Tensor::Tensor(const element::Type& element_type,
const PartialShape& pshape,
ov::Node* node,
size_t node_output_number)
: m_element_type(element_type),
m_partial_shape(pshape),
m_shape_changed(true) {
m_name_it = m_names.cend();
}

void ov::descriptor::Tensor::invalidate_values() {
if (ov::skip_invalidation(*this))
return;
m_upper_value = {};
m_lower_value = {};
m_value_label.clear();
}

void ov::descriptor::Tensor::set_lower_value(const ov::Tensor& value) {
OPENVINO_ASSERT(static_cast<bool>(value));
OPENVINO_ASSERT(m_partial_shape.same_scheme(value.get_shape()));
OPENVINO_ASSERT(m_element_type == value.get_element_type());
m_lower_value = value;
}

void ov::descriptor::Tensor::set_upper_value(const ov::Tensor& value) {
OPENVINO_ASSERT(static_cast<bool>(value));
OPENVINO_ASSERT(m_partial_shape.same_scheme(value.get_shape()));
OPENVINO_ASSERT(m_element_type == value.get_element_type());
m_upper_value = value;
}

void ov::descriptor::Tensor::set_value_label(const TensorLabel& value_label) {
const auto& labels_size = value_label.size();
if (labels_size == 0) {
m_value_label.clear();
} else {
OPENVINO_ASSERT(m_partial_shape.is_static());
OPENVINO_ASSERT(shape_size(m_partial_shape.to_shape()) == labels_size);
m_value_label = value_label;
}
}

const ov::Shape& ov::descriptor::Tensor::get_shape() const {
if (m_partial_shape.is_static()) {
if (m_shape_changed.load(std::memory_order_relaxed)) {
std::lock_guard<std::mutex> guard(m_mutex);
if (m_shape_changed) // double check after mutex lock
{
m_shape = m_partial_shape.to_shape();
m_shape_changed = false;
}
}
return m_shape;
} else {
throw std::invalid_argument("get_shape was called on a descriptor::Tensor with dynamic shape");
}
}

size_t ov::descriptor::Tensor::size() const {
const bool bitwidth_less_than_byte = m_element_type.bitwidth() < 8;
return bitwidth_less_than_byte ? (shape_size(get_shape()) * m_element_type.bitwidth() + 7) >> 3
: (shape_size(get_shape()) * m_element_type.size());
}

const std::unordered_set<std::string>& ov::descriptor::Tensor::get_names() const {
return m_names;
}

const std::string& ov::descriptor::Tensor::get_any_name() const {
if (m_name_it == m_names.cend()) {
OPENVINO_THROW("Attempt to get a name for a Tensor without names");
}
return *m_name_it;
}

void ov::descriptor::Tensor::set_names(const std::unordered_set<std::string>& names) {
m_names = names;
m_name_it = m_names.cbegin();
for (auto it = m_names.cbegin(); it != m_names.cend(); it++) {
if (*it < *m_name_it)
// Update any name
m_name_it = it;
}
}

void ov::descriptor::Tensor::add_names(const std::unordered_set<std::string>& names) {
for (const auto& name : names) {
auto res = m_names.insert(name);
if (m_name_it == m_names.end() || *res.first < *m_name_it)
// Update any name
m_name_it = res.first;
}
}

void ov::descriptor::Tensor::clone_from(const ov::descriptor::Tensor& old) {
std::lock_guard<std::mutex> guard(m_mutex);
set_names(old.get_names());
m_element_type = old.get_element_type();
m_shape = old.m_shape;
m_partial_shape = old.get_partial_shape();
m_lower_value = old.get_lower_value();
m_upper_value = old.get_upper_value();
m_value_label = old.get_value_label();
m_legacy_name = old.m_legacy_name;
m_rt_info = old.get_rt_info();
m_shape_changed = true;
}

std::string ov::descriptor::get_ov_tensor_legacy_name(const ov::descriptor::Tensor& tensor) {
return tensor.m_legacy_name;
}

void ov::descriptor::set_ov_tensor_legacy_name(ov::descriptor::Tensor& tensor, const std::string& tensor_name) {
tensor.m_legacy_name = tensor_name;
}

void ov::descriptor::set_tensor_type(ov::descriptor::Tensor& tensor,
const element::Type& element_type,
const PartialShape& pshape) {
tensor.m_element_type = element_type;
tensor.m_partial_shape = pshape;
tensor.m_shape_changed = true;
}

void ov::descriptor::set_element_type(ov::descriptor::Tensor& tensor, const element::Type& element_type) {
tensor.m_element_type = element_type;
}

std::ostream& ov::descriptor::operator<<(std::ostream& out, const ov::descriptor::Tensor& tensor) {
std::string names;
for (const auto& name : tensor.get_names()) {
if (!names.empty())
names += ", ";
names += name;
}
OPENVINO_SUPPRESS_DEPRECATED_START
if (names.empty())
names = get_ov_tensor_legacy_name(tensor);
OPENVINO_SUPPRESS_DEPRECATED_END
out << "Tensor(" << names << ")";
return out;
}
148 changes: 148 additions & 0 deletions bk/tensor.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#pragma once

#include <atomic>
#include <map>
#include <memory>
#include <mutex>
#include <string>
#include <unordered_set>

#include "openvino/core/any.hpp"
#include "openvino/core/core_visibility.hpp"
#include "openvino/core/partial_shape.hpp"
#include "openvino/core/shape.hpp"
#include "openvino/core/type/element_type.hpp"
#include "openvino/runtime/tensor.hpp"

namespace ov {
class Node;
/// \brief Alias for label tensor.
using TensorLabel = std::vector<label_t>;
/// \brief Alias for vector of label tensors.
using TensorLabelVector = std::vector<TensorLabel>;

namespace pass {
class ReverseShapeAndTypeInfer;
}
namespace descriptor {

class Tensor;

OPENVINO_DEPRECATED("get_ov_tensor_legacy_name() is deprecated. Please don't use this function.")
OPENVINO_API
std::string get_ov_tensor_legacy_name(const Tensor& tensor);

OPENVINO_DEPRECATED("set_ov_tensor_legacy_name() is deprecated. Please don't use this function.")
OPENVINO_API
void set_ov_tensor_legacy_name(Tensor& tensor, const std::string& tensor_name);

// To change Tensor element type please change the Parameter type.
void set_element_type(Tensor& tensor, const element::Type& elemenet_type);

// To change Tensor type please change the Parameter type.
void set_tensor_type(Tensor& tensor, const element::Type& element_type, const PartialShape& pshape);

/// \brief Compile-time descriptor of a first-class value that is a tensor.
class OPENVINO_API Tensor {
public:
Tensor(const element::Type& element_type,
const PartialShape& pshape,
const std::unordered_set<std::string>& names = {});
OPENVINO_DEPRECATED("This constructor is deprecated. Please use constructor with set of names")
Tensor(const element::Type& element_type, const PartialShape& pshape, const std::string& name);
Tensor(const element::Type& element_type, const PartialShape& pshape, Node* node, size_t node_output_number);

Tensor(const Tensor&) = delete;
Tensor& operator=(const Tensor&) = delete;

const std::string& get_any_name() const;
const std::unordered_set<std::string>& get_names() const;
void set_names(const std::unordered_set<std::string>& names);
void add_names(const std::unordered_set<std::string>& names);

/// \brief sets lower bound value description
void set_lower_value(const ov::Tensor& value);
/// \brief sets upper bound value description
void set_upper_value(const ov::Tensor& value);
/// \brief sets value label description
void set_value_label(const TensorLabel& value_label);
/// \brief unsets bound value descriptions
void invalidate_values();

const element::Type& get_element_type() const {
return m_element_type;
}
const Shape& get_shape() const;
const PartialShape& get_partial_shape() const {
return m_partial_shape;
}
/// \brief gets lower bound value description
const ov::Tensor& get_lower_value() const {
return m_lower_value;
}
/// \brief gets upper bound value description
const ov::Tensor& get_upper_value() const {
return m_upper_value;
}
/// \brief gets upper bound value description
TensorLabel get_value_label() const {
return m_value_label;
}
/// \brief checks if lower and upper bound are set and point to the same Tensor
bool has_and_set_bound() const {
return m_upper_value && m_lower_value && m_upper_value.data() == m_lower_value.data();
}
size_t size() const;

RTMap& get_rt_info() {
return m_rt_info;
}
const RTMap& get_rt_info() const {
return m_rt_info;
}

void clone_from(const Tensor& old);

protected:
element::Type m_element_type;

// TODO: remove along with get_shape
// Initially there was Shape m_shape only available to keep shape information.
// Support for dynamic shapes required transition to ov::PartialShape.
// To smoothly transition to ov::PartialShape we introduced m_partial_shape
// and kept m_shape in sync with m_partial_shape. Synchronization point was placed
// in set_partial_shape which dramatically affected performance of ov::Model
// validation. Since we have started the transition to ov::PartialShape and reduced
// Shape usage the only user of m_shape was get_shape method with signature:
// const PartialShape& descriptor::Tensor::get_shape() const
// It was decided to move m_shape and m_partial_shape synchronization point there and
// to keep methods signature backward compatible.
mutable std::mutex m_mutex;
mutable Shape m_shape;
// TODO: end

PartialShape m_partial_shape;
ov::Tensor m_lower_value, m_upper_value;
TensorLabel m_value_label;
std::string m_legacy_name;

std::unordered_set<std::string> m_names;
std::unordered_set<std::string>::const_iterator m_name_it;
RTMap m_rt_info;
mutable std::atomic_bool m_shape_changed;

friend OPENVINO_API std::string get_ov_tensor_legacy_name(const Tensor& tensor);
friend OPENVINO_API void set_ov_tensor_legacy_name(Tensor& tensor, const std::string& tensor_name);
friend void set_element_type(Tensor& tensor, const element::Type& elemenet_type);
friend void set_tensor_type(Tensor& tensor, const element::Type& element_type, const PartialShape& pshape);
friend class pass::ReverseShapeAndTypeInfer;
};

OPENVINO_API
std::ostream& operator<<(std::ostream&, const ov::descriptor::Tensor&);
} // namespace descriptor
} // namespace ov
20 changes: 8 additions & 12 deletions src/common/transformations/include/ov_ops/type_relaxed.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,19 +90,19 @@ class OPENVINO_API TypeRelaxedBase {
for (size_t i = 0; i < node.get_input_size(); ++i) {
auto origin_input_type = get_origin_input_type(i);
if (origin_input_type != element::undefined) {
OPENVINO_SUPPRESS_DEPRECATED_START
node.get_input_tensor(i).set_tensor_type(origin_input_type, node.get_input_partial_shape(i));
OPENVINO_SUPPRESS_DEPRECATED_END
ov::descriptor::set_tensor_type(node.get_input_tensor(i),
origin_input_type,
node.get_input_partial_shape(i));
}
}
}

void restore_input_data_types(Node& node, const element::TypeVector& old_input_types) {
// Restore original input data types
for (size_t i = 0; i < node.get_input_size(); ++i) {
OPENVINO_SUPPRESS_DEPRECATED_START
node.get_input_tensor(i).set_tensor_type(old_input_types[i], node.get_input_partial_shape(i));
OPENVINO_SUPPRESS_DEPRECATED_END
ov::descriptor::set_tensor_type(node.get_input_tensor(i),
old_input_types[i],
node.get_input_partial_shape(i));
}

if (m_original_output_data_types.empty()) {
Expand Down Expand Up @@ -161,9 +161,7 @@ class TemporaryReplaceOutputType {
TemporaryReplaceOutputType(Output<Node> output, element::Type tmp_type) : m_output(output) {
// save original element type in order to restore it in the destructor
orig_type = m_output.get_element_type();
OPENVINO_SUPPRESS_DEPRECATED_START
m_output.get_tensor().set_element_type(tmp_type);
OPENVINO_SUPPRESS_DEPRECATED_END
ov::descriptor::set_element_type(m_output.get_tensor(), tmp_type);
}

/// Return the output port that was used in the constructor
Expand All @@ -173,9 +171,7 @@ class TemporaryReplaceOutputType {

/// Restores the original element type for the output
~TemporaryReplaceOutputType() {
OPENVINO_SUPPRESS_DEPRECATED_START
m_output.get_tensor().set_element_type(orig_type);
OPENVINO_SUPPRESS_DEPRECATED_END
ov::descriptor::set_element_type(m_output.get_tensor(), orig_type);
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,7 @@ bool ov::pass::SymbolicPropagation::run_on_model(const std::shared_ptr<ov::Model
for (auto& output : op->outputs()) {
auto shape = output.get_partial_shape();
symbolic_set_up_for_shape(dt, shape);
OPENVINO_SUPPRESS_DEPRECATED_START
output.get_tensor().set_tensor_type(output.get_element_type(), shape);
OPENVINO_SUPPRESS_DEPRECATED_END
ov::descriptor::set_tensor_type(output.get_tensor(), output.get_element_type(), shape);
}
}
return true;
Expand Down
Loading
Loading