--- a +++ b/feasible_joint_stiffness/lrslib-062/mplrs.h @@ -0,0 +1,284 @@ +/* mplrs.h: header for mplrs.c +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +Author: Charles Jordan skip@ist.hokudai.ac.jp +Based on plrs by Gary Roumanis +Initial lrs Author: David Avis avis@cs.mcgill.ca +*/ + +#ifndef MPLRSH +#define MPLRSH 1 + +#include "lrslib.h" + +#include <mpi.h> +#include <stdlib.h> +#include <string.h> +#include <signal.h> +#include <sys/time.h> + + +#define USAGE "Usage is: \n mpirun -np <number of processes> mplrs <infile> <outfile> \n or \n mpirun -np <number of processes> mplrs <infile> <outfile> -id <initial depth> -maxc <maxcobases> -maxd <depth> -lmin <int> -lmax <int> -scale <int> -maxbuf <int> -countonly -hist <file> -temp <prefix> -freq <file> -stop <stopfile> -checkp <checkpoint file> -restart <checkpoint file> -time <seconds> -stopafter <int>" + +/* Default values for options. */ +#define DEF_LMIN 3 /* default -lmin */ +#define DEF_LMAX -1 /* default -lmax */ +#define DEF_ID 2 /* default -id */ +#define DEF_MAXD 0 /* default -maxd */ +#define DEF_MAXC 50 /* default -maxc */ +#define DEF_MAXNCOB 0 /* default -stopafter (disabled) */ +#define DEF_MAXBUF 500 /* default -maxbuf */ + +#define DEF_TEMP "/tmp/" /* default prefix for temporary files + * use /a/b to get files /a/bfilename, + * use /a/b/ to get files /a/b/filename + */ +#define DEF_INPUT NULL /* default input filename (or NULL) */ +#define DEF_OUTPUT NULL /* default output filename (or NULL) */ +#define DEF_HIST NULL /* default histogram filename (or NULL) */ +#define DEF_RESTART NULL/* default restart filename (or NULL) */ +#define DEF_FREQ NULL /* default sub-problem size filename (NULL) */ +#define DEF_CHECKP NULL /* default checkpoint filename (or NULL) */ +#define DEF_STOP NULL /* default stop-signal filename (or NULL) */ + +#define DEF_SCALEC 100 /* default multiplicative scaling factor for maxc, + * used when L is too large (controlled by lmax) */ + +/* singly linked list */ +typedef struct slist { + void *data; + slist *next; +} slist; + +typedef struct outlist { + char *type; + char *data; + outlist *next; +} outlist; + +/* A linked-list of buffers for MPI communications. + * req[0...count-1] correspond to buf[0...count-1] + * + * When req[i] completes, should free buf[i]. + * When all reqs complete, should free buf, req, tags,sizes,types. + */ +typedef struct msgbuf { + MPI_Request *req; + void **buf; + int count; + int target; + int data; /* optional, use yourself if needed for something */ + int queue; /* if 1, send items 1...count after 0 has completed */ + /* queue pointers must be NULL or something free()able */ + int *tags; /* tags to use on items 1...count if queued */ + int *sizes; /* sizes of sends if queued */ + MPI_Datatype *types; /* types of sends if queued */ + + msgbuf *next; +} msgbuf; + +/* A structure containing the state of this process. + * Each process has one. + */ +typedef struct mplrsv { + /* MPI communication buffers */ + msgbuf *outgoing; + slist *cobasis_list; + + int caughtsig; /* flag for catching a signal */ + /* counts */ + unsigned long rays; + unsigned long vertices; + unsigned long bases; + unsigned long facets; + unsigned long intvertices; + lrs_mp Tnum, Tden, tN, tD, Vnum, Vden; + + struct timeval start, end; + + /* MPI info */ + int rank; /* my rank */ + int size; /* number of MPI processes */ + int my_tag; /* to distinguish MPI sends */ + char host[MPI_MAX_PROCESSOR_NAME]; /* name of this host */ + + /* output_list */ + outlist *output_list; + + /* for convenience */ + char *tfn_prefix; + char *tfn; + FILE *tfile; + int initializing; /* in phase 1? */ + int countonly; /* countonly */ + int outnum; /* number of output lines buffered */ + int maxbuf; /* maximum number of output lines to buffer before flush */ + + char *input_filename; /* input filename */ + char *input; /* buffer for contents of input file */ +} mplrsv; + +/* A structure for variables only the master needs */ +typedef struct masterv { + slist *cobasis_list; /* list of work to do (L) */ + unsigned long tot_L; /* total size of L (total # jobs) */ + unsigned long size_L; /* current size of L (for histograms + * and scaling) + */ + unsigned long num_empty; /* number of times L became empty */ + unsigned int num_producers; /* number of producers running */ + unsigned int *act_producers; /* whether each producer owes us + * remaining bases message. + * Needed only for histograms. + */ + unsigned int live_workers; /* number that haven't exited */ + /* MPI communication buffers */ + int *workin; /* incoming messages from producers + desiring work */ + MPI_Request *mworkers; /* MPI_Requests for these messages */ + msgbuf *incoming; /* incoming cobases from producers */ + MPI_Request *sigcheck; /* MPI_Requests for reporting signals*/ + + int checkpointing; /* are we checkpointing now? */ + + /* user options */ + unsigned int lmin; /* option -lmin */ + unsigned int lmax; /* option -lmax */ + unsigned int scalec; /* option -scale*/ + unsigned int initdepth; /* option -id */ + unsigned int maxdepth; /* option -maxd */ + unsigned int maxcobases; /* option -maxc */ + unsigned int time_limit; /* option -time */ + unsigned long maxncob; /* option -stopafter */ + + /* files */ + char *hist_filename; /*histogram filename (or NULL)*/ + FILE *hist; + int doing_histogram; /* are we doing a histogram? */ + char *freq_filename; /*are we outputting sub-problem sizes?*/ + FILE *freq; + char *restart_filename; /* restart from a checkpoint */ + FILE *restart; + char *checkp_filename; /* filename to save checkpoint*/ + FILE *checkp; + char *stop_filename; /* option -stop */ + FILE *stop; + FILE *input; +} masterv; + +/* A structure for variables only the consumer needs */ +typedef struct consumerv { + /* MPI communication buffers */ + /* for headers */ + MPI_Request *prodreq; /* consumer keeps an open request + * for each producer and master + */ + int *prodibf; /* and two ints as a receive buffer */ + /* for content */ + msgbuf *incoming; /* incoming MPI communication buffers */ + + /* output */ + char *output_filename; /* output filename (or NULL) */ + FILE *output; /* output file (NULL for stdout) */ + + /* status */ + unsigned int num_producers; /* number of producers still going */ + unsigned int checkpoint; /* do we want to checkpoint now? */ + + /* other */ + int waiting_initial; /* waiting for initial producer, + * hold output until after 'begin' + */ +} consumerv; + +/* MASTER and CONSUMER and INITIAL must be different */ +#define MASTER 0 /* the MPI process that becomes master */ +#define CONSUMER 1 /* the MPI process that becomes consumer */ +#define INITIAL 2 + +#define CHECKFLAG -3 /* must be distinct negative values */ +#define RESTARTFLAG -4 + +/* define DEBUG to get many mplrs debug messages */ +#ifdef DEBUG +#define mprintf(a) printf a +#else +#define mprintf(a) +#endif +/* define DEBUG2 to get even more */ +#ifdef DEBUG2 +#define mprintf2(a) printf a +#else +#define mprintf2(a) +#endif +/* define DEBUG3 to get lots */ +#ifdef DEBUG3 +#define mprintf3(a) printf a +#else +#define mprintf3(a) +#endif + +/* function prototypes */ +void mplrs_init(int, char **); +void mplrs_caughtsig(int); +void master_sendfile(void); +void mplrs_initstrucs(); +void mplrs_commandline(int, char **); +void mplrs_initfiles(void); +void bad_args(void); +int mplrs_fallback(void); + +int mplrs_master(void); +void send_work(int, int); +void recv_producer_lists(void); +void process_returned_cobases(msgbuf *); +void setparams(int *); +void check_stop(void); +void master_checksigs(void); +void master_restart(void); +void master_checkpoint(void); +void master_checkpointfile(void); +void master_checkpointconsumer(void); +void print_histogram(timeval *, timeval *); + +int mplrs_worker(void); +void clean_outgoing_buffers(void); /* shared with master */ +void do_work(const int *, const char *); +void process_output(void); +void send_output(int, char *); +void process_cobasis(const char *); +inline slist *addlist(slist *, void *); +void return_unfinished_cobases(void); +char *append_out(char *, int *, const char *); +int mplrs_worker_finished(void); + +int mplrs_consumer(void); +void consumer_start_incoming(void); +msgbuf *consumer_queue_incoming(int *, int); +void consumer_proc_messages(void); +int consumer_checkpoint(void); +inline int outgoing_msgbuf_completed(msgbuf *); +inline void free_msgbuf(msgbuf *); +outlist *reverse_list(outlist*); +void send_master_stats(void); +void recv_master_stats(void); +void send_counting_stats(int); +void recv_counting_stats(int); +void initial_print(void); +inline void phase1_print(void); +void final_print(void); +inline char *dupstr(const char *str); + +#endif /* MPLRSH */