Global.cc 9.31 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
#include "Global.h"
18
#include "Initfile.h"
19
20
21
22
#include "Element.h"
#include "Line.h"
#include "Triangle.h"
#include "Tetrahedron.h"
23
24
25
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
#include "petsc.h"
#endif
26
27
28
namespace AMDiS {

  const char *funcName = NULL;
29
30

#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
31
  bool Msg::outputMainRank = true;
32
33
#endif

Thomas Witkowski's avatar
Blub  
Thomas Witkowski committed
34
  ThreadPrivate<const char *> Msg::oldFuncName(NULL);
35
36
  std::ostream* Msg::out = NULL;
  std::ostream* Msg::error = NULL;
37
  int Global::dimOfWorld = 0;
38
  std::vector<std::vector<int> > Global::geoIndexTable;
39
40
41
42
  int Msg::msgInfo = 10;
  bool Msg::msgWait = true;

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

49

50
51
52
53
54
  void Msg::wait(bool w)
  {
    FUNCNAME("Msg::wait()");

    if (w) {
55
      std::string line;
56
      MSG("wait for <enter> ...");
57
58
      std::cin >> line;
//       char* result = fgets(line, 9, stdin);
59
60
61
    }
  }

62

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

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

80

81
  void Msg::change_error_out(std::ofstream *fp)
82
  {
83
84
85
    FUNCNAME("Msg::change_error_out()");

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

98

99
100
  void Msg::open_error_file(const char *filename, OPENMODE type)
  {
101
    FUNCNAME("Msg::open_error_file()");
102
    std::ofstream *fp;
103

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

      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");
    }
118
119
  }

120

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

128
    if (!out) 
129
      out = &std::cout;
130

Thomas Witkowski's avatar
Blub  
Thomas Witkowski committed
131
    if (funcName &&  oldFuncName.get() != funcName) {
132
      PRINT_LINE((*out), funcName << ":" << std::endl);
133
    } else if (!funcName) {
134
      PRINT_LINE((*out), "*unknown function*" << std::endl);
135
    }
136
137
    PRINT_LINE((*out), "               ");

Thomas Witkowski's avatar
Blub  
Thomas Witkowski committed
138
    oldFuncName.set(funcName);
139
140
  }

141

142
  void Msg::print_error_funcname(const char *funcName, const char *file, int line)
143
144
145
  {
    static int old_line = -1;

146
    if (!error) 
147
      error = &std::cerr;
148

149
150
    std::stringstream oss;

Thomas Witkowski's avatar
Blub  
Thomas Witkowski committed
151
    if (funcName && oldFuncName.get() != funcName) {
152
      oss << funcName << ": ";
153
    } else if (!funcName) {
154
      if (line-old_line > 5) 
155
	oss << "*unknown function*";
156
    }
157

Thomas Witkowski's avatar
Blub  
Thomas Witkowski committed
158
    if (oldFuncName.get() != funcName) {
159
      oss << "ERROR in " << file << ", line " << line << std::endl;;
Thomas Witkowski's avatar
Blub  
Thomas Witkowski committed
160
      oldFuncName.set(funcName);
161
    } else if (line - old_line > 5)
162
      oss << "ERROR in " << file << ", line " << line << "\n" << std::endl;
163

164
    PRINT_LINE((*error), oss.str());
165
166
167
    old_line = line;
  }

168

169
170
  void Msg::print_error_exit(const char *format, ...)
  {
171
172
    va_list arg;
    char buff[255];
173

174
    if (!error) 
175
      error = &std::cerr;
176
177
178

    va_start(arg, format);
    vsprintf(buff, format, arg);
179
    PRINT_LINE((*error), buff);
180
    va_end(arg);
181
182
183
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
    PetscError(MPI_COMM_WORLD, __LINE__, "Msg::print_error_exit", "Global.cc", "src/", 1, PETSC_ERROR_INITIAL, buff);
#else
184
    throw std::runtime_error(buff);
185
#endif
186
187
188
    exit(1);
  }

189

190
191
  void Msg::print_error(const char *format, ...)
  {
192
193
    va_list arg;
    char buff[255];
194
195


196
    if (!error) 
197
      error = &std::cerr;
198
199
200

    va_start(arg, format);
    vsprintf(buff, format, arg);
201
    PRINT_LINE((*error), buff);
202
203
204
    va_end(arg);
  }

205

206
207
208
209
  void Msg::print_warn_funcname(const char *funcName,
				const char *file, 
				int line)
  {
Thomas Witkowski's avatar
Thomas Witkowski committed
210
211
212
213
214
215
216
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
#if (DEBUG == 0)
    if (outputMainRank && MPI::COMM_WORLD.Get_rank() != 0)
      return;
#endif
#endif

217
    static int old_line = -1;
218

219
    if (!out) 
220
      out = &std::cout;
221

222
223
    std::stringstream oss;

Thomas Witkowski's avatar
Blub  
Thomas Witkowski committed
224
    if (funcName  &&  oldFuncName.get() != funcName) {
225
226
227
      oss << funcName << ": ";
    } else if (!funcName) {
      oss << "*unknown function*";
228
    }
229

Thomas Witkowski's avatar
Blub  
Thomas Witkowski committed
230
    if (oldFuncName.get() != funcName) {
231
      oss << "WARNING in " << file << ", line " << line << std::endl;
Thomas Witkowski's avatar
Blub  
Thomas Witkowski committed
232
      oldFuncName.set(funcName);
233
234
235
236
    } else if (line - old_line > 5) {
      oss << "WARNING in " << file << ", line " << line << std::endl;
    }

237
238
239
    if (oss.str() != "") 
      PRINT_LINE((*out), oss.str());
    
240
241
242
    old_line = line;
  }

243

244
245
  void Msg::print_warn(const char *format, ...)
  {
Thomas Witkowski's avatar
Thomas Witkowski committed
246
247
248
249
250
251
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
#if (DEBUG == 0)
    if (outputMainRank && MPI::COMM_WORLD.Get_rank() != 0)
      return;
#endif
#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
    PRINT_LINE((*out), buff);
261
262
263
264
265
266
    va_end(arg);
  }


  void Msg::print(const char *format, ...)
  {
Thomas Witkowski's avatar
Blub  
Thomas Witkowski committed
267
#ifndef SUPPRESS_OUTPUT
268
269
270
271
272
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
    if (outputMainRank && MPI::COMM_WORLD.Get_rank() != 0)
      return;
#endif

273
274
    va_list arg;
    char buff[255];
275
276

    if (!out) 
277
      out = &std::cout;
278
279
280

    va_start(arg, format);
    vsprintf(buff, format, arg);
281
    (*out) << buff;
282
    va_end(arg);
Thomas Witkowski's avatar
Blub  
Thomas Witkowski committed
283
#endif
284
285
  }

286

287
288
289
290
291
292
  void Global::init()
  {
    int d = -1;

    // get dimension
    TEST_EXIT(Parameters::initialized())("Parameters not initialized!\n");
293
    Parameters::get("dimension of world",d,0);
294
    TEST_EXIT(d > 0)("Cannot initialize dimension!\n");
295
    TEST_EXIT((d == 1) || (d == 2) || (d == 3))("Invalid world dimension %d!\n",d);
296
297
298
299

    // set dimension
    dimOfWorld = d;

300
301
302
303
304
    // 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);
305
306
      for (int j = 0; j < geoTableSize; j++)
	geoIndexTable[i][j] = 0;      
307
308
    }

309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
    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);
    }
327

328
    // set msgWait
329
    Msg::setMsgWait(!(Parameters::getMsgWait() == 0));
330
331
  }

332

333
334
  void Global::clear()
  {
Thomas Witkowski's avatar
Thomas Witkowski committed
335
336
337
    delete referenceElement[1];
    delete referenceElement[2];
    delete referenceElement[3];
338
  }
339

340

341
342
  int fac(int i)
  {
343
344
345
346
    if (i <= 1) 
      return 1;
    else 
      return i * fac(i - 1);
347
348
  }

349

350
351
352
353
354
355
  void waitSec(int seconds)
  {
    clock_t endwait = clock () + seconds * CLOCKS_PER_SEC;
    while (clock() < endwait) {}
  }

356

357
  void processMemUsage(double& vm_usage, double& resident_set, bool inMegaByte)
358
  {
359
#ifndef _WIN32
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
    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;
387
    vm_usage = vsize / 1024.0;
388
    resident_set = rss * page_size_kb;
389
390
391
392
393

    if (inMegaByte) {
      vm_usage /= 1024.0;
      resident_set /= 1024.0;
    }
394
395
396
#else
    ERROR("Function not available under MS Windows\n");
#endif
397
398
399
  }


400
}