Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parallel evaluation inefficiency #1

Open
zymbuzz opened this issue Oct 30, 2022 · 0 comments
Open

Parallel evaluation inefficiency #1

zymbuzz opened this issue Oct 30, 2022 · 0 comments

Comments

@zymbuzz
Copy link

zymbuzz commented Oct 30, 2022

% non-parallel evaluation and remaining NaN-values

Hi, thanks for this great procedure. I would like to note that the parallel evaluation slows down considerably if the function is evaluated as Nan. I would like to suggest a work-around that could be improved on.

        if flgEvalParallel
            qqqqq=find(isnan(fitness.raw));
            tries100=1;
            % fitness.raw(k) = NaN;
            tries = flgEvalParallel;  % in parallel case this is the first re-trial
            % Resample, until fitness is not NaN
            while ~isempty(qqqqq)
                Nnanssss=length(qqqqq);
                Nminattemps=36;
                Nnanreplics=floor(Nminattemps/Nnanssss);
                if Nnanreplics>1
                    qqqqqrepelem=repelem(qqqqq,1,Nnanreplics);
                else
                    qqqqqrepelem=qqqqq;
                end
                NnanTRIES=length(qqqqqrepelem);

                arzTRIES=nan(N,NnanTRIES);
                arxTRIES=arzTRIES;
                arxvalidTRIES=arzTRIES;

                eeeee=0;
                for k=qqqqqrepelem
                    eeeee=eeeee+1;
                    if k <= lambda  % regular samples (not the re-evaluation-samples)
                        arzTRIES(:,eeeee) = randn(N,1); % (re)sample

                        if flgDiagonalOnly
                            arxTRIES(:,eeeee) = xmean + sigma * diagD .* arzTRIES(:,eeeee);              % Eq. (1)
                        else
                            arxTRIES(:,eeeee) = xmean + sigma * (BD * arzTRIES(:,eeeee));                % Eq. (1)
                        end
                    else % re-evaluation solution with index > lambda
                        if flgDiagonalOnly
                            arxTRIES(:,eeeee) = arx(:,k-lambda) + (noiseEpsilon * sigma) * diagD .* randn(N,1);
                        else
                            arxTRIES(:,eeeee) = arx(:,k-lambda) + (noiseEpsilon * sigma) * (BD * randn(N,1));
                        end
                    end

                    % You may handle constraints here. You may either resample
                    % arz(:,k) and/or multiply it with a factor between -1 and 1
                    % (the latter will decrease the overall step size) and
                    % recalculate arx accordingly. Do not change arx or arz in any
                    % other way.

                    if ~bnd.isactive
                        arxvalidTRIES(:,eeeee) = arxTRIES(:,eeeee);
                    else
                        arxvalidTRIES(:,eeeee) = xintobounds(arxTRIES(:,eeeee), lbounds, ubounds);
                    end
                end
                fitnessrawTRIES = feval(fitfun, arxvalidTRIES, varargin{:});
                tries = tries + length(qqqqqrepelem);

                idTRIES=~isnan(fitnessrawTRIES);
                fitnessrawTRIES=fitnessrawTRIES(idTRIES);
                qqqqqrepelem=qqqqqrepelem(idTRIES);
                arzTRIES=arzTRIES(:,idTRIES);
                arxTRIES=arxTRIES(:,idTRIES);
                arxvalidTRIES=arxvalidTRIES(:,idTRIES);

                for k=qqqqq
                    idlalala= find(qqqqqrepelem==k,1,'first');
                    if ~isempty(idlalala)
                        arz(:,k)=arzTRIES(:,idlalala);
                        arx(:,k)=arxTRIES(:,idlalala);
                        arxvalid(:,k)=arxvalidTRIES(:,idlalala);
                        fitness.raw(k)=fitnessrawTRIES(idlalala);
                    end
                end

                qqqqq2=find(isnan(fitness.raw));
                if ~isempty(qqqqq2)
                    countevalNaN = countevalNaN + length(qqqqq2);
                    counteval = counteval + length(qqqqq) - length(qqqqq2); % retries due to NaN are not counted
                end
                if floor(tries/100) == tries100
                    warning([num2str(tries) ...
                        ' NaN objective function values at evaluation ' ...
                        num2str(counteval)]);
                end
                tries100=ceil(tries/100);
                qqqqq=qqqqq2;
            end
        else
            for k=find(isnan(fitness.raw)),
                % fitness.raw(k) = NaN;
                tries = flgEvalParallel;  % in parallel case this is the first re-trial
                % Resample, until fitness is not NaN
                while isnan(fitness.raw(k))
                    if k <= lambda  % regular samples (not the re-evaluation-samples)
                        arz(:,k) = randn(N,1); % (re)sample

                        if flgDiagonalOnly
                            arx(:,k) = xmean + sigma * diagD .* arz(:,k);              % Eq. (1)
                        else
                            arx(:,k) = xmean + sigma * (BD * arz(:,k));                % Eq. (1)
                        end
                    else % re-evaluation solution with index > lambda
                        if flgDiagonalOnly
                            arx(:,k) = arx(:,k-lambda) + (noiseEpsilon * sigma) * diagD .* randn(N,1);
                        else
                            arx(:,k) = arx(:,k-lambda) + (noiseEpsilon * sigma) * (BD * randn(N,1));
                        end
                    end

                    % You may handle constraints here. You may either resample
                    % arz(:,k) and/or multiply it with a factor between -1 and 1
                    % (the latter will decrease the overall step size) and
                    % recalculate arx accordingly. Do not change arx or arz in any
                    % other way.

                    if ~bnd.isactive
                        arxvalid(:,k) = arx(:,k);
                    else
                        arxvalid(:,k) = xintobounds(arx(:,k), lbounds, ubounds);
                    end
                    % You may handle constraints here.  You may copy and alter
                    % (columns of) arxvalid(:,k) only for the evaluation of the
                    % fitness function. arx should not be changed.
                    fitness.raw(k) = feval(fitfun, arxvalid(:,k), varargin{:});
                    tries = tries + 1;
                    if isnan(fitness.raw(k))
                        countevalNaN = countevalNaN + 1;
                    end
                    if mod(tries, 100) == 0
                        warning([num2str(tries) ...
                            ' NaN objective function values at evaluation ' ...
                            num2str(counteval)]);
                    end
                end
                counteval = counteval + 1; % retries due to NaN are not counted
            end
        end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant