-
Notifications
You must be signed in to change notification settings - Fork 62
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for Torch's Conv1d strides and ConvTranspose1d (#145)
* Added Torch's ConvTranspose1d support and Torch's Conv1d and ConvTranspose1d stride support. * More tests for ConvTranspose1d * Trying to fix AVX tests * Strided convolution wrapper * Templated strided convolution wrapper with test * clang-format * Trying to fix alignment issues on different platforms * More test fixes * Comments and re-organizing --------- Co-authored-by: jatin <[email protected]>
- Loading branch information
1 parent
2ca066e
commit 32b8664
Showing
24 changed files
with
2,121 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,210 @@ | ||
#pragma once | ||
|
||
#include "conv1d.h" | ||
|
||
namespace RTNEURAL_NAMESPACE | ||
{ | ||
/** | ||
* Dynamic implementation of a 1-dimensional convolutional layer | ||
* with strides. | ||
* | ||
* Internally, this is just a wrapper around the Conv1D layer. | ||
*/ | ||
template <typename T> | ||
class StridedConv1D final : public Layer<T> | ||
{ | ||
public: | ||
/** | ||
* Constructs a strided convolution layer for the given dimensions. | ||
* | ||
* @param in_size: the input size for the layer | ||
* @param out_size: the output size for the layer | ||
* @param kernel_size: the size of the convolution kernel | ||
* @param dilation: the dilation rate to use for dilated convolution | ||
* @param stride: the stride of the convolution | ||
*/ | ||
StridedConv1D(int in_size, int out_size, int kernel_size, int dilation, int stride, int groups = 1) | ||
: Layer<T>(in_size, out_size) | ||
, internal(in_size, out_size, kernel_size, dilation, groups) | ||
, stride(stride) | ||
{ | ||
skip_output.resize(out_size, T {}); | ||
} | ||
|
||
StridedConv1D(std::initializer_list<int> sizes) | ||
: StridedConv1D<T>(*sizes.begin(), *(sizes.begin() + 1), *(sizes.begin() + 2), | ||
*(sizes.begin() + 3), *(sizes.begin() + 4), *(sizes.begin() + 5)) | ||
{ | ||
} | ||
|
||
StridedConv1D(const StridedConv1D& other) = default; | ||
StridedConv1D& operator=(const StridedConv1D& other) = default; | ||
|
||
/** Resets the layer state. */ | ||
RTNEURAL_REALTIME void reset() override | ||
{ | ||
strides_counter = 0; | ||
std::fill(std::begin(skip_output), std::end(skip_output), T {}); | ||
internal.reset(); | ||
} | ||
|
||
/** Returns the name of this layer. */ | ||
std::string getName() const noexcept override { return "strided_conv1d"; } | ||
|
||
/** Performs a stride step for this layer. */ | ||
RTNEURAL_REALTIME inline void skip(const T* input) | ||
{ | ||
internal.skip(input); | ||
} | ||
|
||
/** Performs forward propagation for this layer. */ | ||
RTNEURAL_REALTIME inline void forward(const T* input, T* h) noexcept override | ||
{ | ||
if(strides_counter == 0) | ||
{ | ||
internal.forward(input, h); | ||
std::copy(h, h + Layer<T>::out_size, std::begin(skip_output)); | ||
} | ||
else | ||
{ | ||
internal.skip(input); | ||
std::copy(std::begin(skip_output), std::end(skip_output), h); | ||
} | ||
|
||
strides_counter = (strides_counter == stride - 1) ? 0 : strides_counter + 1; | ||
} | ||
|
||
/** | ||
* Sets the layer weights. | ||
* | ||
* The weights vector must have size weights[out_size][in_size][kernel_size * dilation] | ||
*/ | ||
RTNEURAL_REALTIME void setWeights(const std::vector<std::vector<std::vector<T>>>& weights) | ||
{ | ||
internal.setWeights(weights); | ||
} | ||
|
||
/** | ||
* Sets the layer biases. | ||
* | ||
* The bias vector must have size bias[out_size] | ||
*/ | ||
RTNEURAL_REALTIME void setBias(const std::vector<T>& biasVals) | ||
{ | ||
internal.setBias(biasVals); | ||
} | ||
|
||
/** Returns the size of the convolution kernel. */ | ||
RTNEURAL_REALTIME int getKernelSize() const noexcept { return internal.getKernelSize(); } | ||
|
||
/** Returns the convolution dilation rate. */ | ||
RTNEURAL_REALTIME int getDilationRate() const noexcept { return internal.getDilationRate(); } | ||
|
||
/** Returns the number of "groups" in the convolution. */ | ||
int getGroups() const noexcept { return internal.getGroups(); } | ||
|
||
private: | ||
Conv1D<T> internal; | ||
|
||
const int stride; | ||
int strides_counter = 0; | ||
std::vector<T> skip_output {}; | ||
}; | ||
|
||
//==================================================== | ||
/** | ||
* Static implementation of a 1-dimensional convolution layer | ||
* with strides. | ||
* | ||
* Internally, this is just a wrapper around the Conv1DT layer. | ||
* | ||
* @param in_sizet: the input size for the layer | ||
* @param out_sizet: the output size for the layer | ||
* @param kernel_size: the size of the convolution kernel | ||
* @param dilation_rate: the dilation rate to use for dilated convolution | ||
* @param stride: the stride of the convolution | ||
* @param groups: controls connections between inputs and outputs | ||
* @param dynamic_state: use dynamically allocated layer state | ||
*/ | ||
template <typename T, int in_sizet, int out_sizet, int kernel_size, int dilation_rate, int stride, int groups = 1, bool dynamic_state = false> | ||
class StridedConv1DT | ||
{ | ||
Conv1DT<T, in_sizet, out_sizet, kernel_size, dilation_rate, groups, dynamic_state> internal; | ||
|
||
int strides_counter = 0; | ||
|
||
public: | ||
static constexpr auto in_size = in_sizet; | ||
static constexpr auto out_size = out_sizet; | ||
static constexpr auto filters_per_group = in_size / groups; | ||
static constexpr auto channels_per_group = out_size / groups; | ||
|
||
StridedConv1DT() | ||
: outs(internal.outs) | ||
{ | ||
} | ||
|
||
/** Returns the name of this layer. */ | ||
std::string getName() const noexcept { return "strided_conv1d"; } | ||
|
||
/** Returns false since convolution is not an activation layer. */ | ||
constexpr bool isActivation() const noexcept { return false; } | ||
|
||
/** Resets the layer state. */ | ||
RTNEURAL_REALTIME void reset() | ||
{ | ||
internal.reset(); | ||
} | ||
|
||
/** Performs a stride step for this layer. */ | ||
template <typename Inputs> | ||
RTNEURAL_REALTIME inline void skip(const Inputs& ins) noexcept | ||
{ | ||
internal.skip(ins); | ||
} | ||
|
||
/** Performs forward propagation for this layer. */ | ||
template <typename Inputs> | ||
RTNEURAL_REALTIME inline void forward(const Inputs& ins) noexcept | ||
{ | ||
if(strides_counter == 0) | ||
internal.forward(ins); | ||
else | ||
internal.skip(ins); | ||
|
||
strides_counter = (strides_counter == stride - 1) ? 0 : strides_counter + 1; | ||
} | ||
|
||
/** | ||
* Sets the layer weights. | ||
* | ||
* The weights vector must have size weights[out_size][group_count][kernel_size * dilation] | ||
*/ | ||
RTNEURAL_REALTIME void setWeights(const std::vector<std::vector<std::vector<T>>>& weights) | ||
{ | ||
internal.setWeights(weights); | ||
} | ||
|
||
/** | ||
* Sets the layer biases. | ||
* | ||
* The bias vector must have size bias[out_size] | ||
*/ | ||
RTNEURAL_REALTIME void setBias(const std::vector<T>& biasVals) | ||
{ | ||
internal.setBias(biasVals); | ||
} | ||
|
||
/** Returns the size of the convolution kernel. */ | ||
RTNEURAL_REALTIME int getKernelSize() const noexcept { return kernel_size; } | ||
|
||
/** Returns the convolution dilation rate. */ | ||
RTNEURAL_REALTIME int getDilationRate() const noexcept { return dilation_rate; } | ||
|
||
/** Returns the number of "groups" in the convolution. */ | ||
int getGroups() const noexcept { return groups; } | ||
|
||
/** Reference to the internal layer weights. */ | ||
decltype(internal.outs)& outs; | ||
}; | ||
} |
Oops, something went wrong.