Commit 9fa3b84a authored by incardon's avatar incardon

Adding test for memory_conf + GPU packer

parent 6f81e335
......@@ -293,8 +293,6 @@ if test x$gpu_support = x"no"; then
CUDA_CFLAGS=""
fi
AC_SUBST(NVCCFLAGS)
AM_CONDITIONAL(BUILDCUDA, test x$gpu_support = x"yes")
##### CHECK FOR BOOST ##############
......
......@@ -472,6 +472,9 @@ public:
//! original object type
typedef T T_type;
//! number of properties
static const int max_prop = T::max_prop;
//! constructor require a key and a memory data
encapc(typename memory_traits_inte<T>::type & data, size_t k)
:data(data),k(k)
......
......@@ -225,4 +225,49 @@ struct mem_swap<T,layout,data_type,grid_type,1>
}
};
template<typename data_type, typename layout, unsigned int sel = 2*is_layout_mlin<layout>::value + is_layout_inte<layout>::value>
struct mem_getpointer
{
template<unsigned int d> static void * getPointer(data_type & data_)
{
return data_.mem_r.get_pointer();
}
};
template<typename data_type, typename layout>
struct mem_getpointer<data_type,layout,1>
{
template<unsigned int p> static void * getPointer(data_type & data_)
{
return boost::fusion::at_c<p>(data_).mem_r.get_pointer();
}
};
template<typename data_type, typename Mem_type, typename layout, unsigned int sel = 2*is_layout_mlin<layout>::value + is_layout_inte<layout>::value>
struct mem_setmemory
{
template<unsigned int d> static void setMemory(data_type & data_, Mem_type & m, size_t sz)
{
//! Create and set the memory allocator
data_.setMemory(m);
//! Allocate the memory and create the reppresentation
if (sz != 0) data_.allocate(sz);
}
};
template<typename data_type, typename Mem_type, typename layout>
struct mem_setmemory<data_type,Mem_type,layout,1>
{
template<unsigned int p> static void setMemory(data_type & data_, Mem_type & m, size_t sz)
{
//! Create and set the memory allocator
boost::fusion::at_c<p>(data_).setMemory(m);
//! Allocate the memory and create the reppresentation
if (sz != 0) boost::fusion::at_c<p>(data_).allocate(sz);
}
};
#endif /* OPENFPM_DATA_SRC_GRID_GRID_BASE_IMPL_LAYOUT_HPP_ */
......@@ -86,6 +86,9 @@ public:
//! boost::vector that describe the data type
typedef typename T::type T_type;
//! base layout type
typedef layout_base<T> layout_base_;
protected:
//! Memory layout specification + memory chunk pointer
......@@ -487,8 +490,7 @@ public:
* \param m external memory allocator
*
*/
void setMemory(S & m)
template<unsigned int p = 0> void setMemory(S & m)
{
#ifdef SE_CLASS2
check_valid(this,8);
......@@ -497,10 +499,12 @@ public:
isExternal = true;
//! Create and set the memory allocator
data_.setMemory(m);
// data_.setMemory(m);
//! Allocate the memory and create the reppresentation
if (g1.size() != 0) data_.allocate(g1.size());
// if (g1.size() != 0) data_.allocate(g1.size());
mem_setmemory<decltype(data_),S,layout_base<T>>::template setMemory<p>(data_,m,g1.size());
is_mem_init = true;
}
......@@ -513,13 +517,13 @@ public:
*
*/
void * getPointer()
template<unsigned int p = 0> void * getPointer()
{
#ifdef SE_CLASS2
check_valid(this,8);
#endif
return data_.mem_r.get_pointer();
return mem_getpointer<decltype(data_),layout_base_>::template getPointer<p>(data_);
}
/*! \brief Return a plain pointer to the internal data
......@@ -530,13 +534,13 @@ public:
*
*/
const void * getPointer() const
template<unsigned int p = 0> const void * getPointer() const
{
#ifdef SE_CLASS2
check_valid(this,8);
#endif
return data_.mem_r.get_pointer();
return mem_getpointer<decltype(data_),layout_base_>::template getPointer<p>(data_);
}
/*! \brief Get the reference of the selected element
......
......@@ -10,8 +10,8 @@ else
endif
noinst_PROGRAMS = mem_map
mem_map_SOURCES = ../../openfpm_devices/src/Memleak_check.cpp main.cpp util/multi_array_openfpm/multi_array_ref_openfpm_unit_test.cpp Grid/gpu_test/cuda_gpu_func.cpp $(CUDA_SOURCES) ../../openfpm_devices/src/memory/HeapMemory.cpp ../../openfpm_devices/src/memory/PtrMemory.cpp
mem_map_CXXFLAGS = $(AM_CXXFLAGS) $(LIBHILBERT_INCLUDE) $(CUDA_CFLAGS) $(INCLUDES_PATH) $(BOOST_CPPFLAGS) -I/usr/local/include -I/usr/local/libhilbert/include
mem_map_SOURCES = ../../openfpm_devices/src/Memleak_check.cpp memory_ly/memory_conf_unit_tests.cpp main.cpp util/multi_array_openfpm/multi_array_ref_openfpm_unit_test.cpp Grid/gpu_test/cuda_gpu_func.cpp $(CUDA_SOURCES) ../../openfpm_devices/src/memory/HeapMemory.cpp ../../openfpm_devices/src/memory/PtrMemory.cpp
mem_map_CXXFLAGS = $(AM_CXXFLAGS) $(LIBHILBERT_INCLUDE) $(CUDA_CFLAGS) $(INCLUDES_PATH) $(BOOST_CPPFLAGS) -I/usr/local/include
mem_map_CFLAGS = $(CUDA_CFLAGS)
mem_map_LDADD = $(LINKLIBS)
......
......@@ -30,6 +30,8 @@
#define PACKER_OBJECTS_WITH_WARNING_POINTERS 6
//! Packer error structure has pointers
#define PACKER_OBJECTS_WITH_POINTER_CHECK 7
//! Compile time array packing
#define PACKER_ARRAY_CP_PRIMITIVE 8
#define IS_ENCAP 4
#define IS_GRID 2
......@@ -110,6 +112,24 @@ struct Pack_selector_impl
};
};
template<typename T, bool impl = std::is_array<T>::value>
struct Pack_selector_array_prim
{
enum
{
value = PACKER_PRIMITIVE
};
};
template<typename T>
struct Pack_selector_array_prim<T,true>
{
enum
{
value = PACKER_ARRAY_CP_PRIMITIVE
};
};
/*! \brief Select the primitive packing
*
*/
......@@ -118,7 +138,7 @@ struct Pack_selector_impl<T,true>
{
enum
{
value = PACKER_PRIMITIVE
value = Pack_selector_array_prim<T>::value
};
};
......@@ -133,7 +153,7 @@ struct Pack_selector
{
enum
{
value = Pack_selector_impl< T,std::is_fundamental<T>::value >::value
value = Pack_selector_impl< T,std::is_fundamental<T>::value || std::is_fundamental< typename std::remove_all_extents<T>::type >::value >::value
};
};
......
......@@ -156,6 +156,77 @@ public:
};
template<typename T, typename Mem>
class Packer<T,Mem,PACKER_ARRAY_CP_PRIMITIVE>
{
public:
/*! \brief It packs arrays of C++ primitives
*
* \param ext preallocated memory where to pack the object
* \param obj object to pack
* \param sts pack-stat info
*
*/
inline static void pack(ExtPreAlloc<Mem> & ext, const T & obj, Pack_stat & sts)
{
typedef typename std::remove_extent<T>::type prim_type;
//Pack a vector
ext.allocate(sizeof(T));
meta_copy<T>::meta_copy_(obj,(prim_type *)ext.getPointer());
// update statistic
sts.incReq();
}
/*! \brief It packs arrays of C++ primitives
*
* \param ext preallocated memory where to pack the object
* \param obj object to pack
* \param sts pack-stat info
*
*/
template<typename tp, long unsigned int dim, typename vmpl>
inline static void pack(ExtPreAlloc<Mem> & ext,
const openfpm::detail::multi_array::sub_array_openfpm<tp,dim,vmpl> & obj,
Pack_stat & sts)
{
typedef typename std::remove_extent<T>::type prim_type;
//Pack a vector
ext.allocate(sizeof(T));
meta_copy<T>::meta_copy_(obj,(prim_type *)ext.getPointer());
// update statistic
sts.incReq();
}
/*! \brief It add a request to pack a C++ primitive
*
* \param req requests vector
*
*/
static void packRequest(T & obj,size_t & req)
{
req += sizeof(T);
}
/*! \brief It add a request to pack a C++ primitive
*
* \param req requests vector
*
*/
template<typename tp, long unsigned int dim, typename vmpl>
static void packRequest(const openfpm::detail::multi_array::sub_array_openfpm<tp,dim,vmpl> & obj,
size_t & req)
{
req += sizeof(T);
}
};
/*! \brief Packer for objects, with impossibility to check for internal pointers
*
* \tparam T object type to pack
......
......@@ -297,6 +297,63 @@ BOOST_AUTO_TEST_CASE ( packer_unpacker_test )
}
}
BOOST_AUTO_TEST_CASE ( packer_selector_test )
{
BOOST_REQUIRE_EQUAL(Pack_selector<int>::value,PACKER_PRIMITIVE);
BOOST_REQUIRE_EQUAL(Pack_selector<float>::value,PACKER_PRIMITIVE);
BOOST_REQUIRE_EQUAL(Pack_selector<double>::value,PACKER_PRIMITIVE);
BOOST_REQUIRE_EQUAL(Pack_selector<long int>::value,PACKER_PRIMITIVE);
BOOST_REQUIRE_EQUAL(Pack_selector<int[3]>::value,PACKER_ARRAY_CP_PRIMITIVE);
BOOST_REQUIRE_EQUAL(Pack_selector<float[3][3]>::value,PACKER_ARRAY_CP_PRIMITIVE);
BOOST_REQUIRE_EQUAL(Pack_selector<double[5][6]>::value,PACKER_ARRAY_CP_PRIMITIVE);
BOOST_REQUIRE_EQUAL(Pack_selector<long int[5][8][9]>::value,PACKER_ARRAY_CP_PRIMITIVE);
BOOST_REQUIRE_EQUAL(Pack_selector<openfpm::vector<float>>::value,PACKER_GENERAL);
int aa = Pack_selector<openfpm::vector<aggregate<float,float[3]>>>::value;
BOOST_REQUIRE_EQUAL(aa,PACKER_GENERAL);
aa = Pack_selector<openfpm::vector_gpu<aggregate<float,float[3]>>>::value;
BOOST_REQUIRE_EQUAL(aa,PACKER_GENERAL);
aa = Pack_selector<grid_cpu<3,aggregate<float,float[3]>>>::value;
BOOST_REQUIRE_EQUAL(aa,PACKER_GRID);
openfpm::vector<aggregate<float,float[3]>> vd;
aa = Pack_selector<decltype(vd.get(0))>::value;
BOOST_REQUIRE_EQUAL(aa,PACKER_ENCAP_OBJECTS);
size_t sz[3] = {6,6,6};
grid_cpu<3,aggregate<float,float[3]>> gd(sz);
aa = Pack_selector<decltype(gd.get_o(grid_key_dx<3>({0,0,0})))>::value;
BOOST_REQUIRE_EQUAL(aa,PACKER_ENCAP_OBJECTS);
struct a_test
{
int a;
int b;
int c;
};
BOOST_REQUIRE_EQUAL(Pack_selector<a_test>::value,PACKER_OBJECTS_WITH_WARNING_POINTERS);
struct b_test
{
int a;
int b;
int c;
static bool noPointers() {return true;}
};
BOOST_REQUIRE_EQUAL(Pack_selector<b_test>::value,PACKER_OBJECTS_WITH_POINTER_CHECK);
}
BOOST_AUTO_TEST_CASE ( packer_memory_traits_inte )
{
}
BOOST_AUTO_TEST_SUITE_END()
......
......@@ -167,6 +167,31 @@ struct call_encapUnpack
/////////////////////////////// FUNCTORS FOR AGGREGATE ////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
template<bool inte_layout, typename obj_type, typename Mem>
struct pack_request_op
{
template<unsigned int p> static inline void call_pack_req(const obj_type & obj,size_t & req)
{
typedef typename boost::mpl::at<typename obj_type::type,boost::mpl::int_<p>>::type obj_t;
Packer<obj_t,Mem>::packRequest(obj.template get<p>(),req);
}
};
template<typename obj_type, typename Mem>
struct pack_request_op<true,obj_type,Mem>
{
template<unsigned int p> static inline void call_pack_req(const obj_type & obj,size_t & req)
{
typedef typename boost::mpl::at<typename obj_type::type,boost::mpl::int_<p>>::type obj_t;
Packer<obj_t,Mem>::packRequest(obj.template get<p>(),req);
}
};
template<typename> struct Debug;
//A functor for call_aggregatePackRequest
template<typename obj_type, typename Mem>
......@@ -186,10 +211,7 @@ struct call_packRequest_agg_functor
template<typename T>
inline void operator()(T& t)
{
typedef typename boost::mpl::at<typename obj_type::type,T>::type obj_t;
//for (size_t i = 0; i < obj_type::max_prop ; i++)
Packer<obj_t,Mem>::packRequest(obj.template get<T::value>(),req);
pack_request_op<openfpm::is_multi_array<decltype(obj.template get<T::value>())>::value,obj_type,Mem>::template call_pack_req<T::value>(obj,req);
}
};
......@@ -216,6 +238,17 @@ struct call_aggregatePackRequest
}
};
template<bool inte_layout, typename obj_type, typename Mem>
struct pack_pack_op
{
template<unsigned int p> static inline void call_pack_pack(ExtPreAlloc<Mem> & mem, const obj_type & obj,Pack_stat & sts)
{
typedef typename boost::mpl::at<typename obj_type::type,boost::mpl::int_<p>>::type obj_t;
Packer<obj_t,Mem>::pack(mem,obj.template get<p>(),sts);
}
};
//A functor for call_aggregatePack
template<typename obj_type, typename Mem>
struct call_pack_agg_functor
......@@ -233,10 +266,11 @@ struct call_pack_agg_functor
template<typename T>
inline void operator()(T& t)
{
typedef typename boost::mpl::at<typename obj_type::type,T>::type obj_t;
// typedef typename boost::mpl::at<typename obj_type::type,T>::type obj_t;
//for (size_t i = 0; i < obj.size(); i++)
Packer<obj_t,Mem>::pack(mem,obj.template get<T::value>(),sts);
pack_pack_op<openfpm::is_multi_array<decltype(obj.template get<T::value>())>::value,obj_type,Mem>::template call_pack_pack<T::value>(mem,obj,sts);
// Packer<obj_t,Mem>::pack(mem,obj.template get<T::value>(),sts);
}
};
......
......@@ -95,6 +95,28 @@ public:
};
template<typename T, typename Mem>
class Unpacker<T,Mem,PACKER_ARRAY_CP_PRIMITIVE>
{
public:
/*! \brief It packs arrays of C++ primitives
*
* \param ext preallocated memory where to pack the object
* \param obj object to pack
* \param sts pack-stat info
*
*/
inline static void unpack(ExtPreAlloc<Mem> & ext, T & obj, Unpack_stat & ps)
{
typedef typename std::remove_extent<T>::type prim_type;
meta_copy<T>::meta_copy_((prim_type *)ext.getPointer(),obj);
ps.addOffset(sizeof(T));
}
};
/*! \brief Unpacker for objects with no possibility to check for internal pointers
*
* \tparam T object type to unpack
......
......@@ -145,6 +145,9 @@ namespace openfpm
//! Type of the encapsulation memory parameter
typedef layout layout_type;
//! Type of the encapsulation memory parameter
typedef layout_base<T> layout_base_;
//! iterator for the vector
typedef vector_key_iterator iterator_key;
......@@ -155,6 +158,12 @@ namespace openfpm
//! Type of the value the vector is storing
typedef T value_type;
template<typename Tobj>
struct layout_base__
{
typedef layout_base<Tobj> type;
};
// Implementation of packer and unpacker for vector
#include "vector_pack_unpack.ipp"
......@@ -545,7 +554,8 @@ namespace openfpm
* \param v source vector
*
*/
template <typename S, typename M, typename gp, unsigned int impl, unsigned int ...args> void add_prp(const vector<S,M,typename layout_base<S>::type,layout_base,gp,impl> & v)
template <typename S, typename M, typename gp, unsigned int impl, unsigned int ...args>
void add_prp(const vector<S,M,typename layout_base<S>::type,layout_base,gp,impl> & v)
{
#ifdef SE_CLASS2
check_valid(this,8);
......@@ -1345,16 +1355,18 @@ namespace openfpm
}
/*! \brief Return the pointer that store the data
*
* \tparam property from which take the pointer
*
* \return the pointer that store the data
*
*/
void * getPointer()
template<unsigned int p = 0> void * getPointer()
{
#ifdef SE_CLASS2
check_valid(this,8);
#endif
return base.getPointer();
return base.template getPointer<p>();
}
/*! \brief Return the pointer that store the data
......@@ -1362,7 +1374,7 @@ namespace openfpm
* \return the pointer that store the data
*
*/
const void * getPointer() const
template<unsigned int p = 0> const void * getPointer() const
{
#ifdef SE_CLASS2
check_valid(this,8);
......
......@@ -115,6 +115,8 @@ public:
//! it define that it is a vector
typedef int yes_i_am_vector;
typedef memory_traits_lin<T> layout_base_;
//! iterator for the vector
typedef vector_key_iterator iterator_key;
//! Type of the value the vector is storing
......
......@@ -99,16 +99,16 @@ template<bool sel, int ... prp>
struct pack_simple_cond
{
//! serialize the vector
static inline void pack(const openfpm::vector<T,Memory,layout,layout_base,grow_p,OPENFPM_NATIVE> & obj, ExtPreAlloc<Memory> & mem, Pack_stat & sts)
template<typename Memory2> static inline void pack(const openfpm::vector<T,Memory,layout,layout_base,grow_p,OPENFPM_NATIVE> & obj, ExtPreAlloc<Memory2> & mem, Pack_stat & sts)
{
//Pack the size of a vector
Packer<size_t, Memory>::pack(mem,obj.size(),sts);
Packer<size_t, Memory2>::pack(mem,obj.size(),sts);
// Sending property object
typedef openfpm::vector<T> vctr;
typedef openfpm::vector<T,Memory,layout,layout_base,grow_p> vctr;
typedef object<typename object_creator<typename vctr::value_type::type,prp...>::type> prp_object;
typedef openfpm::vector<prp_object,ExtPreAlloc<Memory>,typename memory_traits_lin<prp_object>::type, memory_traits_lin ,openfpm::grow_policy_identity> dtype;
typedef openfpm::vector<prp_object,ExtPreAlloc<Memory2>,typename layout_base<prp_object>::type, layout_base ,openfpm::grow_policy_identity> dtype;
// Create an object over the preallocated memory (No allocation is produced)
dtype dest;
......@@ -308,7 +308,7 @@ template<int ... prp> inline void packRequest(size_t & req) const
* \param sts pack-stat info
*
*/
template<int ... prp> inline void pack(ExtPreAlloc<Memory> & mem, Pack_stat & sts) const
template<int ... prp, typename Memory2> inline void pack(ExtPreAlloc<Memory2> & mem, Pack_stat & sts) const
{
//If all of the aggregate properties are simple (don't have "pack()" member)
if (has_pack_agg<T,prp...>::result::value == false)
......@@ -321,12 +321,12 @@ template<int ... prp> inline void pack(ExtPreAlloc<Memory> & mem, Pack_stat & st
else
{
//Pack the size of a vector
Packer<size_t, Memory>::pack(mem,this->size(),sts);
Packer<size_t, Memory2>::pack(mem,this->size(),sts);
for (size_t i = 0 ; i < this->size() ; i++)
{
//Call a packer in nested way
call_aggregatePack<decltype(this->get(i)),Memory,prp ... >::call_pack(this->get(i),mem,sts);
call_aggregatePack<decltype(this->get(i)),Memory2,prp ... >::call_pack(this->get(i),mem,sts);
}
}
}
......
......@@ -11,6 +11,7 @@
#include "util/variadic_to_vmpl.hpp"
#include "t_to_memory_c.hpp"
#include "Vector/vect_isel.hpp"
#include "Vector/util.hpp"
/*! \brief This class convert a boost::mpl::fusion/vector to a boost::mpl::fusion/vector with memory_c interleaved
*
......@@ -183,4 +184,23 @@ template<typename T>
struct is_layout_inte<T, typename Void< typename T::yes_is_inte>::type> : std::true_type
{};
/*! \brief is_multiple_buffer_each_prp
*
* return if each property is splitted on a separate buffer. This class make sense to be used if T is
* a vector in case it is not it always return 0
*
* ### Example
*
* \snippet util_test.hpp Check if the vector has multiple buffers for each vector
*
*
*/
template<typename T, unsigned int impl = is_vector<T>::value >
struct is_multiple_buffer_each_prp: std::false_type
{};
template<typename T>
struct is_multiple_buffer_each_prp<T,true>: is_layout_inte<typename T::layout_base_>
{};
#endif
#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>
#include "memory_ly/memory_conf.hpp"
#include "Vector/map_vector.hpp"
BOOST_AUTO_TEST_SUITE( memory_conf_test )
BOOST_AUTO_TEST_CASE( memory_conf_use )
{
bool test = is_multiple_buffer_each_prp<openfpm::vector<float>>::value;
BOOST_REQUIRE_EQUAL(test,false);
test = is_multiple_buffer_each_prp<float>::value;
BOOST_REQUIRE_EQUAL(test,false);
test = is_multiple_buffer_each_prp<openfpm::vector<aggregate<float,float>>>::value;
BOOST_REQUIRE_EQUAL(test,false);
test = is_multiple_buffer_each_prp<openfpm::vector_gpu<aggregate<float,float>>>::value;
BOOST_REQUIRE_EQUAL(test,true);
}
BOOST_AUTO_TEST_SUITE_END()
......@@ -90,6 +90,40 @@ struct meta_copy<T[N1]>
copy_general<T>(src[i1],dst[i1]);
}
}
/*! \brief copy and object from src to dst
*
* \param src source object to copy
* \param dst destination object
*
*/
__device__ __host__