/*******************************************************************************
* Copyright 2020 Intel Corporation
*
* 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.
*******************************************************************************/
#include "gpu/intel/include/dispatch.h"
#include "gpu/intel/include/eltwise.h"
#include "gpu/intel/include/types.h"
#if IS_FWD
__kernel void ref_prelu_fwd(const __global SRC_DATA_T *src,
const __global WEI_DATA_T *weights, __global DST_DATA_T *dst) {
const off_t d0 = GWS_GET_D0() const off_t d1 = GWS_GET_D1() const off_t d2 = GWS_GET_D2() const off_t d3 = GWS_GET_D3() const off_t d4 = GWS_GET_D4() const off_t d5 = GWS_GET_D5()
const off_t data_off = OFF_MD(SRC, d0, d1, d2, d3, d4, d5) const off_t wei_off = OFF_MD(WEI, d0 % WEI_D0, d1 % WEI_D1, d2 % WEI_D2,
d3 % WEI_D3, d4 % WEI_D4, d5 % WEI_D5)
const float src_data = SRC_TO_REF(src[data_off])
const float wei_data = WEI_TO_REF(weights[wei_off])
const float res_data = relu_fwd(src_data, wei_data)
dst[data_off] = TO_DST(res_data)}
#else // #if IS_FWD
__kernel void ref_prelu_bwd(const __global SRC_DATA_T *src,
const __global WEI_DATA_T *weights, const __global DST_DATA_T *diff_dst,
__global DIFF_SRC_DATA_T *diff_src,
__global DIFF_WEI_DATA_T *diff_weights) {
const off_t d0 = GWS_GET_D0() const off_t d1 = GWS_GET_D1() const off_t d2 = GWS_GET_D2() const off_t d3 = GWS_GET_D3() const off_t d4 = GWS_GET_D4() const off_t d5 = GWS_GET_D5()
const off_t data_off = OFF_MD(SRC, d0 % SRC_D0, d1 % SRC_D1, d2 % SRC_D2,
d3 % SRC_D3, d4 % SRC_D4, d5 % SRC_D5) const off_t data_off_pd = OFF_MD(SRC, d0 % SRC_PD0, d1 % SRC_PD1,
d2 % SRC_PD2, d3 % SRC_PD3, d4 % SRC_PD4, d5 % SRC_PD5) const off_t wei_off = OFF_MD(WEI, d0 % WEI_D0, d1 % WEI_D1, d2 % WEI_D2,
d3 % WEI_D3, d4 % WEI_D4, d5 % WEI_D5)
const float src_data = SRC_TO_REF(src[data_off]) const float diff_dst_data = DST_TO_REF(diff_dst[data_off]) const float wei_data = WEI_TO_REF(weights[wei_off])
float diff_src_data
= src_data > 0 ? diff_dst_data : diff_dst_data * wei_data if (data_off != data_off_pd) diff_src_data = 0.f
#define COORDINATES_ARE_IN_RANGE(mem_prefix) \
({ \
bool is_in_range = d0 < CONCAT2(mem_prefix, _PD0) \
&& d1 < CONCAT2(mem_prefix, _PD1) \
&& d2 < CONCAT2(mem_prefix, _PD2) \
&& d3 < CONCAT2(mem_prefix, _PD3) \
&& d4 < CONCAT2(mem_prefix, _PD4) \
&& d5 < CONCAT2(mem_prefix, _PD5) is_in_range })
if (COORDINATES_ARE_IN_RANGE(SRC))
diff_src[data_off_pd] = TO_SRC(diff_src_data) if (!COORDINATES_ARE_IN_RANGE(DIFF_WEI)) return
const off_t diff_wei_off = OFF_MD(DIFF_WEI, d0 % DIFF_WEI_D0,
d1 % DIFF_WEI_D1, d2 % DIFF_WEI_D2, d3 % DIFF_WEI_D3,
d4 % DIFF_WEI_D4, d5 % DIFF_WEI_D5) const off_t diff_wei_off_pd = OFF_MD(DIFF_WEI, d0 % DIFF_WEI_PD0,
d1 % DIFF_WEI_PD1, d2 % DIFF_WEI_PD2, d3 % DIFF_WEI_PD3,
d4 % DIFF_WEI_PD4, d5 % DIFF_WEI_PD5)
float diff_wei_data = src_data > 0 ? 0 : diff_dst_data * src_data if (diff_wei_off != diff_wei_off_pd) diff_wei_data = 0.f
#if DIFF_WEI_DT_F32
diff_weights[diff_wei_off_pd] = diff_wei_data#else // #if DIFF_WEI_DT_F32
diff_weights[diff_wei_off_pd] = TO_DIFF_WEI(diff_wei_data)#endif // #else // #if DIFF_WEI_DT_F32
}
#endif // #else // #if IS_FWD