1
0
mirror of https://github.com/paboyle/Grid.git synced 2024-11-14 01:35:36 +00:00
Grid/lib/AlignedAllocator.h

151 lines
4.1 KiB
C
Raw Normal View History

/*************************************************************************************
Grid physics library, www.github.com/paboyle/Grid
Source file: ./lib/AlignedAllocator.h
Copyright (C) 2015
Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk>
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
See the full license in the file "LICENSE" in the top level distribution directory
*************************************************************************************/
/* END LEGAL */
2015-03-04 05:31:44 +00:00
#ifndef GRID_ALIGNED_ALLOCATOR_H
#define GRID_ALIGNED_ALLOCATOR_H
#ifdef HAVE_MALLOC_MALLOC_H
#include <malloc/malloc.h>
#endif
#ifdef HAVE_MALLOC_H
#include <malloc.h>
#endif
2015-05-15 11:32:11 +01:00
#ifdef HAVE_MM_MALLOC_H
#include <mm_malloc.h>
#endif
2016-02-11 13:37:39 +00:00
#ifdef GRID_COMMS_SHMEM
extern "C" {
2016-02-11 13:37:39 +00:00
#include <mpp/shmem.h>
extern void * shmem_align(size_t, size_t);
extern void shmem_free(void *);
}
2016-02-11 13:37:39 +00:00
#endif
2015-04-03 05:29:54 +01:00
namespace Grid {
2015-03-04 05:31:44 +00:00
////////////////////////////////////////////////////////////////////
// A lattice of something, but assume the something is SIMDized.
////////////////////////////////////////////////////////////////////
template<typename _Tp>
class alignedAllocator {
public:
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef _Tp* pointer;
typedef const _Tp* const_pointer;
typedef _Tp& reference;
typedef const _Tp& const_reference;
typedef _Tp value_type;
template<typename _Tp1> struct rebind { typedef alignedAllocator<_Tp1> other; };
2015-03-04 05:31:44 +00:00
alignedAllocator() throw() { }
2015-03-04 05:31:44 +00:00
alignedAllocator(const alignedAllocator&) throw() { }
2015-03-04 05:31:44 +00:00
template<typename _Tp1> alignedAllocator(const alignedAllocator<_Tp1>&) throw() { }
2015-03-04 05:31:44 +00:00
~alignedAllocator() throw() { }
pointer address(reference __x) const { return &__x; }
2015-06-14 00:48:41 +01:00
// const_pointer address(const_reference __x) const { return &__x; }
2015-03-04 05:31:44 +00:00
size_type max_size() const throw() { return size_t(-1) / sizeof(_Tp); }
pointer allocate(size_type __n, const void* _p= 0)
2015-03-04 05:31:44 +00:00
{
2016-02-11 13:37:39 +00:00
#ifdef GRID_COMMS_SHMEM
_Tp *ptr = (_Tp *) shmem_align(__n*sizeof(_Tp),64);
#define PARANOID_SYMMETRIC_HEAP
#ifdef PARANOID_SYMMETRIC_HEAP
2016-02-11 13:37:39 +00:00
static void * bcast;
static long psync[_SHMEM_REDUCE_SYNC_SIZE];
bcast = (void *) ptr;
2016-02-11 13:37:39 +00:00
shmem_broadcast32((void *)&bcast,(void *)&bcast,sizeof(void *)/4,0,0,0,shmem_n_pes(),psync);
if ( bcast != ptr ) {
std::printf("inconsistent alloc pe %d %lx %lx \n",shmem_my_pe(),bcast,ptr);std::fflush(stdout);
BACKTRACEFILE();
exit(0);
}
assert( bcast == (void *) ptr);
#endif
2016-02-11 13:37:39 +00:00
#else
2015-05-15 11:32:11 +01:00
#ifdef HAVE_MM_MALLOC_H
2015-03-04 05:31:44 +00:00
_Tp * ptr = (_Tp *) _mm_malloc(__n*sizeof(_Tp),128);
2015-05-15 11:32:11 +01:00
#else
_Tp * ptr = (_Tp *) memalign(128,__n*sizeof(_Tp));
2016-02-11 13:37:39 +00:00
#endif
2015-03-04 05:31:44 +00:00
#endif
_Tp tmp;
#undef FIRST_TOUCH_OPTIMISE
#ifdef FIRST_TOUCH_OPTIMISE
#pragma omp parallel for
for(int i=0;i<__n;i++){
ptr[i]=tmp;
}
#endif
2015-03-04 05:31:44 +00:00
return ptr;
}
2015-03-04 05:31:44 +00:00
void deallocate(pointer __p, size_type) {
2016-02-11 13:37:39 +00:00
#ifdef GRID_COMMS_SHMEM
shmem_free((void *)__p);
#else
2015-05-15 11:32:11 +01:00
#ifdef HAVE_MM_MALLOC_H
2015-06-16 14:04:33 +01:00
_mm_free((void *)__p);
2015-05-15 11:32:11 +01:00
#else
2015-06-16 14:04:33 +01:00
free((void *)__p);
2016-02-11 13:37:39 +00:00
#endif
2015-05-15 11:32:11 +01:00
#endif
2015-03-04 05:31:44 +00:00
}
void construct(pointer __p, const _Tp& __val) { };
void construct(pointer __p) { };
2015-03-04 05:31:44 +00:00
void destroy(pointer __p) { };
};
template<typename _Tp> inline bool
operator==(const alignedAllocator<_Tp>&, const alignedAllocator<_Tp>&){ return true; }
template<typename _Tp> inline bool
operator!=(const alignedAllocator<_Tp>&, const alignedAllocator<_Tp>&){ return false; }
2015-04-03 05:29:54 +01:00
}; // namespace Grid
2015-03-04 05:31:44 +00:00
#endif