From e0a5f077afd50b987d4317167c559e6e900fc8c7 Mon Sep 17 00:00:00 2001 From: Pietro Incardona <i-bird@localhost.localdomain> Date: Wed, 23 Dec 2015 20:29:49 -0500 Subject: [PATCH] Add missing files --- Makefile.am | 31 +++- Memleak_check.cpp | 27 +++ Memleak_check.hpp | 417 ++++++++++++++++++++++++++++++++++++++++++++++ cuda_macro.h | 17 ++ main.cpp | 8 + ptr_info.hpp | 21 +++ 6 files changed, 519 insertions(+), 2 deletions(-) create mode 100644 Memleak_check.cpp create mode 100644 Memleak_check.hpp create mode 100644 cuda_macro.h create mode 100755 main.cpp create mode 100644 ptr_info.hpp diff --git a/Makefile.am b/Makefile.am index 7c618d3..7a117da 100755 --- a/Makefile.am +++ b/Makefile.am @@ -1,3 +1,30 @@ -SUBDIRS = src -bin_PROGRAMS = \ No newline at end of file +LINKLIBS = $(PTHREAD_LIBS) $(OPT_LIBS) $(BOOST_LDFLAGS) $(BOOST_PROGRAM_OPTIONS_LIB) $(CUDA_LIBS) $(BOOST_THREAD_LIB) + +if BUILDCUDA + CUDA_SOURCES=memory/CudaMemory.cu +else + CUDA_SOURCES= +endif + +noinst_PROGRAMS = mem +mem_SOURCES = main.cpp memory/HeapMemory.cpp $(CUDA_SOURCES) Memleak_check.cpp +mem_CXXFLAGS = $(INCLUDES_PATH) $(BOOST_CPPFLAGS) -I/usr/local/include +mem_CFLAGS = +mem_LDADD = $(LINKLIBS) -L/usr/lib64/nvidia-bumblebee/ + +lib_LIBRARIES = libofpmmemory.a libofpmmemory_se2.a +libofpmmemory_a_SOURCES = memory/HeapMemory.cpp $(CUDA_SOURCES) memory/PtrMemory.cpp Memleak_check.cpp +libofpmmemory_a_CXXFLAGS = $(INCLUDES_PATH) $(BOOST_CPPFLAGS) -I/usr/local/include +libofpmmemory_a_CFLAGS = + +libofpmmemory_se2_a_SOURCES = memory/HeapMemory.cpp $(CUDA_SOURCES) memory/PtrMemory.cpp Memleak_check.cpp +libofpmmemory_se2_a_CXXFLAGS = $(INCLUDES_PATH) $(BOOST_CPPFLAGS) -I/usr/local/include -DSE_CLASS2 +libofpmmemory_se2_a_CFLAGS = + +nobase_include_HEADERS = memory/ExtPreAlloc.hpp memory/HeapMemory.hpp memory/memory.hpp memory/PreAllocHeapMemory.hpp memory/PtrMemory.hpp \ +Memleak_check.hpp ptr_info.hpp \ +util/se_util.hpp + +.cu.o : + $(NVCC) $(NVCCFLAGS) -I. $(INCLUDES_PATH) -o $@ -c $< diff --git a/Memleak_check.cpp b/Memleak_check.cpp new file mode 100644 index 0000000..0fbe86c --- /dev/null +++ b/Memleak_check.cpp @@ -0,0 +1,27 @@ +#include "config.h" +#include "Memleak_check.hpp" +#include "ptr_info.hpp" + +// counter for allocation of new memory +long int new_data; + +// counter to delete memory +size_t delete_data; + +// structure that store all the active pointer +std::map<byte_ptr, ptr_info> active_ptr; + +// Running process id +long int process_v_cl; + +// Process to print +long int process_to_print = 0; + +// A way to stop the color +std::string col_stop("\e[0m"); + +// Print a message when allocation with id==msg_on_alloc is performed +long int msg_on_alloc = -1; + +// throw when allocation with id==throw_on_alloc is performed +long int thr_on_alloc = -1; diff --git a/Memleak_check.hpp b/Memleak_check.hpp new file mode 100644 index 0000000..45b25bf --- /dev/null +++ b/Memleak_check.hpp @@ -0,0 +1,417 @@ +#include "config.h" +#include <iostream> +#include <map> +#include <iomanip> + +#ifndef MEMLEAK_CHECK_HPP +#define MEMLEAK_CHECK_HPP + +typedef unsigned char * byte_ptr; + +#ifdef SE_CLASS2 + +/////// POSSIBLE EVENTS ///////// + +#define VCLUSTER_EVENT 0x2001 + +#define VECTOR_EVENT 0x1102 +#define VECTOR_STD_EVENT 0x1101 +#define GRID_EVENT 0x1100 + +#define VECTOR_DIST_EVENT 0x4002 +#define GRID_DIST_EVENT 0x4001 + +#define HEAPMEMORY_EVENT 0x0100 +#define CUDAMEMORY_EVENT 0x0101 + +///////////////////////////////// + +#include "util/se_util.hpp" +#include "ptr_info.hpp" + +#define MEM_ERROR 1300lu + +extern long int msg_on_alloc; +extern long int thr_on_alloc; +extern std::string col_stop; +extern long int new_data; +extern size_t delete_data; + +extern std::map<byte_ptr,ptr_info> active_ptr; + +extern long int process_v_cl; +extern long int process_to_print; + +/*! \brief Check and remove the active pointer + * + * Check and remove the pointer from the active list + * + * \param pointer to check and remove + * + * \return true if the operation succeded, false if the pointer does not exist + * + */ +static bool remove_ptr(const void * ptr) +{ + // Check if the pointer exist + std::map<byte_ptr, ptr_info>::iterator it = active_ptr.find((byte_ptr)ptr); + + // if the element does not exist, print that something wrong happened and return + if ( it == active_ptr.end() ) + { + std::cout << "Error " << __FILE__ << ":" << __LINE__ << " pointer not found " << ptr << "\n"; + ACTION_ON_ERROR(MEM_ERROR); + return false; + } + + // erase the pointer + active_ptr.erase((byte_ptr)ptr); + + return true; +} + +#define PRJ_DEVICES 0 +#define PRJ_DATA 1 +#define PRJ_VCLUSTER 2 +#define PRJ_IO 3 +#define PRJ_PDATA 4 + +/*! \brief Get the color for printing unalloc pointers + * + * \param project_id id of the project + * \param size size of the allocation + * \param col color + * + */ +inline static void get_color(size_t project_id, size_t size, std::string & col) +{ + if (size == 8) + { + switch (project_id) + { + case PRJ_DEVICES: + col = std::string("\e[97m"); + break; + case PRJ_DATA: + col = std::string("\e[95m"); + break; + case PRJ_VCLUSTER: + col = std::string("\e[96m"); + break; + case PRJ_IO: + col = std::string("\e[97m"); + break; + case PRJ_PDATA: + col = std::string("\e[93m"); + break; + } + } + else + { + switch (project_id) + { + case PRJ_DEVICES: + col = std::string("\e[7;92m"); + break; + case PRJ_DATA: + col = std::string("\e[7;95m"); + break; + case PRJ_VCLUSTER: + col = std::string("\e[7;96m"); + break; + case PRJ_IO: + col = std::string("\e[7;97m"); + break; + case PRJ_PDATA: + col = std::string("\e[7;93m"); + break; + } + } +} + +/*! \brief Given the structure id it convert to a human readable structure string + * + * \param project_id id of the project + * \param prj string that identify the project + * + */ +inline static void get_structure(size_t struct_id, std::string & str) +{ + switch (struct_id) + { + case VCLUSTER_EVENT: + str = std::string("Vcluster"); + break; + case VECTOR_STD_EVENT: + str = std::string("Vector_std"); + break; + case VECTOR_EVENT: + str = std::string("Vector_native"); + break; + case GRID_EVENT: + str = std::string("Grid"); + break; + case VECTOR_DIST_EVENT: + str = std::string("Vector distributed"); + break; + case GRID_DIST_EVENT: + str = std::string("Grid distributed"); + break; + case HEAPMEMORY_EVENT: + str = std::string("HeapMemory"); + break; + case CUDAMEMORY_EVENT: + str = std::string("CudaMemory"); + break; + default: + str = std::to_string(struct_id); + } +} + + +/*! \brief Given the project id it convert to a human readable project string + * + * \param project_id id of the project + * \param prj string that identify the project + * + */ +inline static void get_project(size_t project_id, std::string & prj) +{ + switch (project_id) + { + case PRJ_DEVICES: + prj = std::string("devices"); + break; + case PRJ_DATA: + prj = std::string("data"); + break; + case PRJ_VCLUSTER: + prj = std::string("vcluster"); + break; + case PRJ_IO: + prj = std::string("io"); + break; + case PRJ_PDATA: + prj = std::string("pdata"); + break; + } +} + +/*! \brief Print all active structures + * + * Print all active structures + * + */ +static void print_alloc() +{ + std::string col; + std::string sid; + std::string prj; + + for (std::map<byte_ptr,ptr_info>::iterator it = active_ptr.begin(); it != active_ptr.end(); ++it) + { + get_color(it->second.project_id,it->second.size,col); + get_structure(it->second.struct_id,sid); + get_project(it->second.project_id,prj); + + std::cout << col << "Allocated memory " << (void *)it->first << " size=" << it->second.size << " id=" << it->second.id << " structure id=" << std::hex << sid << std::dec << " project id=" << prj << col_stop << "\n"; + } +} + +/* \brief When the allocation id==break_id is performed, print a message + * + * \param break_id + * + */ +static void message_on_alloc(long int break_id) +{ + msg_on_alloc = break_id; +} + +/* \brief When the allocation id==break_id is performed, throw + * + * \param throw_id + * + */ +static void throw_on_alloc(long int throw_id) +{ + thr_on_alloc = throw_id; +} + +/*! \brief Add the new allocated active pointer + * + * Add the new allocated active pointer + * + * \param new data active pointer + * \param sz size of the new allocated memory + * + */ +static bool check_new(const void * data, size_t sz, size_t struct_id, size_t project_id) +{ + // Add a new pointer + new_data++; + ptr_info & ptr = active_ptr[(byte_ptr)data]; + ptr.size = sz; + ptr.id = new_data; + ptr.struct_id = struct_id; + ptr.project_id = project_id; + +#ifdef SE_CLASS2_VERBOSE + if (process_to_print < 0 || process_to_print == process_v_cl) + std::cout << "New data: " << new_data << " " << data << "\n"; +#endif + + if (msg_on_alloc == new_data) + std::cout << "Detected allocation: " << __FILE__ << ":" << __LINE__ << " id=" << msg_on_alloc << "\n"; + + if (thr_on_alloc == new_data) + throw MEM_ERROR; + + return true; +} + +/*! \brief check and delete a pointer + * + * check and delete a pointer from the list of active pointers + * + * \param pointer data + * \return true if the operation to delete succeed + * + */ +static bool check_delete(const void * data) +{ + if (data == NULL) return true; + // Delete the pointer + delete_data++; + bool result = remove_ptr(data); + +#ifdef SE_CLASS2_VERBOSE + if (process_to_print < 0 || process_to_print == process_v_cl) + std::cout << "Delete data: " << delete_data << " " << data << "\n"; +#endif + + return result; +} + +/*! \brief check if the access is valid + * + * check if the access is valid + * + * \param ptr pointer we are going to access + * \param size_access is the size in byte of the data we are fetching + * + * \return true if the pointer is valid + * + */ +static bool check_valid(const void * ptr, size_t size_access) +{ + if (active_ptr.size() == 0) + { + std::cerr << "Error invalid pointer: " << __FILE__ << ":" << __LINE__ << " " << ptr << "\n"; + ACTION_ON_ERROR(MEM_ERROR); + return false; + } + + // get the upper bound + + std::map<byte_ptr, ptr_info>::iterator l_b = active_ptr.upper_bound((byte_ptr)ptr); + + // if there is no memory that satisfy the request + if (l_b == active_ptr.begin()) + { + if (process_to_print < 0 || process_to_print == process_v_cl) + { + std::cerr << "Error invalid pointer: " << __FILE__ << ":" << __LINE__ << " " << ptr << " base allocation id=" << l_b->second.id << "\n"; + ACTION_ON_ERROR(MEM_ERROR); + } + return false; + } + + //! subtract one + l_b--; + + // if there is no memory that satisfy the request + if (l_b == active_ptr.end()) + { + if (process_to_print < 0 || process_to_print == process_v_cl) + { + std::cerr << "Error invalid pointer: " << __FILE__ << ":" << __LINE__ << " " << ptr << " base allocation id=" << l_b->second.id << "\n"; + ACTION_ON_ERROR(MEM_ERROR); + } + return false; + } + + // check if ptr is in the range + + size_t sz = l_b->second.size; + + if (((unsigned char *)l_b->first) + sz < ((unsigned char *)ptr) + size_access) + { + if (process_to_print < 0 || process_to_print == process_v_cl) + { + std::cerr << "Error invalid pointer: " << __FILE__ << ":" << __LINE__ << " " << ptr << " base allocation id=" << l_b->second.id << "\n"; + ACTION_ON_ERROR(MEM_ERROR); + } + return false; + } + + return true; +} + + +/*! \brief check if the access is valid + * + * check if the access is valid + * + * \param ptr pointer we are going to access + * \param size_access is the size in byte of the data we are fetching + * + * \return true if the pointer is valid + * + */ +static long int check_whoami(const void * ptr, size_t size_access) +{ + if (active_ptr.size() == 0) + return -1; + + // get the upper bound + + std::map<byte_ptr, ptr_info>::iterator l_b = active_ptr.upper_bound((byte_ptr)ptr); + + // if there is no memory that satisfy the request + if (l_b == active_ptr.begin()) + return -1; + + //! subtract one + l_b--; + + // if there is no memory that satisfy the request + if (l_b == active_ptr.end()) + return -1; + + // check if ptr is in the range + + size_t sz = l_b->second.size; + + if (((unsigned char *)l_b->first) + sz < ((unsigned char *)ptr) + size_access) + return -1; + + return l_b->second.id; +} + +/*! \brief In case of Parallel application it set the process that print the + * + * \param p_to_print is < 0 (Mean all) + * + */ +static void set_process_to_print(long int p_to_print) +{ + process_to_print = p_to_print; +} + +#else + + + +#endif +#endif diff --git a/cuda_macro.h b/cuda_macro.h new file mode 100644 index 0000000..a554d13 --- /dev/null +++ b/cuda_macro.h @@ -0,0 +1,17 @@ +/* + * cuda_macro.h + * + * Created on: Aug 17, 2014 + * Author: Pietro Incardona + */ + +#include <iostream> + +#define CUDA_SAFE_CALL(call) {\ + cudaError_t err = call;\ + if (cudaSuccess != err) {\ + std::cerr << "Cuda error in file "<< __FILE__ << " in line " << __LINE__ << ": " << cudaGetErrorString(err);\ + }\ +} + + diff --git a/main.cpp b/main.cpp new file mode 100755 index 0000000..836632f --- /dev/null +++ b/main.cpp @@ -0,0 +1,8 @@ +#include <iostream> + +#include "config.h" +#define BOOST_TEST_MODULE "C++ test module for OpenFPM_data project" +#include <boost/test/included/unit_test.hpp> + +#include "memory/HeapMemory_unit_tests.hpp" + diff --git a/ptr_info.hpp b/ptr_info.hpp new file mode 100644 index 0000000..9b28d21 --- /dev/null +++ b/ptr_info.hpp @@ -0,0 +1,21 @@ +/* + * ptr_info.hpp + * + * Created on: Nov 19, 2015 + * Author: i-bird + */ + +#ifndef OPENFPM_DEVICES_SRC_PTR_INFO_HPP_ +#define OPENFPM_DEVICES_SRC_PTR_INFO_HPP_ + + +struct ptr_info +{ + size_t id; + size_t struct_id; + size_t project_id; + size_t size; +}; + + +#endif /* OPENFPM_DEVICES_SRC_PTR_INFO_HPP_ */ -- GitLab