source: issm/trunk/test/NightlyRun/runme.m@ 27232

Last change on this file since 27232 was 27232, checked in by Mathieu Morlighem, 3 years ago

merged trunk-jpl and trunk for revision 27230

  • Property svn:executable set to *
File size: 9.9 KB
RevLine 
[4950]1function varargout=runme(varargin)
2%RUNME - test deck for ISSM nightly runs
3%
[27035]4% In a test deck directory (for example, test/NightlyRun) the following
[26744]5% command will launch all existing tests,
[4950]6%
[26744]7% >> runme
8%
9% To run tests 101 and 102,
10%
11% >> runme('id',[101 102])
12%
[4950]13% Available options:
[5085]14% 'id' followed by the list of ids requested
15% 'exclude' ids to be excluded from the test
[25836]16% 'benchmark' 'all' : (all of them)
17% 'nightly' : (nightly run
18% 'validation' : (validation)
19% 'adolc' : validation of adolc tests
20% 'eismint' : validation of eismint tests
21% 'ismip' : validation of ismip-hom tests
22% 'mesh' : validation of mesh tests
23% 'qmu' : validation of dakota tests
24% 'referential' : validation of referential tests
[26744]25% 'slc' : validation of slc tests
[25836]26% 'thermal' : validation of thermal tests
27% 'tranforcing' : validation of transient forcing tests
[16137]28% 'procedure' 'check' : run the test (default)
29% 'update': update the archive
30% 'valgrind': check for memory leaks (default value of md.debug.valgrind needs to be changed manually)
[27035]31% 'ncExport': export netCDF file
[17806]32% 'stoponerror' 1 or 0
[4950]33%
34% Usage:
[15396]35% runme(varargin);
[4950]36%
37% Examples:
38% runme;
[5085]39% runme('exclude',101);
[15396]40% runme('id',102,'procedure','update');
[22758]41% runme('procedure','valgrind','stoponerror',1,'exclude','IdFromString('Dak'));
[26744]42%
43% NOTE:
44% - Will only run test scripts whose names explicitly follow the convention,
45%
46% test<id>.m
47%
48% where <id> is any integer.
49%
[22758]50
[5050]51%Check inputs
[13395]52% {{{
[4950]53if nargout>1
54 help runme
55 error('runme error message: bad usage');
56end
57
[5050]58%recover options
59options=pairoptions(varargin{:});
60% }}}
61
62%Process options
[13395]63%GET benchmark {{{
[5050]64benchmark=getfieldvalue(options,'benchmark','nightly');
[26744]65if ~ismember(benchmark,{'all','nightly','ismip','eismint','thermal','mesh','validation','tranforcing','adolc','slc','qmu'})
[11527]66 disp('runme warning: benchmark not supported, defaulting to test ''nightly''')
[12707]67 benchmark='nightly';
[5050]68end
69% }}}
[13395]70%GET procedure {{{
[4950]71procedure=getfieldvalue(options,'procedure','check');
[27035]72if ~ismember(procedure,{'check','update','valgrind','ncExport'})
[4950]73 disp('runme warning: procedure not supported, defaulting to test ''check''')
74 procedure='check';
75end
[5050]76% }}}
[13395]77%GET output {{{
[5084]78output=getfieldvalue(options,'output','none');
[17806]79if ~ismember(output,{'nightly','none'})
[5084]80 disp('runme warning: output not supported, defaulting to test ''none''')
81 output='none';
82end
83% }}}
[13975]84%GET RANK and NUMPROCS for multithreaded runs {{{
[4999]85rank=getfieldvalue(options,'rank',1);
86numprocs=getfieldvalue(options,'numprocs',1);
87if (numprocs<rank), numprocs=1; end
[5050]88% }}}
[13395]89%GET ids {{{
[27232]90flist=dir; %use dir, as it seems to act OS independent
[4950]91list_ids=[];
[13395]92for i=1:numel(flist),
[26744]93 fname=flist(i).name;
94 if (any(fname=='.')), %Before split, check that file name contains '.'
95 ftokens=strsplit(fname,'.'); %Tokenize file name on '.'
96 if (regexp(ftokens{1},'^test[0-9]+$') &... %Basename must start with 'test' and end with a number
97 strcmp(ftokens{end},'m') ... %Extension (less '.') must be 'm'
98 ),
99 id=sscanf(ftokens{1},'test%d');
100 if isempty(id),
101 disp(['WARNING: ignore file ' flist(i).name]);
102 else
[27232]103 list_ids(end+1)=id; %Keep test id only (strip 'test' and '.m')
[26744]104 end
[14310]105 end
[4950]106 end
107end
[26744]108[i1,i2]=parallelrange(rank,numprocs,length(list_ids)); %Get tests for this cpu only
[4999]109list_ids=list_ids(i1:i2);
110
[4950]111test_ids=getfieldvalue(options,'id',list_ids);
112test_ids=intersect(test_ids,list_ids);
[5050]113% }}}
[13395]114%GET exclude {{{
[5085]115exclude_ids=getfieldvalue(options,'exclude',[]);
[7071]116exclude_ids=[exclude_ids];
[5085]117pos=find(ismember(test_ids,exclude_ids));
118test_ids(pos)=[];
119% }}}
[13395]120%Process Ids according to benchmarks{{{
[5050]121if strcmpi(benchmark,'nightly'),
122 test_ids=intersect(test_ids,[1:999]);
[14067]123elseif strcmpi(benchmark,'validation'),
124 test_ids=intersect(test_ids,[1001:1999]);
[5272]125elseif strcmpi(benchmark,'ismip'),
[5271]126 test_ids=intersect(test_ids,[1101:1199]);
[5272]127elseif strcmpi(benchmark,'eismint'),
[5271]128 test_ids=intersect(test_ids,[1201:1299]);
[5272]129elseif strcmpi(benchmark,'thermal'),
[5271]130 test_ids=intersect(test_ids,[1301:1399]);
[5272]131elseif strcmpi(benchmark,'mesh'),
[5271]132 test_ids=intersect(test_ids,[1401:1499]);
[14067]133elseif strcmpi(benchmark,'tranforcing'),
134 test_ids=intersect(test_ids,[1501:1502]);
135elseif strcmpi(benchmark,'referential'),
136 test_ids=intersect(test_ids,[1601:1602]);
[26744]137elseif strcmpi(benchmark,'slc'),
[20500]138 test_ids=intersect(test_ids,[2001:2500]);
[13395]139elseif strcmpi(benchmark,'adolc'),
[16560]140 test_ids=intersect(test_ids,[3001:3200]);
[18301]141elseif strcmpi(benchmark,'qmu'),
142 test_ids=intersect(test_ids,[218 234 235 412:414 417 418 420]);
[5050]143end
144% }}}
[4950]145
146%Loop over tests and launch sequence
[5501]147root=pwd;
[4950]148for id=test_ids,
[19105]149 disp(sprintf('%s%i%s','----------------starting:',id,'-----------------------'));
[4950]150 try,
151 %Execute test
[22758]152 cd(root);
[19105]153 id_string='N/A';
[5501]154 id_string=IdToName(id);
[22758]155 run(['test' num2str(id)]);
[4950]156
157 %UPDATE ARCHIVE?
158 archive_name=['Archive' num2str(id) ];
159 if strcmpi(procedure,'update'),
[21341]160 delete(['../Archives/' archive_name '.arch'])
[4950]161 for k=1:length(field_names),
162 field=field_values{k};
[21341]163 archwrite(['../Archives/' archive_name '.arch'],[archive_name '_field' num2str(k)], field);
[4950]164 end
[21341]165 disp(sprintf(['File ./../Archives/' archive_name '.arch saved\n']));
[4950]166
[16137]167 %CHECK for memory leaks?
168 elseif strcmpi(procedure,'valgrind'),
169 fields = fieldnames(md.results);
170 for i=1:numel(fields)
171 if ~isfield(md.results.(fields{i}),'errlog'),
172 disp(['Skipping ' fields{i}]);
173 continue;
174 else
175 disp(['Extracting results of ' fields{i}]);
176 end
177 results = md.results.(fields{i});
178 errlog = cellstr(results(1).errlog);
179
180 %Check leaks
181 lines = strfind(errlog,'definitely lost:');
182 lines = find(~cellfun(@isempty,lines));
183 leaks = 0;
184 for j=1:numel(lines)
185 Line = errlog(lines(j));
186 Numbers = sscanf(Line{1},'==%i== definitely lost: %s bytes in %i blocks',[1 Inf]);
187 leaks = leaks + str2num(strrep(char(Numbers(2:end-1)),',',''));
188 end
189 %Check conditional jumps
190 lines = strfind(errlog,'Conditional jump or move depends on uninitialised value');
191 lines = find(~cellfun(@isempty,lines));
192 jumps = numel(lines);
193 %Check invalid read/write
194 lines = strfind(errlog,'Invalid');
195 lines = find(~cellfun(@isempty,lines));
196 inval = numel(lines);
197 if leaks==0,
198 disp(sprintf(['SUCCESS difference: 0 < 0 test id: %i test name: %s field: valgrind mem. leaks'],id,id_string));
199 else
200 disp(sprintf(['ERROR difference: %i > 0 test id: %i test name: %s field: valgrind mem. leaks'],leaks,id,id_string));
201 disp('STOP');
202 return;
203 end
204 if jumps==0,
205 disp(sprintf(['SUCCESS difference: 0 < 0 test id: %i test name: %s field: valgrind cond. jumps'],id,id_string));
206 else
207 disp(sprintf(['ERROR difference: %i > 0 test id: %i test name: %s field: valgrind cond. jumps'],jumps,id,id_string));
208 disp('STOP');
209 return;
210 end
211 if inval==0,
212 disp(sprintf(['SUCCESS difference: 0 < 0 test id: %i test name: %s field: valgrind invalid read/write'],id,id_string));
213 else
214 disp(sprintf(['ERROR difference: %i > 0 test id: %i test name: %s field: valgrind invalid read/write'],inval,id,id_string));
215 disp('STOP');
216 return;
217 end
218 end
[27035]219 %PRODUCE nc files?
220 elseif strcmpi(procedure,'ncExport'),
221 export_netCDF(md, ['test' num2str(id) 'ma.nc'])
222
[12707]223 %ELSE: CHECK TEST
[4950]224 else,
225 for k=1:length(field_names),
226
[4999]227 try,
228 %Get field and tolerance
229 field=field_values{k};
230 fieldname=field_names{k};
231 tolerance=field_tolerances{k};
[4950]232
[4999]233 %compare to archive
[21341]234 %our output is in the correct order (n,1) or (1,1), so we do not need to transpose again
235 archive_cell=archread(['../Archives/' archive_name '.arch'],[archive_name '_field' num2str(k)]);
236 archive=archive_cell{1};
[25836]237 error_diff=full(max(abs(archive(:)-field(:)))/(max(abs(archive(:)))+eps)); %disp test result
[20500]238 if (error_diff>tolerance | isnan(error_diff));
[4999]239 disp(sprintf(['ERROR difference: %-7.2g > %7.2g test id: %i test name: %s field: %s'],...
[5501]240 error_diff,tolerance,id,id_string,fieldname));
[17806]241 if(getfieldvalue(options,'stoponerror',0)), disp('STOP'); return; end
[4999]242 else
243 disp(sprintf(['SUCCESS difference: %-7.2g < %7.2g test id: %i test name: %s field: %s'],...
[5501]244 error_diff,tolerance,id,id_string,fieldname));
[4999]245 end
246
247 catch me2
248
249 %something went wrong, print failure message:
[5104]250 message=getReport(me2);
[17806]251 fprintf('%s',message);
[5084]252 if strcmpi(output,'nightly')
[19105]253 fid=fopen([issmdir() '/nightlylog/matlaberror.log'], 'at');
[5084]254 fprintf(fid,'%s',message);
255 fprintf(fid,'\n------------------------------------------------------------------\n');
256 fclose(fid);
[5501]257 disp(sprintf(['FAILURE difference: N/A test id: %i test name: %s field: %s'],id,id_string,fieldname));
[5104]258 else
[11995]259 disp(sprintf(['FAILURE difference: N/A test id: %i test name: %s field: %s'],id,id_string,fieldname));
[17806]260 fprintf('%s',message);
261 if(getfieldvalue(options,'stoponerror',0)), disp('STOP'); return; end
[5084]262 end
[17806]263 continue;
[4950]264 end
265 end
266 end
267 catch me,
268
269 %something went wrong, print failure message:
[5104]270 message=getReport(me);
[17806]271 fprintf('%s',message);
[5084]272 if strcmpi(output,'nightly')
[19105]273 fid=fopen([issmdir() '/nightlylog/matlaberror.log'], 'at');
[5084]274 fprintf(fid,'%s',message);
275 fprintf(fid,'\n------------------------------------------------------------------\n');
276 fclose(fid);
[5501]277 disp(sprintf(['FAILURE difference: N/A test id: %i test name: %s field: %s'],id,id_string,'N/A'));
[5104]278 else
[11995]279 disp(sprintf(['FAILURE difference: N/A test id: %i test name: %s field: %s'],id,id_string,'N/A'));
[5104]280 rethrow(me);
[17806]281 if(getfieldvalue(options,'stoponerror',0)), disp('STOP'); return; end
[5084]282 end
[4950]283 end
[19105]284 disp(sprintf('%s%i%s','----------------finished:',id,'-----------------------'));
[4950]285end
Note: See TracBrowser for help on using the repository browser.