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