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