function varargout = dctool(varargin)
% DCTOOL Graphical interface for displaying the status of a distributed
% computing network.
%
% DCTOOL, by itself, creates a new DCTOOL or raises the existing
% singleton.
%
% H = DCTOOL returns the handle to a new DCTOOL or the handle to
% the existing singleton.
%
% Tim Farajian 7/11/2005
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @dctool_OpeningFcn, ...
'gui_OutputFcn', @dctool_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT
%----------------------------------------------%
%----------------------------------------------%
% GUI Output function
function varargout = dctool_OutputFcn(ignore, ignore2, handles)
varargout{1} = handles.output;
%----------------------------------------------%
function Figure_CloseRequestFcn(hObject, ignore, handles)
if strcmp(get(handles.updatetimer,'Running'),'on')
stop(handles.updatetimer)
end
delete([handles.updatetimer handles.starttimer])
delete(hObject);
%----------------------------------------------%
function dctool_OpeningFcn(hObject, ignore, handles)
% Choose default command line output for dctool
handles.output = hObject;
% Initialize distributed computing network info
handles.jm = [];handles.Workers = [];handles.Jobs = [];handles.Tasks = [];
handles.cjm = [];handles.cWorker = [];handles.cJob = [];handles.cTask = [];
%%% Create update timer %%%
% Specify timer period
SecPerUpdate = get(handles.RateSlider,'Value');
set(handles.RateText,'String',sprintf('%0.1f',SecPerUpdate))
oldwarn = warning('off','MATLAB:TIMER:RATEPRECISION');
handles.updatetimer = timer('busymode','queue',...
'ExecutionMode','fixedSpacing',...
'Period',SecPerUpdate,'startdelay',0,...
'TimerFcn',@(a,b)Update(a,b,hObject),...
'TasksToExecute',1e6);
% Create timer to start populating listboxes after figure is shown
handles.starttimer = timer('startdelay',0.1,...
'TimerFcn',@PopulateJobManagers,'UserData',handles.Figure);
warning(oldwarn); % Reset warning state
guidata(hObject, handles); % Save handles
start(handles.starttimer); % Start timer to initiate populating listboxes
%----------------------------------------------%
%----------------------------------------------%
%%%%%%%%%%%%%%%%%%%%%
% Listbox Callbacks %
%%%%%%%%%%%%%%%%%%%%%
%%% Job manager changed by user %%%
function jmbox_Callback(hObject, ignore, handles)
if isempty(handles.jm)
% Currently no job manager in listbox
return
end
jm = handles.jm(get(handles.jmbox,'Value')); % Get currently selected manager
if ~isequal(handles.cjm,jm)
% Job manager has changed
handles.cjm = jm; % Reassign current job manager
% Stop update timer
if strcmp(handles.updatetimer.Running,'on')
stop(handles.updatetimer)
end
% Clear list boxes
h = [handles.workerbox handles.jobbox handles.taskbox];
set(h,'String',{})
% Reset current worker, job, and task
handles.cWorker = []; handles.cJob = []; handles.cTask = [];
handles.Workers = []; handles.Jobs = []; handles.Tasks = [];
guidata(hObject,handles);
% Populate list boxes
Populate([],[],hObject);
% Restart the update timer
if strcmp(handles.updatetimer.Running,'off')
start(handles.updatetimer)
end
end
%----------------------------------------------%
%%% Job changed by user %%%
function jobbox_Callback(hObject, ignore, handles)
if isempty(handles.Jobs)
% Currently no jobs in listbox
return
end
job = handles.Jobs(get(handles.jobbox,'Value')); % Selected job
if ~isequal(handles.cJob,job)
% Job changed
handles.cJob = job; % Reassign current job
set(handles.taskbox,'String',{}) % Clear task listbox
handles.cTask = []; % Reset current task
guidata(hObject,handles);
PopulateTasks([],[],hObject);
end
% Submit menu item is disabled if current job is not pending
state = job.state;
if strcmp(state,'pending')
set(handles.MenuSubmit,'Enable','on');
else
set(handles.MenuSubmit,'Enable','off')
end
% JobReport menu item is disabled if current job is pending or queued
if strcmp(state,'pending') || strcmp(state,'queued')
set(handles.MenuReport,'Enable','off');
else
set(handles.MenuReport,'Enable','on')
end
%----------------------------------------------%
%%% Task changed by user %%%
function taskbox_Callback(hObject, ignore, handles)
if isempty(handles.Tasks)
% Currently no tasks in listbox
return
end
% Reassign current task
handles.cTask = handles.Tasks(get(handles.taskbox,'Value')); % Selected task
guidata(hObject,handles);
% Worker changed by user
function workerbox_Callback(hObject, ignore, handles)
if isempty(handles.Workers)
% Currently no workers in listbox
return
end
% Reassign current worker
handles.cWorker = handles.Workers(get(handles.workerbox,'Value'));
guidata(hObject,handles);
%----------------------------------------------%
%----------------------------------------------%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Context Menu Item Callbacks %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Job Manager menu callbacks %%%
%%% Export manager to base workspace
function MenuExportJm_Callback(ignore, ignore2, handles)
jm = inputdlg('Export handle to job manager as name:','Export Job Manager');
assignin('base',jm{1},handles.cjm);
disp('Variables created in the workspace.');
%----------------------------------------------%
%%% Remove manager from manager list
function MenuRemove_Callback(hObject, ignore, handles)
cval = get(handles.jmbox, 'Value'); % Index of selected manager
handles.jm(cval) = []; % Remove handle from list
fv = get(handles.jmbox,'String'); % Get string
fv(cval) = []; % Remove string from list
if isempty(handles.jm)
% No more managers
handles.cjm = []; % Indicate no selected manager
stop(handles.updatetimer); % Stop the update timer
% Disable manager menu items
hMenu = get(get(handles.jmbox,'uiContextMenu'),'Children');
set(hMenu,'Enable','off');
elseif cval > length(handles.jm)
% Current manager index now greater than number of managers -> reduce
cval = length(handles.jm);
handles.cjm = handles.jm(cval);
else
% Indicate current manager is now the next one
handles.cjm = handles.jm(cval);
end
guidata(hObject,handles);
% Update manager listbox
set(handles.jmbox,{'Value','String'},{cval,fv});
% Populate remaining listboxes
Populate([],[],hObject);
%----------------------------------------------%
% Display property inspector
function MenuPropsJM_Callback(ignore, ignore2, handles)
inspect(handles.jm(get(handles.jmbox,'Value')))
%----------------------------------------------%
function MenuBench_Callback(hObject, eventdata, handles)
distcomp_bench_dist(length(handles.Workers), get(handles.cjm,'Name'));
%----------------------------------------------%
%%% Worker menu callbacks %%%
% Export handle to worker to base workspace
function MenuExportWorker_Callback(ignore, ignore2, handles)
name = inputdlg('Export handle to worker as name:','Export Worker');
assignin('base',name{1},handles.cWorker);
disp('Variables created in the workspace.');
%----------------------------------------------%
% VNC into current worker
function MenuVNC_Callback(ignore, ignore2, handles)
VncDir = 'D:\Applications\TightVnc\vncviewer.exe ';
str = [VncDir handles.cWorker.Hostname];
system(str);
%----------------------------------------------%
function MenuPropsWorker_Callback(ignore, ignore2, handles)
inspect(handles.Workers(get(handles.workerbox,'Value')))
%----------------------------------------------%
%%% Job menu callbacks %%%
% Export current job to base workspace
function MenuExportJob_Callback(ignore, ignore2, handles)
name = inputdlg('Export handle to job as name:','Export Job');
if isempty(name)
return
end
assignin('base',name{1},handles.cJob);
disp('Variables created in the workspace.');
%----------------------------------------------%
% Submit current job
function MenuSubmit_Callback(ignore, ignore2, handles)
job = handles.Jobs(get(handles.jobbox,'Value'));
submit(job)
%----------------------------------------------%
% Destroy current job
function MenuDestroy_Callback(ignore, ignore2, handles)
job = handles.Jobs(get(handles.jobbox,'Value'));
if ishandle(job)
destroy(job)
end
%----------------------------------------------%
function MenuReport_Callback(ignore, ignore2, handles)
JobReport(handles.cJob)
%----------------------------------------------%
function MenuPropsJob_Callback(ignore, ignore2, handles)
inspect(handles.Jobs(get(handles.jobbox,'Value')))
%----------------------------------------------%
%%% Task menu callbacks %%%
% Export current task to workspace
function MenuExportTask_Callback(ignore, ignore2, handles)
name = inputdlg('Export handle to task as name:','Export Task');
assignin('base',name{1},handles.cTask);
disp('Variables created in the workspace.');
%----------------------------------------------%
% Cancel current task
function MenuCancel_Callback(ignore, ignore2, handles)
if ishandle(handles.cTask)
cancel(handles.cTask)
end
%----------------------------------------------%
% Destroy current task
function MenuDestroyTask_Callback(ignore, ignore2, handles)
if ishandle(handles.cTask)
destroy(handles.cTask)
end
%----------------------------------------------%
function MenuPropsTask_Callback(ignore, ignore2, handles)
inspect(handles.Tasks(get(handles.taskbox,'Value')))
%----------------------------------------------%
%----------------------------------------------%
%%%%%%%%%%%%%%%%%%%%%%
% Menu Bar Callbacks %
%%%%%%%%%%%%%%%%%%%%%%
function MenuClose_Callback(ignore, ignore2, handles)
close(handles.Figure)
%----------------------------------------------%
function DemoCallback(hObject,ignore)
data = get(hObject,'UserData');
handles = guidata(data{1});
fcn = data{2};
fcn(handles.cjm);
%----------------------------------------------%
%----------------------------------------------%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Functions to populate list boxes %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% For performance reasons, certain operations are performed when the
% listboxes are first populated. Then, Update* performs fewer operations to
% keep them updated.
% Populates all listboxes for the first time (Update keeps t
function Populate(tmr,data,hObject)
if ~ishandle(hObject)
% Figure has been closed -> Stop the timer
stop(tmr);
delete(tmr);
return
end
PopulateWorkers(tmr,data,hObject);
PopulateJobs(tmr,data,hObject);
PopulateTasks(tmr,data,hObject);
%----------------------------------------------%
% Populate manager list with all managers on network
function PopulateJobManagers(tmr, ignore)
hObject = get(tmr,'Userdata');
handles = guidata(hObject);
set(handles.JmUpdateText,'Visible','on'); % Turn on "updating" text
% Clear list boxes
h = [handles.jmbox handles.workerbox handles.jobbox handles.taskbox];
set(h,'String',{})
drawnow
% Reset current worker, job, and task
handles.cWorker = []; handles.cJob = []; handles.cTask = [];
handles.Jobs = []; handles.Tasks = [];
% Get all job managers
handles.jm = findResource('jobmanager');
jmstr = get(handles.jm,{'Name'}); % Get names
set(handles.jmbox,{'value','String'},{1,jmstr}); % Fill manager listbox
% Get handles to manager menu items
hMenu = get(get(handles.jmbox,'uiContextMenu'),'Children');
if isempty(handles.jm)
handles.cjm = []; % Indicate there is no current job manager
set(hMenu,'Enable','off');
else
set(hMenu,'Enable','on');
handles.cjm = handles.jm(1); % Set current job manager
end
guidata(hObject,handles)
set(handles.JmUpdateText,'Visible','off'); % Turn off "update" text
% Populate the list boxes
PopulateWorkers([],[],hObject);
PopulateJobs([],[],hObject);
PopulateTasks([],[],hObject);
% If update timer is not already started -> start it
if strcmp(get(handles.updatetimer,'Running'),'off')
start(handles.updatetimer)
end
%----------------------------------------------%
% Populate worker list box
function PopulateWorkers(ignore, ignore2, hObject)
if ~ishandle(hObject)
% Figure already closed
return
end
handles = guidata(hObject);
set(handles.WorkerUpdateText,'Visible','on'); % Turn on "updating" text
drawnow
% Things may have changed from the drawnow
if ~ishandle(hObject)
return
end
handles = guidata(hObject);
workerstr = {}; workerloc = 1; % Initialize variables
% Get handles to all workers
handles.Workers = [get(handles.cjm,'IdleWorkers');get(handles.cjm,'BusyWorkers')];
% Get handles to all worker menu items
hMenu = get(get(handles.workerbox,'uiContextMenu'),'Children');
if isempty(handles.Workers)
% No workers -> disable menu
handles.cWorker = [];
set(hMenu,'Enable','off');
else
set(hMenu,'Enable','on');
handles.cWorker = handles.Workers(workerloc);
end
handles.WorkerData = get(handles.Workers,{'Name'});
data = get(handles.Workers,{'CurrentTask'});
guidata(hObject,handles)
for n = 1:length(handles.Workers)
if isempty(data) || isempty(data{n})
str = 'Idle';
else
str = 'Busy';
end
workerstr{n} = sprintf('%s - %s',handles.WorkerData{n},str);
end
set(handles.workerbox,{'value','String'},{workerloc,workerstr});
set(handles.WorkerUpdateText,'Visible','off');
%----------------------------------------------%
% Populate job list
function PopulateJobs(ignore, ignore2,hObject)
if ~ishandle(hObject)
% Figure already closed
return
end
handles = guidata(hObject);
set(handles.JobUpdateText,'Visible','on'); % Turn on "updating" text
drawnow
% Things may have changed from the drawnow
if ~ishandle(hObject)
% Figure already closed
return
end
handles = guidata(hObject);
jobstr = {};jobloc = 1; % Initialize variables
handles.Jobs = get(handles.cjm,'Jobs'); % Get handles to all jobs
% Get handles to all job menu items
hMenu = get(get(handles.jobbox,'uiContextMenu'),'Children');
if isempty(handles.Jobs)
% No jobs -> disable menu
handles.cJob = [];
set(hMenu,'Enable','off');
else
set(hMenu,'Enable','on');
handles.cJob = handles.Jobs(jobloc);
end
handles.JobData = get(handles.Jobs,{'Name','UserName'});
state = get(handles.Jobs,{'State'});
guidata(hObject,handles)
if ~ishandle(hObject),return,end % In case figure was closed by now
for n = 1:length(handles.Jobs)
jobstr{n} = sprintf('%s - %s - %s',handles.JobData{n,:},state{n});
end
set(handles.jobbox,{'Value','String'},{jobloc,jobstr});
if isempty(state) || ~strcmp(state{jobloc},'pending')
set(handles.MenuSubmit,'Enable','on');
else
set(handles.MenuSubmit,'Enable','off');
end
set(handles.JobUpdateText,'Visible','off');
%----------------------------------------------%
%%% Populate task list box %%%
function PopulateTasks(ignore, ignore2,hObject)
if ~ishandle(hObject)
% Figure already closed
return
end
handles = guidata(hObject);
set(handles.TaskUpdateText,'Visible','on');
drawnow
% Things may have changed from the drawnow
if ~ishandle(hObject)
% Figure already closed
return
end
handles = guidata(hObject);
taskstr = {};taskloc = 1; % Initialize variables
handles.Tasks = get(handles.cJob,'Tasks'); % Get handles to all tasks
% Get handles to all task menu items
hMenu = get(get(handles.taskbox,'uiContextMenu'),'Children');
if isempty(handles.Tasks)
% No tasks -> disable menu
handles.cTask = [];
set(hMenu,'Enable','off');
else
set(hMenu,'Enable','on');
handles.cTask = handles.Tasks(taskloc); % Specify current task
end
handles.TaskData = get(handles.Tasks,{'ID'});
state = get(handles.Tasks,{'State'});
guidata(hObject,handles)
for n = 1:length(handles.Tasks)
taskstr{n} = sprintf('Task%d - %s',handles.TaskData{n,:},state{n});
end
set(handles.taskbox,{'value','String'},{taskloc,taskstr});
set(handles.TaskUpdateText,'Visible','off');
%----------------------------------------------%
%----------------------------------------------%
%%%%%%%%%%%%%%%%%%%%
% Update listboxes %
%%%%%%%%%%%%%%%%%%%%
% These keep the listboxes updated. Different operations are performed to
% initially populate the listboxes using the Populate* functions.
function Update(ignore,ignore2,hObject)
% Timer callback - Updates all listboxes with current info from job manager
% Each function is similar. Each is organized to minimize the number of
% times the job manager is queried for information, which is expensive.
UpdateWorkers(hObject);
UpdateJobs(hObject);
UpdateTasks(hObject);
%----------------------------------------------%
function UpdateWorkers(hObject)
handles = guidata(hObject);
% Check if update checkbox is off
if ~get(handles.MasterUpdate,'Value') || ~get(handles.WorkerUpdate,'Value')
return
end
set(handles.WorkerUpdateText,'Visible','on'); % Turn on "Updating" text
drawnow % Allow text to be shown - Other callbacks may occur
if ~ishandle(hObject)
return % Figure has been closed
end
handles = guidata(hObject); % Handles may have changed
% Find manager's associated workers
workers = [get(handles.cjm,'IdleWorkers'); get(handles.cjm,'BusyWorkers')];
% Remove workers that are no longer there
stillthere = ismember(handles.Workers, workers);
handles.Workers(~stillthere) = [];
handles.WorkerData(~stillthere) = [];
if size(handles.Workers,2)==0 % Ensure empty is 0-by-n rather than n-by-0
handles.Workers = handles.Workers.';
handles.WorkerData = handles.WorkerData.';
end
% Add new workers
notnew = ismember(workers, handles.Workers);
handles.Workers = [handles.Workers(:); workers(~notnew)];
tname = get(workers(~notnew),{'Name'}); % Get new worker's names
handles.WorkerData = [handles.WorkerData; tname]; % Add name to data list
if length(handles.Workers) == 1 && ~iscell(handles.WorkerData)
% Happens when only one worker
handles.WorkerData = {handles.WorkerData};
end
% Read the current task of all workers
ctask = get(handles.Workers,{'CurrentTask'});
nWorkers = length(handles.Workers); workerstr = {}; % Initialize variables
for n = 1:nWorkers
if isempty(ctask{n})
str = 'Idle';
else
str = 'Busy';
end
workerstr{n} = sprintf('%s - %s',handles.WorkerData{n},str);
end
hMenu = get(get(handles.workerbox,'uiContextMenu'),'Children');
if nWorkers == 0
% No workers in list
workerloc = 1; % Listbox value
handles.cWorker = []; % Assign current worker
set(hMenu,'Enable','off'); % Disable context menu items
else
workerloc = min(nWorkers,get(handles.workerbox,'Value')); % Listbox value
handles.cWorker = handles.Workers(workerloc); % Assign current worker
set(hMenu,'Enable','on'); % Enable context menu items
end
guidata(hObject,handles)
set(handles.workerbox,{'value','String'},{workerloc,workerstr});
set(handles.WorkerUpdateText,'Visible','off');
%----------------------------------------------%
%%% Updates current job info from the job manager
function UpdateJobs(hObject)
if ~ishandle(hObject) % Check if figure has closed
return
end
handles = guidata(hObject);
% Check if update checkbox is off
if ~get(handles.MasterUpdate,'Value') || ~get(handles.JobUpdate,'Value')
return
end
set(handles.JobUpdateText,'Visible','on'); % Show "Updating" text
drawnow % Allow text to be shown - Other callbacks may occur
if ~ishandle(hObject) % Check if figure has closed
return
end
handles = guidata(hObject); % Handles may have changed
jobs = get(handles.cjm,'Jobs'); % Read all jobs in current job manager
% Remove jobs that are no longer there
stillthere = ismember(handles.Jobs, jobs);
handles.Jobs(~stillthere) = [];
handles.JobData(~stillthere,:) = [];
if size(handles.Jobs,2)==0 % Ensure empty is 0-by-n rather than n-by-0
handles.Jobs = handles.Jobs.';
end
if size(handles.JobData,2)==0 % Ensure empty is 0-by-n rather than n-by-0
handles.JobData = handles.JobData.';
end
% Add new jobs
notnew = ismember(jobs, handles.Jobs);
handles.Jobs = [handles.Jobs; jobs(~notnew)];
% Get data about new jobs
r = get(jobs(~notnew),{'Name','UserName'}); % Only need to obtain when new
state = get(handles.Jobs,{'State'}); % Need to obtain every time
handles.JobData = [handles.JobData; r]; % Include new data in list
nJobs = length(handles.Jobs);
jobstr = cell(nJobs,1);
for n = 1:nJobs
jobstr{n} = sprintf('%s - %s - %s',handles.JobData{n,:},state{n});
end
% Get handles to all context menu items
hMenu = get(get(handles.jobbox,'uiContextMenu'),'Children');
if nJobs == 0
% No jobs in list
jobloc = 1; % Listbox value
handles.cJob = []; % Assign current job
set(hMenu,'Enable','off'); % Disable context menu items
else
jobloc = min(nJobs,get(handles.jobbox,'Value')); % Listbox value
handles.cJob = handles.Jobs(jobloc); % Assign current job
set(hMenu,'Enable','on'); % Enable context menu items
end
set(handles.jobbox,{'Value','String'},{jobloc,jobstr});
% Disable Submit menu item if job is not pending
if isempty(state) || ~strcmp(state{jobloc},'pending')
set(handles.MenuSubmit,'Enable','off');
else
set(handles.MenuSubmit,'Enable','on');
end
guidata(hObject,handles)
set(handles.JobUpdateText,'Visible','off');
drawnow
%----------------------------------------------%
function UpdateTasks(hObject)
if ~ishandle(hObject) % Check if figure has closed
return
end
handles = guidata(hObject);
% Check if update checkbox is off
if ~get(handles.MasterUpdate,'Value') || ~get(handles.TaskUpdate,'Value')
return
end
set(handles.TaskUpdateText,'Visible','on'); % Show "Updating" text
drawnow % Allow text to be shown - Other callbacks may occur
if ~ishandle(hObject) % Check if figure has closed
return
end
handles = guidata(hObject); % Handles may have changed
% Find all tasks associated with current job
tasks = get(handles.cJob,'Tasks');
% Remove tasks from list that are no longer there
stillthere = ismember(handles.Tasks, tasks);
handles.Tasks(~stillthere) = [];
handles.TaskData(~stillthere) = [];
if size(handles.Tasks,2)==0 % Ensure empty is 0-by-n rather than n-by-0
handles.Tasks = handles.Tasks.';
handles.TaskData = handles.TaskData.';
end
% Add new tasks to list
notnew = ismember(tasks, handles.Tasks);
handles.Tasks = [handles.Tasks; tasks(~notnew)];
ID = get(tasks(~notnew),{'ID'}); % Only need to obtain when new
state = get(handles.Tasks,{'State'}); % Need to obtain every time
handles.TaskData = [handles.TaskData; ID];
if length(handles.TaskData) == 1
if ~iscell(handles.TaskData)
handles.TaskData = {handles.TaskData};
end
end
nTasks = length(handles.Tasks);
taskstr = {};
for n = 1:length(handles.Tasks)
taskstr{n} = sprintf('Task%d - %s',handles.TaskData{n},state{n});
end
hMenu = get(get(handles.taskbox,'uiContextMenu'),'Children');
if nTasks == 0
% No tasks in list
taskloc = 1; % Listbox value
handles.cTask = []; % Assign current task
set(hMenu,'Enable','off'); % Disable context menu items
else
taskloc = min(nTasks,get(handles.taskbox,'Value')); % Listbox value
handles.cTask = handles.Tasks(taskloc); % Assign current task
set(hMenu,'Enable','on'); % Enable context menu items
end
set(handles.taskbox,{'value','String'},{taskloc,taskstr});
set(handles.TaskUpdateText,'Visible','off');
guidata(hObject,handles)
%----------------------------------------------%
%----------------------------------------------%
%%%%%%%%%%%%%%%%%%%%%%%
% Uicontrol Callbacks %
%%%%%%%%%%%%%%%%%%%%%%%
function MasterUpdate_Callback(hObject, ignore, handles)
h = [handles.WorkerUpdate handles.JobUpdate handles.TaskUpdate];
v = get(hObject,'Value');
if v
set(h,'Enable','on')
else
set(h,'Enable','off')
end
%----------------------------------------------%
% Change the rate at which the interface is refreshed
function RateSlider_Callback(hObject, ignore, handles)
% Stop timer if running
state = strcmp(handles.updatetimer.Running,'on');
if state
stop(handles.updatetimer)
end
% Change timer period - Want smaller values on right of slider
SecPerUpdate = get(hObject,'Value');
set(handles.RateText,'String',sprintf('%0.1f',SecPerUpdate))
oldwarn = warning('off','MATLAB:TIMER:RATEPRECISION');
set(handles.updatetimer,'Period', SecPerUpdate);
warning(oldwarn);
%drawnow
if state
start(handles.updatetimer)
end
%----------------------------------------------%
%----------------------------------------------%
%%%%%%%%%%%%%%
% Job Report %
%%%%%%%%%%%%%%
function varargout = JobReport(varargin)
% JOBREPORT generates a graphical representation of the progress of the
% tasks of a specified job.
%
% JOBREPORT(JOB) generates a plot where the horizontal axis indicates the
% different workers used throughout the job JOB, and the vertical axis
% indicates the starting and finishing times of each task
%
% JOBREPORT(AX,...) plots into the axes with handle AX.
%
% H = JOBREPORT(...) returns a handle to the patch objects.
%
% 5/2005 Tim Farajian
if nargin==1
% Only 1 input
job = varargin{1};
f = figure;
AX = gca;
hold(AX,'on'); % Set hold state
ylabel('Time')
title(['Job report for ' get(job,'Name')],'interpreter','none');
datetick('y');
else
% Axis was specified
[AX job] = deal(varargin{1:2});
if ~ishandle(AX) || ~strcmp(get(AX,'type'),'axes')
error('AX must be a handle to a valid axis object')
end
f = get(AX,'Parent');
end
set(f,'Pointer','watch')
drawnow
if ~ishandle(job) || ~isa(job,'distcomp.job')
error('JOB must be a handle to a valid job object')
else
jobstate = get(job,'State');
if ismember(jobstate,{'pending','queued'})
error('Job has not yet started.')
end
end
tasks = job.Tasks; % Get handles to all tasks in job
if isempty(tasks)
error(['No tasks in ' get(job,'Name')],'Job Report Error');
end
taskstates = get(tasks,'State'); % Get state of all tasks
if length(tasks)==1 && ~iscell(taskstates)
% Ensure its a cell array
taskstates = {taskstates};
end
unavailable = strcmp(taskstates,'unavailable'); % Check if unavailable
tasks(unavailable) = []; % Remove unavailable tasks
taskstates(unavailable) = []; % Remove unavailable taskstates
IDs = get(tasks,'ID'); % Get IDs of all tasks
if length(tasks)==1 && ~iscell(IDs)
% Ensure its a cell array
IDs = {IDs};
end
workers = get(tasks,'Worker'); % Get handle to all workers used by tasks
if iscell(workers)
% Ensure its not a cell array
workers = [workers{:}];
end
% Find the unique workers
[workers ignore wkrnums] = unique(workers);
wkrnames = get(workers,'Name'); % Get names of all workers
if length(workers)==1 && ~iscell(wkrnames)
% Ensure its a cell array
wkrnames = {wkrnames};
end
ax(1:2) = [0 1+length(workers)]; % Set x-axis limits
% Get job start time
JobStart = TaskTime(job,'StartTime');
plot(ax, [JobStart JobStart],'k--')
% Get job finish time and set axes limits
if strcmp(jobstate,{'finished'})
JobFinish = TaskTime(job,'FinishTime');
if JobFinish == JobStart,
JobFinish = JobFinish + 5e-6;
end
dy = max(7e-5,0.6*(JobFinish-JobStart));
my = (JobStart + JobFinish)/2;
plot(ax, [JobFinish JobFinish],'k--')
ax(3:4) = my + dy*[-1 1];
else
JobFinish = now;
jobdiff = max(2e-4,1.1*(JobFinish-JobStart));
ax(3:4) = JobFinish + [-jobdiff 0];
end
% Set figure and axis
axis(ax)
datetick('y')
set(gca,'Xtick',1:length(workers));
set(gca,'XtickLabel',wkrnames);
nTasks = length(tasks);
TaskStart = zeros(nTasks,1);
TaskFinish = zeros(nTasks,1);
h = zeros(nTasks,1); % Preallocate
set(f,'Pointer','arrow')
drawnow
for n = 1:nTasks
task = tasks(n);
switch taskstates{n}
case {'pending'}
continue
case {'running'}
TaskStart(n) = TaskTime(task,'StartTime');
TaskFinish(n) = JobFinish+1e-6;
colr = 'c';
case {'finished'}
TaskStart(n) = TaskTime(task,'StartTime');
TaskFinish(n) = TaskTime(task,'FinishTime');
if isempty(task.ErrorMessage)
colr = 'b';
else
colr = 'r';
end
end
timediff = TaskFinish(n)-TaskStart(n); % Time difference
if timediff<=0
% Ensure time difference is positive
timediff = 5e-6;
TaskFinish(n)=TaskStart(n) + timediff;
end
px = wkrnums(n) - 0.5+[0 0 1 1]; % x-coords of patch
py = TaskStart(n)+timediff*[0 1 1 0]; % y-coords of patch
h(n) = patch(px,py, colr); % Create patch
% Create task text label
text(mean(px),mean(py),...
sprintf('Task%d',IDs{n}),'horizontal','center');
axis(ax)
drawnow
end
if nargout>0
varargout = h;
end
%----------------------------------------------%
function time = TaskTime(obj, prop)
% Subfunction for use with JobReport
timestr = get(obj,prop);
timestr = timestr(5:end);timestr(17:20)=[];
time = datenum(timestr);
function MenuBarHelp_Callback(hObject, eventdata, handles)
fid = fopen('dctool_help.txt');
str = fread(fid,inf,'*char').';
fclose(fid);
f = figure('menubar','none','NumberTitle','off','Name','About DCTOOL');
h=uicontrol('style','edit','parent',f,'min',0,'max',2,'enable','inactive'...
,'units','normalized','position',[0 0 1 1],'string',str,...
'horizontalalignment','left','fontsize',10);
drawnow
%%% Workaround for g271589 %%%
found = false;
jf = get(f, 'javaframe');
ac = jf.getAxisComponent;
cc = ac.getParent.getComponent(0);
if ~isa(cc, 'com.mathworks.hg.peer.FigureComponentContainer')
cc = ac.getParent.getComponent(1);
end
for i=1:cc.getComponentCount
if isa(cc.getComponent(i-1).getComponent(0), 'com.mathworks.hg.peer.utils.UIScrollPane')
s = cc.getComponent(i-1).getComponent(0);
found = true;
end
end
if (found)
e = s.getViewport.getView;
awtinvoke(e, 'scrollRectToVisible(Ljava.awt.Rectangle;)V', ...
java.awt.Rectangle(0, 0, 1, 1));
end