1 /* mplrs.h: header for mplrs.c 2 This program is free software; you can redistribute it and/or 3 modify it under the terms of the GNU General Public License 4 as published by the Free Software Foundation; either version 2 5 of the License, or (at your option) any later version. 6 7 This program is distributed in the hope that it will be useful, 8 but WITHOUT ANY WARRANTY; without even the implied warranty of 9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 GNU General Public License for more details. 11 12 You should have received a copy of the GNU General Public License 13 along with this program; if not, write to the Free Software 14 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 15 16 Author: Charles Jordan skip@ist.hokudai.ac.jp 17 Based on plrs by Gary Roumanis 18 Initial lrs Author: David Avis avis@cs.mcgill.ca 19 */ 20 21 #ifndef MPLRSH 22 #define MPLRSH 1 23 24 #ifdef MA 25 #define GMP 26 #endif 27 28 #include "lrsdriver.h" 29 #include "lrslib.h" 30 31 #include <mpi.h> 32 #include <stdlib.h> 33 #include <string.h> 34 #include <signal.h> 35 #include <sys/time.h> 36 #include <stdio.h> 37 38 extern FILE *lrs_ofp; /* hack to get redund final print in output file */ 39 40 #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> -redund" 41 42 /* Default values for options. */ 43 #define DEF_LMIN 3 /* default -lmin */ 44 #define DEF_LMAX 0 /* default -lmax. but note orig_lmax behavior! */ 45 #define DEF_ID 2 /* default -id */ 46 #define DEF_MAXD 0 /* default -maxd */ 47 #define DEF_MAXC 50 /* default -maxc */ 48 #define DEF_MAXNCOB 0 /* default -stopafter (disabled) */ 49 #define DEF_MAXBUF 500 /* default -maxbuf */ 50 51 #define DEF_TEMP "/tmp/" /* default prefix for temporary files 52 * use /a/b to get files /a/bfilename, 53 * use /a/b/ to get files /a/b/filename 54 */ 55 #define DEF_INPUT NULL /* default input filename (or NULL) */ 56 #define DEF_OUTPUT NULL /* default output filename (or NULL) */ 57 #define DEF_HIST NULL /* default histogram filename (or NULL) */ 58 #define DEF_RESTART NULL/* default restart filename (or NULL) */ 59 #define DEF_FREQ NULL /* default sub-problem size filename (NULL) */ 60 #define DEF_CHECKP NULL /* default checkpoint filename (or NULL) */ 61 #define DEF_STOP NULL /* default stop-signal filename (or NULL) */ 62 63 #define DEF_SCALEC 100 /* default multiplicative scaling factor for maxc, 64 * used when L is too large (controlled by lmax) */ 65 66 #if defined(MA) || (defined(LRSLONG) && !defined(B128)) 67 #define mplrs_init_lrs_main lrs1_main 68 #elif defined(LRSLONG) /* B128 */ 69 #define mplrs_init_lrs_main lrs2_main 70 #elif defined(GMP) 71 #define mplrs_init_lrs_main lrsgmp_main 72 #elif defined(FLINT) 73 #define mplrs_init_lrs_main lrsv2_main 74 #elif defined(MP) 75 #define mplrs_init_lrs_main lrsv2_main 76 #endif 77 78 /* singly linked list */ 79 typedef struct slist { 80 void *data; 81 struct slist *next; 82 } slist; 83 84 typedef struct outlist { 85 char *type; 86 char *data; 87 struct outlist *next; 88 } outlist; 89 90 /* A linked-list of buffers for MPI communications. 91 * req[0...count-1] correspond to buf[0...count-1] 92 * 93 * When req[i] completes, should free buf[i]. 94 * When all reqs complete, should free buf, req, tags,sizes,types. 95 */ 96 typedef struct msgbuf { 97 MPI_Request *req; 98 void **buf; 99 int count; 100 int target; 101 int data; /* optional, use yourself if needed for something */ 102 int queue; /* if 1, send items 1...count after 0 has completed */ 103 /* queue pointers must be NULL or something free()able */ 104 int *tags; /* tags to use on items 1...count if queued */ 105 int *sizes; /* sizes of sends if queued */ 106 MPI_Datatype *types; /* types of sends if queued */ 107 108 struct msgbuf *next; 109 } msgbuf; 110 111 /* A structure containing the state of this process. 112 * Each process has one. 113 */ 114 typedef struct mplrsv { 115 /* MPI communication buffers */ 116 msgbuf *outgoing; 117 slist *cobasis_list; 118 long (*lrs_main)(int, char **, lrs_dic **, lrs_dat **, long, long, char *, lrs_restart_dat *); 119 lrs_dic *P; 120 lrs_dat *Q; 121 lrs_restart_dat *R; 122 123 int caughtsig; /* flag for catching a signal */ 124 unsigned int abortinit; /* lrs_main stage 0 (setup) failed? */ 125 unsigned int overflow; /* 0: lrslong 1:lrslong2 2:lrsgmp */ 126 /* counts */ 127 unsigned long long rays; 128 unsigned long long vertices; 129 unsigned long long bases; 130 unsigned long long facets; 131 unsigned long long linearities; 132 unsigned long long intvertices; 133 unsigned long long deepest; 134 unsigned long long nredundcol; 135 lrs_mp Tnum, Tden, tN, tD, Vnum, Vden; 136 137 struct timeval start, end; 138 139 /* MPI info */ 140 int rank; /* my rank */ 141 int size; /* number of MPI processes */ 142 int my_tag; /* to distinguish MPI sends */ 143 char host[MPI_MAX_PROCESSOR_NAME]; /* name of this host */ 144 145 /* output_list */ 146 outlist *output_list; 147 outlist *ol_tail; 148 149 char *finalwarn; /* for process_output "finalwarn" */ 150 int finalwarn_len; /* length allocated for finalwarn */ 151 char *curwarn; /* to discard "finalwarn" messages on */ 152 int curwarn_len; /* overflow, preventing duplicates */ 153 /* for convenience */ 154 const char *tfn_prefix; 155 char *tfn; 156 FILE *tfile; 157 int initializing; /* in phase 1? */ 158 int countonly; /* countonly */ 159 int outnum; /* number of output lines buffered */ 160 int maxbuf; /* maximum number of output lines to buffer before flush */ 161 int outputblock; /* temporarily prevent a maxbuf-based output flush */ 162 int redund; /* bool: is this a redund run? */ 163 164 char *input_filename; /* input filename */ 165 char *input; /* buffer for contents of input file */ 166 } mplrsv; 167 168 /* A structure for variables only the master needs */ 169 typedef struct masterv { 170 slist *cobasis_list; /* list of work to do (L) */ 171 unsigned long tot_L; /* total size of L (total # jobs) */ 172 unsigned long size_L; /* current size of L (for histograms 173 * and scaling) 174 */ 175 unsigned long num_empty; /* number of times L became empty */ 176 unsigned int num_producers; /* number of producers running */ 177 unsigned int *act_producers; /* whether each producer owes us 178 * remaining bases message. 179 * Needed only for histograms. 180 */ 181 unsigned int live_workers; /* number that haven't exited */ 182 /* MPI communication buffers */ 183 int *workin; /* incoming messages from producers 184 desiring work */ 185 MPI_Request *mworkers; /* MPI_Requests for these messages */ 186 msgbuf *incoming; /* incoming cobases from producers */ 187 float *sigbuf; /*incoming signal/termination requests*/ 188 MPI_Request *sigcheck; /* MPI_Requests for reporting these*/ 189 190 int checkpointing; /* are we checkpointing now? */ 191 int cleanstop; /* was a cleanstop requested? */ 192 int messages; /* do we want to set R->messages? */ 193 194 /* user options */ 195 unsigned int lmin; /* option -lmin */ 196 unsigned int lmax; /* option -lmax */ 197 int orig_lmax; /*user changed lmax? if not,lmax=lmin*/ 198 unsigned int scalec; /* option -scale*/ 199 unsigned int initdepth; /* option -id */ 200 unsigned int maxdepth; /* option -maxd */ 201 unsigned int maxcobases; /* option -maxc */ 202 unsigned int time_limit; /* option -time */ 203 unsigned long maxncob; /* option -stopafter */ 204 int lponly; /* bool for -lponly option */ 205 int redund; /* bool for -redund option */ 206 int max_redundworker; /* max id for a worker 207 * used if m>np-2 208 */ 209 /* files */ 210 char *hist_filename; /*histogram filename (or NULL)*/ 211 FILE *hist; 212 int doing_histogram; /* are we doing a histogram? */ 213 char *freq_filename; /*are we outputting sub-problem sizes?*/ 214 FILE *freq; 215 char *restart_filename; /* restart from a checkpoint */ 216 FILE *restart; 217 char *checkp_filename; /* filename to save checkpoint*/ 218 FILE *checkp; 219 char *stop_filename; /* option -stop */ 220 FILE *stop; 221 FILE *input; 222 } masterv; 223 224 /* A structure for variables only the consumer needs */ 225 typedef struct consumerv { 226 /* MPI communication buffers */ 227 /* for headers */ 228 MPI_Request *prodreq; /* consumer keeps an open request 229 * for each producer and master 230 */ 231 int *prodibf; /* and two ints as a receive buffer */ 232 /* for content */ 233 msgbuf *incoming; /* incoming MPI communication buffers */ 234 235 /* output */ 236 char *output_filename; /* output filename (or NULL) */ 237 FILE *output; /* output file (NULL for stdout) */ 238 239 /* status */ 240 unsigned int num_producers; /* number of producers still going */ 241 242 /* other */ 243 unsigned int oflow_flag; /* 0: no overflow message yet */ 244 int *overflow; /* number of overflowed workers*/ 245 int waiting_initial; /* waiting for initial producer, 246 * hold output until after 'begin' 247 */ 248 int final_print; /* do the final print? (bool) */ 249 long *redineq; /* bool vector for redund, which rows redundant */ 250 int final_redundcheck; /* are we in the final redund check? */ 251 } consumerv; 252 253 /* MASTER and CONSUMER and INITIAL must be different */ 254 #define MASTER 0 /* the MPI process that becomes master */ 255 #define CONSUMER 1 /* the MPI process that becomes consumer */ 256 #define INITIAL 2 257 258 #define CHECKFLAG -3 /* must be distinct negative values */ 259 #define RESTARTFLAG -4 260 #define STOPFLAG -5 261 262 /* define MDEBUG to get many mplrs debug messages */ 263 #ifdef MDEBUG 264 #define mprintf(a) printf a 265 #else 266 #define mprintf(a) 267 #endif 268 /* define MDEBUG2 to get even more */ 269 #ifdef MDEBUG2 270 #define mprintf2(a) printf a 271 #else 272 #define mprintf2(a) 273 #endif 274 /* define MDEBUG3 to get lots */ 275 #ifdef MDEBUG3 276 #define mprintf3(a) printf a 277 #else 278 #define mprintf3(a) 279 #endif 280 281 /* function prototypes */ 282 void mplrs_init(int, char **); 283 void mplrs_caughtsig(int); 284 void master_sendfile(void); 285 void mplrs_initstrucs(); 286 void mplrs_commandline(int, char **); 287 void mplrs_initfiles(void); 288 void bad_args(void); 289 int mplrs_fallback(void); 290 291 int mplrs_master(void); 292 void send_work(int, int); 293 void recv_producer_lists(void); 294 void process_returned_cobases(msgbuf *); 295 void setparams(int *); 296 void check_stop(void); 297 void master_stop_consumer(int); 298 void master_checksigs(void); 299 void master_restart(void); 300 void master_checkpoint(void); 301 void master_checkpointfile(void); 302 void master_checkpointconsumer(void); 303 void print_histogram(struct timeval *, struct timeval *); 304 305 int mplrs_worker(void); 306 void mplrs_worker_init(void); 307 void clean_outgoing_buffers(void); /* shared with master */ 308 void do_work(const int *, char *); 309 void worker_report_overflow(void); 310 void process_output(void); 311 void process_curwarn(void); 312 void send_output(int, char *); 313 void process_cobasis(const char *); 314 slist *addlist(slist *, void *); 315 void return_unfinished_cobases(void); 316 char *append_out(char *, int *, const char *); 317 int mplrs_worker_finished(void); 318 319 int mplrs_consumer(void); 320 void consumer_start_incoming(void); 321 msgbuf *consumer_queue_incoming(int *, int); 322 void consumer_proc_messages(void); 323 int consumer_checkpoint(void); 324 int outgoing_msgbuf_completed(msgbuf *); 325 void free_msgbuf(msgbuf *); 326 outlist *reverse_list(outlist*); 327 void send_master_stats(void); 328 void recv_master_stats(void); 329 void send_counting_stats(int); 330 void recv_counting_stats(int); 331 void initial_print(void); 332 void phase1_print(void); 333 void consumer_setredineq(void); 334 void final_print(void); 335 char *dupstr(const char *str); 336 337 int okay_to_flush(void); 338 void post_output(const char *, const char *); 339 void open_outputblock(void); 340 void close_outputblock(void); 341 void mplrs_cleanstop(int); 342 void mplrs_emergencystop(const char *); 343 void overflow_cleanup(void); 344 void set_restart(const int *, char *); 345 #endif /* MPLRSH */ 346