Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 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
2 changes: 2 additions & 0 deletions compiler/circle-resizer/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
add_subdirectory(src)
add_subdirectory(app)
add_subdirectory(tests)
65 changes: 65 additions & 0 deletions compiler/circle-resizer/include/Dim.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright (c) 2025 Samsung Electronics Co., Ltd. All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef __CIRCLE_RESIZER_DIM_H__
#define __CIRCLE_RESIZER_DIM_H__

#include <stdint.h>

namespace circle_resizer
{
/**
* The representation of a single dimension. Note that a dimension can be dynamic.
*/
class Dim
{
public:
/**
* @brief Initialize single dimension. Note that '-1' means a dynamic dimension.
*
* Exceptions:
* - std::runtime_error if provided dim value is less than -1.
*/
explicit Dim(int32_t dim);

/**
* @brief Create dynamic dimension. Note that it's equivalent of Dim{-1}.
*/
static Dim dynamic();

public:
/**
* @brief Returns true if the dimension is dynamic. Otherwise, return false.
*/
bool is_dynamic() const;

/**
* @brief Returns value of dimension in int32_t representation.
*/
int32_t value() const;

/**
* @brief Returns true of the current dimension and the provided rhs are equal.
*/
bool operator==(const Dim &rhs) const;

private:
// Note that in the future, we might need to support dimension with lower and upper bounds
int32_t _dim_value;
};
} // namespace circle_resizer

#endif // __CIRCLE_RESIZER_DIM_H__
98 changes: 98 additions & 0 deletions compiler/circle-resizer/include/Shape.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* Copyright (c) 2025 Samsung Electronics Co., Ltd. All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef __CIRCLE_RESIZER_SHAPE_H__
#define __CIRCLE_RESIZER_SHAPE_H__

#include "Dim.h"

#include <ostream>
#include <vector>

namespace circle_resizer
{
/**
* The representation of a single shape.
*/
class Shape
{
public:
/**
* @brief Initialize shape with initializer list of dims.
*/
Shape(const std::initializer_list<Dim> &dims);

/**
* @brief Initialize shape with vector of dims.
*/
Shape(const std::vector<Dim> &shape_vec);

/**
* @brief Initialize static shape with initializer list of of uint32_t values.
*
* Exceptions:
* - std::out_of_range if some elements in shape_vec exceed int32_t range.
*/
Shape(const std::initializer_list<uint32_t> &shape_vec);

/**
* @brief Create scalar shape. Note, that the same can be achieved with Shape{}.
*/
static Shape scalar();

public:
/**
* @brief Returns number of dimensions in the shape.
*/
size_t rank() const;

/**
* @brief Returns dimension of the position determined by axis.
*
* Exceptions:
* - std::invalid_argument if the method is called on a scalar shape.
* - std::out_of_range if the provided axis is greater than rank.
*/
Dim operator[](const size_t &axis) const;

/**
* @brief Returns true if the shape is a scalar. Otherwise, return false.
*/
bool is_scalar() const;

/**
* @brief Returns true if all dimensions in the shape are static or the shape is a scalar.
* Otherwise, return false.
*/
bool is_dynamic() const;

/**
* @brief Returns true of the current shape and the provided rhs are equal.
*/
bool operator==(const Shape &rhs) const;

/**
* @brief Print the shape in format [1, 2, 3].
*/
friend std::ostream &operator<<(std::ostream &os, const Shape &shape);

private:
std::vector<Dim> _dims;
};

} // namespace circle_resizer

#endif // __CIRCLE_RESIZER_SHAPE_H__
40 changes: 40 additions & 0 deletions compiler/circle-resizer/include/ShapeParser.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2025 Samsung Electronics Co., Ltd. All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef __CIRCLE_RESIZER_SHAPE_PARSER_H__
#define __CIRCLE_RESIZER_SHAPE_PARSER_H__

#include "Shape.h"

#include <string>
#include <vector>
Comment thread
jinevening marked this conversation as resolved.

namespace circle_resizer
{
/**
Comment thread
jinevening marked this conversation as resolved.
* @brief Parse shapes from string representation to Shapes object.
*
* The single shape is represented by comma-separated integers inside squared brackets.
* If there is more than one shape, they are separated by commas.
* An example for single shape: [1,2,3], an example for many shapes: [1,2,3],[4,5].
*
* Exceptions:
* std::invalid_argument if the parsing failed.
*/
std::vector<Shape> parse_shapes(const std::string &shapes);
Comment thread
jinevening marked this conversation as resolved.
} // namespace circle_resizer

#endif // __CIRCLE_RESIZER_SHAPE_PARSER_H__
9 changes: 9 additions & 0 deletions compiler/circle-resizer/src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
list(APPEND CIRCLE_RESIZER_CORE_SOURCES Dim.cpp)
list(APPEND CIRCLE_RESIZER_CORE_SOURCES Shape.cpp)
list(APPEND CIRCLE_RESIZER_CORE_SOURCES ShapeParser.cpp)

add_library(circle_resizer_core STATIC "${CIRCLE_RESIZER_CORE_SOURCES}")

target_include_directories(circle_resizer_core PUBLIC ../include)

install(TARGETS circle_resizer_core DESTINATION lib)
37 changes: 37 additions & 0 deletions compiler/circle-resizer/src/Dim.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright (c) 2025 Samsung Electronics Co., Ltd. All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "Dim.h"

#include <stdexcept>

using namespace circle_resizer;

Dim::Dim(int32_t dim) : _dim_value{dim}
{
if (dim < -1)
{
throw std::runtime_error("Invalid value of dimension: " + dim);
}
}

Dim Dim::dynamic() { return Dim{-1}; }

bool Dim::is_dynamic() const { return _dim_value == -1; }

int32_t Dim::value() const { return _dim_value; }

bool Dim::operator==(const Dim &rhs) const { return value() == rhs.value(); }
100 changes: 100 additions & 0 deletions compiler/circle-resizer/src/Shape.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* Copyright (c) 2025 Samsung Electronics Co., Ltd. All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "Shape.h"

#include <algorithm>
#include <limits>

using namespace circle_resizer;

Shape::Shape(const std::initializer_list<Dim> &dims) : _dims{dims} {}

Shape::Shape(const std::vector<Dim> &shape_vec) : _dims{shape_vec} {}

Shape::Shape(const std::initializer_list<uint32_t> &shape_vec)
{
for (const auto &dim : shape_vec)
{
if (dim >= std::numeric_limits<int32_t>::max())
{
std::out_of_range("Provided dimension: " + std::to_string(dim) + " is out of range");
}
_dims.emplace_back(Dim{static_cast<int32_t>(dim)});
}
}

Shape Shape::scalar() { return Shape{std::initializer_list<Dim>{}}; }

size_t Shape::rank() const { return _dims.size(); }

Dim Shape::operator[](const size_t &axis) const
{
if (is_scalar())
{
throw std::invalid_argument("You cannot gather dimension from a scalar");
}
if (axis > rank() - 1)
{
throw std::out_of_range("Axis=" + std::to_string(axis) +
" is out of range of shape's rank: " + std::to_string(rank()));
}
return _dims[axis];
}

bool Shape::is_scalar() const { return _dims.empty(); }

bool Shape::is_dynamic() const
{
if (is_scalar())
{
return false;
}
return std::any_of(std::begin(_dims), std::end(_dims),
[](const Dim &dim) { return dim.is_dynamic(); });
}

bool Shape::operator==(const Shape &rhs) const
{
if (rank() != rhs.rank())
{
return false;
}
for (size_t axis = 0; axis < rank(); ++axis)
{
if (_dims[axis].value() != rhs[axis].value())
{
return false;
}
}
return true;
}

std::ostream &circle_resizer::operator<<(std::ostream &os, const Shape &shape)
{
if (shape.is_scalar())
{
os << "[]";
return os;
}
os << "[";
for (int i = 0; i < shape.rank() - 1; ++i)
{
os << shape[i].value() << ", ";
}
os << shape[shape.rank() - 1].value() << "]";
return os;
}
Loading