001/* 002 * $Id: RunGB.java 5926 2018-09-19 21:30:55Z 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.lang.reflect.InvocationTargetException; 016import java.lang.reflect.Method; 017import java.nio.charset.Charset; 018import java.util.Arrays; 019import java.util.List; 020import java.util.jar.JarEntry; 021import java.util.jar.JarFile; 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(+)|build=string|disthyb|cli] <file> 044 * #procs/#threadsPerNode [machinefile] <check> <br> 045 * Build string can be any combination of method calls from GBAlgorithmBuilder. 046 * Method polynomialRing() is called based on declaration from "file". Method 047 * build() is called automatically. For example <br> 048 * build=syzygyPairlist.iterated.graded.parallel(3) 049 * @see edu.jas.application.GBAlgorithmBuilder 050 * @author Heinz Kredel 051 */ 052public class RunGB { 053 054 055 /** 056 * Check result GB if it is a GB. 057 */ 058 static boolean doCheck = false; 059 060 061 /** 062 * main method to be called from commandline <br> 063 * Usage: RunGB [seq|par(+)|build=string|disthyb(+)|cli] <file> 064 * #procs/#threadsPerNode [machinefile] <check> 065 */ 066 @SuppressWarnings("unchecked") 067 public static void main(String[] args) { 068 069 String[] allkinds = new String[] { "seq", "seq+", "par", "par+", "build=", "disthyb", "disthyb+", 070 "cli" }; // must be last 071 072 String usage = "Usage: RunGB [ " + join(allkinds, " | ") + "[port] ] " + "<file> " 073 + "#procs/#threadsPerNode " + "[machinefile] " + "[check] "; 074 075 if (args.length < 1) { 076 System.out.println("args: " + Arrays.toString(args)); 077 System.out.println(usage); 078 return; 079 } 080 081 boolean plusextra = false; 082 String kind = args[0]; 083 boolean sup = false; 084 int k = -1; 085 for (int i = 0; i < args.length; i++) { 086 int j = indexOf(allkinds, args[i]); 087 if (j < 0) { 088 continue; 089 } 090 sup = true; 091 k = i; 092 kind = args[k]; 093 break; 094 } 095 if (!sup) { 096 System.out.println("args(sup): " + Arrays.toString(args)); 097 System.out.println(usage); 098 return; 099 } 100 if (kind.indexOf("+") >= 0) { 101 plusextra = true; 102 } 103 System.out.println("kind: " + kind + ", k = " + k); 104 105 final int GB_SERVER_PORT = 7114; 106 int port = GB_SERVER_PORT; 107 108 if (kind.equals("cli")) { 109 if (args.length - k >= 2) { 110 try { 111 port = Integer.parseInt(args[k + 1]); 112 } catch (NumberFormatException e) { 113 e.printStackTrace(); 114 System.out.println("args(port): " + Arrays.toString(args)); 115 System.out.println(usage); 116 return; 117 } 118 } 119 runClient(port); 120 return; 121 } 122 123 String filename = null; 124 if (!kind.equals("cli")) { 125 if (args.length - k < 2) { 126 System.out.println("args(file): " + Arrays.toString(args)); 127 System.out.println(usage); 128 return; 129 } 130 filename = args[k + 1]; 131 } 132 133 int j = indexOf(args, "check"); 134 if (j >= 0) { 135 doCheck = true; 136 } 137 138 int threads = 0; 139 int threadsPerNode = 1; 140 if (kind.startsWith("par") || kind.startsWith("dist")) { 141 if (args.length - k < 3) { 142 System.out.println("args(par|dist): " + Arrays.toString(args)); 143 System.out.println(usage); 144 return; 145 } 146 String tup = args[k + 2]; 147 String t = tup; 148 int i = tup.indexOf("/"); 149 if (i >= 0) { 150 t = tup.substring(0, i).trim(); 151 tup = tup.substring(i + 1).trim(); 152 try { 153 threadsPerNode = Integer.parseInt(tup); 154 } catch (NumberFormatException e) { 155 e.printStackTrace(); 156 System.out.println("args(threadsPerNode): " + Arrays.toString(args)); 157 System.out.println(usage); 158 return; 159 } 160 } 161 try { 162 threads = Integer.parseInt(t); 163 } catch (NumberFormatException e) { 164 e.printStackTrace(); 165 System.out.println("args(threads): " + Arrays.toString(args)); 166 System.out.println(usage); 167 return; 168 } 169 } 170 171 String mfile = null; 172 if (kind.startsWith("dist")) { 173 if (args.length - k >= 4) { 174 mfile = args[k + 3]; 175 } else { 176 mfile = "machines"; 177 } 178 } 179 180 Reader problem = getReader(filename); 181 if (problem == null) { 182 System.out.println("args(file): " + filename); 183 System.out.println("args(file): examples.jar(" + filename + ")"); 184 System.out.println("args(file): " + Arrays.toString(args)); 185 System.out.println(usage); 186 return; 187 } 188 RingFactoryTokenizer rftok = new RingFactoryTokenizer(problem); 189 GenPolynomialRing pfac = null; 190 try { 191 pfac = rftok.nextPolynomialRing(); 192 rftok = null; 193 } catch (IOException e) { 194 e.printStackTrace(); 195 return; 196 } 197 System.out.println("pfac: " + pfac.toScript()); 198 Reader polyreader = new CatReader(new StringReader("("), problem); // ( has gone 199 //Reader polyreader = problem; 200 GenPolynomialTokenizer tok = new GenPolynomialTokenizer(pfac, polyreader); 201 PolynomialList S = null; 202 try { 203 S = new PolynomialList(pfac, tok.nextPolynomialList()); 204 } catch (IOException e) { 205 e.printStackTrace(); 206 return; 207 } 208 System.out.println("input S =\n" + S); 209 210 GroebnerBaseAbstract gb = null; 211 if (kind.startsWith("build")) { 212 gb = getGBalgo(args, kind, S.ring); 213 if (gb == null) { 214 System.out.println(usage); 215 return; 216 } 217 } 218 219 if (kind.startsWith("seq")) { 220 runSequential(S, plusextra); 221 } else if (kind.startsWith("par")) { 222 runParallel(S, threads, plusextra); 223 } else if (kind.startsWith("disthyb")) { 224 runMasterHyb(S, threads, threadsPerNode, mfile, port, plusextra); 225 //} else if (kind.startsWith("dist")) { 226 //runMaster(S, threads, mfile, port, plusextra); 227 } else if (kind.startsWith("build")) { 228 runGB(S, gb); 229 } 230 ComputerThreads.terminate(); 231 //System.exit(0); 232 } 233 234 235 // no more used 236 @SuppressWarnings("unchecked") 237 static void runMaster(PolynomialList S, int threads, String mfile, int port, boolean plusextra) { 238 List L = S.list; 239 List G = null; 240 long t, t1; 241 GroebnerBaseDistributedEC gbd = null; 242 GroebnerBaseDistributedEC gbds = null; 243 244 System.out.println("\nGroebner base distributed (" + threads + ", " + mfile + ", " + port + ") ..."); 245 t = System.currentTimeMillis(); 246 if (plusextra) { 247 //gbds = new GroebnerBaseDistributedEC(threads,mfile, port); 248 gbds = new GroebnerBaseDistributedEC(mfile, threads, new OrderedSyzPairlist(), port); 249 } else { 250 gbd = new GroebnerBaseDistributedEC(mfile, threads, port); 251 } 252 t1 = System.currentTimeMillis(); 253 if (plusextra) { 254 G = gbds.GB(L); 255 } else { 256 G = gbd.GB(L); 257 } 258 t1 = System.currentTimeMillis() - t1; 259 if (plusextra) { 260 gbds.terminate(); //false); 261 } else { 262 gbd.terminate(); //false); 263 } 264 S = new PolynomialList(S.ring, G); 265 System.out.println("G =\n" + S); 266 System.out.println("G.size() = " + G.size()); 267 t = System.currentTimeMillis() - t; 268 if (plusextra) { 269 System.out.print("d+ "); 270 } else { 271 System.out.print("d "); 272 } 273 System.out.println("= " + threads + ", time = " + t1 + " milliseconds, " + (t - t1) + " start-up " 274 + ", total = " + t); 275 checkGB(S); 276 System.out.println(""); 277 } 278 279 280 @SuppressWarnings("unchecked") 281 static void runMasterHyb(PolynomialList S, int threads, int threadsPerNode, String mfile, int port, 282 boolean plusextra) { 283 List L = S.list; 284 List G = null; 285 long t, t1; 286 GroebnerBaseDistributedHybridEC gbd = null; 287 GroebnerBaseDistributedHybridEC gbds = null; 288 289 System.out.println("\nGroebner base distributed hybrid (" + threads + "/" + threadsPerNode + ", " 290 + mfile + ", " + port + ") ..."); 291 t = System.currentTimeMillis(); 292 if (plusextra) { 293 // gbds = new GroebnerBaseDistributedHybridEC(mfile, threads,port); 294 gbds = new GroebnerBaseDistributedHybridEC(mfile, threads, threadsPerNode, 295 new OrderedSyzPairlist(), port); 296 } else { 297 gbd = new GroebnerBaseDistributedHybridEC(mfile, threads, threadsPerNode, port); 298 } 299 t1 = System.currentTimeMillis(); 300 if (plusextra) { 301 G = gbds.GB(L); 302 } else { 303 G = gbd.GB(L); 304 } 305 t1 = System.currentTimeMillis() - t1; 306 if (plusextra) { 307 gbds.terminate(); // true 308 } else { 309 gbd.terminate(); // false plus eventually killed by script 310 } 311 t = System.currentTimeMillis() - t; 312 S = new PolynomialList(S.ring, G); 313 System.out.println("G =\n" + S); 314 System.out.println("G.size() = " + G.size()); 315 if (plusextra) { 316 System.out.print("d+ "); 317 } else { 318 System.out.print("d "); 319 } 320 System.out.println("= " + threads + ", ppn = " + threadsPerNode + ", time = " + t1 + " milliseconds, " 321 + (t - t1) + " start-up " + ", total = " + t); 322 checkGB(S); 323 System.out.println(""); 324 } 325 326 327 static void runClient(int port) { 328 System.out.println("\nGroebner base distributed client (" + port + ") ..."); 329 ExecutableServer es = new ExecutableServer(port); 330 es.init(); 331 try { 332 es.join(); 333 } catch (InterruptedException e) { 334 // ignored 335 } 336 System.out.println("runClient() done: " + es); 337 } 338 339 340 @SuppressWarnings("unchecked") 341 static void runParallel(PolynomialList S, int threads, boolean plusextra) { 342 List L = S.list; 343 List G; 344 long t; 345 GroebnerBaseAbstract bb = null; 346 GroebnerBaseAbstract bbs = null; 347 if (plusextra) { 348 //bbs = new GroebnerBaseSeqPairParallel(threads); 349 bbs = new GroebnerBaseParallel(threads, new ReductionPar(), new OrderedSyzPairlist()); 350 } else { 351 if (S.ring.coFac.isField()) { 352 bb = new GroebnerBaseParallel(threads); 353 } else { 354 bb = new GroebnerBasePseudoParallel(threads, S.ring.coFac); 355 } 356 } 357 System.out.println("\nGroebner base parallel (" + threads + ") ..."); 358 t = System.currentTimeMillis(); 359 if (plusextra) { 360 G = bbs.GB(L); 361 } else { 362 G = bb.GB(L); 363 } 364 t = System.currentTimeMillis() - t; 365 S = new PolynomialList(S.ring, G); 366 System.out.println("G =\n" + S); 367 System.out.println("G.size() = " + G.size()); 368 369 if (plusextra) { 370 System.out.print("p+ "); 371 } else { 372 System.out.print("p "); 373 } 374 System.out.println("= " + threads + ", time = " + t + " milliseconds"); 375 if (plusextra) { 376 bbs.terminate(); 377 } else { 378 bb.terminate(); 379 } 380 checkGB(S); 381 System.out.println(""); 382 } 383 384 385 @SuppressWarnings("unchecked") 386 static void runSequential(PolynomialList S, boolean plusextra) { 387 List L = S.list; 388 List G; 389 long t; 390 GroebnerBaseAbstract bb = null; 391 if (plusextra) { 392 //bb = new GroebnerBaseSeqPlusextra(); 393 bb = new GroebnerBaseSeq(new ReductionSeq(), new OrderedSyzPairlist()); 394 } else { 395 bb = GBFactory.getImplementation(S.ring.coFac); //new GroebnerBaseSeq(); 396 } 397 System.out.println("\nGroebner base sequential ..."); 398 t = System.currentTimeMillis(); 399 G = bb.GB(L); 400 t = System.currentTimeMillis() - t; 401 S = new PolynomialList(S.ring, G); 402 System.out.println("G =\n" + S); 403 System.out.println("G.size() = " + G.size()); 404 if (plusextra) { 405 System.out.print("seq+, "); 406 } else { 407 System.out.print("seq, "); 408 } 409 System.out.println("time = " + t + " milliseconds"); 410 checkGB(S); 411 System.out.println(""); 412 } 413 414 415 @SuppressWarnings("unchecked") 416 static void runGB(PolynomialList S, GroebnerBaseAbstract bb) { 417 List L = S.list; 418 List G; 419 long t; 420 if (bb == null) { // should not happen 421 bb = GBFactory.getImplementation(S.ring.coFac); 422 } 423 String bbs = bb.toString().replaceAll(" ", ""); 424 System.out.println("\nGroebner base build=" + bbs + " ..."); 425 t = System.currentTimeMillis(); 426 G = bb.GB(L); 427 t = System.currentTimeMillis() - t; 428 S = new PolynomialList(S.ring, G); 429 bbs = bb.toString().replaceAll(" ", ""); 430 System.out.println("G =\n" + S); 431 System.out.println("G.size() = " + G.size()); 432 System.out.print("build=" + bbs + ", "); 433 System.out.println("time = " + t + " milliseconds"); 434 checkGB(S); 435 bb.terminate(); 436 System.out.println(""); 437 } 438 439 440 @SuppressWarnings("unchecked") 441 static void checkGB(PolynomialList S) { 442 if (!doCheck) { 443 return; 444 } 445 GroebnerBaseAbstract bb = GBFactory.getImplementation(S.ring.coFac); 446 long t = System.currentTimeMillis(); 447 boolean chk = bb.isGB(S.list, false); 448 t = System.currentTimeMillis() - t; 449 System.out.println("check isGB = " + chk + " in " + t + " milliseconds"); 450 } 451 452 453 static int indexOf(String[] args, String s) { 454 for (int i = 0; i < args.length; i++) { 455 if (s.startsWith(args[i])) { 456 return i; 457 } 458 } 459 return -1; 460 } 461 462 463 static String join(String[] args, String d) { 464 StringBuffer sb = new StringBuffer(); 465 for (int i = 0; i < args.length; i++) { 466 if (i > 0) { 467 sb.append(d); 468 } 469 sb.append(args[i]); 470 } 471 return sb.toString(); 472 } 473 474 475 @SuppressWarnings("resource") 476 static Reader getReader(String filename) { 477 Reader problem = null; 478 Exception fnf = null; 479 try { 480 problem = new InputStreamReader(new FileInputStream(filename), Charset.forName("UTF8")); 481 problem = new BufferedReader(problem); 482 } catch (FileNotFoundException e) { 483 fnf = e; 484 } 485 if (problem != null) { 486 return problem; 487 } 488 String examples = "examples.jar"; 489 try { 490 JarFile jf = new JarFile(examples); 491 JarEntry je = jf.getJarEntry(filename); 492 if (je == null) { 493 if (jf != null) { 494 jf.close(); 495 } 496 fnf.printStackTrace(); 497 return problem; 498 } 499 problem = new InputStreamReader(jf.getInputStream(je), Charset.forName("UTF8")); 500 problem = new BufferedReader(problem); 501 } catch (FileNotFoundException e) { 502 fnf.printStackTrace(); 503 e.printStackTrace(); 504 } catch (IOException e) { 505 fnf.printStackTrace(); 506 e.printStackTrace(); 507 //} finally { not possible, problem must remain open 508 //jf.close(); 509 } 510 return problem; 511 } 512 513 514 @SuppressWarnings("unchecked") 515 static GroebnerBaseAbstract getGBalgo(String[] args, String bstr, GenPolynomialRing ring) { 516 GroebnerBaseAbstract gb = null; 517 int i = bstr.indexOf("="); 518 if (i < 0) { 519 System.out.println("args(build): " + Arrays.toString(args)); 520 return gb; 521 } 522 i += 1; 523 String tb = bstr.substring(i); 524 //System.out.println("build=" + tb); 525 GBAlgorithmBuilder ab = GBAlgorithmBuilder.polynomialRing(ring); 526 //System.out.println("ab = " + ab); 527 while (!tb.isEmpty()) { 528 int ii = tb.indexOf("."); 529 String mth; 530 if (ii >= 0) { 531 mth = tb.substring(0, ii); 532 tb = tb.substring(ii + 1); 533 } else { 534 mth = tb; 535 tb = ""; 536 } 537 if (mth.startsWith("build")) { 538 continue; 539 } 540 String parm = ""; 541 int jj = mth.indexOf("()"); 542 if (jj >= 0) { 543 mth = mth.substring(0, jj); 544 } else { 545 jj = mth.indexOf("("); 546 if (jj >= 0) { 547 parm = mth.substring(jj + 1); 548 mth = mth.substring(0, jj); 549 jj = parm.indexOf(")"); 550 parm = parm.substring(0, jj); 551 } 552 } 553 //System.out.println("mth = " + mth + ", parm = " + parm); 554 try { 555 Method method; 556 if (parm.isEmpty()) { 557 method = ab.getClass().getMethod(mth, (Class<?>[]) null); 558 ab = (GBAlgorithmBuilder) method.invoke(ab, (Object[]) null); 559 } else { 560 int tparm = Integer.parseInt(parm); 561 method = ab.getClass().getMethod(mth, int.class); 562 ab = (GBAlgorithmBuilder) method.invoke(ab, tparm); 563 } 564 } catch (NoSuchMethodException e) { 565 System.out.println("args(build,method): " + Arrays.toString(args)); 566 return gb; 567 } catch (IllegalAccessException e) { 568 System.out.println("args(build,access): " + Arrays.toString(args)); 569 return gb; 570 } catch (InvocationTargetException e) { 571 System.out.println("args(build,invocation): " + Arrays.toString(args)); 572 return gb; 573 } catch (NumberFormatException e) { 574 System.out.println("args(build,number): " + Arrays.toString(args)); 575 return gb; 576 } 577 } 578 gb = ab.build(); 579 //System.out.println("gb = " + gb); 580 return gb; 581 } 582 583}