001    /*
002     * $Id: GBProxy.java 3211 2010-07-05 12:54:22Z kredel $
003     */
004    
005    package edu.jas.gb;
006    
007    
008    import java.util.ArrayList;
009    import java.util.List;
010    import java.util.concurrent.Callable;
011    import java.util.concurrent.ExecutionException;
012    import java.util.concurrent.ExecutorService;
013    
014    import org.apache.log4j.Logger;
015    
016    import edu.jas.kern.ComputerThreads;
017    import edu.jas.kern.PreemptingException;
018    import edu.jas.poly.GenPolynomial;
019    import edu.jas.structure.GcdRingElem;
020    
021    
022    /**
023     * Groebner bases parallel proxy.
024     * @author Heinz Kredel
025     */
026    
027    public class GBProxy<C extends GcdRingElem<C>> extends GroebnerBaseAbstract<C> {
028    
029    
030        private static final Logger logger = Logger.getLogger(GBProxy.class);
031    
032    
033        private final boolean debug = logger.isDebugEnabled(); //logger.isInfoEnabled();
034    
035    
036        /**
037         * GB engines.
038         */
039        public final GroebnerBaseAbstract<C> e1;
040    
041    
042        public final GroebnerBaseAbstract<C> e2;
043    
044    
045        /**
046         * Thread pool.
047         */
048        protected ExecutorService pool;
049    
050    
051        /**
052         * Proxy constructor.
053         */
054        public GBProxy(GroebnerBaseAbstract<C> e1, GroebnerBaseAbstract<C> e2) {
055            this.e1 = e1;
056            this.e2 = e2;
057            if (pool == null) {
058                pool = ComputerThreads.getPool();
059                //System.out.println("pool 2 = "+pool);
060            }
061        }
062    
063    
064        /**
065         * Get the String representation with GB engines.
066         * @see java.lang.Object#toString()
067         */
068        @Override
069        public String toString() {
070            return "GBProxy[ " + e1.getClass().getName() + ", " + e2.getClass().getName() + " ]";
071        }
072    
073    
074        /**
075         * Cleanup and terminate ThreadPool.
076         */
077        public void terminate() {
078            e1.terminate();
079            e2.terminate();
080        }
081    
082    
083        /**
084         * Cancel ThreadPool.
085         */
086        public int cancel() {
087            int s = e1.cancel();
088            s += e2.cancel();
089            return s;
090        }
091    
092    
093        /**
094         * Groebner base.
095         * @param modv module variable number.
096         * @param F polynomial list.
097         * @return GB(F) a Groebner base of F.
098         */
099        //JAVA6only: @Override
100        public List<GenPolynomial<C>> GB( final int modv, final List<GenPolynomial<C>> F ) {
101            if (F == null || F.isEmpty()) {
102                return F;
103            }
104            // parallel case
105            List<GenPolynomial<C>> G = null;
106            List<Callable<List<GenPolynomial<C>>>> cs = new ArrayList<Callable<List<GenPolynomial<C>>>>(2);
107            cs.add(new Callable<List<GenPolynomial<C>>>() {
108                public List<GenPolynomial<C>> call() {
109                    try {
110                        //System.out.println("starting e1 " + e1.getClass().getName());
111                        List<GenPolynomial<C>> G = e1.GB(modv,F);
112                        if (debug) {
113                            logger.info("GBProxy done e1 " + e1.getClass().getName());
114                        }
115                        return G;
116                    } catch (PreemptingException e) {
117                        throw new RuntimeException("GBProxy e1 preempted " + e);
118                        //return P.ring.getONE();
119                    } catch (Exception e) {
120                        //e.printStackTrace();
121                        logger.info("GBProxy e1 " + e);
122                        logger.info("Exception GBProxy F = " + F);
123                        throw new RuntimeException("GBProxy e1 " + e);
124                        //return P.ring.getONE();
125                    }
126                }
127            });
128            cs.add(new Callable<List<GenPolynomial<C>>>() {
129                public List<GenPolynomial<C>> call() {
130                    try {
131                        //System.out.println("starting e2 " + e2.getClass().getName());
132                        List<GenPolynomial<C>> G = e2.GB(modv,F);
133                        if (debug) {
134                            logger.info("GBProxy done e2 " + e2.getClass().getName());
135                        }
136                        return G;
137                    } catch (PreemptingException e) {
138                        throw new RuntimeException("GBProxy e2 preempted " + e);
139                        //return P.ring.getONE();
140                    } catch (Exception e) {
141                        //e.printStackTrace();
142                        logger.info("GBProxy e2 " + e);
143                        logger.info("Exception GBProxy F = " + F);
144                        throw new RuntimeException("GBProxy e2 " + e);
145                        //return P.ring.getONE();
146                    }
147                }
148            });
149            try {
150                G = pool.invokeAny(cs);
151            } catch (InterruptedException ignored) {
152                logger.info("InterruptedException " + ignored);
153                Thread.currentThread().interrupt();
154            } catch (ExecutionException e) {
155                logger.info("ExecutionException " + e);
156                Thread.currentThread().interrupt();
157            }
158            return G;
159        }
160    
161    }