1*5f39d1b3SJooyung Han // Copyright 2015 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 // unpack.h: unpacking the result blocks computed by compute.h,
16*5f39d1b3SJooyung Han // storing them into the destination matrix.
17*5f39d1b3SJooyung Han
18*5f39d1b3SJooyung Han #ifndef GEMMLOWP_INTERNAL_UNPACK_H_
19*5f39d1b3SJooyung Han #define GEMMLOWP_INTERNAL_UNPACK_H_
20*5f39d1b3SJooyung Han
21*5f39d1b3SJooyung Han #include "allocator.h"
22*5f39d1b3SJooyung Han #include "block_params.h"
23*5f39d1b3SJooyung Han #include "output.h"
24*5f39d1b3SJooyung Han #include "pack.h"
25*5f39d1b3SJooyung Han
26*5f39d1b3SJooyung Han #include <cmath>
27*5f39d1b3SJooyung Han
28*5f39d1b3SJooyung Han namespace gemmlowp {
29*5f39d1b3SJooyung Han
30*5f39d1b3SJooyung Han class PackedResult {
31*5f39d1b3SJooyung Han public:
PackedResult(Allocator * _allocator,const BlockParams & _block_params)32*5f39d1b3SJooyung Han PackedResult(Allocator* _allocator, const BlockParams& _block_params)
33*5f39d1b3SJooyung Han : allocator_(_allocator), block_params_(_block_params) {
34*5f39d1b3SJooyung Han matrix_handle_ = allocator_->Reserve<std::int32_t>(block_params_.l2_rows *
35*5f39d1b3SJooyung Han block_params_.l2_cols);
36*5f39d1b3SJooyung Han }
37*5f39d1b3SJooyung Han
~PackedResult()38*5f39d1b3SJooyung Han ~PackedResult() {}
39*5f39d1b3SJooyung Han
Map()40*5f39d1b3SJooyung Han MatrixMap<std::int32_t, MapOrder::ColMajor> Map() {
41*5f39d1b3SJooyung Han return MatrixMap<std::int32_t, MapOrder::ColMajor>(
42*5f39d1b3SJooyung Han allocator_->GetPointer<std::int32_t>(matrix_handle_),
43*5f39d1b3SJooyung Han block_params_.l2_rows, block_params_.l2_cols, block_params_.l2_rows);
44*5f39d1b3SJooyung Han }
45*5f39d1b3SJooyung Han
Map()46*5f39d1b3SJooyung Han MatrixMap<const std::int32_t, MapOrder::ColMajor> Map() const {
47*5f39d1b3SJooyung Han return MatrixMap<const std::int32_t, MapOrder::ColMajor>(
48*5f39d1b3SJooyung Han allocator_->GetPointer<const std::int32_t>(matrix_handle_),
49*5f39d1b3SJooyung Han block_params_.l2_rows, block_params_.l2_cols, block_params_.l2_rows);
50*5f39d1b3SJooyung Han }
51*5f39d1b3SJooyung Han
52*5f39d1b3SJooyung Han private:
53*5f39d1b3SJooyung Han Allocator* allocator_;
54*5f39d1b3SJooyung Han Allocator::Handle matrix_handle_;
55*5f39d1b3SJooyung Han const BlockParams& block_params_;
56*5f39d1b3SJooyung Han };
57*5f39d1b3SJooyung Han
58*5f39d1b3SJooyung Han struct MatrixBlockBounds {
59*5f39d1b3SJooyung Han int start_row;
60*5f39d1b3SJooyung Han int start_col;
61*5f39d1b3SJooyung Han int rows;
62*5f39d1b3SJooyung Han int cols;
63*5f39d1b3SJooyung Han
MatrixBlockBoundsMatrixBlockBounds64*5f39d1b3SJooyung Han MatrixBlockBounds(int start_row_, int start_col_, int rows_, int cols_)
65*5f39d1b3SJooyung Han : start_row(start_row_),
66*5f39d1b3SJooyung Han start_col(start_col_),
67*5f39d1b3SJooyung Han rows(rows_),
68*5f39d1b3SJooyung Han cols(cols_) {}
69*5f39d1b3SJooyung Han };
70*5f39d1b3SJooyung Han
71*5f39d1b3SJooyung Han template <int Rows, int Cols, typename SrcMapType>
PrefetchResultBlock(const SrcMapType & src,const VectorMap<const std::int32_t,VectorShape::Col> & lhs_sums_of_each_slice,int src_row,int src_col)72*5f39d1b3SJooyung Han void PrefetchResultBlock(const SrcMapType& src,
73*5f39d1b3SJooyung Han const VectorMap<const std::int32_t, VectorShape::Col>&
74*5f39d1b3SJooyung Han lhs_sums_of_each_slice,
75*5f39d1b3SJooyung Han int src_row, int src_col) {
76*5f39d1b3SJooyung Han const std::int32_t* src_data = src.data(src_row, src_col);
77*5f39d1b3SJooyung Han const int src_stride = src.stride();
78*5f39d1b3SJooyung Han const std::int32_t* lhs_sums_data = lhs_sums_of_each_slice.data(src_row);
79*5f39d1b3SJooyung Han for (int r = 0; r < Rows; r += 4) {
80*5f39d1b3SJooyung Han Prefetch(lhs_sums_data + r);
81*5f39d1b3SJooyung Han }
82*5f39d1b3SJooyung Han for (int c = 0; c < Cols; c++) {
83*5f39d1b3SJooyung Han for (int r = 0; r < Rows; r += 4) {
84*5f39d1b3SJooyung Han Prefetch(src_data + r + c * src_stride);
85*5f39d1b3SJooyung Han }
86*5f39d1b3SJooyung Han }
87*5f39d1b3SJooyung Han }
88*5f39d1b3SJooyung Han
89*5f39d1b3SJooyung Han template <typename KernelFormat, typename RegisterBlockType,
90*5f39d1b3SJooyung Han typename SrcMapType, typename LhsOffset, typename RhsOffset,
91*5f39d1b3SJooyung Han typename OutputPipelineExecutorType, typename DstType>
UnpackResultBlock(const SrcMapType & src,const OutputPipelineExecutorType & executor,DstType * dst,const VectorMap<const std::int32_t,VectorShape::Col> & lhs_sums_of_each_slice,const VectorMap<const std::int32_t,VectorShape::Row> & rhs_sums_of_each_slice,const LhsOffset & lhs_offset,const RhsOffset & rhs_offset,int depth,int src_row,int src_col,int src_global_row,int src_global_col,int dst_row,int dst_col)92*5f39d1b3SJooyung Han void UnpackResultBlock(const SrcMapType& src,
93*5f39d1b3SJooyung Han const OutputPipelineExecutorType& executor, DstType* dst,
94*5f39d1b3SJooyung Han const VectorMap<const std::int32_t, VectorShape::Col>&
95*5f39d1b3SJooyung Han lhs_sums_of_each_slice,
96*5f39d1b3SJooyung Han const VectorMap<const std::int32_t, VectorShape::Row>&
97*5f39d1b3SJooyung Han rhs_sums_of_each_slice,
98*5f39d1b3SJooyung Han const LhsOffset& lhs_offset, const RhsOffset& rhs_offset,
99*5f39d1b3SJooyung Han int depth, int src_row, int src_col, int src_global_row,
100*5f39d1b3SJooyung Han int src_global_col, int dst_row, int dst_col) {
101*5f39d1b3SJooyung Han using KernelLhsInputScalar = typename KernelFormat::Lhs::InputScalar;
102*5f39d1b3SJooyung Han using KernelLhsScalar = typename KernelFormat::Lhs::Scalar;
103*5f39d1b3SJooyung Han using KernelRhsInputScalar = typename KernelFormat::Rhs::InputScalar;
104*5f39d1b3SJooyung Han using KernelRhsScalar = typename KernelFormat::Rhs::Scalar;
105*5f39d1b3SJooyung Han static constexpr int KernelLhsZeroPointInput =
106*5f39d1b3SJooyung Han ZeroPointInputValue<KernelLhsInputScalar, KernelLhsScalar>::kValue;
107*5f39d1b3SJooyung Han static constexpr int KernelRhsZeroPointInput =
108*5f39d1b3SJooyung Han ZeroPointInputValue<KernelRhsInputScalar, KernelRhsScalar>::kValue;
109*5f39d1b3SJooyung Han auto acc = Load<RegisterBlockType>(src, src_row, src_col);
110*5f39d1b3SJooyung Han const auto& lhs_sums_of_each_slice_block =
111*5f39d1b3SJooyung Han LoadForBroadcasting<RegisterBlockType>(lhs_sums_of_each_slice, src_row);
112*5f39d1b3SJooyung Han const auto& rhs_sums_of_each_slice_block =
113*5f39d1b3SJooyung Han LoadForBroadcasting<RegisterBlockType>(rhs_sums_of_each_slice, src_col);
114*5f39d1b3SJooyung Han auto lhs_offset_block =
115*5f39d1b3SJooyung Han LoadForBroadcasting<RegisterBlockType>(lhs_offset, src_row);
116*5f39d1b3SJooyung Han auto rhs_offset_block =
117*5f39d1b3SJooyung Han LoadForBroadcasting<RegisterBlockType>(rhs_offset, src_col);
118*5f39d1b3SJooyung Han AddConstant<KernelLhsZeroPointInput>(&lhs_offset_block);
119*5f39d1b3SJooyung Han AddConstant<KernelRhsZeroPointInput>(&rhs_offset_block);
120*5f39d1b3SJooyung Han BroadcastMulAdd(lhs_sums_of_each_slice_block, rhs_offset_block, &acc);
121*5f39d1b3SJooyung Han for (int i = 0; i < decltype(rhs_offset_block)::kRegisterCount; i++) {
122*5f39d1b3SJooyung Han rhs_offset_block.buf.reg[i] = Mul(rhs_offset_block.buf.reg[i], depth);
123*5f39d1b3SJooyung Han }
124*5f39d1b3SJooyung Han BroadcastMulAdd(BroadcastAdd(rhs_sums_of_each_slice_block, rhs_offset_block),
125*5f39d1b3SJooyung Han lhs_offset_block, &acc);
126*5f39d1b3SJooyung Han executor.Execute(acc, dst, src_global_row, src_global_col, dst_row, dst_col);
127*5f39d1b3SJooyung Han }
128*5f39d1b3SJooyung Han
129*5f39d1b3SJooyung Han template <typename KernelFormat, typename ResultBlockType,
130*5f39d1b3SJooyung Han typename PackedResultType, typename LhsOffset, typename RhsOffset,
131*5f39d1b3SJooyung Han typename OutputPipelineType>
UnpackResult(ResultBlockType * dst,const MatrixBlockBounds & dst_block,const PackedResultType & src,int depth,const std::int32_t * lhs_sums_of_each_slice_ptr,const std::int32_t * rhs_sums_of_each_slice_ptr,const LhsOffset & lhs_offset,const RhsOffset & rhs_offset,const OutputPipelineType & output_pipeline)132*5f39d1b3SJooyung Han void UnpackResult(ResultBlockType* dst, const MatrixBlockBounds& dst_block,
133*5f39d1b3SJooyung Han const PackedResultType& src, int depth,
134*5f39d1b3SJooyung Han const std::int32_t* lhs_sums_of_each_slice_ptr,
135*5f39d1b3SJooyung Han const std::int32_t* rhs_sums_of_each_slice_ptr,
136*5f39d1b3SJooyung Han const LhsOffset& lhs_offset, const RhsOffset& rhs_offset,
137*5f39d1b3SJooyung Han const OutputPipelineType& output_pipeline) {
138*5f39d1b3SJooyung Han ScopedProfilingLabel label(ResultBlockType::kOrder == MapOrder::ColMajor
139*5f39d1b3SJooyung Han ? "unpack to column-major"
140*5f39d1b3SJooyung Han : "unpack to row-major");
141*5f39d1b3SJooyung Han assert(dst_block.start_row >= 0);
142*5f39d1b3SJooyung Han assert(dst_block.start_row + dst_block.rows <= dst->rows());
143*5f39d1b3SJooyung Han assert(dst_block.start_col >= 0);
144*5f39d1b3SJooyung Han assert(dst_block.start_col + dst_block.cols <= dst->cols());
145*5f39d1b3SJooyung Han const auto src_map = src.Map();
146*5f39d1b3SJooyung Han const VectorMap<const std::int32_t, VectorShape::Col> lhs_sums_of_each_slice(
147*5f39d1b3SJooyung Han lhs_sums_of_each_slice_ptr, dst_block.rows);
148*5f39d1b3SJooyung Han const VectorMap<const std::int32_t, VectorShape::Row> rhs_sums_of_each_slice(
149*5f39d1b3SJooyung Han rhs_sums_of_each_slice_ptr, dst_block.cols);
150*5f39d1b3SJooyung Han using Int32x1x1 = RegisterBlock<std::int32_t, 1, 1>;
151*5f39d1b3SJooyung Han using Int32x4x1 = RegisterBlock<std::int32_t, 4, 1>;
152*5f39d1b3SJooyung Han using Int32x8x1 = RegisterBlock<std::int32_t, 8, 1>;
153*5f39d1b3SJooyung Han using Int32x1x4 = RegisterBlock<std::int32_t, 1, 4>;
154*5f39d1b3SJooyung Han using Int32x4x4 = RegisterBlock<std::int32_t, 4, 4>;
155*5f39d1b3SJooyung Han using Int32x8x4 = RegisterBlock<std::int32_t, 8, 4>;
156*5f39d1b3SJooyung Han
157*5f39d1b3SJooyung Han using DstScalarType = typename ResultBlockType::Scalar;
158*5f39d1b3SJooyung Han using DstScalarx8x8 = RegisterBlock<DstScalarType, 8, 8>;
159*5f39d1b3SJooyung Han
160*5f39d1b3SJooyung Han OutputPipelineExecutor<OutputPipelineType, Int32x1x1>
161*5f39d1b3SJooyung Han output_pipeline_executor_1x1(output_pipeline);
162*5f39d1b3SJooyung Han OutputPipelineExecutor<OutputPipelineType, Int32x4x1>
163*5f39d1b3SJooyung Han output_pipeline_executor_4x1(output_pipeline);
164*5f39d1b3SJooyung Han OutputPipelineExecutor<OutputPipelineType, Int32x8x1>
165*5f39d1b3SJooyung Han output_pipeline_executor_8x1(output_pipeline);
166*5f39d1b3SJooyung Han OutputPipelineExecutor<OutputPipelineType, Int32x1x4>
167*5f39d1b3SJooyung Han output_pipeline_executor_1x4(output_pipeline);
168*5f39d1b3SJooyung Han OutputPipelineExecutor<OutputPipelineType, Int32x4x4>
169*5f39d1b3SJooyung Han output_pipeline_executor_4x4(output_pipeline);
170*5f39d1b3SJooyung Han OutputPipelineExecutor<OutputPipelineType, Int32x8x4>
171*5f39d1b3SJooyung Han output_pipeline_executor_8x4(output_pipeline);
172*5f39d1b3SJooyung Han
173*5f39d1b3SJooyung Han int c8 = 0;
174*5f39d1b3SJooyung Han if (ResultBlockType::kOrder == MapOrder::RowMajor) {
175*5f39d1b3SJooyung Han for (; c8 <= dst_block.cols - 8; c8 += 8) {
176*5f39d1b3SJooyung Han PrefetchResultBlock<8, 8>(src_map, lhs_sums_of_each_slice, 0, c8);
177*5f39d1b3SJooyung Han int r = 0;
178*5f39d1b3SJooyung Han for (; r <= dst_block.rows - 8; r += 8) {
179*5f39d1b3SJooyung Han const int global_row = r + dst_block.start_row;
180*5f39d1b3SJooyung Han PrefetchResultBlock<8, 8>(src_map, lhs_sums_of_each_slice, r + 8, c8);
181*5f39d1b3SJooyung Han DstScalarType dst_colmajor_buf[64];
182*5f39d1b3SJooyung Han MatrixMap<DstScalarType, MapOrder::ColMajor> dst_colmajor_map(
183*5f39d1b3SJooyung Han dst_colmajor_buf, 8, 8);
184*5f39d1b3SJooyung Han for (int cx = 0; cx < 8; cx += 4) {
185*5f39d1b3SJooyung Han const int c = c8 + cx;
186*5f39d1b3SJooyung Han const int global_col = c + dst_block.start_col;
187*5f39d1b3SJooyung Han UnpackResultBlock<KernelFormat, Int32x8x4>(
188*5f39d1b3SJooyung Han src_map, output_pipeline_executor_8x4, &dst_colmajor_map,
189*5f39d1b3SJooyung Han lhs_sums_of_each_slice, rhs_sums_of_each_slice, lhs_offset,
190*5f39d1b3SJooyung Han rhs_offset, depth, r, c, global_row, global_col, 0, cx);
191*5f39d1b3SJooyung Han }
192*5f39d1b3SJooyung Han StoreFinalOutput(LoadContiguous<DstScalarx8x8>(dst_colmajor_buf), dst,
193*5f39d1b3SJooyung Han r + dst_block.start_row, c8 + dst_block.start_col);
194*5f39d1b3SJooyung Han }
195*5f39d1b3SJooyung Han for (; r <= dst_block.rows - 4; r += 4) {
196*5f39d1b3SJooyung Han const int global_row = r + dst_block.start_row;
197*5f39d1b3SJooyung Han for (int cx = 0; cx < 8; cx += 4) {
198*5f39d1b3SJooyung Han const int c = c8 + cx;
199*5f39d1b3SJooyung Han const int global_col = c + dst_block.start_col;
200*5f39d1b3SJooyung Han UnpackResultBlock<KernelFormat, Int32x4x4>(
201*5f39d1b3SJooyung Han src_map, output_pipeline_executor_4x4, dst,
202*5f39d1b3SJooyung Han lhs_sums_of_each_slice, rhs_sums_of_each_slice, lhs_offset,
203*5f39d1b3SJooyung Han rhs_offset, depth, r, c, global_row, global_col, global_row,
204*5f39d1b3SJooyung Han global_col);
205*5f39d1b3SJooyung Han }
206*5f39d1b3SJooyung Han }
207*5f39d1b3SJooyung Han for (; r < dst_block.rows; r++) {
208*5f39d1b3SJooyung Han const int global_row = r + dst_block.start_row;
209*5f39d1b3SJooyung Han for (int cx = 0; cx < 8; cx += 4) {
210*5f39d1b3SJooyung Han const int c = c8 + cx;
211*5f39d1b3SJooyung Han const int global_col = c + dst_block.start_col;
212*5f39d1b3SJooyung Han UnpackResultBlock<KernelFormat, Int32x1x4>(
213*5f39d1b3SJooyung Han src_map, output_pipeline_executor_1x4, dst,
214*5f39d1b3SJooyung Han lhs_sums_of_each_slice, rhs_sums_of_each_slice, lhs_offset,
215*5f39d1b3SJooyung Han rhs_offset, depth, r, c, global_row, global_col, global_row,
216*5f39d1b3SJooyung Han global_col);
217*5f39d1b3SJooyung Han }
218*5f39d1b3SJooyung Han }
219*5f39d1b3SJooyung Han }
220*5f39d1b3SJooyung Han }
221*5f39d1b3SJooyung Han int c = c8;
222*5f39d1b3SJooyung Han for (; c <= dst_block.cols - 4; c += 4) {
223*5f39d1b3SJooyung Han const int global_col = c + dst_block.start_col;
224*5f39d1b3SJooyung Han PrefetchResultBlock<8, 4>(src_map, lhs_sums_of_each_slice, 0, c);
225*5f39d1b3SJooyung Han int r = 0;
226*5f39d1b3SJooyung Han for (; r <= dst_block.rows - 8; r += 8) {
227*5f39d1b3SJooyung Han const int global_row = r + dst_block.start_row;
228*5f39d1b3SJooyung Han PrefetchResultBlock<8, 4>(src_map, lhs_sums_of_each_slice, r + 8, c);
229*5f39d1b3SJooyung Han UnpackResultBlock<KernelFormat, Int32x8x4>(
230*5f39d1b3SJooyung Han src_map, output_pipeline_executor_8x4, dst, lhs_sums_of_each_slice,
231*5f39d1b3SJooyung Han rhs_sums_of_each_slice, lhs_offset, rhs_offset, depth, r, c,
232*5f39d1b3SJooyung Han global_row, global_col, global_row, global_col);
233*5f39d1b3SJooyung Han }
234*5f39d1b3SJooyung Han for (; r <= dst_block.rows - 4; r += 4) {
235*5f39d1b3SJooyung Han const int global_row = r + dst_block.start_row;
236*5f39d1b3SJooyung Han UnpackResultBlock<KernelFormat, Int32x4x4>(
237*5f39d1b3SJooyung Han src_map, output_pipeline_executor_4x4, dst, lhs_sums_of_each_slice,
238*5f39d1b3SJooyung Han rhs_sums_of_each_slice, lhs_offset, rhs_offset, depth, r, c,
239*5f39d1b3SJooyung Han global_row, global_col, global_row, global_col);
240*5f39d1b3SJooyung Han }
241*5f39d1b3SJooyung Han for (; r < dst_block.rows; r++) {
242*5f39d1b3SJooyung Han const int global_row = r + dst_block.start_row;
243*5f39d1b3SJooyung Han UnpackResultBlock<KernelFormat, Int32x1x4>(
244*5f39d1b3SJooyung Han src_map, output_pipeline_executor_1x4, dst, lhs_sums_of_each_slice,
245*5f39d1b3SJooyung Han rhs_sums_of_each_slice, lhs_offset, rhs_offset, depth, r, c,
246*5f39d1b3SJooyung Han global_row, global_col, global_row, global_col);
247*5f39d1b3SJooyung Han }
248*5f39d1b3SJooyung Han }
249*5f39d1b3SJooyung Han for (; c < dst_block.cols; c++) {
250*5f39d1b3SJooyung Han const int global_col = c + dst_block.start_col;
251*5f39d1b3SJooyung Han PrefetchResultBlock<8, 1>(src_map, lhs_sums_of_each_slice, 0, c);
252*5f39d1b3SJooyung Han int r = 0;
253*5f39d1b3SJooyung Han for (; r <= dst_block.rows - 8; r += 8) {
254*5f39d1b3SJooyung Han const int global_row = r + dst_block.start_row;
255*5f39d1b3SJooyung Han PrefetchResultBlock<8, 1>(src_map, lhs_sums_of_each_slice, r + 8, c);
256*5f39d1b3SJooyung Han UnpackResultBlock<KernelFormat, Int32x8x1>(
257*5f39d1b3SJooyung Han src_map, output_pipeline_executor_8x1, dst, lhs_sums_of_each_slice,
258*5f39d1b3SJooyung Han rhs_sums_of_each_slice, lhs_offset, rhs_offset, depth, r, c,
259*5f39d1b3SJooyung Han global_row, global_col, global_row, global_col);
260*5f39d1b3SJooyung Han }
261*5f39d1b3SJooyung Han for (; r <= dst_block.rows - 4; r += 4) {
262*5f39d1b3SJooyung Han const int global_row = r + dst_block.start_row;
263*5f39d1b3SJooyung Han UnpackResultBlock<KernelFormat, Int32x4x1>(
264*5f39d1b3SJooyung Han src_map, output_pipeline_executor_4x1, dst, lhs_sums_of_each_slice,
265*5f39d1b3SJooyung Han rhs_sums_of_each_slice, lhs_offset, rhs_offset, depth, r, c,
266*5f39d1b3SJooyung Han global_row, global_col, global_row, global_col);
267*5f39d1b3SJooyung Han }
268*5f39d1b3SJooyung Han for (; r < dst_block.rows; r++) {
269*5f39d1b3SJooyung Han const int global_row = r + dst_block.start_row;
270*5f39d1b3SJooyung Han UnpackResultBlock<KernelFormat, Int32x1x1>(
271*5f39d1b3SJooyung Han src_map, output_pipeline_executor_1x1, dst, lhs_sums_of_each_slice,
272*5f39d1b3SJooyung Han rhs_sums_of_each_slice, lhs_offset, rhs_offset, depth, r, c,
273*5f39d1b3SJooyung Han global_row, global_col, global_row, global_col);
274*5f39d1b3SJooyung Han }
275*5f39d1b3SJooyung Han }
276*5f39d1b3SJooyung Han }
277*5f39d1b3SJooyung Han
278*5f39d1b3SJooyung Han } // end namespace gemmlowp
279*5f39d1b3SJooyung Han
280*5f39d1b3SJooyung Han #endif // GEMMLOWP_INTERNAL_UNPACK_H_
281