2 * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #ifndef __ONERT_EXEC_FEATURE_NHWC_READER_H__
18 #define __ONERT_EXEC_FEATURE_NHWC_READER_H__
20 #include "../Reader.h"
24 #include "backend/ITensor.h"
26 #include "util/Utils.h"
37 template <typename T> class Reader : public feature::Reader<T>
40 // Construct for buffer of model inputs
41 Reader(const ir::FeatureShape &shape, const T *ptr, size_t len)
42 : _shape{shape}, _ptr{reinterpret_cast<const uint8_t *>(ptr)}, _len{len}
44 UNUSED_RELEASE(len); // Workaround for unused variable in release mode
45 assert(shape.N * shape.C * shape.H * shape.W * sizeof(T) == len);
48 _strides.C = sizeof(T);
49 _strides.W = shape.C * sizeof(T);
50 _strides.H = shape.C * shape.W * sizeof(T);
51 _strides.N = shape.C * shape.W * shape.H * sizeof(T);
54 // Construct for backend tensor
55 Reader(const backend::ITensor *tensor)
56 : _ptr{tensor->buffer() + tensor->calcOffset({0, 0, 0, 0})}, _len{tensor->total_size()}
58 assert(tensor->layout() == ir::Layout::NHWC);
60 const auto start_offset = tensor->calcOffset({0, 0, 0, 0});
61 _strides.C = tensor->dimension(3) == 1 ? 0 : tensor->calcOffset({0, 0, 0, 1}) - start_offset;
62 _strides.W = tensor->dimension(2) == 1 ? 0 : tensor->calcOffset({0, 0, 1, 0}) - start_offset;
63 _strides.H = tensor->dimension(1) == 1 ? 0 : tensor->calcOffset({0, 1, 0, 0}) - start_offset;
64 _strides.N = tensor->dimension(0) == 1 ? 0 : tensor->calcOffset({1, 0, 0, 0}) - start_offset;
66 _shape.C = tensor->dimension(3);
67 _shape.W = tensor->dimension(2);
68 _shape.H = tensor->dimension(1);
69 _shape.N = tensor->dimension(0);
73 T at(uint32_t batch, uint32_t row, uint32_t col, uint32_t ch) const final
75 return getRef(batch, row, col, ch);
77 T at(uint32_t row, uint32_t col, uint32_t ch) const final { return getRef(0, row, col, ch); }
80 const T &getRef(uint32_t batch, uint32_t row, uint32_t col, uint32_t ch) const
82 const auto offset = feature_index_to_byte_offset(batch, row, col, ch);
84 const T *ptr = reinterpret_cast<const T *>(_ptr + offset);
90 size_t feature_index_to_byte_offset(uint32_t batch, uint32_t row, uint32_t col, uint32_t ch) const
92 assert(1u * _shape.N > batch); // shape.N > batch
93 assert(1u * _shape.H > row); // shape.H > row
94 assert(1u * _shape.W > col); // shape.W > col
95 assert(1u * _shape.C > ch); // shape.C > ch
98 res += batch * _strides.N;
99 res += row * _strides.H;
100 res += col * _strides.W;
101 res += ch * _strides.C;
107 // TODO Remove _shape
108 ir::FeatureShape _shape;
109 using Strides = ir::FeatureShape;
116 } // namespace feature
120 #endif // __ONERT_EXEC_FEATURE_NHWC_READER_H__