001/*
002 * $Id: GBProxy.java 4289 2012-11-04 14:29:36Z kredel $
003 */
004
005package edu.jas.gb;
006
007
008import java.util.ArrayList;
009import java.util.List;
010import java.util.concurrent.Callable;
011import java.util.concurrent.ExecutionException;
012import java.util.concurrent.ExecutorService;
013
014import org.apache.log4j.Logger;
015
016import edu.jas.kern.ComputerThreads;
017import edu.jas.kern.PreemptingException;
018import edu.jas.poly.GenPolynomial;
019import edu.jas.structure.GcdRingElem;
020
021
022/**
023 * Groebner bases parallel proxy.
024 * @author Heinz Kredel
025 */
026
027public 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 transient ExecutorService pool;
049
050
051    /**
052     * Proxy constructor.
053     * @param e1 Groebner base engine.
054     * @param e2 Groebner base engine.
055     */
056    public GBProxy(GroebnerBaseAbstract<C> e1, GroebnerBaseAbstract<C> e2) {
057        this.e1 = e1;
058        this.e2 = e2;
059        pool = ComputerThreads.getPool();
060        //System.out.println("pool 2 = "+pool);
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.toString() + ", " + e2.toString() + " ]";
071    }
072
073
074    /**
075     * Cleanup and terminate ThreadPool.
076     */
077    @Override
078    public void terminate() {
079        e1.terminate();
080        e2.terminate();
081    }
082
083
084    /**
085     * Cancel ThreadPool.
086     */
087    @Override
088    public int cancel() {
089        int s = e1.cancel();
090        s += e2.cancel();
091        return s;
092    }
093
094
095    /**
096     * Groebner base.
097     * @param modv module variable number.
098     * @param F polynomial list.
099     * @return GB(F) a Groebner base of F.
100     */
101    //JAVA6only: @Override
102    public List<GenPolynomial<C>> GB( final int modv, final List<GenPolynomial<C>> F ) {
103        if (F == null || F.isEmpty()) {
104            return F;
105        }
106        // parallel case
107        List<GenPolynomial<C>> G = null;
108        List<Callable<List<GenPolynomial<C>>>> cs = new ArrayList<Callable<List<GenPolynomial<C>>>>(2);
109        cs.add(new Callable<List<GenPolynomial<C>>>() {
110            public List<GenPolynomial<C>> call() {
111                try {
112                    //System.out.println("starting e1 " + e1.getClass().getName());
113                    List<GenPolynomial<C>> G = e1.GB(modv,F);
114                    if (debug) {
115                        logger.info("GBProxy done e1 " + e1.getClass().getName());
116                    }
117                    return G;
118                } catch (PreemptingException e) {
119                    throw new RuntimeException("GBProxy e1 preempted " + e);
120                    //return P.ring.getONE();
121                } catch (Exception e) {
122                    //e.printStackTrace();
123                    logger.info("GBProxy e1 " + e);
124                    logger.info("Exception GBProxy F = " + F);
125                    throw new RuntimeException("GBProxy e1 " + e);
126                    //return P.ring.getONE();
127                }
128            }
129        });
130        cs.add(new Callable<List<GenPolynomial<C>>>() {
131            public List<GenPolynomial<C>> call() {
132                try {
133                    //System.out.println("starting e2 " + e2.getClass().getName());
134                    List<GenPolynomial<C>> G = e2.GB(modv,F);
135                    if (debug) {
136                        logger.info("GBProxy done e2 " + e2.getClass().getName());
137                    }
138                    return G;
139                } catch (PreemptingException e) {
140                    throw new RuntimeException("GBProxy e2 preempted " + e);
141                    //return P.ring.getONE();
142                } catch (Exception e) {
143                    //e.printStackTrace();
144                    logger.info("GBProxy e2 " + e);
145                    logger.info("Exception GBProxy F = " + F);
146                    throw new RuntimeException("GBProxy e2 " + e);
147                    //return P.ring.getONE();
148                }
149            }
150        });
151        try {
152            G = pool.invokeAny(cs);
153        } catch (InterruptedException ignored) {
154            logger.info("InterruptedException " + ignored);
155            Thread.currentThread().interrupt();
156        } catch (ExecutionException e) {
157            logger.info("ExecutionException " + e);
158            Thread.currentThread().interrupt();
159        }
160        return G;
161    }
162
163}