From ea84bca75676ed2bc0a2520256b9056287a71084 Mon Sep 17 00:00:00 2001 From: Rolf Seuster <Rolf.Seuster@cern.ch> Date: Mon, 12 May 2014 18:38:10 +0200 Subject: [PATCH] fix problem under valgrind (RecAlgs-00-00-13) --- Reconstruction/RecAlgs/cmt/requirements | 29 +++ Reconstruction/RecAlgs/src/JobInfo.cxx | 60 +++++++ Reconstruction/RecAlgs/src/JobInfo.h | 53 ++++++ Reconstruction/RecAlgs/src/MemoryAlg.cxx | 124 +++++++++++++ Reconstruction/RecAlgs/src/MemoryAlg.h | 52 ++++++ Reconstruction/RecAlgs/src/TimingAlg.cxx | 165 ++++++++++++++++++ Reconstruction/RecAlgs/src/TimingAlg.h | 55 ++++++ .../src/components/RecAlgs_entries.cxx | 14 ++ .../RecAlgs/src/components/RecAlgs_load.cxx | 4 + 9 files changed, 556 insertions(+) create mode 100755 Reconstruction/RecAlgs/cmt/requirements create mode 100755 Reconstruction/RecAlgs/src/JobInfo.cxx create mode 100755 Reconstruction/RecAlgs/src/JobInfo.h create mode 100755 Reconstruction/RecAlgs/src/MemoryAlg.cxx create mode 100755 Reconstruction/RecAlgs/src/MemoryAlg.h create mode 100755 Reconstruction/RecAlgs/src/TimingAlg.cxx create mode 100755 Reconstruction/RecAlgs/src/TimingAlg.h create mode 100755 Reconstruction/RecAlgs/src/components/RecAlgs_entries.cxx create mode 100755 Reconstruction/RecAlgs/src/components/RecAlgs_load.cxx diff --git a/Reconstruction/RecAlgs/cmt/requirements b/Reconstruction/RecAlgs/cmt/requirements new file mode 100755 index 00000000000..1446e752c35 --- /dev/null +++ b/Reconstruction/RecAlgs/cmt/requirements @@ -0,0 +1,29 @@ +package RecAlgs + +author Rolf Seuster <seuster AT cern.ch> + +public + +use AtlasPolicy AtlasPolicy-* + +private +use StoreGate StoreGate-* Control +use RecEvent RecEvent-* Reconstruction +use AthenaBaseComps AthenaBaseComps-* Control +use GaudiInterface GaudiInterface-* External +use AtlasROOT AtlasROOT-* External +end_private + +#apply_pattern declare_joboptions files="*.py" +#apply_pattern declare_python_modules files="*.py" + +private +library RecAlgs *.cxx components/*.cxx +apply_pattern component_library + +end_private + +#private +#macro cppdebugflags '$(cppdebugflags_s)' +#macro_remove componentshr_linkopts "-Wl,-s" +#end_private diff --git a/Reconstruction/RecAlgs/src/JobInfo.cxx b/Reconstruction/RecAlgs/src/JobInfo.cxx new file mode 100755 index 00000000000..3aa1ad898fa --- /dev/null +++ b/Reconstruction/RecAlgs/src/JobInfo.cxx @@ -0,0 +1,60 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + + +#include "JobInfo.h" + +#include "Cintex/Cintex.h" +#include "Api.h" +#include "G__ci.h" +#include "Class.h" + +//================ Constructor ================================================= + +namespace G__functionscope { + extern int sm_tagdefining; +} + +JobInfo::JobInfo(const std::string& name, ISvcLocator* pSvcLocator) + : + AthAlgorithm(name,pSvcLocator), + m_events(0), + m_last_entries(0), + m_max_entries(G__functionscope::sm_tagdefining), + m_no_warnings(true), + m_printFATAL(false) +{ + declareProperty("PrintFATAL", m_printFATAL,"flag to decide if a FATAL should be printed - protection for Tier0"); +} + +StatusCode JobInfo::execute() +{ + int nc=Cint::G__ClassInfo::GetNumClasses(); + if ( m_events < 2 || nc != m_last_entries ) + { + ATH_MSG_INFO("root's CINTDictionaryArray G__struct : " << nc << " entries are in use"); + ATH_MSG_INFO(" probably around " << m_max_entries << " entries are available (unreliable - use with care !"); + if ( m_no_warnings and nc > 0.9 * m_max_entries ) + { + ATH_MSG_WARNING("CINTDictionary : over 90% filled !!"); + m_no_warnings=false; + } + // will be printed at most twice (m_last_entries will be equal to nc) + if ( nc >= m_max_entries ) + { + if ( m_printFATAL ) + ATH_MSG_FATAL("root's CINTDictionaryArray G__struct : too many entries !! You might experience strange crashes !!"); + else + ATH_MSG_WARNING("root's CINTDictionaryArray G__struct : too many entries !! You might experience strange crashes !!"); + } + + if(msgLvl(MSG::DEBUG)) + for ( int i=m_last_entries; i < nc; ++i ) + ATH_MSG_DEBUG("class " << i << " " << Cint::G__ClassInfo(i).Fullname() ); + m_last_entries=nc; + } + ++m_events; + + return StatusCode::SUCCESS; +} diff --git a/Reconstruction/RecAlgs/src/JobInfo.h b/Reconstruction/RecAlgs/src/JobInfo.h new file mode 100755 index 00000000000..17a3c13292a --- /dev/null +++ b/Reconstruction/RecAlgs/src/JobInfo.h @@ -0,0 +1,53 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef RECALGS_JOBINFO_H +#define RECALGS_JOBINFO_H + +// Gaudi includes +#include "GaudiKernel/ServiceHandle.h" +#include "AthenaBaseComps/AthAlgorithm.h" +#include <string> + +/** @class JobInfo + + +@author Rolf Seuster <seuster AT cern.ch> +*/ + +class ISvcLocator; + +class JobInfo : public AthAlgorithm +{ + public: + + /** Standard Athena-Algorithm Constructor */ + JobInfo(const std::string& name, ISvcLocator* pSvcLocator); + + /** Default Destructor */ + ~JobInfo() {}; + + /** standard Athena-Algorithm method */ + StatusCode initialize() + { return StatusCode::SUCCESS; }; + /** standard Athena-Algorithm method */ + StatusCode execute(); + /** standard Athena-Algorithm method */ + StatusCode finalize() + { return StatusCode::SUCCESS; }; + + private: + + int m_events; + + int m_last_entries; + + int m_max_entries; + + bool m_no_warnings; + + bool m_printFATAL; +}; + +#endif diff --git a/Reconstruction/RecAlgs/src/MemoryAlg.cxx b/Reconstruction/RecAlgs/src/MemoryAlg.cxx new file mode 100755 index 00000000000..c2bc9c24272 --- /dev/null +++ b/Reconstruction/RecAlgs/src/MemoryAlg.cxx @@ -0,0 +1,124 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + + +#include "MemoryAlg.h" +#include "RecEvent/RecoTimingObj.h" +#include "StoreGate/StoreGateSvc.h" + +#include <malloc.h> +#include <stdint.h> + +//================ Constructor ================================================= + +MemoryAlg::MemoryAlg(const std::string& name, ISvcLocator* pSvcLocator) + : + AthAlgorithm(name,pSvcLocator), + m_memoryObjOutputName("unspecified"), + m_usetcmalloc(true) +{ + // template for property declaration + declareProperty("MemoryObjOutputName", m_memoryObjOutputName, "storegate key of output object"); +} + +//================ Initialisation ================================================= + +StatusCode MemoryAlg::initialize() +{ + ATH_MSG_DEBUG( "initialize(); will write out RecoTimingObj with key " << m_memoryObjOutputName); + char *ch = getenv("USETCMALLOC"); + if ( ch && strncmp(ch,"0",1) == 0 ) + m_usetcmalloc=false; + + return StatusCode::SUCCESS; +} + +StatusCode MemoryAlg::execute() +{ + float f0(0); + float f1(0); + RecoTimingObj *t(0); + if(evtStore()->contains<RecoTimingObj>(m_memoryObjOutputName)) + { + ATH_MSG_DEBUG("reading existing object "); + evtStore()->retrieve(t,m_memoryObjOutputName).ignore(); + if ( t->size() ) + f0=(*t)[0]; + if ( t->size() > 0 ) + f1=(*t)[1]; + ATH_MSG_DEBUG("got f0 / f1 " << f0 << " / " << f1); + } + else + { + ATH_MSG_DEBUG("creating new object "); + t=new RecoTimingObj(false); + evtStore()->record(t,m_memoryObjOutputName).ignore(); + } + int a(-1); + FILE *proc = fopen("/proc/self/statm","r"); + if (proc) + fscanf(proc, "%d", &a); + fclose(proc); + float f=float(a) - f0; + t->push_back(f); + ATH_MSG_DEBUG("Memory and delta memory for this event now is: " << f << " (" << f0 << ")" ); + + uintptr_t mem(0); + + char buffer[2048] = {0}; + int out_pipe[2]; + int saved_stderr; + saved_stderr = dup (STDERR_FILENO); + pipe (out_pipe); + dup2 (out_pipe[1], STDERR_FILENO); + close (out_pipe[1]); + malloc_stats (); + // when running under valgrind malloc_stats is a no-op, so reading from the pipe will stall + fprintf(stderr,"\n"); + read (out_pipe[0], buffer, 2047); + // close (STDERR_FILENO); + dup2 (saved_stderr, STDERR_FILENO); + close (out_pipe[0]); + close (saved_stderr); + + ATH_MSG_DEBUG("ROLF " << buffer); + + unsigned int start(0); + while ( start < strlen(buffer) ) + { + int pos(0); + uintptr_t memtmp(0); + int ret; + if ( m_usetcmalloc ) + { +#if __WORDSIZE == 64 + ret = sscanf(&buffer[start], "MALLOC: %lu Bytes in use by application%n", &memtmp, &pos); +#else + ret = sscanf(&buffer[start], "MALLOC: %u Bytes in use by application%n", &memtmp, &pos); +#endif + if ( pos ) + mem=memtmp; + } + else + { +#if __WORDSIZE == 64 + ret = sscanf(&buffer[start], "in use bytes = %lu%n", &memtmp, &pos); +#else + ret = sscanf(&buffer[start], "in use bytes = %u%n", &memtmp, &pos); +#endif + if ( pos ) + mem=memtmp; + } + ATH_MSG_VERBOSE("ROLF rr " << start << " " << ret << " " << memtmp << " " << mem << " len: " << strlen(buffer) << " pos : " << pos ); + while (buffer[start] != '\n' && start<strlen(buffer)) + start += 1; + start += 1; + } + + + t->push_back(float(mem)/1024 - f1); + + /* Success */ + return StatusCode::SUCCESS; +} diff --git a/Reconstruction/RecAlgs/src/MemoryAlg.h b/Reconstruction/RecAlgs/src/MemoryAlg.h new file mode 100755 index 00000000000..f9734b87e26 --- /dev/null +++ b/Reconstruction/RecAlgs/src/MemoryAlg.h @@ -0,0 +1,52 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef RECALGS_MEMORYALG_H +#define RECALGS_MEMORYALG_H + +// Gaudi includes +#include "GaudiKernel/ServiceHandle.h" +#include "AthenaBaseComps/AthAlgorithm.h" +#include <string> +#include <malloc.h> + +/** @class MemoryAlg + +Several of the memory algs can be scheduled. +# Each one saves memory consumption (VMem, VMemPeak, RSS, RSSPeak) +Each one saves memory consumption (VMem, RSS, mallinfo) +to the vector. + +@author Rolf Seuster <seuster AT cern.ch> +*/ + +class MemoryAlg : public AthAlgorithm +{ + public: + + /** Standard Athena-Algorithm Constructor */ + MemoryAlg(const std::string& name, ISvcLocator* pSvcLocator); + + /** Default Destructor */ + ~MemoryAlg() {}; + + /** standard Athena-Algorithm method */ + StatusCode initialize(); + /** standard Athena-Algorithm method */ + StatusCode execute(); + /** standard Athena-Algorithm method */ + StatusCode finalize() + { return StatusCode::SUCCESS; }; + + private: + + /** member variables for algorithm properties: */ + std::string m_memoryObjOutputName; + + struct mallinfo mi; + + bool m_usetcmalloc; + }; + +#endif diff --git a/Reconstruction/RecAlgs/src/TimingAlg.cxx b/Reconstruction/RecAlgs/src/TimingAlg.cxx new file mode 100755 index 00000000000..ea6daa3f811 --- /dev/null +++ b/Reconstruction/RecAlgs/src/TimingAlg.cxx @@ -0,0 +1,165 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + + +#include "TimingAlg.h" +#include "RecEvent/RecoTimingObj.h" +#include "StoreGate/StoreGateSvc.h" + +unsigned int TimingAlg::m_CPUID=0; + +//================ Constructor ================================================= + +TimingAlg::TimingAlg(const std::string& name, ISvcLocator* pSvcLocator) + : + AthAlgorithm(name,pSvcLocator), + m_timingObjOutputName("unspecified"), + m_determineCPUID(true) +{ + // template for property declaration + declareProperty("TimingObjOutputName", m_timingObjOutputName, "storegate key of output object"); + declareProperty("DetermineCPUID", m_determineCPUID,"flag to decide if CPUID should be determined"); +} + +//================ Initialisation ================================================= + +StatusCode TimingAlg::initialize() +{ + ATH_MSG_DEBUG( "initialize(); will write out RecoTimingObj with key " << m_timingObjOutputName); + + // retrieve the StoreGate Service (delete if not needed) + if (!evtStore().retrieve().isSuccess()) { + ATH_MSG_ERROR("Could not retrieve StoreGateSvc!"); + return StatusCode::FAILURE; + } + + if ( m_determineCPUID && ! m_CPUID ) + { + std::string vendor("none"); + std::string stepping("none"); + std::string cpuFamily("none"); + std::string model("none"); + + FILE* file; + unsigned int numProcessors(0); + char line[1024]; + + file = fopen("/proc/cpuinfo", "r"); + numProcessors = 0; + while(fgets(line, 1024, file) != NULL){ + if (strncmp(line, "processor", 9) == 0) numProcessors++; + if (strncmp(line, "vendor_id", 9) == 0) vendor=line; + if (strncmp(line, "stepping", 8) == 0) stepping=line; + if (strncmp(line, "cpu family", 10) == 0) cpuFamily=line; + if (strncmp(line, "model\t" , 6) == 0) model=line; + } + fclose(file); + + size_t found=vendor.find(':'); + if (found!=std::string::npos) + vendor.erase(0,found+2); + + vendor.erase(vendor.size()-1); + stepping.erase(stepping.size()-1); + cpuFamily.erase(cpuFamily.size()-1); + model.erase(model.size()-1); + + ATH_MSG_INFO( "number of CPUs found: " << numProcessors << " of type " << vendor << " " + << cpuFamily << " " << model << " " << stepping ); + + //compress all strings/numbers into 2 uints + m_CPUID_a = 0xFFFFFFFF; + if ( vendor.length() == 12 ) + { + m_CPUID_a = + 0x01000000 * vendor[0] + + 0x00010000 * vendor[1] + + 0x00000100 * vendor[10] + + 0x00000001 * vendor[11]; + + ATH_MSG_DEBUG( "CPU : vendor " << vendor[0] << vendor[1] << " * " << vendor[10] << vendor[11] ); + } + + m_CPUID_b = 0; + int s(0); + s=0xFF; + if (stepping.compare("none") != 0) + sscanf(stepping.c_str(),"stepping\t: %d",&s); + ATH_MSG_VERBOSE( "stepping : " << s ); + if ( s > 255 ) + s = 255; + m_CPUID_b += 0x00000100 * s; + + s=0xFF; + if (cpuFamily.compare("none") != 0) + sscanf(cpuFamily.c_str(),"cpu family\t: %d",&s); + ATH_MSG_VERBOSE( "cpuFamily : " << s ); + if ( s > 255 ) + s = 255; + m_CPUID_b += 0x01000000 * s; + + s=0xFF; + if (model.compare("none") != 0) + sscanf(model.c_str(),"model\t: %d",&s); + ATH_MSG_VERBOSE( "model : " << s ); + if ( s > 255 ) + s = 255; + m_CPUID_b += 0x00010000 * s; + + s = numProcessors; + if ( s > 255 ) + s = 255; + m_CPUID_b += s; + + ATH_MSG_VERBOSE( "CPU : compresses to " << std::hex << m_CPUID_a << " " << m_CPUID_b << std::dec ); + + m_CPUID=1; + } + return StatusCode::SUCCESS; +} + +StatusCode TimingAlg::execute() +{ + float f0(0); + RecoTimingObj *t(0); + if(evtStore()->contains<RecoTimingObj>(m_timingObjOutputName)) + { + ATH_MSG_DEBUG("reading existing object "); + evtStore()->retrieve(t,m_timingObjOutputName).ignore(); + if ( t->size() ) + f0=(*t)[0]; + ATH_MSG_DEBUG("got f0 " << f0 ); + m_CPUID=0; + } + else + { + ATH_MSG_DEBUG("creating new object "); + t=new RecoTimingObj(); + evtStore()->record(t,m_timingObjOutputName).ignore(); + } + + getrusage(RUSAGE_SELF, &r); + float f=float(r.ru_utime.tv_sec+r.ru_stime.tv_sec) + float(r.ru_utime.tv_usec+r.ru_stime.tv_usec)/1000000-f0; + t->push_back(f); + ATH_MSG_DEBUG(" CPU time for this event until now is: " << f); + if ( m_determineCPUID && m_CPUID ) + { + union mytypes_t + { + unsigned int ui; + float f; + } mytypes; + // mytypes.ui=m_CPUID; t->push_back(mytypes.f); + + mytypes.ui=0xF0F0F0F0; t->push_back(mytypes.f); + mytypes.ui=m_CPUID_a; t->push_back(mytypes.f); + mytypes.ui=m_CPUID_b; t->push_back(mytypes.f); + mytypes.ui=0x0F0F0F0F; t->push_back(mytypes.f); + + // don't write out again + m_CPUID=0; + m_determineCPUID=false; + } + return StatusCode::SUCCESS; +} diff --git a/Reconstruction/RecAlgs/src/TimingAlg.h b/Reconstruction/RecAlgs/src/TimingAlg.h new file mode 100755 index 00000000000..65d94d63e15 --- /dev/null +++ b/Reconstruction/RecAlgs/src/TimingAlg.h @@ -0,0 +1,55 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef RECALGS_TIMINGALG_H +#define RECALGS_TIMINGALG_H + +// Gaudi includes +#include "GaudiKernel/ServiceHandle.h" +#include "AthenaBaseComps/AthAlgorithm.h" +#include <string> +#include <sys/time.h> +#include <sys/resource.h> + +/** @class TimingAlg + +Several of the timing algs can be scheduled. +Each one adds the sum of user and system time +from a getrusage call to the vector. + +@author Rolf Seuster <seuster AT cern.ch> +*/ + +class TimingAlg : public AthAlgorithm +{ + public: + + /** Standard Athena-Algorithm Constructor */ + TimingAlg(const std::string& name, ISvcLocator* pSvcLocator); + + /** Default Destructor */ + ~TimingAlg() {}; + + /** standard Athena-Algorithm method */ + StatusCode initialize(); + /** standard Athena-Algorithm method */ + StatusCode execute(); + /** standard Athena-Algorithm method */ + StatusCode finalize() + { return StatusCode::SUCCESS; }; + + private: + + /** member variables for algorithm properties: */ + std::string m_timingObjOutputName; + + bool m_determineCPUID; + struct rusage r; + + static unsigned int m_CPUID; + unsigned int m_CPUID_a; + unsigned int m_CPUID_b; +}; + +#endif diff --git a/Reconstruction/RecAlgs/src/components/RecAlgs_entries.cxx b/Reconstruction/RecAlgs/src/components/RecAlgs_entries.cxx new file mode 100755 index 00000000000..0a0d6a6caf0 --- /dev/null +++ b/Reconstruction/RecAlgs/src/components/RecAlgs_entries.cxx @@ -0,0 +1,14 @@ +#include "GaudiKernel/DeclareFactoryEntries.h" +#include "../TimingAlg.h" +#include "../MemoryAlg.h" +#include "../JobInfo.h" + +DECLARE_ALGORITHM_FACTORY( TimingAlg ) +DECLARE_ALGORITHM_FACTORY( MemoryAlg ) +DECLARE_ALGORITHM_FACTORY( JobInfo ) + +DECLARE_FACTORY_ENTRIES( RecAlgs ) { + DECLARE_ALGORITHM( TimingAlg ); + DECLARE_ALGORITHM( MemoryAlg ); + DECLARE_ALGORITHM( JobInfo ); +} diff --git a/Reconstruction/RecAlgs/src/components/RecAlgs_load.cxx b/Reconstruction/RecAlgs/src/components/RecAlgs_load.cxx new file mode 100755 index 00000000000..36c0d478e78 --- /dev/null +++ b/Reconstruction/RecAlgs/src/components/RecAlgs_load.cxx @@ -0,0 +1,4 @@ +#include "GaudiKernel/LoadFactoryEntries.h" + +LOAD_FACTORY_ENTRIES( RecAlgs ) + -- GitLab