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