ScEpTIC Extension

We extended ScEpTIC with the support for:
  • AST Transformations

  • Energy Model

  • Performance Analysis

  • Memory Usage Analysis


AST Transformations

We extended ScEpTIC to support analysis and transformation passes for the AST. This extension allows developers to transform the AST of functions using python programming language. Before executing any analysis, ScEpTIC automatically applies the program transformations defined in its configuration.

We use this extension to implement part of ALFRED pipeline.

Configuration Parameters

We extended the program_configuration configuration variable with a program_transformations key that takes an ordered list of the transformations that ScEpTIC applies to the program ASTs:

'program_transformations': []

We can specify custom configurations for program transformations using the configuration variable transformation_options:

transformation_options = {
    'transformation_name': config...
}

transformation_options is a dictionary whose key-value pairs correspond to the name of a transformation and its configuration.

Custom Program Transformations

All the program transformations supported by our extension of ScEpTIC are placed inside the directory ScEpTIC/AST/Transformations.

To create a custom program transformation pass, it is sufficient to to create a new directory inside the transformation directory with the name of the program transformation we are going to build. Then, we need to create a __init__.py file inside the new directory, which defines the function apply_transformation():

def apply_transformation(functions, vmstate):
   ...

Such function is the one that ScEpTIC calls to apply the program transformations to the ASTs and takes two arguments:

  • functions: a list containing the functions ASTs

  • vmstate: the state of ScEpTIC

The configuration of the transformation pass can be read using vmstate.transformation_options['transformation_name']

Available Transformations

We designed two different transformations:

  • virtual_memory: applies ALFRED pipeline

  • ratchet: places checkpoint calls inside the program using the strategy of ratchet.

virtual_memory

The virtual_memory transformation applies ALFRED memory mapping to the program.

The transformation requires the following configuration parameters in ScEpTIC configuration:

transformation_options = {
    "virtual_memory": {
        "n_min_function": None,
        "optimize_saved_registers": True,
    }
}
  • n_min_function is the n_min function that ALFRED uses to consolidate read instructions

  • optimize_saved_registers specifies if checkpoint operations only save the registers that are in use

Note that the n_min_function can be defined as:

def n_min_function(n):
    ...

where n corresponds to the number of memory write operations that ALFRED identified when consolidating read instructions. The function must return the number of minimum reads required to proceed with the promotion onto volatile memory.

ratchet

The ratchet transformation places checkpoint calls inside the program using the strategy of ratchet.

The transformation requires the following configuration parameters in ScEpTIC configuration:

transformation_options = {
    "ratchet": {
        "functions_with_outside_frame_accesses": [],
        "optimize_saved_registers": True,
    }
}
  • functions_with_outside_frame_accesses list of the name of functions that access outside their stack frame

  • optimize_saved_registers specifies if checkpoint operations only save the registers that are in use


Energy Model

We extended ScEpTIC to support the calculation of the energy consumption of devices. ScEpTIC uses the python files inside ScEpTIC/emulator/energy to calculate a device energy consumption. We implemented a module that calculates the energy consumption of the MSP430FR5969, which is available inside ScEpTIC/emulator/energy/msp430.py.

To implement a module that calculates the energy consumption of a different device is sufficient to extend the EnergyCalculator base class, found in ScEpTIC/emulator/energy/__init__.py. The extended class needs to expose the following attributes: - voltage: nominal operating voltage - frequency: nominal operating frequency - nvm_extra_cycles: number of wait cycles for NVM accesses - energy_clock_cycle: energy consumption per clock cycle - energy_volatile_memory_access: extra energy consumption per clock cycle for volatile memory accesses - energy_non_volatile_memory_access: extra energy consumption per clock cycle for non-volatile memory accesses - non_volatile_increase: % increase in energy of a single clock cycle accessing non-volatile memory vs volatile memory - adc_active_cycles: number of clock cycles while the ADC is active for checkpoint trigger calls - energy_clock_cycle_adc: extra energy consumption per cycle due to ADC on - adc_instructions: number of instructions executed to initialize, query, and power off the ADC

The extended class needs to expose the following method:
  • n_min_function(n_writes): function to calculate the n_min parameter for applying the read consolidaton for the virtual_memory trasformation

Performance Analysis

We implement an interruption manager that measures the program energy consumption, the executed clock cycles, the number of power failures, and the number of checkpoint/restore operations. The interruption manager is called EnergyMeasureInterruptionManager and it is located in ScEpTIC/emulator/intermittent_executor/interruption_managers/energy_measure.py. Note that the EnergyMeasureInterruptionManager is specifically designed to use ALFRED memory attributes.

Configuration Parameters

We extended ScEpTIC configuration file with the following variables:

run_energy_measure = True

clock_frequency = '8Mhz'

energy_simulation_config = {
    'use_trigger_calls': True,
    'simulate_power_failures': True,
    'trigger_call_to_checkpoint_probability_range': [0, 10, 1],
    'clock_cycles_between_power_failures': 50000,
}

energy_calculator = None
  • run_energy_measure specifies if ScEpTIC needs to execute this analysis

  • clock_frequency specifies the clock frequency of the MCU

  • energy_simulation_config specifies the energy configuration - use_trigger_calls specifies if the simulated checkpoint calls act as trigger calls - simulate_power_failures specifies if ScEpTIC should simulate power failures - trigger_call_to_checkpoint_probability_range specifies a probability range of trigger calls converting into checkpoints - clock_cycles_between_power_failures specifies the number of clock cycles executed between two simulated power failures

  • energy_calculator specifies the energy model and is an instance of EnergyCalculator

Example Configuration

Note that in the example configuration file we provide a pre-configured model for the MSP430FR5969:

clock_frequency = '8Mhz'

energy_simulation_config = {
    'use_trigger_calls': True,
    'simulate_power_failures': True,
    'trigger_call_to_checkpoint_probability_range': [0, 10, 1],
    'clock_cycles_between_power_failures': 50000,
}

msp430fr5969_datasheet = {
    'registers': 10,
    'current_consumption': {
        '8Mhz': {
            'frequency': '8M',        # Clock Frequency
            'voltage': '3',           # Voltage
            'n_waits': '0',           # Number of wait cycles for FRAM accesses
            'I_am_ram': '585u',       # Current consumption for one clock cycle when program and data resides in SRAM
            'I_am_fram_uni': '1220u', # Current consumption for one clock cycle when program and data resides in FRAM
            'I_am_fram': '890u',      # Current consumption for one clock cycle when program resides in FRAM and data in SRAM
            'I_am_fram_hit': '0.75',  # Cache hit rate of I_am_fram
        },
        '16Mhz': {
            'frequency': '16M',       # Clock Frequency
            'voltage': '3',           # Voltage
            'n_waits': '1',           # Number of wait cycles for FRAM accesses
            'I_am_ram': '1070u',      # Current consumption for one clock cycle when program and data resides in SRAM
            'I_am_fram_uni': '1845u', # Current consumption for one clock cycle when program and data resides in FRAM
            'I_am_fram': '1420u',     # Current consumption for one clock cycle when program resides in FRAM and data in SRAM (cache hit 75%)
            'I_am_fram_hit': '0.75',  # Cache hit rate of I_am_fram
        },
    },
    'ADC': {
        'T_off_on': '100n',     # Time to wait for switching the ADC on
        'T_sampling': '1u',     # Time to get a sample
        'I_min': '145u',        # Minimum current consumption of the ADC when it is active
        'I_max': '185u',        # Maximum current consumption of the ADC when it is active
        'N_init': '3',          # Number of instructions to init the ADC
                                # set ADC mode(single); set ADC op_type(read); set ADC on
        'N_off': '1',           # Number of instructions to stop the ADC
                                # set ADC mode(off)
        'N_transfer_ops': '1',  # Number of instructions to retrieve data from the ADC
                                # var_data <- REG_ADC
        'I_to_consider': 'min', # Current consumption of the ADC to consider (min, max, avg)
    },
}

mcu_datasheet = msp430fr5969_datasheet['current_consumption'][clock_frequency]

from ScEpTIC.emulator.energy.msp430 import MSP430EnergyCalculator

energy_calculator = MSP430EnergyCalculator(mcu_datasheet, msp430fr5969_datasheet['registers'], msp430fr5969_datasheet['ADC'])

n_min_function = lambda x: energy_calculator.n_min_function(x)

Analysis Output

This analysis creates an energy directory where ScEpTIC stores analysis results. The energy directory contains two files, results.json and results.txt. The former provides the anaysis results in json format and the latter provides a textual representation of the results.


Memory Usage Analysis

We implement an interruption manager that measures the program memory occupancy when using ALFRED. The interruption manager is called MemorySizeIdentifier and it is located in ScEpTIC/emulator/intermittent_executor/interruption_managers/memory_size.py. Note that the MemorySizeIdentifier is specifically designed to use ALFRED memory attributes.

Configuration Parameters

We extended ScEpTIC configuration file with the following variables:

run_memory_size_measure = True

memory_size_config = {
    'double_buffer_for_anomalies': True,
    'global_variables_default_memory': VirtualMemoryEnum.VOLATILE,
}
  • run_memory_size_measure specifies if ScEpTIC needs to execute this analysis

  • memory_size_config specifies the configuration of this analysis - double_buffer_for_anomalies specifies if the simulated checkpoint mechanism double buffers memory locations to avoid intermittence anomalies - global_variables_default_memory: specifies the default memory where global variables are allocated

Analysis Output

This analysis creates an memory_size directory where ScEpTIC stores analysis results. The memory_size directory contains a results.json file, which contains the analysis results in JSON format.