blob: 90ae7bb1a2913008c1c99f4d7c1303fda8136b91 [file] [log] [blame]
// Copyright 2016 The Gemmlowp Authors. 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 GEMMLOWP_META_STREAMS_H_
#define GEMMLOWP_META_STREAMS_H_
#include <iostream>
#include <typeinfo>
#include "base.h"
namespace gemmlowp {
namespace meta {
struct RowMajor {
public:
int count;
int stride;
};
struct RowMajorWithSum {
public:
int count;
int stride;
int multiplicative_sum_offset;
int additive_sum_offset;
};
struct ColumnMajorWithSum {
public:
int count;
int stride;
int multiplicative_sum_offset;
int additive_sum_offset;
};
template <typename InType>
class StreamUtil<InType, RowMajor> {
public:
static const InType* Offset(const RowMajor& params, const InType* source,
int offset_stride, int offset_advance) {
return reinterpret_cast<const InType*>(
reinterpret_cast<const std::uint8_t*>(source) +
offset_stride * params.stride + offset_advance * sizeof(InType));
}
static InType* Offset(const RowMajor& params, InType* source,
int offset_stride, int offset_advance) {
return reinterpret_cast<InType*>(reinterpret_cast<std::uint8_t*>(source) +
offset_stride * params.stride +
offset_advance * sizeof(InType));
}
static int Scratch(const RowMajor& params, int lanes_count, int pack_size) {
return AlignTo<64>(lanes_count * AlignTo(pack_size, params.stride));
}
};
template <typename InType>
class StreamUtil<InType, RowMajorWithSum> {
public:
static const InType* Offset(const RowMajorWithSum& params,
const InType* source, int offset_stride,
int offset_advance) {
return reinterpret_cast<const InType*>(
reinterpret_cast<const std::uint8_t*>(source) +
offset_stride * params.stride + offset_advance * sizeof(InType));
}
static InType* Offset(const RowMajorWithSum& params, InType* source,
int offset_stride, int offset_advance) {
return reinterpret_cast<InType*>(reinterpret_cast<std::uint8_t*>(source) +
offset_stride * params.stride +
offset_advance * sizeof(InType));
}
static int Scratch(const RowMajorWithSum& params, int lanes_count,
int pack_size) {
return 32 + AlignTo<32>(sizeof(InType) * lanes_count *
AlignTo(pack_size, params.count));
}
};
template <typename InType>
class StreamUtil<InType, ColumnMajorWithSum> {
public:
static const InType* Offset(const ColumnMajorWithSum& params,
const InType* source, int offset_stride,
int offset_advance) {
return reinterpret_cast<const InType*>(
reinterpret_cast<const std::uint8_t*>(source) +
params.stride * offset_advance + offset_stride * sizeof(InType));
}
static const InType* Offset(const ColumnMajorWithSum& params, InType* source,
int offset_stride, int offset_advance) {
return reinterpret_cast<InType*>(reinterpret_cast<std::uint8_t*>(source) +
params.stride * offset_advance +
offset_stride * sizeof(InType));
}
static int Scratch(const ColumnMajorWithSum& params, int lanes_count,
int pack_size) {
return 32 + AlignTo<32>(sizeof(InType) * lanes_count *
AlignTo(pack_size, params.count));
}
};
template <typename InType, int lanes_count, int pack_size, int leftovers>
class Stream<InType, lanes_count, pack_size, leftovers, RowMajor> {
public:
static void Pack(const InType* in, const RowMajor& params, InType* out) {
#ifdef DEBUG
#ifdef DEBUG_METAGEMM_VERBOSE
std::cout << "RowMajor(" << std::string(typeid(InType).name())
<< ")::Pack() -- " << lanes_count << "x" << pack_size << " + "
<< leftovers << std::endl;
#endif
#else
if (lanes_count != 0) {
std::cerr << "FATAL: RowMajorWithSum::Pack not implemented." << std::endl;
std::exit(1);
}
#endif
}
static int UnpackedAdvance(const RowMajor& params) {
return sizeof(InType) * pack_size;
}
static int PackedAdvance(const RowMajor& params) {
return sizeof(InType) * pack_size * lanes_count;
}
static int UnpackedStride(const RowMajor& params) {
return lanes_count * params.stride;
}
static int PackedStride(const RowMajor& params) {
return AlignTo<32>(lanes_count * AlignTo<pack_size>(params.stride));
}
static int Scratch(const RowMajor& params) { return PackedStride(params); }
#ifdef DEBUG
#ifdef DEBUG_METAGEMM_VERBOSE
static void Debug(const RowMajor& params) {
std::cout << "RowMajor(" << typeid(InType).name() << ")" << std::endl;
std::cout << " dims: " << lanes_count << "x" << pack_size << " + "
<< leftovers << std::endl;
std::cout << " scratch: " << Scratch(params) << std::endl;
std::cout << " unpacked advance: " << UnpackedAdvance(params) << std::endl;
std::cout << " packed advance: " << PackedAdvance(params) << std::endl;
std::cout << " unpacked stride: " << UnpackedStride(params) << std::endl;
std::cout << " packed stride: " << PackedStride(params) << std::endl;
std::cout << " params:" << std::endl;
std::cout << " count: " << params.count << std::endl;
std::cout << " stride: " << params.stride << std::endl;
}
#endif
#endif
};
template <typename InType, int lanes_count, int pack_size, int leftovers>
class Stream<InType, lanes_count, pack_size, leftovers, RowMajorWithSum> {
public:
static void Pack(const InType* in, const RowMajorWithSum& params,
InType* out) {
#ifdef DEBUG
#ifdef DEBUG_METAGEMM_VERBOSE
std::cout << "RowMajorWithSum(" << typeid(InType).name() << ")::Pack() -- "
<< lanes_count << "x" << pack_size << " + " << leftovers
<< std::endl;
#endif
#else
if (lanes_count != 0) {
std::cerr << "FATAL: RowMajorWithSum::Pack not implemented." << std::endl;
std::exit(1);
}
#endif
}
static int UnpackedAdvance(const RowMajorWithSum& params) {
return sizeof(InType) * pack_size;
}
static int PackedAdvance(const RowMajorWithSum& params) {
return sizeof(InType) * pack_size * lanes_count;
}
static int UnpackedStride(const RowMajorWithSum& params) {
return sizeof(InType) * lanes_count * params.stride;
}
static int PackedStride(const RowMajorWithSum& params) {
return 32 + AlignTo<32>(sizeof(InType) * lanes_count *
AlignTo<pack_size>(params.count));
}
static int Scratch(const RowMajorWithSum& params) {
return PackedStride(params);
}
#ifdef DEBUG
#ifdef DEBUG_METAGEMM_VERBOSE
static void Debug(const RowMajorWithSum& params) {
std::cout << "RowMajorWithSum(" << typeid(InType).name() << ")"
<< std::endl;
std::cout << " dims: " << lanes_count << "x" << pack_size << " + "
<< leftovers << std::endl;
std::cout << " scratch: " << Scratch(params) << std::endl;
std::cout << " unpacked advance: " << UnpackedAdvance(params) << std::endl;
std::cout << " packed advance: " << PackedAdvance(params) << std::endl;
std::cout << " unpacked stride: " << UnpackedStride(params) << std::endl;
std::cout << " packed stride: " << PackedStride(params) << std::endl;
std::cout << " params:" << std::endl;
std::cout << " count: " << params.count << std::endl;
std::cout << " stride: " << params.stride << std::endl;
std::cout << " multiplicative_sum_offset: "
<< params.multiplicative_sum_offset << std::endl;
std::cout << " additive_sum_offset: " << params.additive_sum_offset
<< std::endl;
}
#endif
#endif
};
template <typename InType, int lanes_count, int pack_size, int leftovers>
class Stream<InType, lanes_count, pack_size, leftovers, ColumnMajorWithSum> {
public:
static void Pack(const InType* in, const ColumnMajorWithSum& params,
InType* out) {
#ifdef DEBUG
#ifdef DEBUG_METAGEMM_VERBOSE
std::cout << "ColumnMajorWithSum(" << typeid(InType).name()
<< ")::Pack() -- " << lanes_count << "x" << pack_size << " + "
<< leftovers << std::endl;
#endif
#else
if (lanes_count != 0) {
std::cerr << "FATAL: ColumnMajorWithSum::Pack not implemented."
<< std::endl;
std::exit(1);
}
#endif
}
static int UnpackedAdvance(const ColumnMajorWithSum& params) {
return sizeof(InType) * pack_size * params.stride;
}
static int PackedAdvance(const ColumnMajorWithSum& params) {
return sizeof(InType) * pack_size * lanes_count;
}
static int UnpackedStride(const ColumnMajorWithSum& params) {
return sizeof(InType) * lanes_count;
}
static int PackedStride(const ColumnMajorWithSum& params) {
return 32 + AlignTo<32>(sizeof(InType) * lanes_count *
AlignTo<pack_size>(params.count));
}
static int Scratch(const ColumnMajorWithSum& params) {
return PackedStride(params);
}
#ifdef DEBUG
#ifdef DEBUG_METAGEMM_VERBOSE
static void Debug(const ColumnMajorWithSum& params) {
std::cout << "ColumnMajorWithSum(" << typeid(InType).name() << ")"
<< std::endl;
std::cout << " dims: " << lanes_count << "x" << pack_size << " + "
<< leftovers << std::endl;
std::cout << " scratch: " << Scratch(params) << std::endl;
std::cout << " unpacked advance: " << UnpackedAdvance(params) << std::endl;
std::cout << " packed advance: " << PackedAdvance(params) << std::endl;
std::cout << " unpacked stride: " << UnpackedStride(params) << std::endl;
std::cout << " packed stride: " << PackedStride(params) << std::endl;
std::cout << " params:" << std::endl;
std::cout << " count: " << params.count << std::endl;
std::cout << " stride: " << params.stride << std::endl;
std::cout << " multiplicative_sum_offset: "
<< params.multiplicative_sum_offset << std::endl;
std::cout << " additive_sum_offset: " << params.additive_sum_offset
<< std::endl;
}
#endif
#endif
};
} // namespace meta
} // namespace gemmlowp
#ifdef GEMMLOWP_NEON_32
#include "streams_arm_32.h"
#elif defined(GEMMLOWP_NEON_64)
#include "streams_arm_64.h"
#endif
#endif // GEMMLOWP_META_STREAMS_H_