// True if the shape's rank is static.
bool m_rank_is_static;
- // True if the shape is static.
+ /// \brief Shape types. The shape type is lazily evaluated by calling the is_static()
+ /// method.
+ ///
+ /// \details It is highly recommended to avoid using the Dimension& operator[](size_t)
+ /// operator. It sets the shape type to SHAPE_IS_UPDATED and disables shape type caching.
+ /// Thus, the is_static method will have linear complexity because the shape is not
+ /// guaranteed to remain static or dynamic.
mutable enum class ShapeType {
- SHAPE_IS_UNKNOWN,
- SHAPE_IS_STATIC,
- SHAPE_IS_DYNAMIC
+ SHAPE_IS_UNKNOWN, // The shape type is unknown and should be calculated by checking all
+ // dimensions.
+ SHAPE_IS_UPDATED, // User has retained a link to one dimension. Therefore, we can't
+ // guarantee that the shape will remain static or dynamic, and its
+ // type will always be evaluated.
+ SHAPE_IS_STATIC, // The shape type is known and static. Also there are no any retained
+ // dimensions by non-constant reference.
+ SHAPE_IS_DYNAMIC // The shape type is dynamic and there are no any retained dimensions
+ // by non-constant reference.
} m_shape_type{ShapeType::SHAPE_IS_UNKNOWN};
// Shape dimensions. This has no meaning if m_rank_is_static is false.
bool ngraph::PartialShape::is_static() const
{
- if (m_shape_type == ShapeType::SHAPE_IS_UNKNOWN)
+ ShapeType shape_type = m_shape_type;
+
+ if (m_shape_type == ShapeType::SHAPE_IS_UNKNOWN || m_shape_type == ShapeType::SHAPE_IS_UPDATED)
{
- m_shape_type =
+ shape_type =
m_rank_is_static && std::all_of(m_dimensions.begin(),
m_dimensions.end(),
[](const Dimension& d) { return d.is_static(); })
? ShapeType::SHAPE_IS_STATIC
: ShapeType::SHAPE_IS_DYNAMIC;
+
+ if (m_shape_type == ShapeType::SHAPE_IS_UNKNOWN)
+ m_shape_type = shape_type;
}
- return m_shape_type == ShapeType::SHAPE_IS_STATIC;
+
+ return shape_type == ShapeType::SHAPE_IS_STATIC;
}
bool ngraph::PartialShape::operator==(const PartialShape& partial_shape) const
throw std::out_of_range("Accessing out-of-range dimension in Dimension[]");
}
m_shape_type =
- ShapeType::SHAPE_IS_UNKNOWN; // We can't guarantee that the shape remains static or dynamic.
+ ShapeType::SHAPE_IS_UPDATED; // We can't guarantee that the shape remains static or dynamic.
return m_dimensions[i];
}
ASSERT_TRUE(s.same_scheme(PartialShape{2, 3, Dimension::dynamic(), 5}));
}
+TEST(partial_shape, changed_dimension_by_reference)
+{
+ PartialShape s{1, 2, 3};
+
+ Dimension& d = s[1];
+
+ ASSERT_TRUE(s.is_static());
+
+ d = Dimension::dynamic();
+
+ ASSERT_TRUE(s.is_dynamic());
+
+ d = 2;
+
+ ASSERT_TRUE(s.is_static());
+}
+
TEST(partial_shape, infer_windowed_reduction_rank_dynamic_rank_dynamic_ok)
{
auto node = std::make_shared<op::Parameter>(element::f32, Shape{});