1*5f39d1b3SJooyung Han // Copyright 2016 The Gemmlowp Authors. All Rights Reserved. 2*5f39d1b3SJooyung Han // 3*5f39d1b3SJooyung Han // Licensed under the Apache License, Version 2.0 (the "License"); 4*5f39d1b3SJooyung Han // you may not use this file except in compliance with the License. 5*5f39d1b3SJooyung Han // You may obtain a copy of the License at 6*5f39d1b3SJooyung Han // 7*5f39d1b3SJooyung Han // http://www.apache.org/licenses/LICENSE-2.0 8*5f39d1b3SJooyung Han // 9*5f39d1b3SJooyung Han // Unless required by applicable law or agreed to in writing, software 10*5f39d1b3SJooyung Han // distributed under the License is distributed on an "AS IS" BASIS, 11*5f39d1b3SJooyung Han // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*5f39d1b3SJooyung Han // See the License for the specific language governing permissions and 13*5f39d1b3SJooyung Han // limitations under the License. 14*5f39d1b3SJooyung Han 15*5f39d1b3SJooyung Han #ifndef GEMMLOWP_META_STREAMS_H_ 16*5f39d1b3SJooyung Han #define GEMMLOWP_META_STREAMS_H_ 17*5f39d1b3SJooyung Han 18*5f39d1b3SJooyung Han #include <iostream> 19*5f39d1b3SJooyung Han #include <typeinfo> 20*5f39d1b3SJooyung Han #include "base.h" 21*5f39d1b3SJooyung Han 22*5f39d1b3SJooyung Han namespace gemmlowp { 23*5f39d1b3SJooyung Han namespace meta { 24*5f39d1b3SJooyung Han 25*5f39d1b3SJooyung Han struct RowMajor { 26*5f39d1b3SJooyung Han public: 27*5f39d1b3SJooyung Han int count; 28*5f39d1b3SJooyung Han int stride; 29*5f39d1b3SJooyung Han }; 30*5f39d1b3SJooyung Han 31*5f39d1b3SJooyung Han struct RowMajorWithSum { 32*5f39d1b3SJooyung Han public: 33*5f39d1b3SJooyung Han int count; 34*5f39d1b3SJooyung Han int stride; 35*5f39d1b3SJooyung Han int multiplicative_sum_offset; 36*5f39d1b3SJooyung Han int additive_sum_offset; 37*5f39d1b3SJooyung Han }; 38*5f39d1b3SJooyung Han 39*5f39d1b3SJooyung Han struct ColumnMajorWithSum { 40*5f39d1b3SJooyung Han public: 41*5f39d1b3SJooyung Han int count; 42*5f39d1b3SJooyung Han int stride; 43*5f39d1b3SJooyung Han int multiplicative_sum_offset; 44*5f39d1b3SJooyung Han int additive_sum_offset; 45*5f39d1b3SJooyung Han }; 46*5f39d1b3SJooyung Han 47*5f39d1b3SJooyung Han template <typename InType> 48*5f39d1b3SJooyung Han class StreamUtil<InType, RowMajor> { 49*5f39d1b3SJooyung Han public: Offset(const RowMajor & params,const InType * source,int offset_stride,int offset_advance)50*5f39d1b3SJooyung Han static const InType* Offset(const RowMajor& params, const InType* source, 51*5f39d1b3SJooyung Han int offset_stride, int offset_advance) { 52*5f39d1b3SJooyung Han return reinterpret_cast<const InType*>( 53*5f39d1b3SJooyung Han reinterpret_cast<const std::uint8_t*>(source) + 54*5f39d1b3SJooyung Han offset_stride * params.stride + offset_advance * sizeof(InType)); 55*5f39d1b3SJooyung Han } 56*5f39d1b3SJooyung Han Offset(const RowMajor & params,InType * source,int offset_stride,int offset_advance)57*5f39d1b3SJooyung Han static InType* Offset(const RowMajor& params, InType* source, 58*5f39d1b3SJooyung Han int offset_stride, int offset_advance) { 59*5f39d1b3SJooyung Han return reinterpret_cast<InType*>(reinterpret_cast<std::uint8_t*>(source) + 60*5f39d1b3SJooyung Han offset_stride * params.stride + 61*5f39d1b3SJooyung Han offset_advance * sizeof(InType)); 62*5f39d1b3SJooyung Han } 63*5f39d1b3SJooyung Han Scratch(const RowMajor & params,int lanes_count,int pack_size)64*5f39d1b3SJooyung Han static int Scratch(const RowMajor& params, int lanes_count, int pack_size) { 65*5f39d1b3SJooyung Han return AlignTo<64>(lanes_count * AlignTo(pack_size, params.stride)); 66*5f39d1b3SJooyung Han } 67*5f39d1b3SJooyung Han }; 68*5f39d1b3SJooyung Han 69*5f39d1b3SJooyung Han template <typename InType> 70*5f39d1b3SJooyung Han class StreamUtil<InType, RowMajorWithSum> { 71*5f39d1b3SJooyung Han public: Offset(const RowMajorWithSum & params,const InType * source,int offset_stride,int offset_advance)72*5f39d1b3SJooyung Han static const InType* Offset(const RowMajorWithSum& params, 73*5f39d1b3SJooyung Han const InType* source, int offset_stride, 74*5f39d1b3SJooyung Han int offset_advance) { 75*5f39d1b3SJooyung Han return reinterpret_cast<const InType*>( 76*5f39d1b3SJooyung Han reinterpret_cast<const std::uint8_t*>(source) + 77*5f39d1b3SJooyung Han offset_stride * params.stride + offset_advance * sizeof(InType)); 78*5f39d1b3SJooyung Han } 79*5f39d1b3SJooyung Han Offset(const RowMajorWithSum & params,InType * source,int offset_stride,int offset_advance)80*5f39d1b3SJooyung Han static InType* Offset(const RowMajorWithSum& params, InType* source, 81*5f39d1b3SJooyung Han int offset_stride, int offset_advance) { 82*5f39d1b3SJooyung Han return reinterpret_cast<InType*>(reinterpret_cast<std::uint8_t*>(source) + 83*5f39d1b3SJooyung Han offset_stride * params.stride + 84*5f39d1b3SJooyung Han offset_advance * sizeof(InType)); 85*5f39d1b3SJooyung Han } 86*5f39d1b3SJooyung Han Scratch(const RowMajorWithSum & params,int lanes_count,int pack_size)87*5f39d1b3SJooyung Han static int Scratch(const RowMajorWithSum& params, int lanes_count, 88*5f39d1b3SJooyung Han int pack_size) { 89*5f39d1b3SJooyung Han return 32 + AlignTo<32>(sizeof(InType) * lanes_count * 90*5f39d1b3SJooyung Han AlignTo(pack_size, params.count)); 91*5f39d1b3SJooyung Han } 92*5f39d1b3SJooyung Han }; 93*5f39d1b3SJooyung Han 94*5f39d1b3SJooyung Han template <typename InType> 95*5f39d1b3SJooyung Han class StreamUtil<InType, ColumnMajorWithSum> { 96*5f39d1b3SJooyung Han public: Offset(const ColumnMajorWithSum & params,const InType * source,int offset_stride,int offset_advance)97*5f39d1b3SJooyung Han static const InType* Offset(const ColumnMajorWithSum& params, 98*5f39d1b3SJooyung Han const InType* source, int offset_stride, 99*5f39d1b3SJooyung Han int offset_advance) { 100*5f39d1b3SJooyung Han return reinterpret_cast<const InType*>( 101*5f39d1b3SJooyung Han reinterpret_cast<const std::uint8_t*>(source) + 102*5f39d1b3SJooyung Han params.stride * offset_advance + offset_stride * sizeof(InType)); 103*5f39d1b3SJooyung Han } 104*5f39d1b3SJooyung Han Offset(const ColumnMajorWithSum & params,InType * source,int offset_stride,int offset_advance)105*5f39d1b3SJooyung Han static const InType* Offset(const ColumnMajorWithSum& params, InType* source, 106*5f39d1b3SJooyung Han int offset_stride, int offset_advance) { 107*5f39d1b3SJooyung Han return reinterpret_cast<InType*>(reinterpret_cast<std::uint8_t*>(source) + 108*5f39d1b3SJooyung Han params.stride * offset_advance + 109*5f39d1b3SJooyung Han offset_stride * sizeof(InType)); 110*5f39d1b3SJooyung Han } 111*5f39d1b3SJooyung Han Scratch(const ColumnMajorWithSum & params,int lanes_count,int pack_size)112*5f39d1b3SJooyung Han static int Scratch(const ColumnMajorWithSum& params, int lanes_count, 113*5f39d1b3SJooyung Han int pack_size) { 114*5f39d1b3SJooyung Han return 32 + AlignTo<32>(sizeof(InType) * lanes_count * 115*5f39d1b3SJooyung Han AlignTo(pack_size, params.count)); 116*5f39d1b3SJooyung Han } 117*5f39d1b3SJooyung Han }; 118*5f39d1b3SJooyung Han 119*5f39d1b3SJooyung Han template <typename InType, int lanes_count, int pack_size, int leftovers> 120*5f39d1b3SJooyung Han class Stream<InType, lanes_count, pack_size, leftovers, RowMajor> { 121*5f39d1b3SJooyung Han public: Pack(const InType * in,const RowMajor & params,InType * out)122*5f39d1b3SJooyung Han static void Pack(const InType* in, const RowMajor& params, InType* out) { 123*5f39d1b3SJooyung Han #ifdef DEBUG 124*5f39d1b3SJooyung Han #ifdef DEBUG_METAGEMM_VERBOSE 125*5f39d1b3SJooyung Han std::cout << "RowMajor(" << std::string(typeid(InType).name()) 126*5f39d1b3SJooyung Han << ")::Pack() -- " << lanes_count << "x" << pack_size << " + " 127*5f39d1b3SJooyung Han << leftovers << std::endl; 128*5f39d1b3SJooyung Han #endif 129*5f39d1b3SJooyung Han #else 130*5f39d1b3SJooyung Han if (lanes_count != 0) { 131*5f39d1b3SJooyung Han std::cerr << "FATAL: RowMajorWithSum::Pack not implemented." << std::endl; 132*5f39d1b3SJooyung Han std::exit(1); 133*5f39d1b3SJooyung Han } 134*5f39d1b3SJooyung Han #endif 135*5f39d1b3SJooyung Han } 136*5f39d1b3SJooyung Han UnpackedAdvance(const RowMajor & params)137*5f39d1b3SJooyung Han static int UnpackedAdvance(const RowMajor& params) { 138*5f39d1b3SJooyung Han return sizeof(InType) * pack_size; 139*5f39d1b3SJooyung Han } 140*5f39d1b3SJooyung Han PackedAdvance(const RowMajor & params)141*5f39d1b3SJooyung Han static int PackedAdvance(const RowMajor& params) { 142*5f39d1b3SJooyung Han return sizeof(InType) * pack_size * lanes_count; 143*5f39d1b3SJooyung Han } 144*5f39d1b3SJooyung Han UnpackedStride(const RowMajor & params)145*5f39d1b3SJooyung Han static int UnpackedStride(const RowMajor& params) { 146*5f39d1b3SJooyung Han return lanes_count * params.stride; 147*5f39d1b3SJooyung Han } 148*5f39d1b3SJooyung Han PackedStride(const RowMajor & params)149*5f39d1b3SJooyung Han static int PackedStride(const RowMajor& params) { 150*5f39d1b3SJooyung Han return AlignTo<32>(lanes_count * AlignTo<pack_size>(params.stride)); 151*5f39d1b3SJooyung Han } 152*5f39d1b3SJooyung Han Scratch(const RowMajor & params)153*5f39d1b3SJooyung Han static int Scratch(const RowMajor& params) { return PackedStride(params); } 154*5f39d1b3SJooyung Han 155*5f39d1b3SJooyung Han #ifdef DEBUG 156*5f39d1b3SJooyung Han #ifdef DEBUG_METAGEMM_VERBOSE Debug(const RowMajor & params)157*5f39d1b3SJooyung Han static void Debug(const RowMajor& params) { 158*5f39d1b3SJooyung Han std::cout << "RowMajor(" << typeid(InType).name() << ")" << std::endl; 159*5f39d1b3SJooyung Han std::cout << " dims: " << lanes_count << "x" << pack_size << " + " 160*5f39d1b3SJooyung Han << leftovers << std::endl; 161*5f39d1b3SJooyung Han std::cout << " scratch: " << Scratch(params) << std::endl; 162*5f39d1b3SJooyung Han std::cout << " unpacked advance: " << UnpackedAdvance(params) << std::endl; 163*5f39d1b3SJooyung Han std::cout << " packed advance: " << PackedAdvance(params) << std::endl; 164*5f39d1b3SJooyung Han std::cout << " unpacked stride: " << UnpackedStride(params) << std::endl; 165*5f39d1b3SJooyung Han std::cout << " packed stride: " << PackedStride(params) << std::endl; 166*5f39d1b3SJooyung Han std::cout << " params:" << std::endl; 167*5f39d1b3SJooyung Han std::cout << " count: " << params.count << std::endl; 168*5f39d1b3SJooyung Han std::cout << " stride: " << params.stride << std::endl; 169*5f39d1b3SJooyung Han } 170*5f39d1b3SJooyung Han #endif 171*5f39d1b3SJooyung Han #endif 172*5f39d1b3SJooyung Han }; 173*5f39d1b3SJooyung Han 174*5f39d1b3SJooyung Han template <typename InType, int lanes_count, int pack_size, int leftovers> 175*5f39d1b3SJooyung Han class Stream<InType, lanes_count, pack_size, leftovers, RowMajorWithSum> { 176*5f39d1b3SJooyung Han public: Pack(const InType * in,const RowMajorWithSum & params,InType * out)177*5f39d1b3SJooyung Han static void Pack(const InType* in, const RowMajorWithSum& params, 178*5f39d1b3SJooyung Han InType* out) { 179*5f39d1b3SJooyung Han #ifdef DEBUG 180*5f39d1b3SJooyung Han #ifdef DEBUG_METAGEMM_VERBOSE 181*5f39d1b3SJooyung Han std::cout << "RowMajorWithSum(" << typeid(InType).name() << ")::Pack() -- " 182*5f39d1b3SJooyung Han << lanes_count << "x" << pack_size << " + " << leftovers 183*5f39d1b3SJooyung Han << std::endl; 184*5f39d1b3SJooyung Han #endif 185*5f39d1b3SJooyung Han #else 186*5f39d1b3SJooyung Han if (lanes_count != 0) { 187*5f39d1b3SJooyung Han std::cerr << "FATAL: RowMajorWithSum::Pack not implemented." << std::endl; 188*5f39d1b3SJooyung Han std::exit(1); 189*5f39d1b3SJooyung Han } 190*5f39d1b3SJooyung Han #endif 191*5f39d1b3SJooyung Han } 192*5f39d1b3SJooyung Han UnpackedAdvance(const RowMajorWithSum & params)193*5f39d1b3SJooyung Han static int UnpackedAdvance(const RowMajorWithSum& params) { 194*5f39d1b3SJooyung Han return sizeof(InType) * pack_size; 195*5f39d1b3SJooyung Han } 196*5f39d1b3SJooyung Han PackedAdvance(const RowMajorWithSum & params)197*5f39d1b3SJooyung Han static int PackedAdvance(const RowMajorWithSum& params) { 198*5f39d1b3SJooyung Han return sizeof(InType) * pack_size * lanes_count; 199*5f39d1b3SJooyung Han } 200*5f39d1b3SJooyung Han UnpackedStride(const RowMajorWithSum & params)201*5f39d1b3SJooyung Han static int UnpackedStride(const RowMajorWithSum& params) { 202*5f39d1b3SJooyung Han return sizeof(InType) * lanes_count * params.stride; 203*5f39d1b3SJooyung Han } 204*5f39d1b3SJooyung Han PackedStride(const RowMajorWithSum & params)205*5f39d1b3SJooyung Han static int PackedStride(const RowMajorWithSum& params) { 206*5f39d1b3SJooyung Han return 32 + AlignTo<32>(sizeof(InType) * lanes_count * 207*5f39d1b3SJooyung Han AlignTo<pack_size>(params.count)); 208*5f39d1b3SJooyung Han } 209*5f39d1b3SJooyung Han Scratch(const RowMajorWithSum & params)210*5f39d1b3SJooyung Han static int Scratch(const RowMajorWithSum& params) { 211*5f39d1b3SJooyung Han return PackedStride(params); 212*5f39d1b3SJooyung Han } 213*5f39d1b3SJooyung Han 214*5f39d1b3SJooyung Han #ifdef DEBUG 215*5f39d1b3SJooyung Han #ifdef DEBUG_METAGEMM_VERBOSE Debug(const RowMajorWithSum & params)216*5f39d1b3SJooyung Han static void Debug(const RowMajorWithSum& params) { 217*5f39d1b3SJooyung Han std::cout << "RowMajorWithSum(" << typeid(InType).name() << ")" 218*5f39d1b3SJooyung Han << std::endl; 219*5f39d1b3SJooyung Han std::cout << " dims: " << lanes_count << "x" << pack_size << " + " 220*5f39d1b3SJooyung Han << leftovers << std::endl; 221*5f39d1b3SJooyung Han std::cout << " scratch: " << Scratch(params) << std::endl; 222*5f39d1b3SJooyung Han std::cout << " unpacked advance: " << UnpackedAdvance(params) << std::endl; 223*5f39d1b3SJooyung Han std::cout << " packed advance: " << PackedAdvance(params) << std::endl; 224*5f39d1b3SJooyung Han std::cout << " unpacked stride: " << UnpackedStride(params) << std::endl; 225*5f39d1b3SJooyung Han std::cout << " packed stride: " << PackedStride(params) << std::endl; 226*5f39d1b3SJooyung Han std::cout << " params:" << std::endl; 227*5f39d1b3SJooyung Han std::cout << " count: " << params.count << std::endl; 228*5f39d1b3SJooyung Han std::cout << " stride: " << params.stride << std::endl; 229*5f39d1b3SJooyung Han std::cout << " multiplicative_sum_offset: " 230*5f39d1b3SJooyung Han << params.multiplicative_sum_offset << std::endl; 231*5f39d1b3SJooyung Han std::cout << " additive_sum_offset: " << params.additive_sum_offset 232*5f39d1b3SJooyung Han << std::endl; 233*5f39d1b3SJooyung Han } 234*5f39d1b3SJooyung Han #endif 235*5f39d1b3SJooyung Han #endif 236*5f39d1b3SJooyung Han }; 237*5f39d1b3SJooyung Han 238*5f39d1b3SJooyung Han template <typename InType, int lanes_count, int pack_size, int leftovers> 239*5f39d1b3SJooyung Han class Stream<InType, lanes_count, pack_size, leftovers, ColumnMajorWithSum> { 240*5f39d1b3SJooyung Han public: Pack(const InType * in,const ColumnMajorWithSum & params,InType * out)241*5f39d1b3SJooyung Han static void Pack(const InType* in, const ColumnMajorWithSum& params, 242*5f39d1b3SJooyung Han InType* out) { 243*5f39d1b3SJooyung Han #ifdef DEBUG 244*5f39d1b3SJooyung Han #ifdef DEBUG_METAGEMM_VERBOSE 245*5f39d1b3SJooyung Han std::cout << "ColumnMajorWithSum(" << typeid(InType).name() 246*5f39d1b3SJooyung Han << ")::Pack() -- " << lanes_count << "x" << pack_size << " + " 247*5f39d1b3SJooyung Han << leftovers << std::endl; 248*5f39d1b3SJooyung Han #endif 249*5f39d1b3SJooyung Han #else 250*5f39d1b3SJooyung Han if (lanes_count != 0) { 251*5f39d1b3SJooyung Han std::cerr << "FATAL: ColumnMajorWithSum::Pack not implemented." 252*5f39d1b3SJooyung Han << std::endl; 253*5f39d1b3SJooyung Han std::exit(1); 254*5f39d1b3SJooyung Han } 255*5f39d1b3SJooyung Han #endif 256*5f39d1b3SJooyung Han } 257*5f39d1b3SJooyung Han UnpackedAdvance(const ColumnMajorWithSum & params)258*5f39d1b3SJooyung Han static int UnpackedAdvance(const ColumnMajorWithSum& params) { 259*5f39d1b3SJooyung Han return sizeof(InType) * pack_size * params.stride; 260*5f39d1b3SJooyung Han } 261*5f39d1b3SJooyung Han PackedAdvance(const ColumnMajorWithSum & params)262*5f39d1b3SJooyung Han static int PackedAdvance(const ColumnMajorWithSum& params) { 263*5f39d1b3SJooyung Han return sizeof(InType) * pack_size * lanes_count; 264*5f39d1b3SJooyung Han } 265*5f39d1b3SJooyung Han UnpackedStride(const ColumnMajorWithSum & params)266*5f39d1b3SJooyung Han static int UnpackedStride(const ColumnMajorWithSum& params) { 267*5f39d1b3SJooyung Han return sizeof(InType) * lanes_count; 268*5f39d1b3SJooyung Han } 269*5f39d1b3SJooyung Han PackedStride(const ColumnMajorWithSum & params)270*5f39d1b3SJooyung Han static int PackedStride(const ColumnMajorWithSum& params) { 271*5f39d1b3SJooyung Han return 32 + AlignTo<32>(sizeof(InType) * lanes_count * 272*5f39d1b3SJooyung Han AlignTo<pack_size>(params.count)); 273*5f39d1b3SJooyung Han } 274*5f39d1b3SJooyung Han Scratch(const ColumnMajorWithSum & params)275*5f39d1b3SJooyung Han static int Scratch(const ColumnMajorWithSum& params) { 276*5f39d1b3SJooyung Han return PackedStride(params); 277*5f39d1b3SJooyung Han } 278*5f39d1b3SJooyung Han 279*5f39d1b3SJooyung Han #ifdef DEBUG 280*5f39d1b3SJooyung Han #ifdef DEBUG_METAGEMM_VERBOSE Debug(const ColumnMajorWithSum & params)281*5f39d1b3SJooyung Han static void Debug(const ColumnMajorWithSum& params) { 282*5f39d1b3SJooyung Han std::cout << "ColumnMajorWithSum(" << typeid(InType).name() << ")" 283*5f39d1b3SJooyung Han << std::endl; 284*5f39d1b3SJooyung Han std::cout << " dims: " << lanes_count << "x" << pack_size << " + " 285*5f39d1b3SJooyung Han << leftovers << std::endl; 286*5f39d1b3SJooyung Han std::cout << " scratch: " << Scratch(params) << std::endl; 287*5f39d1b3SJooyung Han std::cout << " unpacked advance: " << UnpackedAdvance(params) << std::endl; 288*5f39d1b3SJooyung Han std::cout << " packed advance: " << PackedAdvance(params) << std::endl; 289*5f39d1b3SJooyung Han std::cout << " unpacked stride: " << UnpackedStride(params) << std::endl; 290*5f39d1b3SJooyung Han std::cout << " packed stride: " << PackedStride(params) << std::endl; 291*5f39d1b3SJooyung Han std::cout << " params:" << std::endl; 292*5f39d1b3SJooyung Han std::cout << " count: " << params.count << std::endl; 293*5f39d1b3SJooyung Han std::cout << " stride: " << params.stride << std::endl; 294*5f39d1b3SJooyung Han std::cout << " multiplicative_sum_offset: " 295*5f39d1b3SJooyung Han << params.multiplicative_sum_offset << std::endl; 296*5f39d1b3SJooyung Han std::cout << " additive_sum_offset: " << params.additive_sum_offset 297*5f39d1b3SJooyung Han << std::endl; 298*5f39d1b3SJooyung Han } 299*5f39d1b3SJooyung Han #endif 300*5f39d1b3SJooyung Han #endif 301*5f39d1b3SJooyung Han }; 302*5f39d1b3SJooyung Han 303*5f39d1b3SJooyung Han } // namespace meta 304*5f39d1b3SJooyung Han } // namespace gemmlowp 305*5f39d1b3SJooyung Han 306*5f39d1b3SJooyung Han #ifdef GEMMLOWP_NEON_32 307*5f39d1b3SJooyung Han #include "streams_arm_32.h" 308*5f39d1b3SJooyung Han #elif defined(GEMMLOWP_NEON_64) 309*5f39d1b3SJooyung Han #include "streams_arm_64.h" 310*5f39d1b3SJooyung Han #endif 311*5f39d1b3SJooyung Han 312*5f39d1b3SJooyung Han #endif // GEMMLOWP_META_STREAMS_H_ 313