Skip to content

Commit

Permalink
Move Thrust's pinned_allocator into cudf
Browse files Browse the repository at this point in the history
Thrust 1.17 removes the experimental/pinned_allocator. While
Thrust offers a replacement in `thrust::system::cuda::universal_host_pinned_memory_resource`. In doing so we also need to move the consumers to being CUDA sources which would negatively impact our compile time.

Instead we move Thrust's removed pinned_allocator into
cudf and continue to use it
  • Loading branch information
robertmaynard committed Oct 27, 2022
1 parent 1e5058c commit dc3f7de
Show file tree
Hide file tree
Showing 5 changed files with 222 additions and 9 deletions.
5 changes: 2 additions & 3 deletions cpp/benchmarks/io/text/multibyte_split.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@
#include <cudf/strings/combine.hpp>
#include <cudf/types.hpp>
#include <cudf/utilities/default_stream.hpp>
#include <cudf/utilities/pinned_allocator.h>

#include <thrust/host_vector.h>
#include <thrust/system/cuda/experimental/pinned_allocator.h>
#include <thrust/transform.h>

#include <nvbench/nvbench.cuh>
Expand Down Expand Up @@ -135,8 +135,7 @@ static void bench_multibyte_split(nvbench::state& state,
auto const delim_factor = static_cast<double>(delim_percent) / 100;
auto device_input = create_random_input(file_size_approx, delim_factor, 0.05, delim);
auto host_input = std::vector<char>{};
auto host_pinned_input =
thrust::host_vector<char, thrust::system::cuda::experimental::pinned_allocator<char>>{};
auto host_pinned_input = thrust::host_vector<char, cudf::pinned_allocator<char>>{};

if (source_type == data_chunk_source_type::host || source_type == data_chunk_source_type::file ||
source_type == data_chunk_source_type::file_bgzip) {
Expand Down
214 changes: 214 additions & 0 deletions cpp/include/cudf/utilities/pinned_allocator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
/*
* Copyright 2008-2022 NVIDIA Corporation
*
* Licensed 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.
*/

/*! \file thrust/system/cuda/experimental/pinned_allocator.h
* \brief An allocator which creates new elements in "pinned" memory with \p cudaMallocHost
*/

#pragma once

#include <thrust/detail/config.h>
#include <thrust/system/cuda/detail/guarded_cuda_runtime_api.h>
#include <stdexcept>
#include <limits>
#include <string>
#include <thrust/system/system_error.h>
#include <thrust/system/cuda/error.h>


namespace cudf
{

/*! \p pinned_allocator is a CUDA-specific host memory allocator
* that employs \c cudaMallocHost for allocation.
*
* This implementation is ported from the experimental/pinned_allocator
* that Thrust used to provide.
*
* \see https://en.cppreference.com/w/cpp/memory/allocator
*/
template<typename T> class pinned_allocator;

template<>
class pinned_allocator<void>
{
public:
typedef void value_type;
typedef void * pointer;
typedef const void * const_pointer;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;

// convert a pinned_allocator<void> to pinned_allocator<U>
template<typename U>
struct rebind
{
typedef pinned_allocator<U> other;
}; // end rebind
}; // end pinned_allocator


template<typename T>
class pinned_allocator
{
public:
//! \{
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
//! \}

// convert a pinned_allocator<T> to pinned_allocator<U>
template<typename U>
struct rebind
{
typedef pinned_allocator<U> other;
}; // end rebind

/*! \p pinned_allocator's null constructor does nothing.
*/
__host__ __device__
inline pinned_allocator() {}

/*! \p pinned_allocator's null destructor does nothing.
*/
__host__ __device__
inline ~pinned_allocator() {}

/*! \p pinned_allocator's copy constructor does nothing.
*/
__host__ __device__
inline pinned_allocator(pinned_allocator const &) {}

/*! This version of \p pinned_allocator's copy constructor
* is templated on the \c value_type of the \p pinned_allocator
* to copy from. It is provided merely for convenience; it
* does nothing.
*/
template<typename U>
__host__ __device__
inline pinned_allocator(pinned_allocator<U> const &) {}

/*! This method returns the address of a \c reference of
* interest.
*
* \p r The \c reference of interest.
* \return \c r's address.
*/
__host__ __device__
inline pointer address(reference r) { return &r; }

/*! This method returns the address of a \c const_reference
* of interest.
*
* \p r The \c const_reference of interest.
* \return \c r's address.
*/
__host__ __device__
inline const_pointer address(const_reference r) { return &r; }

/*! This method allocates storage for objects in pinned host
* memory.
*
* \p cnt The number of objects to allocate.
* \return a \c pointer to the newly allocated objects.
* \note This method does not invoke \p value_type's constructor.
* It is the responsibility of the caller to initialize the
* objects at the returned \c pointer.
*/
__host__
inline pointer allocate(size_type cnt,
const_pointer = 0)
{
if(cnt > this->max_size())
{
throw std::bad_alloc();
} // end if

pointer result(0);
cudaError_t error = cudaMallocHost(reinterpret_cast<void**>(&result), cnt * sizeof(value_type));

if(error)
{
cudaGetLastError(); // Clear global CUDA error state.
throw std::bad_alloc();
} // end if

return result;
} // end allocate()

/*! This method deallocates pinned host memory previously allocated
* with this \c pinned_allocator.
*
* \p p A \c pointer to the previously allocated memory.
* \p cnt The number of objects previously allocated at
* \p p.
* \note This method does not invoke \p value_type's destructor.
* It is the responsibility of the caller to destroy
* the objects stored at \p p.
*/
__host__
inline void deallocate(pointer p, size_type /*cnt*/)
{
cudaError_t error = cudaFreeHost(p);

cudaGetLastError(); // Clear global CUDA error state.

if(error)
{
cudaGetLastError(); // Clear global CUDA error state.
throw thrust::system_error(error, thrust::cuda_category());
} // end if
} // end deallocate()

/*! This method returns the maximum size of the \c cnt parameter
* accepted by the \p allocate() method.
*
* \return The maximum number of objects that may be allocated
* by a single call to \p allocate().
*/
inline size_type max_size() const
{
return (std::numeric_limits<size_type>::max)() / sizeof(T);
} // end max_size()

/*! This method tests this \p pinned_allocator for equality to
* another.
*
* \param x The other \p pinned_allocator of interest.
* \return This method always returns \c true.
*/
__host__ __device__
inline bool operator==(pinned_allocator const& x) const { return true; }

/*! This method tests this \p pinned_allocator for inequality
* to another.
*
* \param x The other \p pinned_allocator of interest.
* \return This method always returns \c false.
*/
__host__ __device__
inline bool operator!=(pinned_allocator const &x) const { return !operator==(x); }
}; // end pinned_allocator

/*! \}
*/

} // end cudf
4 changes: 2 additions & 2 deletions cpp/src/io/text/bgzip_data_chunk_source.cu
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@
#include <cudf/io/text/detail/bgzip_utils.hpp>
#include <cudf/utilities/default_stream.hpp>
#include <cudf/utilities/error.hpp>
#include <cudf/utilities/pinned_allocator.h>

#include <rmm/cuda_stream_view.hpp>
#include <rmm/device_buffer.hpp>
#include <rmm/exec_policy.hpp>

#include <thrust/host_vector.h>
#include <thrust/iterator/zip_iterator.h>
#include <thrust/system/cuda/experimental/pinned_allocator.h>
#include <thrust/transform.h>

#include <fstream>
Expand Down Expand Up @@ -66,7 +66,7 @@ class bgzip_data_chunk_reader : public data_chunk_reader {
private:
template <typename T>
using pinned_host_vector =
thrust::host_vector<T, thrust::system::cuda::experimental::pinned_allocator<T>>;
thrust::host_vector<T, cudf::pinned_allocator<T>>;

template <typename T>
static void copy_to_device(const pinned_host_vector<T>& host,
Expand Down
4 changes: 2 additions & 2 deletions cpp/src/io/text/data_chunk_source_factories.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@

#include <cudf/detail/nvtx/ranges.hpp>
#include <cudf/io/text/data_chunk_source_factories.hpp>
#include <cudf/utilities/pinned_allocator.h>

#include <rmm/device_buffer.hpp>

#include <thrust/host_vector.h>
#include <thrust/system/cuda/experimental/pinned_allocator.h>

#include <fstream>

Expand All @@ -37,7 +37,7 @@ namespace {
class istream_data_chunk_reader : public data_chunk_reader {
struct host_ticket {
cudaEvent_t event;
thrust::host_vector<char, thrust::system::cuda::experimental::pinned_allocator<char>> buffer;
thrust::host_vector<char, cudf::pinned_allocator<char>> buffer;
};

public:
Expand Down
4 changes: 2 additions & 2 deletions cpp/src/io/utilities/hostdevice_vector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@
#include <cudf/utilities/default_stream.hpp>
#include <cudf/utilities/error.hpp>
#include <cudf/utilities/span.hpp>
#include <cudf/utilities/pinned_allocator.h>

#include <rmm/cuda_stream_view.hpp>
#include <rmm/device_buffer.hpp>

#include <thrust/host_vector.h>
#include <thrust/system/cuda/experimental/pinned_allocator.h>

/**
* @brief A helper class that wraps fixed-length device memory for the GPU, and
Expand Down Expand Up @@ -126,7 +126,7 @@ class hostdevice_vector {
}

private:
thrust::host_vector<T, thrust::system::cuda::experimental::pinned_allocator<T>> h_data;
thrust::host_vector<T, cudf::pinned_allocator<T>> h_data;
rmm::device_uvector<T> d_data;
};

Expand Down

0 comments on commit dc3f7de

Please sign in to comment.