Skip to content

Commit

Permalink
Merge branch 'master' into nashez/napi_tensor_continuous
Browse files Browse the repository at this point in the history
  • Loading branch information
vishniakov-nikolai authored Dec 13, 2024
2 parents 5366f65 + 6b2f8ec commit 456e142
Show file tree
Hide file tree
Showing 26 changed files with 1,020 additions and 282 deletions.
65 changes: 64 additions & 1 deletion src/common/transformations/tests/control_flow/unroll_if_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,15 @@
#include "transformations/init_node_info.hpp"
#include "transformations/rt_info/fused_names_attribute.hpp"

using namespace ov;
using namespace testing;

namespace ov {
namespace test {
using op::v0::Constant;
using op::v0::Parameter;
using op::v0::Result;
using op::v1::Add;

std::shared_ptr<ov::Model> get_then_body() {
auto Xt = std::make_shared<ov::op::v0::Parameter>(ov::element::f32, ov::Shape{3});
Xt->set_friendly_name("Xt");
Expand Down Expand Up @@ -350,3 +356,60 @@ TEST(TransformationTests, UnrollIfInsideIf) {
auto res = compare_functions(f, f_ref);
ASSERT_TRUE(res.first) << res.second;
}

TEST(TransformationTests, UnrollIfToParameterResultModel) {
constexpr auto et = element::f32;
std::shared_ptr<Model> model, model_ref;

{
const auto a = std::make_shared<Parameter>(et, PartialShape{5, 7});
const auto b = std::make_shared<Parameter>(et, PartialShape{1});
const auto c = std::make_shared<Parameter>(et, PartialShape{5, 7});

const auto then_add = std::make_shared<Add>(a, b);
auto then_result = std::make_shared<Result>(then_add);
auto else_result = std::make_shared<Result>(c);

const auto then_body = std::make_shared<Model>(OutputVector{then_result}, ParameterVector{a, b});
const auto else_body = std::make_shared<Model>(OutputVector{else_result}, ParameterVector{c});

const auto if_input_0 = std::make_shared<Parameter>(et, a->get_output_partial_shape(0));
const auto if_input_1 = std::make_shared<Parameter>(et, b->get_output_partial_shape(0));
const auto condition = Constant::create(element::boolean, {1}, {false});
const auto if_op = std::make_shared<op::v8::If>(condition);
if_op->set_then_body(then_body);
if_op->set_else_body(else_body);
if_op->set_input(if_input_0, a, c);
if_op->set_input(if_input_1, b, nullptr);
const auto if_result = if_op->set_output(then_result, else_result);

const auto results = ResultVector{std::make_shared<Result>(if_result)};
model = std::make_shared<Model>(results, ParameterVector{if_input_0, if_input_1}, "simple_if");
model->input(0).set_names({"Input.0"});
model->input(1).set_names({"Input.1"});
model->output(0).set_names({"Output"});

pass::Manager manager;
manager.register_pass<pass::InitNodeInfo>();
manager.register_pass<pass::UnrollIf>();
manager.run_passes(model);

OV_ASSERT_NO_THROW(check_rt_info(model));
}
{
const auto p = std::make_shared<Parameter>(et, PartialShape{5, 7});
const auto r = std::make_shared<Result>(p);
model_ref = std::make_shared<Model>(ResultVector{r}, ParameterVector{p}, "simple_if");
model_ref->input(0).set_names({"Input.0"});
model_ref->output(0).set_names({"Output"});
}

const auto cmp_result = compare_functions(model, model_ref);
ASSERT_TRUE(cmp_result.first) << cmp_result.second;

EXPECT_THAT(model->input(0).get_names(), UnorderedElementsAre("Input.0", "Output"));
EXPECT_THAT(model->output(0).get_names(), UnorderedElementsAre("Output"));
}

} // namespace test
} // namespace ov
76 changes: 75 additions & 1 deletion src/core/dev_api/openvino/core/descriptor_tensor.hpp
Original file line number Diff line number Diff line change
@@ -1,18 +1,92 @@
// Copyright (C) 2018-2024 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#pragma once

#include "openvino/core/descriptor/tensor.hpp"
#include <memory>
#include <unordered_set>

#include "openvino/core/partial_shape.hpp"
#include "openvino/core/type/element_type.hpp"

namespace ov {
namespace descriptor {

class Tensor;
class Input;
class Output;

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

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

/**
* @brief Set destination tensor names as copy of all names from source tensor all tensor names.
*
* @param dst The tensor descriptor to set names.
* @param src The tensor descriptor as from which names will be copied.
*/
OPENVINO_API
void copy_tensor_names(Tensor& dst, const Tensor& src);

/** @brief Tensor descriptor interface. */
class OPENVINO_API ITensorDescriptor {
public:
virtual const element::Type& get_element_type() const = 0;
virtual const PartialShape& get_partial_shape() const = 0;
virtual const Shape& get_shape() const = 0;
virtual void set_type_shape(const element::Type& et, const PartialShape& shape) = 0;

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

virtual RTMap& rt_map() = 0;
virtual const RTMap& rt_map() const = 0;
virtual size_t pointer_hash() const noexcept = 0;

protected:
virtual ~ITensorDescriptor();
};

/** @brief The TensorExtension defines developer API for ov::descriptor::Tensor. */
struct OPENVINO_API TensorExtension {
/**
* @brief Get the tensor descriptor object
*
* @param tensor Tensor descriptor to access its implementation.
* @return Reference to Tensor description implementation.
*/
static const ITensorDescriptor& get_descriptor(const Tensor& tensor);
static std::shared_ptr<ITensorDescriptor>& get_descriptor_ptr(Tensor& tensor);

/**
* @brief The hasher of shared pointer Tensor descriptor.
*/
struct OPENVINO_API Hasher {
size_t operator()(const std::shared_ptr<Tensor>& tensor) const;
};

/**
* @brief The comparator of shared pointer Tensor descriptor.
*/
struct OPENVINO_API Equal {
bool operator()(const std::shared_ptr<Tensor>& lhs, const std::shared_ptr<Tensor>& rhs) const;
};
};

/**
* @brief Set input descriptor as shared tensor on output descriptor.
*
* @param output_descriptor Descriptor to set shared tensor.
* @param input_descriptor Input descriptor to set in output as shared tensor.
*/
OPENVINO_API void set_shared_tensor(Output& output_descriptor, const Input& input_descriptor);
} // namespace descriptor
} // namespace ov
13 changes: 1 addition & 12 deletions src/core/include/openvino/core/descriptor/input.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,13 @@

namespace ov {
class Node;
namespace op {
namespace v0 {
class Result;
} // namespace v0
} // namespace op

namespace descriptor {
class Output;

// Describes a tensor that is an input to an op, directly or indirectly via a tuple
class OPENVINO_API Input {
friend class ov::Node;
friend class ov::op::v0::Result;

public:
/// \param node The node that owns this input
Expand Down Expand Up @@ -111,12 +106,6 @@ class OPENVINO_API Input {
Input& operator=(const Input&) = default;

protected:
/// \return the tensor for the connected output
std::shared_ptr<const Tensor> get_tensor_ptr() const;

/// \return the tensor for the connected output
std::shared_ptr<Tensor> get_tensor_ptr();

// owner of an argument node (in lieu of m_arguments)
std::shared_ptr<Node> m_src_node;
Node* m_node; // The node we are an input for
Expand Down
100 changes: 54 additions & 46 deletions src/core/include/openvino/core/descriptor/tensor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,99 +22,107 @@ namespace ov {
class Node;
/// \brief Alias for symbol tensor.
using TensorSymbol = std::vector<std::shared_ptr<Symbol>>;
/// \brief Alias for vector of symbol tensors.

/// \brief Alias for vector of symbol tensors.
using TensorSymbolVector = std::vector<TensorSymbol>;

namespace pass {
class ReverseShapeAndTypeInfer;
}
namespace descriptor {

class Tensor;
class ITensorDescriptor;

/// \brief Compile-time descriptor of a first-class value that is a tensor.
class OPENVINO_API Tensor {
public:
/// \brief Creates Tensor descriptor
/// \param element_type Element type
/// \param pshape Partial shape of tensor
/// \param names Tensor names (optional default empty).
Tensor(const element::Type& element_type,
const PartialShape& pshape,
const std::unordered_set<std::string>& names = {});

OPENVINO_DEPRECATED("This constructor is deprecated. Will be removed in 2026.0")
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;

/// \brief Gets any tensor name.
/// Throws if tensor has no names.
const std::string& get_any_name() const;

/// \brief Gets tensor names
const std::unordered_set<std::string>& get_names() const;

/// \brief Set new names.
/// \param names Names to set.
void set_names(const std::unordered_set<std::string>& names);

/// \brief Adds new names to tensor.
/// \param names new names to be added.
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 symbol description
void set_value_symbol(const TensorSymbol& value_symbol);

/// \brief unsets bound value descriptions
void invalidate_values();

const element::Type& get_element_type() const {
return m_element_type;
}
/// \brief Gets element type.
const element::Type& get_element_type() const;

/// \brief Gets shape.
/// Throw if Tensor's shape is not static.
const Shape& get_shape() const;
const PartialShape& get_partial_shape() const {
return m_partial_shape;
}

/// \brief Gets partial shape.
const PartialShape& get_partial_shape() const;

/// \brief gets lower bound value description
const ov::Tensor& get_lower_value() const {
return m_lower_value;
}
const ov::Tensor& get_lower_value() const;

/// \brief gets upper bound value description
const ov::Tensor& get_upper_value() const {
return m_upper_value;
}
const ov::Tensor& get_upper_value() const;

/// \brief gets symbol value description
TensorSymbol get_value_symbol() const {
return m_value_symbol;
}
TensorSymbol get_value_symbol() const;

/// \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();
}
bool has_and_set_bound() const;

/// \brief Get Tensor size in bytes.
/// \return Size in bytes.
size_t size() const;

RTMap& get_rt_info() {
return m_rt_info;
}
const RTMap& get_rt_info() const {
return m_rt_info;
}
/// \brief Gets runtime informations.
/// \return Runtime information map which can be modified.
RTMap& get_rt_info();

void clone_from(const Tensor& old);
/// \brief Gets runtime informations.
/// \return Read only runtime information map.
const RTMap& get_rt_info() const;

protected:
element::Type m_element_type;
/// \brief Clones Tensor from the other.
/// \param other Tensor used to clone its properties.
void clone_from(const Tensor& other);

PartialShape m_partial_shape;
protected:
ov::Tensor m_lower_value, m_upper_value;
TensorSymbol m_value_symbol;

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

friend OPENVINO_API void set_element_type(Tensor& tensor, const element::Type& elemenet_type);
friend OPENVINO_API void set_tensor_type(Tensor& tensor,
const element::Type& element_type,
const PartialShape& pshape);
std::shared_ptr<ITensorDescriptor> m_impl;

private:
mutable std::atomic<bool> m_shape_changing{false};
mutable bool m_shape_changed{true};
mutable Shape m_shape;
// hidden extension API for Tensor descriptor
friend struct TensorExtension;
};

OPENVINO_API
std::ostream& operator<<(std::ostream&, const ov::descriptor::Tensor&);
} // namespace descriptor

} // namespace ov
Loading

0 comments on commit 456e142

Please sign in to comment.