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