summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbin/merge.py15
-rw-r--r--lib/Kratos/DFADriver.pm18
-rw-r--r--lib/Kratos/DFADriver/Model.pm376
3 files changed, 169 insertions, 240 deletions
diff --git a/bin/merge.py b/bin/merge.py
index 62e786f..df0da87 100755
--- a/bin/merge.py
+++ b/bin/merge.py
@@ -969,8 +969,6 @@ def analyze(by_name, by_arg, by_param, by_trace, parameters):
if isa == 'transition':
aggval['rel_energy_prev'] = keydata(name, val, by_arg, by_param, by_trace, 'rel_energies_prev')
aggval['rel_energy_next'] = keydata(name, val, by_arg, by_param, by_trace, 'rel_energies_next')
-
- if isa == 'transition' and 'function' in data['model']['transition'][name]['timeout']:
aggval['timeout'] = keydata(name, val, by_arg, by_param, by_trace, 'timeouts')
for i, param in enumerate(sorted(data['model']['parameter'].keys())):
@@ -985,7 +983,6 @@ def analyze(by_name, by_arg, by_param, by_trace, parameters):
analyze_by_param(aggval, by_param, allvalues, name, 'energy', 'energies', param, i)
analyze_by_param(aggval, by_param, allvalues, name, 'rel_energy_prev', 'rel_energies_prev', param, i)
analyze_by_param(aggval, by_param, allvalues, name, 'rel_energy_next', 'rel_energies_next', param, i)
- if isa == 'transition' and 'function' in data['model']['transition'][name]['timeout']:
analyze_by_param(aggval, by_param, allvalues, name, 'timeout', 'timeouts', param, i)
if isa == 'state':
@@ -1003,17 +1000,13 @@ def analyze(by_name, by_arg, by_param, by_trace, parameters):
'estimated relative_prev %s energy by param [pJ]' % name)
fguess_to_function(name, 'rel_energies_next', aggval['rel_energy_next'], parameters, by_param,
'estimated relative_next %s energy by param [pJ]' % name)
+ fguess_to_function(name, 'timeouts', aggval['timeout'], parameters, by_param,
+ 'estimated %s timeout by param [µs]' % name)
maybe_fit_function(aggval, model, by_param, parameters, name, 'duration', 'durations', 'µs')
maybe_fit_function(aggval, model, by_param, parameters, name, 'energy', 'energies', 'pJ')
maybe_fit_function(aggval, model, by_param, parameters, name, 'rel_energy_prev', 'rel_energies_prev', 'pJ')
maybe_fit_function(aggval, model, by_param, parameters, name, 'rel_energy_next', 'rel_energies_next', 'pJ')
- if 'function' in model['timeout'] and 'user' in model['timeout']['function']:
- fguess_to_function(name, 'timeouts', aggval['timeout'], parameters, by_param,
- 'estimated %s timeout by param [µs]' % name)
maybe_fit_function(aggval, model, by_param, parameters, name, 'timeout', 'timeouts', 'µs')
- if 'function' in model['timeout'] and 'user' in model['timeout']['function']:
- if aggval['timeout']['std_param'] > 0 and aggval['timeout']['std_trace'] / aggval['timeout']['std_param'] < 0.5:
- aggval['timeout']['std_by_trace'] = mean_std_by_trace_part(by_trace, transition_names, name, 'timeouts')
for i, arg in enumerate(model['parameters']):
values = list(set([key[1][i] for key in by_arg.keys() if key[0] == name and is_numeric(key[1][i])]))
@@ -1022,6 +1015,8 @@ def analyze(by_name, by_arg, by_param, by_trace, parameters):
analyze_by_arg(aggval, by_arg, allvalues, name, 'energy', 'energies', arg['name'], i)
analyze_by_arg(aggval, by_arg, allvalues, name, 'rel_energy_prev', 'rel_energies_prev', arg['name'], i)
analyze_by_arg(aggval, by_arg, allvalues, name, 'rel_energy_next', 'rel_energies_next', arg['name'], i)
+ analyze_by_arg(aggval, by_arg, allvalues, name, 'timeout', 'timeouts', arg['name'], i)
+
arguments = list(map(lambda x: x['name'], model['parameters']))
arg_fguess_to_function(name, 'durations', aggval['duration'], arguments, by_arg,
'estimated %s duration by arg [µs]' % name)
@@ -1031,6 +1026,8 @@ def analyze(by_name, by_arg, by_param, by_trace, parameters):
'estimated relative_prev %s energy by arg [pJ]' % name)
arg_fguess_to_function(name, 'rel_energies_next', aggval['rel_energy_next'], arguments, by_arg,
'estimated relative_next %s energy by arg [pJ]' % name)
+ arg_fguess_to_function(name, 'timeouts', aggval['timeout'], arguments, by_arg,
+ 'estimated %s timeout by arg [µs]' % name)
return aggdata
diff --git a/lib/Kratos/DFADriver.pm b/lib/Kratos/DFADriver.pm
index b393415..48ebdab 100644
--- a/lib/Kratos/DFADriver.pm
+++ b/lib/Kratos/DFADriver.pm
@@ -680,14 +680,16 @@ sub update_model {
}
for my $name (sort keys %{ $self->{log}{aggregate}{transition} }) {
my $transition = $self->{log}{aggregate}{transition}{$name};
- $self->model->set_transition_data(
- $name,
- $transition->{duration}{median},
- $transition->{energy}{median},
- $transition->{rel_energy_prev}{median},
- $transition->{rel_energy_next}{median}
- );
- for my $key (qw(duration energy rel_energy_prev rel_energy_next timeout)) {
+ my @keys = (qw(duration energy rel_energy_prev rel_energy_next));
+
+ if ($self->model->get_transition_by_name($name)->{level} eq 'epilogue') {
+ push(@keys, 'timeout');
+ }
+
+ for my $key (@keys) {
+ $self->model->set_transition_property(
+ $name, $key, $transition->{$key}{median}
+ );
for my $fname ( keys %{ $transition->{$key}{function} } ) {
$self->model->set_transition_params(
$name, $key, $fname,
diff --git a/lib/Kratos/DFADriver/Model.pm b/lib/Kratos/DFADriver/Model.pm
index bf57c49..ff5757f 100644
--- a/lib/Kratos/DFADriver/Model.pm
+++ b/lib/Kratos/DFADriver/Model.pm
@@ -32,6 +32,44 @@ sub new {
return $self;
}
+sub parse_xml_property {
+ my ($self, $node, $property_name) = @_;
+
+ my $xml = $self->{xml};
+ my $ret = {
+ static => 0
+ };
+
+ my ($property_node) = $node->findnodes("./${property_name}");
+ if (not $property_node) {
+ return $ret;
+ }
+
+ for my $static_node ( $property_node->findnodes('./static') ) {
+ $ret->{static} = 0 + $static_node->textContent;
+ }
+ for my $function_node ( $property_node->findnodes('./function/*') ) {
+ my $name = $function_node->nodeName;
+ my $function = $function_node->textContent;
+ $function =~ s{^ \n* \s* }{}x;
+ $function =~ s{\s* \n* $}{}x;
+ $function =~ s{ [\n\t]+ }{}gx;
+
+ $ret->{function}{$name}{raw} = $function;
+ $ret->{function}{$name}{node} = $function_node;
+
+ my $param_idx = 0;
+ while ( $function_node->hasAttribute("param${param_idx}") ) {
+ push( @{ $ret->{function}{$name}{params} },
+ $function_node->getAttribute("param${param_idx}") );
+ $param_idx++;
+ }
+ }
+
+ return $ret;
+}
+
+
sub parse_xml {
my ($self) = @_;
@@ -45,33 +83,11 @@ sub parse_xml {
my $name = $state_node->getAttribute('name');
my $power = $state_node->getAttribute('power') // 0;
$self->{states}{$name} = {
- power => { static => 0+$power },
+ power => $self->parse_xml_property($state_node, 'power'),
id => $state_index,
node => $state_node,
};
- for my $fun_node ( $state_node->findnodes('./powerfunction/*') ) {
- my $fname = $fun_node->nodeName;
- my $powerfunction = $fun_node->textContent;
- $powerfunction =~ s{^ \n* \s* }{}x;
- $powerfunction =~ s{\s* \n* $}{}x;
- $powerfunction =~ s{ [\n\t]+ }{}gx;
- $self->{states}{$name}{power}{function}{$fname}{raw}
- = $powerfunction;
- $self->{states}{$name}{power}{function}{$fname}{node} = $fun_node;
- my $attrindex = 0;
-
- while ( $fun_node->hasAttribute("param${attrindex}") ) {
- push(
- @{
- $self->{states}{$name}{power}{function}{$fname}{params}
- },
- $fun_node->getAttribute("param${attrindex}")
- );
- $attrindex++;
- }
- }
-
$state_index++;
}
@@ -118,10 +134,11 @@ sub parse_xml {
my $transition = {
name => $transition_node->getAttribute('name'),
- duration => { static => 0+($transition_node->getAttribute('duration') // 0) },
- energy => { static => 0+($transition_node->getAttribute('energy') // 0) },
- rel_energy_prev => { static => 0+($transition_node->getAttribute('rel_energy_prev') // 0) },
- rel_energy_next => { static => 0+($transition_node->getAttribute('rel_energy_next') // 0) },
+ duration => $self->parse_xml_property($transition_node, 'duration'),
+ energy => $self->parse_xml_property($transition_node, 'energy'),
+ rel_energy_prev => $self->parse_xml_property($transition_node, 'rel_energy_prev'),
+ rel_energy_next => $self->parse_xml_property($transition_node, 'rel_energy_next'),
+ timeout => $self->parse_xml_property($transition_node, 'timeout'),
parameters => [@parameters],
origins => [@source_states],
destination => $dst_node->textContent,
@@ -131,96 +148,6 @@ sub parse_xml {
node => $transition_node,
};
- for my $fun_node ( $transition_node->findnodes('./timeoutfunction/*') )
- {
- my $name = $fun_node->nodeName;
- my $function = $fun_node->textContent;
- $function =~ s{^ \n* \s* }{}x;
- $function =~ s{\s* \n* $}{}x;
- $transition->{timeout}{function}{$name}{raw} = $function;
- $transition->{timeout}{function}{$name}{node} = $fun_node;
- my $attrindex = 0;
- while ( $fun_node->hasAttribute("param${attrindex}") ) {
- push(
- @{ $transition->{timeout}{function}{$name}{params} },
- $fun_node->getAttribute("param${attrindex}")
- );
- $attrindex++;
- }
- }
-
- for my $fun_node ( $transition_node->findnodes('./durationfunction/*') )
- {
- my $name = $fun_node->nodeName;
- my $function = $fun_node->textContent;
- $function =~ s{^ \n* \s* }{}x;
- $function =~ s{\s* \n* $}{}x;
- $transition->{duration}{function}{$name}{raw} = $function;
- $transition->{duration}{function}{$name}{node} = $fun_node;
- my $attrindex = 0;
- while ( $fun_node->hasAttribute("param${attrindex}") ) {
- push(
- @{ $transition->{duration}{function}{$name}{params} },
- $fun_node->getAttribute("param${attrindex}")
- );
- $attrindex++;
- }
- }
-
- for my $fun_node ( $transition_node->findnodes('./energyfunction/*') )
- {
- my $name = $fun_node->nodeName;
- my $function = $fun_node->textContent;
- $function =~ s{^ \n* \s* }{}x;
- $function =~ s{\s* \n* $}{}x;
- $transition->{energy}{function}{$name}{raw} = $function;
- $transition->{energy}{function}{$name}{node} = $fun_node;
- my $attrindex = 0;
- while ( $fun_node->hasAttribute("param${attrindex}") ) {
- push(
- @{ $transition->{energy}{function}{$name}{params} },
- $fun_node->getAttribute("param${attrindex}")
- );
- $attrindex++;
- }
- }
-
- for my $fun_node ( $transition_node->findnodes('./rel_energy_prevfunction/*') )
- {
- my $name = $fun_node->nodeName;
- my $function = $fun_node->textContent;
- $function =~ s{^ \n* \s* }{}x;
- $function =~ s{\s* \n* $}{}x;
- $transition->{rel_energy_prev}{function}{$name}{raw} = $function;
- $transition->{rel_energy_prev}{function}{$name}{node} = $fun_node;
- my $attrindex = 0;
- while ( $fun_node->hasAttribute("param${attrindex}") ) {
- push(
- @{ $transition->{rel_energy_prev}{function}{$name}{params} },
- $fun_node->getAttribute("param${attrindex}")
- );
- $attrindex++;
- }
- }
-
- for my $fun_node ( $transition_node->findnodes('./rel_energy_nextfunction/*') )
- {
- my $name = $fun_node->nodeName;
- my $function = $fun_node->textContent;
- $function =~ s{^ \n* \s* }{}x;
- $function =~ s{\s* \n* $}{}x;
- $transition->{rel_energy_next}{function}{$name}{raw} = $function;
- $transition->{rel_energy_next}{function}{$name}{node} = $fun_node;
- my $attrindex = 0;
- while ( $fun_node->hasAttribute("param${attrindex}") ) {
- push(
- @{ $transition->{rel_energy_next}{function}{$name}{params} },
- $fun_node->getAttribute("param${attrindex}")
- );
- $attrindex++;
- }
- }
-
push( @{ $self->{transitions} }, $transition );
$transition_index++;
@@ -246,61 +173,112 @@ sub parse_xml {
return $self;
}
-sub reset {
- my ($self) = @_;
+sub reset_property {
+ my ($self, $node, $name) = @_;
- for my $state (values %{$self->{states}}) {
- $state->{node}->removeAttribute('power');
- for my $list_node (@{$state->{node}->findnodes('./powerfunction')}) {
- for my $fun_name (keys %{$state->{power}{function}}) {
- my $fun_node = $state->{power}{function}{$fun_name}{node};
- if ($fun_node->nodeName eq 'user') {
- for my $attrnode ($fun_node->attributes) {
+ my ($property_node) = $node->findnodes("./${name}");
+
+ if ($property_node) {
+ for my $static_node ($property_node->findnodes('./static')) {
+ $property_node->removeChild($static_node);
+ }
+ for my $function_parent ($property_node->findnodes('./function')) {
+ for my $function_node ($function_parent->childNodes) {
+ if ($function_node->nodeName eq 'user') {
+ for my $attrnode ($function_node->attributes) {
$attrnode->setValue(1);
}
}
else {
- $list_node->removeChild($fun_node);
+ $function_parent->removeChild($function_node);
}
}
}
}
+}
+
+sub reset {
+ my ($self) = @_;
+
+ for my $state (values %{$self->{states}}) {
+ for my $property (qw(power)) {
+ $self->reset_property($state->{node}, $property);
+ }
+ }
+
for my $transition (@{$self->{transitions}}) {
- $transition->{node}->removeAttribute('duration');
- $transition->{node}->removeAttribute('energy');
- $transition->{node}->removeAttribute('rel_energy_prev');
- $transition->{node}->removeAttribute('rel_energy_next');
- for my $list_node (@{$transition->{node}->findnodes('./timeoutfunction')}) {
- for my $fun_name (keys %{$transition->{timeout}{function}}) {
- my $fun_node = $transition->{timeout}{function}{$fun_name}{node};
- if ($fun_node->nodeName eq 'user') {
- for my $attrnode ($fun_node->attributes) {
- $attrnode->setValue(1);
- }
- }
- else {
- $list_node->removeChild($fun_node);
- }
- }
+ for my $property (qw(duration energy rel_energy_prev rel_energy_next timeout)) {
+ $self->reset_property($transition->{node}, $property);
}
}
}
sub set_state_power {
my ( $self, $state, $power ) = @_;
+ my $state_node = $self->{states}{$state}{node};
$power = sprintf( '%.f', $power );
+ $self->{states}{$state}{power}{static} = $power;
printf( "state %-16s: adjust power %d -> %d µW\n",
$state, $self->{states}{$state}{power}{static}, $power );
- $self->{states}{$state}{power}{static} = $power;
- $self->{states}{$state}{node}->setAttribute( 'power', $power );
+ my ($static_parent) = $state_node->findnodes('./power');
+ if (not $static_parent) {
+ $static_parent = XML::LibXML::Element->new('power');
+ $state_node->appendChild($static_parent);
+ }
+
+ for my $static_node ($static_parent->findnodes('./static')) {
+ $static_parent->removeChild($static_node);
+ }
+
+ my $static_node = XML::LibXML::Element->new('static');
+ my $text_node = XML::LibXML::Text->new($power);;
+
+ $text_node->setData($power);
+ $static_node->appendChild($text_node);
+ $static_parent->appendChild($static_node);
+}
+
+sub set_transition_property {
+ my ( $self, $transition_name, $property, $value ) = @_;
+
+ if (not defined $value) {
+ return;
+ }
+
+ my $transition = $self->get_transition_by_name($transition_name);
+ my $transition_node = $transition->{node};
+ $value = sprintf('%.f', $value);
+
+ printf( "transition %-16s: adjust %s %d -> %d\n",
+ $transition->{name}, $property, $transition->{$property}{static}, $value);
+
+ $transition->{$property}{static} = $value;
+
+ my ($static_parent) = $transition_node->findnodes("./${property}");
+ if (not $static_parent) {
+ $static_parent = XML::LibXML::Element->new($property);
+ $transition_node->appendChild($static_parent);
+ }
+
+ for my $static_node ($static_parent->findnodes('./static')) {
+ $static_parent->removeChild($static_node);
+ }
+
+ my $static_node = XML::LibXML::Element->new('static');
+ my $text_node = XML::LibXML::Text->new($value);
+
+ $text_node->setData($value);
+ $static_node->appendChild($text_node);
+ $static_parent->appendChild($static_node);
}
sub set_state_params {
my ( $self, $state, $fun_name, $function, @params ) = @_;
my $old_params = 'None';
+ my $state_node = $self->{states}{$state}{node};
if ( exists $self->{states}{$state}{power}{function}{$fun_name} ) {
$old_params = join( q{ },
@@ -310,42 +288,35 @@ sub set_state_params {
printf( "state %-16s: adjust %s power function parameters [%s] -> [%s]\n",
$state, $fun_name, $old_params, join( q{ }, @params ) );
- if ( not defined $self->{states}{$state}{power}{function}{$fun_name}{node} )
- {
- my ($fun_node)
- = $self->{states}{$state}{node}->findnodes('./powerfunction');
- if ($fun_node) {
- my $new_node = XML::LibXML::Element->new($fun_name);
- $self->{states}{$state}{power}{function}{$fun_name}{node}
- = $new_node;
- $fun_node->appendChild($new_node);
- }
- else {
- say
- ' skipping XML write-back because of missing powerfunction node';
- return;
- }
+ my ($function_parent) = $state_node->findnodes('./power/function');
+
+ if (not $function_parent) {
+ my ($power_node) = $state_node->findnodes('./power');
+ $function_parent = XML::LibXML::Element->new('function');
+ $power_node->appendChild($function_parent);
}
- if ( defined $function ) {
- my $cdata_node = XML::LibXML::CDATASection->new($function);
- $self->{states}{$state}{power}{function}{$fun_name}{node}
- ->removeChildNodes;
- $self->{states}{$state}{power}{function}{$fun_name}{node}
- ->appendChild($cdata_node);
+ for my $function_node ($function_parent->findnodes("./${fun_name}")) {
+ $function_parent->removeChild($function_node);
}
+ my $function_node = XML::LibXML::Element->new($fun_name);
+ my $function_content = XML::LibXML::CDATASection->new($function);
+
+ $function_node->appendChild($function_content);
+ $function_parent->appendChild($function_node);
+
for my $i ( 0 .. $#params ) {
$self->{states}{$state}{power}{function}{$fun_name}{params}[$i]
= $params[$i];
- $self->{states}{$state}{power}{function}{$fun_name}{node}
- ->setAttribute( "param$i", $params[$i] );
+ $function_node->setAttribute( "param$i", $params[$i] );
}
}
sub set_transition_params {
my ( $self, $transition_name, $fun_type, $fun_name, $function, @params ) = @_;
my $transition = $self->get_transition_by_name($transition_name);
+ my $transition_node = $transition->{node};
my $old_params = 'None';
if ( exists $transition->{$fun_type}{function}{$fun_name} ) {
@@ -357,69 +328,28 @@ sub set_transition_params {
"transition %-16s: adjust %s %s function parameters [%s] -> [%s]\n",
$transition_name, $fun_name, $fun_type, $old_params, join( q{ }, @params ) );
- if ( not defined $transition->{$fun_type}{function}{$fun_name}{node} ) {
- my ($fun_node) = $transition->{node}->findnodes("./${fun_type}function");
- if ($fun_node) {
- my $new_node = XML::LibXML::Element->new($fun_name);
- $transition->{$fun_type}{function}{$fun_name}{node} = $new_node;
- $fun_node->appendChild($new_node);
- }
- else {
- say
-" skipping XML write-back because of missing ${fun_type}function node";
- return;
- }
- }
+ my ($function_parent) = $transition_node->findnodes("./${fun_type}/function");
- if ( defined $function ) {
- my $cdata_node = XML::LibXML::CDATASection->new($function);
- $transition->{$fun_type}{function}{$fun_name}{node}->removeChildNodes;
- $transition->{$fun_type}{function}{$fun_name}{node}
- ->appendChild($cdata_node);
+ if (not $function_parent) {
+ my ($property_node) = $transition_node->findnodes("./${fun_type}");
+ $function_parent = XML::LibXML::Element->new('function');
+ $property_node->appendChild($function_parent);
}
- for my $i ( 0 .. $#params ) {
- $transition->{$fun_type}{function}{$fun_name}{params}[$i] = $params[$i];
- $transition->{$fun_type}{function}{$fun_name}{node}
- ->setAttribute( "param$i", $params[$i] );
+ for my $function_node ($function_parent->findnodes("./${fun_name}")) {
+ $function_parent->removeChild($function_node);
}
-}
-
-sub set_transition_data {
- my ( $self, $transition_name, $duration, $energy, $rel_energy_prev, $rel_energy_next ) = @_;
-
- my $transition = $self->get_transition_by_name($transition_name);
- $duration = sprintf( '%.f', $duration );
- $energy = sprintf( '%.f', $energy );
-
- printf( 'transition %-16s: adjust duration %d -> %d µs',
- $transition->{name}, $transition->{duration}{static}, $duration);
- $transition->{duration}{static} = $duration;
- $transition->{node}->setAttribute('duration', $duration);
- printf( ', absolute energy %d -> %d pJ',
- $transition->{energy}{static}, $energy );
+ my $function_node = XML::LibXML::Element->new($fun_name);
+ my $function_content = XML::LibXML::CDATASection->new($function);
- $transition->{energy}{static} = $energy;
- $transition->{node}->setAttribute( 'energy', $energy );
+ $function_node->appendChild($function_content);
+ $function_parent->appendChild($function_node);
- if (defined $rel_energy_prev) {
- $rel_energy_prev = sprintf('%.f', $rel_energy_prev);
- printf( ", relative_prev energy %d -> %d pJ",
- $transition->{rel_energy_prev}{static}, $rel_energy_prev );
-
- $transition->{rel_energy_prev}{static} = $rel_energy_prev;
- $transition->{node}->setAttribute( 'rel_energy_prev', $rel_energy_prev );
- }
- if (defined $rel_energy_next) {
- $rel_energy_next = sprintf('%.f', $rel_energy_next);
- printf( ", relative_next energy %d -> %d pJ",
- $transition->{rel_energy_next}{static}, $rel_energy_next );
-
- $transition->{rel_energy_next}{static} = $rel_energy_next;
- $transition->{node}->setAttribute( 'rel_energy_next', $rel_energy_next );
+ for my $i ( 0 .. $#params ) {
+ $transition->{$fun_type}{function}{$fun_name}{params}[$i] = $params[$i];
+ $function_node->setAttribute( "param$i", $params[$i] );
}
- print("\n");
}
sub save {