I have just installed parallel
on my machine (Linux Mint 20, Octave version: 5.2.0).
I am trying to run an example code taken from here but I get this error with pararrayfun
:
error: 'myfun' undefined near line 1 column 6
execution error
error: __parcellfun_get_next_result__: could not receive result
I read here that pararrayfun
requires a return value to work, which is the case in the example (see code below).
# In this script 4 ways of calculating the values of a one-dimensional function
# are compared, the time taken by each way is measured and it is verified that
# there are no discrepancies in the results.
pkg load parallel
nmax = 10000; # Number of points where the function is calculated
function [a,b] = myfun(n); # Function used in this test
a = pi*(n-2)/n;
f = @(x) (cos(x).^n + sin(x).^(n-1));
b = quadgk(f,0,a);
endfunction
# Fist method, using a for loop, defining the function to calculate
# within the loop.
tic
for n = 1:nmax;
a1(n) = pi*(n-2)/n;
b1(n) = quadgk(@(x) (cos(x).^n + sin(x).^(n-1)),0,a1(n));
endfor
t1 = toc
# Second method, using a for loop and calling "myfun"
tic
for n = 1:nmax;
[a2(n),b2(n)] = myfun(n);
endfor
t2= toc
# Third method, using arrayfun to call "myfun"
tic
ni = 1:nmax;
[a3,b3] = arrayfun("myfun",ni);
t3 = toc
# Forth method, using parrayfun to call "myfun"
tic
ni = 1:nmax;
[a4,b4] = pararrayfun(4,@(n) myfun(n),ni);
t4 = toc
# Are discrepancies in the results?
discrepancies_1 = max(a2-a1) + max(b2-b1) + max(a3-a1)
discrepancies_2 = max(b3-b1) + max(a4-a1) + max(b4-b1)
What could be the problem?
I finally figured out the problem thanks to this post in the GNU Octave discourse group.
The way the “parallel” package works in Octave is that it spawns various “independent” instances of Octave and runs the given code in all of those. For this to work correctly, all necessary functions must be accessible in all of those instances. If I understand your code correctly, you define myFun inline. That way it will only be defined in the “main” instance. Move that function to a dedicated file and store it in a place that is in the load path of all instances. (Maybe use .octaverc to add it to your default load path.)
So basically I had to move my function definition in a separate file "myfun.m" (as also suggested by user Cris Luengo in the comments to my question), and move this file in a folder which is in Octave load path.
To do this, I have create a new dedicated folder ("~/octave/custom_funcs"), and added this to the load path with addpath("~/octave/custom_funcs")
.
Hope this will be helpful for anybody.