001/*
002 * $Id: GBProxy.java 5104 2015-02-07 13:12:43Z 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    @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
111
112            public List<GenPolynomial<C>> call() {
113                try {
114                    //System.out.println("starting e1 " + e1.getClass().getName());
115                    List<GenPolynomial<C>> G = e1.GB(modv, F);
116                    if (debug) {
117                        logger.info("GBProxy done e1 " + e1.getClass().getName());
118                    }
119                    return G;
120                } catch (PreemptingException e) {
121                    throw new RuntimeException("GBProxy e1 preempted " + e);
122                    //return P.ring.getONE();
123                } catch (Exception e) {
124                    //e.printStackTrace();
125                    logger.info("GBProxy e1 " + e);
126                    logger.info("Exception GBProxy F = " + F);
127                    throw new RuntimeException("GBProxy e1 " + e);
128                    //return P.ring.getONE();
129                }
130            }
131        });
132        cs.add(new Callable<List<GenPolynomial<C>>>() {
133
134
135            public List<GenPolynomial<C>> call() {
136                try {
137                    //System.out.println("starting e2 " + e2.getClass().getName());
138                    List<GenPolynomial<C>> G = e2.GB(modv, F);
139                    if (debug) {
140                        logger.info("GBProxy done e2 " + e2.getClass().getName());
141                    }
142                    return G;
143                } catch (PreemptingException e) {
144                    throw new RuntimeException("GBProxy e2 preempted " + e);
145                    //return P.ring.getONE();
146                } catch (Exception e) {
147                    //e.printStackTrace();
148                    logger.info("GBProxy e2 " + e);
149                    logger.info("Exception GBProxy F = " + F);
150                    throw new RuntimeException("GBProxy e2 " + e);
151                    //return P.ring.getONE();
152                }
153            }
154        });
155        try {
156            G = pool.invokeAny(cs);
157        } catch (InterruptedException ignored) {
158            logger.info("InterruptedException " + ignored);
159            Thread.currentThread().interrupt();
160        } catch (ExecutionException e) {
161            logger.info("ExecutionException " + e);
162            Thread.currentThread().interrupt();
163        }
164        return G;
165    }
166
167}