SHOGUN  v3.2.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
memory.cpp
Go to the documentation of this file.
00001 /*
00002  * This program is free software; you can redistribute it and/or modify
00003  * it under the terms of the GNU General Public License as published by
00004  * the Free Software Foundation; either version 3 of the License, or
00005  * (at your option) any later version.
00006  *
00007  * Written (W) 2008-2009 Soeren Sonnenburg
00008  * Copyright (C) 2008-2009 Fraunhofer Institute FIRST and Max-Planck-Society
00009  */
00010 
00011 #include <shogun/lib/config.h>
00012 #include <shogun/lib/ShogunException.h>
00013 #include <shogun/lib/common.h>
00014 #include <shogun/lib/Map.h>
00015 #include <shogun/lib/SGVector.h>
00016 #include <shogun/lib/SGSparseVector.h>
00017 #include <shogun/lib/SGMatrix.h>
00018 #include <shogun/base/SGObject.h>
00019 
00020 #include <string.h>
00021 
00022 #ifdef USE_JEMALLOC
00023 #include <jemalloc/jemalloc.h>
00024 #elif USE_TCMALLOC
00025 #include <gperftools/tcmalloc.h>
00026 #endif
00027 
00028 using namespace shogun;
00029 
00030 #ifdef TRACE_MEMORY_ALLOCS
00031 extern CMap<void*, shogun::MemoryBlock>* sg_mallocs;
00032 
00033 MemoryBlock::MemoryBlock() : ptr(NULL), size(0), file(NULL),
00034     line(-1), is_sgobject(false)
00035 {
00036 }
00037 
00038 MemoryBlock::MemoryBlock(void* p) : ptr(p), size(0), file(NULL),
00039     line(-1), is_sgobject(false)
00040 {
00041 }
00042 
00043 MemoryBlock::MemoryBlock(void* p, size_t sz, const char* fname, int linenr) :
00044     ptr(p), size(sz), file(fname), line(linenr), is_sgobject(false)
00045 {
00046 }
00047 
00048 MemoryBlock::MemoryBlock(const MemoryBlock &b)
00049 {
00050     ptr=b.ptr;
00051     size=b.size;
00052     file=b.file;
00053     line=b.line;
00054     is_sgobject=b.is_sgobject;
00055 }
00056 
00057 
00058 bool MemoryBlock::operator==(const MemoryBlock &b) const
00059 {
00060     return ptr==b.ptr;
00061 }
00062 
00063 void MemoryBlock::display()
00064 {
00065     if (line!=-1)
00066     {
00067         printf("Memory block at %p of size %lld bytes (allocated in %s line %d)\n",
00068                 ptr, (long long int) size, file, line);
00069     }
00070     else
00071     {
00072         if (is_sgobject)
00073         {
00074             CSGObject* obj=(CSGObject*) ptr;
00075             printf("SGObject '%s' at %p of size %lld bytes with %d ref's\n",
00076                     obj->get_name(), obj, (long long int) size, obj->ref_count());
00077         }
00078         else
00079         {
00080             printf("Object at %p of size %lld bytes\n",
00081                     ptr, (long long int) size);
00082         }
00083     }
00084 }
00085 
00086 void MemoryBlock::set_sgobject()
00087 {
00088     is_sgobject=true;
00089 }
00090 #endif
00091 
00092 #ifdef HAVE_CXX11
00093 void* operator new(size_t size)
00094 #else
00095 void* operator new(size_t size) throw (std::bad_alloc)
00096 #endif
00097 {
00098 #if defined(USE_JEMALLOC)
00099     void *p=je_malloc(size);
00100 #elif defined(USE_TCMALLOC)
00101     void *p=tc_malloc(size);
00102 #else
00103     void *p=malloc(size);
00104 #endif
00105 
00106 #ifdef TRACE_MEMORY_ALLOCS
00107     if (sg_mallocs)
00108         sg_mallocs->add(p, MemoryBlock(p,size));
00109 #endif
00110     if (!p)
00111     {
00112         const size_t buf_len=128;
00113         char buf[buf_len];
00114         size_t written=snprintf(buf, buf_len,
00115             "Out of memory error, tried to allocate %lld bytes using new().\n", (long long int) size);
00116         if (written<buf_len)
00117             throw ShogunException(buf);
00118         else
00119             throw ShogunException("Out of memory error using new.\n");
00120     }
00121 
00122     return p;
00123 }
00124 
00125 void operator delete(void *p) throw()
00126 {
00127 #ifdef TRACE_MEMORY_ALLOCS
00128     if (sg_mallocs)
00129         sg_mallocs->remove(p);
00130 #endif
00131 
00132 #if defined(USE_JEMALLOC)
00133     je_free(p);
00134 #elif defined(USE_TCMALLOC)
00135     tc_free(p);
00136 #else
00137     free(p);
00138 #endif
00139 }
00140 
00141 #ifdef HAVE_CXX11
00142 void* operator new[](size_t size)
00143 #else
00144 void* operator new[](size_t size) throw(std::bad_alloc)
00145 #endif
00146 {
00147 #if defined(USE_JEMALLOC)
00148     void *p=je_malloc(size);
00149 #elif defined(USE_TCMALLOC)
00150     void *p=tc_malloc(size);
00151 #else
00152     void *p=malloc(size);
00153 #endif
00154 
00155 #ifdef TRACE_MEMORY_ALLOCS
00156     if (sg_mallocs)
00157         sg_mallocs->add(p, MemoryBlock(p,size));
00158 #endif
00159 
00160     if (!p)
00161     {
00162         const size_t buf_len=128;
00163         char buf[buf_len];
00164         size_t written=snprintf(buf, buf_len,
00165             "Out of memory error, tried to allocate %lld bytes using new[].\n", (long long int) size);
00166         if (written<buf_len)
00167             throw ShogunException(buf);
00168         else
00169             throw ShogunException("Out of memory error using new[].\n");
00170     }
00171 
00172     return p;
00173 }
00174 
00175 void operator delete[](void *p) throw()
00176 {
00177 #ifdef TRACE_MEMORY_ALLOCS
00178     if (sg_mallocs)
00179         sg_mallocs->remove(p);
00180 #endif
00181 
00182 #if defined(USE_JEMALLOC)
00183     je_free(p);
00184 #elif defined(USE_TCMALLOC)
00185     tc_free(p);
00186 #else
00187     free(p);
00188 #endif
00189 }
00190 
00191 namespace shogun
00192 {
00193 void* sg_malloc(size_t size
00194 #ifdef TRACE_MEMORY_ALLOCS
00195         , const char* file, int line
00196 #endif
00197 )
00198 {
00199 #if defined(USE_JEMALLOC)
00200     void* p=je_malloc(size);
00201 #elif defined(USE_TCMALLOC)
00202     void *p=tc_malloc(size);
00203 #else
00204     void* p=malloc(size);
00205 #endif
00206 #ifdef TRACE_MEMORY_ALLOCS
00207     if (sg_mallocs)
00208         sg_mallocs->add(p, MemoryBlock(p,size, file, line));
00209 #endif
00210 
00211     if (!p)
00212     {
00213         const size_t buf_len=128;
00214         char buf[buf_len];
00215         size_t written=snprintf(buf, buf_len,
00216             "Out of memory error, tried to allocate %lld bytes using malloc.\n", (long long int) size);
00217         if (written<buf_len)
00218             throw ShogunException(buf);
00219         else
00220             throw ShogunException("Out of memory error using malloc.\n");
00221     }
00222 
00223     return p;
00224 }
00225 
00226 void* sg_calloc(size_t num, size_t size
00227 #ifdef TRACE_MEMORY_ALLOCS
00228         , const char* file, int line
00229 #endif
00230 )
00231 {
00232 #if defined(USE_JEMALLOC)
00233     void* p=je_calloc(num, size);
00234 #elif defined(USE_TCMALLOC)
00235     void* p=tc_calloc(num, size);
00236 #else
00237     void* p=calloc(num, size);
00238 #endif
00239 
00240 #ifdef TRACE_MEMORY_ALLOCS
00241     if (sg_mallocs)
00242         sg_mallocs->add(p, MemoryBlock(p,size, file, line));
00243 #endif
00244 
00245     if (!p)
00246     {
00247         const size_t buf_len=128;
00248         char buf[buf_len];
00249         size_t written=snprintf(buf, buf_len,
00250             "Out of memory error, tried to allocate %lld bytes using calloc.\n",
00251             (long long int) size);
00252 
00253         if (written<buf_len)
00254             throw ShogunException(buf);
00255         else
00256             throw ShogunException("Out of memory error using calloc.\n");
00257     }
00258 
00259     return p;
00260 }
00261 
00262 void  sg_free(void* ptr)
00263 {
00264 #ifdef TRACE_MEMORY_ALLOCS
00265     if (sg_mallocs)
00266         sg_mallocs->remove(ptr);
00267 #endif
00268 
00269 #if defined(USE_JEMALLOC)
00270     je_free(ptr);
00271 #elif defined(USE_TCMALLOC)
00272     tc_free(ptr);
00273 #else
00274     free(ptr);
00275 #endif
00276 }
00277 
00278 void* sg_realloc(void* ptr, size_t size
00279 #ifdef TRACE_MEMORY_ALLOCS
00280         , const char* file, int line
00281 #endif
00282 )
00283 {
00284 #if defined(USE_JEMALLOC)
00285     void* p=je_realloc(ptr, size);
00286 #elif defined(USE_TCMALLOC)
00287     void* p=tc_realloc(ptr, size);
00288 #else
00289     void* p=realloc(ptr, size);
00290 #endif
00291 
00292 #ifdef TRACE_MEMORY_ALLOCS
00293     if (sg_mallocs)
00294         sg_mallocs->remove(ptr);
00295 
00296     if (sg_mallocs)
00297         sg_mallocs->add(p, MemoryBlock(p,size, file, line));
00298 #endif
00299 
00300     if (!p && (size || !ptr))
00301     {
00302         const size_t buf_len=128;
00303         char buf[buf_len];
00304         size_t written=snprintf(buf, buf_len,
00305             "Out of memory error, tried to allocate %lld bytes using realloc.\n", (long long int) size);
00306         if (written<buf_len)
00307             throw ShogunException(buf);
00308         else
00309             throw ShogunException("Out of memory error using realloc.\n");
00310     }
00311 
00312     return p;
00313 }
00314 
00315 #ifdef TRACE_MEMORY_ALLOCS
00316 void list_memory_allocs()
00317 {
00318     MemoryBlock* temp;
00319     if (sg_mallocs)
00320     {
00321         int32_t num=sg_mallocs->get_num_elements();
00322         int32_t size=sg_mallocs->get_array_size();
00323         printf("%d Blocks are allocated:\n", num);
00324 
00325 
00326         for (int32_t i=0; i<size; i++)
00327         {
00328             temp=sg_mallocs->get_element_ptr(i);
00329             if (temp!=NULL)
00330                 temp->display();
00331         }
00332     }
00333 }
00334 #endif
00335 
00336 #ifdef TRACE_MEMORY_ALLOCS
00337 #define SG_SPECIALIZED_MALLOC(type)                                                             \
00338 template<> type* sg_generic_malloc<type >(size_t len, const char* file, int line)               \
00339 {                                                                                               \
00340     return new type[len]();                                                                     \
00341 }                                                                                               \
00342                                                                                                 \
00343 template<> type* sg_generic_calloc<type >(size_t len, const char* file, int line)               \
00344 {                                                                                               \
00345     return new type[len]();                                                                     \
00346 }                                                                                               \
00347                                                                                                 \
00348 template<> type* sg_generic_realloc<type >(type* ptr, size_t old_len, size_t len, const char* file, int line)   \
00349 {                                                                                               \
00350     type* new_ptr = new type[len]();                                                            \
00351     size_t min_len=old_len;                                                                     \
00352     if (len<min_len)                                                                            \
00353         min_len=len;                                                                            \
00354     for (size_t i=0; i<min_len; i++)                                                            \
00355         new_ptr[i]=ptr[i];                                                                      \
00356     delete[] ptr;                                                                               \
00357     return new_ptr;                                                                             \
00358 }                                                                                               \
00359                                                                                                 \
00360 template<> void sg_generic_free<type >(type* ptr)                                               \
00361 {                                                                                               \
00362     delete[] ptr;                                                                               \
00363 }
00364 
00365 #else // TRACE_MEMORY_ALLOCS
00366 
00367 #define SG_SPECIALIZED_MALLOC(type)                                 \
00368 template<> type* sg_generic_malloc<type >(size_t len)               \
00369 {                                                                   \
00370     return new type[len]();                                         \
00371 }                                                                   \
00372                                                                     \
00373 template<> type* sg_generic_calloc<type >(size_t len)               \
00374 {                                                                   \
00375     return new type[len]();                                         \
00376 }                                                                   \
00377                                                                     \
00378 template<> type* sg_generic_realloc<type >(type* ptr, size_t old_len, size_t len)   \
00379 {                                                                   \
00380     type* new_ptr = new type[len]();                                \
00381     size_t min_len=old_len;                                         \
00382     if (len<min_len)                                                \
00383         min_len=len;                                                \
00384     for (size_t i=0; i<min_len; i++)                                \
00385         new_ptr[i]=ptr[i];                                          \
00386     delete[] ptr;                                                   \
00387     return new_ptr;                                                 \
00388 }                                                                   \
00389                                                                     \
00390 template<> void sg_generic_free<type >(type* ptr)                   \
00391 {                                                                   \
00392     delete[] ptr;                                                   \
00393 }
00394 #endif // TRACE_MEMORY_ALLOCS
00395 
00396 SG_SPECIALIZED_MALLOC(SGVector<bool>)
00397 SG_SPECIALIZED_MALLOC(SGVector<char>)
00398 SG_SPECIALIZED_MALLOC(SGVector<int8_t>)
00399 SG_SPECIALIZED_MALLOC(SGVector<uint8_t>)
00400 SG_SPECIALIZED_MALLOC(SGVector<int16_t>)
00401 SG_SPECIALIZED_MALLOC(SGVector<uint16_t>)
00402 SG_SPECIALIZED_MALLOC(SGVector<int32_t>)
00403 SG_SPECIALIZED_MALLOC(SGVector<uint32_t>)
00404 SG_SPECIALIZED_MALLOC(SGVector<int64_t>)
00405 SG_SPECIALIZED_MALLOC(SGVector<uint64_t>)
00406 SG_SPECIALIZED_MALLOC(SGVector<float32_t>)
00407 SG_SPECIALIZED_MALLOC(SGVector<float64_t>)
00408 SG_SPECIALIZED_MALLOC(SGVector<floatmax_t>)
00409 SG_SPECIALIZED_MALLOC(SGVector<complex128_t>)
00410 
00411 SG_SPECIALIZED_MALLOC(SGSparseVector<bool>)
00412 SG_SPECIALIZED_MALLOC(SGSparseVector<char>)
00413 SG_SPECIALIZED_MALLOC(SGSparseVector<int8_t>)
00414 SG_SPECIALIZED_MALLOC(SGSparseVector<uint8_t>)
00415 SG_SPECIALIZED_MALLOC(SGSparseVector<int16_t>)
00416 SG_SPECIALIZED_MALLOC(SGSparseVector<uint16_t>)
00417 SG_SPECIALIZED_MALLOC(SGSparseVector<int32_t>)
00418 SG_SPECIALIZED_MALLOC(SGSparseVector<uint32_t>)
00419 SG_SPECIALIZED_MALLOC(SGSparseVector<int64_t>)
00420 SG_SPECIALIZED_MALLOC(SGSparseVector<uint64_t>)
00421 SG_SPECIALIZED_MALLOC(SGSparseVector<float32_t>)
00422 SG_SPECIALIZED_MALLOC(SGSparseVector<float64_t>)
00423 SG_SPECIALIZED_MALLOC(SGSparseVector<floatmax_t>)
00424 SG_SPECIALIZED_MALLOC(SGSparseVector<complex128_t>)
00425 
00426 SG_SPECIALIZED_MALLOC(SGMatrix<bool>)
00427 SG_SPECIALIZED_MALLOC(SGMatrix<char>)
00428 SG_SPECIALIZED_MALLOC(SGMatrix<int8_t>)
00429 SG_SPECIALIZED_MALLOC(SGMatrix<uint8_t>)
00430 SG_SPECIALIZED_MALLOC(SGMatrix<int16_t>)
00431 SG_SPECIALIZED_MALLOC(SGMatrix<uint16_t>)
00432 SG_SPECIALIZED_MALLOC(SGMatrix<int32_t>)
00433 SG_SPECIALIZED_MALLOC(SGMatrix<uint32_t>)
00434 SG_SPECIALIZED_MALLOC(SGMatrix<int64_t>)
00435 SG_SPECIALIZED_MALLOC(SGMatrix<uint64_t>)
00436 SG_SPECIALIZED_MALLOC(SGMatrix<float32_t>)
00437 SG_SPECIALIZED_MALLOC(SGMatrix<float64_t>)
00438 SG_SPECIALIZED_MALLOC(SGMatrix<floatmax_t>)
00439 SG_SPECIALIZED_MALLOC(SGMatrix<complex128_t>)
00440 #undef SG_SPECIALIZED_MALLOC
00441 }
00442 
00443 void* shogun::get_copy(void* src, size_t len)
00444 {
00445     void* copy=SG_MALLOC(uint8_t, len);
00446     memcpy(copy, src, len);
00447     return copy;
00448 }
00449 
00450 char* shogun::get_strdup(const char* str)
00451 {
00452     if (!str)
00453         return NULL;
00454 
00455     return (char*) get_copy((void*) str, strlen(str)+1);
00456 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

SHOGUN Machine Learning Toolbox - Documentation