Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions src/layer/vulkan/shader/softplus.comp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright 2026 Futz12 <pchar.cn>
// SPDX-License-Identifier: BSD-3-Clause

#version 450

layout(constant_id = 0) const uint n = 0;

layout(binding = 0) buffer bottom_top_blob { sfpvec4 bottom_top_blob_data[]; };

layout(push_constant) uniform parameter
{
uint n;
} p;

void main()
{
const uint gi = gl_GlobalInvocationID.x;

if (gi >= psc(n))
return;

afpvec4 v = buffer_ld4(bottom_top_blob_data, gi);

v = log(exp(v) + afpvec4(1.f));

buffer_st4(bottom_top_blob_data, gi, v);
}
84 changes: 84 additions & 0 deletions src/layer/vulkan/softplus_vulkan.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Copyright 2026 Futz12 <pchar.cn>
// SPDX-License-Identifier: BSD-3-Clause

#include "softplus_vulkan.h"

#include "layer_shader_type.h"

namespace ncnn {

Softplus_vulkan::Softplus_vulkan()
{
support_vulkan = true;
support_vulkan_packing = true;

pipeline_softplus = 0;
}

int Softplus_vulkan::create_pipeline(const Option& opt)
{
const Mat& shape = top_shapes.empty() ? Mat() : top_shapes[0];

const int dims = shape.dims;

int elempack = 0;
if (dims == 1) elempack = shape.w % 4 == 0 ? 4 : 1;
if (dims == 2) elempack = shape.h % 4 == 0 ? 4 : 1;
if (dims == 3 || dims == 4) elempack = shape.c % 4 == 0 ? 4 : 1;

size_t elemsize;
if (opt.use_fp16_storage || opt.use_fp16_packed)
{
elemsize = elempack * 2u;
}
else
{
elemsize = elempack * 4u;
}

Mat shape_packed;
if (dims == 1) shape_packed = Mat(shape.w / elempack, (void*)0, elemsize, elempack);
if (dims == 2) shape_packed = Mat(shape.w, shape.h / elempack, (void*)0, elemsize, elempack);
if (dims == 3) shape_packed = Mat(shape.w, shape.h, shape.c / elempack, (void*)0, elemsize, elempack);
if (dims == 4) shape_packed = Mat(shape.w, shape.h, shape.d, shape.c / elempack, (void*)0, elemsize, elempack);

std::vector<vk_specialization_type> specializations(1);
specializations[0].u32 = shape_packed.total() * elempack / 4;

const int local_size_x = vkdev->info.subgroup_size();

pipeline_softplus = new Pipeline(vkdev);
pipeline_softplus->set_optimal_local_size_xyz(local_size_x, 1, 1);
pipeline_softplus->create(LayerShaderType::softplus, opt, specializations);

return 0;
}

int Softplus_vulkan::destroy_pipeline(const Option& /*opt*/)
{
delete pipeline_softplus;
pipeline_softplus = 0;

return 0;
}

int Softplus_vulkan::forward_inplace(VkMat& bottom_top_blob, VkCompute& cmd, const Option& /*opt*/) const
{
const size_t n = bottom_top_blob.total() * bottom_top_blob.elempack / 4;

std::vector<VkMat> bindings(1);
bindings[0] = bottom_top_blob;

std::vector<vk_constant_type> constants(1);
constants[0].u32 = n;

VkMat dispatcher;
dispatcher.w = n;
dispatcher.h = 1;
dispatcher.c = 1;
cmd.record_pipeline(pipeline_softplus, bindings, constants, dispatcher);

return 0;
}

} // namespace ncnn
28 changes: 28 additions & 0 deletions src/layer/vulkan/softplus_vulkan.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright 2026 Futz12 <pchar.cn>
// SPDX-License-Identifier: BSD-3-Clause

#ifndef LAYER_SOFTPLUS_VULKAN_H
#define LAYER_SOFTPLUS_VULKAN_H

#include "softplus.h"

namespace ncnn {

class Softplus_vulkan : public Softplus
{
public:
Softplus_vulkan();

virtual int create_pipeline(const Option& opt);
virtual int destroy_pipeline(const Option& opt);

using Softplus::forward_inplace;
virtual int forward_inplace(VkMat& bottom_top_blob, VkCompute& cmd, const Option& opt) const;

public:
Pipeline* pipeline_softplus;
};

} // namespace ncnn

#endif // LAYER_SOFTPLUS_VULKAN_H
Loading