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