Uh oh!
There was an error while loading. Please reload this page.
ARROW-12744: [C++][Compute] Add rounding kernel - #10349
Conversation
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
6a6e01e to
49f232bCompareedponce
commented
Jun 25, 2021
@bkietz@jorisvandenbossche Need feedback on this PR. Specifically, the rounding options provided and kernel implementations. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
402ab23 to
0240f37Compareedponce
commented
Jul 21, 2021
There are 2 round functions ( For tests, I wanted to use the Also, I could not find a way to create the generator dispatchers without explicitly using the @lidavidm@bkietz Any comments or suggestions would be gladly appreciated. |
e7f5d07 to
bf4d80dCompareUh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
lidavidm
commented
Jul 21, 2021
There seem to be some Windows-specific test failures :/ |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
d58bc48 to
8c3943cCompare
lidavidm
left a comment
There was a problem hiding this comment.
Thanks, this looks good to me. I left two small comments.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
7ef8e65 to
dfe6de2CompareUh oh!
There was an error while loading. Please reload this page.
pitrou
commented
Sep 7, 2021
Should you undraft it or is it still WIP? |
edponce
commented
Sep 7, 2021
It is basically complete and undrafted. There are a few minor comments I made w.r.t. to doubts that I have. |
14d6244 to
3e82fd0Compare
pitrou
left a comment
There was a problem hiding this comment.
Nice! A bunch of comments below.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
3e82fd0 to
14382ffCompareUh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
14382ff to
dd001b9Compareedponce
commented
Sep 9, 2021
Ready for review cc @pitrou |
rok
commented
Sep 9, 2021
Looks great! |
edponce
commented
Sep 9, 2021
@rok It is a possibility, if we have the semantics pinned down w.r.t. how to shift specific timestamps (forward, backward, delta). This would be a new set of compute functions: "round_time" and "round_time_to_multiple", where the latter could be a quaternary/varargs function to support multiples for hour, min, sec, ms/ns. |
rok
commented
Sep 9, 2021
Indeed that would probably need some work. Does this currently support arbitrary rounding to multiple on timestamps? If yes it might be good to limit it to timezoneless and UTC timestamps to avoid ambiguous and nonexistent timestamp issues. |
lidavidm
left a comment
There was a problem hiding this comment.
Looks fine to me. One minor comment.
There was a problem hiding this comment.
Should this just return OptionsWrapper::Init like below?
There was a problem hiding this comment.
No, it is RoundOptionsWrapper so that its constructor is invoked via make_unique, which initializes pow10 data member. If we use OptionsWrapper then pow10 is not available. I tried invoking OptionsWrapper::Init but it returns a std::unique_ptr which would require "casting" to RoundOptionsWrapper first and then to KernelState to match return type. The unique_ptr casting caused too many issues so I reverted to mimic the OptionsWrapper::Init method.
There was a problem hiding this comment.
The way I used these OptionsWrapper classes:
- considers
Initfor options validation becauseInitcan return aStatus::Invalid - constructor for initializing non-options state, which can then be accessed in kernels'
Callviactx->state()
There was a problem hiding this comment.
I templetized Init method of KernelState derived classes so that derived constructors can be invoked without the need to duplicate the Init definition. This makes KernelState be fully functional to support options validation and extending kernel state via constructor which can most likely benefit other scalar kernels as well.
For example by extending, OptionsWrapper as follows:
template <typename OptionsType>
structOptionsWrapper : publicKernelState {
template <typename KernelStateType = OptionsWrapper>
static Result<std::unique_ptr<KernelState>> Init(KernelContext* ctx, const KernelInitArgs& args) {
if (auto options = static_cast<const OptionsType*>(args.options)) {
return ::arrow::internal::make_unique<KernelStateType>(*options);
}
...
}
...
};now we can extend custom states as follows:
structRoundOptionsWrapper<RoundOptions> : public OptionsWrapper<RoundOptions> {
using OptionsType = RoundOptions;
using State = RoundOptionsWrapper<OptionsType>;
double pow10;
explicitRoundOptionsWrapper(OptionsType options) : OptionsWrapper(std::move(options)) {
pow10 = RoundUtil::Pow10(std::abs(options.ndigits));
}
static Result<std::unique_ptr<KernelState>> Init(KernelContext* ctx, const KernelInitArgs& args) {
return OptionsWrapper<OptionsType>::Init<State>(ctx, args);
}
};There was a problem hiding this comment.
Ok, I tried the template variant of OptionsWrapper and although it made the code cleaner, it failed to compiled for some systems, so reverted to duplicating the OptionsWrapper::Init definition. I think there needs to be a refactoring of KernelState and related parts to support validating kernel options and extending kernel state in a simpler manner. There are different patterns being used in the code to fulfill these. But this is a separate issue from this PR.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Just for the record, it feels a bit weird to call GenerateArithmeticRound at kernel execution time. That said, a quick benchmarking in Python shows there doesn't seem to be any large overhead:
>>>importpyarrowaspa, pyarrow.computeaspc>>>floor=pc.get_function("floor")
>>>round=pc.get_function("round")
>>>arr=pa.array([None], type=pa.float64())
>>>%timeitfloor.call([arr])
2.57µs ± 10.2nsperloop (mean ± std. dev. of7runs, 100000loopseach)
>>>%timeitfloor.call([arr])
2.58µs ± 11.3nsperloop (mean ± std. dev. of7runs, 100000loopseach)
>>>%timeitround.call([arr])
2.65µs ± 10.6nsperloop (mean ± std. dev. of7runs, 100000loopseach)
>>>%timeitround.call([arr])
2.53µs ± 12.5nsperloop (mean ± std. dev. of7runs, 100000loopseach)There was a problem hiding this comment.
I agree. The purpose of doing this here is to generate dispatchers once prior to kernel invocation. Previously, I tried 2 solutions:
- Have a vector of precompute
GenerateArithmeticFloatingPointand use theoptions.round_modeto index this vector. But this required vector to be ordered identically to the round modes inenum RoundMode. - Similar to above but using an
unordered_mapindexed byoptions.round_mode. This requires adding hash support forRoundModedata type. This approach does not imposes a full constraint on the ordering ofRoundMode.
Which one do you think is best?
There was a problem hiding this comment.
Actually, it is doing the same thing as the other kernels. Other kernels pass exec (an ArrayKernelExec) to the AddKernel method without invoking it. exec is invoked during kernel dispatching because it requires KernelContext, ExecBatch, and Datum parameters.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
edponce
commented
Sep 9, 2021
@rok This PR only supports rounding for basic arithmetic data types (unsigned/signed int and floating-point). |
lidavidm
commented
Sep 9, 2021
@edponce looks like you need to rebase again here as well. |
d6b909d to
65cb707Compareedponce
commented
Sep 10, 2021
0496356 to
302c5f1Compareedponce
commented
Sep 10, 2021
Are there any additional comments/reviews? cc @pitrou@bkietz@jorisvandenbossche |
pitrou
left a comment
There was a problem hiding this comment.
Thanks for the update! I'll push a few minor changes and will merge.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
302c5f1 to
f91a1a5Comparef91a1a5 to
ae740e3CompareThis PR adds rounding compute functions, namely "round" and "round_to_multiple". * `round(x, RoundOptions(ndigits, round_mode))` - round `x` to the precision indicated by `ndigits` * `round_to_multiple(x, RoundToMultipleOptions(multiple, round_mode))` - round `x` to scale of `multiple` Rounding modes supported are: DOWN, UP, TOWARDS_ZERO, TOWARDS_INFINITY, HALF_DOWN, HALF_UP, HALF_TOWARDS_ZERO, HALF_TOWARDS_INFINITY, HALF_TO_EVEN, HALF_TO_ODD. By default tie-breaking modes round to the nearest integer and resolve ties with HALF_TO_EVEN. The rounding functions expect floating-point inputs and return output of the same type. Integral inputs are implicitly type-casted and output is float64. Closesapache#10349 from edponce/ARROW-12744-Add-rounding-kernel Authored-by: Eduardo Ponce <edponce00@gmail.com> Signed-off-by: Antoine Pitrou <antoine@python.org>
This PR adds rounding compute functions, namely "round" and "round_to_multiple".
round(x, RoundOptions(ndigits, round_mode))- roundxto the precision indicated byndigitsround_to_multiple(x, RoundToMultipleOptions(multiple, round_mode))- roundxto scale ofmultipleRounding modes supported are: DOWN, UP, TOWARDS_ZERO, TOWARDS_INFINITY, HALF_DOWN, HALF_UP, HALF_TOWARDS_ZERO, HALF_TOWARDS_INFINITY, HALF_TO_EVEN, HALF_TO_ODD.
By default tie-breaking modes round to the nearest integer and resolve ties with HALF_TO_EVEN.
The rounding functions expect floating-point inputs and return output of the same type. Integral inputs are implicitly type-casted and output is float64.