ScEpTIC Extension ================= .. |ratchet| raw:: html ratchet 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|. .. _alfred-configuration-label: 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-label: 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-label: 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-label: 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.