| 17 | }; |
| 18 | |
| 19 | VulkanLayernorm::VulkanLayernorm(const Op* op, Backend* backend, Tensor * tensor) : VulkanBasicExecution(backend) { |
| 20 | auto layer_norm_param = op->main_as_LayerNorm(); |
| 21 | auto vkbackend = static_cast<VulkanBackend*>(backend); |
| 22 | if (nullptr != layer_norm_param->axis()) { |
| 23 | mAxisSize = layer_norm_param->axis()->size(); |
| 24 | } |
| 25 | mGroup = layer_norm_param->group(); |
| 26 | mUseRMSNorm = layer_norm_param->useRMSNorm(); |
| 27 | |
| 28 | mParam = vkbackend->allocUniform(); |
| 29 | mEps = layer_norm_param->epsilon(); |
| 30 | |
| 31 | mFP16 = tensor->getType().code == halide_type_float && vkbackend->useFP16(); |
| 32 | |
| 33 | if (layer_norm_param->gamma() && layer_norm_param->beta()) { |
| 34 | mHasScale = true; |
| 35 | int size = layer_norm_param->gamma()->size(); |
| 36 | auto prepareParam = [&](std::shared_ptr<Tensor>& paramTensor, const float* sourceData, const char* errorName) { |
| 37 | paramTensor.reset(Tensor::createDevice<float>({size})); |
| 38 | auto status = backend->onAcquireBuffer(paramTensor.get(), Backend::STATIC); |
| 39 | if (!status) { |
| 40 | MNN_ERROR("Out of memory when %s is acquired in LayerNorm.\n", errorName); |
| 41 | return false; |
| 42 | } |
| 43 | const void * paramData; |
| 44 | std::vector<int16_t> paramFP16; |
| 45 | if (mFP16) { |
| 46 | paramFP16.resize(size); |
| 47 | FLOAT_TO_HALF(sourceData, paramFP16.data(), size); |
| 48 | paramData = paramFP16.data(); |
| 49 | } else { |
| 50 | paramData = (const void *) sourceData; |
| 51 | } |
| 52 | auto paramBuffer = vkbackend->getBuffer(paramTensor.get()); |
| 53 | vkbackend->copyToGPUBuffer(paramData, std::get<0>(paramBuffer), std::get<1>(paramBuffer), std::get<2>(paramBuffer)); |
| 54 | return true; |
| 55 | }; |
| 56 | |
| 57 | if (!prepareParam(mGamma, layer_norm_param->gamma()->data(), "gamma")) { |
| 58 | return; |
| 59 | } |
| 60 | |
| 61 | if (layer_norm_param->beta()->size() != size) { |
| 62 | MNN_ERROR("Size of gamma and beta are not match in LayerNorm.\n"); |
| 63 | return; |
| 64 | } |
| 65 | |
| 66 | if (!prepareParam(mBias, layer_norm_param->beta()->data(), "beta")) { |
| 67 | return; |
| 68 | } |
| 69 | } |
| 70 | |
| 71 | mKey = "glsl_norm_"; |
| 72 | if (!mHasScale) { |
| 73 | mDesTypes = { |
| 74 | VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, |
| 75 | VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, |
| 76 | VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, |
nothing calls this directly
no test coverage detected