ESP-IDF Firmware
Firmware architecture and call graph
Loading...
Searching...
No Matches
dspi_conv_f32_ansi.c
Go to the documentation of this file.
1// Copyright 2024 Espressif Systems (Shanghai) PTE LTD
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "dspi_conv.h"
16#include "esp_log.h"
17
18esp_err_t dspi_conv_f32_ansi(const image2d_t *in_image, const image2d_t *filter, image2d_t *out_image)
19{
20 out_image->size_x = in_image->size_x;
21 out_image->size_y = in_image->size_y;
22 float *i_data = (float *)in_image->data;
23 float *out_data = (float *)out_image->data;
24
25 int rest_x = (filter->size_x - 1) >> 1;
26 int rest_y = (filter->size_y - 1) >> 1;
27
28 int i_pos = 0;
29 int i_step = in_image->stride_x * in_image->step_y;
30 int f_step = filter->stride_x * filter->step_y;
31
32 // Up side of image
33 for (int y = 0 ; y < rest_y; y++ ) {
34 int i_pos_y = i_pos;
35 for (int x = 0 ; x < rest_x; x++) {
36 int i_pos_x = i_pos_y;
37 float acc = 0;
38 float *f_data = (float *)filter->data;
39 for (int m = rest_y - y ; m < filter->size_y ; m++) {
40 for (int n = rest_x - x ; n < filter->size_x ; n++) {
41 acc += i_data[i_pos_x + n * in_image->step_x] * f_data[filter->step_x * n];
42 }
43 f_data += f_step;
44 i_pos_x += i_step;
45 }
46 i_pos_y += in_image->step_x;
47 out_data[x * out_image->step_x + y * out_image->stride_x * out_image->step_y] = acc;
48 }
49 for (int x = rest_x ; x < in_image->size_x - filter->size_x / 2; x++) {
50 int i_pos_x = i_pos_y;
51 float acc = 0;
52 float *f_data = (float *)filter->data;
53 for (int m = rest_y - y ; m < filter->size_y ; m++) {
54 for (int n = 0 ; n < filter->size_x ; n++) {
55 acc += i_data[i_pos_x + n * in_image->step_x] * f_data[filter->step_x * n];
56 }
57 f_data += f_step;
58 i_pos_x += i_step;
59 }
60 i_pos_y += in_image->step_x;
61 out_data[x * out_image->step_x + y * out_image->stride_x * out_image->step_y] = acc;
62 }
63 for (int x = in_image->size_x - filter->size_x / 2 - 1; x < in_image->size_x; x++) {
64 int i_pos_x = i_pos_y;
65 float acc = 0;
66 float *f_data = (float *)filter->data;
67 for (int m = rest_y - y ; m < filter->size_y ; m++) {
68 for (int n = 0 ; n < filter->size_x - (x - in_image->size_x + filter->size_x / 2 + 1); n++) {
69 acc += i_data[i_pos_x + n * in_image->step_x] * f_data[filter->step_x * n];
70 }
71 f_data += f_step;
72 i_pos_x += i_step;
73 }
74 i_pos_y += in_image->step_x;
75 out_data[x * out_image->step_x + y * out_image->stride_x * out_image->step_y] = acc;
76 }
77 i_pos += in_image->stride_x * in_image->step_y;
78 }
79 // Middle side of image
80 i_pos = 0;
81 for (int y = rest_y ; y < in_image->size_y - filter->size_y / 2; y++ ) {
82 int i_pos_y = i_pos;
83 for (int x = 0 ; x < rest_x; x++) {
84 int i_pos_x = i_pos_y;
85 float acc = 0;
86 float *f_data = (float *)filter->data;
87 for (int m = 0 ; m < filter->size_y ; m++) {
88 for (int n = rest_x - x ; n < filter->size_x ; n++) {
89 acc += i_data[i_pos_x + n * in_image->step_x] * f_data[filter->step_x * n];
90 }
91 f_data += f_step;
92 i_pos_x += i_step;
93 }
94 i_pos_y += in_image->step_x;
95 out_data[x * out_image->step_x + y * out_image->stride_x * out_image->step_y] = acc;
96 }
97 for (int x = in_image->size_x - filter->size_x / 2 - 1; x < in_image->size_x; x++) {
98 int i_pos_x = i_pos_y;
99 float acc = 0;
100 float *f_data = (float *)filter->data;
101 for (int m = 0 ; m < filter->size_y ; m++) {
102 for (int n = 0 ; n < filter->size_x - (x - in_image->size_x + filter->size_x / 2 + 1); n++) {
103 acc += i_data[i_pos_x + n * in_image->step_x] * f_data[filter->step_x * n];
104 }
105 f_data += f_step;
106 i_pos_x += i_step;
107 }
108 i_pos_y += in_image->step_x;
109 out_data[x * out_image->step_x + y * out_image->stride_x * out_image->step_y] = acc;
110 }
111
112 i_pos += in_image->stride_x * in_image->step_y;
113 }
114 // Down side of image
115 i_pos = 0;
116 for (int y = in_image->size_y - filter->size_y / 2 ; y < in_image->size_y; y++ ) {
117 int i_pos_y = i_pos;
118 for (int x = 0 ; x < rest_x; x++) {
119 int i_pos_x = i_pos_y;
120 float acc = 0;
121 float *f_data = (float *)filter->data;
122 for (int m = 0 ; m < filter->size_y - (y - in_image->size_y + filter->size_y / 2 + 1); m++) {
123 for (int n = rest_x - x ; n < filter->size_x ; n++) {
124 acc += i_data[i_pos_x + n * in_image->step_x] * f_data[filter->step_x * n];
125 }
126 f_data += f_step;
127 i_pos_x += i_step;
128 }
129 i_pos_y += in_image->step_x;
130 out_data[x * out_image->step_x + y * out_image->stride_x * out_image->step_y] = acc;
131 }
132 for (int x = rest_x ; x < in_image->size_x - filter->size_x / 2; x++) {
133 int i_pos_x = i_pos_y;
134 float acc = 0;
135 float *f_data = (float *)filter->data;
136 for (int m = 0 ; m < filter->size_y - (y - in_image->size_y + filter->size_y / 2 + 1); m++) {
137 for (int n = 0 ; n < filter->size_x ; n++) {
138 acc += i_data[i_pos_x + n * in_image->step_x] * f_data[filter->step_x * n];
139 }
140 f_data += f_step;
141 i_pos_x += i_step;
142 }
143 i_pos_y += in_image->step_x;
144 out_data[x * out_image->step_x + y * out_image->stride_x * out_image->step_y] = acc;
145 }
146 for (int x = in_image->size_x - filter->size_x / 2 ; x < in_image->size_x; x++) {
147 int i_pos_x = i_pos_y;
148 float acc = 0;
149 float *f_data = (float *)filter->data;
150 for (int m = 0 ; m < filter->size_y - (y - in_image->size_y + filter->size_y / 2 + 1); m++) {
151 for (int n = 0 ; n < filter->size_x - (x - in_image->size_x + filter->size_x / 2 + 1); n++) {
152 acc += i_data[i_pos_x + n * in_image->step_x] * f_data[filter->step_x * n];
153 }
154 f_data += f_step;
155 i_pos_x += i_step;
156 }
157 i_pos_y += in_image->step_x;
158 out_data[x * out_image->step_x + y * out_image->stride_x * out_image->step_y] = acc;
159 }
160
161 i_pos += in_image->stride_x * in_image->step_y;
162 }
163 // Main image block
164 i_pos = 0;
165 for (int y = rest_y ; y < in_image->size_y - filter->size_y / 2; y++ ) {
166 int i_pos_y = i_pos;
167 for (int x = rest_x ; x < in_image->size_x - filter->size_x / 2; x++) {
168 int i_pos_x = i_pos_y;
169 float acc = 0;
170 float *f_data = (float *)filter->data;
171 for (int m = 0 ; m < filter->size_y ; m++) {
172 for (int n = 0 ; n < filter->size_x ; n++) {
173 acc += i_data[i_pos_x + n * in_image->step_x] * f_data[filter->step_x * n];
174 }
175 f_data += f_step;
176 i_pos_x += i_step;
177 }
178 i_pos_y += in_image->step_x;
179 out_data[x * out_image->step_x + y * out_image->stride_x * out_image->step_y] = acc;
180 }
181 i_pos += in_image->stride_x * in_image->step_y;
182 }
183 return ESP_OK;
184}
struct image2d_s image2d_t
esp_err_t dspi_conv_f32_ansi(const image2d_t *in_image, const image2d_t *filter, image2d_t *out_image)
2D Convolution
int esp_err_t
Definition esp_err.h:21
#define ESP_OK
Definition esp_err.h:23
int stride_x
Definition dsp_types.h:28
int size_x
Definition dsp_types.h:32
void * data
Definition dsp_types.h:25
int step_y
Definition dsp_types.h:27
int step_x
Definition dsp_types.h:26
int size_y
Definition dsp_types.h:33
float y[1024]
Definition test_fir.c:11
float x[1024]
Definition test_fir.c:10
const int m
Definition test_mmult.c:16
const int n
Definition test_mmult.c:17