001/*
002 * $Id: SGBProxy.java 5102 2015-02-07 11:03:52Z 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.GenSolvablePolynomial;
019import edu.jas.structure.GcdRingElem;
020
021
022/**
023 * Groebner bases parallel proxy.
024 * @author Heinz Kredel
025 */
026
027public class SGBProxy<C extends GcdRingElem<C>> extends SolvableGroebnerBaseAbstract<C> {
028
029
030    private static final Logger logger = Logger.getLogger(SGBProxy.class);
031
032
033    private final boolean debug = logger.isDebugEnabled(); //logger.isInfoEnabled();
034
035
036    /**
037     * GB engines.
038     */
039    public final SolvableGroebnerBaseAbstract<C> e1;
040
041
042    public final SolvableGroebnerBaseAbstract<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 SGBProxy(SolvableGroebnerBaseAbstract<C> e1, SolvableGroebnerBaseAbstract<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 "SGBProxy[ " + 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<GenSolvablePolynomial<C>> leftGB(final int modv, final List<GenSolvablePolynomial<C>> F) {
103        if (F == null || F.isEmpty()) {
104            return F;
105        }
106        // parallel case
107        List<GenSolvablePolynomial<C>> G = null;
108        List<Callable<List<GenSolvablePolynomial<C>>>> cs = new ArrayList<Callable<List<GenSolvablePolynomial<C>>>>(
109                        2);
110        cs.add(new Callable<List<GenSolvablePolynomial<C>>>() {
111
112
113            public List<GenSolvablePolynomial<C>> call() {
114                try {
115                    //System.out.println("starting e1 " + e1.getClass().getName());
116                    List<GenSolvablePolynomial<C>> G = e1.leftGB(modv, F);
117                    if (debug) {
118                        logger.info("SGBProxy done e1 " + e1.getClass().getName());
119                    }
120                    return G;
121                } catch (PreemptingException e) {
122                    throw new RuntimeException("SGBProxy e1 preempted " + e);
123                    //return P.ring.getONE();
124                } catch (Exception e) {
125                    //e.printStackTrace();
126                    logger.info("SGBProxy e1 " + e);
127                    logger.info("Exception SGBProxy F = " + F);
128                    throw new RuntimeException("SGBProxy e1 " + e);
129                    //return P.ring.getONE();
130                }
131            }
132        });
133        cs.add(new Callable<List<GenSolvablePolynomial<C>>>() {
134
135
136            public List<GenSolvablePolynomial<C>> call() {
137                try {
138                    //System.out.println("starting e2 " + e2.getClass().getName());
139                    List<GenSolvablePolynomial<C>> G = e2.leftGB(modv, F);
140                    if (debug) {
141                        logger.info("SGBProxy done e2 " + e2.getClass().getName());
142                    }
143                    return G;
144                } catch (PreemptingException e) {
145                    throw new RuntimeException("SGBProxy e2 preempted " + e);
146                    //return P.ring.getONE();
147                } catch (Exception e) {
148                    //e.printStackTrace();
149                    logger.info("SGBProxy e2 " + e);
150                    logger.info("Exception SGBProxy F = " + F);
151                    throw new RuntimeException("SGBProxy e2 " + e);
152                    //return P.ring.getONE();
153                }
154            }
155        });
156        try {
157            G = pool.invokeAny(cs);
158        } catch (InterruptedException ignored) {
159            logger.info("InterruptedException " + ignored);
160            Thread.currentThread().interrupt();
161        } catch (ExecutionException e) {
162            logger.info("ExecutionException " + e);
163            Thread.currentThread().interrupt();
164        }
165        return G;
166    }
167
168
169    /**
170     * Right Groebner base.
171     * @param modv module variable number.
172     * @param F polynomial list.
173     * @return rightGB(F) a Groebner base of F.
174     */
175    @Override
176    public List<GenSolvablePolynomial<C>> rightGB(final int modv, final List<GenSolvablePolynomial<C>> F) {
177        if (F == null || F.isEmpty()) {
178            return F;
179        }
180        // parallel case
181        List<GenSolvablePolynomial<C>> G = null;
182        List<Callable<List<GenSolvablePolynomial<C>>>> cs = new ArrayList<Callable<List<GenSolvablePolynomial<C>>>>(
183                        2);
184        cs.add(new Callable<List<GenSolvablePolynomial<C>>>() {
185
186
187            public List<GenSolvablePolynomial<C>> call() {
188                try {
189                    //System.out.println("starting e1 " + e1.getClass().getName());
190                    List<GenSolvablePolynomial<C>> G = e1.rightGB(modv, F);
191                    if (debug) {
192                        logger.info("SGBProxy done e1 " + e1.getClass().getName());
193                    }
194                    return G;
195                } catch (PreemptingException e) {
196                    throw new RuntimeException("SGBProxy e1 preempted " + e);
197                    //return P.ring.getONE();
198                } catch (Exception e) {
199                    //e.printStackTrace();
200                    logger.info("SGBProxy e1 " + e);
201                    logger.info("Exception SGBProxy F = " + F);
202                    throw new RuntimeException("SGBProxy e1 " + e);
203                    //return P.ring.getONE();
204                }
205            }
206        });
207        cs.add(new Callable<List<GenSolvablePolynomial<C>>>() {
208
209
210            public List<GenSolvablePolynomial<C>> call() {
211                try {
212                    //System.out.println("starting e2 " + e2.getClass().getName());
213                    List<GenSolvablePolynomial<C>> G = e2.rightGB(modv, F);
214                    if (debug) {
215                        logger.info("SGBProxy done e2 " + e2.getClass().getName());
216                    }
217                    return G;
218                } catch (PreemptingException e) {
219                    throw new RuntimeException("SGBProxy e2 preempted " + e);
220                    //return P.ring.getONE();
221                } catch (Exception e) {
222                    //e.printStackTrace();
223                    logger.info("SGBProxy e2 " + e);
224                    logger.info("Exception SGBProxy F = " + F);
225                    throw new RuntimeException("SGBProxy e2 " + e);
226                    //return P.ring.getONE();
227                }
228            }
229        });
230        try {
231            G = pool.invokeAny(cs);
232        } catch (InterruptedException ignored) {
233            logger.info("InterruptedException " + ignored);
234            Thread.currentThread().interrupt();
235        } catch (ExecutionException e) {
236            logger.info("ExecutionException " + e);
237            Thread.currentThread().interrupt();
238        }
239        return G;
240    }
241
242
243    /**
244     * Groebner base.
245     * @param modv module variable number.
246     * @param F polynomial list.
247     * @return twosidedGB(F) a Groebner base of F.
248     */
249    @Override
250    public List<GenSolvablePolynomial<C>> twosidedGB(final int modv, final List<GenSolvablePolynomial<C>> F) {
251        if (F == null || F.isEmpty()) {
252            return F;
253        }
254        // parallel case
255        List<GenSolvablePolynomial<C>> G = null;
256        List<Callable<List<GenSolvablePolynomial<C>>>> cs = new ArrayList<Callable<List<GenSolvablePolynomial<C>>>>(
257                        2);
258        cs.add(new Callable<List<GenSolvablePolynomial<C>>>() {
259
260
261            public List<GenSolvablePolynomial<C>> call() {
262                try {
263                    //System.out.println("starting e1 " + e1.getClass().getName());
264                    List<GenSolvablePolynomial<C>> G = e1.twosidedGB(modv, F);
265                    if (debug) {
266                        logger.info("SGBProxy done e1 " + e1.getClass().getName());
267                    }
268                    return G;
269                } catch (PreemptingException e) {
270                    throw new RuntimeException("SGBProxy e1 preempted " + e);
271                    //return P.ring.getONE();
272                } catch (Exception e) {
273                    //e.printStackTrace();
274                    logger.info("SGBProxy e1 " + e);
275                    logger.info("Exception SGBProxy F = " + F);
276                    throw new RuntimeException("SGBProxy e1 " + e);
277                    //return P.ring.getONE();
278                }
279            }
280        });
281        cs.add(new Callable<List<GenSolvablePolynomial<C>>>() {
282
283
284            public List<GenSolvablePolynomial<C>> call() {
285                try {
286                    //System.out.println("starting e2 " + e2.getClass().getName());
287                    List<GenSolvablePolynomial<C>> G = e2.twosidedGB(modv, F);
288                    if (debug) {
289                        logger.info("SGBProxy done e2 " + e2.getClass().getName());
290                    }
291                    return G;
292                } catch (PreemptingException e) {
293                    throw new RuntimeException("SGBProxy e2 preempted " + e);
294                    //return P.ring.getONE();
295                } catch (Exception e) {
296                    //e.printStackTrace();
297                    logger.info("SGBProxy e2 " + e);
298                    logger.info("Exception SGBProxy F = " + F);
299                    throw new RuntimeException("SGBProxy e2 " + e);
300                    //return P.ring.getONE();
301                }
302            }
303        });
304        try {
305            G = pool.invokeAny(cs);
306        } catch (InterruptedException ignored) {
307            logger.info("InterruptedException " + ignored);
308            Thread.currentThread().interrupt();
309        } catch (ExecutionException e) {
310            logger.info("ExecutionException " + e);
311            Thread.currentThread().interrupt();
312        }
313        return G;
314    }
315
316}