1*4bdc9457SAndroid Build Coastguard Worker// Copyright 2022 Google LLC 2*4bdc9457SAndroid Build Coastguard Worker// 3*4bdc9457SAndroid Build Coastguard Worker// This source code is licensed under the BSD-style license found in the 4*4bdc9457SAndroid Build Coastguard Worker// LICENSE file in the root directory of this source tree. 5*4bdc9457SAndroid Build Coastguard Worker 6*4bdc9457SAndroid Build Coastguard Worker$assert BATCH_TILE >= 1 7*4bdc9457SAndroid Build Coastguard Worker#include <assert.h> 8*4bdc9457SAndroid Build Coastguard Worker#include <stddef.h> 9*4bdc9457SAndroid Build Coastguard Worker#include <stdint.h> 10*4bdc9457SAndroid Build Coastguard Worker 11*4bdc9457SAndroid Build Coastguard Worker#include <xnnpack/math.h> 12*4bdc9457SAndroid Build Coastguard Worker#include <xnnpack/window.h> 13*4bdc9457SAndroid Build Coastguard Worker 14*4bdc9457SAndroid Build Coastguard Worker 15*4bdc9457SAndroid Build Coastguard Workervoid xnn_s16_window_ukernel__scalar_x${BATCH_TILE}( 16*4bdc9457SAndroid Build Coastguard Worker size_t rows, 17*4bdc9457SAndroid Build Coastguard Worker size_t batch_size, 18*4bdc9457SAndroid Build Coastguard Worker const int16_t* input, 19*4bdc9457SAndroid Build Coastguard Worker const int16_t* weights, 20*4bdc9457SAndroid Build Coastguard Worker int16_t* output, 21*4bdc9457SAndroid Build Coastguard Worker uint32_t shift) 22*4bdc9457SAndroid Build Coastguard Worker{ 23*4bdc9457SAndroid Build Coastguard Worker assert(rows > 0); 24*4bdc9457SAndroid Build Coastguard Worker assert(batch_size != 0); 25*4bdc9457SAndroid Build Coastguard Worker assert(input != NULL); 26*4bdc9457SAndroid Build Coastguard Worker assert(weights != NULL); 27*4bdc9457SAndroid Build Coastguard Worker assert(output != NULL); 28*4bdc9457SAndroid Build Coastguard Worker assert(shift < 32); 29*4bdc9457SAndroid Build Coastguard Worker 30*4bdc9457SAndroid Build Coastguard Worker do { 31*4bdc9457SAndroid Build Coastguard Worker size_t n = batch_size; 32*4bdc9457SAndroid Build Coastguard Worker const int16_t* w = weights; 33*4bdc9457SAndroid Build Coastguard Worker $if BATCH_TILE > 1: 34*4bdc9457SAndroid Build Coastguard Worker for (; n >= ${BATCH_TILE}; n -= ${BATCH_TILE}) { 35*4bdc9457SAndroid Build Coastguard Worker $for N in range(BATCH_TILE): 36*4bdc9457SAndroid Build Coastguard Worker const int16_t vi${N} = input[${N}]; 37*4bdc9457SAndroid Build Coastguard Worker input += ${BATCH_TILE}; 38*4bdc9457SAndroid Build Coastguard Worker 39*4bdc9457SAndroid Build Coastguard Worker $for N in range(BATCH_TILE): 40*4bdc9457SAndroid Build Coastguard Worker const int16_t w${N} = w[${N}]; 41*4bdc9457SAndroid Build Coastguard Worker w += ${BATCH_TILE}; 42*4bdc9457SAndroid Build Coastguard Worker 43*4bdc9457SAndroid Build Coastguard Worker $for N in range(BATCH_TILE): 44*4bdc9457SAndroid Build Coastguard Worker int32_t vout${N} = (int32_t) vi${N} * (int32_t) w${N}; 45*4bdc9457SAndroid Build Coastguard Worker 46*4bdc9457SAndroid Build Coastguard Worker $for N in range(BATCH_TILE): 47*4bdc9457SAndroid Build Coastguard Worker vout${N} = math_asr_s32(vout${N}, shift); 48*4bdc9457SAndroid Build Coastguard Worker 49*4bdc9457SAndroid Build Coastguard Worker $for N in range(BATCH_TILE): 50*4bdc9457SAndroid Build Coastguard Worker vout${N} = math_max_s32(vout${N}, INT16_MIN); 51*4bdc9457SAndroid Build Coastguard Worker 52*4bdc9457SAndroid Build Coastguard Worker $for N in range(BATCH_TILE): 53*4bdc9457SAndroid Build Coastguard Worker vout${N} = math_min_s32(vout${N}, INT16_MAX); 54*4bdc9457SAndroid Build Coastguard Worker 55*4bdc9457SAndroid Build Coastguard Worker $for N in range(BATCH_TILE): 56*4bdc9457SAndroid Build Coastguard Worker output[${N}] = (int16_t) vout${N}; 57*4bdc9457SAndroid Build Coastguard Worker 58*4bdc9457SAndroid Build Coastguard Worker output += ${BATCH_TILE}; 59*4bdc9457SAndroid Build Coastguard Worker } 60*4bdc9457SAndroid Build Coastguard Worker 61*4bdc9457SAndroid Build Coastguard Worker if XNN_UNLIKELY(n != 0) { 62*4bdc9457SAndroid Build Coastguard Worker do { 63*4bdc9457SAndroid Build Coastguard Worker const int32_t vi = (int32_t) *input++; 64*4bdc9457SAndroid Build Coastguard Worker const int32_t vw = (int32_t) *w++; 65*4bdc9457SAndroid Build Coastguard Worker int32_t vout = vi * vw; 66*4bdc9457SAndroid Build Coastguard Worker vout = math_asr_s32(vout, shift); 67*4bdc9457SAndroid Build Coastguard Worker vout = math_max_s32(vout, INT16_MIN); 68*4bdc9457SAndroid Build Coastguard Worker vout = math_min_s32(vout, INT16_MAX); 69*4bdc9457SAndroid Build Coastguard Worker *output++ = (int16_t) vout; 70*4bdc9457SAndroid Build Coastguard Worker } while (--n != 0); 71*4bdc9457SAndroid Build Coastguard Worker } 72*4bdc9457SAndroid Build Coastguard Worker } while (--rows != 0); 73*4bdc9457SAndroid Build Coastguard Worker} 74