#include "BinaryPlugin.hpp" namespace MNN { template __global__ void ADD(const int n, const T* in0, const T* in1, T* out, int s0, int s1){ CUDA_KERNEL_LOOP(index, n) { out[index] = in0[index * s0] + in1[index * s1]; } } template __global__ void SUB(const int n, const T* in0, const T* in1, T* out, int s0, int s1){ CUDA_KERNEL_LOOP(index, n) { out[index] = in0[index * s0] - in1[index * s1]; } } template __global__ void MUL(const int n, const T* in0, const T* in1, T* out, int s0, int s1){ CUDA_KERNEL_LOOP(index, n) { out[index] = in0[index * s0] * in1[index * s1]; } } template __global__ void DIV(const int n, const T* in0, const T* in1, T* out, int s0, int s1){ CUDA_KERNEL_LOOP(index, n) { out[index] = in0[index * s0] / in1[index * s1]; } } template __global__ void SQD(const int n, const T* in0, const T* in1, T* out, int s0, int s1){ CUDA_KERNEL_LOOP(index, n) { T data = in0[index * s0] - in1[index * s1]; out[index] = data * data; } } template __global__ void MAXIMUM(const int n, const T* in0, const T* in1, T* out, int s0, int s1); template <> __global__ void MAXIMUM(const int n, const float* in0, const float* in1, float* out, int s0, int s1) { CUDA_KERNEL_LOOP(index, n) { out[index] = max(in0[index * s0], in1[index * s1]); } } template <> __global__ void MAXIMUM(const int n, const half* in0, const half* in1, half* out, int s0, int s1) { CUDA_KERNEL_LOOP(index, n) { float tmp = max(__half2float(in0[index * s0]) , __half2float(in1[index * s1])); out[index] = __float2half(tmp); } } template __global__ void MINIMUM(const int n, const T* in0, const T* in1, T* out, int s0, int s1); template <> __global__ void MINIMUM(const int n, const float* in0, const float* in1, float* out, int s0, int s1) { CUDA_KERNEL_LOOP(index, n) { out[index] = min(in0[index * s0], in1[index * s1]); } } template <> __global__ void MINIMUM(const int n, const half* in0, const half* in1, half* out, int s0, int s1) { CUDA_KERNEL_LOOP(index, n) { float tmp = min(__half2float(in0[index * s0]) , __half2float(in1[index * s1])); out[index] = __float2half(tmp); } } template __global__ void POW(const int n, const T* in0, const T* in1, T* out, int s0, int s1); template <> __global__ void POW(const int n, const float* in0, const float* in1, float* out, int s0, int s1) { CUDA_KERNEL_LOOP(index, n) { out[index] = pow(in0[index * s0], in1[index * s1]); } } template <> __global__ void POW(const int n, const half* in0, const half* in1, half* out, int s0, int s1) { CUDA_KERNEL_LOOP(index, n) { float tmp = pow(__half2float(in0[index * s0]), __half2float(in1[index * s1])); out[index] = __float2half(tmp); } } template cudaError_t binary_template(int type, const int count, const T* bottom_data0, const T* bottom_data1, T* top_data, int s0, int s1, cudaStream_t stream){ if (type == 0) { ADD<<>>(count, bottom_data0, bottom_data1, top_data, s0, s1); } else if (type == 1) { SUB<<>>(count, bottom_data0, bottom_data1, top_data, s0, s1); } else if (type == 2) { MUL<<>>(count, bottom_data0, bottom_data1, top_data, s0, s1); } else if (type == 6) { POW<<>>(count, bottom_data0, bottom_data1, top_data, s0, s1); } else if (type == 3 || type == 7) { DIV<<>>(count, bottom_data0, bottom_data1, top_data, s0, s1); } else if (type == 9) { MAXIMUM<<>>(count, bottom_data0, bottom_data1, top_data, s0, s1); } else if (type == 8) { MINIMUM<<>>(count, bottom_data0, bottom_data1, top_data, s0, s1); } else if (type == 14){ SQD<<>>(count, bottom_data0, bottom_data1, top_data, s0, s1); } else { printf("binary op not support:%d\n", type); } return cudaPeekAtLastError(); } cudaError_t BinaryPlugin::BinaryExecute(nvinfer1::DataType dataType, const int count, const void *const *inputs, void **outputs, int s0, int s1, cudaStream_t stream) { #ifdef TRT_LOG printf("in mType:%d\n", mType); #endif if (dataType == nvinfer1::DataType::kFLOAT){ return binary_template(mType, count, (const float*)inputs[0], (const float*)inputs[1], (float*)outputs[0], s0, s1, stream); }else{ return binary_template<__half>(mType, count, static_cast(inputs[0]), static_cast(inputs[1]), static_cast<__half*>(outputs[0]), s0, s1, stream); } } }; // namespace MNN