001/*
002 * $Id: RunMPIGB.java 5797 2018-03-26 09:48:51Z kredel $
003 */
004
005package edu.jas.application;
006
007
008import java.io.BufferedReader;
009import java.io.FileInputStream;
010import java.io.FileNotFoundException;
011import java.io.IOException;
012import java.io.InputStreamReader;
013import java.io.Reader;
014import java.io.StringReader;
015import java.nio.charset.Charset;
016import java.util.Arrays;
017import java.util.List;
018
019import mpi.MPIException;
020
021import org.apache.log4j.BasicConfigurator;
022
023import edu.jas.gb.GroebnerBaseAbstract;
024import edu.jas.gb.GroebnerBaseDistributedEC;
025import edu.jas.gb.GroebnerBaseDistributedHybridEC;
026import edu.jas.gb.GroebnerBaseDistributedHybridMPI;
027import edu.jas.gb.GroebnerBaseDistributedMPI;
028import edu.jas.gb.GroebnerBaseParallel;
029import edu.jas.gb.GroebnerBaseSeq;
030import edu.jas.gb.OrderedSyzPairlist;
031import edu.jas.gb.ReductionPar;
032import edu.jas.gb.ReductionSeq;
033import edu.jas.gbufd.GBFactory;
034import edu.jas.kern.ComputerThreads;
035import edu.jas.kern.MPIEngine;
036import edu.jas.poly.GenPolynomialRing;
037import edu.jas.poly.GenPolynomialTokenizer;
038import edu.jas.poly.PolynomialList;
039import edu.jas.util.CatReader;
040import edu.jas.util.ExecutableServer;
041
042
043/**
044 * Simple setup to run a GB example in MPI environment. <br>
045 * Usage: RunGB [seq(+)|par(+)|dist(1)(+)|disthyb|cli] &lt;file&gt;
046 * #procs/#threadsPerNode [machinefile]
047 * @author Heinz Kredel
048 */
049
050public class RunMPIGB {
051
052
053    /**
054     * Check result GB if it is a GB.
055     */
056    static boolean doCheck = false;
057
058
059    /**
060     * Enable logging.
061     */
062    static boolean doLog = true;
063
064
065    /**
066     * main method to be called from commandline <br>
067     * Usage: RunMPIGB [seq|par(+)|dist(+)|disthyb|cli] &lt;file&gt;
068     * #procs/#threadsPerNode [machinefile]
069     */
070    @SuppressWarnings("unchecked")
071    public static void main(String[] args) throws IOException, MPIException {
072
073        MPIEngine.setCommandLine(args); //args = MPI.Init(args);
074
075        String[] allkinds = new String[] { "seq", "seq+", 
076                                           "par", "par+", 
077                                           "dist", "dist+", 
078                                           "disthyb", "disthyb+", 
079                                           "distmpi", "distmpi+", 
080                                           "disthybmpi", "disthybmpi+", 
081                                           "cli" };
082
083        String usage = "Usage: RunGB [ "
084                        + RunGB.join(allkinds, " | ") 
085                        + "[port] ] " 
086                        + "<file> " 
087                        + "#procs/#threadsPerNode " 
088                        + "[machinefile] " 
089                        + "[check] [nolog]";
090
091        if (args.length < 1) {
092            System.out.println("args: " + Arrays.toString(args));
093            System.out.println(usage);
094            return;
095        }
096
097        boolean plusextra = false;
098        String kind = args[0];
099        boolean sup = false;
100        int k = -1;
101        for (int i = 0; i < args.length; i++) {
102            int j = RunGB.indexOf(allkinds, args[i]);
103            if (j < 0) {
104                continue;
105            }
106            sup = true;
107            k = i;
108            kind = args[k];
109            break;
110        }
111        if (!sup) {
112            System.out.println("args(sup): " + Arrays.toString(args));
113            System.out.println(usage);
114            return;
115        }
116        if (kind.indexOf("+") >= 0) {
117            plusextra = true;
118        }
119        System.out.println("kind: " + kind + ", k = " + k);
120
121        final int GB_SERVER_PORT = 7114;
122        int port = GB_SERVER_PORT;
123
124        if (kind.equals("cli")) {
125            if (args.length - k >= 2) {
126                try {
127                    port = Integer.parseInt(args[k + 1]);
128                } catch (NumberFormatException e) {
129                    e.printStackTrace();
130                    System.out.println("args(port): " + Arrays.toString(args));
131                    System.out.println(usage);
132                    return;
133                }
134            }
135            RunGB.runClient(port);
136            return;
137        }
138
139        String filename = null;
140        if (!kind.equals("cli")) {
141            if (args.length - k < 2) {
142                System.out.println("args(file): " + Arrays.toString(args));
143                System.out.println(usage);
144                return;
145            }
146            filename = args[k + 1];
147        }
148
149        int j = RunGB.indexOf(args, "check");
150        if (j >= 0) {
151            doCheck = true;
152            RunGB.doCheck = true;
153        }
154        j = RunGB.indexOf(args, "nolog");
155        if (j >= 0) {
156            doLog = false;
157        }
158
159        int threads = 0;
160        int threadsPerNode = 1;
161        if (kind.startsWith("par") || kind.startsWith("dist")) {
162            if (args.length - k < 3) {
163                System.out.println("args(par|dist): " + Arrays.toString(args));
164                System.out.println(usage);
165                return;
166            }
167            String tup = args[k + 2];
168            String t = tup;
169            int i = tup.indexOf("/");
170            if (i >= 0) {
171                t = tup.substring(0, i).trim();
172                tup = tup.substring(i + 1).trim();
173                try {
174                    threadsPerNode = Integer.parseInt(tup);
175                } catch (NumberFormatException e) {
176                    e.printStackTrace();
177                    System.out.println("args(threadsPerNode): " + Arrays.toString(args));
178                    System.out.println(usage);
179                    return;
180                }
181            }
182            try {
183                threads = Integer.parseInt(t);
184            } catch (NumberFormatException e) {
185                e.printStackTrace();
186                System.out.println("args(threads): " + Arrays.toString(args));
187                System.out.println(usage);
188                return;
189            }
190        }
191
192        String mfile = null;
193        if (kind.startsWith("dist")) {
194            if (args.length - k >= 4) {
195                mfile = args[k + 3];
196            } else {
197                mfile = "machines";
198            }
199        }
200
201        Reader problem = RunGB.getReader(filename);
202        if (problem == null) {
203            System.out.println("args(file): " + filename);
204            System.out.println("args(file): examples.jar(" + filename + ")");
205            System.out.println("args(file): " + Arrays.toString(args));
206            System.out.println(usage);
207            return;
208        }
209        RingFactoryTokenizer rftok = new RingFactoryTokenizer(problem);
210        GenPolynomialRing pfac = null;
211        try {
212            pfac = rftok.nextPolynomialRing();
213            rftok = null;
214        } catch (IOException e) {
215            e.printStackTrace();
216            return;
217        }
218        Reader polyreader = new CatReader(new StringReader("("), problem); // ( has gone
219        //Reader polyreader = problem;
220        GenPolynomialTokenizer tok = new GenPolynomialTokenizer(pfac, polyreader);
221        PolynomialList S = null;
222        try {
223            S = new PolynomialList(pfac, tok.nextPolynomialList());
224        } catch (IOException e) {
225            e.printStackTrace();
226            return;
227        }
228        System.out.println("S =\n" + S);
229
230        if (doLog) {
231            BasicConfigurator.configure();
232        }
233
234        if (kind.startsWith("seq")) {
235            RunGB.runSequential(S, plusextra);
236        } else if (kind.startsWith("par")) {
237            RunGB.runParallel(S, threads, plusextra);
238        } else if (kind.startsWith("distmpi")) {
239            runMpi(S, threads, mfile, port, plusextra);
240        } else if (kind.startsWith("disthybmpi")) {
241            runHybridMpi(S, threads, threadsPerNode, mfile, port, plusextra);
242        } else if (kind.startsWith("disthyb")) {
243            RunGB.runMasterHyb(S, threads, threadsPerNode, mfile, port, plusextra);
244        } else if (kind.startsWith("dist")) {
245            RunGB.runMaster(S, threads, mfile, port, plusextra);
246        }
247        ComputerThreads.terminate();
248        //System.exit(0);
249    }
250
251
252    @SuppressWarnings("unchecked")
253    static void runMpi(PolynomialList S, int threads, String mfile, int port, boolean plusextra)
254                    throws IOException, MPIException {
255        List L = S.list;
256        List G = null;
257        long t, t1;
258
259        t = System.currentTimeMillis();
260        System.out.println("\nGroebner base distributed MPI (" + threads + ", " + mfile + ", " + port
261                        + ") ...");
262        GroebnerBaseDistributedMPI gbd = null;
263        GroebnerBaseDistributedMPI gbds = null;
264        if (plusextra) {
265            gbds = new GroebnerBaseDistributedMPI(threads, new OrderedSyzPairlist());
266        } else {
267            gbd = new GroebnerBaseDistributedMPI(threads);
268        }
269        t1 = System.currentTimeMillis();
270        if (plusextra) {
271            G = gbds.GB(L);
272        } else {
273            G = gbd.GB(L);
274        }
275        t1 = System.currentTimeMillis() - t1;
276        if (plusextra) {
277            gbds.terminate();
278        } else {
279            gbd.terminate();
280        }
281        MPIEngine.terminate();
282        if (G == null) {
283            return; // mpi.rank != 0
284        }
285        S = new PolynomialList(S.ring, G);
286        System.out.println("G =\n" + S);
287        System.out.println("G.size() = " + G.size());
288        t = System.currentTimeMillis() - t;
289        if (plusextra) {
290            System.out.print("m+ ");
291        } else {
292            System.out.print("m ");
293        }
294        System.out.println("= " + threads + ", time = " + t1 + " milliseconds, " + (t - t1) + " start-up "
295                        + ", total = " + t);
296        RunGB.checkGB(S);
297        System.out.println("");
298    }
299
300
301    @SuppressWarnings("unchecked")
302    static void runHybridMpi(PolynomialList S, int threads, int threadsPerNode, String mfile, int port,
303                             boolean plusextra) throws IOException, MPIException {
304        List L = S.list;
305        List G = null;
306        long t, t1;
307
308        t = System.currentTimeMillis();
309        System.out.println("\nGroebner base distributed hybrid MPI (" + threads + "/" + threadsPerNode + ", "
310                        + mfile + ", " + port + ") ...");
311        GroebnerBaseDistributedHybridMPI gbd = null;
312        GroebnerBaseDistributedHybridMPI gbds = null;
313        if (plusextra) {
314            gbds = new GroebnerBaseDistributedHybridMPI(threads, threadsPerNode, new OrderedSyzPairlist());
315        } else {
316            gbd = new GroebnerBaseDistributedHybridMPI(threads, threadsPerNode);
317        }
318        t1 = System.currentTimeMillis();
319        if (plusextra) {
320            G = gbds.GB(L);
321        } else {
322            G = gbd.GB(L);
323        }
324        t1 = System.currentTimeMillis() - t1;
325        if (plusextra) {
326            gbds.terminate();
327        } else {
328            gbd.terminate();
329        }
330        MPIEngine.terminate();
331        if (G == null) {
332            return; // mpi.rank != 0
333        }
334        S = new PolynomialList(S.ring, G);
335        System.out.println("G =\n" + S);
336        System.out.println("G.size() = " + G.size());
337        t = System.currentTimeMillis() - t;
338        if (plusextra) {
339            System.out.print("m+ ");
340        } else {
341            System.out.print("m ");
342        }
343        System.out.println("= " + threads + ", ppn = " + threadsPerNode + ", time = " + t1
344                        + " milliseconds, " + (t - t1) + " start-up " + ", total = " + t);
345        RunGB.checkGB(S);
346        System.out.println("");
347    }
348
349}