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, running>>
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, running>>
o8 : Task
|
Use
isReady to check whether the result is available yet.
i9 : isReady t
o9 = false
|
i10 : while not isReady t do sleep 1
|
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
|
i15 : schedule t';
|
i16 : t'
o16 = <<task, created>>
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, running>>
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.