parallel-3.1.1/ 002755 001750 001750 00000000000 12771453045 013226 5 ustar 00olaf olaf 000000 000000 parallel-3.1.1/INDEX 000644 001750 001750 00000000410 12771453045 014011 0 ustar 00olaf olaf 000000 000000 parallel >> Parallel Computing
Single Machine
parcellfun
pararrayfun
Clusters
psend precv reval
pserver
pconnect
sclose
select_sockets
parallel_generate_srp_data
network_get_info
network_set
rfeval
install_vars
netcellfun
netarrayfun
General
select
parallel-3.1.1/inst/ 002755 001750 001750 00000000000 12771453045 014203 5 ustar 00olaf olaf 000000 000000 parallel-3.1.1/inst/__parallel_package_version__.m 000644 001750 001750 00000000445 12771453045 022172 0 ustar 00olaf olaf 000000 000000 ## This file is granted to the public domain.
## -*- texinfo -*-
## @deftypefn{Function File} {} __parallel_package_version__ ()
##
## Internal function, returns version of parallel package.
##
## @end deftypefn
function ver = __parallel_package_version__ ()
ver = "3.0.4";
endfunction
parallel-3.1.1/inst/parcellfun.m 000644 001750 001750 00000036236 12771453045 016524 0 ustar 00olaf olaf 000000 000000 ## Copyright (C) 2009 VZLU Prague, a.s., Czech Republic
##
## This program is free software; you can redistribute it and/or modify it under
## the terms of the GNU General Public License as published by the Free Software
## Foundation; either version 3 of the License, or (at your option) any later
## version.
##
## This program is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
## details.
##
## You should have received a copy of the GNU General Public License along with
## this program; if not, see .
## -*- texinfo -*-
## @deftypefn{Function File} {[@var{o1}, @var{o2}, @dots{}] =} parcellfun (@var{nproc}, @var{fun}, @var{a1}, @var{a2}, @dots{})
## @deftypefnx{Function File} {} parcellfun (nproc, fun, @dots{}, "UniformOutput", @var{val})
## @deftypefnx{Function File} {} parcellfun (nproc, fun, @dots{}, "ErrorHandler", @var{errfunc})
## @deftypefnx{Function File} {} parcellfun (nproc, fun, @dots{}, "VerboseLevel", @var{val})
## @deftypefnx{Function File} {} parcellfun (nproc, fun, @dots{}, "ChunksPerProc", @var{val})
## @deftypefnx{Function File} {} parcellfun (nproc, fun, @dots{}, "CumFunc", @var{cumfunc})
## Evaluates a function for multiple argument sets using multiple processes.
## @var{nproc} should specify the number of processes. A maximum recommended value is
## equal to number of CPUs on your machine or one less.
## @var{fun} is a function handle pointing to the requested evaluating function.
## @var{a1}, @var{a2} etc. should be cell arrays of equal size.
## @var{o1}, @var{o2} etc. will be set to corresponding output arguments.
##
## The UniformOutput and ErrorHandler options are supported with meaning identical
## to @dfn{cellfun}.
## A VerboseLevel option controlling the level output is supported.
## A value of 0 is quiet, 1 is normal, and 2 or more enables
## debugging output.
## The ChunksPerProc option control the number of chunks which contains elementary jobs. This
## option particularly useful when time execution of function is small. Setting this option
## to 100 is a good choice in most cases.
##
## Instead of returning a result for each argument, parcellfun returns
## only one cumulative result if "CumFunc" is non-empty. @var{cumfunc}
## must be a function which performs an operation on two sets of
## outputs of @var{fun} and returnes as many outputs as @var{fun}. If
## @var{nout} is the number of outputs of @var{fun}, @var{cumfunc}
## gets a previous output set of @var{fun} or of @var{cumfunc} as
## first @var{nout} arguments and the current output of @var{fun} as
## last @var{nout} arguments. The performed operation must be
## mathematically commutative and associative. If the operation is
## e.g. addition, the result will be the sum(s) of the outputs of
## @var{fun} over all calls of @var{fun}. Since floating point
## addition and multiplication are only approximately associative, the
## cumulative result will not be exactly reproducible.
##
## Notice that jobs are served from a single first-come first-served queue,
## so the number of jobs executed by each process is generally unpredictable.
## This means, for example, that when using this function to perform Monte-Carlo
## simulations one cannot expect results to be exactly reproducible. The pseudo
## random number generators of each process are initialised with a unique state.
## This currently works only for new style generators.
##
## NOTE: this function is implemented using "fork" and a number of pipes for IPC.
## Suitable for systems with an efficient "fork" implementation (such as GNU/Linux),
## on other systems (Windows) it should be used with caution.
## Also, if you use a multithreaded BLAS, it may be wise to turn off multi-threading
## when using this function.
##
## CAUTION: This function should be regarded as experimental. Although all subprocesses
## should be cleared in theory, there is always a danger of a subprocess hanging up,
## especially if unhandled errors occur. Under GNU and compatible systems, the following
## shell command may be used to display orphaned Octave processes:
## ps --ppid 1 | grep octave
##
## @end deftypefn
## Author: Jaroslav Hajek
## Several improvements thanks to: Travis Collier
## CumFunc feature added by Olaf Till
function varargout = parcellfun (nproc, fun, varargin)
## The list of functions to be seeded in each slave.
persistent random_func_list = {@rand, @randn, @rande, @randp, @randg};
if (nargin < 3 || ! isscalar (nproc) || nproc <= 0)
print_usage ();
endif
if (ischar (fun))
fun = str2func (fun);
elseif (! isa (fun, "function_handle"))
error ("parcellfun: fun must be either a function handle or name")
endif
[nargs, uniform_output, error_handler, verbose_level, ...
chunks_per_proc, cumfunc] = parcellfun_opts ("parcellfun", varargin);
accumulate = ifelse (isempty (cumfunc), false, true);
args = varargin(1:nargs);
if (! all (cellfun ("isclass", args, "cell")))
error ("parcellfun: all non-option arguments except the first one must be cell arrays");
endif
if (nargs == 0)
print_usage ();
elseif (nargs > 1)
[err, args{:}] = common_size (args{:});
if (err)
error ("parcellfun: arguments size must match");
endif
endif
njobs = numel (args{1});
if (chunks_per_proc > 0 && chunks_per_proc < njobs / nproc)
## We need chunked evaluation.
if (accumulate)
chunk_uniform_output = false;
else
chunk_uniform_output = uniform_output;
endif
## Function executed for a chunk.
if (isempty (error_handler))
chunk_fun = @(varargin) cellfun (fun, varargin{:},
"UniformOutput", chunk_uniform_output);
else
chunk_fun = @(varargin) cellfun (fun, varargin{:},
"UniformOutput", chunk_uniform_output,
"ErrorHandler", error_handler);
endif
if (accumulate)
chunk_fun = @(varargin) acc_chunk_fun (cumfunc, chunk_fun, varargin{:});
endif
[varargout{1:nargout}] = chunk_parcellfun (nproc, chunks_per_proc,
chunk_fun, [], verbose_level,
cumfunc, uniform_output,
args{:});
return
endif
nproc = min (nproc, numel (args{1}));
## create communication pipes.
cmdr = cmdw = resr = resw = zeros (nproc, 1);
err = 0;
for i = 1:nproc
## command pipes
[cmdr(i), cmdw(i), err, msg] = pipe ();
if (err)
break;
endif
## result pipes
[resr(i), resw(i), err, msg] = pipe ();
if (err)
break;
endif
endfor
if (! err)
## status pipe
[statr, statw, err, msg] = pipe ();
endif
if (err)
error ("failed to open pipe: %s", msg);
endif
iproc = 0; # the parent process
nsuc = 0; # number of processes succesfully forked.
fflush (stdout); # prevent subprocesses from inheriting buffered output
## get a seed and change state
seed = rand;
pids = zeros (nproc, 1);
## fork subprocesses
for i = 1:nproc
[pid, msg] = fork ();
if (pid > 0)
## parent process. fork succeded.
nsuc ++;
pids(i) = pid;
if (verbose_level > 1)
fprintf (stderr,"parcellfun: child process %d created\n", pids(i));
fflush (stderr);
endif
elseif (pid == 0)
## child process.
iproc = i;
break;
elseif (pid < 0)
## parent process. fork failed.
err = 1;
break;
endif
endfor
if (iproc)
## child process. close unnecessary pipe ends.
fclose (statr);
for i = 1:nproc
## we won't write commands and read results
fclose (cmdw (i));
fclose (resr (i));
if (i != iproc)
## close also those pipes that don't belong to us.
fclose (cmdr (i));
fclose (resw (i));
endif
endfor
else
## parent process. close unnecessary pipe ends.
fclose (statw);
for i = 1:nproc
## we won't read commands and write results
fclose (cmdr (i));
fclose (resw (i));
endfor
if (nsuc)
## we forked some processes. if this is less than we opted for, gripe
## but continue.
if (nsuc < nproc)
warning ("parcellfun: only %d out of %d processes forked", nsuc, nproc);
nproc = nsuc;
endif
else
## this is bad.
error ("parcellfun: failed to fork processes");
endif
endif
## At this point, everything should be OK (?)
if (iproc)
## the border patrol. we really don't want errors escape after the forks.
unwind_protect
try
## re-seed random number states, adjusted for each process
seed *= iproc * (flintmax () - 1); # backwards compatibility
cellfun (@ (fun) fun ("state", seed), random_func_list);
## child process. indicate ready state.
fwrite (statw, -iproc, "double");
fflush (statw);
do
## get command
cmd = fread (cmdr(iproc), 1, "double");
if (cmd)
## we've got a job to do. prepare argument and return lists.
res = cell (1, nargout);
argsc = cell (1, nargs);
for i = 1:nargs
argsc{i} = args{i}{cmd};
endfor
if (isempty (error_handler))
## unguarded evaluation.
[res{:}] = fun (argsc{:});
else
## guarded evaluation
try
[res{:}] = fun (argsc{:});
catch
errs = lasterror (); # fields 'message', 'identifier', 'stack'
errs.index = cmd;
[res{:}] = error_handler (errs, argsc{:});
end_try_catch
endif
## indicate ready state.
fwrite (statw, iproc, "double");
fflush (statw);
## write the result.
## FIXME: this can fail.
fsave (resw(iproc), res);
fflush (resw(iproc));
endif
until (cmd == 0)
catch
## just indicate the error. don't quit this function !!!!
fputs (stderr, "\n");
warning ("parcellfun: unhandled error in subprocess %d", iproc);
## send a termination notice.
fwrite (statw, -iproc, "double");
fflush (statw);
end_try_catch
unwind_protect_cleanup
## This is enclosed in another handler to prevent errors from escaping.
## If something goes wrong, we'll get a broken pipe signal, but anything
## is better than skipping the following __exit__.
try
fclose (statw);
fclose (resw(iproc));
fclose (cmdr(iproc));
end_try_catch
## no more work for us. We call __exit__, which bypasses termination sequences.
__exit__ ();
## we should never get here.
exit ();
end_unwind_protect
else
## parent process.
if (accumulate)
res = cell (nargout, 1);
else
res = cell (nargout, njobs);
endif
firstresult = true;
pjobs = 0;
stop = false;
pending = zeros (1, nproc);
## we need these flags additionally to 'pending' because 1) a child
## might send a result (so pending is set to false) and yet signal
## failure and exit due to an error in sending (which would be
## mistaken for a 'ready' signal if only 'pending' is checked) and
## 2) a child might not signal to be ready until all jobs are
## finished, so pending never gets true (see where the flags are
## used)
ready = false (1, nproc);
terminated = false (1, nproc);
unwind_protect
while ((pjobs < njobs && ! stop) || any (pending))
## wait for a process state.
isubp = fread (statr, 1, "double");
## if pipe contained no more data, that's bad
if (feof (statr))
warning ("parcellfun: premature exit due to closed pipe");
break;
endif
if (isubp > 0)
ijob = pending(isubp);
## we have a result ready.
if (accumulate)
if (firstresult)
res(:, 1) = fload (resr(isubp));
firstresult = false;
else
[res{:, 1}] = cumfunc (res{:}, fload (resr(isubp)){:});
endif
else
res(:, ijob) = fload (resr(isubp));
endif
## clear pending state
pending(isubp) = 0;
else
isubp = -isubp;
if (ready(isubp))
## premature exit means an unhandled error occurred in a subprocess.
## the process should have griped, we just try to exit gracefully.
pending(isubp) = 0;
terminated(isubp) = true;
## no more jobs to start.
stop = true;
## skip the rest; don't send commands to the process.
fclose(cmdw(isubp));
continue;
else
ready(isubp) = true;
endif
endif
if (pjobs < njobs && ! stop)
ijob = ++pjobs;
## send the next job to the process.
fwrite (cmdw(isubp), ijob, "double");
fflush (cmdw(isubp));
## set pending state
pending(isubp) = ijob;
else
## send terminating signal
fwrite (cmdw(isubp), 0, "double");
fclose (cmdw(isubp));
terminated(isubp) = true;
endif
if (verbose_level > 0)
fprintf (stderr, "\rparcellfun: %d/%d jobs done", pjobs - sum (pending != 0), njobs);
fflush (stderr);
endif
endwhile
if (verbose_level > 0)
fputs (stderr, "\n");
fflush (stderr);
endif
unwind_protect_cleanup
## send termination signals to active processes.
for isubp = find (! terminated)
## send terminating signal
fwrite (cmdw(isubp), 0, "double");
fclose (cmdw(isubp));
endfor
## explicitly recognize all terminated processes.
for i = 1:nproc
if (verbose_level > 1)
fprintf(stderr,"parcellfun: waiting for child process %d to close\n", pids(i));
fflush (stderr);
endif
[pid, status] = waitpid (pids(i));
endfor
## FIXME: I think order is possibly important here, and this is correct.
## close all pipe ends
fclose (statr);
for i = 1:nproc
fclose (resr(i));
endfor
end_unwind_protect
## we're finished. transform the result.
if (accumulate)
if (uniform_output)
varargout = res;
else
varargout = num2cell (res);
endif
else
varargout = cell (1, nargout);
shape = size (varargin{1});
for i = 1:nargout
varargout{i} = reshape (res(i,:), shape);
if (uniform_output)
varargout{i} = cell2mat (varargout{i});
endif
endfor
endif
endif
endfunction
function varargout = acc_chunk_fun (cumfunc, chunk_fun, varargin)
[chunk_out{1:nargout}] = chunk_fun (varargin{:});
nel = numel (chunk_out{1});
chunk_out = horzcat (chunk_out{:});
res = chunk_out(1, :);
for (id = 2 : nel)
[res{:}] = cumfunc (res{:}, chunk_out{id, :});
endfor
varargout = res;
endfunction
parallel-3.1.1/inst/__internal_exit__.m 000644 001750 001750 00000000422 12771453045 020016 0 ustar 00olaf olaf 000000 000000 ## This code is in the public domain.
## -*- texinfo -*-
## @deftypefn {Function File} {} __internal_exit__ (@var{status})
## Wrapper for __exit__ for backwards compatibility.
## @end deftypefn
function __internal_exit__ (varargin)
__exit__ (varargin{:});
endfunction
parallel-3.1.1/inst/pararrayfun.m 000644 001750 001750 00000010154 12771453045 016712 0 ustar 00olaf olaf 000000 000000 ## Copyright (C) 2009 Jaroslav Hajek
## Copyright (C) 2009 VZLU Prague, a.s., Czech Republic
## Copyright (C) 2009 Travis Collier
##
## This program is free software; you can redistribute it and/or modify it under
## the terms of the GNU General Public License as published by the Free Software
## Foundation; either version 3 of the License, or (at your option) any later
## version.
##
## This program is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
## details.
##
## You should have received a copy of the GNU General Public License along with
## this program; if not, see .
## -*- texinfo -*-
## @deftypefn{Function File} {[@var{o1}, @var{o2}, @dots{}] =} pararrayfun (@var{nproc}, @var{fun}, @var{a1}, @var{a2}, @dots{})
## @deftypefnx{Function File} {} pararrayfun (nproc, fun, @dots{}, "UniformOutput", @var{val})
## @deftypefnx{Function File} {} pararrayfun (nproc, fun, @dots{}, "ErrorHandler", @var{errfunc})
## Evaluates a function for corresponding elements of an array.
## Argument and options handling is analogical to @code{parcellfun}, except that
## arguments are arrays rather than cells. If cells occur as arguments, they are treated
## as arrays of singleton cells.
## Arrayfun supports one extra option compared to parcellfun: "Vectorized".
## This option must be given together with "ChunksPerProc" and it indicates
## that @var{fun} is able to operate on vectors rather than just scalars, and returns
## a vector. The same must be true for @var{errfunc}, if given.
## In this case, the array is split into chunks which are then directly served to @var{func}
## for evaluation, and the results are concatenated to output arrays.
## If "CumFunc" is also specified (see @code{parcellfun}), @var{fun} is
## expected to return the result of the same cumulative operation
## instead of vectors.
## @c Will be cut out in parallels info file and replaced with the same
## @c references explicitely there, since references to core Octave
## @c functions are not automatically transformed from here to there.
## @c BEGIN_CUT_TEXINFO
## @seealso{parcellfun, arrayfun}
## @c END_CUT_TEXINFO
## @end deftypefn
function varargout = pararrayfun (nproc, func, varargin)
if (nargin < 3)
print_usage ();
endif
[nargs, uniform_output, error_handler, verbose_level, ...
chunks_per_proc, cumfunc, vectorized] = parcellfun_opts ...
("pararrayfun", varargin);
args = varargin(1:nargs);
opts = varargin(nargs+1:end);
if (nargs == 0)
print_usage ();
elseif (nargs > 1)
[err, args{:}] = common_size (args{:});
if (err)
error ("pararrayfun: arguments size must match");
endif
endif
njobs = numel (args{1});
if (vectorized && chunks_per_proc > 0 && ...
chunks_per_proc < njobs / nproc)
## If "Vectorized" is on, we apply the function directly on chunks of
## arrays.
if (! uniform_output && isempty (cumfunc))
func = @ (varargin) num2cell (func (varargin{:}));
endif
[varargout{1:nargout}] = chunk_parcellfun (nproc, chunks_per_proc,
func, error_handler,
verbose_level, cumfunc,
uniform_output, args{:});
else
args = cellfun (@num2cell, args, "UniformOutput", false,
"ErrorHandler", @arg_class_error);
if (chunks_per_proc == 0)
chunks_per_proc = [];
endif
[varargout{1:nargout}] = parcellfun (nproc, func, args{:},
"UniformOutput", uniform_output,
"ErrorHandler", error_handler,
"VerboseLevel", verbose_level,
"ChunksPerProc", chunks_per_proc,
"CumFunc", cumfunc);
endif
endfunction
function arg_class_error (S, X)
error ("arrayfun: invalid argument of class %s", class (X))
endfunction
parallel-3.1.1/inst/__bw_psend__.m 000644 001750 001750 00000000431 12771453045 016752 0 ustar 00olaf olaf 000000 000000 ## This code is in the public domain.
## -*- texinfo -*-
## @deftypefn {Function File} {} __bw_psend__ (@var{fd}, @var{var})
## Wrapper for fload for backwards compatibility (optim package).
## @end deftypefn
function __bw_psend__ (varargin)
fsave (varargin{:});
endfunction
parallel-3.1.1/inst/__bw_prcv__.m 000644 001750 001750 00000000447 12771453045 016622 0 ustar 00olaf olaf 000000 000000 ## This code is in the public domain.
## -*- texinfo -*-
## @deftypefn {Function File} {ret =} __bw_prcv__ (@var{fd})
## Wrapper for fload for backwards compatibility (optim package).
## @end deftypefn
function ret = __bw_prcv__ (varargin)
ret.psend_var = fload (varargin{:});
endfunction
parallel-3.1.1/inst/private/ 002755 001750 001750 00000000000 12771453045 015655 5 ustar 00olaf olaf 000000 000000 parallel-3.1.1/inst/private/parcellfun_opts.m 000644 001750 001750 00000006341 12771453045 021235 0 ustar 00olaf olaf 000000 000000 ## Copyright (C) 2010 VZLU Prague, a.s., Czech Republic
##
## This program is free software; you can redistribute it and/or modify it under
## the terms of the GNU General Public License as published by the Free Software
## Foundation; either version 3 of the License, or (at your option) any later
## version.
##
## This program is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
## details.
##
## You should have received a copy of the GNU General Public License along with
## this program; if not, see .
## -*- texinfo -*-
## @deftypefn{Function File} {} parcellfun_opts (args)
## Undocumented internal function.
## @end deftypefn
function [nargs, uniform_output, error_handler, verbose_level, ...
chunks_per_proc, cumfunc, vectorized, ...
chunk_size] = parcellfun_opts (caller, args)
uniform_output = true;
error_handler = [];
verbose_level = 1; # default to normal output level
chunks_per_proc = 0; # 0 means than size of chunk is 1
vectorized = false;
cumfunc = [];
chunk_size = 1;
nargs = length (args);
## parse options
while (nargs > 1)
opt = args{nargs-1};
if (! ischar (opt))
break;
else
optl = tolower (opt);
val = args{nargs};
endif
switch (optl)
case "uniformoutput"
uniform_output = logical (val);
if (! isscalar (uniform_output))
error ("%s: UniformOutput must be a logical scalar", caller);
endif
case "errorhandler"
error_handler = val;
if (! (isempty (error_handler) || isa (error_handler, "function_handle")))
error ("%s: ErrorHandler must be a function handle", caller);
endif
case "verboselevel"
verbose_level = val;
if (! isscalar (verbose_level))
error ("%s: VerboseLevel must be a numeric scalar", caller);
endif
case "chunksperproc"
if (! isempty (val))
chunks_per_proc = round (val);
if (! isscalar (chunks_per_proc) || chunks_per_proc <= 0)
error ("%s: ChunksPerProc must be a positive scalar", caller);
endif
endif
case "vectorized"
vectorized = logical (val);
if (! isscalar (vectorized))
error ("%s: Vectorized must be a logical scalar", caller);
endif
case "cumfunc"
cumfunc = val;
if (! (isempty (cumfunc) || is_function_handle (cumfunc)))
error ("%s: CumFunc must be empty or a function handle", caller);
endif
case "chunksize"
chunk_size = round (val);
if (! isscalar (chunk_size) || chunk_size <= 0)
error ("%s: ChunkSize must be a positive scalar", caller);
endif
otherwise
error ("%s: invalid option ""%s""", caller, opt);
endswitch
nargs -= 2;
endwhile
if (vectorized)
if (any (strcmp (caller, {"parcellfun", "netcellfun"})))
error ("%s: ""Vectorized"" option not accepted by %s",
caller, caller);
elseif (chunks_per_proc <= 0 && strcmp (caller, "pararrayfun"))
error ("%s: the ""Vectorized"" option requires also ""ChunksPerProc""",
caller);
endif
endif
endfunction
parallel-3.1.1/inst/private/chunk_parcellfun.m 000644 001750 001750 00000004477 12771453045 021370 0 ustar 00olaf olaf 000000 000000 ## Copyright (C) 2010 VZLU Prague, a.s., Czech Republic
## Copyright (C) 2010 Jean-Benoist Leger
##
## This program is free software; you can redistribute it and/or modify it under
## the terms of the GNU General Public License as published by the Free Software
## Foundation; either version 3 of the License, or (at your option) any later
## version.
##
## This program is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
## details.
##
## You should have received a copy of the GNU General Public License along with
## this program; if not, see .
## -*- texinfo -*-
## @deftypefn{Function File} {} chunk_parcellfun (@dots{:})
## Undocumented internal function.
## @end deftypefn
function varargout = chunk_parcellfun (nproc, chunks_per_proc, func,
error_handler, verbose_level,
cumfunc, uniform_output,
varargin)
args = varargin;
nchunks = chunks_per_proc * nproc;
## Compute optimal chunk sizes.
N = numel (args{1});
len_chunk = ceil (N/nchunks);
chunk_sizes = len_chunk (ones(1, nchunks));
chunk_sizes(1:nchunks*len_chunk - N) -= 1;
## Split argument arrays into chunks (thus making arrays of arrays).
chunked_args = cellfun (@(arg) mat2cell (arg(:), chunk_sizes), args, ...
"UniformOutput", false);
## Attach error handler if present.
if (! isempty (error_handler))
chunked_args = [chunked_args, {"ErrorHandler", error_handler}];
endif
## Main call.
[out_brut{1:nargout}] = parcellfun (nproc, func, chunked_args{:},
"UniformOutput", false,
"VerboseLevel", verbose_level,
"CumFunc", cumfunc);
## Concatenate output args and reshape them to correct size.
if (isempty (cumfunc))
true_size = size (args{1});
varargout = cellfun (@(arg) reshape (vertcat (arg{:}), true_size), out_brut, "UniformOutput", false);
elseif (uniform_output)
varargout = cellfun (@(arg) arg{:}, out_brut, "UniformOutput", false);
else
varargout = out_brut;
endif
endfunction
parallel-3.1.1/inst/private/netcellfun_worker.m 000644 001750 001750 00000021350 12771453045 021562 0 ustar 00olaf olaf 000000 000000 ## Copyright (C) 2015, 2016 Olaf Till
##
## This program is free software; you can redistribute it and/or modify it under
## the terms of the GNU General Public License as published by the Free Software
## Foundation; either version 3 of the License, or (at your option) any later
## version.
##
## This program is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
## details.
##
## You should have received a copy of the GNU General Public License along with
## this program; if not, see .
## -*- texinfo -*-
## @deftypefn{Function File} {} netcellfun_worker (@var{in_arrays} @var{connections}, @var{fun}, @dots{})
##
## Undocumented internal function.
##
## @end deftypefn
function varargout = netcellfun_worker (in_arrays, conns, func, varargin)
fname = ifelse (in_arrays, "netarrayfun", "netcellfun");
## nargin () >= 4 has been assured by caller (netcellfun or netarrayfun)
if (! isa (conns, "pconnections"))
error ("%s: `connections' must be a parallel connections object", fname);
endif
info = network_get_info (conns);
## delete local machine, if present, from connections and from info
server_idx = ! [info.local_machine];
conns = conns(server_idx);
info = info(server_idx);
if ((nhosts = numel (conns)) == 0)
error ("%s: connections object contains no servers", fname);
endif
nout = nargout ();
## options are similar to for parcellfun/pararrayfun
[nargs, uniform_output, error_handler, verbose_level, ...
~, cumfunc, vectorized, chunk_size] = parcellfun_opts (fname, varargin);
accumulate = ifelse (isempty (cumfunc), false, true);
args = varargin(1:nargs);
if (nargs > 1)
[err, args{:}] = common_size (args{:});
if (err)
error ("%s: arguments size must match", fname);
endif
endif
argdims = size (args{1});
args_are_columns = iscolumn (args{1});
if (! args_are_columns)
args = cellfun (@ (x) x(:), args, "UniformOutput", false);
endif
## configured or default number of processes at each machine
rnproc = ifelse ([info.nlocaljobs] == 0, [info.nproc], [info.nlocaljobs]);
## number of jobs per call at each machine
rnjobs = rnproc * chunk_size;
## The anonymous functions for remote function calls had to be defined
## without using "varargin", since (up to Octave 4.0.0 at least)
## anonymous functions with varargin were not saved/loaded
## (sent/received) correctly.
if (any (rnjobs == 1))
## There will be (some) single function calls (without parallelity
## within one machine and not via cellfun). Prepare function for
## single function calls. See below why the 'eh' argument is
## necessary.
if (isempty (error_handler))
if (in_arrays)
single_func = @ (idx, eh, varargs) func (varargs{:});
else
single_func = @ (idx, eh, varargs) func (vertcat (varargs{:}){:});
endif
else
if (in_arrays)
single_func = @ (idx, eh, varargs) __netcellfun_guardfun__ ...
(func, error_handler, idx, varargs{:});
else
single_func = @ (idx, eh, varargs) __netcellfun_guardfun__ ...
(func, error_handler, idx, vertcat (varargs{:}){:});
endif
endif
endif
## (For function calls via parcell/arrayfun, the possibly specified
## error handler must be wrapped to add a base to errs.index.)
## construct function calls specific to each server
funs = cell (nhosts, 1);
## this caused some difficulties (4.0.0) with visibility of private functions
## rem_parfun = ifelse (in_arrays, @ pararrayfun, @ parcellfun);
rem_parfun = ifelse (in_arrays, "pararrayfun", "parcellfun");
## (number of argument sets in remote call will be rnproc *
## chunk_size, while ChunksPerProc will be 1)
for (id = 1:nhosts)
if (rnjobs(id) == 1)
funs{id} = single_func;
else
## If (rnproc(id) == 1), this will lead to a single call of
## cellfun via parcell/arrayfun. This case could be treated more
## efficiently. But then we'd have to care for CumFunc here.
## We use eval() to shorten the logic, since a function handle for
## rem_parfun did not work (see comment above). See next comment
## for why the second argument 'eh' is necessary.
if (isempty (error_handler))
eval (sprintf ("funs{id} = @ (idx, eh, varargs) %s \
(rnproc(id), func, varargs{:}, \
'ChunksPerProc', 1, \
'UniformOutput', false, \
'VerboseLevel', 0, \
'Vectorized', vectorized, \
'CumFunc', cumfunc, \
'ErrorHandler', eh);", ...
rem_parfun));
else
## The eval() with explicitely named anonymous function
## arguments is necessary due to the above mentioned issue with
## save/loading anonymous functions with varargin. Also, Octave
## doesn't seem to save the context of an anonymous function
## defined within another anonymous function -- it doesn't save
## the original error handler within the defined error handler
## wrapper; for this reason, the error handler has to be passed
## as an additional (second) argument to the funcion funs{id},
## an argument which could be dropped otherwise.
arg_list = sprintf (", _%i", 1:nargs);
eval (sprintf ("funs{id} = @ (idx, eh, varargs) %s \
(rnproc(id), func, varargs{:}, \
'ChunksPerProc', 1, \
'UniformOutput', false, \
'VerboseLevel', 0, \
'Vectorized', vectorized, \
'CumFunc', cumfunc, \
'ErrorHandler', \
@ (err %s) eh \
(setfield (err, 'index', idx(err.index)) \
%s));",
rem_parfun, arg_list, arg_list));
endif
endif
endfor
## the scheduler
njobs = numel (args{1});
busy_hosts_lidx = false (1, nhosts);
busy_hosts_jobs = cell (1, nhosts); # will contain index vectors
# into jobs
left_lidx = true (njobs, 1);
firstresult = true;
first_rfeval = true;
error_in_first_rfeval = false;
ready = false;
if (! accumulate)
varargout = cell (njobs, nout);
endif
orig_size = size (args{1});
unwind_protect
while (any (left_lidx) || any (busy_hosts_lidx))
## create remote jobs if jobs are left
## go through all free hosts, there are some (first time or select
## returned)
for host_nid = find (! busy_hosts_lidx)
## index vector into jobs for that host, stop creating remote
## jobs if no job is left
if (isempty (job_idxv = find (left_lidx, rnjobs(host_nid))))
break;
endif
## cargs will contain _column_ arrays
cargs = cellfun (@ (x) x(job_idxv), args, "UniformOutput", false);
try
rfeval (funs{host_nid}, job_idxv, error_handler, cargs, nout, [],
conns(host_nid));
catch
if (first_rfeval)
error_in_first_rfeval = true;
endif
error (lasterr ());
end_try_catch
first_rfeval = false;
busy_hosts_lidx(host_nid) = true;
busy_hosts_jobs{host_nid} = job_idxv;
left_lidx(job_idxv) = false;
endfor
## ready creating jobs, now collect some results
## there are busy hosts, if not directly due to the enclosing
## while-condition, then due to creating jobs above
ready_nidx = select_sockets (conns, -1);
for id = ready_nidx
## a cell-array of the outputs, outputs are columns
res = precv (conns(id));
## distinguish between single function and others
if (rnjobs(id) > 1)
## the outputs are in cell-arrays
res = horzcat (res{:});
endif
if (accumulate)
if (firstresult)
varargout = res;
firstresult = false;
else
[varargout{:}] = cumfunc (varargout{:}, res{:});
endif
else
varargout(busy_hosts_jobs{id}, :) = res;
endif
busy_hosts_lidx(id) = false;
left_lidx(busy_hosts_jobs{id}) = false;
endfor
endwhile
ready = true;
unwind_protect_cleanup
if (! (ready || error_in_first_rfeval))
sclose (conns); # might already be closed
endif
end_unwind_protect
## transform the result
if (uniform_output)
varargout = cell2mat (varargout);
endif
varargout = mat2cell (varargout, rows (varargout), ones (1, nout));
if (! (accumulate || args_are_columns))
varargout = cellfun (@ (x) reshape (x, argdims), varargout,
"UniformOutput", false);
endif
endfunction
parallel-3.1.1/inst/parallel_doc.m 000644 001750 001750 00000005121 12771453045 016777 0 ustar 00olaf olaf 000000 000000 ## Copyright (C) 2014-2016 Olaf Till
##
## This program is free software; you can redistribute it and/or modify it under
## the terms of the GNU General Public License as published by the Free Software
## Foundation; either version 3 of the License, or (at your option) any later
## version.
##
## This program is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
## details.
##
## You should have received a copy of the GNU General Public License along with
## this program; if not, see .
## -*- texinfo -*-
## @deftypefn {Function File} {} parallel_doc ()
## @deftypefnx {Function File} {} parallel_doc (@var{keyword})
## Show parallel package documentation.
##
## Runs the info viewer Octave is configured with on the documentation
## in info format of the installed parallel package. Without argument,
## the top node of the documentation is displayed. With an argument,
## the respective index entry is searched for and its node displayed.
##
## @end deftypefn
function parallel_doc (keyword)
if ((nargs = nargin ()) > 1)
print_usage ()
endif
## locate installed documentation
persistent infopath = "";
if (isempty (infopath))
[local_list, global_list] = pkg ("list");
if (! isempty (idx = ...
find (strcmp ("parallel",
{structcat(1, local_list{:}).name}),
1)))
idir = local_list{idx}.dir;
elseif (! isempty (idx = ...
find (strcmp ("parallel",
{structcat(1, global_list{:}).name}),
1)))
idir = global_list{idx}.dir;
else
error ("no installed parallel package found");
endif
infopath = fullfile (idir, "doc/", "parallel.info");
## allow for .gz
if (! exist (infopath, "file"))
infopath = strcat (infopath, ".gz");
endif
endif
## display info
INFO = info_program ();
if (nargs)
error_hint = ", maybe the keyword was not found in the index";
status = system (sprintf ("%s %s --index-search \"%s\"",
INFO, infopath, keyword));
else
error_hint = "";
status = system (sprintf ("%s %s", INFO, infopath));
endif
if (status)
if (status == 127)
error ("unable to find info program `%s'", INFO);
else
error ("info program `%s' returned error code %i%s",
INFO, status, error_hint);
endif
endif
endfunction
parallel-3.1.1/octave-parallel.metainfo.xml 000644 001750 001750 00000002164 12771453045 020625 0 ustar 00olaf olaf 000000 000000
octave-parallelwww.octave.org-octave.desktopParallelParallel Computing
Parallel execution package.
multicore computinglocal parallel computingnetwork parallel computingbeowulf clusterhttp://octave.sourceforge.net/parallelhttps://savannah.gnu.org/bugs/?func=additem&group=octaveGPL-3.0+Octave-Forge Communityoctave-maintainers@gnu.orgFSFAP
parallel-3.1.1/DESCRIPTION 000644 001750 001750 00000000614 12771453045 014733 0 ustar 00olaf olaf 000000 000000 Name: parallel
Version: 3.1.1
Date: 2016-09-24
Author: Hayato Fujiwara, Jaroslav Hajek, Olaf Till
Maintainer: Olaf Till
Title: Parallel Computing.
Description: Parallel execution package. See also package mpi, maintained
by Carlo de Falco.
Depends: octave (>= 3.8.0), struct (>= 1.0.12)
BuildRequires: libgnutls..-dev
Autoload: no
License: GPLv3+
Url: http://octave.sf.net
parallel-3.1.1/COPYING 000644 001750 001750 00000111145 12771453045 014262 0 ustar 00olaf olaf 000000 000000 Appendix G GNU GENERAL PUBLIC LICENSE
*************************************
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. `http://fsf.org/'
Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.
Preamble
========
The GNU General Public License is a free, copyleft license for software
and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains
free software for all its users. We, the Free Software Foundation, use
the GNU General Public License for most of our software; it applies
also to any other work released this way by its authors. You can apply
it to your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you
have certain responsibilities if you distribute copies of the software,
or if you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the
manufacturer can do so. This is fundamentally incompatible with the
aim of protecting users' freedom to change the software. The
systematic pattern of such abuse occurs in the area of products for
individuals to use, which is precisely where it is most unacceptable.
Therefore, we have designed this version of the GPL to prohibit the
practice for those products. If such problems arise substantially in
other domains, we stand ready to extend this provision to those domains
in future versions of the GPL, as needed to protect the freedom of
users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
====================
0. Definitions.
"This License" refers to version 3 of the GNU General Public
License.
"Copyright" also means copyright-like laws that apply to other
kinds of works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the
work in a fashion requiring copyright permission, other than the
making of an exact copy. The resulting work is called a "modified
version" of the earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work
based on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it
on a computer or modifying a private copy. Propagation includes
copying, distribution (with or without modification), making
available to the public, and in some countries other activities as
well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user
through a computer network, with no transfer of a copy, is not
conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to
the extent that warranties are provided), that licensees may
convey the work under this License, and how to view a copy of this
License. If the interface presents a list of user commands or
options, such as a menu, a prominent item in the list meets this
criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any
non-source form of a work.
A "Standard Interface" means an interface that either is an
official standard defined by a recognized standards body, or, in
the case of interfaces specified for a particular programming
language, one that is widely used among developers working in that
language.
The "System Libraries" of an executable work include anything,
other than the work as a whole, that (a) is included in the normal
form of packaging a Major Component, but which is not part of that
Major Component, and (b) serves only to enable use of the work
with that Major Component, or to implement a Standard Interface
for which an implementation is available to the public in source
code form. A "Major Component", in this context, means a major
essential component (kernel, window system, and so on) of the
specific operating system (if any) on which the executable work
runs, or a compiler used to produce the work, or an object code
interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including
scripts to control those activities. However, it does not include
the work's System Libraries, or general-purpose tools or generally
available free programs which are used unmodified in performing
those activities but which are not part of the work. For example,
Corresponding Source includes interface definition files
associated with source files for the work, and the source code for
shared libraries and dynamically linked subprograms that the work
is specifically designed to require, such as by intimate data
communication or control flow between those subprograms and other
parts of the work.
The Corresponding Source need not include anything that users can
regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running
a covered work is covered by this License only if the output,
given its content, constitutes a covered work. This License
acknowledges your rights of fair use or other equivalent, as
provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise
remains in force. You may convey covered works to others for the
sole purpose of having them make modifications exclusively for
you, or provide you with facilities for running those works,
provided that you comply with the terms of this License in
conveying all material for which you do not control copyright.
Those thus making or running the covered works for you must do so
exclusively on your behalf, under your direction and control, on
terms that prohibit them from making any copies of your
copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section
10 makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under
article 11 of the WIPO copyright treaty adopted on 20 December
1996, or similar laws prohibiting or restricting circumvention of
such measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such
circumvention is effected by exercising rights under this License
with respect to the covered work, and you disclaim any intention
to limit operation or modification of the work as a means of
enforcing, against the work's users, your or third parties' legal
rights to forbid circumvention of technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the
code; keep intact all notices of the absence of any warranty; and
give all recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these
conditions:
a. The work must carry prominent notices stating that you
modified it, and giving a relevant date.
b. The work must carry prominent notices stating that it is
released under this License and any conditions added under
section 7. This requirement modifies the requirement in
section 4 to "keep intact all notices".
c. You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable
section 7 additional terms, to the whole of the work, and all
its parts, regardless of how they are packaged. This License
gives no permission to license the work in any other way, but
it does not invalidate such permission if you have separately
received it.
d. If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has
interactive interfaces that do not display Appropriate Legal
Notices, your work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered
work, and which are not combined with it such as to form a larger
program, in or on a volume of a storage or distribution medium, is
called an "aggregate" if the compilation and its resulting
copyright are not used to limit the access or legal rights of the
compilation's users beyond what the individual works permit.
Inclusion of a covered work in an aggregate does not cause this
License to apply to the other parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this
License, in one of these ways:
a. Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b. Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for
as long as you offer spare parts or customer support for that
product model, to give anyone who possesses the object code
either (1) a copy of the Corresponding Source for all the
software in the product that is covered by this License, on a
durable physical medium customarily used for software
interchange, for a price no more than your reasonable cost of
physically performing this conveying of source, or (2) access
to copy the Corresponding Source from a network server at no
charge.
c. Convey individual copies of the object code with a copy of
the written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially,
and only if you received the object code with such an offer,
in accord with subsection 6b.
d. Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access
to the Corresponding Source in the same way through the same
place at no further charge. You need not require recipients
to copy the Corresponding Source along with the object code.
If the place to copy the object code is a network server, the
Corresponding Source may be on a different server (operated
by you or a third party) that supports equivalent copying
facilities, provided you maintain clear directions next to
the object code saying where to find the Corresponding Source.
Regardless of what server hosts the Corresponding Source, you
remain obligated to ensure that it is available for as long
as needed to satisfy these requirements.
e. Convey the object code using peer-to-peer transmission,
provided you inform other peers where the object code and
Corresponding Source of the work are being offered to the
general public at no charge under subsection 6d.
A separable portion of the object code, whose source code is
excluded from the Corresponding Source as a System Library, need
not be included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means
any tangible personal property which is normally used for personal,
family, or household purposes, or (2) anything designed or sold for
incorporation into a dwelling. In determining whether a product
is a consumer product, doubtful cases shall be resolved in favor of
coverage. For a particular product received by a particular user,
"normally used" refers to a typical or common use of that class of
product, regardless of the status of the particular user or of the
way in which the particular user actually uses, or expects or is
expected to use, the product. A product is a consumer product
regardless of whether the product has substantial commercial,
industrial or non-consumer uses, unless such uses represent the
only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to
install and execute modified versions of a covered work in that
User Product from a modified version of its Corresponding Source.
The information must suffice to ensure that the continued
functioning of the modified object code is in no case prevented or
interfered with solely because modification has been made.
If you convey an object code work under this section in, or with,
or specifically for use in, a User Product, and the conveying
occurs as part of a transaction in which the right of possession
and use of the User Product is transferred to the recipient in
perpetuity or for a fixed term (regardless of how the transaction
is characterized), the Corresponding Source conveyed under this
section must be accompanied by the Installation Information. But
this requirement does not apply if neither you nor any third party
retains the ability to install modified object code on the User
Product (for example, the work has been installed in ROM).
The requirement to provide Installation Information does not
include a requirement to continue to provide support service,
warranty, or updates for a work that has been modified or
installed by the recipient, or for the User Product in which it
has been modified or installed. Access to a network may be denied
when the modification itself materially and adversely affects the
operation of the network or violates the rules and protocols for
communication across the network.
Corresponding Source conveyed, and Installation Information
provided, in accord with this section must be in a format that is
publicly documented (and with an implementation available to the
public in source code form), and must require no special password
or key for unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of
this License by making exceptions from one or more of its
conditions. Additional permissions that are applicable to the
entire Program shall be treated as though they were included in
this License, to the extent that they are valid under applicable
law. If additional permissions apply only to part of the Program,
that part may be used separately under those permissions, but the
entire Program remains governed by this License without regard to
the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part
of it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material
you add to a covered work, you may (if authorized by the copyright
holders of that material) supplement the terms of this License
with terms:
a. Disclaiming warranty or limiting liability differently from
the terms of sections 15 and 16 of this License; or
b. Requiring preservation of specified reasonable legal notices
or author attributions in that material or in the Appropriate
Legal Notices displayed by works containing it; or
c. Prohibiting misrepresentation of the origin of that material,
or requiring that modified versions of such material be
marked in reasonable ways as different from the original
version; or
d. Limiting the use for publicity purposes of names of licensors
or authors of the material; or
e. Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f. Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified
versions of it) with contractual assumptions of liability to
the recipient, for any liability that these contractual
assumptions directly impose on those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as
you received it, or any part of it, contains a notice stating that
it is governed by this License along with a term that is a further
restriction, you may remove that term. If a license document
contains a further restriction but permits relicensing or
conveying under this License, you may add to a covered work
material governed by the terms of that license document, provided
that the further restriction does not survive such relicensing or
conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in
the form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights
under this License (including any patent licenses granted under
the third paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly
and finally terminates your license, and (b) permanently, if the
copyright holder fails to notify you of the violation by some
reasonable means prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from
that copyright holder, and you cure the violation prior to 30 days
after your receipt of the notice.
Termination of your rights under this section does not terminate
the licenses of parties who have received copies or rights from
you under this License. If your rights have been terminated and
not permanently reinstated, you do not qualify to receive new
licenses for the same material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer
transmission to receive a copy likewise does not require
acceptance. However, nothing other than this License grants you
permission to propagate or modify any covered work. These actions
infringe copyright if you do not accept this License. Therefore,
by modifying or propagating a covered work, you indicate your
acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not
responsible for enforcing compliance by third parties with this
License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a
covered work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or
could give under the previous paragraph, plus a right to
possession of the Corresponding Source of the work from the
predecessor in interest, if the predecessor has it or can get it
with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you
may not impose a license fee, royalty, or other charge for
exercise of rights granted under this License, and you may not
initiate litigation (including a cross-claim or counterclaim in a
lawsuit) alleging that any patent claim is infringed by making,
using, selling, offering for sale, or importing the Program or any
portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based.
The work thus licensed is called the contributor's "contributor
version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner,
permitted by this License, of making, using, or selling its
contributor version, but do not include claims that would be
infringed only as a consequence of further modification of the
contributor version. For purposes of this definition, "control"
includes the right to grant patent sublicenses in a manner
consistent with the requirements of this License.
Each contributor grants you a non-exclusive, worldwide,
royalty-free patent license under the contributor's essential
patent claims, to make, use, sell, offer for sale, import and
otherwise run, modify and propagate the contents of its
contributor version.
In the following three paragraphs, a "patent license" is any
express agreement or commitment, however denominated, not to
enforce a patent (such as an express permission to practice a
patent or covenant not to sue for patent infringement). To
"grant" such a patent license to a party means to make such an
agreement or commitment not to enforce a patent against the party.
If you convey a covered work, knowingly relying on a patent
license, and the Corresponding Source of the work is not available
for anyone to copy, free of charge and under the terms of this
License, through a publicly available network server or other
readily accessible means, then you must either (1) cause the
Corresponding Source to be so available, or (2) arrange to deprive
yourself of the benefit of the patent license for this particular
work, or (3) arrange, in a manner consistent with the requirements
of this License, to extend the patent license to downstream
recipients. "Knowingly relying" means you have actual knowledge
that, but for the patent license, your conveying the covered work
in a country, or your recipient's use of the covered work in a
country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate,
modify or convey a specific copy of the covered work, then the
patent license you grant is automatically extended to all
recipients of the covered work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that
are specifically granted under this License. You may not convey a
covered work if you are a party to an arrangement with a third
party that is in the business of distributing software, under
which you make payment to the third party based on the extent of
your activity of conveying the work, and under which the third
party grants, to any of the parties who would receive the covered
work from you, a discriminatory patent license (a) in connection
with copies of the covered work conveyed by you (or copies made
from those copies), or (b) primarily for and in connection with
specific products or compilations that contain the covered work,
unless you entered into that arrangement, or that patent license
was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order,
agreement or otherwise) that contradict the conditions of this
License, they do not excuse you from the conditions of this
License. If you cannot convey a covered work so as to satisfy
simultaneously your obligations under this License and any other
pertinent obligations, then as a consequence you may not convey it
at all. For example, if you agree to terms that obligate you to
collect a royalty for further conveying from those to whom you
convey the Program, the only way you could satisfy both those
terms and this License would be to refrain entirely from conveying
the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a
single combined work, and to convey the resulting work. The terms
of this License will continue to apply to the part which is the
covered work, but the special requirements of the GNU Affero
General Public License, section 13, concerning interaction through
a network will apply to the combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new
versions of the GNU General Public License from time to time.
Such new versions will be similar in spirit to the present
version, but may differ in detail to address new problems or
concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU
General Public License "or any later version" applies to it, you
have the option of following the terms and conditions either of
that numbered version or of any later version published by the
Free Software Foundation. If the Program does not specify a
version number of the GNU General Public License, you may choose
any version ever published by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that
proxy's public statement of acceptance of a version permanently
authorizes you to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE
COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS"
WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE
RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.
SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES
AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF
THE POSSIBILITY OF SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely
approximates an absolute waiver of all civil liability in
connection with the Program, unless a warranty or assumption of
liability accompanies a copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
===========================
How to Apply These Terms to Your New Programs
=============================================
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these
terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
ONE LINE TO GIVE THE PROGRAM'S NAME AND A BRIEF IDEA OF WHAT IT DOES.
Copyright (C) YEAR NAME OF AUTHOR
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or (at
your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see `http://www.gnu.org/licenses/'.
Also add information on how to contact you by electronic and paper
mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
PROGRAM Copyright (C) YEAR NAME OF AUTHOR
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the
appropriate parts of the General Public License. Of course, your
program's commands might be different; for a GUI interface, you would
use an "about box".
You should also get your employer (if you work as a programmer) or
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. For more information on this, and how to apply and follow
the GNU GPL, see `http://www.gnu.org/licenses/'.
The GNU General Public License does not permit incorporating your
program into proprietary programs. If your program is a subroutine
library, you may consider it more useful to permit linking proprietary
applications with the library. If this is what you want to do, use the
GNU Lesser General Public License instead of this License. But first,
please read `http://www.gnu.org/philosophy/why-not-lgpl.html'.
parallel-3.1.1/NEWS 000644 001750 001750 00000010556 12771453045 013732 0 ustar 00olaf olaf 000000 000000 parallel 3.1.1
--------------
** Some build fixes. Builds with Octave 4.2.
** Links to core Octave documentation work now in html version of
package documentation.
parallel 3.1.0
--------------
** Added general package documentation, accessible with function
'parallel_doc'.
** Introduced dependency on package 'struct'.
** Fixed handling of argument and output dimensions in netcellfun and
netarrayfun.
** In connecting a cluster, package version and connection protocol
are checked. Will work only with packages from this version
upwards.
** Variables are transferred more efficiently.
** Build fixes for new Octave versions.
** If cluster functions are to be disabled at configure time, this
has to be done always explicitely now.
parallel 3.0.4
--------------
** Building of cluster functions disabled by default for platforms on
which they currently can't be built or used. This enables building
of at least the functions for local parallel computation on these
platforms.
** Fix issue in package building if gnutls headers are not present.
** Make compatible with Octaves new exception-based error
handling. Compatibility with old error handling up to Octave-4.0
is retained.
** Fix bug for usage with 64bit indexing.
parallel 3.0.3
--------------
** Fix bug in package building if SRP is not provided by gnutls.
** Documentation spelling and typo fixes.
parallel 3.0.2
--------------
** Functions 'send()' and 'recv()' have been renamed to 'psend()' and
'precv()', respectively, since previous names are used by the
sockets package.
parallel 3.0.1
--------------
** Fix some issues in package building, e.g. in building if libgnutls
is not present. Note that a libgnutls library (including its
"development package" on some systems) which supports the SRP
protocol is needed to build the 'parallel' package with TLS-based
connections enabled.
parallel 3.0.0
--------------
** 'parcellfun' and 'pararrayfun' accept an option "CumFunc" for
cumulative results.
** Fix handling of option "UniformOutput" with option "Vectorized" in
'pararrayfun'.
** Function 'connect()' has been renamed to 'pconnect()' since the
previous name is used by the control package.
** New functions 'netcellfun' and 'netarrayfun' for remote parallel
execution.
** New convenience function 'rfeval' for single remote function
execution.
** New function 'install_vars' to distribute named variables over the
parallel cluster.
** Better documentation of cluster functions. Start with the function
documentation of 'pconnect()' and 'pserver()', and go on with the
documentation of the functions referenced therein. The
README.parallel file has been removed.
** The value returned by pconnect and the variable 'sockets' held by
pserver, holding the network connections, are now opaque. Indexing
the connections in this value should work as with the matrix used
before.
** Connections can be based on TLS-SRP, which is now the default. New
function parallel_generate_srp_data generates authorization data.
** Parallel cluster commands hanging in system calls (e.g. trying to
read data that was not sent) can be interrupted with Ctrl-C
(invalidating the network connections in most cases, so that
information within server memory will be lost).
** New functions 'network_get_info' and 'network_set'.
** Within a particular parallel network, servers are supposed to be
unique now. But a server can be a part of several parallel
networks, and successful connection attempts of such overlapping
networks should now be possible even if initiated from different
client machines or client processes at the same time.
** Removed deprecated bw_... group of functions.
parallel 2.2.1
--------------
** The bw_... group of functions has been deprecated and will be
removed in the future.
** Made compatible with Octave 4.0.
** Made parcellfun/pararrayfun a bit more stable.
parallel 2.2.0
--------------
** Included functions parcellfun and pararrayfun from package general.
parallel 2.1.1
--------------
** Bugfix for installation on Windows.
parallel 2.1.0, summary of user-visible changes:
------------------------------------------------
** Connections with equal hostnames are now allowed.
** Fix: avoids zombie processes in server if connection is closed.
parallel-3.1.1/src/ 002755 001750 001750 00000000000 12771453100 014005 5 ustar 00olaf olaf 000000 000000 parallel-3.1.1/src/select_sockets.cc 000644 001750 001750 00000015245 12771453046 017344 0 ustar 00olaf olaf 000000 000000 /*
Copyright (C) 2015, 2016 Olaf Till
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; If not, see .
*/
// PKG_ADD: autoload ("select_sockets", "parallel_interface.oct");
// PKG_DEL: autoload ("select_sockets", "parallel_interface.oct", "remove");
#include
#include
#include
#include
#include "parallel-gnutls.h"
#include
#include
#include
#include
#include
#include
DEFUN_DLD (select_sockets, args, ,
"-*- texinfo -*-\n\
@deftypefn {Loadable Function} {} select_sockets (@var{connections}, @var{timeout})\n\
@deftypefnx {Loadable Function} {} select_sockets (@var{connections}, @var{timeout}, @var{nfds})\n\
Calls Unix @code{select} for data connections in a parallel cluster.\n\
\n\
This function is for advanced usage (and therefore has minimal\n\
documentation), typically the programming of schedulers. It can be\n\
called at the client or at a server.\n\
\n\
@var{connections}: valid connections object (see @code{pconnect} and\n\
@code{pserver}, possibly indexed).\n\
\n\
@var{timeout}: seconds, negative for infinite.\n\
\n\
@var{nfds}: Passed to Unix @code{select} as first argument, see\n\
documentation of Uix @code{select}. Default: @code{FD_SETSIZE}\n\
(platform specific).\n\
\n\
An error is returned if nfds or a watched filedescriptor plus one\n\
exceeds FD_SETSIZE.\n\
\n\
Returns an index vector to @var{connections} indicating connections\n\
with pending input, readable with @code{precv}.\n\
\n\
If called at the client, the command connections are included into the\n\
UNIX @code{select} call and checked for error flags, and\n\
@code{select_sockets} returns an error if a flag for a remote error is\n\
received.\n\
\n\
@seealso{pconnect, pserver, reval, psend, precv, sclose, parallel_generate_srp_data}\n\
@end deftypefn")
{
std::string fname ("select_sockets");
octave_value retval;
if (args.length () < 2 || args.length () > 3 ||
args(0).type_id () != octave_parallel_connections::static_type_id ())
{
print_usage ();
return retval;
}
double atimeout = args(1).double_value ();
int nfds = FD_SETSIZE;
bool err;
if (args.length () == 3)
{
SET_ERR (nfds = args(2).int_value (), err);
}
if (err)
{
print_usage ();
return retval;
}
if (nfds <= 0)
{
error ("%s: 'nfds' must be a positive integer", fname.c_str ());
return retval;
}
if (nfds > FD_SETSIZE)
{
error ("%s: 'nfds' exceeds systems maximum given by FD_SETSIZE",
fname.c_str ());
return retval;
}
const octave_base_value &rep = args(0).get_rep ();
const octave_parallel_connections &cconns =
dynamic_cast (rep);
octave_parallel_connections_rep *conns = cconns.get_rep ();
int nconns = conns->get_connections ().numel ();
if (conns->get_whole_network ()->is_closed ())
{
error ("%s: network is closed", fname.c_str ());
return retval;
}
if (nconns < conns->get_all_connections ().numel ()) // it's a subnet
for (int i = 0; i < nconns; i++)
if (conns->get_connections ()(i)->is_pseudo_connection ())
{
error ("%s: using a subnet and local machine was given as one of the connections (index %i)",
fname.c_str (), i + 1);
return retval;
}
timeval tout;
timeval *timeout = &tout;
if (atimeout < 0)
timeout = NULL;
else
{
double ipart, fpart;
fpart = modf (atimeout, &ipart);
tout.tv_sec = lrint (ipart);
tout.tv_usec = lrint (fpart * 1000);
}
fd_set rfds, wfds, efds;
FD_ZERO (&rfds); FD_ZERO (&wfds); FD_ZERO (&efds);
inthandler_dont_restart_syscalls __inthandler_guard__;
for (int i = 0; i < nconns; i++)
{
if (conns->get_connections ()(i)->is_pseudo_connection ())
continue;
int fid = conns->get_connections ()(i)->get_data_stream ()->
get_strbuf ()->get_fid ();
if (fid >= nfds)
{
error ("%s: file descriptor >= nfds or FD_SETSIZE", fname.c_str ());
return retval;
}
FD_SET (fid, &rfds);
if (! conns->is_server ())
{
fid = conns->get_connections ()(i)->get_cmd_stream ()->
get_strbuf ()->get_fid ();
if (fid >= nfds)
{
error ("%s: file descriptor >= nfds or FD_SETSIZE",
fname.c_str ());
return retval;
}
FD_SET (fid, &rfds);
}
}
// don't restart interrupted select()
int n = select (nfds, &rfds, &wfds, &efds, timeout);
if (n == -1)
{
error ("%s: select system call returned an error", fname.c_str ());
return retval;
}
bool command_errors = false;
RowVector ridx (n);
double *fvec;
int i;
for (i = 0, fvec = ridx.fortran_vec (); i < nconns; i++)
{
if (conns->get_connections ()(i)->is_pseudo_connection ())
continue;
if (FD_ISSET
(conns->get_connections ()(i)->get_data_stream ()->
get_strbuf ()->get_fid (),
&rfds))
{
*fvec = double (i + 1);
fvec++;
}
if (! conns->is_server ())
{
if (FD_ISSET
(conns->get_connections ()(i)->get_cmd_stream ()->
get_strbuf ()->get_fid (),
&rfds))
{
int err;
if ((err = conns->get_connections ()(i)->poll_for_errors ()) < 0)
{
conns->close ();
error ("%s: communication error with server with index %i",
fname.c_str (), i + 1);
return retval;
}
else if (err > 0)
{
c_verror ("%s: a previous command at server with index %i caused an error",
fname.c_str (), i + 1);
command_errors = true;
}
}
}
}
if (command_errors)
{
error ("command error");
return retval;
}
return octave_value (ridx);
}
parallel-3.1.1/src/sensitive-data.cc 000644 001750 001750 00000004140 12771453046 017242 0 ustar 00olaf olaf 000000 000000 /*
Copyright (C) 2015, 2016 Olaf Till
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; If not, see .
*/
#include "parallel-gnutls.h"
void sensitive_string::fill (int n, bool lock)
{
valid = false;
bool err = false;
if (internally_allocated || locked_length)
{
c_verror ("internal error in filling");
return;
}
val.data = new unsigned char[n + 1];
if (val.data)
{
internally_allocated = true;
val.size = n;
if (lock)
{
if (mlock (val.data, n))
{
c_verror ("could not lock memory pages");
return;
}
else
locked_length = n;
}
}
else
{
val.size = 0;
c_verror ("could not allocate memory");
return;
}
int rfd;
if ((rfd = open ("/dev/random", O_RDONLY)) == -1)
{
c_verror ("could not open /dev/random");
return;
}
// reduces each random byte to the 128 characters from 0x20 to 0x9F,
// in order to disallow value 0x0 (end of string) without unevenly
// redistributing the probability of the allowed values
for (int i = 0; i < n; i++)
{
if (read (rfd, &(val.data[i]), 1) != 1)
{
c_verror ("could not read from /dev/random");
err = true;
break;
}
val.data[i] = (unsigned char) (((unsigned int) (val.data[i]>>1)) + 0x20);
}
val.data[n] = '\0';
if (close (rfd))
{
c_verror ("could not close /dev/random");
err = true;
}
if (! err)
valid = true;
}
parallel-3.1.1/src/psend.cc 000644 001750 001750 00000012234 12771453046 015436 0 ustar 00olaf olaf 000000 000000 // Copyright (C) 2002 Hayato Fujiwara
// Copyright (C) 2010-2016 Olaf Till
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; If not, see .
// PKG_ADD: autoload ("psend", "parallel_interface.oct");
// PKG_DEL: autoload ("psend", "parallel_interface.oct", "remove");
#include
#include
#include
#include
#include "parallel-gnutls.h"
#include
#include
#include
#include
#if HAVE_UNISTD_H
#include
#endif
DEFUN_DLD (psend, args, ,
"-*- texinfo -*-\n\
@deftypefn {Loadable Function} {} psend (@var{value}, @var{connections})\n\
Send the value in variable @var{value} to all parallel cluster machines specified by @var{connections}.\n\
\n\
This function can be called both at the client machine and (with\n\
@code{reval}) at a server machine. See @code{pconnect} for a\n\
description of the @var{connections} variable, and @code{pserver} for\n\
a description of this variable (named @code{sockets}) at the server\n\
side. @var{connections} can contain all connections of the network, a\n\
subset of them, or a single connection. The machine at which\n\
@code{psend} was called (client or server), if contained in the\n\
@var{connections} variable, is ignored.\n\
\n\
The value sent with @code{psend} must be received with @code{precv} at\n\
the target machine. Note that values can be sent to each machine, even\n\
from a server machine to a different server machine.\n\
\n\
If @code{psend} is called at the client machine, a corresponding\n\
@code{precv} should have been called before at the target machine,\n\
otherwise the client will hang if @var{value} contains large data\n\
(which can not be held by the operating systems socket buffers).\n\
\n\
@seealso{pconnect, pserver, reval, precv, sclose, parallel_generate_srp_data, select_sockets}\n\
@end deftypefn")
{
std::string fname ("psend");
octave_value retval;
if (args.length () != 2 ||
args(1).type_id () != octave_parallel_connections::static_type_id ())
{
print_usage ();
return retval;
}
const octave_base_value &rep = args(1).get_rep ();
const octave_parallel_connections &cconns =
dynamic_cast (rep);
octave_parallel_connections_rep *conns = cconns.get_rep ();
int nconns = conns->get_connections ().numel ();
if (conns->get_whole_network ()->is_closed ())
{
error ("%s: network is closed", fname.c_str ());
return retval;
}
inthandler_dont_restart_syscalls __inthandler_guard__;
// check each connection before a command is sent over any
if (nconns < conns->get_all_connections ().numel ()) // it's a subnet
for (int i = 0; i < nconns; i++)
if (conns->get_connections ()(i)->is_pseudo_connection ())
{
error ("%s: using a subnet and own node was given as one of the receivers (index %i)",
fname.c_str (), i + 1);
return retval;
}
if (! conns->is_server ())
{
bool command_errors = false, stream_errors = false;
int err;
for (int i = 0; i < nconns; i++)
{
if (conns->get_connections ()(i)->is_pseudo_connection ())
continue;
if ((err = conns->get_connections ()(i)->poll_for_errors ()))
{
if (err > 0)
{
c_verror ("%s: a previous command at server with index %i caused an error",
fname.c_str (), i + 1);
command_errors = true;
}
else // err < 0
{
c_verror ("%s: communication error with server with index %i",
fname.c_str (), i + 1);
stream_errors = true;
}
}
}
if (stream_errors)
conns->close ();
if (stream_errors || command_errors)
{
error ("error in psend");
return retval;
}
}
double sid;
// args(0) is const, make copy
octave_value val = args(0);
for (int i = 0; i < nconns; i++)
{
if (conns->get_connections ()(i)->is_pseudo_connection ())
continue;
if (minimal_write_data (conns->get_connections ()(i)->
get_data_stream ()->get_ostream (), val)
|| ! conns->get_connections ()(i)->get_data_stream ()->good ())
{
conns->close ();
error ("%s: communication error", fname.c_str ());
return retval;
}
}
return retval;
}
parallel-3.1.1/src/__netcellfun_guardfun__.copy_to_m 000644 001750 001750 00000002301 12771453045 022547 0 ustar 00olaf olaf 000000 000000 ## Copyright (C) 2015, 2016 Olaf Till
##
## This program is free software; you can redistribute it and/or modify it under
## the terms of the GNU General Public License as published by the Free Software
## Foundation; either version 3 of the License, or (at your option) any later
## version.
##
## This program is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
## details.
##
## You should have received a copy of the GNU General Public License along with
## this program; if not, see .
## -*- texinfo -*-
## @deftypefn{Function File} {} __netcellfun_guardfun__ (@dots{})
##
## Undocumented internal function.
##
## @end deftypefn
function varargout = __netcellfun_guardfun__ (func, errh, idx, varargin)
## This must be an extra function file to be visible at the remote
## side.
nout = nargout ();
try
[varargout{1:nout}] = func (varargin{:});
catch
errs = lasterror ();
errs.index = idx;
[varargout{1:nout}] = errh (errs, varargin{:});
end_try_catch
endfunction
parallel-3.1.1/src/m4/ 002755 001750 001750 00000000000 12771453046 014336 5 ustar 00olaf olaf 000000 000000 parallel-3.1.1/src/m4/std-gnu11.m4 000644 001750 001750 00000057625 12771453046 016340 0 ustar 00olaf olaf 000000 000000 # Prefer GNU C11 and C++11 to earlier versions. -*- coding: utf-8 -*-
# This implementation is taken from GNU Autoconf lib/autoconf/c.m4
# commit 017d5ddd82854911f0119691d91ea8a1438824d6
# dated Sun Apr 3 13:57:17 2016 -0700
# This implementation will be obsolete once we can assume Autoconf 2.70
# or later is installed everywhere a Gnulib program might be developed.
# Copyright (C) 2001-2016 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
# Written by David MacKenzie, with help from
# Akim Demaille, Paul Eggert,
# François Pinard, Karl Berry, Richard Pixley, Ian Lance Taylor,
# Roland McGrath, Noah Friedman, david d zuhn, and many others.
# AC_PROG_CC([COMPILER ...])
# --------------------------
# COMPILER ... is a space separated list of C compilers to search for.
# This just gives the user an opportunity to specify an alternative
# search list for the C compiler.
AC_DEFUN_ONCE([AC_PROG_CC],
[AC_LANG_PUSH(C)dnl
AC_ARG_VAR([CC], [C compiler command])dnl
AC_ARG_VAR([CFLAGS], [C compiler flags])dnl
_AC_ARG_VAR_LDFLAGS()dnl
_AC_ARG_VAR_LIBS()dnl
_AC_ARG_VAR_CPPFLAGS()dnl
m4_ifval([$1],
[AC_CHECK_TOOLS(CC, [$1])],
[AC_CHECK_TOOL(CC, gcc)
if test -z "$CC"; then
dnl Here we want:
dnl AC_CHECK_TOOL(CC, cc)
dnl but without the check for a tool without the prefix.
dnl Until the check is removed from there, copy the code:
if test -n "$ac_tool_prefix"; then
AC_CHECK_PROG(CC, [${ac_tool_prefix}cc], [${ac_tool_prefix}cc])
fi
fi
if test -z "$CC"; then
AC_CHECK_PROG(CC, cc, cc, , , /usr/ucb/cc)
fi
if test -z "$CC"; then
AC_CHECK_TOOLS(CC, cl.exe)
fi
if test -z "$CC"; then
AC_CHECK_TOOL(CC, clang)
fi
])
test -z "$CC" && AC_MSG_FAILURE([no acceptable C compiler found in \$PATH])
# Provide some information about the compiler.
_AS_ECHO_LOG([checking for _AC_LANG compiler version])
set X $ac_compile
ac_compiler=$[2]
for ac_option in --version -v -V -qversion -version; do
_AC_DO_LIMIT([$ac_compiler $ac_option >&AS_MESSAGE_LOG_FD])
done
m4_expand_once([_AC_COMPILER_EXEEXT])[]dnl
m4_expand_once([_AC_COMPILER_OBJEXT])[]dnl
_AC_LANG_COMPILER_GNU
if test $ac_compiler_gnu = yes; then
GCC=yes
else
GCC=
fi
_AC_PROG_CC_G
dnl
dnl Set ac_prog_cc_stdc to the supported C version.
dnl Also set the documented variable ac_cv_prog_cc_stdc;
dnl its name was chosen when it was cached, but it is no longer cached.
_AC_PROG_CC_C11([ac_prog_cc_stdc=c11
ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11],
[_AC_PROG_CC_C99([ac_prog_cc_stdc=c99
ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99],
[_AC_PROG_CC_C89([ac_prog_cc_stdc=c89
ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89],
[ac_prog_cc_stdc=no
ac_cv_prog_cc_stdc=no])])])
dnl
AC_LANG_POP(C)dnl
])# AC_PROG_CC
# AC_PROG_CXX([LIST-OF-COMPILERS])
# --------------------------------
# LIST-OF-COMPILERS is a space separated list of C++ compilers to search
# for (if not specified, a default list is used). This just gives the
# user an opportunity to specify an alternative search list for the C++
# compiler.
# aCC HP-UX C++ compiler much better than `CC', so test before.
# FCC Fujitsu C++ compiler
# KCC KAI C++ compiler
# RCC Rational C++
# xlC_r AIX C Set++ (with support for reentrant code)
# xlC AIX C Set++
AC_DEFUN([AC_PROG_CXX],
[AC_LANG_PUSH(C++)dnl
AC_ARG_VAR([CXX], [C++ compiler command])dnl
AC_ARG_VAR([CXXFLAGS], [C++ compiler flags])dnl
_AC_ARG_VAR_LDFLAGS()dnl
_AC_ARG_VAR_LIBS()dnl
_AC_ARG_VAR_CPPFLAGS()dnl
_AC_ARG_VAR_PRECIOUS([CCC])dnl
if test -z "$CXX"; then
if test -n "$CCC"; then
CXX=$CCC
else
AC_CHECK_TOOLS(CXX,
[m4_default([$1],
[g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++])],
g++)
fi
fi
# Provide some information about the compiler.
_AS_ECHO_LOG([checking for _AC_LANG compiler version])
set X $ac_compile
ac_compiler=$[2]
for ac_option in --version -v -V -qversion; do
_AC_DO_LIMIT([$ac_compiler $ac_option >&AS_MESSAGE_LOG_FD])
done
m4_expand_once([_AC_COMPILER_EXEEXT])[]dnl
m4_expand_once([_AC_COMPILER_OBJEXT])[]dnl
_AC_LANG_COMPILER_GNU
if test $ac_compiler_gnu = yes; then
GXX=yes
else
GXX=
fi
_AC_PROG_CXX_G
_AC_PROG_CXX_CXX11([ac_prog_cxx_stdcxx=cxx11
ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx11
ac_cv_prog_cxx_cxx98=$ac_cv_prog_cxx_cxx11],
[_AC_PROG_CXX_CXX98([ac_prog_cxx_stdcxx=cxx98
ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx98],
[ac_prog_cxx_stdcxx=no
ac_cv_prog_cxx_stdcxx=no])])
AC_LANG_POP(C++)dnl
])# AC_PROG_CXX
# _AC_C_STD_TRY(STANDARD, TEST-PROLOGUE, TEST-BODY, OPTION-LIST,
# ACTION-IF-AVAILABLE, ACTION-IF-UNAVAILABLE)
# --------------------------------------------------------------
# Check whether the C compiler accepts features of STANDARD (e.g `c89', `c99')
# by trying to compile a program of TEST-PROLOGUE and TEST-BODY. If this fails,
# try again with each compiler option in the space-separated OPTION-LIST; if one
# helps, append it to CC. If eventually successful, run ACTION-IF-AVAILABLE,
# else ACTION-IF-UNAVAILABLE.
AC_DEFUN([_AC_C_STD_TRY],
[AC_MSG_CHECKING([for $CC option to enable ]m4_translit($1, [c], [C])[ features])
AC_CACHE_VAL(ac_cv_prog_cc_$1,
[ac_cv_prog_cc_$1=no
ac_save_CC=$CC
AC_LANG_CONFTEST([AC_LANG_PROGRAM([$2], [$3])])
for ac_arg in '' $4
do
CC="$ac_save_CC $ac_arg"
_AC_COMPILE_IFELSE([], [ac_cv_prog_cc_$1=$ac_arg])
test "x$ac_cv_prog_cc_$1" != "xno" && break
done
rm -f conftest.$ac_ext
CC=$ac_save_CC
])# AC_CACHE_VAL
ac_prog_cc_stdc_options=
case "x$ac_cv_prog_cc_$1" in
x)
AC_MSG_RESULT([none needed]) ;;
xno)
AC_MSG_RESULT([unsupported]) ;;
*)
ac_prog_cc_stdc_options=" $ac_cv_prog_cc_$1"
CC=$CC$ac_prog_cc_stdc_options
AC_MSG_RESULT([$ac_cv_prog_cc_$1]) ;;
esac
AS_IF([test "x$ac_cv_prog_cc_$1" != xno], [$5], [$6])
])# _AC_C_STD_TRY
# _AC_C_C99_TEST_HEADER
# ---------------------
# A C header suitable for testing for C99.
AC_DEFUN([_AC_C_C99_TEST_HEADER],
[[#include
#include
#include
#include
#include
#include
// Check varargs macros. These examples are taken from C99 6.10.3.5.
#define debug(...) fprintf (stderr, __VA_ARGS__)
#define showlist(...) puts (#__VA_ARGS__)
#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
static void
test_varargs_macros (void)
{
int x = 1234;
int y = 5678;
debug ("Flag");
debug ("X = %d\n", x);
showlist (The first, second, and third items.);
report (x>y, "x is %d but y is %d", x, y);
}
// Check long long types.
#define BIG64 18446744073709551615ull
#define BIG32 4294967295ul
#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
#if !BIG_OK
your preprocessor is broken;
#endif
#if BIG_OK
#else
your preprocessor is broken;
#endif
static long long int bignum = -9223372036854775807LL;
static unsigned long long int ubignum = BIG64;
struct incomplete_array
{
int datasize;
double data[];
};
struct named_init {
int number;
const wchar_t *name;
double average;
};
typedef const char *ccp;
static inline int
test_restrict (ccp restrict text)
{
// See if C++-style comments work.
// Iterate through items via the restricted pointer.
// Also check for declarations in for loops.
for (unsigned int i = 0; *(text+i) != '\0'; ++i)
continue;
return 0;
}
// Check varargs and va_copy.
static bool
test_varargs (const char *format, ...)
{
va_list args;
va_start (args, format);
va_list args_copy;
va_copy (args_copy, args);
const char *str = "";
int number = 0;
float fnumber = 0;
while (*format)
{
switch (*format++)
{
case 's': // string
str = va_arg (args_copy, const char *);
break;
case 'd': // int
number = va_arg (args_copy, int);
break;
case 'f': // float
fnumber = va_arg (args_copy, double);
break;
default:
break;
}
}
va_end (args_copy);
va_end (args);
return *str && number && fnumber;
}]])# _AC_C_C99_TEST_HEADER
# _AC_C_C99_TEST_BODY
# -------------------
# A C body suitable for testing for C99, assuming the corresponding header.
AC_DEFUN([_AC_C_C99_TEST_BODY],
[[
// Check bool.
_Bool success = false;
// Check restrict.
if (test_restrict ("String literal") == 0)
success = true;
char *restrict newvar = "Another string";
// Check varargs.
success &= test_varargs ("s, d' f .", "string", 65, 34.234);
test_varargs_macros ();
// Check flexible array members.
struct incomplete_array *ia =
malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
ia->datasize = 10;
for (int i = 0; i < ia->datasize; ++i)
ia->data[i] = i * 1.234;
// Check named initializers.
struct named_init ni = {
.number = 34,
.name = L"Test wide string",
.average = 543.34343,
};
ni.number = 58;
int dynamic_array[ni.number];
dynamic_array[ni.number - 1] = 543;
// work around unused variable warnings
return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x'
|| dynamic_array[ni.number - 1] != 543);
]])
# _AC_PROG_CC_C99 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE])
# ----------------------------------------------------------------
# If the C compiler is not in ISO C99 mode by default, try to add an
# option to output variable CC to make it so. This macro tries
# various options that select ISO C99 on some system or another. It
# considers the compiler to be in ISO C99 mode if it handles _Bool,
# // comments, flexible array members, inline, long long int, mixed
# code and declarations, named initialization of structs, restrict,
# va_copy, varargs macros, variable declarations in for loops and
# variable length arrays.
AC_DEFUN([_AC_PROG_CC_C99],
[_AC_C_STD_TRY([c99],
[_AC_C_C99_TEST_HEADER],
[_AC_C_C99_TEST_BODY],
dnl Try
dnl GCC -std=gnu99 (unused restrictive modes: -std=c99 -std=iso9899:1999)
dnl IBM XL C -qlanglvl=extc1x (V12.1; does not pass C11 test)
dnl IBM XL C -qlanglvl=extc99
dnl (pre-V12.1; unused restrictive mode: -qlanglvl=stdc99)
dnl HP cc -AC99
dnl Intel ICC -std=c99, -c99 (deprecated)
dnl IRIX -c99
dnl Solaris -D_STDC_C99=
dnl cc's -xc99 option uses linker magic to define the external
dnl symbol __xpg4 as if by "int __xpg4 = 1;", which enables C99
dnl behavior for C library functions. This is not wanted here,
dnl because it means that a single module compiled with -xc99
dnl alters C runtime behavior for the entire program, not for
dnl just the module. Instead, define the (private) symbol
dnl _STDC_C99, which suppresses a bogus failure in .
dnl The resulting compiler passes the test case here, and that's
dnl good enough. For more, please see the thread starting at:
dnl http://lists.gnu.org/archive/html/autoconf/2010-12/msg00059.html
dnl Tru64 -c99
dnl with extended modes being tried first.
[[-std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc1x -qlanglvl=extc99]], [$1], [$2])[]dnl
])# _AC_PROG_CC_C99
# _AC_PROG_CC_C11 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE])
# ----------------------------------------------------------------
# If the C compiler is not in ISO C11 mode by default, try to add an
# option to output variable CC to make it so. This macro tries
# various options that select ISO C11 on some system or another. It
# considers the compiler to be in ISO C11 mode if it handles _Alignas,
# _Alignof, _Noreturn, _Static_assert, UTF-8 string literals,
# duplicate typedefs, and anonymous structures and unions.
AC_DEFUN([_AC_PROG_CC_C11],
[_AC_C_STD_TRY([c11],
[_AC_C_C99_TEST_HEADER[
// Check _Alignas.
char _Alignas (double) aligned_as_double;
char _Alignas (0) no_special_alignment;
extern char aligned_as_int;
char _Alignas (0) _Alignas (int) aligned_as_int;
// Check _Alignof.
enum
{
int_alignment = _Alignof (int),
int_array_alignment = _Alignof (int[100]),
char_alignment = _Alignof (char)
};
_Static_assert (0 < -_Alignof (int), "_Alignof is signed");
// Check _Noreturn.
int _Noreturn does_not_return (void) { for (;;) continue; }
// Check _Static_assert.
struct test_static_assert
{
int x;
_Static_assert (sizeof (int) <= sizeof (long int),
"_Static_assert does not work in struct");
long int y;
};
// Check UTF-8 literals.
#define u8 syntax error!
char const utf8_literal[] = u8"happens to be ASCII" "another string";
// Check duplicate typedefs.
typedef long *long_ptr;
typedef long int *long_ptr;
typedef long_ptr long_ptr;
// Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1.
struct anonymous
{
union {
struct { int i; int j; };
struct { int k; long int l; } w;
};
int m;
} v1;
]],
[_AC_C_C99_TEST_BODY[
v1.i = 2;
v1.w.k = 5;
_Static_assert ((offsetof (struct anonymous, i)
== offsetof (struct anonymous, w.k)),
"Anonymous union alignment botch");
]],
dnl Try
dnl GCC -std=gnu11 (unused restrictive mode: -std=c11)
dnl with extended modes being tried first.
dnl
dnl Do not try -qlanglvl=extc1x, because IBM XL C V12.1 (the latest version as
dnl of September 2012) does not pass the C11 test. For now, try extc1x when
dnl compiling the C99 test instead, since it enables _Static_assert and
dnl _Noreturn, which is a win. If -qlanglvl=extc11 or -qlanglvl=extc1x passes
dnl the C11 test in some future version of IBM XL C, we'll add it here,
dnl preferably extc11.
[[-std=gnu11]], [$1], [$2])[]dnl
])# _AC_PROG_CC_C11
# AC_PROG_CC_C89
# --------------
# Do not use AU_ALIAS here and in AC_PROG_CC_C99 and AC_PROG_CC_STDC,
# as that'd be incompatible with how Automake redefines AC_PROG_CC. See
# .
AU_DEFUN([AC_PROG_CC_C89],
[AC_REQUIRE([AC_PROG_CC])],
[$0 is obsolete; use AC_PROG_CC]
)
# AC_PROG_CC_C99
# --------------
AU_DEFUN([AC_PROG_CC_C99],
[AC_REQUIRE([AC_PROG_CC])],
[$0 is obsolete; use AC_PROG_CC]
)
# AC_PROG_CC_STDC
# ---------------
AU_DEFUN([AC_PROG_CC_STDC],
[AC_REQUIRE([AC_PROG_CC])],
[$0 is obsolete; use AC_PROG_CC]
)
# AC_C_PROTOTYPES
# ---------------
# Check if the C compiler supports prototypes, included if it needs
# options.
AC_DEFUN([AC_C_PROTOTYPES],
[AC_REQUIRE([AC_PROG_CC])dnl
if test "$ac_prog_cc_stdc" != no; then
AC_DEFINE(PROTOTYPES, 1,
[Define to 1 if the C compiler supports function prototypes.])
AC_DEFINE(__PROTOTYPES, 1,
[Define like PROTOTYPES; this can be used by system headers.])
fi
])# AC_C_PROTOTYPES
# _AC_CXX_STD_TRY(STANDARD, TEST-PROLOGUE, TEST-BODY, OPTION-LIST,
# ACTION-IF-AVAILABLE, ACTION-IF-UNAVAILABLE)
# ----------------------------------------------------------------
# Check whether the C++ compiler accepts features of STANDARD (e.g
# `cxx98', `cxx11') by trying to compile a program of TEST-PROLOGUE
# and TEST-BODY. If this fails, try again with each compiler option
# in the space-separated OPTION-LIST; if one helps, append it to CXX.
# If eventually successful, run ACTION-IF-AVAILABLE, else
# ACTION-IF-UNAVAILABLE.
AC_DEFUN([_AC_CXX_STD_TRY],
[AC_MSG_CHECKING([for $CXX option to enable ]m4_translit(m4_translit($1, [x], [+]), [a-z], [A-Z])[ features])
AC_LANG_PUSH(C++)dnl
AC_CACHE_VAL(ac_cv_prog_cxx_$1,
[ac_cv_prog_cxx_$1=no
ac_save_CXX=$CXX
AC_LANG_CONFTEST([AC_LANG_PROGRAM([$2], [$3])])
for ac_arg in '' $4
do
CXX="$ac_save_CXX $ac_arg"
_AC_COMPILE_IFELSE([], [ac_cv_prog_cxx_$1=$ac_arg])
test "x$ac_cv_prog_cxx_$1" != "xno" && break
done
rm -f conftest.$ac_ext
CXX=$ac_save_CXX
])# AC_CACHE_VAL
ac_prog_cxx_stdcxx_options=
case "x$ac_cv_prog_cxx_$1" in
x)
AC_MSG_RESULT([none needed]) ;;
xno)
AC_MSG_RESULT([unsupported]) ;;
*)
ac_prog_cxx_stdcxx_options=" $ac_cv_prog_cxx_$1"
CXX=$CXX$ac_prog_cxx_stdcxx_options
AC_MSG_RESULT([$ac_cv_prog_cxx_$1]) ;;
esac
AC_LANG_POP(C++)dnl
AS_IF([test "x$ac_cv_prog_cxx_$1" != xno], [$5], [$6])
])# _AC_CXX_STD_TRY
# _AC_CXX_CXX98_TEST_HEADER
# -------------------------
# A C++ header suitable for testing for CXX98.
AC_DEFUN([_AC_CXX_CXX98_TEST_HEADER],
[[
#include
#include
#include
#include
#include
#include
#include