mirror of https://github.com/alibaba/MNN.git
101 lines
3.6 KiB
C++
101 lines
3.6 KiB
C++
//
|
|
// GLRelu.cpp
|
|
// MNN
|
|
//
|
|
// Created by MNN on 2019/01/31.
|
|
// Copyright © 2018, Alibaba Group Holding Limited
|
|
//
|
|
|
|
#include "backend/opengl/GLRelu.hpp"
|
|
#include <sstream>
|
|
#include "AllShader.hpp"
|
|
#include "backend/opengl/GLBackend.hpp"
|
|
#include "core/Macro.h"
|
|
#include "core/TensorUtils.hpp"
|
|
|
|
namespace MNN {
|
|
namespace OpenGL {
|
|
GLRelu::GLRelu(const std::vector<Tensor *> &inputs, const Op *op, Backend *bn) : Execution(bn) {
|
|
mType = op->type();
|
|
if(!(mType == OpType_PReLU)){
|
|
mSlope = op->main_as_Relu()->slope();
|
|
}else{
|
|
mOp = op;
|
|
}
|
|
}
|
|
|
|
GLRelu::~GLRelu() {
|
|
|
|
}
|
|
|
|
ErrorCode GLRelu::onResize(const std::vector<Tensor *> &inputs, const std::vector<Tensor *> &outputs) {
|
|
std::vector<std::string> prefix;
|
|
setLocalSize(prefix, mLocalSize, 8, 8, 1);
|
|
if (OpType_ReLU == mType) {
|
|
prefix.push_back("#define RELU");
|
|
mProgram = ((GLBackend *)backend())->getProgram("relu", glsl_relu_glsl, prefix);
|
|
}else if(OpType_ReLU6 == mType){
|
|
prefix.push_back("#define RELU6");
|
|
mProgram = ((GLBackend *)backend())->getProgram("relu", glsl_relu_glsl, prefix);
|
|
}else if(OpType_PReLU == mType){
|
|
int count = ALIGN_UP4(mOp->main_as_PRelu()->slope()->size());
|
|
mSlopeBuffer = std::shared_ptr<GLSSBOBuffer>(new GLSSBOBuffer(sizeof(float) * count));
|
|
float* slope = (float*)(mSlopeBuffer->map(GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT));
|
|
if(slope != nullptr){
|
|
::memset(slope, 0, count * sizeof(float));
|
|
::memcpy(slope, mOp->main_as_PRelu()->slope()->data(), mOp->main_as_PRelu()->slope()->size() * sizeof(float));
|
|
}
|
|
mSlopeBuffer->unmap();
|
|
mProgram = ((GLBackend *)backend())->getProgram("prelu", glsl_preluWithChannel_glsl, prefix);
|
|
}else{
|
|
MNN_PRINT("not support !!!");
|
|
return NOT_SUPPORT;
|
|
}
|
|
return NO_ERROR;
|
|
}
|
|
|
|
ErrorCode GLRelu::onExecute(const std::vector<Tensor *> &inputs, const std::vector<Tensor *> &outputs) {
|
|
auto input = inputs[0];
|
|
auto output = outputs[0];
|
|
int iw = input->width();
|
|
int ih = input->height();
|
|
int ic_4 = UP_DIV(input->channel(), 4);
|
|
int ib = input->batch();
|
|
|
|
if(OpType_PReLU == mType){
|
|
mProgram->useProgram();
|
|
glBindImageTexture(0, output->deviceId(), 0, GL_TRUE, 0, GL_WRITE_ONLY, ((GLBackend *)backend())->getTextrueFormat());
|
|
{
|
|
int texId = 0;
|
|
glActiveTexture(GL_TEXTURE0 + texId);
|
|
glUniform1i(1, texId);
|
|
glBindTexture(GL_TEXTURE_3D, input->deviceId());
|
|
OPENGL_CHECK_ERROR;
|
|
}
|
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, mSlopeBuffer->getId());
|
|
glUniform4i(3, iw, ih, ic_4, ib);
|
|
OPENGL_CHECK_ERROR;
|
|
((GLBackend *)backend())->compute(UP_DIV(iw, mLocalSize[0]), UP_DIV(ih, mLocalSize[1]), UP_DIV(ic_4, mLocalSize[2]));
|
|
}else{
|
|
mProgram->useProgram();
|
|
glBindImageTexture(0, output->deviceId(), 0, GL_TRUE, 0, GL_WRITE_ONLY, ((GLBackend *)backend())->getTextrueFormat());
|
|
{
|
|
int texId = 0;
|
|
glActiveTexture(GL_TEXTURE0 + texId);
|
|
glUniform1i(1, texId);
|
|
glBindTexture(GL_TEXTURE_3D, input->deviceId());
|
|
OPENGL_CHECK_ERROR;
|
|
}
|
|
glUniform4i(2, iw, ih, ic_4, ib);
|
|
glUniform1f(3, mSlope);
|
|
OPENGL_CHECK_ERROR;
|
|
((GLBackend *)backend())->compute(UP_DIV(iw, mLocalSize[0]), UP_DIV(ih, mLocalSize[1]), UP_DIV(ic_4, mLocalSize[2]));
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
GLCreatorRegister<TypedCreator<GLRelu>> __relu_op(OpType_ReLU);
|
|
GLCreatorRegister<TypedCreator<GLRelu>> __prelu_op(OpType_PReLU);
|
|
} // namespace OpenGL
|
|
} // namespace MNN
|