forked from apache/arrow
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
apacheGH-37753: [C++][Gandiva] Add external function registry support (…
…apache#38116) # Rationale for this change This PR tries to enhance Gandiva by supporting external function registry, so that developers can author third party functions without modifying Gandiva's core codebase. See apache#37753 for more details. In this PR, the external function needs to be compiled into LLVM IR for integration. # What changes are included in this PR? Two new APIs are added to `FunctionRegistry`: ```C++ /// \brief register a set of functions into the function registry from a given bitcode /// file arrow::Status Register(const std::vector<NativeFunction>& funcs, const std::string& bitcode_path); /// \brief register a set of functions into the function registry from a given bitcode /// buffer arrow::Status Register(const std::vector<NativeFunction>& funcs, std::shared_ptr<arrow::Buffer> bitcode_buffer); ``` Developers can use these two APIs to register external functions. Typically, developers will register a set of function metadatas (`funcs`) for all functions in a LLVM bitcode file, by giving either the path to the LLVM bitcode file or an `arrow::Buffer` containing the LLVM bitcode buffer. The overall flow looks like this: ![image](https://github.com/apache/arrow/assets/27754/b2b346fe-931f-4253-b198-4c388c57a56b) # Are these changes tested? Some unit tests are added to verify this enhancement # Are there any user-facing changes? Some new ways to interfacing the library are added in this PR: * The `Configuration` class now supports accepting a customized function registry, which developers can register their own external functions and uses it as the function registry * The `FunctionRegistry` class has two new APIs mentioned above * The `FunctionRegistry` class, after instantiation, now it doesn't have any built-in function registered in it. And we switch to use a new function `GANDIVA_EXPORT std::shared_ptr<FunctionRegistry> default_function_registry();` to retrieve the default function registry, which contains all the Gandiva built-in functions. * Some library depending on Gandiva C++ library, such as Gandiva's Ruby binding's `Gandiva::FunctionRegistry` class behavior is changed accordingly # Notes * Performance * the code generation time grows with the number of externally added function bitcodes (the more functions are added, the slower the codegen will be), even if the externally function is not used in the given expression at all. But this is not a new issue, and it applies to built-in functions as well (the more built-in functions are there, the slower the codegen will be). In my limited testing, this is because `llvm::Linker::linkModule` takes non trivial of time, which happens to every IR loaded, and the `RemoveUnusedFunctions` happens after that, which doesn't help to reduce the time of `linkModule`. We may have to selectively load only necessary IR (primarily selectively doing `linkModule` for these IR), but more metadata may be needed to tell which functions can be found in which IR. This could be a separated PR for improving it, please advice if any one has any idea on improving it. Thanks. * Integration with other programming languages via LLVM IR/bitcode * So far I only added an external C++ function in the codebase for unit testing purpose. Rust based function is possible but I gave it a try and found another issue (Rust has std lib which needs to be processed in different approach), I will do some exploration for other languages such as zig later. * Non pre-compiled functions, may require some different approach to get the function pointer, and we may discuss and work on it in a separated PR later. Another issue apache#38589 was logged for this. * The discussion thread in dev mail list, https://lists.apache.org/thread/lm4sbw61w9cl7fsmo7tz3gvkq0ox6rod * I submitted another PR previously (apache#37787) which introduced JSON based function registry, and after discussion, I will close that PR and use this PR instead * Closes: apache#37753 Lead-authored-by: Yue Ni <[email protected]> Co-authored-by: Sutou Kouhei <[email protected]> Signed-off-by: Sutou Kouhei <[email protected]>
- Loading branch information
Showing
43 changed files
with
809 additions
and
247 deletions.
There are no files selected for viewing
This file contains 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 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 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 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 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,30 @@ | ||
/* | ||
* 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 <gandiva/function_registry.h> | ||
|
||
#include <gandiva-glib/function-registry.h> | ||
|
||
GGandivaFunctionRegistry * | ||
ggandiva_function_registry_new_raw( | ||
std::shared_ptr<gandiva::FunctionRegistry> *gandiva_function_registry); | ||
std::shared_ptr<gandiva::FunctionRegistry> | ||
ggandiva_function_registry_get_raw(GGandivaFunctionRegistry *function_registry); |
This file contains 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 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 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,75 @@ | ||
# 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. | ||
|
||
# Create bitcode for the given source file. | ||
function(gandiva_add_bitcode SOURCE) | ||
set(CLANG_OPTIONS -std=c++17) | ||
if(MSVC) | ||
# "19.20" means that it's compatible with Visual Studio 16 2019. | ||
# We can update this to "19.30" when we dropped support for Visual | ||
# Studio 16 2019. | ||
# | ||
# See https://cmake.org/cmake/help/latest/variable/MSVC_VERSION.html | ||
# for MSVC_VERSION and Visual Studio version. | ||
set(FMS_COMPATIBILITY 19.20) | ||
list(APPEND CLANG_OPTIONS -fms-compatibility | ||
-fms-compatibility-version=${FMS_COMPATIBILITY}) | ||
endif() | ||
|
||
get_filename_component(SOURCE_BASE ${SOURCE} NAME_WE) | ||
get_filename_component(ABSOLUTE_SOURCE ${SOURCE} ABSOLUTE) | ||
set(BC_FILE ${CMAKE_CURRENT_BINARY_DIR}/${SOURCE_BASE}.bc) | ||
set(PRECOMPILE_COMMAND) | ||
if(CMAKE_OSX_SYSROOT) | ||
list(APPEND | ||
PRECOMPILE_COMMAND | ||
${CMAKE_COMMAND} | ||
-E | ||
env | ||
SDKROOT=${CMAKE_OSX_SYSROOT}) | ||
endif() | ||
list(APPEND | ||
PRECOMPILE_COMMAND | ||
${CLANG_EXECUTABLE} | ||
${CLANG_OPTIONS} | ||
-DGANDIVA_IR | ||
-DNDEBUG # DCHECK macros not implemented in precompiled code | ||
-DARROW_STATIC # Do not set __declspec(dllimport) on MSVC on Arrow symbols | ||
-DGANDIVA_STATIC # Do not set __declspec(dllimport) on MSVC on Gandiva symbols | ||
-fno-use-cxa-atexit # Workaround for unresolved __dso_handle | ||
-emit-llvm | ||
-O3 | ||
-c | ||
${ABSOLUTE_SOURCE} | ||
-o | ||
${BC_FILE} | ||
${ARROW_GANDIVA_PC_CXX_FLAGS}) | ||
if(ARROW_BINARY_DIR) | ||
list(APPEND PRECOMPILE_COMMAND -I${ARROW_BINARY_DIR}/src) | ||
endif() | ||
if(ARROW_SOURCE_DIR) | ||
list(APPEND PRECOMPILE_COMMAND -I${ARROW_SOURCE_DIR}/src) | ||
endif() | ||
if(NOT ARROW_USE_NATIVE_INT128) | ||
foreach(boost_include_dir ${Boost_INCLUDE_DIRS}) | ||
list(APPEND PRECOMPILE_COMMAND -I${boost_include_dir}) | ||
endforeach() | ||
endif() | ||
add_custom_command(OUTPUT ${BC_FILE} | ||
COMMAND ${PRECOMPILE_COMMAND} | ||
DEPENDS ${SOURCE_FILE}) | ||
endfunction() |
This file contains 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.