source: git/Singular/LIB/parallel.lib @ dc8c23

spielwiese
Last change on this file since dc8c23 was dc8c23, checked in by Andreas Steenpass <steenpass@…>, 10 years ago
chg: base parallel.lib on tasks.lib (cherry picked from commit 0cbbf3c2c18164653d67edfd8628967b92fa77cc) Signed-off-by: Andreas Steenpass <steenpass@mathematik.uni-kl.de> Conflicts: Singular/LIB/parallel.lib
  • Property mode set to 100644
File size: 10.7 KB
RevLine 
[dc8c23]1////////////////////////////////////////////////////////////////////
2version="version parallel.lib 4.0.0.0 Dec_2013 "; // $Id$
[5f0de8]3category="General purpose";
4info="
[dc8c23]5LIBRARY:   parallel.lib  An abstraction layer for parallel skeletons
6
[5f0de8]7AUTHOR:    Andreas Steenpass, e-mail: steenpass@mathematik.uni-kl.de
8
[e1b841]9OVERVIEW:
[dc8c23]10This library provides implementations of several parallel 'skeletons' (i.e.
11ways in which parallel tasks rely upon and interact with each other). It is
12based on the library tasks.lib and aims at both ordinary Singular users as well
13as authors of Singular libraries.
[e1b841]14
[dc8c23]15KEYWORDS:  parallelization; parallel skeletons; distributed computing
[5f0de8]16
[dc8c23]17SEE ALSO:  resources_lib, tasks_lib, modstd_lib, modnormal_lib
[5f0de8]18
19PROCEDURES:
[dc8c23]20  parallelWaitN();      execute several jobs in parallel
21                        and wait for N of them to finish
22  parallelWaitFirst();  execute several jobs in parallel
23                        and wait for the first to finish
24  parallelWaitAll();    execute several jobs in parallel
25                        and wait for all of them to finish
26  parallelTestAND();    run several tests in parallel
27                        and determine if they all succeed
28  parallelTestOR();     run several tests in parallel
29                        and determine if any of them succeeds
[5f0de8]30";
31
[dc8c23]32LIB "tasks.lib";
[e1b841]33
[dc8c23]34proc parallelWaitN(alias list commands, alias list args, int N, list #)
35"USAGE:   parallelWaitN(commands, arguments, N[, timeout]); commands list,
36          arguments list, N int, timeout int
37RETURN:   a list, containing the results of commands[i] applied to
38          arguments[i], i = 1, ..., size(arguments).
39       @* The procedure waits for N jobs to finish.
40       @* An optional timeout in ms can be provided. Default is 0 which
41          disables the timeout.
42NOTE:     The entries of the list commands must be strings. The entries of the
43          list arguments must be lists.
44       @* The type of any entry of the returned list whose corresponding task
45          did not finish (due to timeout or error) is \"none\".
46       @* The returned list may contain more than N results if several jobs
47          finished \"at the same time\". It may contain less than N results in
48          the case of timeout or errors occurring.
49SEE ALSO: parallelWaitAll, parallelWaitFirst, tasks_lib
50EXAMPLE:  example parallelWaitN; shows an example"
[5f0de8]51{
[dc8c23]52    // auxiliary variables
53    int i;
[5f0de8]54
[dc8c23]55    // read optional parameters
56    int timeout;
57    int ncores;   // obsolete, but kept for compatibility with old libraries
58    if (size(#) > 0) {
59        if (typeof(#[1]) != "int") {
60            ERROR("wrong optional parameters");
[5f0de8]61        }
[dc8c23]62        timeout = #[1];
63        if (size(#) > 1) {
64            if (size(#) > 2 || typeof(#[2]) != "int") {
65                ERROR("wrong optional parameters");
66            }
67            ncores = #[2];
[5f0de8]68        }
69    }
70
[dc8c23]71    // apply wrapper for obsolete optional parameter ncores
72    if (ncores) {
73        list semaphore_save = Resources::setcores_subtree(ncores);
[5f0de8]74    }
[dc8c23]75
76    // error checking
77    int njobs = size(commands);
78    if (njobs != size(args)) {
79        ERROR("The number of commands does not match the number of lists"
80            +newline+"of arguments.");
81    }
82    if (njobs == 0) {
83        ERROR("no commands specified");
84    }
85    for (i = 1; i <= njobs; i++) {
86        if (typeof(commands[i]) != "string") {
87            ERROR("The first argument is not a list of strings.");
[5f0de8]88        }
[dc8c23]89        if (typeof(args[i]) != "list") {
90            ERROR("The second argument is not a list of lists.");
[5f0de8]91        }
92    }
93
[dc8c23]94    // compute the tasks
95    for (i = 1; i <= njobs; i++) {
96        task t(i) = commands[i], args[i];
[5f0de8]97    }
[dc8c23]98    startTasks(t(1..njobs));
99    list indices = waitTasks(list(t(1..njobs)), N, timeout);
[5f0de8]100
[dc8c23]101    // wrap back to saved semaphore
102    if (ncores) {
103        Resources::resetcores_subtree(semaphore_save);
[5f0de8]104    }
105
[dc8c23]106    // return results
107    list results;
108    for (i = size(indices); i > 0; i--) {
109        results[indices[i]] = getResult(t(indices[i]));
110    }
111    for (i = 1; i <= njobs; i++) {
112        killTask(t(i));
113    }
114    return(results);
[5f0de8]115}
116example
117{
[dc8c23]118    "EXAMPLE:";
119    echo = 2;
120    ring R = 0, (x,y,z), lp;
121    ideal I = 3x3y+x3+xy3+y2z2, 2x3z-xy-xz3-y4-z2, 2x2yz-2xy2+xz2-y4;
122    ideal J = x10+x9y2, x2y7-y8;
123    list commands = list("std", "std");
124    list arguments = list(list(I), list(J));
125    parallelWaitN(commands, arguments, 1);
[5f0de8]126}
127
[dc8c23]128proc parallelWaitFirst(alias list commands, alias list args, list #)
129"USAGE:   parallelWaitFirst(commands, args[, timeout]); commands list,
130          arguments list, timeout int
131RETURN:   a list, containing at least one (if no timeout occurs) of the results
132          of commands[i] applied to arguments[i], i = 1, ..., size(arguments).
133       @* The command @code{parallelWaitFirst(commands, arguments[, timeout])}
134          is synonymous to
135          @code{parallelWaitN(commands, arguments, 1[, timeout])}. See
136          @ref{parallelWaitN} for details on optional arguments and other
137          remarks.
138SEE ALSO: parallelWaitN, parallelWaitAll, tasks_lib
139EXAMPLE:  example parallelWaitFirst; shows an example"
[5f0de8]140{
[dc8c23]141    return(parallelWaitN(commands, args, 1, #));
[5f0de8]142}
143example
144{
[dc8c23]145    "EXAMPLE:";
146    echo = 2;
147    ring R = 0, (x,y,z), lp;
148    ideal I = 3x3y+x3+xy3+y2z2, 2x3z-xy-xz3-y4-z2, 2x2yz-2xy2+xz2-y4;
149    ideal J = x10+x9y2, x2y7-y8;
150    list commands = list("std", "std");
151    list arguments = list(list(I), list(J));
152    parallelWaitFirst(commands, arguments);
[5f0de8]153}
154
[dc8c23]155proc parallelWaitAll(def commands, alias list args, list #)
156"USAGE:   parallelWaitAll(commands, arguments[, timeout]); commands list or
157          string, arguments list, timeout int
158RETURN:   a list, containing the results of commands[i] applied to
159          arguments[i], i = 1, ..., size(arguments).
160       @* The command @code{parallelWaitAll(commands, arguments[, timeout])} is
161          synonymous to @code{parallelWaitN(commands, arguments,
162          size(arguments)[, timeout])}. See @ref{parallelWaitN} for details on
163          optional arguments and other remarks.
164NOTE:     As a shortcut, @code{commands} can be a string. This is synonymous to
165          providing a list of @code{size(arguments)} copies of this string.
166SEE ALSO: parallelWaitFirst, parallelWaitN, tasks_lib
167EXAMPLE:  example parallelWaitAll; shows an example"
[5f0de8]168{
[dc8c23]169    if (typeof(commands) != "list" && typeof(commands) != "string") {
170        ERROR("invalid type of first argument");
171    }
172    if (typeof(commands) == "list") {
173        return(parallelWaitN(commands, args, size(args), #));
174    }
175    else {
176        list cmds;
177        for (int i = size(args); i > 0; i--) {
178            cmds[i] = commands;
179        }
180        return(parallelWaitN(cmds, args, size(args), #));
[5f0de8]181    }
182}
183example
184{
[dc8c23]185    "EXAMPLE:";
186    echo = 2;
187    ring R = 0, (x,y,z), dp;
188    ideal I1 = z8+z6+4z5+4z3+4z2+4, -z2+y;
189    ideal I2 = x9y2+x10, x2y7-y8;
190    ideal I3 = x3-2xy, x2y-2y2+x;
191    string command = "std";
192    list arguments = list(list(I1), list(I2), list(I3));
193    parallelWaitAll(command, arguments);
[5f0de8]194}
195
[dc8c23]196proc parallelTestAND(def commands, alias list args, list #)
197"USAGE:   parallelTestAND(commands, arguments[, timeout]); commands list or
198          string, arguments list, timeout int
199RETURN:   1, if commands[i] applied to arguments[i] is not equal to zero for
200          all i = 1, ..., size(arguments);
201          0, otherwise.
202       @* An optional timeout in ms can be provided. Default is 0 which
203          disables the timeout. In case of timeout, -1 is returned.
204NOTE:     The entries of the list commands must be strings. The entries of the
205          list arguments must be lists.
206       @* commands[i] applied to arguments[i] must evaluate to an integer for
207          i = 1, ..., size(arguments).
208       @* As a shortcut, @code{commands} can be a string. This is synonymous to
209          providing a list of @code{size(arguments)} copies of this string.
210SEE ALSO: parallelTestOR, tasks_lib
211EXAMPLE:  example parallelTestAND; shows an example"
[5f0de8]212{
[dc8c23]213    // note: this can be improved
214    list results = parallelWaitAll(commands, args, #);
215    int i;
216    for (i = size(args); i > 0; i--) {
217        if (typeof(results[i]) != "int" && typeof(results[i]) != "none") {
218            ERROR("result no. "+string(i)+" not of type int");
219        }
[5f0de8]220    }
[dc8c23]221    for (i = size(args); i > 0; i--) {
222        if (typeof(results[i]) == "none") {   // timeout
223            return(-1);
224        }
[5f0de8]225    }
[dc8c23]226    for (i = size(results); i > 0; i--) {
227        if (!results[i]) {
228            return(0);
229        }
[5f0de8]230    }
[dc8c23]231    return(1);
232}
233example
234{
235    "EXAMPLE:";
236    echo = 2;
237    ring R = 0, (x,y,z), dp;
238    ideal I = x, y, z;
239    intvec v = 0:3;
240    list l = list(I, v);
241    module m1 = x*gen(1);
242    module m2;
243    string command = "size";
244    list arguments1 = list(list(I), list(v), list(l), list(m1));
245    list arguments2 = list(list(I), list(v), list(l), list(m2));
246    // test if all the arguments have non-zero size
247    parallelTestAND(command, arguments1);
248    parallelTestAND(command, arguments2);
249}
250
251proc parallelTestOR(def commands, alias list args, list #)
252"USAGE:   parallelTestOR(commands, arguments[, timeout]); commands list or
253          string, arguments list, timeout int
254RETURN:   1, if commands[i] applied to arguments[i] is not equal to zero for
255          any i = 1, ..., size(arguments);
256          0, otherwise.
257       @* An optional timeout in ms can be provided. Default is 0 which
258          disables the timeout. In case of timeout, -1 is returned.
259NOTE:     The entries of the list commands must be strings. The entries of the
260          list arguments must be lists.
261       @* commands[i] applied to arguments[i] must evaluate to an integer for
262          i = 1, ..., size(arguments).
263       @* As a shortcut, @code{commands} can be a string. This is synonymous to
264          providing a list of @code{size(arguments)} copies of this string.
265SEE ALSO: parallelTestAND, tasks_lib
266EXAMPLE:  example parallelTestAND; shows an example"
267{
268    // note: this can be improved
269    list results = parallelWaitAll(commands, args, #);
270    int i;
271    for (i = size(args); i > 0; i--) {
272        if (typeof(results[i]) != "int" && typeof(results[i]) != "none") {
273            ERROR("result no. "+string(i)+" not of type int");
[5f0de8]274        }
275    }
[dc8c23]276    for (i = size(args); i > 0; i--) {
277        if (typeof(results[i]) == "none") {   // timeout
278            return(-1);
[5f0de8]279        }
[dc8c23]280    }
281    for (i = size(results); i > 0; i--) {
282        if (results[i]) {
283            return(1);
[5f0de8]284        }
285    }
[dc8c23]286    return(0);
[5f0de8]287}
[dc8c23]288example
[5f0de8]289{
[dc8c23]290    "EXAMPLE:";
291    echo = 2;
292    ring R = 0, (x,y,z), dp;
293    ideal I;
294    string s;
295    list l;
296    module m1 = x*gen(1);
297    module m2;
298    string command = "size";
299    list arguments1 = list(list(I), list(s), list(l), list(m1));
300    list arguments2 = list(list(I), list(s), list(l), list(m2));
301    // test if any of the arguments has non-zero size
302    parallelTestOR(command, arguments1);
303    parallelTestOR(command, arguments2);
[5f0de8]304}
[7f30e2]305
Note: See TracBrowser for help on using the repository browser.