2%> This is the base
class for generating objects
3%> that contain the contents of a report file
4%> generated by a ParaMonte sampler.<br>
7%> This
class is meant to be primarily internally
8%> used by the ParaMonte MATLAB library samplers.<br>
9%> See the documentation of the
class constructor.
12%> See below
for information on the attributes (properties).<br>
15%> See below
for information on the methods.<br>
20%> \JoshuaOsborne, May 21 2024, 1:13 AM, University of Texas at Arlington<br>
21%> \FatemehBagheri, May 20 2024, 1:25 PM, NASA Goddard Space Flight Center (GSFC), Washington, D.C.<br>
22%> \AmirShahmoradi, May 16 2016, 9:03 AM, Oden Institute
for Computational Engineering and Sciences (ICES), UT Austin<br>
25 properties(Access =
public)
29 %> The scalar MATLAB ``
struct`` containing the set of
30 %> computed properties extracted from the report file.<br>
36 %> The scalar MATLAB
string containing the entire
37 %> contents of the report file with all Carriage Return
38 %> characters removed (relevant only to Windows OS).<br>
44 %> The vector of MATLAB strings containing the set of
45 %> all lines in the report file with all Carriage Return
46 %> and New Line characters removed.<br>
52 %> The scalar MATLAB ``
struct`` containing the set of
53 %> predefined visualizations
for the output data.<br>
59 %> The scalar MATLAB ``
string`` containing the ParaMonte
60 %> library
banner as appearing in the report file.<br>
66 % % The scalar MATLAB ``
struct`` containing the sampler
67 % % setup information extracted from the report file.
73 % % The scalar MATLAB ``
struct`` containing the set of
74 % % simulation specifications extracted from the report file.
83 %> This is an internal
class variable inaccessible to the end users.<br>
89 %> The scalar MATLAB integer representing the number of indentation
90 %> characters at the beginning of each description line in the report file.<br>
91 %> This is an internal
class variable inaccessible to the end users.<br>
93 indentLen = 4; % indent length of the records
97 %> The scalar MATLAB integer representing the minimum length of two of decoration symbols.<br>
98 %> This is an internal
class variable inaccessible to the end users.<br>
104 %> The scalar MATLAB
string representing the decoration symbol used in
105 %> the report file, to be determined at runtime (currently ``%``).<br>
106 %> This is an internal
class variable inaccessible to the end users.<br>
112 %> The scalar MATLAB
string representing the prefix used in the description lines of the report file.<br>
113 %> This is an internal
class variable inaccessible to the end users.<br>
115 prefix =
' - NOTE: ';
119 %> The scalar MATLAB
string representing the sample
name.<br>
120 %> This is an internal
class variable inaccessible to the end users.<br>
126 methods(Access =
public)
129 %> Return a scalar
object of
class [pm.sampling.FileContentsReport](@ref
FileContentsReport).<br>
131 %> This is the constructor of the
class [pm.sampling.FileContentsReport](@ref
FileContentsReport).<br>
133 %> \param[in] file : The input scalar MATLAB
string containing the path to an external report file.<br>
134 %> \param[in] silent : See the corresponding argument of [pm.io.FileContents](@ref
FileContents)
class.<br>
135 %> (**optional**. The
default is set by [pm.io.FileContents](@ref
FileContents).)
136 %> \param[in] method : The input scalar MATLAB
string
137 %> containing the sampling method
name.<br>
138 %> The input value must be any of the following:<br>
140 %> <li> ``
"ParaDRAM"``
141 %> <li> ``
"ParaDISE"``
142 %> <li> ``
"ParaNest"``
144 %> (**optional**. If missing, some of the report file contents may not be properly parsed.)
147 %> ``self`` : The output scalar
object of
class [pm.sampling.FileContentsReport](@ref
FileContentsReport).<br>
153 %> contents = pm.sampling.FileContentsReport(file, [])
154 %> contents = pm.sampling.FileContentsReport(file, silent)
155 %> contents = pm.sampling.FileContentsReport(file, [], [])
156 %> contents = pm.sampling.FileContentsReport(file, silent, [])
157 %> contents = pm.sampling.FileContentsReport(file, silent, method)
165 %> \image html example/sampling/
Paradram/himmelblau/
Paradram.himmelblau.parallelism.speedup.scaling.strong.sameeff.png width=700
167 %> \image html example/sampling/
Paradram/himmelblau/
Paradram.himmelblau.parallelism.speedup.scaling.strong.zeroeff.png width=700
172 %> \JoshuaOsborne, May 21 2024, 1:30 AM, University of Texas at Arlington<br>
173 %> \FatemehBagheri, May 20 2024, 1:25 PM, NASA Goddard Space Flight Center (GSFC), Washington, D.C.<br>
174 %> \AmirShahmoradi, May 16 2016, 9:03 AM, Oden Institute
for Computational Engineering and Sciences (ICES), UT Austin<br>
180 self = self@pm.io.FileContents(file, silent);
182 self.
method = convertStringsToChars(method);
183 self.prefix = [self.method, self.prefix];
187 %%%% remove any CARRIAGE RETURN.
190 self.contents = strrep(fileread(file),
char(13),
'');
191 self.contents = strrep(self.contents, newline, [
' ', newline]);
192 self.lineList = strsplit(self.contents, newline);
193 self.lineListLen = length(self.lineList);
194 iend = 1; % the line we are about to parse.
196 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
197 %%%% determine the decoration symbol and read the
banner.
198 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
201 %%%% Here we assume the first non-empty line starts with the symbol character (likely ``%``).
204 ibeg = self.skipNull(iend);
205 failed = self.lineListLen < ibeg || length(self.lineList{ibeg}) < 4;
207 line = self.lineList{ibeg};
208 failed = any(line(1) ~= line(2 : 4));
210 iend = self.skipFull(ibeg + 1);
211 failed = self.lineListLen < iend;
216 self.banner = self.concat(self.lineList(ibeg : iend));
218 self.warn(line,
"Failed to detect the decoration symbol used in the report file.");
221 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
222 %%%% read the ParaMonte MATLAB library
interface specifications
223 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
225 %self.setup.library.interface = self.parseSection(
"interface.specifications");
227 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
229 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
231 %self.setup.library.compiler.version = self.parseSection(
"compiler.version");
233 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
234 %%%% read the ParaMonte MATLAB library
compiler options
235 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
237 %self.setup.library.compiler.options = self.parseSection(
"compiler.options");
239 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
240 %%%% read the Runtime platform specifications
241 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
243 %self.setup.platform = self.parseSection(
"runtime.platform.specifications");
245 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
246 %%%% read the simulation environment
247 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
249 %self.setup.io = self.parseSection(
"simulation.environment");
251 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
252 %%%% read the simulation specifications
253 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
255 %self.spec.base = self.parseSection(
"simulation.specifications.base");
256 %
if self.method ==
"ParaDRAM" || self.method ==
"ParaDISE"
257 % self.spec.mcmc = self.parseSection(
"simulation.specifications.mcmc");
258 % self.spec.dram = self.parseSection(
"simulation.specifications.dram");
259 %elseif self.method ==
"ParaNest"
260 % self.spec.nest = self.parseSection(
"simulation.specifications.nest");
263 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
264 %%%%
statistics:
this must be always the last item to parse
265 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
267 self.checkpoint(
"parsing the simulation statistics...", 1);
271 item = self.lineList{iend};
273 self.spinner.spin(iend / self.lineListLen);
275 if strcmp(item(1 : min(6, length(item))),
'stats.')
278 %%%% First non-empty line.
281 ibeg = self.skipNull(iend + 1);
282 failed = self.lineListLen < ibeg;
284 iend = self.skipFull(ibeg + 1);
285 failed = self.lineListLen < iend;
287 % Retrieve the value.
288 % The strategy is to read all values as table by dumping
289 % the value in a temporary file and reading it as a table.
290 tempfile = tempname();
291 fid = fopen(tempfile,
"w");
292 fprintf(fid, self.concat(strtrim(self.lineList(ibeg : iend - 1))));
294 df = readtable(tempfile);
295 %
if numel(df.Properties.VariableNames) == 1
296 %
if strcmpi(df.Properties.VariableNames(1),
"Var1")
297 % df.Properties.VariableNames(1) =
"value";
300 %self.(strtrim(item)).df = df;
301 eval([
'self.', strtrim(item),
'.df = df;']);
306 %%%% Retrieve the description.
309 ibeg = self.skipNull(iend + 1);
310 iend = self.skipFull(ibeg + 1);
311 if ~all(self.isdesc(self.lineList(ibeg : iend - 1)))
312 self.warn(
string(ibeg) + "-" +
string(iend), "A description record does not contain """ +
string(self.prefix) + """");
314 % Concatenate lines and remove prefixes from each description lines.
315 desc = strrep(self.concat(strtrim(self.lineList(ibeg : iend - 1))), self.prefix, '');
316 eval(['self.', strtrim(item), '.description = desc;']);
317 %self.(strtrim(item)).description = desc;
323 if self.lineListLen < iend
329 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
334 %%%% Add the
parallel scaling visualizations.
337 silent_kws = {
"silent", self.silent};
340 for parcond = [
"sameeff",
"zeroeff"]
341 if strcmp(parcond,
"sameeff")
342 titletext = "Strong Scaling: Current-Efficiency Sampling";
343 elseif strcmp(parcond, "zeroeff")
344 titletext = "Strong Scaling: Zero-Efficiency Sampling";
347 + "Internal ParaMonte library error occurred." + newline ...
348 + "Please report this error to the ParaMonte library developers." + newline ...
352 self.stats.parallelism.speedup.scaling.strong.(parcond).vis = struct();
353 self.stats.parallelism.speedup.scaling.strong.(parcond).vis.desc ...
354 = "This component is added in the post-processing phase to facilitate quick " ...
355 + "visualization of the
parallel scaling behavior of the sampler under the " + parcond + "
parallel conditions.";
356 self.stats.parallelism.speedup.scaling.strong.(parcond).vis.lineScatter = ...
357 pm.vis.
PlotLineScatter ( self.stats.parallelism.speedup.scaling.strong.(parcond).df ...
358 , "colx", 1, "coly", 2, "colc", 2, "axes", {
"xscale",
"log"} ...
359 ,
"scatter", {
"size", 10,
"color", pm.vis.color.rgb(
"red")} ...
360 ...,
"colormap", {
"enabled",
false,
"map",
"autumn"} ...
361 ,
"title", {
"enabled",
true,
"titletext", titletext} ...
362 ,
"plot", {
"linewidth", 2.5} ...
367 warning ( newline ...
368 +
"Failed to create the visualizations for the parallelization scaling behavior of the sampler." + newline ...
369 +
"It is possible that the component ``stats.parallelism.speedup.scaling.strong.(parcond).df`` of the " + newline ...
370 +
"output ``report`` object of class ``pm.sampling.FileContentsReport`` does not exist, where " + newline ...
371 +
"the string `parcond` can be either ``optimal`` or ``perfect``." + newline ...
372 +
"Here is the error message:" + newline ...
374 +
string(me.identifier) + newline +
string(me.message) + newline ...
380 %%%% Add the
parallel process contribution visualizations.
385 %%%% Set up the Cyclic Geometric fit to
parallel processes contributions.
388 cgfit = @(iproc, successProb, normFac, processCount) ...
389 successProb .* normFac .* (1 - successProb).^(iproc - 1) ./ (1 - (1 - successProb).^processCount);
392 %%%% Set up the data frame containing the processes contributions and its Cyclic Geometric fit to
parallel processes contributions.
395 dfpc = self.stats.parallelism.process.contribution.count.current.df;
396 dfpc.cyclicGeometricFit = cgfit ( dfpc.processID ...
397 , self.stats.parallelism.process.contribution.count.current.fit.df.successProb ...
398 , self.stats.parallelism.process.contribution.count.current.fit.df.normFac ...
399 , self.stats.parallelism.process.count.current.df.Var1 ...
401 self.stats.parallelism.process.contribution.count.current.vis =
struct();
402 self.stats.parallelism.process.contribution.count.current.vis.desc = ...
403 "This component is added in the post-processing phase to facilitate quick " + ...
404 "visualization of the contributions of the parallel processes to the final chain.";
405 self.stats.parallelism.process.contribution.count.current.vis.line = ...
406 pm.vis.PlotLine ( dfpc ...
407 ,
"colx",
"processID",
"coly", 2:3,
"axes", {
"xscale",
"log",
"yscale",
"log"} ...
408 ,
"ylabel", {
"txt",
"Accepted-Sample Contribution"} ...
409 ,
"xlabel", {
"txt",
"Process ID"} ...
410 ,
"colormap", {
"enabled",
false} ...
411 ,
"legend", {
"enabled",
true} ...
412 ,
"plot", {
"linewidth", 2.5} ...
416 warning ( newline ...
417 +
"Failed to create the visualizations for the parallel processes contributions and their Cyclic Geomtric fit." + newline ...
418 +
"It is possible that the component ``stats.parallelism.current.process.contribution`` of the " + newline ...
419 +
"output ``report`` object of class ``pm.sampling.FileContentsReport`` does not exist, or " + newline ...
420 +
"its sub-components are missing." + newline ...
421 +
"Here is the error message:" + newline ...
423 +
string(me.identifier) + newline +
string(me.message) + newline ...
430 end % methods(Access =
public)
432 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
434 methods(Hidden, Static)
436 %function reportParseFailure(topic)
437 % topic = string(strtrim(strrep(strrep(topic, newline,
' '),
char(13),
' ')));
438 % warning ( newline ...
439 % +
"Failed to parse the record """ + topic +
""". " + newline ...
440 % +
"The structure of the report file appears to have been compromised. Skipping..." + newline ...
445 %function reportMissingValue(topic)
446 % topic = string(strtrim(strrep(strrep(topic, newline,
' '),
char(13),
' ')));
447 % warning ( newline ...
448 % +
"Failed to parse the value corresponding to the record """ + topic +
""". " + newline ...
449 % +
"The structure of the report file appears to have been compromised. Skipping..." + newline ...
454 function str = concat(lines)
455 % Concatenate the elements of an input cell array by
456 % the
new line character and
return the result as a single
string.
457 str = string(join(lines, newline));
462 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
466 %function result = isSectionHeader(self, record)
467 % result = self.dsymLen < length(record) && contains(record(1 : self.dsymLen), self.dsym);
470 %function stopBeforeNextSectionHeader(self)
471 % % NOTE:
if it is already within a section header, it will skip it and
find the next section header.
472 % record = self.lineList{iend};
473 % isCurrentSectionHeader = self.dsymLen < length(record) && contains(record(1 : self.dsymLen), self.dsym);
475 %
if iend == self.lineListLen
478 % record = self.lineList{iend};
479 %
if self.dsymLen < length(record) && contains(record(1 : self.dsymLen), self.dsym)
480 %
if isCurrentSectionHeader
488 % isCurrentSectionHeader =
false;
495 %function skipCurrentSectionHeader(self)
497 % record = self.lineList{iend};
498 %
if self.dsymLen < length(record) && contains(record(1 : self.dsymLen), self.dsym)
500 %
if iend == self.lineListLen
510 %function section = parseSection(self, topic)
511 % ilineLastSuccess = iend;
512 % topic = lower(topic);
514 % topicFound =
false;
517 %
if self.lineListLen <= iend
520 % record = lower(self.lineList{iend});
521 %
if contains(record, topic)
529 % self.skipCurrentSectionHeader();
531 % self.stopBeforeNextSectionHeader();
532 % section = self.concat(lineStart, iend);
534 % self.reportParseFailure(topic);
535 % iend = ilineLastSuccess;
539 function result = isdesc(self, record)
540 result = contains(record, self.prefix);
543 function iend = skipNull(self, ibeg)
544 % skip the empty lines after the current
545 % until encountering the first non-empty line.
548 if self.lineListLen < iend
550 elseif ~isempty(strtrim(self.lineList{iend}))
557 function iend = skipFull(self, ibeg)
558 % skip the nonempty lines after the current
559 % until encountering the first empty line.
562 if self.lineListLen < iend
564 elseif isempty(strtrim(self.lineList{iend}))
573 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function name(in vendor)
Return the MPI library name as used in naming the ParaMonte MATLAB shared library directories.
function version(in silent)
Return a scalar MATLAB string containing the latest available ParaMonte MATLAB version newer than the...
function banner()
Return a scalar MATLAB string containing the ParaMonte MATLAB library banner.
This is the base class for generating objects that contain the contents of a report file generated by...
function skipNull(in self, in ibeg)
function isdesc(in self, in record)
function skipFull(in self, in ibeg)
static function concat(in lines)
function FileContentsReport(in file, in silent, in method)
Return a scalar object of class pm.sampling.FileContentsReport.
This is the base class for generating objects that contain the contents of a given file.
This is the ParaDRAM class for generating instances of serial and parallel Delayed-Rejection Adaptive...
This is the PlotLineScatter class for generating instances of 2-dimensional Line-Scatter Plot visuali...
function compiler()
Return a scalar MATLAB logical that is true if and only if the current installation of MATLAB contain...
function find(in vendor)
Return a list of scalar MATLAB strings containing the paths to all detected mpiexec binaries installe...
function parallel()
Return a scalar MATLAB logical that is true if and only if the current installation of MATLAB contain...
function statistics()
Return a scalar MATLAB logical that is true if and only if the current installation of MATLAB contain...