Liebe Gitlab-Nutzer, lieber Gitlab-Nutzer, es ist nun möglich sich mittels des ZIH-Logins/LDAP an unserem Dienst anzumelden. Ein Anmelden über dieses erzeugt ein neues Konto. Das alte Konto ist über den Reiter "Standard" erreichbar. Die Administratoren

Dear Gitlab user, it is now possible to log in to our service using the ZIH login/LDAP. Logging in via this will create a new account. The old account can be accessed via the "Standard" tab. The administrators

Global.cc 8.67 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 23 24 25 26
#include "Element.h"
#include "Line.h"
#include "Triangle.h"
#include "Tetrahedron.h"

namespace AMDiS {

  const char *funcName = NULL;
27 28

#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
29
  bool Msg::outputMainRank = true;
30 31
#endif

Thomas Witkowski's avatar
Blub  
Thomas Witkowski committed
32
  ThreadPrivate<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
  void Msg::wait(bool w)
  {
    FUNCNAME("Msg::wait()");

    if (w) {
      char line[10];
      MSG("wait for <enter> ...");
Praetorius, Simon's avatar
Praetorius, Simon committed
55
      char* result = fgets(line, 9, stdin);
56 57 58
    }
  }

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

Thomas Witkowski's avatar
Blub  
Thomas Witkowski committed
128
    if (funcName &&  oldFuncName.get() != 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), "               ");

Thomas Witkowski's avatar
Blub  
Thomas Witkowski committed
135
    oldFuncName.set(funcName);
136 137
  }

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;

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

Thomas Witkowski's avatar
Blub  
Thomas Witkowski committed
155
    if (oldFuncName.get() != funcName) {
156
      oss << "ERROR in " << file << ", line " << line << std::endl;;
Thomas Witkowski's avatar
Blub  
Thomas Witkowski committed
157
      oldFuncName.set(funcName);
158
    } 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;

Thomas Witkowski's avatar
Blub  
Thomas Witkowski committed
210
    if (funcName  &&  oldFuncName.get() != funcName) {
211 212 213
      oss << funcName << ": ";
    } else if (!funcName) {
      oss << "*unknown function*";
214
    }
215

Thomas Witkowski's avatar
Blub  
Thomas Witkowski committed
216
    if (oldFuncName.get() != funcName) {
217
      oss << "WARNING in " << file << ", line " << line << std::endl;
Thomas Witkowski's avatar
Blub  
Thomas Witkowski committed
218
      oldFuncName.set(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, ...)
  {
Thomas Witkowski's avatar
Blub  
Thomas Witkowski committed
247
#ifndef SUPPRESS_OUTPUT
248 249 250 251 252
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
    if (outputMainRank && MPI::COMM_WORLD.Get_rank() != 0)
      return;
#endif

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

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

    va_start(arg, format);
    vsprintf(buff, format, arg);
261
    (*out) << buff;
262
    va_end(arg);
Thomas Witkowski's avatar
Blub  
Thomas Witkowski committed
263
#endif
264 265
  }

266

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

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

    // set dimension
    dimOfWorld = d;

280 281 282 283 284
    // 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);
285 286
      for (int j = 0; j < geoTableSize; j++)
	geoIndexTable[i][j] = 0;      
287 288
    }

289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306
    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);
    }
307

308
    // set msgWait
309
    Msg::setMsgWait(!(Parameters::getMsgWait() == 0));
310 311
  }

312

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

320

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

329

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

336

337
  void processMemUsage(double& vm_usage, double& resident_set, bool inMegaByte)
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
  {
    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;
366
    vm_usage = vsize / 1024.0;
367
    resident_set = rss * page_size_kb;
368 369 370 371 372

    if (inMegaByte) {
      vm_usage /= 1024.0;
      resident_set /= 1024.0;
    }
373 374 375
  }


376
}