Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:17:24

0001 //==========================================================================
0002 //  AIDA Detector description implementation 
0003 //--------------------------------------------------------------------------
0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0005 // All rights reserved.
0006 //
0007 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0009 //
0010 //  \author Markus Frank
0011 //  \date   2015-11-09
0012 //
0013 //==========================================================================
0014 
0015 // Framework include files
0016 #include <DDG4/Geant4DetectorConstruction.h>
0017 #include <unistd.h>
0018 
0019 // C/C++ include files
0020 
0021 /// Namespace for the AIDA detector description toolkit
0022 namespace dd4hep {
0023 
0024   /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit
0025   namespace sim {
0026 
0027     /// Debug class to dump resources usage during detector construction
0028     /**
0029      *  Debug class to dump resources usage during detector construction
0030      *
0031      *  \author  M.Frank
0032      *  \version 1.0
0033      *  \ingroup DD4HEP_SIMULATION
0034      */
0035     class Geant4DetectorConstructionResources : public Geant4DetectorConstruction   {
0036     public:
0037       /// Class to store the status information of a process from /proc/<pid>/status
0038       /**
0039        *
0040        * \author  M.Frank
0041        * \version 1.0
0042        */
0043       class __attribute__((__packed__)) StatusProcess {
0044       public:
0045         char   comm[399];
0046         char   state;
0047         int    umask;
0048         int    tgid;
0049         int    ngid;
0050         int    pid;
0051         int    ppid;
0052         int    uid;
0053         int    gid;
0054         int    utrace;
0055         int    fdSize;
0056         long   vmPeak;
0057         long   vmSize;
0058         long   vmLock;
0059         long   vmPin;
0060         long   vmHWM;
0061         long   vmRSS;
0062         long   vmRSSano;
0063         long   vmRSSfil;
0064         long   vmRSSshm;
0065         long   vmData;
0066         long   vmStack;
0067         long   vmExe;
0068         long   vmLib;
0069         long   vmPTE;
0070         long   vmSwap;
0071         /// Default constructor
0072         StatusProcess() {}
0073       };
0074       std::unique_ptr<StatusProcess> snapshot;
0075       std::string when   { "geometry|sensitives" };
0076 
0077       void print_status(const char* tag, const StatusProcess& sp) const;
0078       
0079     public:
0080       /// Initializing constructor for DDG4
0081       Geant4DetectorConstructionResources(Geant4Context* ctxt, const std::string& nam);
0082       /// Default destructor
0083       virtual ~Geant4DetectorConstructionResources();
0084       /// Sensitive detector construction callback. Called at "Construct()"
0085       virtual void constructGeo(Geant4DetectorConstructionContext*)  override;
0086       /// Sensitives construction callback. Called at "ConstructSDandField()"
0087       virtual void constructSensitives(Geant4DetectorConstructionContext* ctxt)  override;
0088     };
0089   }    // End namespace sim
0090 }      // End namespace dd4hep
0091 
0092 
0093 // Framework include files
0094 #include <DD4hep/InstanceCount.h>
0095 #include <DD4hep/Printout.h>
0096 #include <DD4hep/Plugins.h>
0097 #include <DD4hep/Detector.h>
0098 
0099 #include <DDG4/Geant4Mapping.h>
0100 #include <DDG4/Geant4Kernel.h>
0101 #include <DDG4/Factories.h>
0102 
0103 #include <stdexcept>
0104 #include <sys/types.h>
0105 #include <sys/stat.h>
0106 #include <fcntl.h>
0107 
0108 using namespace dd4hep::sim;
0109 
0110 DECLARE_GEANT4ACTION(Geant4DetectorConstructionResources)
0111 
0112 namespace  {
0113   
0114   class SysFile  {
0115   public:
0116     class FileDescriptor    {
0117       /// File handle
0118       int m_fd;
0119       
0120     public:
0121       /// Initializing constructor
0122       FileDescriptor(int value) : m_fd(value)      {}
0123       /// Default destructor. Non-virtuality is intended. Do not inherit!
0124       ~FileDescriptor();
0125       /// Access file handle
0126       int get() const      {   return m_fd;   }
0127     };
0128     
0129       
0130   public:
0131     /// File name
0132     std::string m_name;
0133     /// Initializing constructor
0134     SysFile(const char* name) : m_name(name) {}
0135     /// Initializing constructor
0136     SysFile(const std::string& name) : m_name(name) {}
0137     /// Default destructor. Non-virtuality is intended. Do not inherit!
0138     ~SysFile() {}
0139     /// Read buffer from file in  one go
0140     int read(char* buffer, size_t len) const;
0141   };
0142 
0143   /// Default destructor. Non-virtuality is intended. Do not inherit!
0144   SysFile::FileDescriptor::~FileDescriptor()   {
0145     if (m_fd > 0)  ::close(m_fd);
0146     m_fd = 0;
0147   }
0148 
0149   /// Read buffer from file in  one go
0150   int SysFile::read(char* buf, size_t siz) const  {
0151     FileDescriptor fd(::open(m_name.c_str(),O_RDONLY));  
0152     if( fd.get() < 0 )  {
0153       std::string err = "Failed to open "+m_name+" ";
0154       throw std::runtime_error(err+std::make_error_code(std::errc(errno)).message());
0155     }
0156     std::size_t tmp = 0;
0157     while ( tmp < siz )  {
0158       int sc = ::read(fd.get(),buf+tmp,siz-tmp);
0159       if ( sc >  0 ) {
0160         tmp += sc;
0161       }
0162       else if ( sc == 0 )  {
0163         buf[tmp] = 0;
0164         return tmp;
0165       }
0166       else if ( errno == EINTR )  {
0167         printf("EINTR~!!!!\n");
0168         continue;
0169       }
0170       else  {
0171         break;
0172       }
0173     }
0174     if ( tmp != siz )  {
0175       std::string err = "Read of system file "+m_name+" failed:";
0176       throw std::runtime_error(err+std::make_error_code(std::errc(errno)).message());
0177     }
0178     return tmp;
0179   }
0180 
0181   int read_info(Geant4DetectorConstructionResources::StatusProcess& proc, int proc_id) {
0182     char buff[2048], *ptr=buff;
0183     std::string fn = "/proc/"+std::to_string(proc_id)+"/status";
0184     int nitem=0, cnt=SysFile(fn.c_str()).read(buff,sizeof(buff));
0185     if(cnt>0)  {
0186       int ival;
0187       long int lval;
0188 
0189       while(ptr && ptr<(buff+cnt)) {
0190         char* p   = ::strchr(ptr,'\t');
0191         char* end = ::strchr(ptr,'\n');
0192 
0193         ptr = (end) ? end+1 : 0;
0194         if ( 0 == p ) continue;
0195         ++p;
0196         switch(++nitem) {
0197         case 1:   ::sscanf(p,"%s",proc.comm);                  break;
0198         case 2:   ::sscanf(p,"%d",&ival); proc.umask = ival;   break;
0199         case 3:   ::sscanf(p,"%c",&proc.state);                break;
0200         case 4:   ::sscanf(p,"%d",&ival); proc.tgid    = ival; break;
0201         case 5:   ::sscanf(p,"%d",&ival); proc.ngid    = ival; break;
0202         case 6:   ::sscanf(p,"%d",&ival); proc.pid     = ival; break;
0203         case 7:   ::sscanf(p,"%d",&ival); proc.ppid    = ival; break;
0204         case 8:   ::sscanf(p,"%d",&ival); proc.utrace  = ival; break;
0205         case 9:   ::sscanf(p,"%d",&ival); proc.uid     = ival; break;
0206         case 10:  ::sscanf(p,"%d",&ival); proc.gid     = ival; break;
0207         case 11:  ::sscanf(p,"%d",&ival); proc.fdSize  = ival; break;
0208         case 17:  ::sscanf(p,"%ld",&lval); proc.vmPeak  = lval; break;
0209         case 18:  ::sscanf(p,"%ld",&lval); proc.vmSize  = lval; break;
0210         case 19:  ::sscanf(p,"%ld",&lval); proc.vmLock  = lval; break;
0211         case 20:  ::sscanf(p,"%ld",&lval); proc.vmPin   = lval; break;
0212         case 21:  ::sscanf(p,"%ld",&lval); proc.vmHWM   = lval; break;
0213         case 22:  ::sscanf(p,"%ld",&lval); proc.vmRSS   = lval; break;
0214         case 23:  ::sscanf(p,"%ld",&lval); proc.vmRSSano= lval; break;
0215         case 24:  ::sscanf(p,"%ld",&lval); proc.vmRSSfil= lval; break;
0216         case 25:  ::sscanf(p,"%ld",&lval); proc.vmRSSshm= lval; break;
0217         case 26:  ::sscanf(p,"%ld",&lval); proc.vmData  = lval; break;
0218         case 27:  ::sscanf(p,"%ld",&lval); proc.vmStack = lval; break;
0219         case 28:  ::sscanf(p,"%ld",&lval); proc.vmExe   = lval; break;
0220         case 29:  ::sscanf(p,"%ld",&lval); proc.vmLib   = lval; break;
0221         case 30:  ::sscanf(p,"%ld",&lval); proc.vmPTE   = lval; break;
0222         case 31:  ::sscanf(p,"%ld",&lval); proc.vmSwap  = lval; break;
0223         case 32:  return 1;
0224         default:                                                break;
0225         }
0226       }
0227       return 1;
0228     }
0229     return 0;
0230   }
0231 }
0232 
0233 /// Initializing constructor for other clients
0234 Geant4DetectorConstructionResources::Geant4DetectorConstructionResources(Geant4Context* ctxt, const std::string& nam)
0235 : Geant4DetectorConstruction(ctxt,nam)
0236 {
0237   declareProperty("When", this->when);
0238   InstanceCount::increment(this);
0239 }
0240 
0241 /// Default destructor
0242 Geant4DetectorConstructionResources::~Geant4DetectorConstructionResources() {
0243   InstanceCount::decrement(this);
0244 }
0245 
0246 /// Sensitive detector construction callback. Called at "Construct()"
0247 void Geant4DetectorConstructionResources::constructGeo(Geant4DetectorConstructionContext*)   {
0248   if ( this->when.find("geometry") != std::string::npos )  {
0249     this->snapshot = std::make_unique<StatusProcess>();
0250     read_info(*this->snapshot, ::getpid());
0251     this->print_status("ConstructGeo: ", *this->snapshot);
0252   }
0253 }
0254 
0255 void Geant4DetectorConstructionResources::print_status(const char* tag, const StatusProcess& sp) const {
0256   this->always("%s Name:     \t%s", tag, sp.comm);
0257   this->always("%s State:    \t%c", tag, sp.state);
0258   this->always("%s Umask:    \t%8d", tag, sp.umask);
0259   this->always("%s Tgid:     \t%8d", tag, sp.tgid);
0260   this->always("%s Pid:      \t%8d", tag, sp.pid);
0261   this->always("%s PPid:     \t%8d", tag, sp.ppid);
0262   this->always("%s utrace:   \t%8d", tag, sp.utrace);
0263   this->always("%s Uid:      \t%8d", tag, sp.uid);
0264   this->always("%s Gid:      \t%8d", tag, sp.gid);
0265   this->always("%s FDSize:   \t%8d", tag, sp.fdSize);
0266   this->always("%s VmPeak:   \t%8ld kB", tag, sp.vmPeak);
0267   this->always("%s VmSize:   \t%8ld kB", tag, sp.vmSize);
0268   this->always("%s VmLck:    \t%8ld kB", tag, sp.vmLock);
0269   this->always("%s VmHWM:    \t%8ld kB", tag, sp.vmHWM);
0270   this->always("%s VmRSS:    \t%8ld kB", tag, sp.vmRSS);
0271   this->always("%s VmRSS     anon:    \t%8ld kB", tag, sp.vmRSSano);
0272   this->always("%s VmRSS     file:    \t%8ld kB", tag, sp.vmRSSfil);
0273   this->always("%s VmRSS     shm:     \t%8ld kB", tag, sp.vmRSSshm);
0274   this->always("%s VmData:   \t%8ld kB", tag, sp.vmData);
0275   this->always("%s VmStk:    \t%8ld kB", tag, sp.vmStack);
0276   this->always("%s VmExe:    \t%8ld kB", tag, sp.vmExe);
0277   this->always("%s VmLib:    \t%8ld kB", tag, sp.vmLib);
0278   this->always("%s VmPTE:    \t%8ld kB", tag, sp.vmPTE);
0279 }
0280 
0281 /// Sensitive detector construction callback. Called at "ConstructSDandField()"
0282 void Geant4DetectorConstructionResources::constructSensitives(Geant4DetectorConstructionContext*)   {
0283   if ( this->when.find("sensitives") != std::string::npos )  {
0284     StatusProcess rd;
0285     read_info(rd, ::getpid());
0286     this->print_status("ConstructSD:  ", rd);
0287 #if 0
0288     if ( snapshot )   {
0289       const auto& snap = *this->snapshot;
0290        this->always("   --> DIFFERENCE:  FDSize:   \t%8d", rd.fdSize - snap.fdSize);
0291        this->always("   --> DIFFERENCE:  VmPeak:   \t%8ld kB", rd.vmPeak - snap.vmPeak);
0292        this->always("   --> DIFFERENCE:  VmSize:   \t%8ld kB", rd.vmSize - snap.vmSize);
0293        this->always("   --> DIFFERENCE:  VmLck:    \t%8ld kB", rd.vmLock - snap.vmLock);
0294        this->always("   --> DIFFERENCE:  VmHWM:    \t%8ld kB", rd.vmHWM - snap.vmHWM);
0295        this->always("   --> DIFFERENCE:  VmRSS:    \t%8ld kB", rd.vmRSS - snap.vmRSS);
0296        this->always("   --> DIFFERENCE:  VmRSS     anon:    \t%8ld kB", rd.vmRSSano - snap.vmRSSano);
0297        this->always("   --> DIFFERENCE:  VmRSS     file:    \t%8ld kB", rd.vmRSSfil - snap.vmRSSfil);
0298        this->always("   --> DIFFERENCE:  VmRSS     shm:     \t%8ld kB", rd.vmRSSshm - snap.vmRSSshm);
0299        this->always("   --> DIFFERENCE:  VmData:   \t%8ld kB", rd.vmData - snap.vmData);
0300        this->always("   --> DIFFERENCE:  VmStk:    \t%8ld kB", rd.vmStack - snap.vmStack);
0301        this->always("   --> DIFFERENCE:  VmExe:    \t%8ld kB", rd.vmExe - snap.vmExe);
0302        this->always("   --> DIFFERENCE:  VmLib:    \t%8ld kB", rd.vmLib - snap.vmLib);
0303        this->always("   --> DIFFERENCE:  VmPTE:    \t%8ld kB", rd.vmPTE - snap.vmPTE);
0304     }
0305 #endif
0306   }
0307   snapshot.reset();
0308 }