Show main.cpp syntax highlighted
#include "Oscill8External.h" // emery added for oscill8
#include "auto_f2c.h"
#include "auto_c.h"
#ifdef WIN32 /* @@edc: added for windows getopt */
extern char *optarg;
int getopt(int nargc, char * const *nargv, const char *ostr);
#endif
#ifdef FLOATING_POINT_TRAP
#include <fpu_control.h>
/* This is a x86 specific function only used for debugging.
It turns on various floating point traps. */
static int trapfpe()
{
fpu_control_t traps;
traps = _FPU_DEFAULT & (~(_FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM));
_FPU_SETCW(traps);
}
#endif
BEGIN_AUTO_NAMESPACE;
FILE *fp2 = NULL;
FILE *fp3 = NULL;
FILE *fp6 = NULL;
FILE *fp7 = NULL;
FILE *fp8 = NULL;
FILE *fp9 = NULL;
FILE *fp12 = NULL;
// initialize these... they may be reset before a call to AUTO_main
int num_model_pars = 10;
int num_total_pars = 2*num_model_pars;
int sysoff = num_model_pars;
void SetAutoNumParameters(int n)
{
num_model_pars = n;
num_total_pars = 4*n;
sysoff = n;
}
// add changable fort names for ease
char fort_name[13][512];
int fort_names_are_valid = 0;
double auto_progress = 0.0;
void SetFortNames(const char *key)
{
sprintf(fort_name[2], "%s.2", key);
sprintf(fort_name[3], "%s.3", key);
sprintf(fort_name[6], "%s.6", key);
sprintf(fort_name[7], "%s.7", key);
sprintf(fort_name[8], "%s.8", key);
sprintf(fort_name[9], "%s.9", key);
sprintf(fort_name[12], "%s.12", key);
}
int global_conpar_type=CONPAR_DEFAULT;
int global_setubv_type=SETUBV_DEFAULT;
int global_reduce_type=REDUCE_DEFAULT;
int global_num_procs=1;
int global_verbose_flag=0;
static void options(){
fprintf(fp6, "-v: Give verbose output.\n");
fprintf(fp6, "-m: Use the Message Passing Interface library for parallelization.\n");
fprintf(fp6, "-t: Use the Pthreads library for parallelization.\n");
fprintf(fp6, " This option takes one of three arguements.\n");
fprintf(fp6, " 'conpar' parallelizes the condensation of parameters routine.\n");
fprintf(fp6, " 'setubv' parallelizes the jacobian setup routine.\n");
fprintf(fp6, " 'reduce' parallelizes the nested dissection routine.\n");
fprintf(fp6, " 'all' parallelizes all routines.\n");
fprintf(fp6, " In general the recommeneded option is 'all'.\n");
fprintf(fp6, "-#: The number of processing units to use (currently only used with the -t option)\n");
}
static void scheme_not_supported_error(char *scheme) {
fprintf(fp6, "'%s' not available in this binary\n",scheme);
fprintf(fp6, "Support for '%s' needs to be included at compile time\n",scheme);
EXTERNAL_LIBRARY_FATAL_ERROR("O8AUTO", 0);
}
int AUTO_main(int argc,char *argv[])
{
// init progress
auto_progress = 0.0;
#ifdef WIN32
clock_t time0, time1;
#else
struct timeval *time0,*time1;
#endif
integer *icp = (integer *)malloc(sizeof(integer)*num_total_pars);
doublereal *par = (doublereal *)malloc(sizeof(doublereal)*num_total_pars),
*thl = (doublereal *)malloc(sizeof(doublereal)*num_total_pars);
doublereal *thu = 0;
integer *iuz = 0;
doublereal *vuz = 0;
iap_type iap;
rap_type rap;
function_list list;
#ifdef USAGE
struct rusage *init_usage,*total_usage;
usage_start(&init_usage);
usage_start(&total_usage);
#endif
#ifdef FLOATING_POINT_TRAP
trapfpe();
#endif
#ifdef MPI
MPI_Init(&argc,&argv);
#endif
// check if we should set fort_names or not
if(!fort_names_are_valid)
{
SetFortNames("fort");
strcpy(fort_name[6], "stdout");
}
OPEN_FP3:
fp3 = fopen(fort_name[3],"r");
if(fp3 == NULL) {
EXTERNAL_LIBRARY_FPRINTF_STDERR("warning: Could not open %s\n", fort_name[3]);
// don't die, just "touch" the file
fp3 = fopen(fort_name[3], "w");
if(fp3 == NULL)
{
EXTERNAL_LIBRARY_FPRINTF_STDERR("Error: couldn't not create %s\n", fort_name[3]);
EXTERNAL_LIBRARY_FATAL_ERROR("O8AUTO", 1);
}
fclose(fp3);
goto OPEN_FP3;
}
#ifdef LIBRARY_ONLY
if(strcmp(fort_name[6], "stdout"))
{
fp6 = fopen(fort_name[6],"w");
if(fp6 == NULL) {
EXTERNAL_LIBRARY_FPRINTF_STDERR("Error: Could not open %s\n", fort_name[6]);
EXTERNAL_LIBRARY_FATAL_ERROR("O8AUTO", 1);
}
}
else
fp6 = stdout;
#endif
fp7 = fopen(fort_name[7],"w");
if(fp7 == NULL) {
EXTERNAL_LIBRARY_FPRINTF_STDERR("Error: Could not open %s\n", fort_name[7]);
EXTERNAL_LIBRARY_FATAL_ERROR("O8AUTO", 1);
}
#ifdef _DEBUG
fp9 = fopen(fort_name[9],"w");
if(fp9 == NULL) {
EXTERNAL_LIBRARY_FPRINTF_STDERR("Error: Could not open %s\n", fort_name[9]);
EXTERNAL_LIBRARY_FATAL_ERROR("O8AUTO", 1);
}
#endif
#ifndef LIBRARY_ONLY
{
int c;
while (1)
{
c = getopt(argc, argv, "mt:?#:v");
if (c == -1)
break;
switch (c){
case 'v':
global_verbose_flag=1;
break;
case 'm':
#ifdef MPI
global_conpar_type = CONPAR_MPI;
global_setubv_type = SETUBV_MPI;
break;
#endif
scheme_not_supported_error("mpi");
break;
case 't':
#ifdef PTHREADS
if(strcmp(optarg,"setubv")==0) {
global_setubv_type = SETUBV_PTHREADS;
}
else if(strcmp(optarg,"conpar")==0) {
global_conpar_type = CONPAR_PTHREADS;
}
else if(strcmp(optarg,"reduce")==0) {
global_conpar_type = REDUCE_PTHREADS;
}
else if(strcmp(optarg,"all")==0) {
global_conpar_type = CONPAR_PTHREADS;
global_setubv_type = SETUBV_PTHREADS;
global_reduce_type = REDUCE_PTHREADS;
}
else {
EXTERNAL_LIBRARY_FPRINTF_STDERR("Unknown type for threads '%s'. Using 'all'\n",optarg);
global_conpar_type = CONPAR_PTHREADS;
global_setubv_type = SETUBV_PTHREADS;
}
break;
#endif
scheme_not_supported_error("threads");
break;
case '#':
global_num_procs=atoi(optarg);
break;
case '?':
options();
EXTERNAL_LIBRARY_FATAL_ERROR("O8AUTO", 0);
break;
default:
EXTERNAL_LIBRARY_PRINTF("?? getopt returned character code 0%o ??\n", c);
options();
EXTERNAL_LIBRARY_FATAL_ERROR("O8AUTO", 0);
}
} // while
} // scope
#endif
#ifdef MPI
{
char processor_name[MPI_MAX_PROCESSOR_NAME];
int myid,namelen;
MPI_Comm_rank(MPI_COMM_WORLD,&myid);
MPI_Get_processor_name(processor_name,&namelen);
if(global_verbose_flag) {
EXTERNAL_LIBRARY_FPRINTF_STDERR("Process %d on %s with pid %ld\n",
myid, processor_name, (long int)getpid());
}
if(myid!=0) {
global_conpar_type = CONPAR_MPI;
global_setubv_type = SETUBV_MPI;
mpi_worker();
}
}
#endif
/* Initialization : */
iap.mynode = mynode();
iap.numnodes = numnodes();
if (iap.numnodes > 1) {
iap.parallel_flag = 1;
} else {
iap.parallel_flag = 0;
}
while(1){
time_start(&time0);
time_start(&time1);
/* NOTE: thu is allocated inside this function, and the
pointer is passed back. I know this is ugly, but
this function does a bit of work to get thu setup correctly,
as well as figuring out the size the array should be.
What really should happen is to have one function which
reads fort.2 and another fuction which initializes the array.
That way the allocation could happen between the two calles.
*/
{
logical eof;
init(&iap, &rap, par, icp, thl, &thu, &iuz, &vuz, &eof);
if (eof) {
break;
}
}
/* Find restart label and determine type of restart point. */
if (iap.irs > 0) {
logical found = FALSE_;
findlb(&iap, &rap, iap.irs, &(iap.nfpr), &found);
if (! found) {
if (iap.mynode == 0) {
EXTERNAL_LIBRARY_FPRINTF_STDERR("\nRestart label %4ld not found\n",iap.irs);
}
EXTERNAL_LIBRARY_FATAL_ERROR("O8AUTO", 0);
}
}
#ifdef MPI
if(global_setubv_type==SETUBV_MPI) {
/* A few words about what is going on here. ips, irs, isw, itp, and
nfpr are used to choose which functions are used for funi, icni, bcni, etc.
unfortunately, their values are changed in init1 and chdim. In the
old version of AUTO the functions were already choosen by the point
these values were modified, so there was no problem. Now, in the
message passing parallel version, the workers need both versions, since
they both need to select the appropriate functions (using the old values)
and actually compute (using the new values). */
int comm_size,i;
integer funi_icni_params[5];
MPI_Comm_size(MPI_COMM_WORLD,&comm_size);
funi_icni_params[0]=iap.ips;
funi_icni_params[1]=iap.irs;
funi_icni_params[2]=iap.isw;
funi_icni_params[3]=iap.itp;
funi_icni_params[4]=iap.nfpr;
for(i=1;i<comm_size;i++){
/*Send message to get worker into init mode*/
{
int message=AUTO_MPI_INIT_MESSAGE;
MPI_Send(&message,1,MPI_INT,i,0,MPI_COMM_WORLD);
}
}
MPI_Bcast(funi_icni_params,5,MPI_LONG,0,MPI_COMM_WORLD);
}
#endif
set_function_pointers(iap,&list);
init1(&iap, &rap, icp, par);
chdim(&iap);
/* Create the allocations for the global structures used in
autlib3.c and autlib5.c. These are purely an efficiency thing.
The allocation and deallocation of these scratch areas takes
up a nontrivial amount of time if done directly in the
wrapper functions in autlib3.c*/
allocate_global_memory(iap);
/* ---------------------------------------------------------- */
/* ---------------------------------------------------------- */
/* One-parameter continuations */
/* ---------------------------------------------------------- */
/* ---------------------------------------------------------- */
#ifdef AUTO_CONSTRUCT_DESTRUCT
user_construct(argc,argv);
#endif
#ifdef USAGE
usage_end(init_usage,"main initialization");
#endif
if(list.type==AUTOAE)
autoae(&iap, &rap, par, icp, list.aelist.funi, list.aelist.stpnt, list.aelist.pvli, thl, thu, iuz, vuz);
if(list.type==AUTOBV)
autobv(&iap, &rap, par, icp, list.bvlist.funi, list.bvlist.bcni,
list.bvlist.icni, list.bvlist.stpnt, list.bvlist.pvli, thl, thu, iuz, vuz);
#ifdef USAGE
usage_end(total_usage,"total");
#endif
if(fp9 != NULL)
time_end(time0,"Total Time ",fp9);
fp9_printf("----------------------------------------------");
fp9_printf("----------------------------------------------\n");
time_end(time1,"",fp6);
#ifdef AUTO_CONSTRUCT_DESTRUCT
user_destruct();
#endif
}
#ifdef MPI
{
int message = AUTO_MPI_KILL_MESSAGE;
int size,i;
MPI_Comm_size(MPI_COMM_WORLD,&size);
for(i=1;i<size;i++)
MPI_Send(&message,1,MPI_INT,i,0,MPI_COMM_WORLD);
}
MPI_Finalize();
#endif
free(icp);
free(par);
free(thl);
if(thu != 0)
free(thu);
if(iuz != 0)
free(iuz);
if(vuz != 0)
free(vuz);
// close files
fclose(fp2); fp2 = NULL;
fclose(fp3); fp3 = NULL;
#ifdef LIBRARY_ONLY
if(fp6 != stdout)
fclose(fp6);
fp6 = NULL;
#else
fp6 = stdout;
#endif
if(fp7 != NULL)
{
fclose(fp7);
fp7 = NULL;
}
if(fp8 != NULL)
{
fclose(fp8);
fp8 = NULL;
}
if(fp9 != NULL)
{
fclose(fp9);
fp9 = NULL;
}
auto_progress = 1.0;
return 0;
}
END_AUTO_NAMESPACE;
#ifndef LIBRARY_ONLY /* @@edc: compiling in main will be an option now */
int main(int argc,char *argv[])
{
#ifdef __cplusplus
using LibAuto::AUTO_main;
#endif
return AUTO_main(argc, argv);
}
#endif
See more files for this project here