cloudy  trunk
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
optimize_phymir.cpp
Go to the documentation of this file.
1 /* This file is part of Cloudy and is copyright (C)1978-2017 by Gary J. Ferland and
2  * others. For conditions of distribution and use see copyright notice in license.txt */
3 /*optimize_phymir Peter van Hoof's optimization routine */
4 
5 #include "cddefines.h"
6 #include "version.h"
7 #include "optimize.h"
8 #if defined(__unix) || defined(__APPLE__)
9 #include <cstddef>
10 #include <sys/types.h>
11 #include <sys/wait.h>
12 #include <unistd.h>
13 #else
14 #define pid_t int
15 #define fork() TotalInsanityAsStub<pid_t>()
16 #define wait(X) TotalInsanityAsStub<pid_t>()
17 #endif
18 
19 
22 const char* STATEFILE = "continue.pmr";
23 const char* STATEFILE_BACKUP = "continue.bak";
24 
25 /* The optimization algorithm Phymir and its subsidiary routines have been
26  * written by Peter van Hoof. */
27 
28 inline void wr_block(const void*,size_t,const char*);
29 inline void rd_block(void*,size_t,const char*);
30 
31 
32 template<class X, class Y, int NP, int NSTR>
34 {
35  DEBUG_ENTRY( "p_clear1()" );
36 
37  // first zero out the entire struct so that even the padding gets initialized
38  // this prevents complaints about writing uninitialized bytes by valgrind
39  memset( this, 0, sizeof(*this) );
40 
41  p_xmax = numeric_limits<X>::max();
42  p_ymax = numeric_limits<Y>::max() / Y(2.);
43  for( int i=0; i < 2*NP+1; ++i )
44  {
45  for( int j=0; j < NP; ++j )
46  p_xp[i][j] = -p_xmax;
47  p_yp[i] = -p_ymax;
48  }
49  for( int i=0; i < NP; ++i )
50  {
51  p_absmin[i] = -p_xmax;
52  p_absmax[i] = p_xmax;
53  p_varmin[i] = p_xmax;
54  p_varmax[i] = -p_xmax;
55  for( int j=0; j < NP; ++j )
56  p_a2[i][j] = -p_xmax;
57  p_c1[i] = -p_xmax;
58  p_c2[i] = -p_xmax;
59  p_xc[i] = -p_xmax;
60  p_xcold[i] = -p_xmax;
61  }
62  p_vers = VRSNEW;
63  p_toler = -p_xmax;
64  p_dmax = X(0.);
65  p_dold = X(0.);
66  p_ymin = p_ymax;
67  p_dim = int32(NP);
68  p_sdim = int32(NSTR);
69  p_nvar = int32(0);
70  p_noptim = int32(0);
71  p_maxiter = int32(0);
72  p_jmin = int32(-1);
73  p_maxcpu = int32(1);
74  p_curcpu = int32(0);
75  p_mode = PHYMIR_ILL;
76  // p_chState, and p_chStr[123] have already been initialized with memset above
77 
78  // calculate the size of the struct from the start upto, but not including p_size
79  // this section of the struct will be written in binary mode to a state file
80  // cast pointers to size_t so that we get the size in bytes for fwrite / fread
81  // make p_size an uint32 so that the width of the field is platform independent
82  p_size = static_cast<uint32>(reinterpret_cast<size_t>(&p_size) - reinterpret_cast<size_t>(this));
83  p_func = NULL;
84 }
85 
86 template<class X, class Y, int NP, int NSTR>
87 void phymir_state<X,Y,NP,NSTR>::p_wr_state(const char *fnam) const
88 {
89  DEBUG_ENTRY( "p_wr_state()" );
90 
91  if( cpu.i().lgMaster() && strlen(fnam) > 0 )
92  {
93  FILE *fdes = open_data( fnam, "wb", AS_LOCAL_ONLY_TRY );
94  bool lgErr = ( fdes == NULL );
95  lgErr = lgErr || ( fwrite( &p_size, sizeof(uint32), 1, fdes ) != 1 );
96  lgErr = lgErr || ( fwrite( this, static_cast<size_t>(p_size), 1, fdes ) != 1 );
97  lgErr = lgErr || ( fclose(fdes) != 0 );
98  if( lgErr )
99  {
100  printf( "p_wr_state: error writing file: %s\n", fnam );
101  remove(fnam);
102  }
103  }
104  return;
105 }
106 
107 template<class X, class Y, int NP, int NSTR>
109 {
110  DEBUG_ENTRY( "p_rd_state()" );
111 
112  FILE *fdes = open_data( fnam, "rb", AS_LOCAL_ONLY );
113  uint32 wrsize;
114  bool lgErr = ( fread( &wrsize, sizeof(uint32), 1, fdes ) != 1 );
115  lgErr = lgErr || ( p_size != wrsize );
116  lgErr = lgErr || ( fread( this, static_cast<size_t>(p_size), 1, fdes ) != 1 );
117  lgErr = lgErr || ( fclose(fdes) != 0 );
118  if( lgErr )
119  {
120  printf( "p_rd_state: error reading file: %s\n", fnam );
122  }
123  return;
124 }
125 
126 template<class X, class Y, int NP, int NSTR>
128  int jj,
129  int runNr)
130 {
131  DEBUG_ENTRY( "p_execute_job()" );
132 
133  pid_t pid;
134  switch( p_mode )
135  {
136  case PHYMIR_SEQ:
137  return p_lgLimitExceeded(x) ? p_ymax : p_func(x,runNr);
138  case PHYMIR_FORK:
139  p_curcpu++;
140  if( p_curcpu > p_maxcpu )
141  {
142  /* too many processes, wait for one to finish */
143  (void)wait(NULL);
144  p_curcpu--;
145  }
146  /* flush all open files */
147  fflush(NULL);
148  pid = fork();
149  if( pid < 0 )
150  {
151  fprintf( ioQQQ, "creating the child process failed\n" );
153  }
154  else if( pid == 0 )
155  {
156  /* this is child process so execute */
157  p_execute_job_parallel( x, jj, runNr );
158  /* at this point ioQQQ points to the main output of the parent process,
159  * the child should not close that in cdEXIT(), so wipe the handle here */
160  ioQQQ = NULL;
162  }
163  // the real y-value is not available yet...
164  return p_ymax;
165  case PHYMIR_MPI:
166  if( (jj%cpu.i().nCPU()) == cpu.i().nRANK() )
167  p_execute_job_parallel( x, jj, runNr );
168  // the real y-value is not available yet...
169  return p_ymax;
170  default:
171  TotalInsanity();
172  }
173 }
174 
175 // p_execute_job_parallel MUST be const, otherwise changes by child processes may be lost!
176 template<class X, class Y, int NP, int NSTR>
178  int jj,
179  int runNr) const
180 {
181  DEBUG_ENTRY( "p_execute_job_parallel()" );
182 
183  char fnam1[20], fnam2[20];
184  sprintf(fnam1,"yval_%d",jj);
185  sprintf(fnam2,"output_%d",jj);
186  /* each child should have its own output file */
187  FILE *ioQQQ_old = ioQQQ;
188  ioQQQ = open_data( fnam2, "w" );
189  // fail-safe in case p_func crashes without being caught...
190  Y yval = p_ymax;
191  wr_block(&yval,sizeof(yval),fnam1);
192  if( !p_lgLimitExceeded(x) )
193  {
194  try
195  {
196  yval = p_func(x,runNr);
197  }
198  catch( ... )
199  {
200  // make sure output is complete since files may not have been closed properly...
201  fflush(NULL);
202  yval = p_ymax;
203  }
204  wr_block(&yval,sizeof(yval),fnam1);
205  }
206  fclose( ioQQQ );
207  ioQQQ = ioQQQ_old;
208 }
209 
210 template<class X, class Y, int NP, int NSTR>
212  int jhi)
213 {
214  DEBUG_ENTRY( "p_barrier()" );
215 
216  switch( p_mode )
217  {
218  case PHYMIR_SEQ:
219  // nothing to do...
220  break;
221  case PHYMIR_FORK:
222  /* wait for child processes to terminate */
223  while( p_curcpu > 0 )
224  {
225  (void)wait(NULL);
226  p_curcpu--;
227  }
228  p_process_output( jlo, jhi );
229  break;
230  case PHYMIR_MPI:
231  // wait for all function evaluations to finish so that output is complete
232  MPI_Barrier( MPI_COMM_WORLD );
233  p_process_output( jlo, jhi );
234  // y values are known now, so broadcast to other ranks
235  MPI_Bcast( &p_yp[jlo], jhi-jlo+1, MPI_type(p_yp), 0, MPI_COMM_WORLD );
236  break;
237  default:
238  TotalInsanity();
239  }
240 }
241 
242 template<class X, class Y, int NP, int NSTR>
244  int jhi)
245 {
246  DEBUG_ENTRY( "p_process_output()" );
247 
248  if( cpu.i().lgMaster() )
249  {
250  char fnam[20];
251  for( int jj=jlo; jj <= jhi; jj++ )
252  {
253  sprintf(fnam,"yval_%d",jj);
254  rd_block(&p_yp[jj],sizeof(p_yp[jj]),fnam);
255  remove(fnam);
256  sprintf(fnam,"output_%d",jj);
257  append_file(ioQQQ,fnam);
258  remove(fnam);
259  }
260  }
261 }
262 
263 template<class X, class Y, int NP, int NSTR>
265 {
266  DEBUG_ENTRY( "p_evaluate_hyperblock()" );
267 
268  int jlo = 1, jhi = 0;
269  for( int j=0; j < p_nvar; j++ )
270  {
271  X sgn = X(1.);
272  for( int jj=2*j+1; jj <= 2*j+2; jj++ )
273  {
274  sgn = -sgn;
275  for( int i=0; i < p_nvar; i++ )
276  {
277  p_xp[jj][i] = p_xc[i] + sgn*p_dmax*p_c2[j]*p_a2[j][i];
278  p_varmax[i] = max(p_varmax[i],p_xp[jj][i]);
279  p_varmin[i] = min(p_varmin[i],p_xp[jj][i]);
280  }
281  if( !lgMaxIterExceeded() )
282  {
283  // p_execute_job will not return the correct chi^2 in parallel mode
284  // only after p_barrier() has finished will p_yp[jj] contain the correct value
285  p_yp[jj] = p_execute_job( p_xp[jj], jj, p_noptim++ );
286  jhi = jj;
287  }
288  }
289  }
290  /* wait for jobs to terminate */
291  p_barrier( jlo, jhi );
292 }
293 
294 template<class X, class Y, int NP, int NSTR>
296 {
297  DEBUG_ENTRY( "p_setup_next_hyperblock()" );
298 
299  const Y F0 = Y(1.4142136);
300  const X F1 = X(0.7071068);
301  const X F2 = X(0.1);
302 
303  /* find best model */
304  for( int jj=1; jj <= 2*p_nvar; jj++ )
305  {
306  if( p_yp[jj] < p_ymin )
307  {
308  p_ymin = p_yp[jj];
309  p_jmin = jj;
310  }
311  }
312  bool lgNewCnt = p_jmin > 0;
313 
314  /* determine minimum and relative uncertainties */
315  bool lgNegd2 = false;
316  X xnrm = X(0.);
317  X xhlp[NP];
318  for( int i=0; i < p_nvar; i++ )
319  {
320  Y d1 = p_yp[2*i+2] - p_yp[2*i+1];
321  Y d2 = Y(0.5)*p_yp[2*i+2] - p_yp[0] + Y(0.5)*p_yp[2*i+1];
322  if( d2 <= Y(0.) )
323  lgNegd2 = true;
324  xhlp[i] = -p_dmax*p_c2[i]*(static_cast<X>(max(min((Y(0.25)*d1)/max(d2,Y(1.e-10)),F0),-F0)) -
325  p_delta(2*i+1,p_jmin) + p_delta(2*i+2,p_jmin));
326  xnrm += pow2(xhlp[i]);
327  }
328  xnrm = static_cast<X>(sqrt(xnrm));
329  /* set up new transformation matrix */
330  int imax = 0;
331  X amax = X(0.);
332  for( int j=0; j < p_nvar; j++ )
333  {
334  for( int i=0; i < p_nvar; i++ )
335  {
336  if( xnrm > X(0.) )
337  {
338  if( j == 0 )
339  {
340  p_a2[0][i] *= xhlp[0];
341  }
342  else
343  {
344  p_a2[0][i] += xhlp[j]*p_a2[j][i];
345  p_a2[j][i] = p_delta(i,j);
346  if( j == p_nvar-1 && abs(p_a2[0][i]) > amax )
347  {
348  imax = i;
349  amax = abs(p_a2[0][i]);
350  }
351  }
352  }
353  else
354  {
355  p_a2[j][i] = p_delta(i,j);
356  }
357  }
358  }
359  /* this is to assure maximum linear independence of the base vectors */
360  if( imax > 0 )
361  {
362  p_a2[imax][0] = X(1.);
363  p_a2[imax][imax] = X(0.);
364  }
365  /* apply Gram-Schmidt procedure to get orthogonal base */
366  p_phygrm( p_a2, p_nvar );
367 
368  /* set up hyperblock dimensions in new base and choose new center */
369  for( int i=0; i < p_nvar; i++ )
370  {
371  p_c2[i] = X(0.);
372  for( int j=0; j < p_nvar; j++ )
373  {
374  p_c2[i] += pow2(p_a2[i][j]/p_c1[j]);
375  }
376  p_c2[i] = static_cast<X>(1./sqrt(p_c2[i]));
377  p_xc[i] = p_xp[p_jmin][i];
378  p_xp[0][i] = p_xc[i];
379  }
380  p_yp[0] = p_yp[p_jmin];
381  p_jmin = 0;
382  /* choose size of next hyperblock */
383  X r1, r2;
384  if( lgNegd2 )
385  {
386  /* this means that the hyperblock either is bigger than the scale
387  * on which the function varies, or is so small that we see noise.
388  * in both cases make the hyperblock smaller. */
389  r1 = F1;
390  r2 = F1;
391  }
392  else
393  {
394  r1 = F2;
395  if( lgNewCnt )
396  {
397  /* when we make progress, p_dmax may become bigger */
398  r2 = sqrt(1.f/F1);
399  }
400  else
401  {
402  /* when there is no progress force p_dmax smaller, otherwise there
403  * may never be an end */
404  r2 = sqrt(F1);
405  }
406  }
407  p_dmax = min(max(xnrm/p_c2[0],p_dmax*r1),p_dmax*r2);
408  /* fail-safe against excessive behaviour */
409  p_dmax = MIN2(p_dmax,p_dold);
410 }
411 
412 template<class X, class Y, int NP, int NSTR>
414 {
415  DEBUG_ENTRY( "p_reset_hyperblock()" );
416 
417  if( !lgConvergedRestart() )
418  {
419  /* reset hyperblock so that we can restart the optimization */
420  for( int i=0; i < p_nvar; i++ )
421  {
422  p_xcold[i] = p_xc[i];
423  p_c2[i] = p_c1[i];
424  }
425  p_dmax = p_dold;
426  p_reset_transformation_matrix();
427  }
428 }
429 
430 template<class X, class Y, int NP, int NSTR>
432  int n)
433 {
434  DEBUG_ENTRY( "p_phygrm()" );
435 
436  /* apply modified Gram-Schmidt procedure to a */
437  for( int i=0; i < n; i++ )
438  {
439  X ip = X(0.);
440  for( int k=0; k < n; k++ )
441  ip += pow2(a[i][k]);
442  ip = sqrt(ip);
443  for( int k=0; k < n; k++ )
444  a[i][k] /= ip;
445  for( int j=i+1; j < n; j++ )
446  {
447  X ip = X(0.);
448  for( int k=0; k < n; k++ )
449  ip += a[i][k]*a[j][k];
450  for( int k=0; k < n; k++ )
451  a[j][k] -= ip*a[i][k];
452  }
453  }
454  return;
455 }
456 
457 template<class X, class Y, int NP, int NSTR>
459 {
460  DEBUG_ENTRY( "p_lgLimitExceeded()" );
461 
462  for( int i=0; i < p_nvar; i++ )
463  {
464  if( x[i] < p_absmin[i] )
465  return true;
466  if( x[i] > p_absmax[i] )
467  return true;
468  }
469  return false;
470 }
471 
472 template<class X, class Y, int NP, int NSTR>
474 {
475  DEBUG_ENTRY( "p_reset_transformation_matrix()" );
476 
477  /* initialize transformation matrix to unity */
478  for( int i=0; i < p_nvar; i++ )
479  for( int j=0; j < p_nvar; j++ )
480  p_a2[j][i] = p_delta(i,j);
481 }
482 
483 template<class X, class Y, int NP, int NSTR>
484 void phymir_state<X,Y,NP,NSTR>::init_minmax(const X pmin[], // pmin[nvar]: minimum values for params
485  const X pmax[], // pmax[nvar]: maximum values for params
486  int nvar) // will not be initialized yet
487 {
488  DEBUG_ENTRY( "init_minmax()" );
489 
490  ASSERT( !lgInitialized() );
491 
492  for( int i=0; i < nvar; i++ )
493  {
494  p_absmin[i] = pmin[i];
495  p_absmax[i] = pmax[i];
496  }
497 }
498 
499 template<class X, class Y, int NP, int NSTR>
500 void phymir_state<X,Y,NP,NSTR>::init_strings(const char* date, // date string for inclusion in state file
501  const char* version, // version string for inclusion in state file
502  const char* host_name) // host name for inclusion in state file
503 {
504  DEBUG_ENTRY( "init_strings()" );
505 
506  // use NSTR-1 so that last 0 byte is not overwritten...
507  if( date != NULL )
508  strncpy( p_chStr1, date, NSTR-1 );
509  if( version != NULL )
510  strncpy( p_chStr2, version, NSTR-1 );
511  if( host_name != NULL )
512  strncpy( p_chStr3, host_name, NSTR-1 );
513 }
514 
515 template<class X, class Y, int NP, int NSTR>
516 void phymir_state<X,Y,NP,NSTR>::init_state_file_name(const char* fnam) // name of the state file that will be written
517 {
518  DEBUG_ENTRY( "init_state_file_name()" );
519 
520  // use NSTR-1 so that last 0 byte is not overwritten...
521  strncpy( p_chState, fnam, NSTR-1 );
522 }
523 
524 template<class X, class Y, int NP, int NSTR>
525 void phymir_state<X,Y,NP,NSTR>::initial_run(Y (*func)(const X[],int), // function to be optimized
526  int nvar, // number of parameters to be optimized
527  const X start[], // start[n]: initial estimates for params
528  const X del[], // del[n]: initial stepsizes for params
529  X toler, // absolute tolerance on parameters
530  int maxiter, // maximum number of iterations
531  phymir_mode mode, // execution mode: sequential, fork, mpi
532  int maxcpu) // maximum no. of CPUs to use
533 {
534  DEBUG_ENTRY( "initial_run()" );
535 
536  ASSERT( nvar > 0 && nvar <= NP );
537 
538  p_func = func;
539  p_nvar = nvar;
540  p_toler = toler;
541  p_maxiter = maxiter;
542  p_mode = mode;
543  p_maxcpu = maxcpu;
544  p_noptim = 0;
545 
546  /* initialize hyperblock dimensions and center */
547  p_dmax = X(0.);
548  for( int i=0; i < p_nvar; i++ )
549  p_dmax = max(p_dmax,abs(del[i]));
550 
551  p_dold = p_dmax;
552  for( int i=0; i < p_nvar; i++ )
553  {
554  p_xc[i] = start[i];
555  p_xcold[i] = p_xc[i] + X(10.)*p_toler;
556  p_c1[i] = abs(del[i])/p_dmax;
557  p_c2[i] = p_c1[i];
558  p_xp[0][i] = p_xc[i];
559  p_varmax[i] = max(p_varmax[i],p_xc[i]);
560  p_varmin[i] = min(p_varmin[i],p_xc[i]);
561  }
562 
563  // p_execute_job will not return the correct chi^2 in parallel mode
564  // only after p_barrier() has finished will p_yp[0] contain the correct value
565  p_yp[0] = p_execute_job( p_xc, 0, p_noptim++ );
566  p_barrier( 0, 0 );
567 
568  p_ymin = p_yp[0];
569  p_jmin = 0;
570 
571  p_reset_transformation_matrix();
572 
573  p_wr_state( p_chState );
574 }
575 
576 template<class X, class Y, int NP, int NSTR>
577 void phymir_state<X,Y,NP,NSTR>::continue_from_state(Y (*func)(const X[],int), // function to be optimized
578  int nvar, // number of parameters to be optimized
579  const char* fnam, // file name of the state file
580  X toler, // absolute tolerance on parameters
581  int maxiter, // maximum number of iterations
582  phymir_mode mode, // execution mode: sequential, fork, mpi
583  int maxcpu) // maximum no. of CPUs to use
584 {
585  DEBUG_ENTRY( "continue_from_state()" );
586 
587  p_rd_state( fnam );
588  // sanity checks
589  if( !fp_equal( p_vers, VRSNEW ) )
590  {
591  printf( "optimize continue - file has incompatible version, sorry\n" );
593  }
594  if( p_dim != NP )
595  {
596  printf( "optimize continue - arrays have wrong dimension, sorry\n" );
598  }
599  if( p_sdim != NSTR )
600  {
601  printf( "optimize continue - strings have wrong length, sorry\n" );
603  }
604  if( p_nvar != nvar )
605  {
606  printf( "optimize continue - wrong number of free parameters, sorry\n" );
608  }
609  // this pointer was not part of the state file, it would be useless...
610  p_func = func;
611  // Option to override the tolerance set in the state file. This is useful
612  // if you want to refine an already finished run to a smaller tolerance.
613  p_toler = toler;
614  // you ran out of iterations, but wanted to continue...
615  p_maxiter = maxiter;
616  // it is OK to continue in a different mode
617  p_mode = mode;
618  p_maxcpu = maxcpu;
619 }
620 
621 template<class X, class Y, int NP, int NSTR>
623 {
624  DEBUG_ENTRY( "optimize()" );
625 
626  ASSERT( lgInitialized() );
627 
628  while( !lgConverged() )
629  {
630  p_evaluate_hyperblock();
631  if( lgMaxIterExceeded() )
632  break;
633  p_setup_next_hyperblock();
634  p_wr_state( p_chState );
635  }
636 }
637 
638 template<class X, class Y, int NP, int NSTR>
640 {
641  DEBUG_ENTRY( "optimize_with_restart()" );
642 
643  ASSERT( lgInitialized() );
644 
645  while( !lgConvergedRestart() )
646  {
647  optimize();
648  if( lgMaxIterExceeded() )
649  break;
650  p_reset_hyperblock();
651  }
652 }
653 
654 template<class X, class Y, int NP, int NSTR>
656 {
657  DEBUG_ENTRY( "lgConvergedRestart()" );
658 
659  if( lgConverged() )
660  {
661  X dist = X(0.);
662  for( int i=0; i < p_nvar; i++ )
663  dist += pow2(p_xc[i] - p_xcold[i]);
664  dist = static_cast<X>(sqrt(dist));
665  return ( dist <= p_toler );
666  }
667  return false;
668 }
669 
671  const realnum del[],
672  long int nvarPhymir,
673  chi2_type *ymin,
674  realnum toler)
675 {
676  DEBUG_ENTRY( "optimize_phymir()" );
677 
678  if( nvarPhymir > LIMPAR )
679  {
680  fprintf( ioQQQ, "optimize_phymir: too many parameters are varied, increase LIMPAR\n" );
682  }
683 
685 
686  // first check if a statefile already exists, back it up in that case
687  (void)remove(STATEFILE_BACKUP);
688  FILE *tmp = open_data( STATEFILE, "r", AS_LOCAL_ONLY_TRY );
689  if( tmp != NULL )
690  {
691  fclose( tmp );
692  // create backup copy of statefile
693  FILE *dest = open_data( STATEFILE_BACKUP, "wb", AS_LOCAL_ONLY_TRY );
694  if( dest != NULL )
695  {
696  append_file( dest, STATEFILE );
697  fclose( dest );
698  }
699  }
700 
702  long nCPU = optimize.lgParallel ? ( cpu.i().lgMPI() ? cpu.i().nCPU() : optimize.useCPU ) : 1;
703  cpu.i().set_used_nCPU( nCPU );
704  if( optimize.lgOptCont )
705  {
706  phymir.continue_from_state( optimize_func, nvarPhymir, STATEFILE, toler,
707  optimize.nIterOptim, mode, nCPU );
708  }
709  else
710  {
712  phymir.init_strings( t_version::Inst().chDate, t_version::Inst().chVersion,
713  cpu.i().host_name() );
714  phymir.initial_run( optimize_func, nvarPhymir, xc, del, toler,
715  optimize.nIterOptim, mode, nCPU );
716  }
717 
718  phymir.optimize_with_restart();
719 
720  if( phymir.lgMaxIterExceeded() )
721  {
722  fprintf( ioQQQ, " Optimizer exceeding maximum iterations.\n" );
723  fprintf( ioQQQ, " This can be reset with the OPTIMIZE ITERATIONS command.\n" );
724  }
725 
726  // updates to optimize.nOptimiz and optimize.varmin/max in child processes are lost, so repair here...
727  optimize.nOptimiz = phymir.noptim();
728  for( int i=0; i < nvarPhymir; i++ )
729  {
730  xc[i] = phymir.xval(i);
731  optimize.varmax[i] = min(phymir.xmax(i),optimize.varang[i][1]);
732  optimize.varmin[i] = max(phymir.xmin(i),optimize.varang[i][0]);
733  }
734  *ymin = phymir.yval();
735  return;
736 }
737 
739 inline void wr_block(const void *ptr,
740  size_t len,
741  const char *fnam)
742 {
743  DEBUG_ENTRY( "wr_block()" );
744 
745  FILE *fdes = open_data( fnam, "wb" );
746  if( fwrite(ptr,len,size_t(1),fdes) != 1 ) {
747  printf( "error writing on file: %s\n",fnam );
748  fclose(fdes);
750  }
751  fclose(fdes);
752  return;
753 }
754 
756 inline void rd_block(void *ptr,
757  size_t len,
758  const char *fnam)
759 {
760  DEBUG_ENTRY( "rd_block()" );
761 
762  FILE *fdes = open_data( fnam, "rb", AS_LOCAL_ONLY );
763  if( fread(ptr,len,size_t(1),fdes) != 1 ) {
764  printf( "error reading on file: %s\n",fnam );
765  fclose(fdes);
767  }
768  fclose(fdes);
769  return;
770 }
long nRANK() const
Definition: cpu.h:392
void p_rd_state(const char *)
FILE * open_data(const char *fname, const char *mode, access_scheme scheme)
Definition: cpu.cpp:751
Y yval() const
Definition: optimize.h:144
realnum varmax[LIMPAR]
Definition: optimize.h:187
void set_used_nCPU(long n)
Definition: cpu.h:386
X xval(int i) const
Definition: optimize.h:141
X xmin(int i) const
Definition: optimize.h:142
NORETURN void TotalInsanity(void)
Definition: service.cpp:1067
t_cpu_i & i()
Definition: cpu.h:415
void rd_block(void *, size_t, const char *)
Y p_execute_job(const X[], int, int)
chi2_type optimize_func(const realnum param[], int grid_index=-1)
X xmax(int i) const
Definition: optimize.h:143
long int nOptimiz
Definition: optimize.h:250
realnum varang[LIMPAR][2]
Definition: optimize.h:201
void p_wr_state(const char *) const
#define MPI_Barrier(Z)
Definition: mpi_utilities.h:84
void optimize_phymir(realnum[], const realnum[], long, chi2_type *, realnum)
int32 noptim() const
Definition: optimize.h:145
FILE * ioQQQ
Definition: cddefines.cpp:7
#define MIN2(a, b)
Definition: cddefines.h:807
const char * STATEFILE
void p_execute_job_parallel(const X[], int, int) const
static t_version & Inst()
Definition: cddefines.h:209
void init_strings(const char *, const char *, const char *)
void continue_from_state(Y(*)(const X[], int), int, const char *, X, int, phymir_mode, int)
void wr_block(const void *, size_t, const char *)
long int nIterOptim
Definition: optimize.h:209
#define F1(x, y, z)
bool fp_equal(sys_float x, sys_float y, int n=3)
Definition: cddefines.h:858
void p_barrier(int, int)
void init_minmax(const X[], const X[], int)
bool lgParallel
Definition: optimize.h:263
float realnum
Definition: cddefines.h:124
#define EXIT_FAILURE
Definition: cddefines.h:168
bool lgMaster() const
Definition: cpu.h:393
long max(int a, long b)
Definition: cddefines.h:821
bool lgConvergedRestart() const
#define cdEXIT(FAIL)
Definition: cddefines.h:484
long min(int a, long b)
Definition: cddefines.h:766
const long LIMPAR
Definition: optimize.h:61
t_optimize optimize
Definition: optimize.cpp:6
STATIC double dist(long, realnum[], realnum[])
void p_reset_transformation_matrix()
void append_file(FILE *dest, const char *source)
#define ASSERT(exp)
Definition: cddefines.h:617
double chi2_type
Definition: optimize.h:49
STATIC void start(long, realnum[], realnum[], long, long[], realnum *, int *)
const realnum VRSNEW
Definition: optimize.h:47
T pow2(T a)
Definition: cddefines.h:985
void init_state_file_name(const char *)
#define DEBUG_ENTRY(funcname)
Definition: cddefines.h:729
long useCPU
Definition: optimize.h:265
bool lgMPI() const
Definition: cpu.h:388
bool p_lgLimitExceeded(const X[]) const
bool lgMaxIterExceeded() const
Definition: optimize.h:137
#define fork()
void p_setup_next_hyperblock()
bool lgOptCont
Definition: optimize.h:264
int fprintf(const Output &stream, const char *format,...)
Definition: service.cpp:1217
#define F2(x, y, z)
realnum varmin[LIMPAR]
Definition: optimize.h:188
void p_reset_hyperblock()
void optimize_with_restart()
void p_evaluate_hyperblock()
void p_process_output(int, int)
long nCPU() const
Definition: cpu.h:385
static t_cpu cpu
Definition: cpu.h:423
const char * STATEFILE_BACKUP
#define pid_t
const char * host_name() const
Definition: cpu.h:395
void initial_run(Y(*)(const X[], int), int, const X[], const X[], X, int, phymir_mode, int)
#define wait(X)
#define MPI_Bcast(V, W, X, Y, Z)
Definition: mpi_utilities.h:85
void p_phygrm(X[][NP], int)
phymir_mode
Definition: optimize.h:65
#define EXIT_SUCCESS
Definition: cddefines.h:166