-
Notifications
You must be signed in to change notification settings - Fork 461
Add general transpose for vivado/vitis #1124
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
d6957bd
add general transpose for vivado/vitis
calad0i cf72985
add test
calad0i 3fc6fd4
Merge branch 'main' into general_transpose
jmitrevs 49fd6d8
add docstring
calad0i bbc316e
purge 3d stream xpose ward in ch_last converter pass
calad0i File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 hidden or 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 hidden or 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 was deleted.
Oops, something went wrong.
This file contains hidden or 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 hidden or 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,39 @@ | ||
#ifndef NNET_PERMUTE_H_ | ||
#define NNET_PERMUTE_H_ | ||
|
||
namespace nnet { | ||
|
||
struct transpose_config { | ||
static const unsigned dims; | ||
static const unsigned N; | ||
// vivado/vitis hls can't index constexpr array for some reason | ||
// and vivado hls don't like template recursion either (vitis is fine) | ||
// thus this appears to be the only workaround (or overkill it with codegen) | ||
static const unsigned *const from_shape; | ||
static const unsigned *const to_shape; | ||
static const unsigned *const perm; | ||
static const unsigned *const perm_strides; | ||
}; | ||
|
||
template <typename CONFIG_T> unsigned transfer_idx(int index) { | ||
// Given output idx in c-order flat array, return input idx | ||
int idx = 0; | ||
for (int i = CONFIG_T::dims - 1; i >= 0; i--) { | ||
idx += (index % CONFIG_T::to_shape[i]) * CONFIG_T::perm_strides[i]; | ||
index /= CONFIG_T::to_shape[i]; | ||
} | ||
return idx; | ||
} | ||
|
||
template <typename data_T, typename res_T, typename CONFIG_T> | ||
void transpose(const data_T data[CONFIG_T::N], res_T res[CONFIG_T::N]) { | ||
for (int i = 0; i < CONFIG_T::N; i++) { | ||
#pragma HLS UNROLL | ||
int idx = transfer_idx<CONFIG_T>(i); | ||
res[i] = data[idx]; | ||
} | ||
} | ||
|
||
} // namespace nnet | ||
|
||
#endif |
67 changes: 67 additions & 0 deletions
67
hls4ml/templates/vivado/nnet_utils/nnet_transpose_stream.h
This file contains hidden or 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,67 @@ | ||
#ifndef NNET_TRANSPOSE_STREAM_H | ||
#define NNET_TRANSPOSE_STREAM_H | ||
|
||
#include "hls_stream.h" | ||
#include "nnet_transpose.h" | ||
#include <type_traits> | ||
|
||
namespace nnet { | ||
|
||
template <typename data_T, typename res_T, typename CONFIG_T> | ||
typename std::enable_if<CONFIG_T::dims == 2, void>::type transpose(hls::stream<data_T> &data, hls::stream<res_T> &res) { | ||
// #pragma HLS INLINE RECURSIVE | ||
typename data_T::value_type data_array[CONFIG_T::N]; | ||
#pragma HLS ARRAY_PARTITION variable=data_array complete | ||
|
||
for (int i = 0; i < CONFIG_T::N / data_T::size; i++) { | ||
#pragma HLS PIPELINE | ||
data_T in_data = data.read(); | ||
for (int j = 0; j < data_T::size; j++) { | ||
#pragma HLS UNROLL | ||
data_array[i * data_T::size + j] = typename data_T::value_type(in_data[j]); | ||
} | ||
} | ||
|
||
for (int i = 0; i < CONFIG_T::N / res_T::size; i++) { | ||
#pragma HLS PIPELINE | ||
res_T out_data; | ||
PRAGMA_DATA_PACK(out_data) | ||
for (int j = 0; j < res_T::size; j++) { | ||
#pragma HLS UNROLL | ||
out_data[j] = typename res_T::value_type(data_array[j * CONFIG_T::from_shape[1] + i]); | ||
} | ||
res.write(out_data); | ||
} | ||
} | ||
|
||
// This sfinae is for vivado_hls, which has some overhead using the transfer_idx in io_stream. | ||
// In vitis both performs exactly the same, thus this is not removed out of convenience. | ||
template <typename data_T, typename res_T, typename CONFIG_T> | ||
typename std::enable_if<CONFIG_T::dims != 2, void>::type transpose(hls::stream<data_T> &data, hls::stream<res_T> &res) { | ||
// #pragma HLS INLINE RECURSIVE | ||
typename data_T::value_type data_array[CONFIG_T::N]; | ||
#pragma HLS ARRAY_PARTITION variable=data_array complete | ||
|
||
for (int i = 0; i < CONFIG_T::N / data_T::size; i++) { | ||
#pragma HLS PIPELINE | ||
data_T in_data = data.read(); | ||
for (int j = 0; j < data_T::size; j++) { | ||
#pragma HLS UNROLL | ||
data_array[i * data_T::size + j] = typename data_T::value_type(in_data[j]); | ||
} | ||
} | ||
|
||
for (int i = 0; i < CONFIG_T::N / res_T::size; i++) { | ||
#pragma HLS PIPELINE | ||
res_T out_data; | ||
PRAGMA_DATA_PACK(out_data) | ||
for (int j = 0; j < res_T::size; j++) { | ||
#pragma HLS UNROLL | ||
out_data[j] = typename res_T::value_type(data_array[transfer_idx<CONFIG_T>(i * res_T::size + j)]); | ||
} | ||
res.write(out_data); | ||
} | ||
} | ||
|
||
} // namespace nnet | ||
#endif |
This file contains hidden or 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
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.