Skip to content

Commit

Permalink
Set up libarrow_gpu, add simple unit test that allocates memory on de…
Browse files Browse the repository at this point in the history
…vice

Change-Id: I40e6b5d77f895d7803dfad64dd9fc2d9f882c0f3
  • Loading branch information
wesm committed Aug 20, 2017
1 parent 6ad976e commit e8f04a8
Show file tree
Hide file tree
Showing 10 changed files with 388 additions and 1 deletion.
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
111 changes: 111 additions & 0 deletions cpp/src/arrow/gpu/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# 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")

set(ARROW_GPU_TEST_LINK_LIBS
arrow_shared
arrow_gpu_shared
)

# 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

0 comments on commit e8f04a8

Please sign in to comment.