/** * \file dnn/src/common/tensor_iter.cpp * MegEngine is Licensed under the Apache License, Version 2.0 (the "License") * * Copyright (c) 2014-2021 Megvii Inc. All rights reserved. * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ #include "megdnn/tensor_iter.h" #include "src/common/utils.h" using namespace megdnn; ////////////////////////// TypeRef //////////////////// TypeRef::TypeRef(dt_quint4* _ptr, size_t _offset) { ptr = reinterpret_cast(_ptr); offset = _offset; uint8_t cur = ptr[offset >> 1]; val = convert(cur, dt_quint4(cur), offset & 0x1) .as_uint8(); } void TypeRef::operator=(const uint8_t _) { uint8_t cur = ptr[offset >> 1]; ptr[offset >> 1] = convert(dt_quint4(_), cur, offset & 0x1); } TypeRef::TypeRef(dt_qint4* _ptr, size_t _offset) { ptr = reinterpret_cast(_ptr); offset = _offset; int8_t cur = ptr[offset >> 1]; val = convert(cur, dt_qint4(cur), offset & 0x1).as_int8(); } void TypeRef::operator=(const int8_t _) { int8_t cur = ptr[offset >> 1]; ptr[offset >> 1] = convert(dt_qint4(_), cur, offset & 0x1); } ////////////////////// TensorIter ///////////////////// template typename TensorIter::Iter TensorIter::Iter::make( ctype *ptr, const TensorLayout &layout, size_t offset) { megdnn_assert(layout.ndim); Iter rst; rst.m_ptr = ptr; if (valonly) rst.m_layout = layout.collapse_contiguous(); else rst.m_layout = layout; rst.m_logical_offset = offset; rst.m_tot_nr_elems = rst.m_layout.total_nr_elems(); rst.m_offset = 0; megdnn_assert(offset <= rst.m_tot_nr_elems); for (int i = rst.m_layout.ndim - 1; i >= 0; i --) { auto shp = rst.m_layout.shape[i]; auto stride = rst.m_layout.stride[i]; if (!shp) { // empty iter for empty layout return {}; } rst.m_axis_reset_stride[i] = stride * (shp - 1); rst.m_axis_offset[i] = offset % shp; rst.m_offset += rst.m_axis_offset[i] * stride; offset /= shp; } return rst; } template void TensorIter::Iter::on_access_idx_valonly_true() const { megdnn_throw("can not access idx of TensorIter if valonly is true"); } namespace megdnn { #define cb(_dt) \ template class TensorIter::ctype, false>; \ template class TensorIter::ctype, true>; MEGDNN_FOREACH_DTYPE_NAME(cb) MEGDNN_FOREACH_PARAMETERIZED_DTYPE(cb) #undef cb } // vim: syntax=cpp.doxygen foldmethod=marker foldmarker=f{{{,f}}}