Skip to content

Commit

Permalink
ARROW-15769: [C++] Generate less arithmetic kernels
Browse files Browse the repository at this point in the history
Template arithmetic kernel executors with the underlying physical type to increase code reuse, decrease binary size, decrease compilation times.

Closes apache#12497 from pitrou/ARROW-15769-arith-kernel-code-reduction

Authored-by: Antoine Pitrou <[email protected]>
Signed-off-by: David Li <[email protected]>
  • Loading branch information
pitrou authored and lidavidm committed Feb 23, 2022
1 parent 1ae81a6 commit 6b63103
Showing 1 changed file with 18 additions and 17 deletions.
35 changes: 18 additions & 17 deletions cpp/src/arrow/compute/kernels/scalar_arithmetic.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2614,6 +2614,10 @@ const FunctionDoc round_to_multiple_doc{
} // namespace

void RegisterScalarArithmetic(FunctionRegistry* registry) {
// NOTE for registration of arithmetic kernels: to minimize code generation,
// it is advised to template the actual executors with physical execution
// types (e.g. Int64 instead of Duration or Timestamp).

// ----------------------------------------------------------------------
auto absolute_value =
MakeUnaryArithmeticFunction<AbsoluteValue>("abs", &absolute_value_doc);
Expand All @@ -2633,7 +2637,7 @@ void RegisterScalarArithmetic(FunctionRegistry* registry) {
// Add add(timestamp, duration) -> timestamp
for (auto unit : TimeUnit::values()) {
InputType in_type(match::TimestampTypeUnit(unit));
auto exec = ScalarBinary<TimestampType, DurationType, TimestampType, Add>::Exec;
auto exec = ScalarBinary<Int64Type, Int64Type, Int64Type, Add>::Exec;
DCHECK_OK(add->AddKernel({in_type, duration(unit)}, OutputType(FirstType),
std::move(exec)));
}
Expand All @@ -2657,8 +2661,7 @@ void RegisterScalarArithmetic(FunctionRegistry* registry) {
// Add add_checked(timestamp, duration) -> timestamp
for (auto unit : TimeUnit::values()) {
InputType in_type(match::TimestampTypeUnit(unit));
auto exec =
ScalarBinary<TimestampType, DurationType, TimestampType, AddChecked>::Exec;
auto exec = ScalarBinary<Int64Type, Int64Type, Int64Type, AddChecked>::Exec;
DCHECK_OK(add_checked->AddKernel({in_type, duration(unit)}, OutputType(FirstType),
std::move(exec)));
}
Expand Down Expand Up @@ -2691,7 +2694,7 @@ void RegisterScalarArithmetic(FunctionRegistry* registry) {
// Add subtract(timestamp, duration) -> timestamp
for (auto unit : TimeUnit::values()) {
InputType in_type(match::TimestampTypeUnit(unit));
auto exec = ScalarBinary<TimestampType, DurationType, TimestampType, Subtract>::Exec;
auto exec = ScalarBinary<Int64Type, Int64Type, Int64Type, Subtract>::Exec;
DCHECK_OK(subtract->AddKernel({in_type, duration(unit)}, OutputType(FirstType),
std::move(exec)));
}
Expand All @@ -2706,26 +2709,26 @@ void RegisterScalarArithmetic(FunctionRegistry* registry) {
// Add subtract(time32, time32) -> duration
for (auto unit : {TimeUnit::SECOND, TimeUnit::MILLI}) {
InputType in_type(match::Time32TypeUnit(unit));
auto exec = ScalarBinaryEqualTypes<Int64Type, Time32Type, Subtract>::Exec;
auto exec = ScalarBinaryEqualTypes<Int64Type, Int32Type, Subtract>::Exec;
DCHECK_OK(subtract->AddKernel({in_type, in_type}, duration(unit), std::move(exec)));
}

// Add subtract(time64, time64) -> duration
for (auto unit : {TimeUnit::MICRO, TimeUnit::NANO}) {
InputType in_type(match::Time64TypeUnit(unit));
auto exec = ScalarBinaryEqualTypes<Int64Type, Time64Type, Subtract>::Exec;
auto exec = ScalarBinaryEqualTypes<Int64Type, Int64Type, Subtract>::Exec;
DCHECK_OK(subtract->AddKernel({in_type, in_type}, duration(unit), std::move(exec)));
}

// Add subtract(date32, date32) -> duration(TimeUnit::SECOND)
InputType in_type_date_32(date32());
auto exec_date_32 = ScalarBinaryEqualTypes<Int64Type, Date32Type, SubtractDate32>::Exec;
auto exec_date_32 = ScalarBinaryEqualTypes<Int64Type, Int32Type, SubtractDate32>::Exec;
DCHECK_OK(subtract->AddKernel({in_type_date_32, in_type_date_32},
duration(TimeUnit::SECOND), std::move(exec_date_32)));

// Add subtract(date64, date64) -> duration(TimeUnit::MILLI)
InputType in_type_date_64(date64());
auto exec_date_64 = ScalarBinaryEqualTypes<Int64Type, Date64Type, Subtract>::Exec;
auto exec_date_64 = ScalarBinaryEqualTypes<Int64Type, Int64Type, Subtract>::Exec;
DCHECK_OK(subtract->AddKernel({in_type_date_64, in_type_date_64},
duration(TimeUnit::MILLI), std::move(exec_date_64)));

Expand All @@ -2751,8 +2754,7 @@ void RegisterScalarArithmetic(FunctionRegistry* registry) {
// Add subtract_checked(timestamp, duration) -> timestamp
for (auto unit : TimeUnit::values()) {
InputType in_type(match::TimestampTypeUnit(unit));
auto exec =
ScalarBinary<TimestampType, DurationType, TimestampType, SubtractChecked>::Exec;
auto exec = ScalarBinary<Int64Type, Int64Type, Int64Type, SubtractChecked>::Exec;
DCHECK_OK(subtract_checked->AddKernel({in_type, duration(unit)},
OutputType(FirstType), std::move(exec)));
}
Expand All @@ -2768,30 +2770,30 @@ void RegisterScalarArithmetic(FunctionRegistry* registry) {

// Add subtract_checked(date32, date32) -> duration(TimeUnit::SECOND)
auto exec_date_32_checked =
ScalarBinaryEqualTypes<Int64Type, Date32Type, SubtractCheckedDate32>::Exec;
ScalarBinaryEqualTypes<Int64Type, Int32Type, SubtractCheckedDate32>::Exec;
DCHECK_OK(subtract_checked->AddKernel({in_type_date_32, in_type_date_32},
duration(TimeUnit::SECOND),
std::move(exec_date_32_checked)));

// Add subtract_checked(date64, date64) -> duration(TimeUnit::MILLI)
auto exec_date_64_checked =
ScalarBinaryEqualTypes<Int64Type, Date64Type, SubtractChecked>::Exec;
ScalarBinaryEqualTypes<Int64Type, Int64Type, SubtractChecked>::Exec;
DCHECK_OK(subtract_checked->AddKernel({in_type_date_64, in_type_date_64},
duration(TimeUnit::MILLI),
std::move(exec_date_64_checked)));

// Add subtract_checked(time32, time32) -> duration
for (auto unit : {TimeUnit::SECOND, TimeUnit::MILLI}) {
InputType in_type(match::Time32TypeUnit(unit));
auto exec = ScalarBinaryEqualTypes<Int64Type, Time32Type, SubtractChecked>::Exec;
auto exec = ScalarBinaryEqualTypes<Int64Type, Int32Type, SubtractChecked>::Exec;
DCHECK_OK(
subtract_checked->AddKernel({in_type, in_type}, duration(unit), std::move(exec)));
}

// Add subtract_checked(time64, time64) -> duration
for (auto unit : {TimeUnit::MICRO, TimeUnit::NANO}) {
InputType in_type(match::Time64TypeUnit(unit));
auto exec = ScalarBinaryEqualTypes<Int64Type, Time64Type, SubtractChecked>::Exec;
auto exec = ScalarBinaryEqualTypes<Int64Type, Int64Type, SubtractChecked>::Exec;
DCHECK_OK(
subtract_checked->AddKernel({in_type, in_type}, duration(unit), std::move(exec)));
}
Expand Down Expand Up @@ -2841,7 +2843,7 @@ void RegisterScalarArithmetic(FunctionRegistry* registry) {

// Add divide(duration, int64) -> duration
for (auto unit : TimeUnit::values()) {
auto exec = ScalarBinaryNotNull<DurationType, DurationType, Int64Type, Divide>::Exec;
auto exec = ScalarBinaryNotNull<Int64Type, Int64Type, Int64Type, Divide>::Exec;
DCHECK_OK(
divide->AddKernel({duration(unit), int64()}, duration(unit), std::move(exec)));
}
Expand All @@ -2854,8 +2856,7 @@ void RegisterScalarArithmetic(FunctionRegistry* registry) {

// Add divide_checked(duration, int64) -> duration
for (auto unit : TimeUnit::values()) {
auto exec =
ScalarBinaryNotNull<DurationType, DurationType, Int64Type, DivideChecked>::Exec;
auto exec = ScalarBinaryNotNull<Int64Type, Int64Type, Int64Type, DivideChecked>::Exec;
DCHECK_OK(divide_checked->AddKernel({duration(unit), int64()}, duration(unit),
std::move(exec)));
}
Expand Down

0 comments on commit 6b63103

Please sign in to comment.