Global.cc 8.54 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
//
// Software License for AMDiS
//
// Copyright (c) 2010 Dresden University of Technology 
// All rights reserved.
// Authors: Simon Vey, Thomas Witkowski et al.
//
// This file is part of AMDiS
//
// See also license.opensource.txt in the distribution.


13
14
15
16
#include <stdarg.h>
#include <stdio.h>
#include <sstream>

17
18
19
20
21
22
23
24
25
26
#include "Global.h"
#include "Parameters.h"
#include "Element.h"
#include "Line.h"
#include "Triangle.h"
#include "Tetrahedron.h"

namespace AMDiS {

  const char *funcName = NULL;
27
28
29
30
31

#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
  bool Msg::outputMainRank = false;
#endif

32
  const char *Msg::oldFuncName = NULL;
33
34
  std::ostream* Msg::out = NULL;
  std::ostream* Msg::error = NULL;
35
  int Global::dimOfWorld = 0;
36
  std::vector<std::vector<int> > Global::geoIndexTable;
37
38
39
40
  int Msg::msgInfo = 10;
  bool Msg::msgWait = true;

  Element *Global::referenceElement[4] = 
41
    { NULL, 
Thomas Witkowski's avatar
Thomas Witkowski committed
42
43
44
      new Line(NULL), 
      new Triangle(NULL), 
      new Tetrahedron(NULL) 
Thomas Witkowski's avatar
Thomas Witkowski committed
45
    };
46

47

48
49
50
51
52
53
54
55
56
57
58
  void Msg::wait(bool w)
  {
    FUNCNAME("Msg::wait()");

    if (w) {
      char line[10];
      MSG("wait for <enter> ...");
      fgets(line, 9, stdin);
    }
  }

59

60
  void Msg::change_out(std::ostream  *fp)
61
62
63
64
  {
    FUNCNAME("Msg::change_out()");
  
    if (fp) {
65
66
      if (out && *out != std::cout && *out != std::cerr) {
	dynamic_cast< std::ofstream*>(out)->close();
67
68
69
70
71
72
73
	delete out;
      }

      out = fp;
    } else {
      ERROR("file pointer is pointer to nil;\n");
      ERROR("use previous stream for errors furthermore\n");
74
    } 
75
76
  }

77

78
  void Msg::change_error_out(std::ofstream *fp)
79
  {
80
81
82
    FUNCNAME("Msg::change_error_out()");

    if (fp) {
83
      if (error && *error != std::cout && *error != std::cerr) {
84
	dynamic_cast< std::ofstream*>(error)->close();
85
	delete error;
86
      }
87
88
89
90
91
92
      
      error = fp;
    } else {
      ERROR("file pointer is pointer to nil;\n");
      ERROR("use previous stream for errors furthermore\n");
    }
93
94
  }

95

96
97
  void Msg::open_error_file(const char *filename, OPENMODE type)
  {
98
    FUNCNAME("Msg::open_error_file()");
99
    std::ofstream *fp;
100

101
102
    if (filename && (fp = new std::ofstream(filename, type))) {
      if (error && *error != std::cout && *error != std::cerr) {
103
	dynamic_cast< std::ofstream*>(error)->close();
104
	delete error;
105
      }
106
107
108
109
110
111
112
113
114

      error = fp;
    } else {
      if (filename)
	ERROR("can not open %s;\n", filename);
      else
	ERROR("no filename specified;\n");
      ERROR("use previous stream for errors furthermore\n");
    }
115
116
  }

117

118
119
  void Msg::print_funcname(const char *funcName)
  {
120
121
122
123
124
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
    if (outputMainRank && MPI::COMM_WORLD.Get_rank() != 0)
      return;
#endif

125
    if (!out) 
126
      out = &std::cout;
127
128

    if (funcName &&  oldFuncName != funcName) {
129
      PRINT_LINE((*out), funcName << ":" << std::endl);
130
    } else if (!funcName) {
131
      PRINT_LINE((*out), "*unknown function*" << std::endl);
132
    }
133
134
    PRINT_LINE((*out), "               ");

135
136
137
    oldFuncName = funcName;
  }

138

139
  void Msg::print_error_funcname(const char *funcName, const char *file, int line)
140
141
142
  {
    static int old_line = -1;

143
    if (!error) 
144
      error = &std::cerr;
145

146
147
    std::stringstream oss;

148
    if (funcName && oldFuncName != funcName) {
149
      oss << funcName << ": ";
150
    } else if (!funcName) {
151
      if (line-old_line > 5) 
152
	oss << "*unknown function*";
153
    }
154

155
    if (oldFuncName != funcName) {
156
      oss << "ERROR in " << file << ", line " << line << std::endl;;
157
158
      oldFuncName = funcName;
    } else if (line - old_line > 5)
159
      oss << "ERROR in " << file << ", line " << line << "\n" << std::endl;
160

161
    PRINT_LINE((*error), oss.str());
162
163
164
    old_line = line;
  }

165

166
167
  void Msg::print_error_exit(const char *format, ...)
  {
168
169
    va_list arg;
    char buff[255];
170

171
    if (!error) 
172
      error = &std::cerr;
173
174
175

    va_start(arg, format);
    vsprintf(buff, format, arg);
176
    PRINT_LINE((*error), buff);
177
178
179
180
181
    va_end(arg);

    exit(1);
  }

182

183
184
  void Msg::print_error(const char *format, ...)
  {
185
186
    va_list arg;
    char buff[255];
187
188


189
    if (!error) 
190
      error = &std::cerr;
191
192
193

    va_start(arg, format);
    vsprintf(buff, format, arg);
194
    PRINT_LINE((*error), buff);
195
196
197
    va_end(arg);
  }

198

199
200
201
202
  void Msg::print_warn_funcname(const char *funcName,
				const char *file, 
				int line)
  {
203
    static int old_line = -1;
204

205
    if (!out) 
206
      out = &std::cout;
207

208
209
    std::stringstream oss;

210
    if (funcName  &&  oldFuncName != funcName) {
211
212
213
      oss << funcName << ": ";
    } else if (!funcName) {
      oss << "*unknown function*";
214
    }
215

216
    if (oldFuncName != funcName) {
217
      oss << "WARNING in " << file << ", line " << line << std::endl;
218
      oldFuncName = funcName;
219
220
221
222
    } else if (line - old_line > 5) {
      oss << "WARNING in " << file << ", line " << line << std::endl;
    }

223
224
225
    if (oss.str() != "") 
      PRINT_LINE((*out), oss.str());
    
226
227
228
    old_line = line;
  }

229

230
231
  void Msg::print_warn(const char *format, ...)
  {
232
233
    va_list arg;
    char buff[255];
234

235
    if (!out) 
236
      out = &std::cout;
237
238
239

    va_start(arg, format);
    vsprintf(buff, format, arg);
240
    PRINT_LINE((*out), buff);
241
242
243
244
245
246
    va_end(arg);
  }


  void Msg::print(const char *format, ...)
  {
247
248
249
250
251
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
    if (outputMainRank && MPI::COMM_WORLD.Get_rank() != 0)
      return;
#endif

252
253
    va_list arg;
    char buff[255];
254
255

    if (!out) 
256
      out = &std::cout;
257
258
259

    va_start(arg, format);
    vsprintf(buff, format, arg);
260
    (*out) << buff;
261
262
263
    va_end(arg);
  }

264

265
266
267
268
269
270
  void Global::init()
  {
    int d = -1;

    // get dimension
    TEST_EXIT(Parameters::initialized())("Parameters not initialized!\n");
271
272
    Parameters::getGlobalParameter(0, "dimension of world","%d",&d);
    TEST_EXIT(d > 0)("Cannot initialize dimension!\n");
273
    TEST_EXIT((d == 1) || (d == 2) || (d == 3))("Invalid world dimension %d!\n",d);
274
275
276
277

    // set dimension
    dimOfWorld = d;

278
279
280
281
282
    // prepare geoIndex-Table
    int geoTableSize = abs(static_cast<int>(MINPART)) + MAXPART + 1;
    geoIndexTable.resize(4);
    for (int i = 0; i < 4; i++) {
      geoIndexTable[i].resize(geoTableSize);
283
284
      for (int j = 0; j < geoTableSize; j++)
	geoIndexTable[i][j] = 0;      
285
286
    }

287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
    geoIndexTable[0][PARTS - MINPART] = 1;
    geoIndexTable[0][VERTEX - MINPART] = 1;
    geoIndexTable[0][EDGE - MINPART] = 0;
    geoIndexTable[0][FACE - MINPART] = 0;
    geoIndexTable[0][WORLD - MINPART] = dimOfWorld;

    for (int i = 1; i < 4; i++) {
      geoIndexTable[i][CENTER - MINPART] = referenceElement[i]->getGeo(CENTER);
      geoIndexTable[i][VERTEX - MINPART] = referenceElement[i]->getGeo(VERTEX);
      geoIndexTable[i][EDGE - MINPART] = referenceElement[i]->getGeo(EDGE);
      geoIndexTable[i][FACE - MINPART] = referenceElement[i]->getGeo(FACE);
      geoIndexTable[i][DIMEN - MINPART] = referenceElement[i]->getGeo(DIMEN);
      geoIndexTable[i][PARTS - MINPART] = referenceElement[i]->getGeo(PARTS);
      geoIndexTable[i][NEIGH - MINPART] = referenceElement[i]->getGeo(NEIGH);
      geoIndexTable[i][WORLD - MINPART] = dimOfWorld;
      geoIndexTable[i][BOUNDARY - MINPART] = referenceElement[i]->getGeo(BOUNDARY);
      geoIndexTable[i][PROJECTION - MINPART] = referenceElement[i]->getGeo(PROJECTION);
    }
305

306
307
308
    // set msgWait
    Parameters::getGlobalParameter(0, "WAIT", "%d", &d);  
    Msg::setMsgWait(!(d == 0));
309
310
  }

311

312
313
  void Global::clear()
  {
Thomas Witkowski's avatar
Thomas Witkowski committed
314
315
316
    delete referenceElement[1];
    delete referenceElement[2];
    delete referenceElement[3];
317
  }
318

319

320
321
  int fac(int i)
  {
322
323
324
325
    if (i <= 1) 
      return 1;
    else 
      return i * fac(i - 1);
326
327
  }

328

329
330
331
332
333
334
  void waitSec(int seconds)
  {
    clock_t endwait = clock () + seconds * CLOCKS_PER_SEC;
    while (clock() < endwait) {}
  }

335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369

  void processMemUsage(double& vm_usage, double& resident_set)
  {
    using std::ios_base;
    using std::ifstream;
    using std::string;
    
    vm_usage     = 0.0;
    resident_set = 0.0;
    
    // 'file' stat seems to give the most reliable results    
    ifstream stat_stream("/proc/self/stat",ios_base::in);
    
    // dummy vars for leading entries in stat that we don't care about
    string pid, comm, state, ppid, pgrp, session, tty_nr;
    string tpgid, flags, minflt, cminflt, majflt, cmajflt;
    string utime, stime, cutime, cstime, priority, nice;
    string O, itrealvalue, starttime;
    
    // the two fields we want    
    unsigned long vsize;
    long rss;
    
    stat_stream >> pid >> comm >> state >> ppid >> pgrp >> session >> tty_nr
		>> tpgid >> flags >> minflt >> cminflt >> majflt >> cmajflt
		>> utime >> stime >> cutime >> cstime >> priority >> nice
		>> O >> itrealvalue >> starttime >> vsize >> rss;

    // in case x86-64 is configured to use 2MB pages    
    long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024;
    vm_usage     = vsize / 1024.0;
    resident_set = rss * page_size_kb;
  }


370
}