mirror of
https://github.com/GOSTSec/ccminer
synced 2025-01-09 22:38:05 +00:00
240 lines
6.4 KiB
C++
240 lines
6.4 KiB
C++
/*
|
|
* Copyright 2008-2012 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 thrust
|
|
{
|
|
|
|
namespace system
|
|
{
|
|
|
|
namespace cuda
|
|
{
|
|
|
|
namespace experimental
|
|
{
|
|
|
|
/*! \addtogroup memory_management Memory Management
|
|
* \addtogroup memory_management_classes
|
|
* \ingroup memory_management
|
|
* \{
|
|
*/
|
|
|
|
/*! \p pinned_allocator is a CUDA-specific host memory allocator
|
|
* that employs \c cudaMallocHost for allocation.
|
|
*
|
|
* \see http://www.sgi.com/tech/stl/Allocators.html
|
|
*/
|
|
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)
|
|
{
|
|
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);
|
|
|
|
if(error)
|
|
{
|
|
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) { 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) { return !operator==(x); }
|
|
}; // end pinned_allocator
|
|
|
|
/*! \}
|
|
*/
|
|
|
|
} // end experimental
|
|
|
|
} // end cuda
|
|
|
|
} // end system
|
|
|
|
// alias cuda's members at top-level
|
|
namespace cuda
|
|
{
|
|
|
|
namespace experimental
|
|
{
|
|
|
|
using thrust::system::cuda::experimental::pinned_allocator;
|
|
|
|
} // end experimental
|
|
|
|
} // end cuda
|
|
|
|
} // end thrust
|
|
|