Reputation: 1
I am trying to parallelize a for-loop with numba. I'm new to this library, but after some research I crafted this code, which looked correct in comparison to the examples I studied:
@njit(nopython=True, parallel=True)
def tempFtemp(ftemp_pte, func_F, numPointsEval, pointsToEval):
for i in prange(0, numPointsEval):
ftemp_pte[:,i] = np.hstack(func_F(np.vstack(pointsToEval[:,i])))
return ftemp_pte
ftemp_pte= tempFtemp(ftemp_pte, func_F, numPointsEval, pointsToEval)
When i compile it in my program thought, i get the error "non-precise type pyobject" at the line for i in prange(0, numPointsEval):
. Both ftemp_pte
and pointsToEval
are 2d arrays, numPointsEval
is an integer and func_F
is a random function which will produce the 1d arrays to be stored in ftemp_pte[:,i]
.
Any help on how to figure out what is producing this error would be greatly appreciated.
[EDIT]
The sequential code i have initially (which works) is the following:
def func_F(x):
f= np.zeros((1,2))
f[0,0]= x[0,0]
n= max(np.size(x,0), np.size(x,1))
g = 1 + 9* np.sum(x[1:n])/(n-1)
h = 1 - np.sqrt(f[0,0]/g)
f[0,1] = g * h
F= np.transpose(f)
return F
for i in range(0, numPointsEval):
ftemp_pte[:,i] = np.hstack(func_F(np.vstack(pointsToEval[:,i])))
I also should mention that the use of hstack
and vstack
is needed, so that the format of the arrays created can match ftemp_pte
array. Removing those instructions would result in a mismatch of dimensions.
The variable ftemp_pte
always has 2 rows and x columns. One example of the correct values is
[[0.21875 0.21875 0.21875 0.21875 0.21875 0.21875 0.21875
0.21875 0.21875 0.21875 0.21875 0.21875 0.21875 0.21875
0.21875 0.21875 0.21875 0.21875 0.21875 0.21875 0.21875
0.21875 0.21875 0.21875 0.21875 0.21875 0.21875 0.21875
0.21875 ]
[0.5397286 0.5397286 0.5397286 0.5397286 0.5397286 0.5397286 0.5397286
0.5397286 0.5397286 0.5397286 0.5397286 0.5397286 0.5397286 0.5397286
0.5397286 0.5397286 0.5397286 0.5397286 0.5397286 0.5397286 0.5397286
0.5397286 0.5397286 0.5397286 0.5397286 0.5397286 0.5397286 0.5397286
0.5397286]]
The original purpose of my code is to translate to Python the following Matlab's parfor instruction
parfor i=1:numPointsEval
ftemp_pte(:,i) = feval(func_F,pointsToEval(:,i));
Any help would be greatly appreciated
Upvotes: 0
Views: 484
Reputation: 3437
Answer to problem #2.
As long as you are not really stacking arrays, but reshaping them, you should avoid hstack()
and vstack()
and consider using reshape()
or ravel()
. This way for example:
ftemp_pte[:, i] = func_F(pointsToEval[:, i].reshape(1, -1)).ravel()
However, reshape()
on non-contiguous arrays is not supported by numba.
So I have managed to make your code run with numba by transposing everything to avoid reshaping arrays. The following code does work and may give you some ideas:
@nb.njit
def func_F(x):
f = np.zeros(2) # Simple 1d array
f[0] = x[0]
n = max(x.shape)
g = 1 + 9 * np.sum(x[1:n]) / (n - 1)
h = 1 - np.sqrt(f[0] / g)
f[1] = g * h
return f
@nb.njit(parallel=True)
def tempFtemp(ftemp_pte, func_F, numPointsEval, pointsToEval):
for i in nb.prange(numPointsEval):
ftemp_pte[i] = func_F(pointsToEval[i])
return ftemp_pte
ftemp_pte = np.zeros((2, 5)).T
pointsToEval = np.zeros((2, 5)).T
numPointsEval = 5
ftemp_pte = tempFtemp(ftemp_pte, func_F, numPointsEval, pointsToEval)
print(ftemp_pte.T)
Upvotes: 1
Reputation: 3437
The docs say that first-class function objects can be Numba cfunc compiled functions, JIT compiled functions, and objects that implement the Wrapper Address Protocol.
You can pass a JITted function, as in this simplified example:
@nb.njit
def cos(a):
return np.cos(a)
@nb.njit(parallel=True)
def tempFtemp(ftemp_pte, func_F, numPointsEval, pointsToEval):
for i in nb.prange(numPointsEval):
ftemp_pte[:, i] = func_F(pointsToEval[:, i])
return ftemp_pte
ftemp_pte = tempFtemp(ftemp_pte, np.cos, numPointsEval, pointsToEval) # Error
ftemp_pte = tempFtemp(ftemp_pte, cos, numPointsEval, pointsToEval) # Works
This solves the "non-precise type pyobject" problem, but I have deleted the hstack
and vstack
operations from the example because they produce their own problems and inefficiencies.
Upvotes: 0