222 lines
5.0 KiB
C++
222 lines
5.0 KiB
C++
/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/SylvMemory.cpp,v 1.1.1.1 2004/06/04 13:00:49 kamenik Exp $ */
|
|
|
|
/* Tag $Name: $ */
|
|
|
|
#include "SylvMemory.h"
|
|
#include "SylvException.h"
|
|
#include "KronVector.h"
|
|
|
|
#if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
|
|
# include <dynmex.h>
|
|
#endif
|
|
|
|
#include <cmath>
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
|
|
/**********************************************************/
|
|
/* SylvMemoryPool */
|
|
/**********************************************************/
|
|
|
|
SylvMemoryPool memory_pool;
|
|
|
|
SylvMemoryPool::SylvMemoryPool()
|
|
: base(0), length(0), allocated(0), stack_mode(false)
|
|
{
|
|
}
|
|
|
|
void SylvMemoryPool::init(size_t size)
|
|
{
|
|
#ifdef USE_MEMORY_POOL
|
|
length = size;
|
|
|
|
#if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
|
|
if (base)
|
|
throw SYLV_MES_EXCEPTION("Attempt to use matlab memory pool twice.");
|
|
base = (char*) mxMalloc(length);
|
|
#else
|
|
base = (char*) malloc(length);
|
|
#endif
|
|
|
|
#else
|
|
throw SYLV_MES_EXCEPTION("SylvMemoryPool::init() called for non memory pool code.");
|
|
#endif
|
|
}
|
|
|
|
void* SylvMemoryPool::allocate(size_t size)
|
|
{
|
|
#ifdef USE_MEMORY_POOL
|
|
if (allocated + size < length) {
|
|
char* res = base + allocated;
|
|
allocated += size;
|
|
return res;
|
|
} else {
|
|
throw SYLV_MES_EXCEPTION("Run out of memory space");
|
|
}
|
|
#else
|
|
throw SYLV_MES_EXCEPTION("SylvMemoryPool::allocate() called for non memory pool code.");
|
|
#endif
|
|
}
|
|
|
|
void SylvMemoryPool::free(void* p)
|
|
{
|
|
#ifdef USE_MEMORY_POOL
|
|
int offset = ((char*)p) - base;
|
|
|
|
#ifdef DEBUG
|
|
if (offset < 0)
|
|
throw SYLV_MES_EXCEPTION("SylvMemoryPool::free() frees wrong address < begin.");
|
|
if (offset >= (int)length)
|
|
throw SYLV_MES_EXCEPTION("SylvMemoryPool::free() frees wrong address > end.");
|
|
#endif
|
|
|
|
if (stack_mode && offset >= 0 && offset < (int)allocated)
|
|
allocated = offset;
|
|
|
|
#else
|
|
throw SYLV_MES_EXCEPTION("SylvMemoryPool::free() called for non memory pool code.");
|
|
#endif
|
|
}
|
|
|
|
void SylvMemoryPool::setStackMode(bool mode)
|
|
{
|
|
stack_mode = mode;
|
|
}
|
|
|
|
SylvMemoryPool::~SylvMemoryPool()
|
|
{
|
|
reset();
|
|
}
|
|
|
|
void SylvMemoryPool::reset()
|
|
{
|
|
#if !defined(MATLAB_MEX_FILE) && !defined(OCTAVE_MEX_FILE)
|
|
delete [] base;
|
|
base = 0;
|
|
allocated = 0;
|
|
length = 0;
|
|
stack_mode = false;
|
|
#endif
|
|
}
|
|
|
|
/**********************************************************/
|
|
/* global new and delete */
|
|
/**********************************************************/
|
|
|
|
#ifdef USE_MEMORY_POOL
|
|
|
|
void* operator new(size_t size)
|
|
{
|
|
return memory_pool.allocate(size);
|
|
}
|
|
|
|
void* operator new[](size_t size)
|
|
{
|
|
return memory_pool.allocate(size);
|
|
}
|
|
|
|
void operator delete(void* p)
|
|
{
|
|
memory_pool.free(p);
|
|
}
|
|
|
|
void operator delete[](void* p)
|
|
{
|
|
memory_pool.free(p);
|
|
}
|
|
|
|
#endif
|
|
|
|
/**********************************************************/
|
|
/* saved version of global new and delete */
|
|
/**********************************************************/
|
|
|
|
#ifdef USE_MEMORY_POOL
|
|
void* MallocAllocator::operator new(size_t size)
|
|
{
|
|
#if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
|
|
throw SYLV_MES_EXCEPTION("Attempt to call wrong memory allocator.");
|
|
#else
|
|
void* res = malloc(size);
|
|
if (!res)
|
|
throw SYLV_MES_EXCEPTION("Malloc unable to allocate memory.");
|
|
return res;
|
|
#endif
|
|
}
|
|
|
|
void* MallocAllocator::operator new[](size_t size)
|
|
{
|
|
#if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
|
|
throw SYLV_MES_EXCEPTION("Attempt to call wrong memory allocator.");
|
|
#else
|
|
void* res = malloc(size);
|
|
if (!res)
|
|
throw SYLV_MES_EXCEPTION("Malloc unable allocate memory.");
|
|
return res;
|
|
#endif
|
|
}
|
|
|
|
void MallocAllocator::operator delete(void* p)
|
|
{
|
|
#if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
|
|
throw SYLV_MES_EXCEPTION("Attempt to call wrong memory destructor.");
|
|
#else
|
|
free(p);
|
|
#endif
|
|
}
|
|
|
|
void MallocAllocator::operator delete[](void* p)
|
|
{
|
|
#if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
|
|
throw SYLV_MES_EXCEPTION("Attempt to call wrong memory destructor.");
|
|
#else
|
|
free(p);
|
|
#endif
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
/**********************************************************/
|
|
/* SylvMemoryDriver */
|
|
/**********************************************************/
|
|
|
|
void SylvMemoryDriver::allocate(int num_d, int m, int n, int order)
|
|
{
|
|
#ifdef USE_MEMORY_POOL
|
|
int x_cols = power(m,order);
|
|
int total = num_d*x_cols*n; // storage for big matrices
|
|
total += x_cols; // storage for one extra row of a big matrix
|
|
int dig_vectors = (int)ceil(((double)(power(m,order)-1))/(m-1));
|
|
total += 8*n*dig_vectors; // storage for kron vectors instantiated during solv
|
|
total += 50*(m*m+n*n); // some storage for small square matrices
|
|
total *= sizeof(double); // everything in doubles
|
|
memory_pool.init(total);
|
|
#endif
|
|
}
|
|
|
|
|
|
SylvMemoryDriver::SylvMemoryDriver(int num_d, int m, int n, int order)
|
|
{
|
|
allocate(num_d, m, n, order);
|
|
}
|
|
|
|
SylvMemoryDriver::SylvMemoryDriver(const SylvParams& pars, int num_d,
|
|
int m, int n, int order)
|
|
{
|
|
if (*(pars.method) == SylvParams::iter)
|
|
num_d++;
|
|
if (*(pars.want_check))
|
|
num_d++;
|
|
allocate(num_d, m, n, order);
|
|
}
|
|
|
|
SylvMemoryDriver::~SylvMemoryDriver()
|
|
{
|
|
memory_pool.reset();
|
|
}
|
|
|
|
void SylvMemoryDriver::setStackMode(bool mode) {
|
|
memory_pool.setStackMode(mode);
|
|
}
|