#ifndef KOKKOS_HBWSPACE_HPP
#define KOKKOS_HBWSPACE_HPP
#include <Kokkos_Macros.hpp>
#ifdef KOKKOS_ENABLE_HBWSPACE
#include <Kokkos_HostSpace.hpp>
namespace Kokkos {
namespace Experimental {
namespace Impl {
void init_lock_array_hbw_space();
bool lock_address_hbw_space( void* ptr );
void unlock_address_hbw_space( void* ptr );
}
}
}
namespace Kokkos {
namespace Experimental {
class HBWSpace {
public:
typedef HBWSpace 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_OPENMP )
typedef Kokkos::OpenMP execution_space;
#elif defined( KOKKOS_ENABLE_THREADS )
typedef Kokkos::Threads 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::Qhreads, 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;
HBWSpace();
HBWSpace( const HBWSpace & rhs ) = default;
HBWSpace & operator = ( const HBWSpace & ) = default;
~HBWSpace() = default;
enum AllocationMechanism { STD_MALLOC, POSIX_MEMALIGN, POSIX_MMAP, INTEL_MM_ALLOC };
explicit
HBWSpace( 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 "HBW"; }
private:
AllocationMechanism m_alloc_mech;
friend class Kokkos::Impl::SharedAllocationRecord< Kokkos::Experimental::HBWSpace, void >;
};
}
}
namespace Kokkos {
namespace Impl {
template<>
class SharedAllocationRecord< Kokkos::Experimental::HBWSpace, void >
: public SharedAllocationRecord< void, void >
{
private:
friend Kokkos::Experimental::HBWSpace;
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::Experimental::HBWSpace m_space;
protected:
~SharedAllocationRecord();
SharedAllocationRecord() = default;
SharedAllocationRecord( const Kokkos::Experimental::HBWSpace & 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::Experimental::HBWSpace & 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::Experimental::HBWSpace & 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::Experimental::HBWSpace &, bool detail = false );
};
}
}
namespace Kokkos {
namespace Impl {
static_assert( Kokkos::Impl::MemorySpaceAccess< Kokkos::Experimental::HBWSpace, Kokkos::Experimental::HBWSpace >::assignable, "" );
template<>
struct MemorySpaceAccess< Kokkos::HostSpace, Kokkos::Experimental::HBWSpace > {
enum { assignable = true };
enum { accessible = true };
enum { deepcopy = true };
};
template<>
struct MemorySpaceAccess< Kokkos::Experimental::HBWSpace, Kokkos::HostSpace > {
enum { assignable = false };
enum { accessible = true };
enum { deepcopy = true };
};
}
}
namespace Kokkos {
namespace Impl {
template< class ExecutionSpace >
struct DeepCopy< Experimental::HBWSpace, Experimental::HBWSpace, ExecutionSpace > {
DeepCopy( void * dst, const void * src, size_t n ) {
memcpy( dst, src, n );
}
DeepCopy( const ExecutionSpace& exec, void * dst, const void * src, size_t n ) {
exec.fence();
memcpy( dst, src, n );
}
};
template< class ExecutionSpace >
struct DeepCopy< HostSpace, Experimental::HBWSpace, ExecutionSpace > {
DeepCopy( void * dst, const void * src, size_t n ) {
memcpy( dst, src, n );
}
DeepCopy( const ExecutionSpace& exec, void * dst, const void * src, size_t n ) {
exec.fence();
memcpy( dst, src, n );
}
};
template< class ExecutionSpace >
struct DeepCopy< Experimental::HBWSpace, HostSpace, ExecutionSpace > {
DeepCopy( void * dst, const void * src, size_t n ) {
memcpy( dst, src, n );
}
DeepCopy( const ExecutionSpace& exec, void * dst, const void * src, size_t n ) {
exec.fence();
memcpy( dst, src, n );
}
};
}
}
namespace Kokkos {
namespace Impl {
template<>
struct VerifyExecutionCanAccessMemorySpace< Kokkos::HostSpace, Kokkos::Experimental::HBWSpace >
{
enum { value = true };
inline static void verify( void ) { }
inline static void verify( const void * ) { }
};
template<>
struct VerifyExecutionCanAccessMemorySpace< Kokkos::Experimental::HBWSpace, Kokkos::HostSpace >
{
enum { value = true };
inline static void verify( void ) { }
inline static void verify( const void * ) { }
};
}
}
#endif
#endif