Ask Your Question
0

Can't thread with permutation groups?

asked 2012-08-24 12:12:10 -0600

Martin Malandro gravatar image

I'm having trouble running threads involving permutation groups. Here is a small example that shows the issue on Sage 5.2 (and also Sage 4.8).

import time
from threading import Thread

class f(Thread):
    def __init__(self,val):
        Thread.__init__(self)
        self.val=val
    def run(self):
        G=CyclicPermutationGroup(self.val)
        print 'here'
        print G

a=f(4)
b=f(4)
a.start()
b.start()
a.join()
b.join()

The "here"s print but then the worksheet (usually) just keeps running without doing anything and refuses to be interrupted, or (sometimes) crashes and offers error messages such as

Exception in thread Thread-2:
Traceback (most recent call last):
  File "/sagenb/sage_install/sage-5.2-sage.math.washington.edu-x86_64-Linux/local/lib/python/threading.py", line 551, in __bootstrap_inner
    self.run()
  File "/tmp/tmp4JA7Av/___code___.py", line 14, in run
    print G
  File "sage_object.pyx", line 154, in sage.structure.sage_object.SageObject.__repr__ (sage/structure/sage_object.c:1753)
  File "/sagenb/sage_install/sage-5.2-sage.math.washington.edu-x86_64-Linux/local/lib/python2.7/site-packages/sage/groups/perm_gps/permgroup_named.py", line 436, in _repr_
    return "Cyclic group of order %s as a permutation group"%self.order()
  File "/sagenb/sage_install/sage-5.2-sage.math.washington.edu-x86_64-Linux/local/lib/python2.7/site-packages/sage/groups/perm_gps/permgroup.py", line 1400, in order
    if not self.gens() or self.gens() == [self(1)]:
  File "/sagenb/sage_install/sage-5.2-sage.math.washington.edu-x86_64-Linux/local/lib/python2.7/site-packages/sage/groups/perm_gps/permgroup.py", line 646, in __call__
    return self.identity()
  File "/sagenb/sage_install/sage-5.2-sage.math.washington.edu-x86_64-Linux/local/lib/python2.7/site-packages/sage/groups/perm_gps/permgroup.py", line 902, in identity
    return self._element_class()([], self, check=True)
  File "permgroup_element.pyx", line 452, in sage.groups.perm_gps.permgroup_element.PermutationGroupElement.__init__ (sage/groups/perm_gps permgroup_element.c:4337)
  File "sage_object.pyx", line 463, in sage.structure.sage_object.SageObject._gap_ (sage/structure/sage_object.c:4518)
  File "sage_object.pyx", line 439, in sage.structure.sage_object.SageObject._interface_ (sage/structure/sage_object.c:4118)
  File "/sagenb/sage_install/sage-5.2-sage.math.washington.edu-x86_64-Linux/local/lib/python2.7/site-packages/sage/interfaces/interface.py", line 198, in __call__
    return cls(self, x, name=name)
  File "/sagenb/sage_install/sage-5.2-sage.math.washington.edu-x86_64-Linux/local/lib/python2.7/site-packages/sage/interfaces/expect.py", line 1328, in __init__
    raise TypeError, x
TypeError: Gap produced error output
Syntax error: ; expected
$sage2:=Group([PermList([2, 3, 4, 1])]);;
 ^

   executing $sage2:=Group([PermList([2, 3, 4, 1])]);;

I've gotten other error messages as well, but nothing I can reliably reproduce.

If you delete the start and join lines for a or b in the code, it runs fine, of course.

Any ideas here? In case you're curious, the reason I'm trying to thread is this. I have a bunch of problems that can be solved by either of two different methods. For any given problem, one method is usually much faster than the other, but it's difficult to predict in advance which one will be the faster one, so for a given problem I'd like ... (more)

edit retag flag offensive close merge delete

Comments

I don't understand the error message, but keep in mind that the permutation groups use GAP under the hood, and maybe we haven't connected our threading with any threading it might have - do we spawn multiple GAP sessions in this case?

kcrisman gravatar imagekcrisman ( 2012-08-27 03:32:40 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
1

answered 2012-08-27 22:54:26 -0600

Mike Hansen gravatar image

The problem is that the GAP interface is not threadsafe -- both threads are accessing the same GAP session. You could use the @parallel decorator and forking (which has a bit of overhead). For example,

def method_1(n):
    import time
    time.sleep(20)
    return 1, Integer(gap(n)*n)

def method_2(n):
    return 2, Integer(gap(n)*n)

def try_fast(n):
    @parallel
    def try_method(method):
        return method(n)

    method_num, result = try_method([method_1, method_2]).next()[1]
    print "Computed by method %s"%method_num
    return result

The result of the (decorated) try_method function is an iterator which will yield the results as soon as they are ready. In this case, we just need the first one.

 sage: %time try_fast(4)
 Killing any remaining workers...
 Computed by method 2
 CPU times: user 0.00 s, sys: 0.02 s, total: 0.02 s
 Wall time: 0.27 s
 16
edit flag offensive delete link more

Comments

This works, but when I run it in a loop I get the "Killing any remaining workers" message each time try_fast runs. If I go this route, can I expect Sage to kill the slower workers stably in general?

Martin Malandro gravatar imageMartin Malandro ( 2012-08-28 16:03:08 -0600 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

Stats

Asked: 2012-08-24 12:12:10 -0600

Seen: 211 times

Last updated: Aug 27 '12