Commit 18cf685f authored by incardon's avatar incardon

Fix OpenFPM_data to compile with the new OpenFPM_devices concept

parent 266f95f5
SUBDIRS = src
bin_PROGRAMS =
\ No newline at end of file
This diff is collapsed.
......@@ -23,6 +23,7 @@ m4_ifdef([AX_CUDA],,[m4_include([m4/ax_cuda.m4])])
CXXFLAGS+=" --std=c++11 "
NVCCFLAGS=" "
INCLUDES_PATH=" "
# Checks for programs.
AC_PROG_CXX
......@@ -60,6 +61,10 @@ else
NVCCFLAGS+="$NVCCFLAGS -O3 "
fi
####### include OpenFPM_devices include path
INCLUDES_PATH+="-I. -I../../OpenFPM_devices/src"
####### Checking for GPU support
AX_CUDA
......@@ -105,6 +110,7 @@ AX_CHECK_COMPILER_FLAGS([-mmmx],[CXXFLAGS="$CXXFLAGS -mmmx"],[no_mmx=yes])
AX_CHECK_COMPILER_FLAGS([-Wno-unused-but-set-variable],[CXXFLAGS="$CXXFLAGS -Wno-unused-but-set-variable"],[])
AC_SUBST(NVCCFLAGS)
AC_SUBST(INCLUDES_PATH)
# Checks for typedefs, structures, and compiler characteristics.
......
......@@ -2,10 +2,10 @@
LINKLIBS = $(PTHREAD_LIBS) $(OPT_LIBS) $(BOOST_LDFLAGS) $(BOOST_PROGRAM_OPTIONS_LIB) $(CUDA_LIBS) $(BOOST_THREAD_LIB)
bin_PROGRAMS = mem_map
mem_map_SOURCES = main.cpp
mem_map_CXXFLAGS = $(CUDA_CFLAGS)
mem_map_SOURCES = main.cpp ../../OpenFPM_devices/src/memory/CudaMemory.cu
mem_map_CXXFLAGS = $(CUDA_CFLAGS) $(INCLUDES_PATH)
mem_map_CFLAGS = $(CUDA_CFLAGS)
mem_map_LDADD = $(LINKLIBS) -L/usr/lib64/nvidia-bumblebee/
.cu.o :
$(NVCC) $(NVCCFLAGS) -o $@ -c $<
$(NVCC) $(NVCCFLAGS) $(INCLUDES_PATH) -o $@ -c $<
......@@ -3,6 +3,7 @@
#include <vector>
#include <initializer_list>
#include <array>
#include "memory.hpp"
#define HARDWARE 1
......
#define BOOST_DISABLE_ASSERTS
#include "map.hpp"
#include "memory_cpu.hpp"
#include "memory_gpu.hpp"
#include "Particle.hpp"
#include <boost/mpl/int.hpp>
#include <typeinfo>
#include <test_1.hpp>
#include <test_2.hpp>
#include <ct_array.hpp>
#include "memory/CudaMemory.cuh"
//#include <test_3.hpp>
//#include <test_4.hpp>
//#include <test_5.hpp>
#include "memory_gpu_thrust.hpp"
/*float Wi(float dist_x)
{
......@@ -23,6 +23,7 @@
return 0.0;
}*/
int main()
{
/* tensor<int,3,3,3> c;
......@@ -33,8 +34,8 @@ int main()
sz.push_back(GS_SIZE);
sz.push_back(GS_SIZE);
grid_gpu<3, Point<float>, memory_gpu<memory_gpu_type<Point<float>>::type> > c3(sz);
grid_gpu<3, Point<float>, memory_gpu_type<Point<float>>::type > c3(sz);
c3.setMemory<CudaMemory>();
// cpu test
......
//! Warning: apparently you cannot used nested boost::mpl with boost::fusion
//! can create template circularity, this include avoid the problem
#include <boost/fusion/include/mpl.hpp>
#include <boost/fusion/sequence/intrinsic/at_c.hpp>
#include <boost/fusion/include/at_c.hpp>
#include <boost/fusion/include/for_each.hpp>
......@@ -6,13 +10,13 @@
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/container/vector/vector_fwd.hpp>
#include <boost/fusion/include/vector_fwd.hpp>
#include <boost/type_traits.hpp>
#include "grid.hpp"
#include "Particle.hpp"
#include "Point.hpp"
#include "memory_cpu.hpp"
#include "memory_gpu.hpp"
#include "memory_array.hpp"
#include "memory_c.hpp"
#ifndef MAP_HPP_
#define MAP_HPP_
......@@ -20,10 +24,16 @@
// Compiled based specialization
template<typename T>
struct mem_reference
{
typedef T& type;
};
template<unsigned int p>
struct Point_type_cpu_prop
{
typedef typename boost::fusion::result_of::at<memory_cpu_type<Point<float>>::rtype,boost::mpl::int_<p> >::type type;
typedef typename boost::fusion::result_of::at<memory_cpu_type<Point<float>>::rtype,boost::mpl::int_<p> >::type type;
};
/*!
......@@ -103,97 +113,26 @@ class grid_cpu
}
};
/*template<unsigned int dim, typename T>
class layout_cpu<Particles<dim,Point<T>,memory_cpu<T>>,part_key>
{
grid<Point<T>,memory_cpu<Point<T>>> * g1;
public:
layout_cpu(std::vector<size_t> sz)
{
g1 = new grid<Point<T>,memory_cpu<Point<T>>>(sz);
}
inline Point<T> & get(grid_key & v1)
{
return g1->get(v1);
}
inline size_t size()
{
return g1->size();
}
};*/
/*template<typename T>
class layout_cpu<grid<tensor<T>,memory_cpu<T>>,grid_key>
{
grid<Point<T>,memory_cpu<T>> & g1;
layout_cpu(grid<Point<T>,memory_cpu<T>> & g1)
: g1(g1)
{
}
inline Point<T> get(grid_key & v1)
{
return g1.get(v1);
}
inline size_t size()
{
g1.size();
}
};*/
/*template<>
map_cpu<grid<grid<Point>>>
{
grid & g1;
grid & g2;
map(grid & g1, grid & g2)
: g1(g1), g2(g2)
{
}
inline map_id <unsigned int p>get(key & v1, key & v2)
{
return g1.idx(v1)*g2.size()+g2.idx(v2)*sizeof(Point);
}
inline map_id <>
{
}
}*/
// nested_struct
/*template<typename S, typename T>
struct nested_struct
{
typedef typename boost::fusion::result_of::pop_back<T>::type popv;
nested_struct< S, popv > ggn;
S gn;
};
template<typename S>
struct nested_struct<S,boost::fusion::vector<>>
{
nested_struct< S, boost::fusion::result_of::pop_back<T>::type > ggn;
S<boost::fusion::result_of::end<T>> gn;
};*/
/*! \brief This class is an helper to get the return type of get for each property
*
* This class is an helper to get the return type of get for each property
*
* \param p id of the property
* \param T original boost fusion vector, T is suppose to be a boost::fusion::vector<memory_c<...>,.....>
*
*/
template<unsigned int p,typename T>
struct type_gpu_prop
{
typedef typename memory_gpu_type<T>::rtype vtype;
typedef typename boost::fusion::result_of::at< vtype,boost::mpl::int_<p> >::type type;
//! return a boost::fusion::vector<memory_c<....>....>
typedef typename memory_gpu_type<T>::type vtype;
//! return a memory_c<...>
typedef typename boost::fusion::result_of::at< vtype,boost::mpl::int_<p> >::type rtype;
//! remove the reference
typedef typename boost::remove_reference<rtype>::type mtype;
//! get the base type that the buffer is storing
typedef typename mtype::type type;
};
/*! \brief this class is a functor for "for_each" algorithm
......@@ -201,20 +140,29 @@ struct type_gpu_prop
* This class is a functor for "for_each" algorithm. For each
* element of the boost::vector the operator() is called
*
* \param T Type of memory allocator
*
*/
template<typename S>
struct allocate
{
//! size to allocate
size_t sz;
//! constructor it fix the size
allocate(size_t sz)
:sz(sz){};
//! It call the allocate function for each member
template<typename T>
void operator()(T& t) const
{
t.mem.allocate(sz*sizeof(t.mem_r::type));
t.mem_r.set_pointer(t.mem.getPointer());
//! Create and set the memory allocator
t.setMemory(*new S());
//! Allocate the memory and create the reppresentation
t.allocate(sz);
}
};
......@@ -224,9 +172,9 @@ class grid_gpu
//! It store all the information regarding the grid
grid<dim,void> g1;
//! This is the interface to allocate an resize memory
//! This is the interface to allocate,resize ... memory
//! and give also a representation to the allocated memory
typename Mem::type data;
Mem data;
public:
......@@ -234,7 +182,22 @@ class grid_gpu
grid_gpu(std::vector<size_t> & sz)
:g1(sz)
{
for_each(data,allocate(g1.size()));
}
/*! \brief Create the object that provide memory
*
* Create the object that provide memory
*
* \param T memory
*
*/
template<typename S> void setMemory()
{
//! Create an allocate object
allocate<S> all(g1.size());
for_each(data,all);
}
/* template <unsigned int p>inline typename mem_reference<typename type_gpu_prop<p,T>::type>::type get(grid_key<p> & v1)
......@@ -262,14 +225,19 @@ class grid_gpu
return boost::fusion::at_c<p>(data).get(g1.LinId(v1.k[3],v1.k[2],v1.k[1],v1.k[0]));
}*/
template <unsigned int p>inline typename mem_reference<typename type_gpu_prop<p,T>::type >::type get(grid_key_d<dim,p> & v1)
template <unsigned int p>inline typename type_gpu_prop<p,T>::reference get(grid_key_d<dim,p> & v1)
{
return boost::fusion::at_c<p>(data).mem_r->operator[](g1.LinId(v1));
}
template <unsigned int p>inline typename type_gpu_prop<p,T>::type::reference get(grid_key_dx<dim> & v1)
{
return boost::fusion::at_c<p>(data.mem_r).get(g1.LinId(v1));
return boost::fusion::at_c<p>(data).mem_r->operator[](g1.LinId(v1));
}
template <unsigned int p>inline typename mem_reference<typename type_gpu_prop<p,T>::type >::type get(grid_key_dx<dim> & v1)
template <unsigned int p>inline typename type_gpu_prop<p,T>::type diocane(grid_key_dx<dim> & v1)
{
return boost::fusion::at_c<p>(data.mem_r).get(g1.LinId(v1));
return boost::fusion::at_c<p>(data).mem_r->operator[](g1.LinId(v1));
}
inline size_t size()
......@@ -286,12 +254,6 @@ class grid_gpu
}
};
#ifdef GPU
use template<unsigned int n, typename T>grid_gpu<n,T> grid<n,T>
#else CPU
#endif
#endif
......@@ -11,12 +11,17 @@
*
*/
#ifndef MEMORY_HPP_
#define MEMORY_HPP_
typedef long int mem_id;
#include <stddef.h>
class memory
{
public:
/*! \brief allocate on device a buffer of
*
* Allocate on the device a buffer of memory
......@@ -76,3 +81,5 @@ class memory
*/
~memory() {};
};
#endif
......@@ -5,6 +5,8 @@
* Author: Pietro Incardona
*/
#include <memory.hpp>
/*!
*
* \brief This class give a representation to a chunk or memory
......@@ -15,15 +17,11 @@
*
*/
#include <memory.hpp>
template<typename T>
class memory_array
{
//! Internal pointer
T * ptr;
memory_array(void * ptr)
: ptr(ptr)
{};
//! return the i element
T get(mem_id i)
......@@ -31,11 +29,27 @@ class memory_array
return ptr[i];
}
public:
//! Set the internal pointer to the indicated chunk of memory
void set_pointer(void * ptr_)
{
ptr = ptr_;
ptr = static_cast<T *>(ptr_);
}
//! operator[]
T & operator[](mem_id i)
{
return ptr[i];
}
//! Default constructor
memory_array() {};
//! Constructor
memory_array(void * ptr)
: ptr(static_cast<T *>(ptr))
{};
};
......
......@@ -5,6 +5,13 @@
* Author: Pietro Incardona
*/
#include <boost/multi_array.hpp>
#include <array>
#include "ct_array.hpp"
#ifndef MEMORY_C_HPP_
#define MEMORY_C_HPP_
/*!
* \brief This class is a container for the memory interface
*
......@@ -18,32 +25,244 @@
*
*/
template<typename T, typename D = void *>
template<typename T, typename D = memory>
class memory_c
{
public:
//! define T
typedef memory_c<T> type;
//! define a reference to T
typedef T& reference;
//! compile time specialization object that allocate memory
D mem;
D * mem;
//! object that represent the memory as an array of objects T
memory_array<T> mem_r;
memory_array<T> * mem_r;
/*! \brief This function set the object that allocate memory
*
* This object set the object that allocate memory
*
* \param the memory object
*
*/
void setMemory(memory & mem)
{
this->mem = &mem;
}
/*! \brief This function allocate memory and associate the representation to mem_r
*
* This function allocate memory and associate the representation of that chunk of
* memory to mem_r
*
*/
bool allocate(const size_t sz)
{
memory * mem = this->mem;
//! We create a chunk of memory
mem->resize( sz*sizeof(T) );
//! we create the representation for this buffer
mem_r = new memory_array<T>(mem->getPointer());
return true;
}
//! constructor
memory_c(){}
};
/*! \brief This class is a trick to indicate the compiler a specific
* specialization pattern
*
* This class is a trick to indicate the compiler a specific specialization
* pattern, in particular it say that T is a multidimensional array and
* need a special treatment, T is suppose to be a boost::mpl::vector of
* unsigned int indicating each dimension. T has to be a type of known size at
* compile time
*
*/
template<typename T>
class memory_c<typename T,void *>
class multi_array
{
//! Reference to an object to allocate memory
memory & mem;
typedef T type;
};
//! object that represent the memory as an array of objects T
memory_array<T> mem_r
/*! \brief This class is a trick to indicate the compiler a specific
* specialization pattern
*
* This class is a trick to indicate the compiler a specific specialization
* pattern, in particular it say that T is a key and
* need a special treatment. T is suppose to be a boost::mpl::vector of
* any type, (Actually does not have an application but is a generalization
* of multi-array). T has to be a type of known size at compile time
*
*/
template<typename T>
class key
{
typedef T type;
};
/*! \brief this class multiply all the unsigned element in a boost::mpl::vector
*
* this class multiply all the unsigned element in a boost::mpl::vector excluding
* the first element
*
* \param T expecting a boost::mpl::vector
*
*/
template<typename T, unsigned int N>
struct mult
{
enum { value = mult<T,N-1>::value * boost::mpl::at<T,boost::mpl::int_<N>>::type::value };
};
template <typename T>
struct mult<T,1>
{
enum { value = boost::mpl::at<T,boost::mpl::int_<1>>::type::value };
};
/*! \brief Specialization of memory_c for multi_array
*
* Specialization of memory_c for multi_array
*
* \param T is suppose to be a boost::mpl::vector specifing at position 0 the type and at
* position 1 to N the dimensions size of the multi_array
*
*/
template<typename T>
class memory_c<multi_array<T>, memory>
{
//! define T
// typedef T type;
//! define boost::mpl::int_ without boost::mpl
template<int S> using int_ = boost::mpl::int_<S>;
//! define the template vector size it give a number at compile time
typedef typename boost::mpl::size<T> size_p;
//! Define "at" meta function without boost::mpl
template< typename S, unsigned int n> using at = boost::mpl::at<S,boost::mpl::int_<n> >;
typedef typename at<T,0>::type base;
//! define size_type
typedef typename boost::multi_array_ref<base,size_p::value>::size_type size_type;
/*! \brief In combination with generate_array is used to produce array at compile-time
*
* In combination with generate_array is used to produce at compile-time
* arrays like {0,N-1,.........0} used in boost::multi_array for index ordering
*
*/
template<size_t index,size_t N> struct ordering
{
enum { value = (N-index) % N };
};
public:
/*! \brief This function set the object that allocate memory
*
* This object set the object that allocate memory
*
* \param the memory object
*
*/
void setMemory(memory & mem)
{
this->mem = &mem;
}
/*! \brief This function allocate memory and associate the representation to mem_r
*
* This function allocate memory and associate the representation of that chunk of
* memory to mem_r
*
*/
bool allocate(const size_t sz)
{
memory * mem = this->mem;
//! We create a chunk of memory
mem->resize( sz*mult<T,size_p::value-1>::value*sizeof(base) );
// We create an array dims from the boost::mpl::vector
typedef typename generate_array_dims<T>::result dims;
//! we define the dimension of the full multi_array buffer
boost::array<size_type ,size_p::value> dimensions = {sz,{dims::data}};
std::cout << "Dimensions \n";
for (int i = 0; i < size_p::value ; i++)
{
std::cout << dimensions[i] << " ";
}
//! we generate the ordering buffer ord::data = {0,N-1 ...... 1 }
typedef typename generate_array<size_p::value, ordering>::result ord;
//! we define the index ordering
const typename boost::multi_array<T,size_p::value>::size_type ordering[size_p::value] = {*ord::data};
std::cout << "Ordering \n";
for (int i = 0; i < size_p::value ; i++)
{
std::cout << dimensions[i] << " ";
}
//! we define the ascending order
bool ascending[] = {true,true,true,true,true,true};
//! we create the representation for this buffer
mem_r = new boost::multi_array_ref<base,size_p::value>(static_cast<base *>(mem->getPointer()),dimensions,boost::general_storage_order<size_p::value>(ordering,ascending));
return true;
}
//! define the type of the multi_array vector minus one of the original size
//! basically we remove the index 0 of the multi_array