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

Last change on this file since 2419 was 2419, checked in by jderouillat, 21 months ago

Update the memory log system using plotly and CSV files, a dedicated viewer has been added.

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