MATLAB Answers

How to use GPU arrayfun in App Designer: Function passed as first input argument contains unsupported 'MCOS' language feature 'CLASSDEF'

2 views (last 30 days)
Thomas Hope
Thomas Hope on 28 Apr 2020
Commented: Thomas Hope on 29 Apr 2020
Problem: I'm a student and struggling for building a ideal low-pass filter for images. Considering that generating the mask for the ideal low-pass filter is a element-wise job, I decided to use GPU arrayfun to accelerate my computation and everything worked well in the MATLAB console, until I transformed my code to App Designer.
Here's the code to generate the mask:
function c = func3(app, x, y) % a private class method
dx = x - app.center(1);
dy = y - app.center(2);
d = (dx^2 + dy^2)^(1/2);
if d > app.radius / 2
c = 0;
else
c = 1;
end
end
And the following is my code of the filter
app.shape = gpuArray(size(app.PollutedImage));
app.center = floor(app.shape / 2);
app.radius = min(app.center(1), app.center(2));
[X, Y] = meshgrid(1:app.shape(2), 1:app.shape(1));
spectrum = fftshift(fft2(app.PollutedImage));
if app.CurrentFilter == app.IdealLowPassFilter
mask = gpuArray(arrayfun(@(x, y) func3(app, x, y), X, Y));
filtered_spectrum = spectrum .* mask;
app.EnhancedImage = uint8(real(ifft2(fftshift(filtered_spectrum))));
end
Then I got the following error report:
Function passed as first input argument contains unsupported 'MCOS' language feature 'CLASSDEF'
Now I have to transform the mask generating job to a cpu version which is too slow but at least, doing its job(need to finish my homework) so is there any solution to this problem or using GPU arrayfun in App Designer is impossible, I wonder.
Thank you for your help!

  0 Comments

Sign in to comment.

Accepted Answer

Edric Ellis
Edric Ellis on 28 Apr 2020
I think you simply need to make your function func3 be a normal (non-method) function. You should be able to place it in either an ordinary function on the path, or a function in the private subdirectory of your @class directory, like this:
% @myClass/myClass.m:
classdef myClass
methods
function out = doStuff2(obj)
out = arrayfun(@algoPrivateFunction, gpuArray(1:10));
end
end
end
and:
% @myClass/private/algoPrivateFunction.m:
function out = algoPrivateFunction(x)
out = -x;
end
You'll also want to modify your function so that the data types it accepts are plain numeric types rather than objects. Also note that if your arrayfun call is inside a class method, you must use a plain function handle (like @someFunction) rather than an anonymous function handle (in the form @(x,y) someFunction(x,y)).

More Answers (0)


Translated by