[Cython] cython.parallel tasks, single, master, critical, barriers

mark florisson markflorisson88 at gmail.com
Wed Oct 12 16:00:13 CEST 2011


On 12 October 2011 10:20, Robert Bradshaw <robertwb at math.washington.edu> wrote:
> On Wed, Oct 12, 2011 at 1:49 AM, Dag Sverre Seljebotn
> <d.s.seljebotn at astro.uio.no> wrote:
>> On 10/12/2011 10:36 AM, Dag Sverre Seljebotn wrote:
>>>
>>> On 10/12/2011 09:55 AM, Robert Bradshaw wrote:
>>>>
>>>> On Sun, Oct 9, 2011 at 5:57 AM, Dag Sverre Seljebotn
>>>> <d.s.seljebotn at astro.uio.no> wrote:
>>>>>
>>>>> On 10/09/2011 02:18 PM, Dag Sverre Seljebotn wrote:
>>>>>>
>>>>>> On 10/09/2011 02:11 PM, mark florisson wrote:
>>>>>>>
>>>>>>> with parallel.critical():
>>>>>>> this section of code is mutually exclusive with other critical
>>>>>>> sections
>>>>>>> optional keyword argument 'name' specifies a name for the critical
>>>>>>> section,
>>>>>>> which means all sections with that name will exclude each other,
>>>>>>> but not
>>>>>>> critical sections with different names
>>>>>>>
>>>>>>> Note: all threads that encounter the section will execute it, just
>>>>>>> not at the same time
>>>>>
>>
>> On critical sections, I do feel string naming is rather un-Pythonic. I'd
>> rather have
>>
>> lock_a = parallel.Mutex()
>> lock_b = parallel.Mutex()
>> with cython.parallel:
>>    with lock_a:
>>        ...
>>    with lock_b:
>>        ...
>>
>> This maps well to pthread mutexes, though much harder to map it to OpenMP...
>
> For this low level, perhaps people should just be using the pthreads
> library directly? Here I'm showing my ignorance: can that work with
> OpenMP spawned threads? (Maybe a compatibility layer is required for
> transparent Windows support.) Suppose one could write a context object
> that did not require the GIL, then one could do
>
> with MyContext():
>   ...
>
> in a nogil block, MyContext could be implemented by whoever on
> whatever thread library, no special language support required.

Exactly, that's always possible. I myself very much like how critical
works, but if you want a more Pythonic-looking mutex, it might be
better to make that the user's burden. Otherwise we'd also have to
give it a type, make it compatible with code that doesn't have the
GIL, acquisition count it when passing it around, etc.

If your program doesn't even have other Python threads running, you
could even use 'with gil:' as a global synchronization.

The only good thing about named and unnamed critical sections is
really the convenience of writing it, and the resulting conciseness
(which imho, if you know how critical works, only adds to the code
readability).

However, not providing parallel.Mutex would mean people probably want
to resort to the goodies from the threading module, which would
ironically not be impossible because you'd need to GIL to use them :)
But we could recommend the PyThread_*_lock stuff in the documentation.

>> So my proposal is:
>>
>>  a) parallel.Mutex() can take a string argument and then returns the same
>> mutex each time for the same string, meaning you can do
>>
>> with parallel.Mutex("somename"):
>>
>> which maps directly to OpenMP.
>>
>>  b) However, this does not make sense:
>>
>> with parallel.Mutex():
>>
>> because each thread would instantiate a *seperate* mutex. So raise compiler
>> error ("Redundant code, thread will never block on fresh mutex")
>>
>>  c) However, one can use a default global Mutex instance:
>>
>> with parallel.global_mutex
>>
>> (mapping to an un-named critical in OpenMP)
>>
>> This seems to be simple enough to implement, and allows generalizing to the
>> advanced case above later (probably using pthreads/Windows directly).
>
> Alternatively, let parallel.Mutex() be the global mutex, with some
> other way of getting a new, unique mutex to pass around and use in
> multiple places.
>
> - Robert
> _______________________________________________
> cython-devel mailing list
> cython-devel at python.org
> http://mail.python.org/mailman/listinfo/cython-devel
>


More information about the cython-devel mailing list