Institut de Robòtica i Informàtica Industrial
KRD Group

The CuikSuite Project

cuik.c

Go to the documentation of this file.
00001 
00002 #include "cuiksystem.h"
00003 #include "parameters.h"
00004 
00005 #include "defines.h"
00006 #include "error.h"
00007 #include "box_list.h"
00008 #include "filename.h"
00009 #include "random.h"
00010 
00011 #include <string.h>
00012 #include <stdlib.h>
00013 #include <time.h>
00014 
00015 #if (_USE_MPI)
00016   #include <mpi.h>
00017   #include <unistd.h>
00018 #endif
00019 
00149 int main(int argc, char **arg)
00150 {
00151   signed int np=1,p=0;     /* The default mode is to run on one processor */
00152 
00153   FILE *f_out;             /* File where the solutions are printed as they 
00154                               are found */
00155 
00156   FILE *f_state;           /* File from where we try to recover the execution
00157                               state of cuik (this is used to continue execution
00158                               after a crash) */
00159 
00160   #if (!_QUIET)
00161     FILE *f_in;            /* Used to read-and-print the equation input 
00162                               file in the output file */
00163   #endif
00164 
00165   Tfilename fcuik;
00166   Tfilename fparam;
00167   Tfilename fsols;
00168   Tfilename fstate;
00169 
00170   TCuikSystem cuiksystem;  /* The set of variables and equations */
00171   Tparameters parameters;  /* Parameters used in the Cuik process */
00172 
00173   boolean restart;         /* Restart from a state file */
00174 
00175   #if (_USE_MPI)
00176     unsigned int i;
00177     unsigned int fileflag_in;
00178     MPI_Status status;
00179     char name[MPI_MAX_PROCESSOR_NAME+1];
00180     signed int len;
00181 
00182     MPI_Init(&argc,&arg);
00183 
00184     /* Set up a new Error handler */
00185     MPI_Errhandler_set(MPI_COMM_WORLD,MPI_ERRORS_RETURN);
00186 
00187     MPI_Comm_rank(MPI_COMM_WORLD,&p);  /*number of this process*/
00188     MPI_Comm_size(MPI_COMM_WORLD,&np); /*total number of processes*/
00189   #endif
00190 
00191   if (argc>1)
00192     {
00193       randomReset();
00194 
00195       /*Init parameters*/
00196       CreateFileName(NULL,arg[1],NULL,PARAM_EXT,&fparam);
00197       InitParametersFromFile(GetFileFullName(&fparam),&parameters);
00198 
00199       /*Read the problem from file*/
00200       CreateFileName(NULL,arg[1],NULL,CUIK_EXT,&fcuik);
00201       InitCuikSystemFromFile(&parameters,GetFileFullName(&fcuik),&cuiksystem);
00202 
00203       /*Check if a state file is available*/
00204       if (p==0)
00205         {
00206           CreateFileName(NULL,arg[1],NULL,STATE_EXT,&fstate);
00207           f_state=fopen(GetFileFullName(&fstate),"rb");
00208           if (f_state)
00209             {
00210               restart=TRUE;
00211               fclose(f_state);
00212             }
00213           else
00214             restart=FALSE;
00215         }
00216       else
00217         restart=FALSE;
00218       
00219 
00220       /*Check if we can create the output file*/
00221       f_out=stdout; /* the default is stdout for all processes. 
00222                        Only process 0 has special output file */
00223       if (p==0)
00224         {
00225           CreateFileName(NULL,arg[1],NULL,SOL_EXT,&fsols);
00226           if (restart)
00227             f_out=fopen(GetFileFullName(&fsols),"a"); /*append data to an already existing file*/
00228           else
00229             f_out=fopen(GetFileFullName(&fsols),"w"); /*start a brand new output file*/
00230 
00231           if (!f_out)
00232             Error("Could not open main output file");
00233         }
00234 
00235       #if (!_QUIET)
00236         /*While the rest of processors read the parameter file, the 
00237           first processors stores data about the problem to be solved 
00238           next in the output file*/
00239         if (p==0)
00240           {
00241             if (restart)
00242               {
00243                 fprintf(f_out,"\n==========================================================================\n");
00244                 fprintf(f_out,"RESTARTING CUIK FROM A PREVIOUS EXECUTION STATE\n");
00245                 fprintf(f_out,"WE ASSUME THAT THE .cuik FILE AND THE .param FILE HAVE NOT CHANGED");
00246                 fprintf(f_out,"\n==========================================================================\n\n");
00247                 fflush(f_out);
00248               }
00249             else
00250               {
00251                 fprintf(f_out,"\n==========================================================================\n");
00252                 PrintParameters(f_out,&parameters);
00253             
00254                 /*Print the description of the problem to be solved*/
00255                 fprintf(f_out,"\n==========================================================================\n");
00256                 fprintf(f_out,"Equations from file: %s\n",GetFileFullName(&fcuik));
00257                 f_in=fopen(GetFileFullName(&fcuik),"r");
00258                 if (!f_in)
00259                   Error("Error opening input file");
00260                 else
00261                   {
00262                     int c;
00263 
00264                     do { c=fgetc(f_in); if (c!=EOF) fprintf(f_out,"%c",c); } while(c!=EOF);
00265                     fclose(f_in);
00266                     fprintf(f_out,"\n"); 
00267                   }
00268          
00269                 fprintf(f_out,"\n==========================================================================\n");
00270                 PrintCuikSystemWithSimplification(&parameters,f_out,&cuiksystem);
00271                 fprintf(f_out,"\n==========================================================================\n");
00272               }
00273             fflush(f_out);
00274           }
00275       #endif
00276 
00277       /* The main processors takes care of writing the solutions as they are 
00278          found by the slaves */
00279       if ((p==0)&&(!restart))
00280         { 
00281           fprintf(f_out,"SOLUTIONS (to input file %s):\n\n",GetFileFullName(&fcuik)); 
00282           fflush(f_out);
00283         }
00284 
00285       if (np<3) /*single cpu execution -> Do not use parallel cuik*/
00286         {
00287           if (p==0)
00288             SolveCuikSystem(&parameters,0,restart,GetFileFullName(&fstate),f_out,NULL,&cuiksystem); 
00289         }
00290       #if (_USE_MPI)
00291       else
00292         {
00293           MPI_Get_processor_name(name,&len);
00294 
00295           /*Execution on several cpu: one is the master and the rest are slaves*/
00296           /*First we wait all the slaves to be ready. We do not want to send out boxes
00297             if the slaves are not ready to receive them.*/
00298           if (p==0)
00299             {
00300               fprintf(stdout,"Main scheduler running on %s\n",name);
00301               fprintf(stdout,"Waiting all processes to read the param/cuik files\n"); 
00302               fflush(stdout);
00303               
00304               for(i=1;i<(unsigned int)np;i++)
00305                 {
00306                   while ((MPI_Recv(&fileflag_in,1,MPI_UNSIGNED,i,50+i,MPI_COMM_WORLD,&status)!=MPI_SUCCESS)&&
00307                          (fileflag_in!=i));
00308                   fprintf(stdout,"Ping from process %u received\n",i);
00309                   fflush(stdout);
00310                 }
00311 
00312               fprintf(stdout,"Starting scheduler\n");
00313               fflush(stdout); 
00314 
00315               MPI_SolveCuikSystem(&parameters,restart,GetFileFullName(&fstate),f_out,&cuiksystem); /* one master */
00316             }
00317           else
00318             {
00319               fprintf(stdout,"Starting sub-proces on processor %d running on %s\n",p,name);
00320               fflush(stdout); 
00321               /* Send a signal to the scheduler process (process number 0) indicating
00322                  that sub-process 'p' is ready to process boxes */
00323               MPI_Ssend(&p,1,MPI_UNSIGNED,0,50+p,MPI_COMM_WORLD);
00324 
00325               MPI_TreatBox(&parameters,&cuiksystem); /* and np-1 slaves */
00326 
00327               printf("Killing sub-process %u\n",p);
00328               fflush(stdout);
00329             }
00330         }
00331       #endif
00332 
00333       if (p==0) 
00334         {
00335           fprintf(f_out,"END OF THE SOLUTION FILE\n\n");
00336           fclose(f_out);
00337         }
00338 
00339       /*Delete  the parameters and the graph itself*/
00340       DeleteParameters(&parameters);
00341       DeleteCuikSystem(&cuiksystem);
00342       
00343       DeleteFileName(&fcuik);
00344       DeleteFileName(&fparam);
00345 
00346       if (p==0)
00347         {
00348           DeleteFileName(&fsols);
00349  
00350           /*Remove the last state file generated*/
00351           remove(GetFileFullName(&fstate));
00352           DeleteFileName(&fstate);
00353         }
00354     }
00355   else
00356     {
00357       if (p==0) /* Only one error message */
00358         {
00359           fprintf(stderr,"  Wrong number of parameters.\n");
00360           fprintf(stderr,"  Use:\n");   
00361           fprintf(stderr,"      cuik <problem filename>.cuik \n");
00362           fprintf(stderr,"  where <problem filename> contains the kinematic equations\n");
00363           fprintf(stderr,"    (the '.cuik' extension is not required)\n");
00364         }
00365     }
00366 
00367   #if (_USE_MPI)
00368     MPI_Finalize();
00369   #endif
00370 
00371   return(EXIT_SUCCESS);
00372 }
00373