001/* 002 * $Id: RunGB.java 5861 2018-07-20 10:09:03Z 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 Reader polyreader = new CatReader(new StringReader("("), problem); // ( has gone 198 //Reader polyreader = problem; 199 GenPolynomialTokenizer tok = new GenPolynomialTokenizer(pfac, polyreader); 200 PolynomialList S = null; 201 try { 202 S = new PolynomialList(pfac, tok.nextPolynomialList()); 203 } catch (IOException e) { 204 e.printStackTrace(); 205 return; 206 } 207 System.out.println("input S =\n" + S); 208 209 GroebnerBaseAbstract gb = null; 210 if (kind.startsWith("build")) { 211 gb = getGBalgo(args, kind, S.ring); 212 if (gb == null) { 213 System.out.println(usage); 214 return; 215 } 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 } else if (kind.startsWith("build")) { 227 runGB(S, gb); 228 } 229 ComputerThreads.terminate(); 230 //System.exit(0); 231 } 232 233 234 // no more used 235 @SuppressWarnings("unchecked") 236 static void runMaster(PolynomialList S, int threads, String mfile, int port, boolean plusextra) { 237 List L = S.list; 238 List G = null; 239 long t, t1; 240 GroebnerBaseDistributedEC gbd = null; 241 GroebnerBaseDistributedEC gbds = null; 242 243 System.out.println("\nGroebner base distributed (" + threads + ", " + mfile + ", " + port + ") ..."); 244 t = System.currentTimeMillis(); 245 if (plusextra) { 246 //gbds = new GroebnerBaseDistributedEC(threads,mfile, port); 247 gbds = new GroebnerBaseDistributedEC(mfile, threads, new OrderedSyzPairlist(), port); 248 } else { 249 gbd = new GroebnerBaseDistributedEC(mfile, threads, port); 250 } 251 t1 = System.currentTimeMillis(); 252 if (plusextra) { 253 G = gbds.GB(L); 254 } else { 255 G = gbd.GB(L); 256 } 257 t1 = System.currentTimeMillis() - t1; 258 if (plusextra) { 259 gbds.terminate(); //false); 260 } else { 261 gbd.terminate(); //false); 262 } 263 S = new PolynomialList(S.ring, G); 264 System.out.println("G =\n" + S); 265 System.out.println("G.size() = " + G.size()); 266 t = System.currentTimeMillis() - t; 267 if (plusextra) { 268 System.out.print("d+ "); 269 } else { 270 System.out.print("d "); 271 } 272 System.out.println("= " + threads + ", time = " + t1 + " milliseconds, " + (t - t1) + " start-up " 273 + ", total = " + t); 274 checkGB(S); 275 System.out.println(""); 276 } 277 278 279 @SuppressWarnings("unchecked") 280 static void runMasterHyb(PolynomialList S, int threads, int threadsPerNode, String mfile, int port, 281 boolean plusextra) { 282 List L = S.list; 283 List G = null; 284 long t, t1; 285 GroebnerBaseDistributedHybridEC gbd = null; 286 GroebnerBaseDistributedHybridEC gbds = null; 287 288 System.out.println("\nGroebner base distributed hybrid (" + threads + "/" + threadsPerNode + ", " 289 + mfile + ", " + port + ") ..."); 290 t = System.currentTimeMillis(); 291 if (plusextra) { 292 // gbds = new GroebnerBaseDistributedHybridEC(mfile, threads,port); 293 gbds = new GroebnerBaseDistributedHybridEC(mfile, threads, threadsPerNode, 294 new OrderedSyzPairlist(), port); 295 } else { 296 gbd = new GroebnerBaseDistributedHybridEC(mfile, threads, threadsPerNode, port); 297 } 298 t1 = System.currentTimeMillis(); 299 if (plusextra) { 300 G = gbds.GB(L); 301 } else { 302 G = gbd.GB(L); 303 } 304 t1 = System.currentTimeMillis() - t1; 305 if (plusextra) { 306 gbds.terminate(); // true 307 } else { 308 gbd.terminate(); // false plus eventually killed by script 309 } 310 t = System.currentTimeMillis() - t; 311 S = new PolynomialList(S.ring, G); 312 System.out.println("G =\n" + S); 313 System.out.println("G.size() = " + G.size()); 314 if (plusextra) { 315 System.out.print("d+ "); 316 } else { 317 System.out.print("d "); 318 } 319 System.out.println("= " + threads + ", ppn = " + threadsPerNode + ", time = " + t1 + " milliseconds, " 320 + (t - t1) + " start-up " + ", total = " + t); 321 checkGB(S); 322 System.out.println(""); 323 } 324 325 326 static void runClient(int port) { 327 System.out.println("\nGroebner base distributed client (" + port + ") ..."); 328 ExecutableServer es = new ExecutableServer(port); 329 es.init(); 330 try { 331 es.join(); 332 } catch (InterruptedException e) { 333 // ignored 334 } 335 System.out.println("runClient() done: " + es); 336 } 337 338 339 @SuppressWarnings("unchecked") 340 static void runParallel(PolynomialList S, int threads, boolean plusextra) { 341 List L = S.list; 342 List G; 343 long t; 344 GroebnerBaseAbstract bb = null; 345 GroebnerBaseAbstract bbs = null; 346 if (plusextra) { 347 //bbs = new GroebnerBaseSeqPairParallel(threads); 348 bbs = new GroebnerBaseParallel(threads, new ReductionPar(), new OrderedSyzPairlist()); 349 } else { 350 if (S.ring.coFac.isField()) { 351 bb = new GroebnerBaseParallel(threads); 352 } else { 353 bb = new GroebnerBasePseudoParallel(threads, S.ring.coFac); 354 } 355 } 356 System.out.println("\nGroebner base parallel (" + threads + ") ..."); 357 t = System.currentTimeMillis(); 358 if (plusextra) { 359 G = bbs.GB(L); 360 } else { 361 G = bb.GB(L); 362 } 363 t = System.currentTimeMillis() - t; 364 S = new PolynomialList(S.ring, G); 365 System.out.println("G =\n" + S); 366 System.out.println("G.size() = " + G.size()); 367 368 if (plusextra) { 369 System.out.print("p+ "); 370 } else { 371 System.out.print("p "); 372 } 373 System.out.println("= " + threads + ", time = " + t + " milliseconds"); 374 if (plusextra) { 375 bbs.terminate(); 376 } else { 377 bb.terminate(); 378 } 379 checkGB(S); 380 System.out.println(""); 381 } 382 383 384 @SuppressWarnings("unchecked") 385 static void runSequential(PolynomialList S, boolean plusextra) { 386 List L = S.list; 387 List G; 388 long t; 389 GroebnerBaseAbstract bb = null; 390 if (plusextra) { 391 //bb = new GroebnerBaseSeqPlusextra(); 392 bb = new GroebnerBaseSeq(new ReductionSeq(), new OrderedSyzPairlist()); 393 } else { 394 bb = GBFactory.getImplementation(S.ring.coFac); //new GroebnerBaseSeq(); 395 } 396 System.out.println("\nGroebner base sequential ..."); 397 t = System.currentTimeMillis(); 398 G = bb.GB(L); 399 t = System.currentTimeMillis() - t; 400 S = new PolynomialList(S.ring, G); 401 System.out.println("G =\n" + S); 402 System.out.println("G.size() = " + G.size()); 403 if (plusextra) { 404 System.out.print("seq+, "); 405 } else { 406 System.out.print("seq, "); 407 } 408 System.out.println("time = " + t + " milliseconds"); 409 checkGB(S); 410 System.out.println(""); 411 } 412 413 414 @SuppressWarnings("unchecked") 415 static void runGB(PolynomialList S, GroebnerBaseAbstract bb) { 416 List L = S.list; 417 List G; 418 long t; 419 if (bb == null) { // should not happen 420 bb = GBFactory.getImplementation(S.ring.coFac); 421 } 422 String bbs = bb.toString().replaceAll(" ", ""); 423 System.out.println("\nGroebner base build=" + bbs + " ..."); 424 t = System.currentTimeMillis(); 425 G = bb.GB(L); 426 t = System.currentTimeMillis() - t; 427 S = new PolynomialList(S.ring, G); 428 bbs = bb.toString().replaceAll(" ", ""); 429 System.out.println("G =\n" + S); 430 System.out.println("G.size() = " + G.size()); 431 System.out.print("build=" + bbs + ", "); 432 System.out.println("time = " + t + " milliseconds"); 433 checkGB(S); 434 bb.terminate(); 435 System.out.println(""); 436 } 437 438 439 @SuppressWarnings("unchecked") 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 452 static int indexOf(String[] args, String s) { 453 for (int i = 0; i < args.length; i++) { 454 if (s.startsWith(args[i])) { 455 return i; 456 } 457 } 458 return -1; 459 } 460 461 462 static String join(String[] args, String d) { 463 StringBuffer sb = new StringBuffer(); 464 for (int i = 0; i < args.length; i++) { 465 if (i > 0) { 466 sb.append(d); 467 } 468 sb.append(args[i]); 469 } 470 return sb.toString(); 471 } 472 473 474 @SuppressWarnings("resource") 475 static Reader getReader(String filename) { 476 Reader problem = null; 477 Exception fnf = null; 478 try { 479 problem = new InputStreamReader(new FileInputStream(filename), Charset.forName("UTF8")); 480 problem = new BufferedReader(problem); 481 } catch (FileNotFoundException e) { 482 fnf = e; 483 } 484 if (problem != null) { 485 return problem; 486 } 487 String examples = "examples.jar"; 488 try { 489 JarFile jf = new JarFile(examples); 490 JarEntry je = jf.getJarEntry(filename); 491 if (je == null) { 492 if (jf != null) { 493 jf.close(); 494 } 495 fnf.printStackTrace(); 496 return problem; 497 } 498 problem = new InputStreamReader(jf.getInputStream(je), Charset.forName("UTF8")); 499 problem = new BufferedReader(problem); 500 } catch (FileNotFoundException e) { 501 fnf.printStackTrace(); 502 e.printStackTrace(); 503 } catch (IOException e) { 504 fnf.printStackTrace(); 505 e.printStackTrace(); 506 //} finally { not possible, problem must remain open 507 //jf.close(); 508 } 509 return problem; 510 } 511 512 513 @SuppressWarnings("unchecked") 514 static GroebnerBaseAbstract getGBalgo(String[] args, String bstr, GenPolynomialRing ring) { 515 GroebnerBaseAbstract gb = null; 516 int i = bstr.indexOf("="); 517 if (i < 0) { 518 System.out.println("args(build): " + Arrays.toString(args)); 519 return gb; 520 } 521 i += 1; 522 String tb = bstr.substring(i); 523 //System.out.println("build=" + tb); 524 GBAlgorithmBuilder ab = GBAlgorithmBuilder.polynomialRing(ring); 525 //System.out.println("ab = " + ab); 526 while (!tb.isEmpty()) { 527 int ii = tb.indexOf("."); 528 String mth; 529 if (ii >= 0) { 530 mth = tb.substring(0, ii); 531 tb = tb.substring(ii + 1); 532 } else { 533 mth = tb; 534 tb = ""; 535 } 536 if (mth.startsWith("build")) { 537 continue; 538 } 539 String parm = ""; 540 int jj = mth.indexOf("()"); 541 if (jj >= 0) { 542 mth = mth.substring(0, jj); 543 } else { 544 jj = mth.indexOf("("); 545 if (jj >= 0) { 546 parm = mth.substring(jj + 1); 547 mth = mth.substring(0, jj); 548 jj = parm.indexOf(")"); 549 parm = parm.substring(0, jj); 550 } 551 } 552 //System.out.println("mth = " + mth + ", parm = " + parm); 553 try { 554 Method method; 555 if (parm.isEmpty()) { 556 method = ab.getClass().getMethod(mth, (Class<?>[]) null); 557 ab = (GBAlgorithmBuilder) method.invoke(ab, (Object[]) null); 558 } else { 559 int tparm = Integer.parseInt(parm); 560 method = ab.getClass().getMethod(mth, int.class); 561 ab = (GBAlgorithmBuilder) method.invoke(ab, tparm); 562 } 563 } catch (NoSuchMethodException e) { 564 System.out.println("args(build,method): " + Arrays.toString(args)); 565 return gb; 566 } catch (IllegalAccessException e) { 567 System.out.println("args(build,access): " + Arrays.toString(args)); 568 return gb; 569 } catch (InvocationTargetException e) { 570 System.out.println("args(build,invocation): " + Arrays.toString(args)); 571 return gb; 572 } catch (NumberFormatException e) { 573 System.out.println("args(build,number): " + Arrays.toString(args)); 574 return gb; 575 } 576 } 577 gb = ab.build(); 578 //System.out.println("gb = " + gb); 579 return gb; 580 } 581 582}