Commit e60b3adb authored by Kirill Terekhov's avatar Kirill Terekhov

pool_array no longer depend on allocation/deallocation order; unit test on...

pool_array no longer depend on allocation/deallocation order; unit test on pool_array; some fancy functions to retrive derivatives for variable/hessian_variable
parent e74b3f1a
Pipeline #225 failed with stages
in 10 minutes and 35 seconds
......@@ -2844,9 +2844,12 @@ namespace INMOST
//typedef char pool_type[pool_size];
typedef std::map<void *,unsigned> page_fault_type;
std::vector< char * > pool; ///< Data storage
std::vector<bool> inuse; ///< marks block as in use, for unordered deallocation
std::vector<unsigned> last_alloc; ///< Last allocated block position, used to track allocation
page_fault_type page_fault;
public:
unsigned last_byte() const {return last_alloc.back();}
unsigned allocations() const {return inuse.size(); }
memory_pool(){pool.push_back(new char[1 << pool_size_bits]); last_alloc.push_back(0); }
//memory_pool(const memory_pool & b) : pool(b.pool), last_alloc(b.last_alloc) {}
//memory_pool & operator = (memory_pool const & b) {pool = b.pool; last_alloc = b.last_alloc; return *this;}
......@@ -2877,6 +2880,7 @@ namespace INMOST
void * data = (void *)&pool[pagepos][datapos];
for(unsigned i = 0; i < n; ++i) new (&static_cast<T *>(data)[i]) T(c);
last_alloc.push_back(newpos);
inuse.push_back(true);
//std::cout << "allocated " << sizeof(T)*n << " bytes from " << oldpos << " to " << newpos << " at page " << pagepos << " at " << data << std::endl;
//std::cout << this << " last_alloc[" << last_alloc.size() << "]:";
//for(unsigned i = 0; i < last_alloc.size(); ++i) std::cout << " " << last_alloc[i];
......@@ -2900,27 +2904,31 @@ namespace INMOST
template<typename T>
void deallocate(T * mem)
{
unsigned oldpos = last_alloc.size() > 1 ? last_alloc[last_alloc.size()-2] : 0;
unsigned newpos = last_alloc.size() > 0 ? last_alloc[last_alloc.size()-1] : 0;
unsigned pagepos = newpos >> pool_size_bits;
unsigned datapos = oldpos % (1 << pool_size_bits);
//std::cout << "deallocate " << mem << " from " << oldpos << " to " << newpos << " page " << pagepos << std::endl;
//std::cout << this << " last_alloc[" << last_alloc.size() << "]:";
//for(unsigned i = 0; i < last_alloc.size(); ++i) std::cout << " " << last_alloc[i];
//std::cout << std::endl;
if( last_alloc.size() > 1 && (((T*)&pool[pagepos][datapos]) == mem) )
bool find = false;
unsigned checkpos = last_alloc.size(), oldpos, newpos, pagepos, datapos;
if( checkpos > 1 )
{
unsigned n = (newpos - oldpos)/sizeof(T);
for(unsigned i = 0; i < n; ++i) mem[i].~T();
last_alloc.pop_back();
//std::cout << "deallocate from " << oldpos << " to " << newpos << std::endl;
if( last_alloc.back() != 0 && last_alloc.back()%(1<<pool_size_bits) == 0 )
while( !find && checkpos > 1 )
{
//std::cout << "remove page " << (last_alloc.back() >> pool_size_bits) << " start marker " << std::endl;
last_alloc.pop_back();
oldpos = last_alloc[checkpos-2];
newpos = last_alloc[checkpos-1];
pagepos = newpos >> pool_size_bits;
datapos = oldpos % (1 << pool_size_bits);
if( (((T*)&pool[pagepos][datapos]) == mem) )
{
unsigned n = (newpos - oldpos)/sizeof(T);
for(unsigned i = 0; i < n; ++i) mem[i].~T();
inuse[checkpos-2] = false;
find = true;
}
checkpos--;
}
}
else
//std::cout << "deallocate " << mem << " from " << oldpos << " to " << newpos << " page " << pagepos << std::endl;
//std::cout << this << " last_alloc[" << last_alloc.size() << "]:";
//for(unsigned i = 0; i < last_alloc.size(); ++i) std::cout << " " << last_alloc[i];
//std::cout << std::endl;
if( !find )
{
page_fault_type::iterator it = page_fault.find((void *)mem);
assert(it != page_fault.end() && "deallocated block does not match neither last allocated block nor page fault");
......@@ -2936,6 +2944,18 @@ namespace INMOST
free(mem);
page_fault.erase(it);
}
while( !inuse.empty() && inuse.back() == false )
{
inuse.pop_back();
last_alloc.pop_back();
//std::cout << "deallocate from " << oldpos << " to " << newpos << std::endl;
if( last_alloc.back() != 0 && last_alloc.back()%(1<<pool_size_bits) == 0 )
{
//std::cout << "remove page " << (last_alloc.back() >> pool_size_bits) << " start marker " << std::endl;
last_alloc.pop_back();
}
}
}
~memory_pool()
{
......
......@@ -101,6 +101,7 @@ namespace INMOST
__INLINE void GetJacobian(INMOST_DATA_REAL_TYPE mult, Sparse::RowMerger & r) const {if( index != ENUMUNDEF ) r[index] += mult;}
__INLINE void GetJacobian(INMOST_DATA_REAL_TYPE mult, Sparse::Row & r) const {if( index != ENUMUNDEF ) r[index] += mult;}
__INLINE void GetHessian(INMOST_DATA_REAL_TYPE multJ, Sparse::Row & J, INMOST_DATA_REAL_TYPE multH, Sparse::HessianRow & H) const {if( index != ENUMUNDEF ) J.Push(index,multJ); (void)multH; (void)H;}
__INLINE INMOST_DATA_REAL_TYPE GetDerivative(INMOST_DATA_ENUM_TYPE i) {return index == i? 1.0 : 0.0;}
__INLINE var_expression & operator =(var_expression const & other)
{
value = other.value;
......@@ -205,6 +206,7 @@ namespace INMOST
*/
__INLINE Sparse::Row & GetRow() {return entries;}
__INLINE const Sparse::Row & GetRow() const {return entries;}
__INLINE INMOST_DATA_REAL_TYPE GetDerivative(INMOST_DATA_ENUM_TYPE index) {return GetRow()[index];}
__INLINE multivar_expression & operator +=(basic_expression const & expr)
{
value += expr.GetValue();
......@@ -484,6 +486,7 @@ namespace INMOST
__INLINE Sparse::Row & GetRow() {return entries;}
__INLINE Sparse::HessianRow & GetHessianRow() {return hessian_entries;}
__INLINE const Sparse::Row & GetRow() const {return entries;}
__INLINE INMOST_DATA_REAL_TYPE GetDerivative(INMOST_DATA_ENUM_TYPE index) {return GetRow()[index];}
__INLINE const Sparse::HessianRow & GetHessianRow() const {return hessian_entries;}
__INLINE hessian_multivar_expression & operator +=(basic_expression const & expr)
{
......@@ -679,6 +682,7 @@ namespace INMOST
*/
__INLINE Sparse::Row & GetRow() {return *entries;}
__INLINE const Sparse::Row & GetRow() const {return *entries;}
__INLINE INMOST_DATA_REAL_TYPE GetDerivative(INMOST_DATA_ENUM_TYPE index) {return GetRow()[index];}
__INLINE multivar_expression_reference & operator +=(basic_expression const & expr)
{
value += expr.GetValue();
......@@ -820,6 +824,7 @@ namespace INMOST
H = *hentries;
for(Sparse::HessianRow::iterator it = H.Begin(); it != H.End(); ++it) it->second *= multH;
}
__INLINE INMOST_DATA_REAL_TYPE GetDerivative(INMOST_DATA_ENUM_TYPE index) {return GetRow()[index];}
__INLINE multivar_expression GetVariable(INMOST_DATA_ENUM_TYPE index)
{
multivar_expression ret(0);
......
......@@ -23,5 +23,7 @@ endif()
endif()
add_subdirectory(linalg_test000)
add_subdirectory(linalg_test000)
add_subdirectory(container_test000)
add_subdirectory(xml_reader_test000)
......
project(autodiff_test000)
set(SOURCE main.cpp)
add_executable(container_test000 ${SOURCE})
target_link_libraries(container_test000 inmost)
if(USE_MPI)
message("linking container_test000 with MPI")
target_link_libraries(container_test000 ${MPI_LIBRARIES})
if(MPI_LINK_FLAGS)
set_target_properties(container_test000 PROPERTIES LINK_FLAGS "${MPI_LINK_FLAGS}")
endif()
endif(USE_MPI)
add_test(NAME container_test000_pool_array COMMAND $<TARGET_FILE:container_test000> 0)
#include "inmost.h"
#include <cstdio>
#include <cmath>
using namespace INMOST;
int main(int argc,char ** argv)
{
int test = 0;
if (argc > 1) test = atoi(argv[1]);
if( test == 0 ) //check order of deallocation does not cause problem
{
std::cout << "allocs: " << get_pool().allocations() << " byte " << get_pool().last_byte() << std::endl;
pool_array<double> * a = new pool_array<double>(2);
std::cout << "allocs: " << get_pool().allocations() << " byte " << get_pool().last_byte() << std::endl;
pool_array<int> * b = new pool_array<int>(3);
std::cout << "allocs: " << get_pool().allocations() << " byte " << get_pool().last_byte() << std::endl;
pool_array<char> * c = new pool_array<char>(6);
std::cout << "allocs: " << get_pool().allocations() << " byte " << get_pool().last_byte() << std::endl;
delete a;
std::cout << "allocs: " << get_pool().allocations() << " byte " << get_pool().last_byte() << std::endl;
delete b;
std::cout << "allocs: " << get_pool().allocations() << " byte " << get_pool().last_byte() << std::endl;
delete c;
std::cout << "allocs: " << get_pool().allocations() << " byte " << get_pool().last_byte() << std::endl;
}
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment