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
Add DCT 1D CPU kernel #1569
Add DCT 1D CPU kernel #1569
Conversation
Signed-off-by: Joaquin Anton <janton@nvidia.com>
Signed-off-by: Joaquin Anton <janton@nvidia.com>
Signed-off-by: Joaquin Anton <janton@nvidia.com>
Signed-off-by: Joaquin Anton <janton@nvidia.com>
Signed-off-by: Joaquin Anton <janton@nvidia.com>
bce6537
to
3952d38
Compare
!build |
CI MESSAGE: [1032164]: BUILD STARTED |
CI MESSAGE: [1032164]: BUILD PASSED |
* @brief DCT kernel arguments | ||
*/ | ||
struct DctArgs { | ||
/// @brief DCT type. Supported types are 1, 2, 3, 4 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What this value maps to?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't map to anything. See:
https://en.wikipedia.org/wiki/Discrete_cosine_transform#Formal_definition
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this reference should be put here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's in the operator documentation, but ok, I'll add it here as well
make_string("Axis is out of bounds: ", args.axis)); | ||
int64_t n = in.shape[args.axis]; | ||
|
||
if (args.dct_type == 1) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have that check repeated in FillCosineTableTypeI
. Do we need to have that in two places?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's ok - this is a public API, so we throw - in FillCosineTable we assert (it should not be reachable with such parameter, regardless of what external caller does)..
|
||
template <typename T> | ||
void ReferenceDctTypeI(span<T> out, span<const T> in, bool normalize) { | ||
int64_t in_length = in.size(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we put similar assert as in the implementation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will do
dali/kernels/signal/dct/dct_cpu.cc
Outdated
for (int64_t k = 0; k < ndct; k++) { | ||
T norm_factor = (k == 0) ? factor_k_0 : factor_k_i; | ||
for (int64_t n = 0; n < input_length; n++) { | ||
table[idx++] = norm_factor * std::cos(phase_mul * (n + T(0.5)) * k); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it's a one-off calculation, then the code below give more precision:
table[idx++] = norm_factor * std::cos(phase_mul * (n + T(0.5)) * k); | |
table[idx++] = T(norm_factor * std::cos(phase_mul * (n + 0.5) * k); |
dali/kernels/signal/dct/dct_cpu.cc
Outdated
|
||
template <typename T> | ||
void FillCosineTableTypeII(T *table, int64_t input_length, int64_t ndct, bool normalize) { | ||
T phase_mul = M_PI / input_length; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
T phase_mul = M_PI / input_length; | |
double phase_mul = M_PI / input_length; |
dali/kernels/signal/dct/dct_cpu.cc
Outdated
T factor_k_0 = 1, factor_k_i = 1; | ||
if (normalize) { | ||
factor_k_i = std::sqrt(2 / T(input_length)); | ||
factor_k_0 = factor_k_i / std::sqrt(T(2)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't it just:
factor_k_0 = factor_k_i / std::sqrt(T(2)); | |
factor_k_0 = std::sqrt(input_length); |
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1 / std::sqrt(input_length)
actually. Changed it
dali/kernels/signal/dct/dct_cpu.cc
Outdated
void FillCosineTableTypeI(T *table, int64_t input_length, int64_t ndct, bool normalize) { | ||
assert(input_length > 1); | ||
assert(!normalize); | ||
T phase_mul = M_PI / (input_length - 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
T phase_mul = M_PI / (input_length - 1); | |
double phase_mul = M_PI / (input_length - 1); |
dali/kernels/signal/dct/dct_cpu.cc
Outdated
T phase_mul = M_PI / input_length; | ||
T factor_n_0 = 0.5, factor_n_i = 1; | ||
if (normalize) { | ||
factor_n_i = std::sqrt(T(2) / input_length); | ||
factor_n_0 = factor_n_i / std::sqrt(T(2)); | ||
} | ||
int64_t idx = 0; | ||
for (int64_t k = 0; k < ndct; k++) { | ||
table[idx++] = factor_n_0; // n = 0 | ||
for (int64_t n = 1; n < input_length; n++) { | ||
table[idx++] = factor_n_i * std::cos(phase_mul * n * (k + T(0.5))); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As above.
dali/kernels/signal/dct/dct_cpu.cc
Outdated
T phase_mul = M_PI / input_length; | ||
T factor = normalize ? std::sqrt(T(2)/input_length) : T(1); | ||
int64_t idx = 0; | ||
for (int64_t k = 0; k < ndct; k++) { | ||
for (int64_t n = 0; n < input_length; n++) { | ||
table[idx++] = factor * std::cos(phase_mul * (n + T(0.5)) * (k + T(0.5))); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...and again.
Signed-off-by: Joaquin Anton <janton@nvidia.com>
!build |
CI MESSAGE: [1038528]: BUILD STARTED |
CI MESSAGE: [1038528]: BUILD PASSED |
Why we need this PR?
What happened in this PR?
Created a DCT 1D CPU kernel implementation. The kernel takes an arbitrarily sized tensor and performs a DCT transformation over the selected axis.
Dct1DCpu kernel, tests
The kernel implementation
Unit tests
Doxygen
JIRA TASK: [DALI-1185]