Calculations/Dipolar-Gas-Simulator/+Helper/runWithProfiling.m

58 lines
1.9 KiB
Matlab

function [varargout] = runWithProfiling(funcHandle, nOutputs, saveDirectory)
%RUNWITHPROFILING Profile runtime and memory usage, and log stats to JSON file.
%
% Usage:
% [a, b, c, stats] = runWithProfiling(@() sim.run(), 3, './Results/');
%
% Inputs:
% funcHandle - Function handle to run (e.g., @() sim.run())
% nOutputs - Number of outputs expected from funcHandle
% saveDirectory - Directory path to save stats JSON file
%
% Outputs:
% varargout - Outputs of funcHandle (1 to nOutputs)
% - Final output is a struct 'stats' with fields:
% .runtime - Wall-clock time (s)
% .workspaceMemoryMB - Total memory used (MB)
% .timestamp - ISO timestamp of run
% .hostname - System hostname
% Time the function
tStart = tic;
[varargout{1:nOutputs}] = funcHandle();
runtime = toc(tStart);
% Estimate workspace memory usage
try
vars = whos;
totalBytes = sum([vars.bytes]);
workspaceMemoryMB = totalBytes / 1e6;
catch
workspaceMemoryMB = NaN;
end
% Create stats struct
stats.runtime = runtime;
stats.workspaceMemoryMB = workspaceMemoryMB;
stats.timestamp = datestr(now, 'yyyy-mm-dd_HH-MM-SS');
[~, hostname] = system('hostname');
stats.hostname = strtrim(hostname);
% Save as JSON
try
if ~exist(saveDirectory, 'dir')
mkdir(saveDirectory);
end
filename = fullfile(saveDirectory, ['profiling_stats_', stats.timestamp, '.json']);
jsonStr = jsonencode(stats, 'PrettyPrint', true);
fid = fopen(filename, 'w');
fwrite(fid, jsonStr, 'char');
fclose(fid);
catch ME
warning('Failed to save profiling stats: %s', ME.message);
end
% Return stats
varargout{nOutputs + 1} = stats;
end