diff --git a/compiler/luci/pass/src/helpers/ArrayIndex.cpp b/compiler/luci/pass/src/helpers/ArrayIndex.cpp new file mode 100644 index 00000000000..28faf4a31ce --- /dev/null +++ b/compiler/luci/pass/src/helpers/ArrayIndex.cpp @@ -0,0 +1,48 @@ +/* + * 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 "ArrayIndex.h" + +#include + +namespace luci +{ + +Array4DIndex::Array4DIndex(uint32_t D0, uint32_t D1, uint32_t D2, uint32_t D3) + : _dim{D0, D1, D2, D3} +{ + assert(D0 > 0 && D1 > 0 && D2 > 0 && D3 > 0); + + _strides[3] = 1; + _strides[2] = D3; + _strides[1] = D3 * D2; + _strides[0] = D3 * D2 * D1; + + for (int i = 0; i < 4; ++i) + { + assert(_strides[i] > 0); + } +} +uint32_t Array4DIndex::operator()(uint32_t i0, uint32_t i1, uint32_t i2, uint32_t i3) const +{ + assert(i0 < _dim[0] && i1 < _dim[1] && i2 < _dim[2] && i3 < _dim[3]); + return i0 * _strides[0] + i1 * _strides[1] + i2 * _strides[2] + i3 * _strides[3]; +} + +uint32_t Array4DIndex::size(void) const { return _strides[3]; } +uint32_t Array4DIndex::stride(uint32_t axis) const { return _strides[axis]; } + +} // namespace luci diff --git a/compiler/luci/pass/src/helpers/ArrayIndex.h b/compiler/luci/pass/src/helpers/ArrayIndex.h new file mode 100644 index 00000000000..3658ffae23b --- /dev/null +++ b/compiler/luci/pass/src/helpers/ArrayIndex.h @@ -0,0 +1,52 @@ +/* + * 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 __LUCI_ARRAY_INDEX_H__ +#define __LUCI_ARRAY_INDEX_H__ + +#include + +namespace luci +{ + +/** + * @brief Index class for 4D tensor (NHWC) to calculate linear index from multi-dimensional indices. + */ +class Array4DIndex +{ +public: + Array4DIndex(uint32_t N, uint32_t H, uint32_t W, uint32_t D); + /** + * @brief Calculate linear index from multi-dimensional indices. + */ + uint32_t operator()(uint32_t n, uint32_t h, uint32_t w, uint32_t d) const; + /** + * @brief Get total number of elements in the tensor. + */ + uint32_t size(void) const; + /** + * @brief Get stride of the given axis. + */ + uint32_t stride(uint32_t axis) const; + +protected: + uint32_t _dim[4]; + uint32_t _strides[4]; +}; + +} // namespace luci + +#endif // __LUCI_ARRAY_INDEX_H__ diff --git a/compiler/luci/pass/src/helpers/ArrayIndex.test.cpp b/compiler/luci/pass/src/helpers/ArrayIndex.test.cpp new file mode 100644 index 00000000000..3e0bb39fdd0 --- /dev/null +++ b/compiler/luci/pass/src/helpers/ArrayIndex.test.cpp @@ -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. + */ + +#include "ArrayIndex.h" + +#include + +TEST(LuciPassHelpersArrayIndex, array_index_4d) +{ + luci::Array4DIndex idx(5, 4, 3, 2); + + EXPECT_EQ(idx.rank(), 4); + + EXPECT_EQ(idx(0, 0, 0, 0), 0); + + EXPECT_EQ(idx(1, 0, 0, 0), idx.stride(0)); + EXPECT_EQ(idx(0, 1, 0, 0), idx.stride(1)); + EXPECT_EQ(idx(0, 0, 1, 0), idx.stride(2)); + EXPECT_EQ(idx(0, 0, 0, 1), idx.stride(3)); + + EXPECT_EQ(idx(4, 3, 2, 1), 4 * 4 * 3 * 2 + 3 * 3 * 2 + 2 * 2 + 1); +} + +TEST(LuciPassHelpersArrayIndex, array_index_4d_NEG) +{ + ASSERT_THROW(luci::Array4DIndex idx(5, 4, 3, -1)); +}