Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cpp/src/gandiva/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ set(SRC_FILES
function_registry_datetime.cc
function_registry_hash.cc
function_registry_math_ops.cc
function_registry_math_ops_trig.cc
function_registry_string.cc
function_registry_timestamp_arithmetic.cc
function_signature.cc
Expand Down
13 changes: 9 additions & 4 deletions cpp/src/gandiva/function_registry.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,19 @@
// under the License.

#include "gandiva/function_registry.h"

#include <iterator>
#include <utility>
#include <vector>

#include "gandiva/function_registry_arithmetic.h"
#include "gandiva/function_registry_datetime.h"
#include "gandiva/function_registry_hash.h"
#include "gandiva/function_registry_math_ops.h"
#include "gandiva/function_registry_math_ops_trig.h"
#include "gandiva/function_registry_string.h"
#include "gandiva/function_registry_timestamp_arithmetic.h"

#include <iterator>
#include <utility>
#include <vector>

namespace gandiva {

FunctionRegistry::iterator FunctionRegistry::begin() const {
Expand Down Expand Up @@ -65,6 +67,9 @@ SignatureMap FunctionRegistry::InitPCMap() {
auto v6 = GetDateTimeArithmeticFunctionRegistry();
pc_registry_.insert(std::end(pc_registry_), v6.begin(), v6.end());

auto v7 = GetMathOpsTrigFunctionRegistry();
pc_registry_.insert(std::end(pc_registry_), v7.begin(), v7.end());

for (auto& elem : pc_registry_) {
for (auto& func_signature : elem.signatures()) {
map.insert(std::make_pair(&(func_signature), &elem));
Expand Down
4 changes: 3 additions & 1 deletion cpp/src/gandiva/function_registry_arithmetic.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
// under the License.

#include "gandiva/function_registry_arithmetic.h"

#include "gandiva/function_registry_common.h"

namespace gandiva {
Expand All @@ -38,11 +39,12 @@ std::vector<NativeFunction> GetArithmeticFunctionRegistry() {
UNARY_SAFE_NULL_IF_NULL(not, {}, boolean, boolean),
UNARY_SAFE_NULL_IF_NULL(castBIGINT, {}, int32, int64),
UNARY_SAFE_NULL_IF_NULL(castINT, {}, int64, int32),
UNARY_SAFE_NULL_IF_NULL(castINT, {}, int8, int32),
UNARY_SAFE_NULL_IF_NULL(castBIGINT, {}, decimal128, int64),

// cast to float32
UNARY_CAST_TO_FLOAT32(int32), UNARY_CAST_TO_FLOAT32(int64),
UNARY_CAST_TO_FLOAT32(float64),
UNARY_CAST_TO_FLOAT32(float64), UNARY_CAST_TO_FLOAT32(int8),

// cast to float64
UNARY_CAST_TO_FLOAT64(int32), UNARY_CAST_TO_FLOAT64(int64),
Expand Down
16 changes: 15 additions & 1 deletion cpp/src/gandiva/function_registry_math_ops.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
// under the License.

#include "gandiva/function_registry_math_ops.h"

#include "gandiva/function_registry_common.h"

namespace gandiva {
Expand All @@ -28,6 +29,11 @@ namespace gandiva {
UNARY_SAFE_NULL_IF_NULL(name, ALIASES, float32, float64), \
UNARY_SAFE_NULL_IF_NULL(name, ALIASES, float64, float64)

#define MATH_UNARY_OPS_FLOAT(name, ALIASES) \
UNARY_SAFE_NULL_IF_NULL(name, ALIASES, int32, float32), \
UNARY_SAFE_NULL_IF_NULL(name, ALIASES, uint32, float32), \
UNARY_SAFE_NULL_IF_NULL(name, ALIASES, float32, float32)

#define MATH_BINARY_UNSAFE(name, ALIASES) \
BINARY_UNSAFE_NULL_IF_NULL(name, ALIASES, int32, float64), \
BINARY_UNSAFE_NULL_IF_NULL(name, ALIASES, int64, float64), \
Expand All @@ -45,11 +51,16 @@ namespace gandiva {
std::vector<NativeFunction> GetMathOpsFunctionRegistry() {
static std::vector<NativeFunction> math_fn_registry_ = {
MATH_UNARY_OPS(cbrt, {}), MATH_UNARY_OPS(exp, {}), MATH_UNARY_OPS(log, {}),
MATH_UNARY_OPS(log10, {}),
MATH_UNARY_OPS(log10, {}), MATH_UNARY_OPS(sqrt, {}),

MATH_UNARY_OPS_FLOAT(sqrtf, {}), MATH_UNARY_OPS_FLOAT(cbrtf, {}),
MATH_UNARY_OPS_FLOAT(expf, {}), MATH_UNARY_OPS_FLOAT(logf, {}),
MATH_UNARY_OPS_FLOAT(log10f, {}),

MATH_BINARY_UNSAFE(log, {}),

BINARY_SYMMETRIC_SAFE_NULL_IF_NULL(power, {"pow"}, float64),
BINARY_SYMMETRIC_SAFE_NULL_IF_NULL(powerf, {"powf"}, float32),

UNARY_SAFE_NULL_NEVER_BOOL_FN(isnull, {}),
UNARY_SAFE_NULL_NEVER_BOOL_FN(isnotnull, {}),
Expand All @@ -61,6 +72,7 @@ std::vector<NativeFunction> GetMathOpsFunctionRegistry() {

// decimal functions
UNARY_SAFE_NULL_IF_NULL(abs, {}, decimal128, decimal128),
UNARY_SAFE_NULL_IF_NULL(absf, {}, float32, float32),
UNARY_SAFE_NULL_IF_NULL(ceil, {}, decimal128, decimal128),
UNARY_SAFE_NULL_IF_NULL(floor, {}, decimal128, decimal128),
UNARY_SAFE_NULL_IF_NULL(round, {}, decimal128, decimal128),
Expand All @@ -82,6 +94,8 @@ std::vector<NativeFunction> GetMathOpsFunctionRegistry() {

#undef MATH_UNARY_OPS

#undef MATH_UNARY_OPS_FLOAT

#undef MATH_BINARY_UNSAFE

#undef UNARY_SAFE_NULL_NEVER_BOOL_FN
Expand Down
52 changes: 52 additions & 0 deletions cpp/src/gandiva/function_registry_math_ops_trig.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

#include "gandiva/function_registry_math_ops_trig.h"

#include "gandiva/function_registry_common.h"

namespace gandiva {

#define MATH_UNARY_OPS(name, ALIASES) \
UNARY_SAFE_NULL_IF_NULL(name, ALIASES, int32, float64), \
UNARY_SAFE_NULL_IF_NULL(name, ALIASES, int64, float64), \
UNARY_SAFE_NULL_IF_NULL(name, ALIASES, uint32, float64), \
UNARY_SAFE_NULL_IF_NULL(name, ALIASES, uint64, float64), \
UNARY_SAFE_NULL_IF_NULL(name, ALIASES, float32, float64), \
UNARY_SAFE_NULL_IF_NULL(name, ALIASES, float64, float64)

#define MATH_UNARY_OPS_FLOAT(name, ALIASES) \
UNARY_SAFE_NULL_IF_NULL(name, ALIASES, int32, float32), \
UNARY_SAFE_NULL_IF_NULL(name, ALIASES, uint32, float32), \
UNARY_SAFE_NULL_IF_NULL(name, ALIASES, float32, float32)

std::vector<NativeFunction> GetMathOpsTrigFunctionRegistry() {
static std::vector<NativeFunction> math_fn_registry_ = {
MATH_UNARY_OPS(sin, {}), MATH_UNARY_OPS(cos, {}),
MATH_UNARY_OPS(tan, {}), MATH_UNARY_OPS(asin, {}),
MATH_UNARY_OPS(acos, {}), MATH_UNARY_OPS(atan, {}),

MATH_UNARY_OPS_FLOAT(sinf, {}), MATH_UNARY_OPS_FLOAT(cosf, {}),
MATH_UNARY_OPS_FLOAT(tanf, {}), MATH_UNARY_OPS_FLOAT(asinf, {}),
MATH_UNARY_OPS_FLOAT(acosf, {}), MATH_UNARY_OPS_FLOAT(atanf, {})};
return math_fn_registry_;
}

#undef MATH_UNARY_OPS

#undef MATH_UNARY_OPS_FLOAT
} // namespace gandiva
28 changes: 28 additions & 0 deletions cpp/src/gandiva/function_registry_math_ops_trig.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

#pragma once

#include <vector>

#include "gandiva/native_function.h"

namespace gandiva {

std::vector<NativeFunction> GetMathOpsTrigFunctionRegistry();

} // namespace gandiva
3 changes: 3 additions & 0 deletions cpp/src/gandiva/precompiled/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ set(PRECOMPILED_SRCS
decimal_ops.cc
decimal_wrapper.cc
extended_math_ops.cc
extended_math_ops_trig.cc
hash.cc
print.cc
string_ops.cc
Expand Down Expand Up @@ -119,6 +120,8 @@ if(ARROW_BUILD_TESTS)
arithmetic_ops.cc
extended_math_ops_test.cc
extended_math_ops.cc
extended_math_ops_trig_test.cc
extended_math_ops_trig.cc
decimal_ops_test.cc
decimal_ops.cc
../decimal_type_util.cc
Expand Down
3 changes: 3 additions & 0 deletions cpp/src/gandiva/precompiled/arithmetic_ops.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
extern "C" {

#include <math.h>

#include "./types.h"

// Expand inner macro for all numeric types.
Expand Down Expand Up @@ -107,6 +108,8 @@ NUMERIC_DATE_TYPES(BINARY_RELATIONAL, greater_than_or_equal_to, >=)

CAST_UNARY(castBIGINT, int32, int64)
CAST_UNARY(castINT, int64, int32)
CAST_UNARY(castINT, int8, int32)
CAST_UNARY(castFLOAT4, int8, float32)
CAST_UNARY(castFLOAT4, int32, float32)
CAST_UNARY(castFLOAT4, int64, float32)
CAST_UNARY(castFLOAT8, int32, float64)
Expand Down
67 changes: 67 additions & 0 deletions cpp/src/gandiva/precompiled/extended_math_ops.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ extern "C" {
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "./types.h"

// Expand the inner fn for types that support extended math.
Expand All @@ -34,34 +35,79 @@ extern "C" {
INNER(float32, OUT_TYPE) \
INNER(float64, OUT_TYPE)

#define ENUMERIC_TYPES_UNARY_FLOAT(INNER, OUT_TYPE) \
INNER(int32, OUT_TYPE) \
INNER(uint32, OUT_TYPE) \
INNER(int64, OUT_TYPE) \
INNER(uint64, OUT_TYPE) \
INNER(float32, OUT_TYPE)

// Square root
#define SQRTF(IN_TYPE, OUT_TYPE) \
FORCE_INLINE \
gdv_##OUT_TYPE sqrtf_##IN_TYPE(gdv_##IN_TYPE in) { \
return static_cast<gdv_float32>(sqrtf(static_cast<float>(in))); \
}
#define SQRT(IN_TYPE, OUT_TYPE) \
FORCE_INLINE \
gdv_##OUT_TYPE sqrt_##IN_TYPE(gdv_##IN_TYPE in) { \
return static_cast<gdv_float64>(sqrtl(static_cast<long double>(in))); \
}

ENUMERIC_TYPES_UNARY_FLOAT(SQRTF, float32)
ENUMERIC_TYPES_UNARY(SQRT, float64)

// Cubic root
#define CBRTF(IN_TYPE, OUT_TYPE) \
FORCE_INLINE \
gdv_##OUT_TYPE cbrtf_##IN_TYPE(gdv_##IN_TYPE in) { \
return static_cast<gdv_float32>(cbrtf(static_cast<float>(in))); \
}
#define CBRT(IN_TYPE, OUT_TYPE) \
FORCE_INLINE \
gdv_##OUT_TYPE cbrt_##IN_TYPE(gdv_##IN_TYPE in) { \
return static_cast<gdv_float64>(cbrtl(static_cast<long double>(in))); \
}

ENUMERIC_TYPES_UNARY_FLOAT(CBRTF, float32)
ENUMERIC_TYPES_UNARY(CBRT, float64)

// Exponent
#define EXPF(IN_TYPE, OUT_TYPE) \
FORCE_INLINE \
gdv_##OUT_TYPE expf_##IN_TYPE(gdv_##IN_TYPE in) { \
return static_cast<gdv_float32>(expf(static_cast<float>(in))); \
}
#define EXP(IN_TYPE, OUT_TYPE) \
FORCE_INLINE \
gdv_##OUT_TYPE exp_##IN_TYPE(gdv_##IN_TYPE in) { \
return static_cast<gdv_float64>(expl(static_cast<long double>(in))); \
}

ENUMERIC_TYPES_UNARY_FLOAT(EXPF, float32)
ENUMERIC_TYPES_UNARY(EXP, float64)

// log
#define LOGF(IN_TYPE, OUT_TYPE) \
FORCE_INLINE \
gdv_##OUT_TYPE logf_##IN_TYPE(gdv_##IN_TYPE in) { \
return static_cast<gdv_float32>(logf(static_cast<float>(in))); \
}
#define LOG(IN_TYPE, OUT_TYPE) \
FORCE_INLINE \
gdv_##OUT_TYPE log_##IN_TYPE(gdv_##IN_TYPE in) { \
return static_cast<gdv_float64>(logl(static_cast<long double>(in))); \
}

ENUMERIC_TYPES_UNARY_FLOAT(LOGF, float32)
ENUMERIC_TYPES_UNARY(LOG, float64)

// log base 10
#define LOG10F(IN_TYPE, OUT_TYPE) \
FORCE_INLINE \
gdv_##OUT_TYPE log10f_##IN_TYPE(gdv_##IN_TYPE in) { \
return static_cast<gdv_float32>(log10f(static_cast<float>(in))); \
}
#define LOG10(IN_TYPE, OUT_TYPE) \
FORCE_INLINE \
gdv_##OUT_TYPE log10_##IN_TYPE(gdv_##IN_TYPE in) { \
Expand All @@ -70,6 +116,7 @@ ENUMERIC_TYPES_UNARY(LOG, float64)

#define LOGL(VALUE) static_cast<gdv_float64>(logl(static_cast<long double>(VALUE)))

ENUMERIC_TYPES_UNARY_FLOAT(LOG10F, float32)
ENUMERIC_TYPES_UNARY(LOG10, float64)

FORCE_INLINE
Expand Down Expand Up @@ -103,14 +150,34 @@ LOG_WITH_BASE(float32, float32, float64)
LOG_WITH_BASE(float64, float64, float64)

// power
#define POWERF(IN_TYPE1, IN_TYPE2, OUT_TYPE) \
FORCE_INLINE \
gdv_##OUT_TYPE powerf_##IN_TYPE1##_##IN_TYPE2(gdv_##IN_TYPE1 in1, \
gdv_##IN_TYPE2 in2) { \
return static_cast<gdv_float32>(powf(in1, in2)); \
}
#define POWER(IN_TYPE1, IN_TYPE2, OUT_TYPE) \
FORCE_INLINE \
gdv_##OUT_TYPE power_##IN_TYPE1##_##IN_TYPE2(gdv_##IN_TYPE1 in1, gdv_##IN_TYPE2 in2) { \
return static_cast<gdv_float64>(powl(in1, in2)); \
}

POWERF(float32, float32, float32)
POWER(float64, float64, float64)

// ABS
#define ABSF(IN_TYPE, OUT_TYPE) \
FORCE_INLINE \
gdv_##OUT_TYPE absf_##IN_TYPE(gdv_##IN_TYPE in) { \
if (static_cast<gdv_##IN_TYPE>(in) < 0) { \
return static_cast<gdv_##OUT_TYPE>(-in); \
} else { \
return static_cast<gdv_##OUT_TYPE>(in); \
} \
}

ABSF(float32, float32)

FORCE_INLINE
gdv_int64 truncate_int64_int32(gdv_int64 in, gdv_int32 out_scale) {
bool overflow = false;
Expand Down
13 changes: 9 additions & 4 deletions cpp/src/gandiva/precompiled/extended_math_ops_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,23 @@
// specific language governing permissions and limitations
// under the License.

#include <gandiva/precompiled/testing.h>
#include <gtest/gtest.h>
#include <math.h>

#include <gtest/gtest.h>
#include "gandiva/execution_context.h"
#include "gandiva/precompiled/types.h"

namespace gandiva {

static const double MAX_ERROR = 0.00005;
TEST(TestExtendedMathOps, TestSqrt) {
VerifyFuzzyEquals(sqrt_int32(9), 3);
VerifyFuzzyEquals(sqrt_int64(9), 3);
VerifyFuzzyEquals(sqrt_float32(9), 3);
VerifyFuzzyEquals(sqrt_float64(9), 3);

void VerifyFuzzyEquals(double actual, double expected, double max_error = MAX_ERROR) {
EXPECT_TRUE(fabs(actual - expected) < max_error) << actual << " != " << expected;
VerifyFuzzyEquals(sqrt_float32(6.25), 2.5);
VerifyFuzzyEquals(sqrt_float64(6.25), 2.5);
}

TEST(TestExtendedMathOps, TestCbrt) {
Expand Down
Loading