Date: Tue, 16 Feb 2010 09:47:57 +0100
From: Luca Favatella <slacky...@gmail.com>
Subject:
On 08/02/2010, Luca Favatella <slacky...@gmail.com> wrote:
> On 08/02/2010, Muthiah Annamalai <muthusp...@gmail.com> wrote:
[...]
> Great! Thanks for your interest and contribution.
> I'd prefer to keep ga package Matlab compatible, so I locally started
> to implement handling of "UseParallel" [0] and "Vectorized" [1]
> options. Below you can read the description I'm adding for them. I
> hope to commit this code by this week. Then we will be able to decide
> if it is possible to add your ideas (or other ideas in this email
> thread) in a Matlab-compatible way.
| (Sorry for the delay.)
|
| Now modifying one line in __ga_scores__.m it is possible to integrate
| parallel evaluation (I marked that line with TODO).
| You can commit you changes yourself, or please provide me a patch.
|
| Cheers,
| Luca Favatella
Hello there,
Thanks for modify the toolbox to allow for the vectorized solver support.
I found it necessary to add option Ncore to the GA optimset default functions,
as default_options.Ncores = 1; .
The patch uses essentially the same mechanism of separate processess,
( despite the excellent suggestions to use MPI and parcellfun() ) as I found
them to have some advantages which only MPI could give for large data sets.
Jaroslav & Riccardo Corradini for your suggestions.
The patch touches the following files:
1. gaoptimset.m
2. __gaoptimset_default_options__.m
3. __ga_scores__.m
and introduces two new files,
4. __ga_multicore_scores__.m
5. __ga_multicore_helper__.m
I hope they are acceptable changes.
Let me know what you think.
Best,
-Muthu
Index: __gaoptimset_default_options__.m
===================================================================
--- __gaoptimset_default_options__.m (revision 6922)
+++ __gaoptimset_default_options__.m (working copy)
@@ -50,4 +50,6 @@
#default_options.TolFun = 1e-6;
default_options.UseParallel = "never";
default_options.Vectorized = "off";
-endfunction
\ No newline at end of file
+ default_options.Ncores = 1;
+endfunction
+
Index: __ga_scores__.m
===================================================================
--- __ga_scores__.m (revision 6922)
+++ __ga_scores__.m (working copy)
@@ -22,7 +22,16 @@
warning ("'Vectorized' option is 'on': ignoring 'UseParallel' \
option, even if it is 'always'");
endif
- Scores = problem.fitnessfcn (Population);
+ ## use multicore score evaluator
+ ## fitnessfcn has to be a string or m-file name converted from a handle.
+ ## accessible from another process that does not share memory-space.
+ if ( strcmp(class(problem.fitnessfcn),"function_handle") )
+ fitness_fcn_name = func2str( problem.fitnessfcn );
+ else
+ fitness_fcn_name = problem.fitnessfcn;
+ end
+ Scores = __ga_multicore_score__(fitness_fcn_name,population,problem.options.ncores);
+ return
else ## not using vectorized evaluation
if (! strcmp (problem.options.Vectorized, "off"))
error ("'Vectorized' option must be 'on' or 'off'");
@@ -42,4 +51,4 @@
Scores = tmp(1:nrP, 1);
endif
endif
-endfunction
\ No newline at end of file
+endfunction
Index: gaoptimset.m
===================================================================
--- gaoptimset.m (revision 6922)
+++ gaoptimset.m (working copy)
@@ -54,6 +54,8 @@
## "always" | "never" (default) . Parallel evaluation of objective function. TODO: parallel evaluation of nonlinear constraints
## @item Vectorized
## "on" | "off" (default) . Vectorized evaluation of objective function. TODO: vectorized evaluation of nonlinear constraints
+## @item Ncores
+## n | 1 ( default ) . Specify non-zero integer, the number of cores to use for evaluating the Vectorized GA on multicore machines.
## @end table
##
## @seealso{ga}
@@ -92,4 +94,4 @@
%! options = gaoptimset ("EliteCount", 1, "FitnessLimit", 1e-7, "Generations", 1000, "PopInitRange", [-5; 5], "PopulationSize", 200);
%!
%! ## "CrossoverFraction" is not specified, so gaoptimset should put the default value: testing this too
-%! assert ([(getfield (options, "CrossoverFraction")); (getfield (options, "EliteCount")); (getfield (options, "FitnessLimit")); (getfield (options, "Generations")); (getfield (options, "PopInitRange")); (getfield (options, "PopulationSize"))], [0.8; 1; 1e-7; 1000; [-5; 5]; 200])
\ No newline at end of file
+%! assert ([(getfield (options, "CrossoverFraction")); (getfield (options, "EliteCount")); (getfield (options, "FitnessLimit")); (getfield (options, "Generations")); (getfield (options, "PopInitRange")); (getfield (options, "PopulationSize"))], [0.8; 1; 1e-7; 1000; [-5; 5]; 200])
## Copyright (C) 2010 Muthiah Annamalai <gnumu...@users.sf.net>
## Copyright (C) 2008 Luca Favatella <slacky...@gmail.com>
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; If not, see <http://www.gnu.org/licenses/>.
## Author: Luca Favatella <slacky...@gmail.com>
## Version: 5.3.1
##
## Modified for use with Multicore CPU to utilize data-parallel
## nature of GA fitness functions, which we cannot do with limited
## License software. Go Octave!
##
## Assumptions, Fitness functions have to be a m-file, since we
## donot share memory with the child process.
## [ncores] has to be the number of cores to be used in the GA
## fitness evaluation, obtained as struct element of GA problem,
## and passed down to us.
##
function Scores = __ga_multicore_scores__ (fitnessfcn, Population, ncores)
if ( nargin < 2 )
error('__ga_multicore_scores__ : internal function, wrong invocation');
elseif ( nargin < 3 )
ncores = 2;
end
[nrPopulation ncPopulation] = size (Population);
Scores = zeros(nrPopulation,1);
probstr = sprintf('GA-%d-Pop-%dx%d-',round(rand()*1e6),nrPopulation,ncPopulation);
datestr = strrep(ctime(time),':','-');
matfileprefix = sprintf('%s-%s',probstr,datestr);
matfileprefix = strrep(matfileprefix,' ','-');
index = 1;
while ( index <= nrPopulation )
matfilename = {};
## save ncore data elements to file
idx = index;
while ( idx <= nrPopulation && idx < index + ncores )
matfile = sprintf('%s-%d.mat',matfileprefix(1:end-1),idx);
matfilename{idx-index + 1} = matfile;
data = Population(index, 1:ncPopulation);
save('-mat',matfile,'data');
idx = idx + 1;
end
nprocs = idx-index; ## number of processess to be started.
## start the processess with the marshaller function
idx = index; pid_child = zeros( nprocs, 1 );
while ( idx <= nrPopulation && idx < index + ncores )
matfile = matfilename{idx-index + 1};
pid_child( idx - index + 1 ) = system(sprintf('octave -q __ga_multicore_helper__.m "%s" "%s" ',fitnessfcn, matfile),'','async');
idx = idx + 1;
end
## wait for the processess to finish
for idx = 1:nprocs
waitpid( pid_child(idx), 0 );
## fprintf('GA multicore: Terminated Child %d\n',pid_child(idx));
end
## matfilename; nprocs
## load results from the processed cousins
for idx = 1:nprocs
matfile = matfilename{idx}
procfile = sprintf('proc-%s',matfile);
load(procfile); ## has variable fitnessval.
Scores(index+idx-1,1) = fitnessval;
unlink(matfile);
unlink(procfile);
end
index = index + ncores;
end
Scores(1:nrPopulation, 1) = Scores;
endfunction
## Copyright (C) 2010 Muthiah Annamalai <gnumu...@users.sf.net>
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; If not, see <http://www.gnu.org/licenses/>.
##
## usage: octave -q __ga_multicore_helper__.m fitnessfcn matfile
## and save the result in proc-$matfile in the variable fitnessval.
## load(procfile); ## has variable fitnessval.
##
more off
parameters = argv();
## fprintf('__ga_multicore_helper__.m : Child process %d: command line received :\n',getpid());
## parameters
fitnessfcn = parameters{1}; matfile = parameters{2};
load(matfile);
fitnessval = feval( fitnessfcn, data(:) );
## fitnessval
save('-mat',sprintf('proc-%s',matfile),'fitnessval');
------------------------------------------------------------------------------
Download Intel® Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Octave-dev mailing list
Octave-dev@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/octave-dev