Newer
Older
classdef SCDclass_expcode
%A SCD expcode object
% This object is a virgin SCD expode
% its constructor builds an expode
% with all templates algorithms
properties (Access = private)
activenodes % numerical list of configured active nodes
activecpus % numerical list of configured CPUs
%nodeddlist % list of data dictionaries at node level
wrapperlist % list of configured wrappers
algoobjlist % list of loaded algorithm objects
algonamelist % List of loaded algorithm names
algoddlist % list of data dictionaries at algorithm level
mdscontainer % container class for MDS+ interface objects
taskcontainer % container class for generic init and term task objects
exportedtps % list of tunable parameters variable to be exported
stdinits % list of standard inits scripts
modeltoactualize % name of the algorithm to actualize ('all' means all coonfigured)
end
properties
% Main properties
name % Expcode main name
maincode % Expcode numerical code
status % Expcode development status
loadverbose % Verbosity level of the loading (currently 0 or 1)
end
methods(Static)
function node = defaultnode(nodenr)
node01.active = 0;
node01.ncpu = 1;
node01.type = 'std1cpu2015a';
node01.timing.t_start = -4.5;
node01.timing.t_stop = 3;
node01.timing.dt = 1e-4;
node01.buildcfg.conffile{1} = 'standard';
node01.buildcfg.initscdbeforecomp = 0;
node01.haswavegen = 1;
node01.hasethercat = 0;
node01.hasadc = 1;
node02.active = 0;
node02.ncpu = 4;
node02.type = 'std1cpu2015a';
node02.timing.t_start = -4.5;
node02.timing.t_stop = 3;
node02.timing.dt = 1e-4;
node02.thperiod = [1.0000e-03 1.0000e-03 1.0000e-03 1.0000e-03];
node02.buildcfg.conffile{1} = 'standard';
node02.buildcfg.conffile{2} = 'standard';
node02.buildcfg.conffile{3} = 'standard';
node02.buildcfg.conffile{4} = 'standard';
node02.buildcfg.conffile=node02.buildcfg.conffile';
node02.buildcfg.initscdbeforecomp = 0;
node02.haswavegen = 1;
node02.hasadc = 1;
node02.hasethercat = 1;
node03.active = 0;
node03.ncpu = 4;
node03.type = '4cpus2015a';
node03.timing.t_start = -2.0;
node03.timing.t_stop = 2.75;
node03.timing.dt = 1e-3;
node03.thperiod = [1.0000e-03 1.0000e-03 1.0000e-03 1.0000e-03];
node03.buildcfg.conffile{1} = 'standard';
node03.buildcfg.conffile{2} = 'standard';
node03.buildcfg.conffile{3} = 'standard';
node03.buildcfg.conffile{4} = 'standard';
node03.buildcfg.conffile=node03.buildcfg.conffile';
node03.buildcfg.initscdbeforecomp = [0 0 0 0];
node03.haswavegen = 1;
node03.hasadc = 0;
node03.hasethercat = 0;
node04.active = 0;
node04.ncpu = 4;
node04.type = 'std1cpu2015a';
node04.timing.t_start = -4.5;
node04.timing.t_stop = 3;
node04.timing.dt = 1e-4;
node04.buildcfg.conffile{1} = 'standard';
node04.buildcfg.initscdbeforecomp = 0;
node04.haswavegen = 1;
node04.hasadc = 0;
node04.hasethercat = 0;
node05.active = 0;
node05.ncpu = 1;
node05.type = 'std1cpu2015a';
node05.timing.t_start = -4.5;
node05.timing.t_stop = 3;
node05.timing.dt = 1e-4;
node05.buildcfg.conffile{1} = 'standard';
node05.buildcfg.initscdbeforecomp = 0;
node05.haswavegen = 1;
node05.hasadc = 0;
node05.hasethercat = 0;
node06.active = 0;
node06.ncpu = 4;
node06.type = '4cpus2015a';
node06.timing.t_start = 0.0;
node06.timing.t_stop = 2.75;
node06.timing.dt = 1e-3;
node06.thperiod = [1.0000e-03 1.0000e-03 1.0000e-03 1.0000e-03];
node06.buildcfg.conffile{1} = 'standard';
node06.buildcfg.conffile{2} = 'standard';
node06.buildcfg.conffile{3} = 'standard';
node06.buildcfg.conffile{4} = 'standard';
node06.buildcfg.conffile=node06.buildcfg.conffile';
node06.buildcfg.initscdbeforecomp = [0 0 0 0];
node06.haswavegen = 1;
node06.hasadc = 0;
node06.hasethercat = 0;
node07.active = 0;
node07.ncpu = 4;
node07.type = '4cpus2015a';
node07.timing.t_start = -0.5;
node07.timing.t_stop = 2.5;
node07.timing.dt = 1e-3;
node07.thperiod = [1.0000e-03 1.0000e-03 1.0000e-03 1.0000e-03];
node07.buildcfg.conffile{1} = 'standard';
node07.buildcfg.conffile{2} = 'standard';
node07.buildcfg.conffile{3} = 'standard';
node07.buildcfg.conffile{4} = 'standard';
node07.buildcfg.conffile=node07.buildcfg.conffile';
node07.buildcfg.initscdbeforecomp = [0 0 0 0];
node07.haswavegen = 1;
node07.hasadc = 1;
node07.hasethercat = 0;
node08.active = 0;
node08.ncpu = 1;
node08.type = '4cpus2015a';
node08.timing.t_start = -0.5;
node08.timing.t_stop = 2.5;
node08.timing.dt = 1e-3;
node08.thperiod = [1.0000e-03 1.0000e-03 1.0000e-03 1.0000e-03];
node08.buildcfg.conffile{1} = 'standard';
node08.buildcfg.conffile{2} = 'standard';
node08.buildcfg.conffile{3} = 'standard';
node08.buildcfg.conffile{4} = 'standard';
node08.buildcfg.conffile=node08.buildcfg.conffile';
node08.buildcfg.initscdbeforecomp = [0 0 0 0];
node08.haswavegen = 1;
node08.hasadc = 1;
node08.hasethercat = 0;
node = eval(sprintf('node%02d',nodenr));
% [general part]
node.hasrfm = 1; % all nodes have rfm
node.wrapper = cell(node.ncpu,1);
node.wrapdatadicts=cell(node.ncpu,1);
node.varalgo = ones(node.ncpu,1);
node.cpuactive = zeros(node.ncpu,1);
node.datadict=sprintf('SCD_rtc_%02d.sldd',nodenr);
for iwrap=1:node.ncpu
node.wrapper{iwrap} = sprintf('SCDwrap_template%02d%02d.slx',nodenr,iwrap);
node.wrapdatadicts{iwrap} = sprintf('SCDwrap_template%02d%02d.sldd',nodenr,iwrap);
end
end
function build_nodes(compileslx_list)
for mynodeslx = compileslx_list
fprintf(' *** Buiding Node %s ***\n',mynodeslx{1});
rtwbuild(mynodeslx{1});
end
end
if nargin==0
myslx = 'tcv';
elseif nargin==1
assert(isnumeric(inode))
myslx = sprintf('SCD_rtc_%02d',inode);
elseif nargin==2
myslx = sprintf('SCD_rtccode_%02d_%02d',inode,icpu);
else
error('invalid number of arguments');
end
function close_all(saveflag)
if nargin==0
saveflag = 1;
end
assert(saveflag == 1 || saveflag == 0,'saveflag must be 1 or 0')
if saveflag==1
closemsg = 'Saving and Closing %s\n';
else
closemsg = 'Dicarding changes and closing %s\n';
end
while ~isempty(bdroot)
fprintf(closemsg,bdroot);
close_system(bdroot,saveflag)
end
methods
function obj=SCDclass_expcode()
% All templates constructor
obj.name = 'template';
obj.maincode = 1;
obj.status = 'debug';
obj.loadverbose = 1;
obj.activenodes=[1 2 3 6 7 8];
obj.activecpus=[ {1}; ...
{1:4}; ...
{1:4}; ...
{1:4}; ...
{1:4}; ...
{1}];
obj.algonamelist={};
obj.algoddlist={};
obj.wrapperlist={};
obj.exportedtps = [];
obj.mdscontainer = SCDclass_mdsobjcontainer;
obj.taskcontainer = SCDclass_taskcontainer;
for inode = 1:8
tmp(inode) = SCDclass_expcode.defaultnode(inode);
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
end
function printinfo(obj)
fprintf('*****************************************************\n');
fprintf('* SCD expcode: ''%s'', main code: %d\n',obj.name,obj.maincode);
fprintf('*****************************************************\n');
fprintf('* Configured wrappers:\n')
if(numel(obj.wrapperlist)>0)
for ii=1:numel(obj.wrapperlist)
fprintf(' Node: %d, CPU: %d, varalgo: %d, wrapper: ''%s'', datadict: ''%s''\n', ...
obj.wrapperlist{ii}{1}, ...
obj.wrapperlist{ii}{2}, ...
obj.wrapperlist{ii}{3}, ...
obj.wrapperlist{ii}{4}, ...
obj.wrapperlist{ii}{5} ...
);
end
end
fprintf('* Configured algorithms:\n');
if(numel(obj.algonamelist)>0)
for ii=1:numel(obj.algonamelist), fprintf(' ''%s''\n', char(obj.algonamelist{ii})); end
end
fprintf('* Configured algorithm data dictionaries:\n')
if(numel(obj.algoddlist)>0)
for ii=1:numel(obj.algoddlist), fprintf(' ''%s''\n', char(obj.algoddlist{ii})); end
end
fprintf('* Configured exported tunparams structures:\n')
if(numel(obj.exportedtps)>0)
for ii=1:numel(obj.exportedtps), fprintf(' ''%s''\n', char(obj.exportedtps{ii})); end
end
fprintf('* Configured MDS tunparams objects: %d (use printparameters method for details)\n', obj.mdscontainer.numparams);
fprintf('* Configured MDS wavegens objects: %d (use printwavegens method for details)\n', obj.mdscontainer.numwavegens);
fprintf('* Configured general purpose tasks: %d (use printtasks method for details)\n', obj.taskcontainer.numtasks);
fprintf('* Configured init scripts: %d (use printinits method for details)\n', numel(obj.stdinits));
end
function CacheFolder = setcachefolder(obj)
%% Set Cache Folder for experimental code (avoid conflicts with other tmp files)
CacheFolder = fullfile(fileparts(mfilename('fullpath')),'..','..',...
'gencodes',sprintf('CacheFolder-%d',obj.maincode));
fprintf('Setting Simulink Cache folder to %s\n',CacheFolder)
Simulink.fileGenControl('set',...
'CacheFolder',CacheFolder,...
'createdir',true);
end
function CodeGenFolder = setcodegenfolder(obj)
CodeGenFolder = fullfile(fileparts(mfilename('fullpath')),'..','..',...
'gencodes',sprintf('CodeGenFolder-%d',obj.maincode));
fprintf('Setting code generation folder to %s\n',CodeGenFolder)
Simulink.fileGenControl('set',...
'CodeGenFolder',CodeGenFolder,...
'createdir',true);
end
function obj = addwrapper(obj, inode, icpu, varalgo, wrappername, varargin)
p=inputParser;
checknodes = @(x) ismember(x,obj.activenodes );
checkcpu = @(x) ismember(x,obj.activecpus{inode});
addRequired(p, 'node', checknodes);
addRequired(p, 'cpu', checkcpu);
addRequired(p, 'varalgo');
addRequired(p, 'modelname', @(x) ischar(x));
addOptional(p, 'datadictionary', '', @(x) ischar(x));
parse(p, inode, icpu, varalgo, wrappername, varargin{:});
% In data dcitionary is not specified it is assumed having
% the same name than the model
if(isempty(p.Results.datadictionary))
datadictionary=[p.Results.modelname '.sldd'];
else
datadictionary=[p.Results.datadictionary '.sldd'];
end
% First checking for duplicates
if(numel(obj.wrapperlist)>0)
wrappernamelist={};
wrapperddnamelist={};
for ii=1:numel(obj.wrapperlist)
wrappernamelist{end+1}=obj.wrapperlist{ii}{4};
wrapperddnamelist{end+1}=obj.wrapperlist{ii}{5};
end
if(ismember(p.Results.modelname,wrappernamelist) || ismember(p.Results.datadictionary,wrapperddnamelist))
warning('SCDclass_expcode:addwrapper','wrapper ''%s'' already present, ignoring.',wrappername);
%% update node info
nodestr=sprintf('node%02d',inode);
obj.nodes(inode).varalgo(icpu) = varalgo;
obj.nodes(inode).wrapper{icpu} = wrappername;
obj.nodes(inode).cpuactive(icpu) = 1;
%% save in wrapper list
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
tempwrapper=cell(10,1);
tempwrapper{1}=p.Results.node;
tempwrapper{2}=p.Results.cpu;
tempwrapper{3}=p.Results.varalgo;
tempwrapper{4}=p.Results.modelname;
tempwrapper{5}=datadictionary;
obj.wrapperlist{end+1}=tempwrapper;
end
function obj = addalgorithm(obj, in_node, in_cpu, in_algo)
% TODO: import the entrire object into a container class ??
p=inputParser;
checknodes = @(x) ismember(x,obj.activenodes );
checkcpu = @(x) ismember(x,obj.activecpus{in_node});
addRequired(p, 'node', checknodes);
addRequired(p, 'cpu', checkcpu);
addRequired(p, 'algo', @(x) isobject(x));
parse(p, in_node, in_cpu, in_algo);
node = p.Results.node;
cpu = p.Results.cpu;
algo = p.Results.algo;
% Checking and importing algorithm name
if(~ismember(algo.getname,obj.algonamelist))
obj.algonamelist{end+1}=algo.getname;
else
warning('SCDclass_expcode:addalgorithm','algorithm ''%s'' already present in the expcode, skipping!',algo.getname);
return;
end
% Importing algorithm MDS objects into the main mdscontainer,
% filling base structure name
algomdscontainer=algo.getmdscontainer;
basewgstruct=sprintf('SCDsimdata.SCDnode%02d%02d_simdata.wavegen', node, cpu);
algomdscontainer=algomdscontainer.setwavegenbasestruct(basewgstruct);
obj.mdscontainer=obj.mdscontainer.importmdsobjects(algomdscontainer);
% Importing exported tps
algoexptps=algo.getexportedtps;
if(numel(algoexptps)>0)
for(ii=1:numel(algoexptps))
if(~ismember(algoexptps{ii},obj.exportedtps))
obj.exportedtps{end+1}=algoexptps{ii};
else
warning('SCDclass_expcode:addalgorithm','exported tunparams sctruct ''%s'' already present, ignoring',algoexptps{ii})
end
end
end
% Importing algorithms data dictionary, only those with proper
% name
algodd=algo.getdatadictionary;
if(strcmp(algodd(1:7),'SCDalgo'))
if(~ismember(algodd,obj.algoddlist))
obj.algoddlist{end+1}=algodd;
else
warning('SCDclass_expcode:addalgorithm','algorithm data dictionary ''%s'' already present, ignoring', algodd);
end
else
% warning here ?
end
% Importing tasks
algotaskcontainer=algo.gettaskcontainer;
obj.taskcontainer=obj.taskcontainer.importtaskobjects(algotaskcontainer);
% Importing inits
algoinits=algo.getinits;
if(numel(algoinits)>0)
toadd = ones(numel(algoinits),1);
for ii=1:numel(algoinits)
if(~isempty(obj.stdinits))
for jj=1:numel(obj.stdinits)
for kk=1:numel(obj.stdinits{jj}{2})
if(strcmp(char(obj.stdinits{jj}{2}{kk}),algoinits{ii}{2}))
warning('SCDclass_expcode:addalgorithm','An init driving the structure %s has already been added, ignoring this init.\d',algoinits{ii}{2})
toadd(ii)=0;
end
end
end
if toadd(ii)
temp=cell(10,1);
temp{1}=algoinits{ii}{1};
temp{2}=algoinits{ii}{2};
obj.stdinits{end+1}=temp;
end
if any(toadd) % if any inits from this algoobj were taken
obj.algoobjlist{end+1}=algo; %% Add the full algorithm object here, to see if it is fine
end
end
end
function out = getexportedtps(obj)
out = obj.exportedtps;
end
function obj = importexpcode(obj, expcode)
% This function imports settings of an existing expcode into another
warning('Not yet supported!');
return;
% tunparamstruct import
exportedtpstoadd = expcode.getexportedtps;
for ii=1:numel(exportedtpstoadd)
if ~sum(ismember(exportedtpstoadd{ii},obj.exportedtps))
obj.addtunparamstruct(exportedtpstoadd{ii});
end
end
% parameters import
obj.mdscontainer=obj.mdscontainer.importmdsobjects(expcode.mdscontainer);
end
function setup(obj)
% This function sets up the TCV Simulink model
% to simulate this experimental code.
% NOTE THAT it doesn't actualize tunable parameters
% and wavegens, call actualizedata for that
fprintf('Setting up expcode %d, ''%s'', configuring wrappers ...\n',obj.maincode,obj.name);
obj=obj.setupwrappers;
obj.setupvaralgo;
fprintf('Setting up expcode %d, ''%s'', configuring data dictionaries ...\n',obj.maincode,obj.name);
obj.setupwrapdd;
obj.setupalgodd;
fprintf('Setting up expcode %d, ''%s'', configuring global data ...\n',obj.maincode,obj.name);
obj.setupmain;
fprintf('Setting up expcode %d, ''%s'', configuring main workspace variables ...\n',obj.maincode,obj.name);
obj.buildworkspacesimstruct;
obj.buildworkspacetpstruct;
% Set cache and codegen folders
function actualize(obj, shot, varargin)
p=inputParser;
% if a model name is given, operations will be performed
% only on it, otherwise they will be performed on all
% configured models
addParameter(p,'model','',@(x) ischar(x));
parse(p,varargin{:});
if(isempty(p.Results.model))
obj.modeltoactualize='all';
else
obj.modeltoactualize=p.Results.model;
end
fprintf('Actualizing expcode %d, ''%s'', performing tasks ...\n',obj.maincode,obj.name);
obj.taskcontainer.modeltoexecute=obj.modeltoactualize;
obj.taskcontainer.exectasksoninit(shot);
end
function actualizedata(obj, shot)
% This function actualizes configured
% tunable parameters and wavegens timeseries
% according to the given shot
currentexpcode=Simulink.data.evalinGlobal('tcv','scd.expcode');
if(currentexpcode~=obj.maincode)
error('SCDclass_expcode:wrongexpcodeloaded','Cannot perform data actualization, the loaded expcode is not matching, try to setup the expcode first');
end
fprintf('Actualizing expcode %d, ''%s'', configuring tunable parameters ...\n',obj.maincode,obj.name);
obj.actualizeparameters(shot)
fprintf('Actualizing expcode %d, ''%s'', configuring wavegens ...\n',obj.maincode,obj.name);
obj.actualizewavegens(shot);
end
function printparameters(obj)
obj.mdscontainer.printparameters;
end
function printwavegens(obj)
obj.mdscontainer.printwavegens;
end
function printtasks(obj)
obj.taskcontainer.printtasks;
end
function actualizeparameters(obj,shot)
obj.mdscontainer.modeltoactualize=obj.modeltoactualize;
obj.mdscontainer.actualizeparameters(shot);
end
function actualizewavegens(obj,shot)
obj.mdscontainer.modeltoactualize=obj.modeltoactualize;
obj.mdscontainer.actualizewavegens(shot);
function printinits(obj)
if(~isempty(obj.stdinits))
for ii=1:numel(obj.stdinits)
fprintf('%s -> %s\n',char(obj.stdinits{ii}{1}),char(obj.stdinits{ii}{2}));
end
end
end
if nargin==1
obj.algoobjlist{ii}.callinits();
elseif nargin==2
error('this use is deprecated, add tasks instead')
else
error('invalid number of arguments for callinits');
end
function printMARTe2taskconfig(obj, shot, varargin)
p=inputParser;
% if a model name is given, operations will be performed
% only on it, otherwise they will be performed on all
% configured models
addParameter(p,'model','',@(x) ischar(x));
parse(p,varargin{:});
if(isempty(p.Results.model))
obj.taskcontainer.modeltogenerate='all';
else
obj.taskcontainer.modeltogenerate=p.Results.model;
end
obj.taskcontainer.printMARTe2taskconfig(shot);
end
function printMARTe2parconfig(obj, shot, varargin)
p=inputParser;
% if a model name is given, operations will be performed
% only on it, otherwise they will be performed on all
% configured models
addParameter(p,'model','',@(x) ischar(x));
parse(p,varargin{:});
if(isempty(p.Results.model))
obj.mdscontainer.modeltogenerate='all';
else
obj.mdscontainer.modeltogenerate=p.Results.model;
end
obj.mdscontainer.printMARTe2parconfig(shot);
function printMARTe2wgbusconfig(obj, shot, ddname, busname, frequency)
fprintf("+MDSWavegen_%s = {\n", busname);
fprintf(" Class = MDSWavegen\n");
fprintf(" Shot = %d\n",shot);
fprintf(" Frequency = %.2f\n",frequency);
dim=obj.mdscontainer.printMARTe2wgbusconfig(shot, ddname, busname);
fprintf(" Signals = {\n");
fprintf(" wavegen_%s = { Type = float32 NumberOfElements = %d }\n", busname, dim );
fprintf(" }\n");
eval(sprintf('%s([],[],[],''compile'')',myslx));
eval(sprintf('%s([],[],[],''term'')',myslx));
catch ME
rethrow(ME)
end
end
function sim(~,varargin)
SCDconf_setSIMconf
fprintf('Simulating %s.slx\n',myslx)
sim(myslx)
openslx = SCDclass_expcode.getslxname(varargin{:});
fprintf('Opening %s.slx\n',openslx)
if numel(varargin)==0
fprintf('\n=== Building all threads for %s ===\n',obj.name);
% make list of nodes to build
compileslx_list = cell(0);
for inode=1:8
for icpu = 1:nodeinfo.ncpu
if nodeinfo.cpuactive(icpu)
SCDclass_expcode.getslxname(inode,icpu)]; %#ok<AGROW>
else
warning('Do not compile node %d thread %d since this is just a dummy',inode,icpu);
end
end
end
end
if isempty(compileslx_list)
fprintf('No active nodes found, no .slx to compile. Done\n');
return
end
else
% user passed nodes,threads to compile
fprintf('building %s.slx\n',myslx)
end
% set CodeGen folder for this expcode (allows fast rebuilding)
assert(~isempty(getenv('RTCCODE_LIBPATH')),'RTCCODE_LIBPATH environment variable needs to be defined to compile');
SCDconf_setCODEconf('configurationSettingsCODEicc')
try
SCDclass_expcode.build_nodes(compileslx_list);
catch ME
% if fails on first attempt, clear build folder and retry
fprintf(' **** FIRST ATTEMPT BUILDING %s FAILED **** \n',obj.name)
fprintf(' Error message:\n %s\n',getReport(ME));
fprintf(' Try again clearning build folder\n')
system(sprintf('rm -rf %s/*',CodeGenFolder));
SCDclass_expcode.build_nodes(compileslx_list);
end
end
methods (Access = private)
function obj=printlog(obj,str)
if obj.loadverbose==1
fprintf('Expcode %d, %s\n', obj.maincode, str);
end
end
function obj = buildworkspacetpstruct(obj)
% this funtion builds a workspace structures containing
% dictionaries, this structure is the one actually used
% for loading simulation wavegen data
% It is better not to use directly data dictionaries structures
% to avoid flooding dds with big sim data sets (and
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
dd=SCDconf_getdatadict('tcv.sldd');
for ii=1:numel(obj.exportedtps)
simstructnamedd=sprintf('%s_tmpl',char(obj.exportedtps(ii)));
simstructnamews=char(obj.exportedtps(ii));
simstruct=dd.getEntry(simstructnamedd).getValue;
assignstr=sprintf('%s=temp;',simstructnamews);
assignin('base','temp',simstruct);
evalin('base',assignstr);
end
evalin('base','clear temp;');
end
function obj = setupwrapdd(obj)
% Sets up the data dictionaries of the wrappers to be loaded
% on the nodes inside the main tcv.sldd
% For every node, given the current status finds its dictionary
% and the requred data sources, find actions to do and setup
% wrappers data sources accordingly
% It is assumed that there is only 1 wrapper and 1 wrapper data
% dictionary active at a given time for every CPU model
% Looping through every active node
for idx_nodedds=1:numel(obj.activenodes)
% Getting data dictionary and required data sources
datadictname = obj.nodes(inode).datadict';
nodedd=Simulink.data.dictionary.open(datadictname);
nodeddsources=nodedd.DataSources;
reqsources=obj.nodes(inode).wrapdatadicts';
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
% Filtering out not pertinent data sources by name prefix
nodeddsourcesok={};
nodeddsourcesokitems=0;
for ii=1:numel(nodeddsources)
if(strcmp(nodeddsources{ii}(1:7),'SCDwrap'))
temp={nodeddsources{ii}, 0};
nodeddsourcesok=[nodeddsourcesok; temp];
nodeddsourcesokitems=nodeddsourcesokitems+1;
end
end
reqsourcesok={};
reqsourcesokitems=0;
for ii=1:numel(reqsources)
if(strcmp(reqsources{ii}(1:7),'SCDwrap'))
temp={reqsources{ii}, 1};
reqsourcesok=[reqsourcesok; temp];
reqsourcesokitems=reqsourcesokitems+1;
else
str=sprintf('Proposed wrapper data dictionary %s does not begin with SCDwrap, ignoring it.', reqsources{ii});
warning(str);
%obj.printlog(str);
end
end
% Finding which data sources to eliminate and which to add
if(nodeddsourcesokitems>0 && reqsourcesokitems>0)
for ii=1:nodeddsourcesokitems
todel=1;
for jj=1:reqsourcesokitems
if(strcmp(char(nodeddsourcesok{ii,1}),char(reqsourcesok{jj,1})))
todel=0;
break
end
end
nodeddsourcesok{ii,2}=todel;
end
for ii=1:reqsourcesokitems
toadd=1;
for jj=1:nodeddsourcesokitems
if(strcmp(char(reqsourcesok{ii,1}),char(nodeddsourcesok{jj,1})))
toadd=0;
break
end
end
reqsourcesok{ii,2}=toadd;
end
end
% Removing data sources
if(nodeddsourcesokitems>0)
for ii=1:nodeddsourcesokitems
if(nodeddsourcesok{ii,2}==1)
str=sprintf('Removing wrapper data source %s from %s', char(nodeddsourcesok{ii,1}), datadictname);
obj.printlog(str);
removeDataSource(nodedd, char(nodeddsourcesok{ii,1}));
end
end
end
% Adding data sources
if(reqsourcesokitems>0)
for ii=1:reqsourcesokitems
if(reqsourcesok{ii,2}==1)
str=sprintf('Adding wrapper data source %s to %s', char(reqsourcesok{ii,1}), datadictname);
obj.printlog(str);
addDataSource(nodedd, char(reqsourcesok{ii,1}));
end
end
end
end
end
function obj = setupalgodd(obj)
% Getting data dictionary and required data sources
tcvdd=Simulink.data.dictionary.open('tcv.sldd');
tcvddsources=tcvdd.DataSources;
reqsources=obj.algoddlist;
% Filtering out not pertinent data sources by name prefix
tcvddsourcesok={};
tcvddsourcesokitems=0;
for ii=1:numel(tcvddsources)
if(strcmp(tcvddsources{ii}(1:7),'SCDalgo'))
temp={tcvddsources{ii}, 1};
tcvddsourcesok=[tcvddsourcesok; temp];
tcvddsourcesokitems=tcvddsourcesokitems+1;
end
end
reqsourcesok={};
reqsourcesokitems=0;
for ii=1:numel(reqsources)
if(strcmp(reqsources{ii}(1:7),'SCDalgo'))
temp={reqsources{ii}, 1};
reqsourcesok=[reqsourcesok; temp];
reqsourcesokitems=reqsourcesokitems+1;
else
warning('SCDexpcode:setupalgodd','Proposed algo data dictionary %s does not begin with SCDalgo, ignoring it.', reqsources{ii});
end
end
% Finding which data sources to eliminate and which to add
if(tcvddsourcesokitems>0 && reqsourcesokitems>0)
for ii=1:tcvddsourcesokitems
todel=1;
for jj=1:reqsourcesokitems
if(strcmp(char(tcvddsourcesok{ii,1}),char(reqsourcesok{jj,1})))
todel=0;
break
end
end
tcvddsourcesok{ii,2}=todel;
end
for ii=1:reqsourcesokitems
toadd=1;
for jj=1:tcvddsourcesokitems
if(strcmp(char(reqsourcesok{ii,1}),char(tcvddsourcesok{jj,1})))
toadd=0;
break
end
end
reqsourcesok{ii,2}=toadd;
end
end
% Removing data sources
if(tcvddsourcesokitems>0)
for ii=1:tcvddsourcesokitems
if(tcvddsourcesok{ii,2}==1)
str=sprintf('Removing algorithm data source %s', char(tcvddsourcesok{ii,1}));
obj.printlog(str);
removeDataSource(tcvdd, char(tcvddsourcesok{ii,1}));
end
end
end
% Adding data sources
if(reqsourcesokitems>0)
for ii=1:reqsourcesokitems
if(reqsourcesok{ii,2}==1)
str=sprintf('Adding algorithm data source %s', char(reqsourcesok{ii,1}));
obj.printlog(str);
addDataSource(tcvdd, char(reqsourcesok{ii,1}));
end
end
end
end
function buildworkspacesimstruct(obj)
% obj.mdscontainer.buildworkspacesimstructnode(obj,node)
% obj.mdscontainer.buildworkspacesimstruct; % old
dd=SCDconf_getdatadict('tcv.sldd');
for ii = 1:numel(obj.activenodes)
inode = obj.activenodes(ii);
buildworkspacesimstructnode(obj,inode,dd);
end
end
function obj = setupmain(obj)
% sets up global configs for the expcode
assigncmd=sprintf('scd.expcode=%d;',obj.maincode);
Simulink.data.evalinGlobal('tcv',assigncmd);
end
function obj = setupwrappers(obj)
for ii=1:numel(obj.wrapperlist)
inode = obj.wrapperlist{ii}{1};
switch inode
%%% THIS SHOULD BE REFACTORED
case {1,8}
obj.nodes(inode).varalgo=obj.wrapperlist{ii}{3};
obj.nodes(inode).wrapdatadicts{1}=obj.wrapperlist{ii}{5};
warning('SCDclass_expcode:setupwrappers','not supported node%02d cpu',inode);
if(obj.wrapperlist{ii}{2}>=1 && obj.wrapperlist{ii}{2}<=4)
obj.nodes(inode).varalgo(obj.wrapperlist{ii}{2})=obj.wrapperlist{ii}{3};
obj.nodes(inode).wrapdatadicts{obj.wrapperlist{ii}{2}}=obj.wrapperlist{ii}{5};
warning('SCDclass_expcode:setupwrappers','not supported node%02d cpu',inode);
otherwise
warning('SCDclass_expcode:setupwrappers','not supported node');
end
end
end
function obj = setupvaralgo(obj)
% Sets up varalgo structure in main tcv data dictionary
% according to varalgo info of the nodes
% Getting data section of main tcv data dictionary
d=Simulink.data.dictionary.open('tcv.sldd');
dd=getSection(d, 'Design Data');
varalgodd=dd.getEntry('SCDvaralgo');
s=struct();
% Looping through every active node
for ii=1:numel(obj.activenodes)
inode = obj.activenodes(ii);
varalgo=obj.nodes(inode).varalgo';
for jj=1:numel(varalgo)
fieldname = sprintf('algo%02d%02d',inode,jj);
s.(fieldname)=varalgo(jj);
end
end
varalgodd.setValue(s);
end
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
function obj = buildworkspacesimstructnode(obj,inode,dd)
node = obj.nodes(inode);
try % get existing SCDsimdata
SCDsimdata = evalin('base','SCDsimdata');
catch ME
if strcmp(ME.identifier,'MATLAB:UndefinedFunction')
SCDsimdata = struct(); % assign here if empty
else
rethrow(ME);
end
end
if node.haswavegen
for ithread = 1:node.ncpu
% get whatever is in data dictionary template in wrappers
simstructname = sprintf('SCDnode%02d%02d_simdata',inode,ithread);
fprintf(' setting up %s\n',simstructname);
try
simstruct = dd.getEntry(simstructname).getValue;
catch
warning('%s not found in data dictionary, auto-generate from bus definition',simstructname)
wgbusname = sprintf('WG%02d%02dbus',inode,ithread);
simstruct = SCDconf_createsimdatastruct(dd,wgbusname);
end
SCDsimdata.(simstructname) = simstruct;
end
end
% Node-specific
simstructname = sprintf('SCDnode%02dsimdata',inode);