Skip to content

Commit

Permalink
deconv1d dynamic weight
Browse files Browse the repository at this point in the history
  • Loading branch information
nihui committed Oct 31, 2023
1 parent d19508b commit 3498208
Show file tree
Hide file tree
Showing 7 changed files with 400 additions and 7 deletions.
4 changes: 4 additions & 0 deletions docs/developer-guide/operators.md
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,7 @@ y = activation(x3, act_type, act_params)
| 19 | output_pad_bottom| int | output_pad_right | |
| 20 | output_w | int | 0 | |
| 21 | output_h | int | output_w | |
| 28 | dynamic_weight| int | 0 | |

| weight | type | shape |
| ------------- | ----- | --------------------- |
Expand Down Expand Up @@ -558,6 +559,7 @@ y = activation(x3, act_type, act_params)
| 15 | pad_right | int | pad_left | |
| 18 | output_pad_right| int | 0 | |
| 20 | output_w | int | 0 | |
| 28 | dynamic_weight| int | 0 | |

| weight | type | shape |
| ------------- | ----- | --------------------- |
Expand Down Expand Up @@ -638,6 +640,7 @@ y = activation(x3, act_type, act_params)
| 19 | output_pad_bottom| int | output_pad_right | |
| 20 | output_w | int | 0 | |
| 21 | output_h | int | output_w | |
| 28 | dynamic_weight| int | 0 | |

| weight | type | shape |
| ------------- | ----- | --------------------- |
Expand Down Expand Up @@ -668,6 +671,7 @@ y = activation(x3, act_type, act_params)
| 15 | pad_right | int | pad_left | |
| 18 | output_pad_right| int | 0 | |
| 20 | output_w | int | 0 | |
| 28 | dynamic_weight| int | 0 | |

| weight | type | shape |
| ------------- | ----- | --------------------- |
Expand Down
93 changes: 93 additions & 0 deletions src/layer/deconvolution1d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,21 @@ int Deconvolution1D::load_param(const ParamDict& pd)
activation_type = pd.get(9, 0);
activation_params = pd.get(10, Mat());

dynamic_weight = pd.get(28, 0);

if (dynamic_weight)
{
one_blob_only = false;
}

return 0;
}

int Deconvolution1D::load_model(const ModelBin& mb)
{
if (dynamic_weight)
return 0;

weight_data = mb.load(weight_data_size, 0);
if (weight_data.empty())
return -100;
Expand Down Expand Up @@ -143,6 +153,89 @@ int Deconvolution1D::forward(const Mat& bottom_blob, Mat& top_blob, const Option
return 0;
}

int Deconvolution1D::forward(const std::vector<Mat>& bottom_blobs, std::vector<Mat>& top_blobs, const Option& opt) const
{
const Mat& bottom_blob = bottom_blobs[0];
const Mat& _weight_data = bottom_blobs[1];
Mat& top_blob = top_blobs[0];

const int _num_input = bottom_blob.h;
const int _kernel_w = _weight_data.w;
const int _num_output = _weight_data.h * 1;

Mat weight_data_flattened;
flatten(_weight_data, weight_data_flattened, opt);
if (weight_data_flattened.empty())
return -100;

// transpose group-inch/group-outch/group-kw to group-outch/group-inch/group-kw
Mat weight_data_transposed;
{
weight_data_transposed.create(_kernel_w * _num_output * _num_input / 1, 4u, opt.workspace_allocator);
if (weight_data_transposed.empty())
return -100;

const int outch_g = _num_output / 1;
const int inch_g = _num_input / 1;
const int maxk = _kernel_w;

for (int g = 0; g < 1; g++)
{
// reorder weight from inch-outch to outch-inch
float* wg2 = (float*)weight_data_transposed + g * outch_g * inch_g * maxk;
const float* wg = (const float*)weight_data_flattened + g * inch_g * outch_g * maxk;
for (int i = 0; i < outch_g; i++)
{
for (int j = 0; j < inch_g; j++)
{
for (int k = 0; k < maxk; k++)
{
wg2[(i * inch_g + j) * maxk + k] = wg[(j * outch_g + i) * maxk + k];
}
}
}
}
}

Mat bias_data_flattened;
if (bias_term)
{
const Mat& _bias_data = bottom_blobs[2];
flatten(_bias_data, bias_data_flattened, opt);
if (bias_data_flattened.empty())
return -100;
}

const int w = bottom_blob.w;

const int kernel_extent_w = dilation_w * (_kernel_w - 1) + 1;

int outw = (w - 1) * stride_w + kernel_extent_w + output_pad_right;

Mat top_blob_bordered;
if (pad_left > 0 || pad_right > 0 || output_w > 0)
{
top_blob_bordered.create(outw, _num_output, 4u, opt.workspace_allocator);
}
else
{
top_blob_bordered = top_blob;
top_blob_bordered.create(outw, _num_output, 4u, opt.blob_allocator);
}
if (top_blob_bordered.empty())
return -100;

int ret = deconvolution1d(bottom_blob, top_blob_bordered, weight_data_transposed, bias_data_flattened, _kernel_w, stride_w, dilation_w, activation_type, activation_params, opt);
if (ret != 0)
return ret;

cut_padding(top_blob_bordered, top_blob, opt);
if (top_blob.empty())
return -100;

return 0;
}

void Deconvolution1D::cut_padding(const Mat& top_blob_bordered, Mat& top_blob, const Option& opt) const
{
if (pad_left > 0 || pad_right > 0)
Expand Down
4 changes: 4 additions & 0 deletions src/layer/deconvolution1d.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ class Deconvolution1D : public Layer

virtual int forward(const Mat& bottom_blob, Mat& top_blob, const Option& opt) const;

virtual int forward(const std::vector<Mat>& bottom_blobs, std::vector<Mat>& top_blobs, const Option& opt) const;

protected:
void cut_padding(const Mat& top_blob_bordered, Mat& top_blob, const Option& opt) const;

Expand All @@ -50,6 +52,8 @@ class Deconvolution1D : public Layer
int activation_type;
Mat activation_params;

int dynamic_weight;

// model
Mat weight_data;
Mat bias_data;
Expand Down
93 changes: 93 additions & 0 deletions src/layer/deconvolutiondepthwise1d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,21 @@ int DeconvolutionDepthWise1D::load_param(const ParamDict& pd)
activation_type = pd.get(9, 0);
activation_params = pd.get(10, Mat());

dynamic_weight = pd.get(28, 0);

if (dynamic_weight)
{
one_blob_only = false;
}

return 0;
}

int DeconvolutionDepthWise1D::load_model(const ModelBin& mb)
{
if (dynamic_weight)
return 0;

weight_data = mb.load(weight_data_size, 0);
if (weight_data.empty())
return -100;
Expand Down Expand Up @@ -195,6 +205,89 @@ int DeconvolutionDepthWise1D::forward(const Mat& bottom_blob, Mat& top_blob, con
return 0;
}

int DeconvolutionDepthWise1D::forward(const std::vector<Mat>& bottom_blobs, std::vector<Mat>& top_blobs, const Option& opt) const
{
const Mat& bottom_blob = bottom_blobs[0];
const Mat& _weight_data = bottom_blobs[1];
Mat& top_blob = top_blobs[0];

const int _num_input = bottom_blob.h;
const int _kernel_w = _weight_data.w;
const int _num_output = _weight_data.h * group;

Mat weight_data_flattened;
flatten(_weight_data, weight_data_flattened, opt);
if (weight_data_flattened.empty())
return -100;

// transpose group-inch/group-outch/group-kw to group-outch/group-inch/group-kw
Mat weight_data_transposed;
{
weight_data_transposed.create(_kernel_w * _num_output * _num_input / group, 4u, opt.workspace_allocator);
if (weight_data_transposed.empty())
return -100;

const int outch_g = _num_output / group;
const int inch_g = _num_input / group;
const int maxk = _kernel_w;

for (int g = 0; g < group; g++)
{
// reorder weight from inch-outch to outch-inch
float* wg2 = (float*)weight_data_transposed + g * outch_g * inch_g * maxk;
const float* wg = (const float*)weight_data_flattened + g * inch_g * outch_g * maxk;
for (int i = 0; i < outch_g; i++)
{
for (int j = 0; j < inch_g; j++)
{
for (int k = 0; k < maxk; k++)
{
wg2[(i * inch_g + j) * maxk + k] = wg[(j * outch_g + i) * maxk + k];
}
}
}
}
}

Mat bias_data_flattened;
if (bias_term)
{
const Mat& _bias_data = bottom_blobs[2];
flatten(_bias_data, bias_data_flattened, opt);
if (bias_data_flattened.empty())
return -100;
}

const int w = bottom_blob.w;

const int kernel_extent_w = dilation_w * (_kernel_w - 1) + 1;

int outw = (w - 1) * stride_w + kernel_extent_w + output_pad_right;

Mat top_blob_bordered;
if (pad_left > 0 || pad_right > 0 || output_w > 0)
{
top_blob_bordered.create(outw, _num_output, 4u, opt.workspace_allocator);
}
else
{
top_blob_bordered = top_blob;
top_blob_bordered.create(outw, _num_output, 4u, opt.blob_allocator);
}
if (top_blob_bordered.empty())
return -100;

int ret = deconvolutiondepthwise1d(bottom_blob, top_blob_bordered, weight_data_transposed, bias_data_flattened, _kernel_w, stride_w, dilation_w, group, activation_type, activation_params, opt);
if (ret != 0)
return ret;

cut_padding(top_blob_bordered, top_blob, opt);
if (top_blob.empty())
return -100;

return 0;
}

void DeconvolutionDepthWise1D::cut_padding(const Mat& top_blob_bordered, Mat& top_blob, const Option& opt) const
{
if (pad_left > 0 || pad_right > 0)
Expand Down
4 changes: 4 additions & 0 deletions src/layer/deconvolutiondepthwise1d.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ class DeconvolutionDepthWise1D : public Layer

virtual int forward(const Mat& bottom_blob, Mat& top_blob, const Option& opt) const;

virtual int forward(const std::vector<Mat>& bottom_blobs, std::vector<Mat>& top_blobs, const Option& opt) const;

protected:
void cut_padding(const Mat& top_blob_bordered, Mat& top_blob, const Option& opt) const;

Expand All @@ -51,6 +53,8 @@ class DeconvolutionDepthWise1D : public Layer
int activation_type;
Mat activation_params;

int dynamic_weight;

// model
Mat weight_data;
Mat bias_data;
Expand Down
Loading

0 comments on commit 3498208

Please sign in to comment.