/*
 * Copyright (c) 2019 ARM Limited.
 *
 * SPDX-License-Identifier: MIT
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#pragma once

#include "arm_gemm.hpp"

#include "barrier.hpp"
#include "gemm_implementation.hpp"
#include "quantized.hpp"

namespace arm_gemm {

/* Quantized wrapper - do an integer GEMM and wrap around the quantization. */

template<typename To, typename Tr, typename Tgemm>
class QuantizeWrapper : public GemmCommon<To, Tr> {
private:
    UniqueGemmCommon<To, Tgemm>  _subgemm = nullptr;
    int32_t                     *_row_sums = nullptr;
    int32_t                     *_col_sums = nullptr;
    Requantize32                 _params;
    GemmArgs                     _args;
    barrier                      _barrier;

    void *working_space = nullptr;
    bool  arrays_set = false;

    /* We need a subgemm which outputs the 32-bit intermediates - how much space is needed for that? */
    size_t subgemm_output_size() const {
        return (_args._Msize * _args._Nsize * _args._nbatches * _args._nmulti * sizeof(int32_t));
    }

    size_t col_sum_size() const {
        return (_args._Nsize * _args._nmulti * sizeof(int32_t));
    }

    size_t row_sum_size() const {
        return (_args._Msize * _args._nbatches * _args._nmulti * sizeof(int32_t));
    }

    /* Local working space: We need space for the subgemm output (above) and
     * the row sums.  If the GEMM is not pretransposed we need to store the
     * column sums here too.  */
    size_t local_working_size() const {
        size_t sz = subgemm_output_size() + row_sum_size();

        if (_args._pretransposed_hint) {
            return sz;
        }

        return sz + col_sum_size();
    }

    void set_child_arrays() {
        if (working_space == nullptr || arrays_set == false)
            return;

        /* Use the first part of our working space for the subgemm result, pass the operand details straight through. */
        _subgemm->set_arrays(this->_Aptr, this->_lda, this->_A_batch_stride, this->_A_multi_stride,
                             this->_Bptr, this->_ldb,                        this->_B_multi_stride,
                             reinterpret_cast<Tgemm *>(working_space), _args._Nsize, (_args._Nsize * _args._Msize), (_args._Nsize * _args._Msize * _args._nbatches),
                             nullptr, 0);
    }

    void col_sums_pretransposed(const To *B, const int ldb, const int B_multi_stride) {
        for (unsigned int multi=0; multi<_args._nmulti; multi++) {
            compute_col_sums(_params, _args._Nsize, _args._Ksize, B + (multi * B_multi_stride), ldb, _col_sums + (multi * _args._Nsize), _args._Ksize, multi, 0);
        }
    }

    void col_sums_runtime(unsigned int threadid) {
        unsigned int first_col = (threadid * _args._Nsize) / _args._maxthreads;
        unsigned int last_col = ((threadid + 1) * _args._Nsize) / _args._maxthreads;

        for (unsigned int multi=0; multi<_args._nmulti; multi++) {
            compute_col_sums(_params, (last_col - first_col), _args._Ksize, this->_Bptr + (multi * this->_B_multi_stride) + first_col, this->_ldb, _col_sums + (multi * _args._Nsize) + first_col, _args._Ksize, multi, first_col);
        }
    }

    void requantize_runtime(unsigned int threadid) {
        unsigned int first_row = (threadid * _args._Msize) / _args._maxthreads;
        unsigned int last_row = ((threadid+1) * _args._Msize) / _args._maxthreads;

        for (unsigned int multi=0; multi<_args._nmulti; multi++) {
            for (unsigned int batch=0; batch<_args._nbatches; batch++) {
                /* Compute row sums now */
                compute_row_sums(_params, _args._Ksize, (last_row - first_row), this->_Aptr + (multi * this->_A_multi_stride) + (batch * this->_A_batch_stride) + (first_row * this->_lda),
                                           this->_lda, _row_sums + (multi * _args._nbatches * _args._Msize) + (batch * _args._Msize) + first_row);
                // If we don't care about negative values, call the version of this function that doesn't correct before shifting.
                // 'c_offset' represents zero, so if the lowest possible quantized output value is the same or more than that we will not output negative numbers.
                requantize_block_32(_params, _args._Nsize, (last_row - first_row),
                                    reinterpret_cast<Tgemm *>(working_space) + (multi * (_args._Msize * _args._Nsize * _args._nbatches)) + (batch * (_args._Msize * _args._Nsize)) + (first_row * _args._Nsize),
                                    _args._Nsize,
                                    this->_Cptr + (multi * this->_C_multi_stride) + (batch * this->_C_batch_stride) + (first_row * this->_ldc), this->_ldc,
                                    _row_sums + (multi * _args._nbatches * _args._Msize) + (batch * _args._Msize) + first_row,
                                    _col_sums + (multi * _args._Nsize));
            }
        }
    }


public:
    QuantizeWrapper(const QuantizeWrapper &) = delete;
    QuantizeWrapper operator=(const QuantizeWrapper &) = delete;

    QuantizeWrapper(const GemmArgs &args, const Requantize32 &qp) : _params(qp), _args(args), _barrier(args._maxthreads) {
        GemmArgs newargs = GemmArgs(args._ci, args._Msize, args._Nsize, args._Ksize, args._nbatches, args._nmulti, args._trA, args._trB, Activation(), args._maxthreads, args._pretransposed_hint, nullptr);
        _subgemm = gemm<To, Tgemm>(newargs);

        if (_subgemm == nullptr) {
            return;
        }

        if (!_subgemm->B_is_pretransposed()) {
            _args._pretransposed_hint = false;
        }
    }

    void set_arrays(const To *A, const int lda, const int A_batch_stride, const int A_multi_stride,
                    const To *B, const int ldb, const int B_multi_stride,
                          Tr *C, const int ldc, const int C_batch_stride, const int C_multi_stride,
                    const Tr *bias, const int bias_multi_stride) override {
        GemmCommon<To, Tr>::set_arrays(A, lda, A_batch_stride, A_multi_stride, B, ldb, B_multi_stride, C, ldc, C_batch_stride, C_multi_stride, bias, bias_multi_stride);

        arrays_set = true;
        set_child_arrays();
    }

    unsigned int get_window_size() const override {
        return _subgemm->get_window_size();
    }

    void set_nthreads(int nthreads) override {
        _subgemm->set_nthreads(nthreads);
        _barrier.set_nthreads(nthreads);
        _args._maxthreads = nthreads;
    }

    void execute(unsigned int start, unsigned int end, int threadid) override {
        _subgemm->execute(start, end, threadid);
        if (!_args._pretransposed_hint) {
            col_sums_runtime(threadid);
        }

        _barrier.arrive_and_wait();

        requantize_runtime(threadid);
    }

    size_t get_working_size() const override {
        return _subgemm->get_working_size() + local_working_size();
    }

    // Space arrangement:

    // ptr
    // V
    // | subgemm output | row_sums | col_sums (if not pretransposed | subgemm working space |
    void set_working_space(void *space) override {
        uintptr_t space_int = reinterpret_cast<uintptr_t>(space);

        working_space = space;
        _subgemm->set_working_space(reinterpret_cast<void *>(space_int + local_working_size()));

        _row_sums = reinterpret_cast<int32_t *>(space_int + subgemm_output_size());
        if (!_args._pretransposed_hint) {
            _col_sums = reinterpret_cast<int32_t *>(space_int + subgemm_output_size() + row_sum_size());
        }

        set_child_arrays();
    }

    bool B_is_pretransposed() const override {
        /* We clear this flag if the subgemm isn't pretransposed, so just return its value */
        return _args._pretransposed_hint;
    }

    bool B_pretranspose_required() const override {
        return _subgemm->B_pretranspose_required();
    }

    size_t get_B_pretransposed_array_size() const override {
        if (_args._pretransposed_hint) {
            return _subgemm->get_B_pretransposed_array_size() + col_sum_size();
        }

        return 0;
    }

    void pretranspose_B_array(void *buffer, const To *B, const int ldb, const int B_multi_stride) override {
        if (!_args._pretransposed_hint) {
            return;
        }

        uintptr_t buffer_int = reinterpret_cast<uintptr_t>(buffer);
        _subgemm->pretranspose_B_array(reinterpret_cast<void *>(buffer_int + col_sum_size()), B, ldb, B_multi_stride);

        _col_sums = reinterpret_cast<int32_t *>(buffer);

        col_sums_pretransposed(B, ldb, B_multi_stride);
    }

    void set_pretransposed_B_data(void *buffer) override {
        if (!_args._pretransposed_hint) {
            return;
        }

        uintptr_t buffer_int = reinterpret_cast<uintptr_t>(buffer);
        _subgemm->set_pretransposed_B_data(reinterpret_cast<void *>(buffer_int + col_sum_size()));
        _col_sums = reinterpret_cast<int32_t *>(buffer);
    }

    void set_quantized_bias(const int32_t *bias, size_t bias_multi_stride) override {
        _params.bias = bias;
        _params.bias_multi_stride = bias_multi_stride;
    }
};

} // namespace arm_gemm
