AdaptInstationary.cc 12.3 KB
Newer Older
1
2
3
4
5
6
7
8
9
#include "AdaptInstationary.h"
#include "Parameters.h"
#include "Estimator.h"
#include "ProblemIterationInterface.h"
#include "ProblemTimeInterface.h"
#include "Serializer.h"

namespace AMDiS {

Thomas Witkowski's avatar
Thomas Witkowski committed
10
  AdaptInstationary::AdaptInstationary(std::string name,
11
				       ProblemIterationInterface *problemStat,  
12
13
14
				       AdaptInfo *info,
				       ProblemTimeInterface *problemInstat,
				       AdaptInfo *initialInfo,
15
				       time_t initialTimestampSet)
16
    : AdaptBase(name, problemStat, info, problemInstat, initialInfo),
17
18
      breakWhenStable(0),
      dbgMode(false)
19
20
21
  {
    FUNCNAME("AdaptInstationary::AdaptInstationary()");

22
23
24
//     MSG("You make use of the obsolete constructor AdaptInstationary::AdaptInstationary(...)!\n");
//     MSG("Please use the constructor that uses references instead of pointers!\n");

25
26
27
    initConstructor(problemStat, info, initialInfo, initialTimestampSet);

 }
28

Thomas Witkowski's avatar
Thomas Witkowski committed
29

30
31
32
33
34
  AdaptInstationary::AdaptInstationary(std::string name,
				       ProblemIterationInterface &problemStat,  
				       AdaptInfo &info,
				       ProblemTimeInterface &problemInstat,
				       AdaptInfo &initialInfo,
35
				       time_t initialTimestampSet)
36
37
38
39
40
41
    : AdaptBase(name, &problemStat, &info, &problemInstat, &initialInfo),
      breakWhenStable(0),
      dbgMode(false)
  {
    FUNCNAME("AdaptInstationary::AdaptInstationary()");

42
43
    initConstructor(&problemStat, &info, &initialInfo, initialTimestampSet);
 
44
45
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
46

47
48
49
  void AdaptInstationary::initConstructor(ProblemIterationInterface *problemStat,  
					  AdaptInfo *info,
					  AdaptInfo *initialInfo,
50
					  time_t initialTimestampSet)
51
  {
Thomas Witkowski's avatar
Thomas Witkowski committed
52
    initialize(name);
53

Thomas Witkowski's avatar
Thomas Witkowski committed
54
    fixedTimestep = (info->getMinTimestep() == info->getMaxTimestep());
55
56
 
    if (initialTimestampSet == 0)
Thomas Witkowski's avatar
Thomas Witkowski committed
57
      initialTimestamp = time(NULL);
58
    else
59
60
      initialTimestamp = initialTimestampSet;

61
    // Check if the problem should be deserialized because of the -rs parameter.
Thomas Witkowski's avatar
Thomas Witkowski committed
62
    std::string serializationFilename = "";
63
64
65
66
67
    GET_PARAMETER(0, "argv->rs", &serializationFilename);

    if (serializationFilename.compare("")) {
      // The value of the -rs argument is ignored, because we want to use the 
      // serialization file mentioned in the used init file.
Thomas Witkowski's avatar
Thomas Witkowski committed
68
      MSG("Deserialization from file: %s\n", queueSerializationFilename.c_str());
69

Thomas Witkowski's avatar
Thomas Witkowski committed
70
      std::ifstream in(queueSerializationFilename.c_str());
71
72
73
      deserialize(in);
      in.close();

74
75
      info->setIsDeserialized(true);
      initialInfo->setIsDeserialized(true);
76
77
78
79
80
81
82
83
84
85
    } else {
      int readSerialization = 0;
      int readSerializationWithAdaptInfo = 0;

      GET_PARAMETER(0, (*problemStat).getName() + "->input->read serialization", "%d", 
		    &readSerialization);
      GET_PARAMETER(0, (*problemStat).getName() + "->input->serialization with adaptinfo", "%d",
		    &readSerializationWithAdaptInfo);

      if (readSerialization && readSerializationWithAdaptInfo) {
Thomas Witkowski's avatar
Thomas Witkowski committed
86
	std::string serializationFilename = "";
87
88
89
90
91
92

	GET_PARAMETER(0, (*problemStat).getName() + "->input->serialization filename", 
		      &serializationFilename);
	TEST_EXIT(serializationFilename != "")("no serialization file\n");

	MSG("Deserialization with AdaptInfo from file: %s\n", serializationFilename.c_str());
Thomas Witkowski's avatar
Thomas Witkowski committed
93
	std::ifstream in(serializationFilename.c_str());
94
95
96
97
98
99
	deserialize(in);
	in.close();
      }
    }
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
100

101
102
103
104
  AdaptInstationary::~AdaptInstationary()
  {
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
105

106
107
108
109
110
  void AdaptInstationary::explicitTimeStrategy()
  {
    FUNCNAME("AdaptInstationary::explicitTimeStrategy()");

    // estimate before first adaption
Thomas Witkowski's avatar
Thomas Witkowski committed
111
    if (adaptInfo->getTime() <= adaptInfo->getStartTime())
Thomas Witkowski's avatar
Thomas Witkowski committed
112
      problemIteration->oneIteration(adaptInfo, ESTIMATE);
Thomas Witkowski's avatar
Thomas Witkowski committed
113
114


115
    // increment time
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
116
    adaptInfo->setTime(adaptInfo->getTime() + adaptInfo->getTimestep());
117

Thomas Witkowski's avatar
Thomas Witkowski committed
118
    problemTime->setTime(adaptInfo);
119

Thomas Witkowski's avatar
Thomas Witkowski committed
120
    INFO(info,6)("time = %e, timestep = %e\n",
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
121
		  adaptInfo->getTime(), adaptInfo->getTimestep());
122

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
123
    adaptInfo->setSpaceIteration(0);
124
125
  
    // do the iteration
Thomas Witkowski's avatar
Thomas Witkowski committed
126
127
128
    problemIteration->beginIteration(adaptInfo);
    problemIteration->oneIteration(adaptInfo, FULL_ITERATION);
    problemIteration->endIteration(adaptInfo);
129
    adaptInfo->setLastProcessedTimestep(adaptInfo->getTimestep()); 
130
131
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
132

133
134
135
136
137
  void AdaptInstationary::implicitTimeStrategy()
  {
    FUNCNAME("AdaptInstationary::implicitTimeStrategy()");

    do {
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
138
      adaptInfo->setTime(adaptInfo->getTime() + adaptInfo->getTimestep());
Thomas Witkowski's avatar
Thomas Witkowski committed
139
      problemTime->setTime(adaptInfo);
140

Thomas Witkowski's avatar
Thomas Witkowski committed
141
142
      INFO(info,6)("time = %e, try timestep = %e\n",
		   adaptInfo->getTime(), adaptInfo->getTimestep());
143

Thomas Witkowski's avatar
Thomas Witkowski committed
144
      problemIteration->oneIteration(adaptInfo, NO_ADAPTION);
145

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
146
      adaptInfo->incTimestepIteration();
147
   
Thomas Witkowski's avatar
Thomas Witkowski committed
148
      if (!fixedTimestep && 
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
149
	  !adaptInfo->timeToleranceReached() &&
150
	  adaptInfo->getTimestepIteration() <= adaptInfo->getMaxTimestepIteration() &&
Thomas Witkowski's avatar
Thomas Witkowski committed
151
	  !(adaptInfo->getTimestep() <= adaptInfo->getMinTimestep())) {
152
153
	  
	  adaptInfo->setTime(adaptInfo->getTime() - adaptInfo->getTimestep());
Thomas Witkowski's avatar
Thomas Witkowski committed
154
	  adaptInfo->setTimestep(adaptInfo->getTimestep() * timeDelta1);
155
	  continue;
156
      }
157

158

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
159
      adaptInfo->setSpaceIteration(0);
160
161
162
163


      /* === Do only space iterations only if the maximum is higher than 0. === */

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
164
      if (adaptInfo->getMaxSpaceIteration() > 0) {
165
    
166
167
	/* === Space iterations === */
	do {
Thomas Witkowski's avatar
Thomas Witkowski committed
168
	  problemIteration->beginIteration(adaptInfo);
169
	  
Thomas Witkowski's avatar
Thomas Witkowski committed
170
171
	  if (problemIteration->oneIteration(adaptInfo, FULL_ITERATION)) {
	    if (!fixedTimestep && 
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
172
		!adaptInfo->timeToleranceReached() &&
Thomas Witkowski's avatar
Thomas Witkowski committed
173
174
		!(adaptInfo->getTimestep() <= adaptInfo->getMinTimestep())) {
	      adaptInfo->setTime(adaptInfo->getTime() - adaptInfo->getTimestep());
Thomas Witkowski's avatar
Thomas Witkowski committed
175
176
	      adaptInfo->setTimestep(adaptInfo->getTimestep() * timeDelta2);
	      problemIteration->endIteration(adaptInfo);
Thomas Witkowski's avatar
Thomas Witkowski committed
177
178
179
	      adaptInfo->incSpaceIteration();
	      break;
	    }	
180
181
	  }

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
182
	  adaptInfo->incSpaceIteration();
Thomas Witkowski's avatar
Thomas Witkowski committed
183
	  problemIteration->endIteration(adaptInfo);
184
	  
Thomas Witkowski's avatar
Thomas Witkowski committed
185
186
	} while (!adaptInfo->spaceToleranceReached() && 
		 adaptInfo->getSpaceIteration() <= adaptInfo->getMaxSpaceIteration());
187
188

      } else {
Thomas Witkowski's avatar
Thomas Witkowski committed
189
	problemIteration->endIteration(adaptInfo);
190
191
      }

192

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
193
    } while(!adaptInfo->timeToleranceReached() &&
Thomas Witkowski's avatar
Thomas Witkowski committed
194
	    !(adaptInfo->getTimestep() <= adaptInfo->getMinTimestep()) && 
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
195
	    adaptInfo->getTimestepIteration() <= adaptInfo->getMaxTimestepIteration());  
196

197
    adaptInfo->setLastProcessedTimestep(adaptInfo->getTimestep()); 
198
199
200
201

    // After successful iteration/timestep the timestep will be changed according 
    // adaption rules for next timestep. 
    // First, check for increase of timestep
Thomas Witkowski's avatar
Thomas Witkowski committed
202
203
    if (!fixedTimestep && adaptInfo->timeErrorLow()) {
      adaptInfo->setTimestep(adaptInfo->getTimestep() * timeDelta2);
204
205
206
207
208
209
210
      if (dbgMode) {
	// print information about timestep increase
      }
    } else {
      if (dbgMode) {
	std::cout << "=== ADAPT INFO DEBUG MODE ===\n";
	std::cout << " Do not increase timestep: \n";
Thomas Witkowski's avatar
Thomas Witkowski committed
211
	if (fixedTimestep)
212
	  std::cout << "   fixedTimestep = true\n";	
Thomas Witkowski's avatar
Thomas Witkowski committed
213
	if (!adaptInfo->timeErrorLow())
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
214
	  adaptInfo->printTimeErrorLowInfo();
215
      }
216
    }
Thomas Witkowski's avatar
Thomas Witkowski committed
217

218
    // Second, check for decrease of timestep
Thomas Witkowski's avatar
Thomas Witkowski committed
219
    if (!fixedTimestep &&
220
	!adaptInfo->timeToleranceReached() &&
Thomas Witkowski's avatar
Thomas Witkowski committed
221
222
	!(adaptInfo->getTimestep() <= adaptInfo->getMinTimestep()))
	adaptInfo->setTimestep(adaptInfo->getTimestep() * timeDelta1);    
223
224
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255

  void AdaptInstationary::simpleAdaptiveTimeStrategy()
  {
    FUNCNAME("AdaptInstationary::explicitTimeStrategy()");

    // estimate before first adaption
    if (adaptInfo->getTime() <= adaptInfo->getStartTime())
      problemIteration->oneIteration(adaptInfo, ESTIMATE);

    adaptInfo->setTime(adaptInfo->getTime() + adaptInfo->getTimestep());
    problemTime->setTime(adaptInfo);
    
    INFO(info,6)("time = %e, timestep = %e\n",
		 adaptInfo->getTime(), adaptInfo->getTimestep());
    
    problemIteration->oneIteration(adaptInfo, FULL_ITERATION);

    adaptInfo->setLastProcessedTimestep(adaptInfo->getTimestep());        
    
    // First, check for increase of timestep
    if (!fixedTimestep && adaptInfo->timeErrorLow())
      adaptInfo->setTimestep(adaptInfo->getTimestep() * timeDelta2);
    
    // Second, check for decrease of timestep
    if (!fixedTimestep &&
	!adaptInfo->timeToleranceReached() &&
	!(adaptInfo->getTimestep() <= adaptInfo->getMinTimestep()))
      adaptInfo->setTimestep(adaptInfo->getTimestep() * timeDelta1);    
  }


256
257
  void AdaptInstationary::oneTimestep()
  {
258
    FUNCNAME("AdaptInstationary::oneTimestep()");
259

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
260
    adaptInfo->setTimestepIteration(0);
261

262
263
264
265
266
267
268
    switch (strategy) {
    case 0:
      explicitTimeStrategy();
      break;
    case 1:
      implicitTimeStrategy();
      break;
Thomas Witkowski's avatar
Thomas Witkowski committed
269
270
271
    case 2:
      simpleAdaptiveTimeStrategy();
      break;
272
    default:
Thomas Witkowski's avatar
Thomas Witkowski committed
273
      ERROR_EXIT("Unknown strategy = %d!\n", strategy);
274
    }
275

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
276
    adaptInfo->incTimestepNumber();
277
278
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
279

280
281
282
283
284
  int AdaptInstationary::adapt()
  {
    FUNCNAME("AdaptInstationary::adapt()");
    int errorCode = 0;

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
285
    TEST_EXIT(adaptInfo->getTimestep() >= adaptInfo->getMinTimestep())
286
      ("timestep < min timestep\n");
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
287
    TEST_EXIT(adaptInfo->getTimestep() <= adaptInfo->getMaxTimestep())
288
289
      ("timestep > max timestep\n");

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
290
    TEST_EXIT(adaptInfo->getTimestep() > 0)("timestep <= 0!\n");
291

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
292
293
    if (adaptInfo->getTimestepNumber() == 0) {
      adaptInfo->setTime(adaptInfo->getStartTime());
Thomas Witkowski's avatar
Thomas Witkowski committed
294
295
      initialAdaptInfo->setStartTime(adaptInfo->getStartTime());
      initialAdaptInfo->setTime(adaptInfo->getStartTime());
296

Thomas Witkowski's avatar
Thomas Witkowski committed
297
      problemTime->setTime(adaptInfo);
298
299

      // initial adaption
Thomas Witkowski's avatar
Thomas Witkowski committed
300
301
      problemTime->solveInitialProblem(initialAdaptInfo);
      problemTime->transferInitialSolution(adaptInfo);
302
303
    }

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
304
    while (!adaptInfo->reachedEndTime()) {
Thomas Witkowski's avatar
Thomas Witkowski committed
305
      iterationTimestamp = time(NULL);
306

Thomas Witkowski's avatar
Thomas Witkowski committed
307
      problemTime->initTimestep(adaptInfo);
308
      oneTimestep();
Thomas Witkowski's avatar
Thomas Witkowski committed
309
      problemTime->closeTimestep(adaptInfo);
Thomas Witkowski's avatar
Thomas Witkowski committed
310

311
      if (breakWhenStable && (adaptInfo->getSolverIterations() == 0)) 
312
	break;
313
314
315
316
      /*     
      if (adaptInfo->forceBreak) 
	  break;
      */
317
318
319
320
321
322
323
324
325
326
327
328
      // Check if there is a runtime limitation. If there is a runtime limitation
      // and there is no more time for a next adaption loop, than return the error
      // code for rescheduling the problem and break the adaption loop.
      if (checkQueueRuntime()) {
	errorCode = RescheduleErrorCode;
	break;
      }
    }

    return errorCode;
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
329

Thomas Witkowski's avatar
Thomas Witkowski committed
330
  void AdaptInstationary::initialize(std::string aName)
331
332
333
334
  {
    FUNCNAME("AdaptInstationary::initialize()");

    strategy = 0;
Thomas Witkowski's avatar
Thomas Witkowski committed
335
336
337
338
    timeDelta1 = 0.7071;
    timeDelta2 = 1.4142;
    queueRuntime = -1;
    queueSerializationFilename = "__serialized_problem.ser";
339
340

    GET_PARAMETER(0, aName + "->strategy", "%d", &strategy);
Thomas Witkowski's avatar
Thomas Witkowski committed
341
342
343
    GET_PARAMETER(0, aName + "->time delta 1", "%f", &timeDelta1);
    GET_PARAMETER(0, aName + "->time delta 2", "%f", &timeDelta2);
    GET_PARAMETER(0, aName + "->info", "%d", &info);
344
    GET_PARAMETER(0, aName + "->break when stable", "%d", &breakWhenStable);
Thomas Witkowski's avatar
Thomas Witkowski committed
345
    GET_PARAMETER(0, aName + "->queue->runtime", "%d", &queueRuntime);
Thomas Witkowski's avatar
Thomas Witkowski committed
346
    GET_PARAMETER(0, aName + "->queue->serialization filename", 
Thomas Witkowski's avatar
Thomas Witkowski committed
347
		  &queueSerializationFilename);
348
349
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
350

Thomas Witkowski's avatar
Thomas Witkowski committed
351
  void AdaptInstationary::serialize(std::ostream &out)
352
353
354
  {
    FUNCNAME("AdaptInstationary::serialize()");

Thomas Witkowski's avatar
Thomas Witkowski committed
355
    problemIteration->serialize(out);
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
356
    adaptInfo->serialize(out);
Thomas Witkowski's avatar
Thomas Witkowski committed
357
358
    if (problemTime)
      problemTime->serialize(out);    
359
360
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
361

Thomas Witkowski's avatar
Thomas Witkowski committed
362
  void AdaptInstationary::deserialize(std::istream &in)
363
364
365
  {
    FUNCNAME("AdaptInstationary::deserialize()");

Thomas Witkowski's avatar
Thomas Witkowski committed
366
    problemIteration->deserialize(in);
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
367
    adaptInfo->deserialize(in);
Thomas Witkowski's avatar
Thomas Witkowski committed
368
369
    if (problemTime)
      problemTime->deserialize(in);    
370
371
372
373
374
375
  }


  bool AdaptInstationary::checkQueueRuntime()
  {
    // If there is no time limited runtime queue, there is also nothing to check.
Thomas Witkowski's avatar
Thomas Witkowski committed
376
    if (queueRuntime == -1) {
377
378
379
380
381
382
      return false;
    }
    // Get the current time.
    time_t currentTimestamp = time(NULL);

    // Update list with the last iteration runtimes.
Thomas Witkowski's avatar
Thomas Witkowski committed
383
    lastIterationsDuration.push(currentTimestamp - iterationTimestamp);
384
    // The list should not contain more than 5 elements. If so, delete the oldest one.
Thomas Witkowski's avatar
Thomas Witkowski committed
385
386
    if (lastIterationsDuration.size() > 5)
      lastIterationsDuration.pop();    
387
388

    // Calculate the avarage of the last iterations.
Thomas Witkowski's avatar
Thomas Witkowski committed
389
    std::queue<int> tmpQueue = lastIterationsDuration;
390
391
    int avrgLastIterations = 0;
    while (!tmpQueue.empty()) {
392
393
	avrgLastIterations += tmpQueue.front();
	tmpQueue.pop();
394
    } 
Thomas Witkowski's avatar
Thomas Witkowski committed
395
    avrgLastIterations /= lastIterationsDuration.size();
396

397
    // Check if there is enough time for a further iteration.
Thomas Witkowski's avatar
Thomas Witkowski committed
398
399
    if (initialTimestamp + queueRuntime - currentTimestamp < avrgLastIterations * 2) {
      std::ofstream out(queueSerializationFilename.c_str());
400
401
402
403
404
405
406
407
408
409
      serialize(out);
      out.close();

      return true;
    }

    return false;
  }

}