Skip to content

Parallel evaluation inefficiency #1

@zymbuzz

Description

@zymbuzz

% 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions