Skip to content
Closed
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
8 changes: 8 additions & 0 deletions cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
"Build the Arrow IPC extensions"
ON)

option(ARROW_GPU
"Build the Arrow GPU extensions (requires CUDA installation)"
OFF)

option(ARROW_JEMALLOC
"Build the Arrow jemalloc-based allocator"
OFF)
Expand Down Expand Up @@ -713,6 +717,10 @@ if (ARROW_IPC)
add_dependencies(arrow_dependencies metadata_fbs)
endif()

if (ARROW_GPU)
add_subdirectory(src/arrow/gpu)
endif()

set(ARROW_SRCS
src/arrow/array.cc
src/arrow/buffer.cc
Expand Down
2 changes: 2 additions & 0 deletions cpp/src/arrow/builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ class ARROW_EXPORT ArrayBuilder {
std::shared_ptr<DataType> type() const { return type_; }

protected:
ArrayBuilder() {}

std::shared_ptr<DataType> type_;
MemoryPool* pool_;

Expand Down
106 changes: 106 additions & 0 deletions cpp/src/arrow/gpu/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# 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.

function(ADD_ARROW_CUDA_TEST REL_TEST_NAME)
set(options)
set(single_value_args)
set(multi_value_args STATIC_LINK_LIBS)
cmake_parse_arguments(ARG "${options}" "${one_value_args}" "${multi_value_args}" ${ARGN})
if(ARG_UNPARSED_ARGUMENTS)
message(SEND_ERROR "Error: unrecognized arguments: ${ARG_UNPARSED_ARGUMENTS}")
endif()

if(NO_TESTS OR NOT ARROW_BUILD_STATIC)
return()
endif()
get_filename_component(TEST_NAME ${REL_TEST_NAME} NAME_WE)

if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${REL_TEST_NAME}.cc)
# This test has a corresponding .cc file, set it up as an executable.
set(TEST_PATH "${EXECUTABLE_OUTPUT_PATH}/${TEST_NAME}")
cuda_add_executable(${TEST_NAME} "${REL_TEST_NAME}.cc")

if (ARG_STATIC_LINK_LIBS)
# Customize link libraries
target_link_libraries(${TEST_NAME} ${ARG_STATIC_LINK_LIBS})
else()
target_link_libraries(${TEST_NAME} ${ARROW_TEST_LINK_LIBS})
endif()
add_dependencies(unittest ${TEST_NAME})
else()
# No executable, just invoke the test (probably a script) directly.
set(TEST_PATH ${CMAKE_CURRENT_SOURCE_DIR}/${REL_TEST_NAME})
endif()

if (ARROW_TEST_MEMCHECK)
SET_PROPERTY(TARGET ${TEST_NAME}
APPEND_STRING PROPERTY
COMPILE_FLAGS " -DARROW_VALGRIND")
add_test(${TEST_NAME}
bash -c "cd ${EXECUTABLE_OUTPUT_PATH}; valgrind --tool=memcheck --leak-check=full --leak-check-heuristics=stdstring --error-exitcode=1 ${TEST_PATH}")
elseif(MSVC)
add_test(${TEST_NAME} ${TEST_PATH})
else()
add_test(${TEST_NAME}
${BUILD_SUPPORT_DIR}/run-test.sh ${CMAKE_BINARY_DIR} test ${TEST_PATH})
endif()
set_tests_properties(${TEST_NAME} PROPERTIES LABELS "unittest")
endfunction()

#######################################
# arrow_gpu
#######################################

if (DEFINED ENV{CUDA_HOME})
set(CUDA_TOOLKIT_ROOT_DIR "$ENV{CUDA_HOME}")
endif()

find_package(CUDA REQUIRED)
include_directories(SYSTEM ${CUDA_INCLUDE_DIRS})

set(ARROW_GPU_SRCS
cuda_memory.cc
)

set(ARROW_GPU_SHARED_LINK_LIBS
arrow_shared
)

cuda_add_library(arrow_gpu SHARED
${ARROW_GPU_SRCS}
)

install(FILES
cuda_common.h
cuda_memory.h
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/arrow/gpu")

# pkg-config support
configure_file(arrow-gpu.pc.in
"${CMAKE_CURRENT_BINARY_DIR}/arrow-gpu.pc"
@ONLY)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/arrow-gpu.pc"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig/")

if (ARROW_BUILD_TESTS)
set(ARROW_GPU_TEST_LINK_LIBS
${ARROW_TEST_LINK_LIBS}
arrow_gpu)
ADD_ARROW_CUDA_TEST(cuda-test
STATIC_LINK_LIBS ${ARROW_GPU_TEST_LINK_LIBS})
endif()
26 changes: 26 additions & 0 deletions cpp/src/arrow/gpu/arrow-gpu.pc.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# 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.

libdir=@CMAKE_INSTALL_FULL_LIBDIR@
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@

Name: Apache Arrow GPU
Description: GPU integration library for Apache Arrow
Version: @ARROW_VERSION@
Requires: arrow
Libs: -L${libdir} -larrow_gpu
Cflags: -I${includedir}
45 changes: 45 additions & 0 deletions cpp/src/arrow/gpu/cuda-test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// 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 <cstdint>
#include <limits>
#include <string>

#include "gtest/gtest.h"

#include "arrow/status.h"
#include "arrow/test-util.h"

#include "arrow/gpu/cuda_memory.h"

namespace arrow {
namespace gpu {

class TestCudaBuffer : public ::testing::Test {};

TEST_F(TestCudaBuffer, Allocate) {
const int device = 0;

const int64_t kSize = 100;
std::shared_ptr<CudaBuffer> buffer;

ASSERT_OK(AllocateCudaBuffer(device, kSize, &buffer));
ASSERT_EQ(kSize, buffer->size());
}

} // namespace gpu
} // namespace arrow
46 changes: 46 additions & 0 deletions cpp/src/arrow/gpu/cuda_common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// 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.

// Non-public header

#ifndef ARROW_GPU_CUDA_COMMON_H
#define ARROW_GPU_CUDA_COMMON_H

#include <cuda_runtime_api.h>

namespace arrow {
namespace gpu {

#define CUDA_DCHECK(STMT) \
do { \
int ret = (STMT); \
DCHECK_EQ(0, ret); \
(void)ret; \
} while (0)

#define CUDA_RETURN_NOT_OK(STMT) \
do { \
cudaError_t ret = (STMT); \
if (ret != cudaSuccess) { \
return Status::IOError("Cuda API call failed: " #STMT); \
} \
} while (0)

} // namespace gpu
} // namespace arrow

#endif // ARROW_GPU_CUDA_COMMON_H
65 changes: 65 additions & 0 deletions cpp/src/arrow/gpu/cuda_memory.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// 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 "arrow/gpu/cuda_memory.h"

#include <cstdint>
#include <memory>

#include "arrow/buffer.h"
#include "arrow/status.h"
#include "arrow/util/logging.h"

#include "arrow/gpu/cuda_common.h"

namespace arrow {
namespace gpu {

CudaBuffer::~CudaBuffer() {
if (own_data_) {
CUDA_DCHECK(cudaFree(mutable_data_));
}
}

Status CudaBuffer::CopyHost(uint8_t* out) {
CUDA_RETURN_NOT_OK(cudaMemcpy(out, data_, size_, cudaMemcpyDeviceToHost));
return Status::OK();
}

Status AllocateCudaBuffer(int gpu_number, const int64_t size,
std::shared_ptr<CudaBuffer>* out) {
CUDA_RETURN_NOT_OK(cudaSetDevice(gpu_number));
uint8_t* data = nullptr;
CUDA_RETURN_NOT_OK(
cudaMalloc(reinterpret_cast<void**>(&data), static_cast<size_t>(size)));
*out = std::make_shared<CudaBuffer>(data, size, gpu_number, true);
return Status::OK();
}

CudaHostBuffer::~CudaHostBuffer() { CUDA_DCHECK(cudaFreeHost(mutable_data_)); }

Status AllocateCudaHostBuffer(const int gpu_number, const int64_t size,
std::shared_ptr<CudaHostBuffer>* out) {
uint8_t* data = nullptr;
CUDA_RETURN_NOT_OK(
cudaMallocHost(reinterpret_cast<void**>(&data), static_cast<size_t>(size)));
*out = std::make_shared<CudaHostBuffer>(data, size);
return Status::OK();
}

} // namespace gpu
} // namespace arrow
Loading