001/* 002 * $Id: GroebnerBaseDistributedEC.java 4304 2012-12-01 10:41:22Z kredel $ 003 */ 004 005package edu.jas.gb; 006 007 008import java.io.IOException; 009import java.io.Serializable; 010import java.util.ArrayList; 011import java.util.Collections; 012import java.util.List; 013import java.util.ListIterator; 014import java.util.concurrent.Semaphore; 015 016import org.apache.log4j.Logger; 017 018import edu.jas.poly.ExpVector; 019import edu.jas.poly.GenPolynomial; 020import edu.jas.structure.RingElem; 021import edu.jas.util.ChannelFactory; 022import edu.jas.util.DistHashTable; 023import edu.jas.util.DistHashTableServer; 024import edu.jas.util.SocketChannel; 025import edu.jas.util.Terminator; 026import edu.jas.util.ThreadPool; 027import edu.jas.util.DistThreadPool; 028import edu.jas.util.RemoteExecutable; 029 030 031/** 032 * Groebner Base distributed algorithm. Implements a distributed 033 * memory parallel version of Groebner bases with executable 034 * channels. Using pairlist class, distributed tasks do reduction, one 035 * communication channel per task. 036 * @param <C> coefficient type 037 * @author Heinz Kredel 038 */ 039 040public class GroebnerBaseDistributedEC<C extends RingElem<C>> extends GroebnerBaseAbstract<C> { 041 042 043 private static final Logger logger = Logger.getLogger(GroebnerBaseDistributedEC.class); 044 045 046 /** 047 * Number of threads to use. 048 */ 049 protected final int threads; 050 051 052 /** 053 * Default number of threads. 054 */ 055 protected static final int DEFAULT_THREADS = 2; 056 057 058 /** 059 * Pool of threads to use. <b>Note:</b> No ComputerThreads for one node 060 * tests 061 */ 062 protected transient final ThreadPool pool; 063 064 065 /** 066 * Default server port. 067 */ 068 protected static final int DEFAULT_PORT = 55711; 069 070 071 /** 072 * Default distributed hash table server port. 073 */ 074 protected final int DHT_PORT; 075 076 077 /** 078 * Server port to use. 079 */ 080 protected final int port; 081 082 083 /** 084 * machine file to use. 085 */ 086 protected final String mfile; 087 088 089 /** 090 * Distributed thread pool to use. 091 */ 092 private final DistThreadPool dtp; 093 094 095 /** 096 * Distributed hash table server to use. 097 */ 098 private final DistHashTableServer<Integer> dhts; 099 100 101 /** 102 * Constructor. 103 * @param mfile name of the machine file. 104 */ 105 public GroebnerBaseDistributedEC(String mfile) { 106 this(mfile, DEFAULT_THREADS, DEFAULT_PORT); 107 } 108 109 110 /** 111 * Constructor. 112 * @param mfile name of the machine file. 113 * @param threads number of threads to use. 114 */ 115 public GroebnerBaseDistributedEC(String mfile, int threads) { 116 this(mfile, threads, new ThreadPool(threads), DEFAULT_PORT); 117 } 118 119 120 /** 121 * Constructor. 122 * @param mfile name of the machine file. 123 * @param threads number of threads to use. 124 * @param port server port to use. 125 */ 126 public GroebnerBaseDistributedEC(String mfile, int threads, int port) { 127 this(mfile, threads, new ThreadPool(threads), port); 128 } 129 130 131 /** 132 * Constructor. 133 * @param mfile name of the machine file. 134 * @param threads number of threads to use. 135 * @param pool ThreadPool to use. 136 * @param port server port to use. 137 */ 138 public GroebnerBaseDistributedEC(String mfile, int threads, ThreadPool pool, int port) { 139 this(mfile, threads, pool, new OrderedPairlist<C>(), port); 140 } 141 142 143 /** 144 * Constructor. 145 * @param mfile name of the machine file. 146 * @param threads number of threads to use. 147 * @param pl pair selection strategy 148 * @param port server port to use. 149 */ 150 public GroebnerBaseDistributedEC(String mfile, int threads, PairList<C> pl, int port) { 151 this(mfile, threads, new ThreadPool(threads), pl, port); 152 } 153 154 155 /** 156 * Constructor. 157 * @param mfile name of the machine file. 158 * @param threads number of threads to use. 159 * @param pool ThreadPool to use. 160 * @param pl pair selection strategy 161 * @param port server port to use. 162 */ 163 public GroebnerBaseDistributedEC(String mfile, int threads, ThreadPool pool, PairList<C> pl, int port) { 164 super(new ReductionPar<C>(), pl); 165 this.threads = threads; 166 if (mfile == null || mfile.length() == 0) { 167 this.mfile = "../util/machines"; // contains localhost 168 } else { 169 this.mfile = mfile; 170 } 171 if (threads < 1) { 172 threads = 1; 173 } 174 if ( pool == null ) { 175 pool = new ThreadPool(threads); 176 } 177 this.pool = pool; 178 this.port = port; 179 logger.info("machine file " + mfile + ", port = " + port); 180 this.dtp = new DistThreadPool(this.threads, this.mfile); 181 logger.info("running " + dtp); 182 this.DHT_PORT = this.dtp.getEC().getMasterPort() + 100; 183 this.dhts = new DistHashTableServer<Integer>(this.DHT_PORT); 184 this.dhts.init(); 185 logger.info("running " + dhts); 186 } 187 188 189 /** 190 * Cleanup and terminate ThreadPool. 191 */ 192 @Override 193 public void terminate() { 194 terminate(true); 195 } 196 197 198 /** 199 * Terminates the distributed thread pools. 200 * @param shutDown true, if shut-down of the remote executable servers is 201 * requested, false, if remote executable servers stay alive. 202 */ 203 public void terminate(boolean shutDown) { 204 pool.terminate(); 205 dtp.terminate(shutDown); 206 logger.info("dhts.terminate()"); 207 dhts.terminate(); 208 } 209 210 211 /** 212 * Distributed Groebner base. 213 * @param modv number of module variables. 214 * @param F polynomial list. 215 * @return GB(F) a Groebner base of F or null, if a IOException occurs. 216 */ 217 public List<GenPolynomial<C>> GB(int modv, List<GenPolynomial<C>> F) { 218 String master = dtp.getEC().getMasterHost(); 219 //int port = dtp.getEC().getMasterPort(); // wrong port 220 GBExerClient<C> gbc = new GBExerClient<C>(master, port, DHT_PORT); 221 for (int i = 0; i < threads; i++) { 222 // schedule remote clients 223 dtp.addJob(gbc); 224 } 225 // run master 226 List<GenPolynomial<C>> G = GBMaster(modv, F); 227 228 return G; 229 } 230 231 232 /** 233 * Distributed Groebner base. 234 * @param modv number of module variables. 235 * @param F polynomial list. 236 * @return GB(F) a Groebner base of F or null, if a IOException occurs. 237 */ 238 public List<GenPolynomial<C>> GBMaster(int modv, List<GenPolynomial<C>> F) { 239 ChannelFactory cf = new ChannelFactory(port); 240 cf.init(); 241 logger.info("GBMaster on " + cf); 242 243 GenPolynomial<C> p; 244 List<GenPolynomial<C>> G = new ArrayList<GenPolynomial<C>>(); 245 PairList<C> pairlist = null; 246 boolean oneInGB = false; 247 int l = F.size(); 248 int unused; 249 ListIterator<GenPolynomial<C>> it = F.listIterator(); 250 while (it.hasNext()) { 251 p = it.next(); 252 if (p.length() > 0) { 253 p = p.monic(); 254 if (p.isONE()) { 255 oneInGB = true; 256 G.clear(); 257 G.add(p); 258 //return G; must signal termination to others 259 } 260 if (!oneInGB) { 261 G.add(p); 262 } 263 if (pairlist == null) { 264 //pairlist = new OrderedPairlist<C>(modv, p.ring); 265 pairlist = strategy.create(modv, p.ring); 266 if (!p.ring.coFac.isField()) { 267 throw new IllegalArgumentException("coefficients not from a field"); 268 } 269 } 270 // theList not updated here 271 if (p.isONE()) { 272 unused = pairlist.putOne(); 273 } else { 274 unused = pairlist.put(p); 275 } 276 } else { 277 l--; 278 } 279 } 280 //if (l <= 1) { 281 //return G; must signal termination to others 282 //} 283 284 logger.debug("looking for clients"); 285 DistHashTable<Integer, GenPolynomial<C>> theList = new DistHashTable<Integer, GenPolynomial<C>>("localhost", DHT_PORT); 286 theList.init(); 287 List<GenPolynomial<C>> al = pairlist.getList(); 288 for (int i = 0; i < al.size(); i++) { 289 GenPolynomial<C> nn = theList.put(Integer.valueOf(i), al.get(i)); 290 if (nn != null) { 291 logger.info("double polynomials " + i + ", nn = " + nn + ", al(i) = " + al.get(i)); 292 } 293 } 294 // wait for arrival 295 while ( theList.size() < al.size() ) { 296 logger.info("#distributed list = " + theList.size() + " #pairlist list = " + al.size()); 297 GenPolynomial<C> nn = theList.getWait(al.size()-1); 298 } 299 300 Terminator fin = new Terminator(threads); 301 ReducerServerEC<C> R; 302 for (int i = 0; i < threads; i++) { 303 R = new ReducerServerEC<C>(fin, cf, theList, G, pairlist); 304 pool.addJob(R); 305 } 306 logger.debug("main loop waiting"); 307 fin.waitDone(); 308 int ps = theList.size(); 309 logger.debug("#distributed list = " + ps); 310 // make sure all polynomials arrived: not needed in master 311 // G = (ArrayList)theList.values(); 312 G = pairlist.getList(); 313 if (ps != G.size()) { 314 logger.info("#distributed list = " + theList.size() + " #pairlist list = " + G.size()); 315 } 316 long time = System.currentTimeMillis(); 317 List<GenPolynomial<C>> Gp; 318 Gp = minimalGB(G); // not jet distributed but threaded 319 time = System.currentTimeMillis() - time; 320 logger.info("parallel gbmi = " + time); 321 /* 322 time = System.currentTimeMillis(); 323 G = GroebnerBase.<C>GBmi(G); // sequential 324 time = System.currentTimeMillis() - time; 325 logger.info("sequential gbmi = " + time); 326 */ 327 G = Gp; 328 logger.debug("cf.terminate()"); 329 cf.terminate(); 330 logger.info("theList.terminate()"); 331 theList.terminate(); 332 logger.info("" + pairlist); 333 return G; 334 } 335 336 337 /** 338 * GB distributed client part. 339 * @param host the server runs on. 340 * @param port the server runs. 341 * @param dhtport of the DHT server. 342 * @throws IOException 343 */ 344 public static <C extends RingElem<C>> void clientPart(String host, int port, int dhtport) throws IOException { 345 ChannelFactory cf = new ChannelFactory(port + 10); // != port for localhost 346 cf.init(); 347 logger.info("clientPart connecting to " + host + ", port = " + port + ", dhtport = " + dhtport); 348 SocketChannel pairChannel = cf.getChannel(host, port); 349 350 DistHashTable<Integer, GenPolynomial<C>> theList 351 = new DistHashTable<Integer, GenPolynomial<C>>(host, dhtport); 352 theList.init(); 353 ReducerClientEC<C> R = new ReducerClientEC<C>(pairChannel, theList); 354 355 logger.info("clientPart running on " + host + ", pairChannel = " + pairChannel); 356 R.run(); 357 358 pairChannel.close(); 359 theList.terminate(); 360 cf.terminate(); 361 return; 362 } 363 364 365 /** 366 * Minimal ordered groebner basis. 367 * @param Fp a Groebner base. 368 * @return a reduced Groebner base of Fp. 369 */ 370 @Override 371 public List<GenPolynomial<C>> minimalGB(List<GenPolynomial<C>> Fp) { 372 GenPolynomial<C> a; 373 ArrayList<GenPolynomial<C>> G; 374 G = new ArrayList<GenPolynomial<C>>(Fp.size()); 375 ListIterator<GenPolynomial<C>> it = Fp.listIterator(); 376 while (it.hasNext()) { 377 a = it.next(); 378 if (a.length() != 0) { // always true 379 // already monic a = a.monic(); 380 G.add(a); 381 } 382 } 383 if (G.size() <= 1) { 384 return G; 385 } 386 387 ExpVector e; 388 ExpVector f; 389 GenPolynomial<C> p; 390 ArrayList<GenPolynomial<C>> F; 391 F = new ArrayList<GenPolynomial<C>>(G.size()); 392 boolean mt; 393 394 while (G.size() > 0) { 395 a = G.remove(0); 396 e = a.leadingExpVector(); 397 398 it = G.listIterator(); 399 mt = false; 400 while (it.hasNext() && !mt) { 401 p = it.next(); 402 f = p.leadingExpVector(); 403 mt = e.multipleOf(f); 404 } 405 it = F.listIterator(); 406 while (it.hasNext() && !mt) { 407 p = it.next(); 408 f = p.leadingExpVector(); 409 mt = e.multipleOf(f); 410 } 411 if (!mt) { 412 F.add(a); 413 } else { 414 // System.out.println("dropped " + a.length()); 415 } 416 } 417 G = F; 418 if (G.size() <= 1) { 419 return G; 420 } 421 Collections.reverse(G); // important for lex GB 422 423 MiReducerServerEC<C>[] mirs = (MiReducerServerEC<C>[]) new MiReducerServerEC[G.size()]; 424 int i = 0; 425 F = new ArrayList<GenPolynomial<C>>(G.size()); 426 while (G.size() > 0) { 427 a = G.remove(0); 428 // System.out.println("doing " + a.length()); 429 List<GenPolynomial<C>> R = new ArrayList<GenPolynomial<C>>(G.size() + F.size()); 430 R.addAll(G); 431 R.addAll(F); 432 mirs[i] = new MiReducerServerEC<C>(R, a); 433 pool.addJob(mirs[i]); 434 i++; 435 F.add(a); 436 } 437 G = F; 438 F = new ArrayList<GenPolynomial<C>>(G.size()); 439 for (i = 0; i < mirs.length; i++) { 440 a = mirs[i].getNF(); 441 F.add(a); 442 } 443 return F; 444 } 445 446} 447 448 449/** 450 * Distributed server reducing worker threads. 451 * @param <C> coefficient type 452 */ 453 454class ReducerServerEC<C extends RingElem<C>> implements Runnable { 455 456 457 private final Terminator pool; 458 459 460 private final ChannelFactory cf; 461 462 463 private SocketChannel pairChannel; 464 465 466 private final DistHashTable<Integer, GenPolynomial<C>> theList; 467 468 469 //private List<GenPolynomial<C>> G; 470 private final PairList<C> pairlist; 471 472 473 private static final Logger logger = Logger.getLogger(ReducerServerEC.class); 474 475 476 ReducerServerEC(Terminator fin, ChannelFactory cf, DistHashTable<Integer, GenPolynomial<C>> dl, 477 List<GenPolynomial<C>> G, PairList<C> L) { 478 pool = fin; 479 this.cf = cf; 480 theList = dl; 481 //this.G = G; 482 pairlist = L; 483 } 484 485 486 public void run() { 487 logger.info("reducer server running with " + cf); 488 try { 489 pairChannel = cf.getChannel(); 490 } catch (InterruptedException e) { 491 logger.debug("get pair channel interrupted"); 492 e.printStackTrace(); 493 return; 494 } 495 if (logger.isDebugEnabled()) { 496 logger.debug("pairChannel = " + pairChannel); 497 } 498 Pair<C> pair; 499 //GenPolynomial<C> pi; 500 //GenPolynomial<C> pj; 501 //GenPolynomial<C> S; 502 GenPolynomial<C> H = null; 503 boolean set = false; 504 boolean goon = true; 505 int polIndex = -1; 506 int red = 0; 507 int sleeps = 0; 508 509 // while more requests 510 while (goon) { 511 // receive request 512 logger.info("receive request"); 513 Object req = null; 514 try { 515 req = pairChannel.receive(); 516 } catch (IOException e) { 517 goon = false; 518 e.printStackTrace(); 519 } catch (ClassNotFoundException e) { 520 goon = false; 521 e.printStackTrace(); 522 } 523 //logger.debug("received request, req = " + req); 524 if (req == null) { 525 goon = false; 526 break; 527 } 528 if (!(req instanceof GBTransportMessReq)) { 529 goon = false; 530 break; 531 } 532 533 // find pair 534 logger.debug("find pair"); 535 while (!pairlist.hasNext()) { // wait 536 if (!set) { 537 pool.beIdle(); 538 set = true; 539 } 540 if (!pool.hasJobs() && !pairlist.hasNext()) { 541 goon = false; 542 break; 543 } 544 try { 545 sleeps++; 546 if (sleeps % 10 == 0) { 547 logger.info(" reducer is sleeping"); 548 } 549 Thread.sleep(100); 550 } catch (InterruptedException e) { 551 goon = false; 552 break; 553 } 554 } 555 if (!pairlist.hasNext() && !pool.hasJobs()) { 556 goon = false; 557 break; //continue; //break? 558 } 559 if (set) { 560 set = false; 561 pool.notIdle(); 562 } 563 564 pair = pairlist.removeNext(); 565 /* 566 * send pair to client, receive H 567 */ 568 logger.debug("send pair = " + pair); 569 GBTransportMess msg = null; 570 if (pair != null) { 571 msg = new GBTransportMessPairIndex(pair); // ,pairlist.size()-1); // size-1 572 } else { 573 msg = new GBTransportMess(); // not End(); at this time 574 // goon ?= false; 575 } 576 try { 577 pairChannel.send(msg); 578 } catch (IOException e) { 579 e.printStackTrace(); 580 goon = false; 581 break; 582 } 583 logger.debug("#distributed list = " + theList.size()); 584 Object rh = null; 585 try { 586 rh = pairChannel.receive(); 587 } catch (IOException e) { 588 e.printStackTrace(); 589 goon = false; 590 break; 591 } catch (ClassNotFoundException e) { 592 e.printStackTrace(); 593 goon = false; 594 break; 595 } 596 //logger.debug("received H polynomial"); 597 if (rh == null) { 598 if (pair != null) { 599 pair.setZero(); 600 } 601 } else if (rh instanceof GBTransportMessPoly) { 602 // update pair list 603 red++; 604 H = ((GBTransportMessPoly<C>) rh).pol; 605 if (logger.isDebugEnabled()) { 606 logger.debug("H = " + H); 607 } 608 if (H == null) { 609 if (pair != null) { 610 pair.setZero(); 611 } 612 } else { 613 if (H.isZERO()) { 614 pair.setZero(); 615 } else { 616 if (H.isONE()) { 617 // pool.allIdle(); 618 polIndex = pairlist.putOne(); 619 GenPolynomial<C> nn = theList.put(Integer.valueOf(polIndex), H); 620 if (nn != null) { 621 logger.info("double polynomials nn = " + nn + ", H = " + H); 622 } 623 goon = false; 624 break; 625 } 626 polIndex = pairlist.put(H); 627 // use putWait ? but still not all distributed 628 GenPolynomial<C> nn = theList.put(Integer.valueOf(polIndex), H); 629 if (nn != null) { 630 logger.info("double polynomials nn = " + nn + ", H = " + H); 631 } 632 } 633 } 634 } 635 } 636 logger.info("terminated, done " + red + " reductions"); 637 638 /* 639 * send end mark to client 640 */ 641 logger.debug("send end"); 642 try { 643 pairChannel.send(new GBTransportMessEnd()); 644 } catch (IOException e) { 645 if (logger.isDebugEnabled()) { 646 e.printStackTrace(); 647 } 648 } 649 pool.beIdle(); 650 pairChannel.close(); 651 } 652 653} 654 655 656/** 657 * Distributed clients reducing worker threads. 658 */ 659 660class ReducerClientEC<C extends RingElem<C>> implements Runnable { 661 662 663 private final SocketChannel pairChannel; 664 665 666 private final DistHashTable<Integer, GenPolynomial<C>> theList; 667 668 669 private final ReductionPar<C> red; 670 671 672 private static final Logger logger = Logger.getLogger(ReducerClientEC.class); 673 674 675 ReducerClientEC(SocketChannel pc, DistHashTable<Integer, GenPolynomial<C>> dl) { 676 pairChannel = pc; 677 theList = dl; 678 red = new ReductionPar<C>(); 679 } 680 681 682 public void run() { 683 logger.debug("pairChannel = " + pairChannel + " reducer client running"); 684 Pair<C> pair = null; 685 GenPolynomial<C> pi; 686 GenPolynomial<C> pj; 687 GenPolynomial<C> sp = null; 688 GenPolynomial<C> S; 689 GenPolynomial<C> H = null; 690 //boolean set = false; 691 boolean goon = true; 692 int reduction = 0; 693 //int sleeps = 0; 694 Integer pix; 695 Integer pjx; 696 697 while (goon) { 698 /* protocol: 699 * request pair, process pair, send result 700 */ 701 // pair = (Pair) pairlist.removeNext(); 702 Object req = new GBTransportMessReq(); 703 logger.debug("send request = " + req); 704 H = null; 705 try { 706 pairChannel.send(req); 707 } catch (IOException e) { 708 goon = false; 709 e.printStackTrace(); 710 break; 711 } 712 logger.debug("receive pair, goon = " + goon); 713 Object pp = null; 714 try { 715 pp = pairChannel.receive(); 716 } catch (IOException e) { 717 goon = false; 718 if (logger.isDebugEnabled()) { 719 e.printStackTrace(); 720 } 721 break; 722 } catch (ClassNotFoundException e) { 723 goon = false; 724 e.printStackTrace(); 725 } 726 if (logger.isDebugEnabled()) { 727 logger.debug("received pair = " + pp); 728 } 729 if (pp == null) { // should not happen 730 continue; 731 } 732 if (pp instanceof GBTransportMessEnd) { 733 goon = false; 734 continue; 735 } 736 if (pp instanceof GBTransportMessPair || pp instanceof GBTransportMessPairIndex) { 737 pi = pj = null; 738 if (pp instanceof GBTransportMessPair) { // obsolete, for tests 739 GBTransportMessPair<C> tmp = (GBTransportMessPair<C>) pp; 740 pair = (Pair<C>) tmp.pair; 741 if (pair != null) { 742 pi = pair.pi; 743 pj = pair.pj; 744 //logger.debug("pair: pix = " + pair.i 745 // + ", pjx = " + pair.j); 746 } 747 } 748 if (pp instanceof GBTransportMessPairIndex) { 749 GBTransportMessPairIndex tmpi = (GBTransportMessPairIndex)pp; 750 pix = tmpi.i; 751 pjx = tmpi.j; 752 //Integer sx = tmpi.s; // bug: -1; // last polynomial 753 //sp = theList.getWait(sx); 754 pi = theList.getWait(pix); 755 pj = theList.getWait(pjx); 756 //logger.info("pix = " + pix + ", pjx = " + pjx + ", sx = " + sx); 757 } 758 759 if (pi != null && pj != null) { 760 S = red.SPolynomial(pi, pj); 761 //System.out.println("S = " + S); 762 if (S.isZERO()) { 763 // pair.setZero(); does not work in dist 764 } else { 765 if (logger.isDebugEnabled()) { 766 logger.debug("ht(S) = " + S.leadingExpVector()); 767 } 768 H = red.normalform(theList, S); 769 reduction++; 770 if (H.isZERO()) { 771 // pair.setZero(); does not work in dist 772 } else { 773 H = H.monic(); 774 if (logger.isInfoEnabled()) { 775 logger.info("ht(H) = " + H.leadingExpVector()); 776 } 777 } 778 } 779 } else { 780 logger.info("pi = " + pi + ", pj = " + pj + ", sp = " + sp); 781 } 782 } 783 784 // send H or must send null 785 if (logger.isDebugEnabled()) { 786 logger.debug("#distributed list = " + theList.size()); 787 logger.debug("send H polynomial = " + H); 788 } 789 try { 790 pairChannel.send(new GBTransportMessPoly<C>(H)); 791 } catch (IOException e) { 792 goon = false; 793 e.printStackTrace(); 794 } 795 } 796 logger.info("terminated, done " + reduction + " reductions"); 797 pairChannel.close(); 798 } 799} 800 801 802/** 803 * Distributed server reducing worker threads for minimal GB Not jet distributed 804 * but threaded. 805 */ 806 807class MiReducerServerEC<C extends RingElem<C>> implements Runnable { 808 809 810 private final List<GenPolynomial<C>> G; 811 812 813 private GenPolynomial<C> H; 814 815 816 private final Semaphore done = new Semaphore(0); 817 818 819 private final Reduction<C> red; 820 821 822 private static final Logger logger = Logger.getLogger(MiReducerServer.class); 823 824 825 MiReducerServerEC(List<GenPolynomial<C>> G, GenPolynomial<C> p) { 826 this.G = G; 827 H = p; 828 red = new ReductionPar<C>(); 829 } 830 831 832 /** 833 * getNF. Blocks until the normal form is computed. 834 * @return the computed normal form. 835 */ 836 public GenPolynomial<C> getNF() { 837 try { 838 done.acquire(); //done.P(); 839 } catch (InterruptedException e) { 840 } 841 return H; 842 } 843 844 845 public void run() { 846 if (logger.isDebugEnabled()) { 847 logger.debug("ht(H) = " + H.leadingExpVector()); 848 } 849 H = red.normalform(G, H); //mod 850 done.release(); //done.V(); 851 if (logger.isDebugEnabled()) { 852 logger.debug("ht(H) = " + H.leadingExpVector()); 853 } 854 // H = H.monic(); 855 } 856} 857 858 859/** 860 * Distributed clients reducing worker threads for minimal GB. Not jet used. 861 */ 862 863class MiReducerClientEC<C extends RingElem<C>> implements Runnable { 864 865 866 private final List<GenPolynomial<C>> G; 867 868 869 private GenPolynomial<C> H; 870 871 872 private final Reduction<C> red; 873 874 875 private final Semaphore done = new Semaphore(0); 876 877 878 private static final Logger logger = Logger.getLogger(MiReducerClient.class); 879 880 881 MiReducerClientEC(List<GenPolynomial<C>> G, GenPolynomial<C> p) { 882 this.G = G; 883 H = p; 884 red = new ReductionPar<C>(); 885 } 886 887 888 /** 889 * getNF. Blocks until the normal form is computed. 890 * @return the computed normal form. 891 */ 892 public GenPolynomial<C> getNF() { 893 try { 894 done.acquire(); //done.P(); 895 } catch (InterruptedException u) { 896 Thread.currentThread().interrupt(); 897 } 898 return H; 899 } 900 901 902 public void run() { 903 if (logger.isDebugEnabled()) { 904 logger.debug("ht(S) = " + H.leadingExpVector()); 905 } 906 H = red.normalform(G, H); //mod 907 done.release(); //done.V(); 908 if (logger.isDebugEnabled()) { 909 logger.debug("ht(H) = " + H.leadingExpVector()); 910 } 911 // H = H.monic(); 912 } 913} 914 915 916/** 917 * Objects of this class are to be send to a ExecutableServer. 918 */ 919 920class GBExerClient<C extends RingElem<C>> implements RemoteExecutable { 921 922 923 String host; 924 925 926 int port; 927 928 929 int dhtport; 930 931 932 /** 933 * GBExerClient. 934 * @param host 935 * @param port 936 * @param dhtport 937 */ 938 public GBExerClient(String host, int port, int dhtport) { 939 this.host = host; 940 this.port = port; 941 this.dhtport = dhtport; 942 } 943 944 945 /** 946 * run. 947 */ 948 public void run() { 949 //System.out.println("running " + this); 950 try { 951 GroebnerBaseDistributedEC. <C>clientPart(host,port,dhtport); 952 } catch (Exception e) { 953 e.printStackTrace(); 954 } 955 } 956 957 958 /** 959 * String representation. 960 */ 961 @Override 962 public String toString() { 963 StringBuffer s = new StringBuffer("GBExerClient("); 964 s.append("host="+host); 965 s.append(", port="+port); 966 s.append(", dhtport="+dhtport); 967 s.append(")"); 968 return s.toString(); 969 } 970 971}