cuik.c
Go to the documentation of this file.
1 
2 #include "cuiksystem.h"
3 #include "parameters.h"
4 
5 #include "defines.h"
6 #include "error.h"
7 #include "box_list.h"
8 #include "filename.h"
9 #include "random.h"
10 
11 #include <string.h>
12 #include <stdlib.h>
13 #include <time.h>
14 
15 #if (_USE_MPI)
16  #include <mpi.h>
17  #include <unistd.h>
18 #endif
19 
20 
172 int main(int argc, char **arg)
173 {
174  signed int np=1,p=0; /* The default mode is to run in one processor */
175 
176  FILE *f_out; /* File where the solutions are printed as they
177  are found */
178 
179  FILE *f_state; /* File from where we try to recover the execution
180  state of cuik (this is used to continue execution
181  after a crash) */
182 
183  #if (!_QUIET)
184  FILE *f_in; /* Used to read-and-print the equation input
185  file in the output file */
186  #endif
187 
188  Tfilename fcuik;
189  Tfilename fparam;
190  Tfilename fsols;
191  Tfilename fstate;
192 
193  TCuikSystem cuiksystem; /* The set of variables and equations */
194  Tparameters parameters; /* Parameters used in the Cuik process */
195 
196  boolean restart; /* Restart from a state file */
197 
198  #if (_USE_MPI)
199  unsigned int i;
200  unsigned int fileflag_in;
201  MPI_Status status;
202  char name[MPI_MAX_PROCESSOR_NAME+1];
203  signed int len;
204 
205  MPI_Init(&argc,&arg);
206 
207  /* Set up a new Error handler */
208  //MPI_Errhandler_set(MPI_COMM_WORLD,MPI_ERRORS_RETURN);
209  MPI_Comm_set_errhandler(MPI_COMM_WORLD,MPI_ERRORS_RETURN);
210 
211  MPI_Comm_rank(MPI_COMM_WORLD,&p); /*number of this process*/
212  MPI_Comm_size(MPI_COMM_WORLD,&np); /*total number of processes*/
213  #endif
214 
215  if (argc>1)
216  {
217  randomReset();
218 
219  /*Init parameters*/
220  CreateFileName(NULL,arg[1],NULL,PARAM_EXT,&fparam);
221  InitParametersFromFile(GetFileFullName(&fparam),&parameters);
222 
223  /*Read the problem from file*/
224  CreateFileName(NULL,arg[1],NULL,CUIK_EXT,&fcuik);
225  InitCuikSystemFromFile(&parameters,GetFileFullName(&fcuik),&cuiksystem);
226 
227  #if (_USE_MPI)
228  /* Update the cuiksystem for all the processors (in complex files this can
229  take a while and its better to do it before starting to process boxes */
230  VerifyCuikSystem(&parameters,&cuiksystem);
231  #endif
232 
233  /*Check if a state file is available*/
234  if (p==0)
235  {
236  CreateFileName(NULL,arg[1],NULL,STATE_EXT,&fstate);
237  f_state=fopen(GetFileFullName(&fstate),"rb");
238  if (f_state)
239  {
240  restart=TRUE;
241  fclose(f_state);
242  }
243  else
244  restart=FALSE;
245  }
246  else
247  restart=FALSE;
248 
249 
250  /*Check if we can create the output file*/
251  f_out=stdout; /* the default is stdout for all processes.
252  Only process 0 has special output file */
253  if (p==0)
254  {
255  CreateFileName(NULL,arg[1],NULL,SOL_EXT,&fsols);
256  if (restart)
257  f_out=fopen(GetFileFullName(&fsols),"a"); /*append data to an already existing file*/
258  else
259  f_out=fopen(GetFileFullName(&fsols),"w"); /*start a brand new output file*/
260 
261  if (!f_out)
262  Error("Could not open main output file");
263  }
264 
265  #if (!_QUIET)
266  /*While the rest of processors read the parameter file, the
267  first processors stores data about the problem to be solved
268  next in the output file*/
269  if (p==0)
270  {
271  if (restart)
272  {
273  fprintf(f_out,"\n==========================================================================\n");
274  fprintf(f_out,"RESTARTING CUIK FROM A PREVIOUS EXECUTION STATE\n");
275  fprintf(f_out,"WE ASSUME THAT THE .cuik FILE AND THE .param FILE HAVE NOT CHANGED");
276  fprintf(f_out,"\n==========================================================================\n\n");
277  fflush(f_out);
278  }
279  else
280  {
281  fprintf(f_out,"\n==========================================================================\n");
282  PrintParameters(f_out,&parameters);
283 
284  /*Print the description of the problem to be solved*/
285  fprintf(f_out,"\n==========================================================================\n");
286  fprintf(f_out,"Equations from file: %s\n",GetFileFullName(&fcuik));
287  f_in=fopen(GetFileFullName(&fcuik),"r");
288  if (!f_in)
289  Error("Error opening input file");
290  else
291  {
292  int c;
293 
294  do { c=fgetc(f_in); if (c!=EOF) fprintf(f_out,"%c",c); } while(c!=EOF);
295  fclose(f_in);
296  fprintf(f_out,"\n");
297  }
298 
299  fprintf(f_out,"\n==========================================================================\n");
300  PrintCuikSystemWithSimplification(&parameters,f_out,&cuiksystem);
301  fprintf(f_out,"\n==========================================================================\n");
302  }
303  fflush(f_out);
304  }
305  #endif
306 
307  /* The main processors takes care of writing the solutions as they are
308  found by the slaves */
309  if ((p==0)&&(!restart))
310  {
311  fprintf(f_out,"Cuik executed in %u processors\n",np);
312  fprintf(f_out,"SOLUTIONS (to input file %s):\n\n",GetFileFullName(&fcuik));
313  fflush(f_out);
314  }
315 
316  if (np<3) /*single cpu execution -> Do not use parallel cuik*/
317  {
318  if (p==0)
319  SolveCuikSystem(&parameters,restart,GetFileFullName(&fstate),
320  NULL,f_out,NULL,&cuiksystem);
321  }
322  #if (_USE_MPI)
323  else
324  {
325  MPI_Get_processor_name(name,&len);
326 
327  /*Execution on several cpu: one is the master and the rest are slaves*/
328  /*First we wait all the slaves to be ready. We do not want to send out boxes
329  if the slaves are not ready to receive them.*/
330  if (p==0)
331  {
332  fprintf(stdout,"Main scheduler running on %s\n",name);
333  fprintf(stdout,"Waiting all processes to read the param/cuik files\n");
334  fflush(stdout);
335 
336  for(i=1;i<(unsigned int)np;i++)
337  {
338  while ((MPI_Recv(&fileflag_in,1,MPI_UNSIGNED,i,50+i,MPI_COMM_WORLD,&status)!=MPI_SUCCESS)&&
339  (fileflag_in!=i));
340  fprintf(stdout,"Ping from process %u received\n",i);
341  fflush(stdout);
342  }
343 
344  fprintf(stdout,"Starting scheduler\n");
345  fflush(stdout);
346 
347  MPI_SolveCuikSystem(&parameters,restart,GetFileFullName(&fstate),NULL,f_out,&cuiksystem); /* one master */
348  }
349  else
350  {
351  fprintf(stdout,"Starting sub-proces on processor %d running on %s\n",p,name);
352  fflush(stdout);
353  /* Send a signal to the scheduler process (process number 0) indicating
354  that sub-process 'p' is ready to process boxes */
355  MPI_Ssend(&p,1,MPI_UNSIGNED,0,50+p,MPI_COMM_WORLD);
356 
357  MPI_TreatBox(&parameters,&cuiksystem); /* and np-1 slaves */
358 
359  printf("Killing sub-process %u\n",p);
360  fflush(stdout);
361  }
362  }
363  #endif
364 
365  if (p==0)
366  {
367  fprintf(f_out,"END OF THE SOLUTION FILE\n\n");
368  fclose(f_out);
369  }
370 
371  /*Delete the parameters and the graph itself*/
372  DeleteParameters(&parameters);
373  DeleteCuikSystem(&cuiksystem);
374 
375  DeleteFileName(&fcuik);
376  DeleteFileName(&fparam);
377 
378  if (p==0)
379  {
380  DeleteFileName(&fsols);
381 
382  /*Remove the last state file generated*/
383  remove(GetFileFullName(&fstate));
384  DeleteFileName(&fstate);
385  }
386  }
387  else
388  {
389  if (p==0) /* Only one error message */
390  {
391  fprintf(stderr," Wrong number of parameters.\n");
392  fprintf(stderr," Use:\n");
393  fprintf(stderr," cuik <problem file name>.cuik \n");
394  fprintf(stderr," where <problem file name> contains the kinematic equations\n");
395  fprintf(stderr," (the '.cuik' extension is not required)\n");
396  }
397  }
398 
399  #if (_USE_MPI)
400  MPI_Finalize();
401  #endif
402 
403  return(EXIT_SUCCESS);
404 }
405 
void PrintCuikSystemWithSimplification(Tparameters *p, FILE *f, TCuikSystem *cs)
Prints the simplified cuiksystem.
Definition: cuiksystem.c:5047
#define FALSE
FALSE.
Definition: boolean.h:30
void PrintParameters(FILE *f, Tparameters *p)
Prints a parameter set.
Definition: parameters.c:181
Data structure to hold the information about the name of a file.
Definition: filename.h:248
void randomReset()
Resets the random seed.
Definition: random.c:18
void DeleteCuikSystem(TCuikSystem *cs)
Destructor.
Definition: cuiksystem.c:5113
Definition of the Tfilename type and the associated functions.
#define TRUE
TRUE.
Definition: boolean.h:21
void Error(const char *s)
General error function.
Definition: error.c:80
#define PARAM_EXT
File extension for parameter files.
Definition: filename.h:131
#define CUIK_EXT
File extension for equation files.
Definition: filename.h:70
Collection of methods to work on Tlist of boxes.
void MPI_TreatBox(Tparameters *p, TCuikSystem *cs)
Determines the solution set for a cuiksystem. Child process.
Definition: cuiksystem.c:4490
Error and warning functions.
void DeleteFileName(Tfilename *fn)
Destructor.
Definition: filename.c:205
void SolveCuikSystem(Tparameters *p, boolean restart, char *fstate, Tbox *searchSpace, FILE *f_out, Tlist *sol, TCuikSystem *cs)
Determines the solution set for a cuiksystem.
Definition: cuiksystem.c:3926
Definitions of constants and macros used in several parts of the cuik library.
void InitCuikSystemFromFile(Tparameters *p, char *filename, TCuikSystem *cs)
Constructor from a file.
A table of parameters.
Definition of the TCuikSystem type and the associated functions.
void CreateFileName(char *path, char *name, char *suffix, char *ext, Tfilename *fn)
Constructor.
Definition: filename.c:22
void InitParametersFromFile(char *file, Tparameters *p)
Constructor from a file.
Definition: parameters.c:51
char * GetFileFullName(Tfilename *fn)
Gets the file full name (paht+name+extension).
Definition: filename.c:151
#define SOL_EXT
File extension for solution files.
Definition: filename.h:137
A cuiksystem, i.e., a set of variables and equations defining a position analysis problem...
Definition: cuiksystem.h:181
void DeleteParameters(Tparameters *p)
Destructor.
Definition: parameters.c:295
int main(int argc, char **arg)
Main body of the cuik application.
Definition: cuik.c:172
void VerifyCuikSystem(Tparameters *p, TCuikSystem *cs)
Checks the consistency of the cuiksystem.
Definition: cuiksystem.c:2194
Definition of basic randomization functions.
Definition of the Tparameters type and the associated functions.
#define STATE_EXT
File extension for files storing the interval solver state.
Definition: filename.h:193
void MPI_SolveCuikSystem(Tparameters *p, boolean restart, char *fstate, Tbox *searchSpace, FILE *f_out, TCuikSystem *cs)
Determines the solution set for a cuiksystem. Main scheduler.
Definition: cuiksystem.c:4103