source: XIOS3/trunk/src/mem_checker.cpp @ 2420

Last change on this file since 2420 was 2420, checked in by jderouillat, 18 months ago

Add an option (log_memory : set to false by default), to activate memory monitoring. Logs are now buffered.

  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 4.5 KB
Line 
1#include "mem_checker.hpp"
2#include "cxios.hpp"
3#include "mpi.hpp"
4#include <string>
5#include <map>
6#include <iostream>
7#include <sstream>
8
9#include <fcntl.h>
10#include <iomanip>
11#include <unistd.h>
12#include <cstring>
13
14namespace xios
15{
16  CMemChecker CMemChecker::dummy_("") ;
17  std::map<std::string,CMemChecker> CMemChecker::allMemChecker_;
18  bool CMemChecker::enabled_=true;
19  bool CMemChecker::first_=true;
20  double CMemChecker::vsize_init_=0;
21  double CMemChecker::time_init_=0;
22  std::ofstream CMemChecker::fout_;
23  int CMemChecker::flush_counter_=1;
24 
25  CMemChecker::CMemChecker(const std::string& name) : name_(name) 
26  { 
27    if (first_) check() ;
28    reset();
29  }
30
31  void CMemChecker::check(void)
32  {
33    std::ifstream statStream("/proc/self/stat",std::ios_base::in);
34    enabled_ &= statStream.good() ;
35    first_=false ;
36  }
37  double CMemChecker::getMem(void)
38  {
39    if (first_) check() ;
40    if (!enabled_) return 0;
41    std::ifstream statStream("/proc/self/stat",std::ios_base::in);
42    std::string dummy ;
43    for(int i=1;i<=22;i++) statStream>>dummy ;
44    unsigned long vsize; 
45    statStream>>vsize ;
46    return vsize ;
47  }
48  double CMemChecker::getMemRSS(void)
49  {
50    //sleep( 1 ) ;
51    if (first_) check() ;
52    if (!enabled_) return 0;
53    std::ifstream statStream("/proc/self/stat",std::ios_base::in);
54    std::string dummy ;
55    for(int i=1;i<=23;i++) statStream>>dummy ;
56    double vsize; 
57    statStream>>vsize ;
58    if (vsize_init_==0) {
59      vsize_init_ = vsize;
60      time_init_=MPI_Wtime();
61    }
62    vsize -= vsize_init_;
63    vsize *= 4096; //getconf("PAGE_SIZE");
64    return vsize ;
65  }
66  void CMemChecker::logMem( std::string id, bool finalizeLog )
67  {
68    if ( !CXios::logMemory ) return ;
69
70    int rk = 0;
71    MPI_Comm_rank( MPI_COMM_WORLD, &rk );
72    std::string logName("xios_memory_"+std::to_string(rk)+".csv");
73    double mem = getMemRSS();
74    if (!mem) {
75      fout_.open( logName );
76      fout_ << "time,event,memory" << std::endl;
77    }
78
79    fout_.precision(4);
80    // Time format : YYYY-MM-DD HH:MM:SS.XXX -> seconds * 1000.
81    fout_ << (MPI_Wtime()-time_init_) << "," << id << "," << mem/1000000. << std::endl;
82
83    if ((MPI_Wtime()-time_init_)>flush_counter_*600.)
84    {
85      fout_.flush();
86      flush_counter_++;
87    }
88   
89    if (finalizeLog)
90    {
91      fout_.close();
92    }
93  }
94
95 
96  void CMemChecker::suspend(void)
97  {
98    if (first_) check() ;
99    if (!enabled_) return ;
100    if (!suspended_) cumulatedMem_ += getMem() - lastMem_;
101    suspended_ = true;
102  }
103 
104  void CMemChecker::resume(void)
105  {
106    if (first_) check() ;
107    if (!enabled_) return ;
108    if (suspended_) lastMem_ = getMem();
109    suspended_ = false;
110  }
111
112  void CMemChecker::suspendRSS(void)
113  {
114    if (first_) check() ;
115    if (!enabled_) return ;
116    if (!suspended_) cumulatedMem_ += getMemRSS() - lastMem_;
117    suspended_ = true;
118  }
119 
120  void CMemChecker::resumeRSS(void)
121  {
122    if (first_) check() ;
123    if (!enabled_) return ;
124    if (suspended_) lastMem_ = getMemRSS();
125    suspended_ = false;
126  }
127 
128
129  void CMemChecker::reset(void)
130  {
131    if (first_) check() ;
132    if (!enabled_) return ;
133    cumulatedMem_ = 0.;
134    suspended_ = true;
135  }
136 
137  double CMemChecker::getCumulatedMem(void)
138  {
139    if (first_) check() ;
140    if (!enabled_) return 0;
141    return cumulatedMem_;
142  }
143 
144  CMemChecker& CMemChecker::get(const std::string name)
145  {
146    if (first_) check() ;
147    if (!enabled_) return dummy_ ;
148    else
149    {
150      std::map<std::string,CMemChecker>::iterator it = allMemChecker_.find(name);
151      if (it == allMemChecker_.end())
152        it = allMemChecker_.insert(std::make_pair(name, CMemChecker(name))).first;
153      return it->second;
154    }
155  }
156
157  std::string CMemChecker::getAllCumulatedMem(void)
158  {
159    if (first_) check() ;
160    if (!enabled_) return std::string(" MemChecker : memory consumption report not available") ; 
161    std::ostringstream strOut ;
162    const double Kb=1024 ;
163    const double Mb=Kb*1024 ;
164    const double Gb=Mb*1024 ;
165    const double Tb=Gb*1024 ;
166    for(std::map<std::string,CMemChecker>::iterator it=allMemChecker_.begin();it!=allMemChecker_.end();++it)
167    { 
168      strOut<<"MemChecker : "<<it->first<<"    -->   consumed memory : " ;
169      double mem=it->second.getCumulatedMem() ;
170      if (mem>=Tb) strOut<< mem / Tb<<" Tb"<<std::endl ;
171      else if (mem>=Gb) strOut<< mem / Gb<<" Gb"<<std::endl ;
172      else if (mem>=Mb) strOut<< mem / Mb<<" Mb"<<std::endl ;
173      else if (mem>=Kb) strOut<< mem / Kb<<" Kb"<<std::endl ;
174      else strOut<< mem <<" bytes"<<std::endl ;
175    }
176    return strOut.str() ;
177  }
178}
Note: See TracBrowser for help on using the repository browser.