Skip to content

Commit c6eb5a0

Browse files
authored
[circle-resizer] Add Shape parser (#15082)
This commit adds the shapes representation and capabilities to parse string inputs into Shapes objects. ONE-DCO-1.0-Signed-off-by: Mateusz Bencer m.bencer@partner.samsung.com
1 parent 34ed2ba commit c6eb5a0

11 files changed

Lines changed: 678 additions & 0 deletions

File tree

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1+
add_subdirectory(src)
12
add_subdirectory(app)
3+
add_subdirectory(tests)
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Copyright (c) 2025 Samsung Electronics Co., Ltd. All Rights Reserved
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#ifndef __CIRCLE_RESIZER_DIM_H__
18+
#define __CIRCLE_RESIZER_DIM_H__
19+
20+
#include <stdint.h>
21+
22+
namespace circle_resizer
23+
{
24+
25+
/**
26+
* The representation of a single dimension. Note that a dimension can be dynamic.
27+
*/
28+
class Dim
29+
{
30+
public:
31+
/**
32+
* @brief Initialize single dimension. Note that '-1' means a dynamic dimension.
33+
*
34+
* Exceptions:
35+
* - std::runtime_error if provided dim value is less than -1.
36+
*/
37+
explicit Dim(int32_t dim);
38+
39+
/**
40+
* @brief Create dynamic dimension. Note that it's equivalent of Dim{-1}.
41+
*/
42+
static Dim dynamic();
43+
44+
public:
45+
/**
46+
* @brief Returns true if the dimension is dynamic. Otherwise, return false.
47+
*/
48+
bool is_dynamic() const;
49+
50+
/**
51+
* @brief Returns value of dimension in int32_t representation.
52+
*/
53+
int32_t value() const;
54+
55+
/**
56+
* @brief Returns true of the current dimension and the provided rhs are equal.
57+
*/
58+
bool operator==(const Dim &rhs) const;
59+
60+
private:
61+
// Note that in the future, we might need to support dimension with lower and upper bounds
62+
int32_t _dim_value;
63+
};
64+
65+
} // namespace circle_resizer
66+
67+
#endif // __CIRCLE_RESIZER_DIM_H__
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
* Copyright (c) 2025 Samsung Electronics Co., Ltd. All Rights Reserved
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#ifndef __CIRCLE_RESIZER_SHAPE_H__
18+
#define __CIRCLE_RESIZER_SHAPE_H__
19+
20+
#include "Dim.h"
21+
22+
#include <ostream>
23+
#include <vector>
24+
25+
namespace circle_resizer
26+
{
27+
28+
/**
29+
* The representation of a single shape.
30+
*/
31+
class Shape
32+
{
33+
public:
34+
/**
35+
* @brief Initialize shape with initializer list of dims.
36+
*/
37+
Shape(const std::initializer_list<Dim> &dims);
38+
39+
/**
40+
* @brief Initialize shape with vector of dims.
41+
*/
42+
Shape(const std::vector<Dim> &shape_vec);
43+
44+
/**
45+
* @brief Initialize static shape with initializer list of of uint32_t values.
46+
*
47+
* Exceptions:
48+
* - std::out_of_range if some elements in shape_vec exceed int32_t range.
49+
*/
50+
Shape(const std::initializer_list<uint32_t> &shape_vec);
51+
52+
/**
53+
* @brief Create scalar shape. Note, that the same can be achieved with Shape{}.
54+
*/
55+
static Shape scalar();
56+
57+
public:
58+
/**
59+
* @brief Returns number of dimensions in the shape.
60+
*/
61+
size_t rank() const;
62+
63+
/**
64+
* @brief Returns dimension of the position determined by axis.
65+
*
66+
* Exceptions:
67+
* - std::invalid_argument if the method is called on a scalar shape.
68+
* - std::out_of_range if the provided axis is greater than rank.
69+
*/
70+
Dim operator[](const size_t &axis) const;
71+
72+
/**
73+
* @brief Returns true if the shape is a scalar. Otherwise, return false.
74+
*/
75+
bool is_scalar() const;
76+
77+
/**
78+
* @brief Returns true if all dimensions in the shape are static or the shape is a scalar.
79+
* Otherwise, return false.
80+
*/
81+
bool is_dynamic() const;
82+
83+
/**
84+
* @brief Returns true of the current shape and the provided rhs are equal.
85+
*/
86+
bool operator==(const Shape &rhs) const;
87+
88+
/**
89+
* @brief Print the shape in format [1, 2, 3].
90+
*/
91+
friend std::ostream &operator<<(std::ostream &os, const Shape &shape);
92+
93+
private:
94+
std::vector<Dim> _dims;
95+
};
96+
97+
} // namespace circle_resizer
98+
99+
#endif // __CIRCLE_RESIZER_SHAPE_H__
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright (c) 2025 Samsung Electronics Co., Ltd. All Rights Reserved
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#ifndef __CIRCLE_RESIZER_SHAPE_PARSER_H__
18+
#define __CIRCLE_RESIZER_SHAPE_PARSER_H__
19+
20+
#include "Shape.h"
21+
22+
#include <string>
23+
#include <vector>
24+
25+
namespace circle_resizer
26+
{
27+
28+
/**
29+
* @brief Parse shapes from string representation to Shapes object.
30+
*
31+
* The single shape is represented by comma-separated integers inside squared brackets.
32+
* If there is more than one shape, they are separated by commas.
33+
* An example for single shape: [1,2,3], an example for many shapes: [1,2,3],[4,5].
34+
*
35+
* Exceptions:
36+
* std::invalid_argument if the parsing failed.
37+
*/
38+
std::vector<Shape> parse_shapes(const std::string &shapes);
39+
40+
} // namespace circle_resizer
41+
42+
#endif // __CIRCLE_RESIZER_SHAPE_PARSER_H__
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
list(APPEND CIRCLE_RESIZER_CORE_SOURCES Dim.cpp)
2+
list(APPEND CIRCLE_RESIZER_CORE_SOURCES Shape.cpp)
3+
list(APPEND CIRCLE_RESIZER_CORE_SOURCES ShapeParser.cpp)
4+
5+
add_library(circle_resizer_core STATIC "${CIRCLE_RESIZER_CORE_SOURCES}")
6+
7+
target_include_directories(circle_resizer_core PUBLIC ../include)
8+
9+
install(TARGETS circle_resizer_core DESTINATION lib)
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright (c) 2025 Samsung Electronics Co., Ltd. All Rights Reserved
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include "Dim.h"
18+
19+
#include <stdexcept>
20+
21+
using namespace circle_resizer;
22+
23+
Dim::Dim(int32_t dim) : _dim_value{dim}
24+
{
25+
if (dim < -1)
26+
{
27+
throw std::runtime_error("Invalid value of dimension: " + dim);
28+
}
29+
}
30+
31+
Dim Dim::dynamic() { return Dim{-1}; }
32+
33+
bool Dim::is_dynamic() const { return _dim_value == -1; }
34+
35+
int32_t Dim::value() const { return _dim_value; }
36+
37+
bool Dim::operator==(const Dim &rhs) const { return value() == rhs.value(); }
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
* Copyright (c) 2025 Samsung Electronics Co., Ltd. All Rights Reserved
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include "Shape.h"
18+
19+
#include <algorithm>
20+
#include <limits>
21+
22+
using namespace circle_resizer;
23+
24+
Shape::Shape(const std::initializer_list<Dim> &dims) : _dims{dims} {}
25+
26+
Shape::Shape(const std::vector<Dim> &shape_vec) : _dims{shape_vec} {}
27+
28+
Shape::Shape(const std::initializer_list<uint32_t> &shape_vec)
29+
{
30+
for (const auto &dim : shape_vec)
31+
{
32+
if (dim >= std::numeric_limits<int32_t>::max())
33+
{
34+
std::out_of_range("Provided dimension: " + std::to_string(dim) + " is out of range");
35+
}
36+
_dims.emplace_back(Dim{static_cast<int32_t>(dim)});
37+
}
38+
}
39+
40+
Shape Shape::scalar() { return Shape{std::initializer_list<Dim>{}}; }
41+
42+
size_t Shape::rank() const { return _dims.size(); }
43+
44+
Dim Shape::operator[](const size_t &axis) const
45+
{
46+
if (is_scalar())
47+
{
48+
throw std::invalid_argument("You cannot gather dimension from a scalar");
49+
}
50+
if (axis > rank() - 1)
51+
{
52+
throw std::out_of_range("Axis=" + std::to_string(axis) +
53+
" is out of range of shape's rank: " + std::to_string(rank()));
54+
}
55+
return _dims[axis];
56+
}
57+
58+
bool Shape::is_scalar() const { return _dims.empty(); }
59+
60+
bool Shape::is_dynamic() const
61+
{
62+
if (is_scalar())
63+
{
64+
return false;
65+
}
66+
return std::any_of(std::begin(_dims), std::end(_dims),
67+
[](const Dim &dim) { return dim.is_dynamic(); });
68+
}
69+
70+
bool Shape::operator==(const Shape &rhs) const
71+
{
72+
if (rank() != rhs.rank())
73+
{
74+
return false;
75+
}
76+
for (size_t axis = 0; axis < rank(); ++axis)
77+
{
78+
if (_dims[axis].value() != rhs[axis].value())
79+
{
80+
return false;
81+
}
82+
}
83+
return true;
84+
}
85+
86+
std::ostream &circle_resizer::operator<<(std::ostream &os, const Shape &shape)
87+
{
88+
if (shape.is_scalar())
89+
{
90+
os << "[]";
91+
return os;
92+
}
93+
os << "[";
94+
for (int i = 0; i < shape.rank() - 1; ++i)
95+
{
96+
os << shape[i].value() << ", ";
97+
}
98+
os << shape[shape.rank() - 1].value() << "]";
99+
return os;
100+
}

0 commit comments

Comments
 (0)