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 }