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