mirror of https://github.com/alibaba/MNN.git
				
				
				
			
		
			
				
	
	
		
			127 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			127 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C++
		
	
	
	
| //
 | |
| //  VulkanNormalize.cpp
 | |
| //  MNN
 | |
| //
 | |
| //  Created by MNN on 2019/01/31.
 | |
| //  Copyright © 2018, Alibaba Group Holding Limited
 | |
| //
 | |
| 
 | |
| #include "VulkanNormalize.hpp"
 | |
| #include "Macro.h"
 | |
| #include "TensorUtils.hpp"
 | |
| 
 | |
| namespace MNN {
 | |
| struct GpuParam {
 | |
|     ivec4 imgSize;
 | |
|     int channelDiv4;
 | |
|     float eps;
 | |
| };
 | |
| 
 | |
| VulkanNormalize::VulkanNormalize(const Op* op, Backend* bn) : VulkanBasicExecution(bn) {
 | |
|     auto normalizeParam = op->main_as_Normalize();
 | |
|     mEps                = normalizeParam->eps();
 | |
| 
 | |
|     std::vector<VkDescriptorType> VulkanNormalizeTypes{
 | |
|         VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
 | |
|         VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
 | |
|         VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
 | |
|     };
 | |
| 
 | |
|     std::vector<VkDescriptorType> VulkanScaleTypes{
 | |
|         VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
 | |
|         VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER};
 | |
| 
 | |
|     mVkBackend = static_cast<VulkanBackend*>(bn);
 | |
|     mSampler   = mVkBackend->getCommonSampler();
 | |
|     // normalize
 | |
|     mVulkanNormalizePipeline =
 | |
|         mVkBackend->getPipeline("glsl_normalizeChannel_comp",
 | |
|                                 /*glsl_normalizeChannel_comp, glsl_normalizeChannel_comp_len,*/ VulkanNormalizeTypes);
 | |
|     mParamBuffer.reset(new VulkanBuffer(mVkBackend->getMemoryPool(), false, sizeof(GpuParam), nullptr,
 | |
|                                         VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT));
 | |
|     MNN_ASSERT(normalizeParam->channelShared() == false);
 | |
|     // scale
 | |
|     mVulkanScalePipeline =
 | |
|         mVkBackend->getPipeline("glsl_scale_comp", /*glsl_scale_comp, glsl_scale_comp_len,*/ VulkanScaleTypes);
 | |
| 
 | |
|     mScale.reset(new VulkanBuffer(mVkBackend->getMemoryPool(), false, sizeof(float) * normalizeParam->scale()->size(),
 | |
|                                   normalizeParam->scale()->data(), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT));
 | |
|     mBias.reset(new VulkanBuffer(mVkBackend->getMemoryPool(), false, sizeof(float) * normalizeParam->scale()->size(),
 | |
|                                  nullptr, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT));
 | |
|     auto biasPtr = reinterpret_cast<float*>(mBias->map());
 | |
|     ::memset(biasPtr, 0, sizeof(float) * normalizeParam->scale()->size());
 | |
|     mBias->unmap();
 | |
| }
 | |
| VulkanNormalize::~VulkanNormalize() {
 | |
| }
 | |
| ErrorCode VulkanNormalize::onEncode(const std::vector<Tensor*>& inputs, const std::vector<Tensor*>& outputs,
 | |
|                                     const VulkanCommandPool::Buffer* cmdBuffer) {
 | |
|     auto input            = inputs[0];
 | |
|     auto output           = outputs[0];
 | |
|     const int channelDiv4 = UP_DIV(input->channel(), 4);
 | |
| 
 | |
|     TensorUtils::copyShape(input, &mTempTensor, true);
 | |
|     MNN_ASSERT(TensorUtils::getDescribe(input)->dimensionFormat == MNN_DATA_FORMAT_NC4HW4);
 | |
|     backend()->onAcquireBuffer(&mTempTensor, Backend::DYNAMIC);
 | |
|     backend()->onReleaseBuffer(&mTempTensor, Backend::DYNAMIC);
 | |
| 
 | |
|     auto tempTensorImage = mVkBackend->findTensor(mTempTensor.deviceId())->image();
 | |
|     MNN_ASSERT(nullptr != tempTensorImage);
 | |
|     auto VulkanNormalizeParam = reinterpret_cast<GpuParam*>(mParamBuffer->map());
 | |
|     ::memset(VulkanNormalizeParam, 0, sizeof(GpuParam));
 | |
| 
 | |
|     VulkanNormalizeParam->imgSize[0]  = input->width();
 | |
|     VulkanNormalizeParam->imgSize[1]  = input->height();
 | |
|     VulkanNormalizeParam->imgSize[2]  = channelDiv4;
 | |
|     VulkanNormalizeParam->imgSize[3]  = 0;
 | |
|     VulkanNormalizeParam->channelDiv4 = channelDiv4;
 | |
|     VulkanNormalizeParam->eps         = mEps;
 | |
| 
 | |
|     mParamBuffer->flush(true, 0, sizeof(GpuParam));
 | |
|     mParamBuffer->unmap();
 | |
| 
 | |
|     // normalize
 | |
|     mNormalizeDescriptorSet.reset(mVulkanNormalizePipeline->createSet());
 | |
|     mNormalizeDescriptorSet->writeImage(reinterpret_cast<VkImageView>(mTempTensor.deviceId()), mSampler->get(),
 | |
|                                         VK_IMAGE_LAYOUT_GENERAL, 0);
 | |
|     mNormalizeDescriptorSet->writeImage(reinterpret_cast<VkImageView>(input->deviceId()), mSampler->get(),
 | |
|                                         VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 1);
 | |
|     mNormalizeDescriptorSet->writeBuffer(mParamBuffer->buffer(), 2, mParamBuffer->size());
 | |
| 
 | |
|     mVulkanNormalizePipeline->bind(cmdBuffer->get(), mNormalizeDescriptorSet->get());
 | |
| 
 | |
|     vkCmdDispatch(cmdBuffer->get(), UP_DIV(input->width(), 8), UP_DIV(input->height(), 8), input->batch());
 | |
| 
 | |
|     // scale
 | |
|     mScaleDescriptorSet.reset(mVulkanScalePipeline->createSet());
 | |
|     mScaleDescriptorSet->writeImage(reinterpret_cast<VkImageView>(output->deviceId()), mSampler->get(),
 | |
|                                     VK_IMAGE_LAYOUT_GENERAL, 0);
 | |
|     mScaleDescriptorSet->writeImage(reinterpret_cast<VkImageView>(mTempTensor.deviceId()), mSampler->get(),
 | |
|                                     VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 1);
 | |
|     mScaleDescriptorSet->writeBuffer(mScale->buffer(), 2, mScale->size());
 | |
|     mScaleDescriptorSet->writeBuffer(mBias->buffer(), 3, mBias->size());
 | |
|     mScaleDescriptorSet->writeBuffer(mParamBuffer->buffer(), 4, mParamBuffer->size());
 | |
|     mVulkanScalePipeline->bind(cmdBuffer->get(), mScaleDescriptorSet->get());
 | |
| 
 | |
|     cmdBuffer->barrierImage(tempTensorImage->get(), VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
 | |
| 
 | |
|     vkCmdDispatch(cmdBuffer->get(), UP_DIV(input->width(), 16), UP_DIV(input->height(), 16),
 | |
|                   channelDiv4 * input->batch());
 | |
| 
 | |
|     return NO_ERROR;
 | |
| }
 | |
| 
 | |
| class VulkanNormalizeCreator : public VulkanBackend::Creator {
 | |
| public:
 | |
|     virtual Execution* onCreate(const std::vector<Tensor*>& inputs, const MNN::Op* op, Backend* bn) const override {
 | |
|         return new VulkanNormalize(op, bn);
 | |
|     }
 | |
| };
 | |
| 
 | |
| static bool gResistor = []() {
 | |
|     VulkanBackend::addCreator(OpType_Normalize, new VulkanNormalizeCreator);
 | |
|     return true;
 | |
| }();
 | |
| 
 | |
| } // namespace MNN
 |