#ifndef KOKKOS_HOSTSPACE_HPP
#define KOKKOS_HOSTSPACE_HPP
#include <cstring>
#include <string>
#include <iosfwd>
#include <typeinfo>
#include <Kokkos_Core_fwd.hpp>
#include <Kokkos_Concepts.hpp>
#include <Kokkos_MemoryTraits.hpp>
#include <impl/Kokkos_Traits.hpp>
#include <impl/Kokkos_Error.hpp>
#include <impl/Kokkos_SharedAlloc.hpp>
#include "impl/Kokkos_HostSpace_deepcopy.hpp"
namespace Kokkos {
namespace Impl {
void init_lock_array_host_space();
bool lock_address_host_space(void* ptr);
void unlock_address_host_space( void* ptr );
}
}
namespace Kokkos {
class HostSpace {
public:
typedef HostSpace memory_space;
typedef size_t size_type;
#if defined( KOKKOS_ENABLE_DEFAULT_DEVICE_TYPE_OPENMP )
typedef Kokkos::OpenMP execution_space;
#elif defined( KOKKOS_ENABLE_DEFAULT_DEVICE_TYPE_THREADS )
typedef Kokkos::Threads execution_space;
#elif defined( KOKKOS_ENABLE_DEFAULT_DEVICE_TYPE_HPX )
typedef Kokkos::Experimental::HPX execution_space;
#elif defined( KOKKOS_ENABLE_OPENMP )
typedef Kokkos::OpenMP execution_space;
#elif defined( KOKKOS_ENABLE_THREADS )
typedef Kokkos::Threads execution_space;
#elif defined( KOKKOS_ENABLE_HPX )
typedef Kokkos::Experimental::HPX execution_space;
#elif defined( KOKKOS_ENABLE_SERIAL )
typedef Kokkos::Serial execution_space;
#else
# error "At least one of the following host execution spaces must be defined: Kokkos::OpenMP, Kokkos::Threads, Kokkos::Qthreads, or Kokkos::Serial. You might be seeing this message if you disabled the Kokkos::Serial device explicitly using the Kokkos_ENABLE_Serial:BOOL=OFF CMake option, but did not enable any of the other host execution space devices."
#endif
typedef Kokkos::Device< execution_space, memory_space > device_type;
HostSpace();
HostSpace( HostSpace && rhs ) = default;
HostSpace( const HostSpace & rhs ) = default;
HostSpace & operator = ( HostSpace && ) = default;
HostSpace & operator = ( const HostSpace & ) = default;
~HostSpace() = default;
enum AllocationMechanism { STD_MALLOC, POSIX_MEMALIGN, POSIX_MMAP, INTEL_MM_ALLOC };
explicit
HostSpace( const AllocationMechanism & );
void * allocate( const size_t arg_alloc_size ) const;
void deallocate( void * const arg_alloc_ptr
, const size_t arg_alloc_size ) const;
static constexpr const char* name() { return m_name; }
private:
AllocationMechanism m_alloc_mech;
static constexpr const char* m_name = "Host";
friend class Kokkos::Impl::SharedAllocationRecord< Kokkos::HostSpace, void >;
};
}
namespace Kokkos {
namespace Impl {
static_assert( Kokkos::Impl::MemorySpaceAccess< Kokkos::HostSpace, Kokkos::HostSpace >::assignable, "" );
template< typename S >
struct HostMirror {
private:
enum { keep_exe = Kokkos::Impl::MemorySpaceAccess
< typename S::execution_space::memory_space, Kokkos::HostSpace >::accessible };
enum { keep_mem = Kokkos::Impl::MemorySpaceAccess
< Kokkos::HostSpace, typename S::memory_space >::accessible };
public:
typedef typename std::conditional
< keep_exe && keep_mem
, S
, typename std::conditional
< keep_mem
, Kokkos::Device< Kokkos::HostSpace::execution_space
, typename S::memory_space >
, Kokkos::HostSpace
>::type
>::type Space;
};
}
}
namespace Kokkos {
namespace Impl {
template<>
class SharedAllocationRecord< Kokkos::HostSpace, void >
: public SharedAllocationRecord< void, void >
{
private:
friend Kokkos::HostSpace;
typedef SharedAllocationRecord< void, void > RecordBase;
SharedAllocationRecord( const SharedAllocationRecord & ) = delete;
SharedAllocationRecord & operator = ( const SharedAllocationRecord & ) = delete;
static void deallocate( RecordBase * );
#ifdef KOKKOS_DEBUG
static RecordBase s_root_record;
#endif
const Kokkos::HostSpace m_space;
protected:
~SharedAllocationRecord();
SharedAllocationRecord() = default;
SharedAllocationRecord( const Kokkos::HostSpace & arg_space
, const std::string & arg_label
, const size_t arg_alloc_size
, const RecordBase::function_type arg_dealloc = & deallocate
);
public:
inline
std::string get_label() const
{
return std::string( RecordBase::head()->m_label );
}
KOKKOS_INLINE_FUNCTION static
SharedAllocationRecord * allocate( const Kokkos::HostSpace & arg_space
, const std::string & arg_label
, const size_t arg_alloc_size
)
{
#if defined( KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST )
return new SharedAllocationRecord( arg_space, arg_label, arg_alloc_size );
#else
return (SharedAllocationRecord *) 0;
#endif
}
static
void * allocate_tracked( const Kokkos::HostSpace & arg_space
, const std::string & arg_label
, const size_t arg_alloc_size );
static
void * reallocate_tracked( void * const arg_alloc_ptr
, const size_t arg_alloc_size );
static
void deallocate_tracked( void * const arg_alloc_ptr );
static SharedAllocationRecord * get_record( void * arg_alloc_ptr );
static void print_records( std::ostream &, const Kokkos::HostSpace &, bool detail = false );
};
}
}
namespace Kokkos {
namespace Impl {
#define PAR_DEEP_COPY_USE_MEMCPY
template< class ExecutionSpace >
struct DeepCopy< HostSpace, HostSpace, ExecutionSpace > {
DeepCopy( void * dst, const void * src, size_t n ) {
hostspace_parallel_deepcopy(dst,src,n);
}
DeepCopy( const ExecutionSpace& exec, void * dst, const void * src, size_t n ) {
exec.fence();
hostspace_parallel_deepcopy(dst,src,n);
exec.fence();
}
};
}
}
#endif