diff --git a/docs/USERS_GUIDE.html b/docs/USERS_GUIDE.html index 5d953607892031797d1df6c13825dd9e4109c379..8b573222b6f63bb724c4c8ccd45c20f35aa46606 100644 --- a/docs/USERS_GUIDE.html +++ b/docs/USERS_GUIDE.html @@ -22,6 +22,7 @@ <div><a href="#libr">Library use</a></div> <div><a href="MATLAB.html">MATLAB</a></div> <div><a href="HYPERGRAPH.html">Hypergraphs</a></div> +<div><a href="USERS_GUIDE_OPT.html">MondriaanOpt</a></div> <div><a href="#prof">Profiling</a></div> <div><a href="#dev">Developers</a></div> <div><a href="#moar">More...</a></div> @@ -70,9 +71,8 @@ Go inside the directory <tt>Mondriaan4</tt> and type <li><tt>% make</tt></li> </ul> <p> -This will compile the Mondriaan library, tools included with -the Mondriaan library, and all 102 unit tests of the library -with the default options as given in <tt>mondriaan.mk</tt>. +This will compile the Mondriaan library, the <a href="USERS_GUIDE_OPT.html">MondriaanOpt</a> library and +tools included with the Mondriaan library. After compilation the include files are located in <tt>Mondriaan4/src/include</tt>, the compiled library in <tt>Mondriaan4/src/lib</tt>, @@ -790,14 +790,14 @@ Chapter 12 of Combinatorial Scientific Computing, Chapman and Hall/CRC, pp. 321- <hr> <p> -Last updated: September 27, 2016.<br><br> +Last updated: October 27, 2016.<br><br> June 9, 2009 by Rob Bisseling,<br> December 2, 2010 by Bas Fagginger Auer,<br> December 10, 2010 by A. N. Yzelman,<br> March 27, 2012 by Bas Fagginger Auer,<br> April 18, 2013 by Daniël M. Pelt,<br> August 29, 2013 by Rob Bisseling and Bas Fagginger Auer,<br> -September 27, 2016 by Marco van Oort.<br><br> +October 27, 2016 by Marco van Oort.<br><br> To <a href="http://www.staff.science.uu.nl/~bisse101/Mondriaan"> the Mondriaan package home page</a>.</p> diff --git a/docs/USERS_GUIDE_OPT.html b/docs/USERS_GUIDE_OPT.html index 10243d53d8a660a931857d104dcc7fdd14d7d4aa..e6a6705ba2451f99017f56a5c674ff7aa2f7d4eb 100644 --- a/docs/USERS_GUIDE_OPT.html +++ b/docs/USERS_GUIDE_OPT.html @@ -14,6 +14,7 @@ <h2>User's guide MondriaanOpt</h2> <div id="top"> +<div><a href="USERS_GUIDE.html">« Mondriaan</a></div> <div><a href="#inst">Installing</a></div> <div><a href="#outp">Output</a></div> <div><a href="#opts">Options</a></div> @@ -30,30 +31,44 @@ This offline version is bundled with the software for your convenience. </p> <hr> +<p> +Whereas Mondriaan uses heuristics to obtain good partitionings for sparse matrix-vector multiplication for any number of processors, +MondriaanOpt will calculate an actual optimal solution for this partitioning problem with 2 processors. More precisely, it will +calculate a partitioning with minimum volume among all solutions that obey the imbalance constraint. +</p> + +<p> +A database with already solved problems with use of MondriaanOpt can be found <a href="http://www.staff.science.uu.nl/~bisse101/Mondriaan/Opt/">online</a>. +</p> + <h3><a name="inst">How to install MondriaanOpt</a></h3> <p> MondriaanOpt comes packaged with the Mondriaan software. Refer to <a href="./USERS_GUIDE.html">this page</a> for instructions on using Mondriaan. MondriaanOpt is automatically compiled when you compile Mondriaan. The executable is then available at <tt>tools/MondriaanOpt</tt>. </p> + +<h3><a name="run">How to run MondriaanOpt</a></h3> <p> -Whereas Mondriaan uses heuristics to obtain good partitionings for sparse matrix-vector multiplication for any number of processors, -MondriaanOpt will calculate an actual optimal solution for this partitioning problem with 2 processors. More precisely, it will -calculate a partitioning with minimum volume among all solutions that obey the imbalance constraint. +The MondriaanOpt program has the following interface: +<ul><li><tt>% ./tools/MondriaanOpt matrix [P [eps]] [options]</tt></li></ul> +One, two or three parameters may be passed, after which further options may be given. +Either [eps], -e or -k must be passed, and it is advised to pass -v (see <a href="#opts">options</a>). </p> -<h3><a name="run">How to run MondriaanOpt</a></h3> <p> -Go inside the directory <tt>Mondriaan4</tt> and type +Some equivalent examples are: </p> <ul> -<li><tt>% cd tools</tt></li> -<li><tt>% ./MondriaanOpt -m ../tests/arc130.mtx -e 0.03 -v 20</tt></li> + <li><tt>% ./tools/MondriaanOpt tests/arc130.mtx 2 0.03 -v 17</tt></li> + <li><tt>% ./tools/MondriaanOpt tests/arc130.mtx -e 0.03 -v 17</tt></li> + <li><tt>% ./tools/MondriaanOpt tests/arc130.mtx -k 660 -v 17</tt></li> </ul> + <p> -if you want to partition the <tt>arc130.mtx</tt> matrix (Matrix Market file format) +The above examples partition the <tt>arc130.mtx</tt> matrix (Matrix Market file format) for 2 processors with at most 3% load imbalance, knowing that solutions must exist with -volume at most 20. The matrix should be the full relative path; <em>in the above example +volume at most 17. The matrix should be the full relative path; <em>in the above example output is saved in the Mondriaan tests folder</em> (<tt>../tests/</tt>). </p> @@ -89,6 +104,7 @@ containing a visualisation of the partitioning. <p><i> Here, the free nonzeros of a partitioning are distributed among the two processors in such a way that load imbalance is kept at a minimum. +Note that whenever we write <tt>P</tt> for the number of processors below, it implicitly equals 2. </i></p> <h4>Distributed matrix (<tt>-P2</tt>)</h4> <p> The <tt>MondriaanOpt</tt> program @@ -134,51 +150,81 @@ and you may not need it. containing a visualisation of the partitioning. </p> +<h4><u>Output to <tt>stdout</tt>/<tt>stderr</tt></u></h4> +<p> +In a succesful run, at the end of execution general statistics are written to <tt>stdout</tt>. +Also, during such a run, every <tt>2^23 = 8388608</tt> iterations the current depth in the tree is written to <tt>stderr</tt>, in the format <tt>`current depth`/`maximum depth`</tt>. +Last but not least, every time a new solution is found which improves on the previous solution regarding total volume, a message is written to <tt>stderr</tt> reporting the newly found volume and load distribution in the format <tt>`load P0`, `load P1`, `load Free`</tt>. +</p> <h3><a name="opts">Program options</a></h3> <p> -The MondriaanOpt options can be passed in the command line. -An overview of the options is given below. +The MondriaanOpt program has the following interface: +<ul><li><tt>% ./tools/MondriaanOpt matrix [P [eps]] [options]</tt></li></ul> +One, two or three parameters may be passed, after which further options may be given. +An overview of the available parameters and options is given below. </p> +<h4>Parameters</h4> <table> <thead> <tr> - <th>Option</th> - <th>Value</th> + <th>Parameter</th> <th>Description</th> </tr> </thead> <tbody> <tr> - <td>-m</td> <td>Matrix file</td> <td><i>Required.</i> The input matrix file in Matrix Market (.mtx) format</td> </tr> + <tr> + <td>Number of processors</td> + <td>Present for consistency with other Mondriaan* commands. This parameter, if given, must be equal to 2.</td> + </tr> + <tr> + <td>Load imbalance</td> + <td>The maximum allowed load imbalance</td> + </tr> + </tbody> +</table> + +<h4>Options</h4> +<p> +Apart from the matrix, at least one of [eps], -e or -k must be given, defining the maximum allowed load imbalance. +</p> +<table> + <thead> + <tr> + <th>Option</th> + <th>Value</th> + <th>Description</th> + </tr> + </thead> + <tbody> <tr> <td>-v</td> <td>Volume</td> - <td><i>Required.</i> The starting upper bound volume</td> + <td> + <i>Recommended.</i> The starting upper bound volume. + This defaults to <tt>m+n</tt>, with <tt>m</tt> and <tt>n</tt> denoting the dimensions of the matrix to be partitioned. + While this is a valid upper bound, you may wish to pass a tighter upper bound to reduce computing time. + </td> </tr> <tr> <td>-e</td> <td>Load imbalance</td> - <td><i>Required if -k is not passed.</i> The allowed load imbalance</td> + <td>The maximum allowed load imbalance</td> </tr> <tr> <td>-k</td> <td>Number of nonzeros</td> - <td><i>Required if -e is not passed.</i> The maximum allowed number of nonzeros per part</td> + <td>The maximum allowed number of nonzeros per part</td> </tr> <tr> <td>-t</td> <td>Seconds</td> <td>Max running time in seconds</td> </tr> - <tr> - <td>-r</td> - <td>Dumpfile</td> - <td>Resume with given dumpfile</td> - </tr> <tr> <td>-h</td> <td><i>None</i></td> @@ -211,8 +257,8 @@ Daniel M. Pelt and Rob H. Bisseling, <i>Journal of Parallel and Distributed Comp <hr> <p> -Last updated: October 3, 2016.<br><br> -October 3, 2016 by Marco van Oort.<br><br> +Last updated: October 27, 2016.<br><br> +October 27, 2016 by Marco van Oort.<br><br> To <a href="http://www.staff.science.uu.nl/~bisse101/Mondriaan"> the Mondriaan package home page</a>.</p> diff --git a/src/MondriaanOpt/MondriaanOpt.c b/src/MondriaanOpt/MondriaanOpt.c index a3fde9e33486cecfce16b6961582914be3b0a5b7..a86fb5e093cadf7c978ebeda8464c358b4e8c2af 100644 --- a/src/MondriaanOpt/MondriaanOpt.c +++ b/src/MondriaanOpt/MondriaanOpt.c @@ -39,16 +39,19 @@ int main(int argc,char **argv){ /* Output time used */ printf("Time taken: %lf s\n",opt.time); - - /* Output final volume upper bound to stdout */ - printf("%d\n",sol.maxvol); if(sol.maxvol < opt.maxvol) { + /* A solution has been found */ + /* Output final volume upper bound to stdout */ + printf("Final volume: %d\n",sol.maxvol); + /* Convert to other file formats */ printConverted(&opt); } else { - printf("No solution with a volume lower than %d exists!\n", opt.maxvol); + /* No solution found. */ + /* Subtract 1 from maxvol, as maxvol contains 'the volume we want to improve', while we want to print 'the upper bound'. */ + printf("No solution with a volume at most %d exists!\n", opt.maxvol-1); } exit (EXIT_SUCCESS); diff --git a/src/MondriaanOpt/errors.c b/src/MondriaanOpt/errors.c index 93d2ff4b6b8b48f7b221c4d91dfbbf42b623e10f..a6f9575c9a432278558f1a6529dd151c80c02d80 100644 --- a/src/MondriaanOpt/errors.c +++ b/src/MondriaanOpt/errors.c @@ -7,28 +7,45 @@ void exitwitherror(unsigned int err){ if(err==0){ /* Options error, output program usage */ fprintf(stderr,"MondriaanOpt - written by Daan Pelt and Rob Bisseling (2015)\n"); - fprintf(stderr,"\nInvalid options are given...\nUsage:\n\n"); - fprintf(stderr," ./program -m \"matrix file\" -e \"load imbalance\" -v \"volume\"\n"); - fprintf(stderr," or \n"); - fprintf(stderr," ./program -m \"matrix file\" -k \"number of nonzeros\" -v \"volume\"\n\n"); + fprintf(stderr,"\nInvalid options are given...\nUsage:\n"); + fprintf(stderr," ./tools/MondriaanOpt matrix [P [eps]] [options]\n\n"); + + fprintf(stderr,"Either [eps], -e or -k must be passed, and it is advised to pass -v.\n"); fprintf(stderr,"Use -h option for more help\n"); fprintf(stderr,"\n"); exit(EXIT_SUCCESS); }else if(err==1){ /* Help asked */ fprintf(stderr,"MondriaanOpt - written by Daan Pelt and Rob Bisseling (2015)\n"); - printf("\nProgram to find optimal matrix bipartitioning.\n\nRequired options:\n"); - printf(" -m \"matrix file\" : the input matrix file in Matrix Market (.mtx) format\n"); + printf("\nProgram to find optimal matrix bipartitioning.\n\nUsage:\n"); + printf(" ./tools/MondriaanOpt matrix [P [eps]] [options]\n\n"); + + printf("One, two or three parameters may be passed, after which further options may be given.\n"); + printf("Either [eps], -e or -k must be passed, and it is advised to pass -v (see below).\n\n"); + + printf("Parameters:\n"); + printf(" matrix : the input matrix file in Matrix Market (.mtx) format (may not start with a dash (-))\n"); + printf(" P : the number of processors. This must equal 2; this option is present for consistency with the other Mondriaan* commands\n"); + printf(" eps : the maximum allowed load imbalance\n\n"); + + printf("Further options:\n"); printf(" -v \"volume\" : the starting upper bound volume\n"); - printf("\nAlso, it is required to pass either of the following:\n"); - printf(" -e \"load imbalance\" : the allowed load imbalance\n"); + printf(" -e \"load imbalance\" : the maximum allowed load imbalance\n"); printf(" -k \"number of nonzeros\" : the maximum allowed number of nonzeros per part\n"); - printf("\nFurther options:\n"); printf(" -t \"seconds\" : max running time in seconds\n"); - printf(" -r \"dumpfile\" : resume with given dumpfile\n"); printf(" -h : show this help\n"); - printf(" -svg : Write visualisations of the partitioning to .svg files\n"); + printf(" -svg : Write visualisations of the partitioning to .svg files\n\n"); + + printf("Apart from the matrix, at least one of [eps], -e or -k must be given, defining the maximum allowed load imbalance.\n"); + printf("The default value for the initial upper bound on the communication volume is m+n (m and n being the dimensions of the matrix),\n"); + printf("but it is strongly recommended to pass a better upper bound (-v) if available, to reduce computing time.\n\n"); + + printf("Equivalent examples:\n"); + printf(" ./tools/MondriaanOpt tests/arc130.mtx 2 0.03 -v 17\n"); + printf(" ./tools/MondriaanOpt tests/arc130.mtx -e 0.03 -v 17\n"); + printf(" ./tools/MondriaanOpt tests/arc130.mtx -k 660 -v 17\n"); printf("\n"); + exit(EXIT_SUCCESS); }else if(err==2){ /* Not enough memory */ diff --git a/src/MondriaanOpt/options.c b/src/MondriaanOpt/options.c index 8962eb2f42ec1052a1f325a1f3e4d4d75dcfeb2a..960f3ed1857d9d67bfc66816935c5b8cb7f1bf46 100644 --- a/src/MondriaanOpt/options.c +++ b/src/MondriaanOpt/options.c @@ -28,16 +28,32 @@ char readoptions(struct options *o, int c, char **v){ o->maxruntime=0.; o->nbranches=0; /* number of branches traversed */ o->SVG=SVGNo; + o->maxvol = -1; + + while(i<c && v[i][0] != '-') { + if(i == 1) { + /* Read matrix filename */ + sprintf(o->fn,"%s",v[i]); + req[0]=TRUE; + } + if(i == 2) { + if(strcmp(v[i], "2") != 0) { + exitwitherror(0); + } + } + if(i == 3) { + o->eps = atof(v[i]); + o->epsset = TRUE; + req[1]=TRUE; + } + + i++; + } + /* Read while there are options left */ while(i<c){ - if(strcmp(v[i],"-m")==0){ - /* Matrix file */ - if(i==c-1) exitwitherror(0); - sprintf(o->fn,"%s",v[i+1]); - req[0]=TRUE; - i++; - }else if(strcmp(v[i],"-t")==0){ + if(strcmp(v[i],"-t")==0){ /* Max running time in seconds */ if(i==c-1) exitwitherror(0); o->maxruntime = atof(v[i+1]); @@ -59,8 +75,8 @@ char readoptions(struct options *o, int c, char **v){ }else if(strcmp(v[i],"-v")==0){ /* Starting upper bound on volume, e.g. MIN(m,n)+1 for an m by n matrix */ if(i==c-1) exitwitherror(0); - o->maxvol = atoi(v[i+1]); - req[2]=TRUE; + /* We add +1, to change from 'upper bound' to 'the value we want to improve upon' */ + o->maxvol = atoi(v[i+1])+1; i++; }else if(strcmp(v[i],"-h")==0){ /* Get help */ diff --git a/src/MondriaanOpt/options.h b/src/MondriaanOpt/options.h index df5b47364cf7a4f742c29fa54de60830b96624d1..b310874b1a362888446d5954b89fd0f4ed588c2b 100644 --- a/src/MondriaanOpt/options.h +++ b/src/MondriaanOpt/options.h @@ -5,7 +5,7 @@ #include <sys/time.h> #define MAXFNSIZE 64 -#define CUR_REQ_OPTIONS 3 +#define CUR_REQ_OPTIONS 2 #define TRUE 1 #define FALSE 0 diff --git a/src/MondriaanOpt/solution.c b/src/MondriaanOpt/solution.c index a41a85df0706bd5e84448fda57749af302621a7f..664750b29863b6bf36456aafe164f41d480e289f 100644 --- a/src/MondriaanOpt/solution.c +++ b/src/MondriaanOpt/solution.c @@ -65,10 +65,14 @@ void initsolution(const struct mat *a, struct solution *s, struct options *o){ s->max1 = o->k; /* Set volume upper bound */ + if(o->maxvol == -1) { + o->maxvol = a->m + a->n; + fprintf(stderr, "Warning: With the default upper bound on the communication volume, m+n, the program may take long to complete. Consider passing a better upper bound with the -v option.\n"); + } s->maxvol = o->maxvol; /* Set matrix name */ - s->matname = basename(o->fn); + s->matname = o->fn; /* basename(o->fn) */ /* Set start time of solution process */ time(&(s->starttime)); diff --git a/tools/MatlabMondriaanOpt.c b/tools/MatlabMondriaanOpt.c index 7a5ba6bb14de9bc2996581807cf115760c8894c4..4e572f7a77f16339a82fb2fc92dc0fe14559284a 100644 --- a/tools/MatlabMondriaanOpt.c +++ b/tools/MatlabMondriaanOpt.c @@ -89,7 +89,7 @@ int DoMondriaanOpt(struct sparsematrix *A, struct solution *sol, struct mat *a, sprintf(Options.fn, "MatlabMex.mtx"); Options.eps = Imbalance; Options.epsset = TRUE; - Options.maxvol = Volume; + Options.maxvol = Volume+1; /* We add +1, to change from 'upper bound' to 'the volume we want to improve upon' */ /* Initialise solution */ initsolution(a,sol,&Options); diff --git a/tools/mondriaanOpt.m b/tools/mondriaanOpt.m index c29b738c66791233eaee42db3a98dc1f3a7e583a..2a6160ed0a2410e6b8272998c60cccd5f5c5b587 100644 --- a/tools/mondriaanOpt.m +++ b/tools/mondriaanOpt.m @@ -43,6 +43,10 @@ function [I, s] = mondriaanOpt(A, Imbalance, Volume) comVol = MatlabMondriaanOpt(A, Imbalance, Volume); elapsedTime = toc; + if(comVol > Volume) + throw(MException('mondriaanOpt:NoSol', ['No solution with a volume at most ' num2str(Volume) ' exists!'])); + end + % Read computed partitioning from disk I = mmread('MatlabMex.mtx-I2f');