next | previous | forward | backward | up | top | index | toc | Macaulay2 web site
Macaulay2Doc > The Macaulay2 language > parallel programming with threads and tasks

parallel programming with threads and tasks

The task system schedules functions and inputs to run on a preset number of threads. The number of threads to be used is given by the variable allowableThreads, and may be examined and changed as follows.

i1 : allowableThreads

o1 = 2
i2 : allowableThreads = 8

o2 = 8

To run a function in another thread use schedule, as in the following example.

i3 : R = ZZ/101[x,y,z];
i4 : I = (ideal vars R)^2

             2             2        2
o4 = ideal (x , x*y, x*z, y , y*z, z )

o4 : Ideal of R
i5 : dogb = I -> () -> res quotient module I

o5 = dogb

o5 : FunctionClosure
i6 : f = dogb I

o6 = f

o6 : FunctionClosure
i7 : t = schedule f

o7 = <<task, result available, task done>>

o7 : Task

Note that schedule returns a task, not the result of the computation, which will be accessible only after the task has completed the computation.

i8 : t

o8 = <<task, result available, task done>>

o8 : Task

Use isReady to check whether the result is available yet.

i9 : isReady t

o9 = true
i10 : while not isReady t do sleep 1

To retrieve the result, use taskResult.

i11 : taskResult t

       1      6      8      3
o11 = R  <-- R  <-- R  <-- R  <-- 0
                                   
      0      1      2      3      4

o11 : ChainComplex
i12 : assert instance(oo,ChainComplex)

It is possible to make a task without starting it running, using createTask.

i13 : t' = createTask f

o13 = <<task, created>>

o13 : Task
i14 : t'

o14 = <<task, created>>

o14 : Task

Start it running with schedule.

i15 : schedule t';
i16 : t'

o16 = <<task, result available, task done>>

o16 : Task
i17 : while not isReady t' do sleep 1
i18 : taskResult t'

       1      6      8      3
o18 = R  <-- R  <-- R  <-- R  <-- 0
                                   
      0      1      2      3      4

o18 : ChainComplex

One may use addStartTask to specify that one task is to be started after another one finishes. In the following example, G will start after F finishes.

i19 : F = createTask(() -> "result of F")

o19 = <<task, created>>

o19 : Task
i20 : G = createTask(() -> "result of G")

o20 = <<task, created>>

o20 : Task
i21 : addStartTask(F,G)
i22 : schedule F

o22 = <<task, result available, task done>>

o22 : Task
i23 : while not isReady F do sleep 1
i24 : taskResult F

o24 = result of F
i25 : while not isReady G do sleep 1
i26 : taskResult G

o26 = result of G

Use addCancelTask to specify that the completion of one task triggers the cancellation of another, by means of an interrupt exception.

Use addDependencyTask to schedule a task, but to ensure that it will not run until one or more other tasks finish running.

Using the functions above, essentially any parallel functionality needed can be created.

Low level C API functionality using the same scheduler also exists in the Macaulay2/system directory. It works essentially the same way as the Macaulay2 interface.

Warning: Access to external libraries such as singular, etc., may not currently be thread safe.

Menu