Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port thrust's pinned_allocator to cudf, since Thrust 1.17 removes the type #12004

Merged
Show file tree
Hide file tree
Changes from 2 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
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 @@
/*
robertmaynard marked this conversation as resolved.
Show resolved Hide resolved
* 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;
robertmaynard marked this conversation as resolved.
Show resolved Hide resolved

// convert a pinned_allocator<void> to pinned_allocator<U>
template<typename U>
struct rebind
{
typedef pinned_allocator<U> other;
}; // end rebind
robertmaynard marked this conversation as resolved.
Show resolved Hide resolved
}; // end pinned_allocator
robertmaynard marked this conversation as resolved.
Show resolved Hide resolved


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;
robertmaynard marked this conversation as resolved.
Show resolved Hide resolved
//! \}

// 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/include/cudf/utilities/span.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ struct host_span : public cudf::detail::span_base<T, Extent, host_span<T, Extent
std::is_convertible_v<std::remove_pointer_t<decltype(thrust::raw_pointer_cast(
std::declval<C&>().data()))> (*)[],
T (*)[]>>* = nullptr>
constexpr host_span(C& in) : base(in.data(), in.size())
constexpr host_span(C& in) : base(thrust::raw_pointer_cast(in.data()), in.size())
{
}

Expand All @@ -239,7 +239,7 @@ struct host_span : public cudf::detail::span_base<T, Extent, host_span<T, Extent
std::is_convertible_v<std::remove_pointer_t<decltype(thrust::raw_pointer_cast(
std::declval<C&>().data()))> (*)[],
T (*)[]>>* = nullptr>
constexpr host_span(C const& in) : base(in.data(), in.size())
constexpr host_span(C const& in) : base(thrust::raw_pointer_cast(in.data()), in.size())
{
}

Expand Down
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