Tannic
A C++ Tensor Library
Loading...
Searching...
No Matches
convolutions.hpp
Go to the documentation of this file.
1// Copyright 2025 Eric Hermosis
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
16#ifndef CONVOLUTIONS_HPP
17#define CONVOLUTIONS_HPP
18
30#include <tuple>
31#include <array>
32#include <vector>
33#include <cassert>
34
35#include "concepts.hpp"
36#include "types.hpp"
37#include "traits.hpp"
38#include "shape.hpp"
39#include "tensor.hpp"
40#include "exceptions.hpp"
41#include "transformations.hpp"
42
43namespace tannic {
44
45class Tensor;
46
48
58public:
59 std::array<std::size_t, 1> strides;
60 std::array<std::size_t, 1> padding;
61
72 constexpr type promote(type signal, type kernel) const {
73 if (signal != kernel)
74 throw Exception("Dtypes must match in convolutions.");
75 return signal;
76 }
77
96 constexpr Shape transform(Shape const& signal, Shape const& kernel) const {
97 if (signal.rank() != 3 || kernel.rank() != 3)
98 throw Exception("Only rank 3 tensors supported for Conv1D.");
99
100 std::size_t N = signal[0]; // Batch size
101 std::size_t C_in = signal[1]; // Input channels
102 std::size_t L_in = signal[2]; // Input length
103
104 std::size_t C_out = kernel[0]; // Output channels
105 std::size_t K_in = kernel[1]; // Kernel input channels
106 std::size_t K_len = kernel[2]; // Kernel length
107
108 if (C_in != K_in)
109 throw Exception("Input channels must match kernel channels.");
110
111 std::size_t L_out = (L_in + 2 * padding[0] - K_len) / strides[0] + 1;
112 return Shape{N, C_out, L_out};
113 }
114
122 void forward(Tensor const& signal, Tensor const& kernel, Tensor& result) const;
123};
124
134public:
135 std::array<std::size_t, 2> strides;
136 std::array<std::size_t, 2> padding;
137
148 constexpr type promote(type signal, type kernel) const {
149 if (signal != kernel)
150 throw Exception("Dtypes must match in convolutions.");
151 return signal;
152 }
153
174 constexpr Shape transform(Shape const& signal, Shape const& kernel) const {
175 if (signal.rank() != 4 | kernel.rank() != 4)
176 throw Exception("Only rank 4 tensors supported.");
177
178 std::size_t N = signal[0]; // Batch size
179 std::size_t C_in = signal[1]; // Input channels
180 std::size_t H_in = signal[2]; // Input height
181 std::size_t W_in = signal[3]; // Input width
182
183 std::size_t C_out = kernel[0]; // Output channels
184 std::size_t K_in = kernel[1]; // Kernel input channels
185 std::size_t K_h = kernel[2]; // Kernel height
186 std::size_t K_w = kernel[3]; // Kernel width
187
188 if (C_in != K_in)
189 throw Exception("Input channels must match kernel channels.");
190
191 std::size_t H_out = (H_in + 2 * padding[0] - K_h) / strides[0] + 1;
192 std::size_t W_out = (W_in + 2 * padding[1] - K_w) / strides[1] + 1;
193
194 return Shape{N, C_out, H_out, W_out};
195 }
196
204 void forward(Tensor const& signal, Tensor const& kernel, Tensor& result) const;
205};
206
219template<Expression Signal, Expression Kernel>
220constexpr auto convolve1D(Signal&& signal, Kernel&& kernel, std::size_t stride, std::size_t padding) {
221 if (stride == 0)
222 throw Exception("Stride must be non-zero for Conv1D.");
223
225 {{stride}, {padding}},
226 std::forward<Signal>(signal),
227 std::forward<Kernel>(kernel)
228 );
229}
230
243template<Expression Signal, Expression Kernel>
244constexpr auto convolve1D(
245 Signal&& signal, Kernel&& kernel,
246 std::array<std::size_t, 1> strides,
247 std::array<std::size_t, 1> padding
248) {
249 if (strides[0] == 0)
250 throw Exception("Stride must be non-zero for Conv1D.");
251
253 {strides, padding},
254 std::forward<Signal>(signal),
255 std::forward<Kernel>(kernel)
256 );
257}
258
271template<Expression Signal, Expression Kernel>
272constexpr auto convolve2D(Signal&& signal, Kernel&& kernel, std::size_t stride, std::size_t padding) {
273 if (stride == 0)
274 throw Exception("Stride must be non-zero for Conv2D.");
275
277 {{stride, stride}, {padding, padding}},
278 std::forward<Signal>(signal),
279 std::forward<Kernel>(kernel)
280 );
281}
282
295template<Expression Signal, Expression Kernel>
296constexpr auto convolve2D(
297 Signal&& signal, Kernel&& kernel,
298 std::array<std::size_t, 2> strides,
299 std::array<std::size_t, 2> padding
300) {
301 if (strides[0] == 0 || strides[1] == 0)
302 throw Exception("Stride values must be non-zero for Conv2D.");
303
305 {strides, padding},
306 std::forward<Signal>(signal),
307 std::forward<Kernel>(kernel)
308 );
309}
310
311
312} namespace tannic {
313
316
317} // namespace tannic
318
319#endif // CONVOLUTIONS_HPP
A simple generic exception type for the Tannic Tensor Library.
Definition: exceptions.hpp:44
Represents the shape (dimensions) of an tensor-like expression.
Definition: shape.hpp:79
constexpr rank_type rank() const noexcept
Returns the number of dimensions (rank).
Definition: shape.hpp:207
A multidimensional, strided tensor data structure.
Definition: tensor.hpp:99
Expression for 1D convolution operations.
Definition: convolutions.hpp:57
constexpr Shape transform(Shape const &signal, Shape const &kernel) const
Computes output shape for 1D convolution.
Definition: convolutions.hpp:96
std::array< std::size_t, 1 > padding
Padding values for the convolution operation.
Definition: convolutions.hpp:60
std::array< std::size_t, 1 > strides
Stride values for the convolution operation.
Definition: convolutions.hpp:59
void forward(Tensor const &signal, Tensor const &kernel, Tensor &result) const
Performs the forward pass of 1D convolution.
constexpr type promote(type signal, type kernel) const
Type promotion for 1D convolution.
Definition: convolutions.hpp:72
Expression for 2D convolution operations.
Definition: convolutions.hpp:133
std::array< std::size_t, 2 > strides
Stride values for height and width dimensions.
Definition: convolutions.hpp:135
constexpr type promote(type signal, type kernel) const
Type promotion for 2D convolution.
Definition: convolutions.hpp:148
void forward(Tensor const &signal, Tensor const &kernel, Tensor &result) const
Performs the forward pass of 2D convolution.
constexpr Shape transform(Shape const &signal, Shape const &kernel) const
Computes output shape for 2D convolution.
Definition: convolutions.hpp:174
std::array< std::size_t, 2 > padding
Padding values for height and width dimensions.
Definition: convolutions.hpp:136
Expression template for tensor transformations.
Definition: transformations.hpp:58
Definition: convolutions.hpp:47
constexpr auto convolve2D(Signal &&signal, Kernel &&kernel, std::size_t stride, std::size_t padding)
Creates a 2D convolution expression with uniform stride and padding.
Definition: convolutions.hpp:272
constexpr auto convolve1D(Signal &&signal, Kernel &&kernel, std::size_t stride, std::size_t padding)
Creates a 1D convolution expression with uniform stride and padding.
Definition: convolutions.hpp:220
Definition: buffer.hpp:41