001/*
002 * $Id: RunGB.java 5313 2015-10-26 22:46:38Z 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;
018import java.util.jar.JarEntry;
019import java.util.jar.JarFile;
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.GroebnerBaseParallel;
027import edu.jas.gb.GroebnerBaseSeq;
028import edu.jas.gb.OrderedSyzPairlist;
029import edu.jas.gb.ReductionPar;
030import edu.jas.gb.ReductionSeq;
031import edu.jas.gbufd.GBFactory;
032import edu.jas.gbufd.GroebnerBasePseudoParallel;
033import edu.jas.kern.ComputerThreads;
034import edu.jas.poly.GenPolynomialRing;
035import edu.jas.poly.GenPolynomialTokenizer;
036import edu.jas.poly.PolynomialList;
037import edu.jas.util.CatReader;
038import edu.jas.util.ExecutableServer;
039
040
041/**
042 * Simple setup to run a GB example. <br />
043 * Usage: RunGB [seq(+)|par(+)|dist(+)|disthyb|cli] &lt;file&gt;
044 * #procs/#threadsPerNode [machinefile]
045 * @author Heinz Kredel
046 */
047public class RunGB {
048
049
050    /**
051     * Check result GB if it is a GB.
052     */
053    static boolean doCheck = false;
054
055
056    /**
057     * Enable logging.
058     */
059    static boolean doLog = true;
060
061
062    /**
063     * main method to be called from commandline <br />
064     * Usage: RunGB [seq|par(+)|dist(+)|disthyb(+)|cli] &lt;file&gt;
065     * #procs/#threadsPerNode [machinefile] &lt;check&gt; &lt;log&gt;
066     */
067    @SuppressWarnings("unchecked")
068    public static void main(String[] args) {
069
070        String[] allkinds = new String[] { "seq", "seq+", "par", "par+", "dist", "dist+", "disthyb",
071                "disthyb+", "cli" }; // must be last
072
073        String usage = "Usage: RunGB [ " + join(allkinds, " | ") + "[port] ] " + "<file> "
074                        + "#procs/#threadsPerNode " + "[machinefile] " + "[check] [nolog]";
075
076        if (args.length < 1) {
077            System.out.println("args: " + Arrays.toString(args));
078            System.out.println(usage);
079            return;
080        }
081
082        boolean plusextra = false;
083        String kind = args[0];
084        boolean sup = false;
085        int k = -1;
086        for (int i = 0; i < args.length; i++) {
087            int j = indexOf(allkinds, args[i]);
088            if (j < 0) {
089                continue;
090            }
091            sup = true;
092            k = i;
093            kind = args[k];
094            break;
095        }
096        if (!sup) {
097            System.out.println("args(sup): " + Arrays.toString(args));
098            System.out.println(usage);
099            return;
100        }
101        if (kind.indexOf("+") >= 0) {
102            plusextra = true;
103        }
104        System.out.println("kind: " + kind + ", k = " + k);
105
106        final int GB_SERVER_PORT = 7114;
107        int port = GB_SERVER_PORT;
108
109        if (kind.equals("cli")) {
110            if (args.length - k >= 2) {
111                try {
112                    port = Integer.parseInt(args[k + 1]);
113                } catch (NumberFormatException e) {
114                    e.printStackTrace();
115                    System.out.println("args(port): " + Arrays.toString(args));
116                    System.out.println(usage);
117                    return;
118                }
119            }
120            runClient(port);
121            return;
122        }
123
124        String filename = null;
125        if (!kind.equals("cli")) {
126            if (args.length - k < 2) {
127                System.out.println("args(file): " + Arrays.toString(args));
128                System.out.println(usage);
129                return;
130            }
131            filename = args[k + 1];
132        }
133
134        int j = indexOf(args, "check");
135        if (j >= 0) {
136            doCheck = true;
137        }
138        j = indexOf(args, "nolog");
139        if (j >= 0) {
140            doLog = false;
141        }
142
143        int threads = 0;
144        int threadsPerNode = 1;
145        if (kind.startsWith("par") || kind.startsWith("dist")) {
146            if (args.length - k < 3) {
147                System.out.println("args(par|dist): " + Arrays.toString(args));
148                System.out.println(usage);
149                return;
150            }
151            String tup = args[k + 2];
152            String t = tup;
153            int i = tup.indexOf("/");
154            if (i >= 0) {
155                t = tup.substring(0, i).trim();
156                tup = tup.substring(i + 1).trim();
157                try {
158                    threadsPerNode = Integer.parseInt(tup);
159                } catch (NumberFormatException e) {
160                    e.printStackTrace();
161                    System.out.println("args(threadsPerNode): " + Arrays.toString(args));
162                    System.out.println(usage);
163                    return;
164                }
165            }
166            try {
167                threads = Integer.parseInt(t);
168            } catch (NumberFormatException e) {
169                e.printStackTrace();
170                System.out.println("args(threads): " + Arrays.toString(args));
171                System.out.println(usage);
172                return;
173            }
174        }
175
176        String mfile = null;
177        if (kind.startsWith("dist")) {
178            if (args.length - k >= 4) {
179                mfile = args[k + 3];
180            } else {
181                mfile = "machines";
182            }
183        }
184
185        Reader problem = getReader(filename);
186        if (problem == null) {
187            System.out.println("args(file): " + filename);
188            System.out.println("args(file): examples.jar(" + filename + ")");
189            System.out.println("args(file): " + Arrays.toString(args));
190            System.out.println(usage);
191            return;
192        }
193        RingFactoryTokenizer rftok = new RingFactoryTokenizer(problem);
194        GenPolynomialRing pfac = null;
195        try {
196            pfac = rftok.nextPolynomialRing();
197            rftok = null;
198        } catch (IOException e) {
199            e.printStackTrace();
200            return;
201        }
202        Reader polyreader = new CatReader(new StringReader("("), problem); // ( has gone
203        //Reader polyreader = problem; 
204        GenPolynomialTokenizer tok = new GenPolynomialTokenizer(pfac, polyreader);
205        PolynomialList S = null;
206        try {
207            S = new PolynomialList(pfac, tok.nextPolynomialList());
208        } catch (IOException e) {
209            e.printStackTrace();
210            return;
211        }
212        System.out.println("input S =\n" + S);
213
214        if (doLog) {
215            BasicConfigurator.configure();
216        }
217
218        if (kind.startsWith("seq")) {
219            runSequential(S, plusextra);
220        } else if (kind.startsWith("par")) {
221            runParallel(S, threads, plusextra);
222        } else if (kind.startsWith("disthyb")) {
223            runMasterHyb(S, threads, threadsPerNode, mfile, port, plusextra);
224        } else if (kind.startsWith("dist")) {
225            runMaster(S, threads, mfile, port, plusextra);
226        }
227        ComputerThreads.terminate();
228        //System.exit(0);
229    }
230
231
232    @SuppressWarnings("unchecked")
233    static void runMaster(PolynomialList S, int threads, String mfile, int port, boolean plusextra) {
234        List L = S.list;
235        List G = null;
236        long t, t1;
237        GroebnerBaseDistributedEC gbd = null;
238        GroebnerBaseDistributedEC gbds = null;
239
240        System.out.println("\nGroebner base distributed (" + threads + ", " + mfile + ", " + port + ") ...");
241        t = System.currentTimeMillis();
242        if (plusextra) {
243            //gbds = new GroebnerBaseDistributedEC(threads,mfile, port);
244            gbds = new GroebnerBaseDistributedEC(mfile, threads, new OrderedSyzPairlist(), port);
245        } else {
246            gbd = new GroebnerBaseDistributedEC(mfile, threads, port);
247        }
248        t1 = System.currentTimeMillis();
249        if (plusextra) {
250            G = gbds.GB(L);
251        } else {
252            G = gbd.GB(L);
253        }
254        t1 = System.currentTimeMillis() - t1;
255        if (plusextra) {
256            gbds.terminate(); //false);
257        } else {
258            gbd.terminate(); //false);
259        }
260        S = new PolynomialList(S.ring, G);
261        System.out.println("G =\n" + S);
262        System.out.println("G.size() = " + G.size());
263        t = System.currentTimeMillis() - t;
264        if (plusextra) {
265            System.out.print("d+ ");
266        } else {
267            System.out.print("d ");
268        }
269        System.out.println("= " + threads + ", time = " + t1 + " milliseconds, " + (t - t1) + " start-up "
270                        + ", total = " + t);
271        checkGB(S);
272        System.out.println("");
273    }
274
275
276    @SuppressWarnings("unchecked")
277    static void runMasterHyb(PolynomialList S, int threads, int threadsPerNode, String mfile, int port,
278                    boolean plusextra) {
279        List L = S.list;
280        List G = null;
281        long t, t1;
282        GroebnerBaseDistributedHybridEC gbd = null;
283        GroebnerBaseDistributedHybridEC gbds = null;
284
285        System.out.println("\nGroebner base distributed hybrid (" + threads + "/" + threadsPerNode + ", "
286                        + mfile + ", " + port + ") ...");
287        t = System.currentTimeMillis();
288        if (plusextra) {
289            // gbds = new GroebnerBaseDistributedHybridEC(mfile, threads,port);
290            gbds = new GroebnerBaseDistributedHybridEC(mfile, threads, threadsPerNode,
291                            new OrderedSyzPairlist(), port);
292        } else {
293            gbd = new GroebnerBaseDistributedHybridEC(mfile, threads, threadsPerNode, port);
294        }
295        t1 = System.currentTimeMillis();
296        if (plusextra) {
297            G = gbds.GB(L);
298        } else {
299            G = gbd.GB(L);
300        }
301        t1 = System.currentTimeMillis() - t1;
302        if (plusextra) {
303            gbds.terminate(); // true
304        } else {
305            gbd.terminate(); // false plus eventually killed by script
306        }
307        t = System.currentTimeMillis() - t;
308        S = new PolynomialList(S.ring, G);
309        System.out.println("G =\n" + S);
310        System.out.println("G.size() = " + G.size());
311        if (plusextra) {
312            System.out.print("d+ ");
313        } else {
314            System.out.print("d ");
315        }
316        System.out.println("= " + threads + ", ppn = " + threadsPerNode + ", time = " + t1
317                        + " milliseconds, " + (t - t1) + " start-up " + ", total = " + t);
318        checkGB(S);
319        System.out.println("");
320    }
321
322
323    static void runClient(int port) {
324        System.out.println("\nGroebner base distributed client (" + port + ") ...");
325        ExecutableServer es = new ExecutableServer(port);
326        es.init();
327        try {
328            es.join();
329        } catch (InterruptedException e) {
330            // ignored
331        }
332    }
333
334
335    @SuppressWarnings("unchecked")
336    static void runParallel(PolynomialList S, int threads, boolean plusextra) {
337        List L = S.list;
338        List G;
339        long t;
340        GroebnerBaseAbstract bb = null;
341        GroebnerBaseAbstract bbs = null;
342        if (plusextra) {
343            //bbs = new GroebnerBaseSeqPairParallel(threads);
344            bbs = new GroebnerBaseParallel(threads, new ReductionPar(), new OrderedSyzPairlist());
345        } else {
346            if (S.ring.coFac.isField()) {
347                bb = new GroebnerBaseParallel(threads);
348            } else {
349                bb = new GroebnerBasePseudoParallel(threads, S.ring.coFac);
350            }
351        }
352        System.out.println("\nGroebner base parallel (" + threads + ") ...");
353        t = System.currentTimeMillis();
354        if (plusextra) {
355            G = bbs.GB(L);
356        } else {
357            G = bb.GB(L);
358        }
359        t = System.currentTimeMillis() - t;
360        S = new PolynomialList(S.ring, G);
361        System.out.println("G =\n" + S);
362        System.out.println("G.size() = " + G.size());
363
364        if (plusextra) {
365            System.out.print("p+ ");
366        } else {
367            System.out.print("p ");
368        }
369        System.out.println("= " + threads + ", time = " + t + " milliseconds");
370        if (plusextra) {
371            bbs.terminate();
372        } else {
373            bb.terminate();
374        }
375        checkGB(S);
376        System.out.println("");
377    }
378
379
380    @SuppressWarnings("unchecked")
381    static void runSequential(PolynomialList S, boolean plusextra) {
382        List L = S.list;
383        List G;
384        long t;
385        GroebnerBaseAbstract bb = null;
386        if (plusextra) {
387            //bb = new GroebnerBaseSeqPlusextra();
388            bb = new GroebnerBaseSeq(new ReductionSeq(), new OrderedSyzPairlist());
389        } else {
390            bb = GBFactory.getImplementation(S.ring.coFac); //new GroebnerBaseSeq();
391        }
392        System.out.println("\nGroebner base sequential ...");
393        t = System.currentTimeMillis();
394        G = bb.GB(L);
395        t = System.currentTimeMillis() - t;
396        S = new PolynomialList(S.ring, G);
397        System.out.println("G =\n" + S);
398        System.out.println("G.size() = " + G.size());
399        if (plusextra) {
400            System.out.print("seq+, ");
401        } else {
402            System.out.print("seq, ");
403        }
404        System.out.println("time = " + t + " milliseconds");
405        checkGB(S);
406        System.out.println("");
407    }
408
409
410    @SuppressWarnings("unchecked")
411    static void checkGB(PolynomialList S) {
412        if (!doCheck) {
413            return;
414        }
415        GroebnerBaseAbstract bb = GBFactory.getImplementation(S.ring.coFac);
416        long t = System.currentTimeMillis();
417        boolean chk = bb.isGB(S.list, false);
418        t = System.currentTimeMillis() - t;
419        System.out.println("check isGB = " + chk + " in " + t + " milliseconds");
420    }
421
422
423    static int indexOf(String[] args, String s) {
424        for (int i = 0; i < args.length; i++) {
425            if (s.equals(args[i])) {
426                return i;
427            }
428        }
429        return -1;
430    }
431
432
433    static String join(String[] args, String d) {
434        StringBuffer sb = new StringBuffer();
435        for (int i = 0; i < args.length; i++) {
436            if (i > 0) {
437                sb.append(d);
438            }
439            sb.append(args[i]);
440        }
441        return sb.toString();
442    }
443
444
445    @SuppressWarnings("resource")
446    static Reader getReader(String filename) {
447        Reader problem = null;
448        Exception fnf = null;
449        try {
450            problem = new InputStreamReader(new FileInputStream(filename), Charset.forName("UTF8"));
451            problem = new BufferedReader(problem);
452        } catch (FileNotFoundException e) {
453            fnf = e;
454        }
455        if (problem != null) {
456            return problem;
457        }
458        String examples = "examples.jar";
459        try {
460            JarFile jf = new JarFile(examples);
461            JarEntry je = jf.getJarEntry(filename);
462            if (je == null) {
463                if (jf != null ) {
464                   jf.close();
465                }
466                fnf.printStackTrace();
467                return problem;
468            }
469            problem = new InputStreamReader(jf.getInputStream(je), Charset.forName("UTF8"));
470            problem = new BufferedReader(problem);
471        } catch (FileNotFoundException e) {
472            fnf.printStackTrace();
473            e.printStackTrace();
474        } catch (IOException e) {
475            fnf.printStackTrace();
476            e.printStackTrace();
477            //} finally { not possible, problem must remain open
478            //jf.close();
479        }
480        return problem;
481    }
482
483}