PHY Abstraction

The signal-to-interference-plus-noise ratio (SINR) that a single codeword experiences across multiple streams, computed via
PostEqualizationSINR
, is aggregated into a single effective SINR value. The effective SINR is chosen so that, if all subcarriers and streams experienced it uniformly, the resulting block error rate (BLER) would remain approximately the same.The effective SINR is then mapped to a BLER value via precomputed tables, based on the code block size.
The transport BLER (TBLER) can be finally computed as the probability that at least one of the code blocks in the transport block is not correctly received.
For a usage example of PHY abstraction in Sionna, refer to the Physical Layer Abstraction notebook.
Next, we formally describe the general principle of effective SINR mapping (ESM) and the exponential ESM (EESM) model.
Thus, the corresponding effective SINR can be expressed as:
Single-link channel. In the basic case with one link (
To obtain the pairwise
codeword error probability, we average expression (62) across all
where the inequality stems again from the Chernoff bound.
Multi-link channel. Expression (63) extends to a multi-link channel
(
EESM expression. By equating the multi-link pairwise error probability bound (64) with the analogous single-link expression (61), we recognize that the multi-link channel is analogous to a single-link channel with SINR:
Note that the introduction of parameter
- class sionna.sys.EffectiveSINR(*args, precision=None, **kwargs)[source]
Class template for computing the effective SINR from input SINR values across multiple subcarriers and streams
- Input:
sinr ([…, num_ofdm_symbols, num_subcarriers, num_ut, num_streams_per_ut], tf.float) – Post-equalization SINR in linear scale for different OFDM symbols, subcarriers, users and streams. If one entry is zero, the corresponding stream is considered as not utilized.
mcs_index ([…, num_ut], tf.int32 (default: None)) – Modulation and coding scheme (MCS) index for each user
mcs_table_index ([…, num_ut], tf.int32 (default: None)) – MCS table index for each user. For further details, refer to the Note.
mcs_category ([…, num_ut], tf.int32 (default: None)) – MCS table category for each user. For further details, refer to the Note.
per_stream (bool (default: False)) – If True, the effective SINR is computed on a per-user and per-stream basis and is aggregated across different subcarriers. If False, the effective SINR is computed on a per-user basis and is aggregated across streams and subcarriers.
kwargs (dict) – Additional input parameters
- Output:
sinr_eff (([…, num_ut, num_streams_per_ut] | […, num_ut]), tf.float) – Effective SINR in linear scale for each user and associated stream. If
per_stream
is True, thensinr_eff
has shape […, num_ut, num_streams_per_rx], andsinr_eff[..., u, s]
is the effective SINR for stream s of user u across all subcarriers. Ifper_stream
is False, thensinr_eff
has shape […, num_ut], andsinr_eff[..., u]
is the effective SINR for user u across all streams and subcarriers.
- class sionna.sys.EESM(load_beta_table_from='default', sinr_eff_min_db=-30, sinr_eff_max_db=30, precision=None)[source]
Computes the effective SINR from input SINR values across multiple subcarriers and streams via the exponential effective SINR mapping (EESM) method
Let
be the SINR experienced by user on subcarrier , and stream . Ifper_stream
is False, it computes the effective SINR aggregated across all utilized streams and subcarriers for each user :where
is a parameter depending on the Modulation and Coding Scheme (MCS) of user .If
per_stream
is True, it computes the effective SINR aggregated across subcarriers, for each user and associated stream :- Parameters:
load_beta_table_from (str) – File name from which the tables containing the values of
parameters are loadedsinr_eff_min_db (float (default: -30)) – Minimum effective SINR value [dB]. Useful to avoid numerical errors
sinr_eff_max_db (float (default: 50)) – Maximum effective SINR value [dB]. Useful to avoid numerical errors
precision (None (default) | “single” | “double”) – Precision used for internal calculations and outputs. If set to None,
precision
is used.
- Input:
sinr ([…, num_ofdm_symbols, num_subcarriers, num_ut, num_streams_per_ut], tf.float) – Post-equalization SINR in linear scale for different OFDM symbols, subcarriers, users and streams. If one entry is zero, the corresponding stream is considered as not utilized.
mcs_index ([…, num_ut], tf.int32) – Modulation and coding scheme (MCS) index for each user
mcs_table_index ([…, num_ut], tf.int32 (default: 1)) – MCS table index for each user. For further details, refer to the Note.
mcs_category ([…, num_ut], tf.int32 (default: None)) – MCS table category for each user. For further details, refer to the Note.
per_stream (bool (default: False)) – If True, then the effective SINR is computed on a per-user and per-stream basis and is aggregated across different subcarriers. If False, then the effective SINR is computed on a per-user basis and is aggregated across streams and subcarriers.
- Output:
sinr_eff (([…, num_ut, num_streams_per_ut] | […, num_ut]), tf.float) – Effective SINR in linear scale for each user and associated stream. If
per_stream
is True, thensinr_eff
has shape […, num_ut, num_streams_per_rx], andsinr_eff[..., u, s]
is the effective SINR for stream s of user u across all subcarriers. Ifper_stream
is False, thensinr_eff
has shape […, num_ut], andsinr_eff[..., u]
is the effective SINR for user u across all streams and subcarriers.
Note
If the input SINR is zero for a specific stream, the stream is considered unused and does not contribute to the effective SINR computation.
Example
from sionna.phy import config from sionna.sys import EESM from sionna.phy.utils import db_to_lin batch_size = 10 num_ofdm_symbols = 12 num_subcarriers = 32 num_ut = 15 num_streams_per_ut = 2 # Generate random MCS indices mcs_index = config.tf_rng.uniform([batch_size, num_ut], minval=0, maxval=27, dtype=tf.int32) # Instantiate the EESM object eesm = EESM() # Generate random SINR values sinr_db = config.tf_rng.uniform([batch_size, num_ofdm_symbols, num_subcarriers, num_ut, num_streams_per_ut], minval=-5, maxval=30) sinr = db_to_lin(sinr_db) # Compute the effective SINR for each receiver # [batch_size, num_rx] sinr_eff = eesm(sinr, mcs_index, mcs_table_index=1, per_stream=False) print(sinr_eff.shape) # (10, 15) # Compute the per-stream effective SINR for each receiver # [batch_size, num_rx, num_streams_per_rx] sinr_eff_per_stream = eesm(sinr, mcs_index, mcs_table_index=2, per_stream=True) print(sinr_eff_per_stream.shape) # (10, 15, 2)
- property beta_table
Maps MCS indices to the corresponding parameters, commonly called
, calibrating the Exponential Effective SINR Map (EESM) method. It has the formbeta_table['index'][mcs_table_index][mcs]
- Type:
dict (read-only)
- property beta_table_filenames
Get/set the absolute path name of the JSON file containing the mapping between MCS and EESM beta parameters, stored in
beta
- Type:
str | list of str
- property beta_tensor
Tensor corresponding to
self.beta_table
- Type:
[n_tables, n_mcs], tf.float (read-only)
- class sionna.sys.PHYAbstraction(interp_fun=None, mcs_decoder_fun=None, transport_block_fun=None, sinr_effective_fun=None, load_bler_tables_from='default', snr_db_interp_min_max_delta=(-5, 30.01, 0.1), cbs_interp_min_max_delta=(24, 8448, 100), bler_interp_delta=0.01, precision=None, **kwargs)[source]
Class for physical layer abstraction
For a given signal-to-interference-plus-noise-ratio (SINR) provided on a per-stream basis, and for a given modulation order, coderate, and number of coded bits specified for each user, it produces the corresponding number of successfully decoded bits, HARQ feedback, effective SINR, block error rate (BLER), and transport BLER (TBLER).
At object instantiation, precomputed BLER tables are loaded and interpolated on a fine (SINR, code block size) grid for each modulation and coding scheme (MCS) index.
When the object is called, the post-equalization SINR is first converted to an effective SINR. Then, the effective SINR is used to retrieve the BLER from pre-computed and interpolated tables. Finally, the BLER determines the TBLER, which represents the probability that at least one code block is incorrectly received.
- Parameters:
interp_fun (instance of
Interpolate
| None (default)) – Function for interpolating data defined on rectangular or unstructured grids, used for BLER and SINR interpolation. If None, it is set to an instance ofSplineGriddataInterpolation
.mcs_decoder_fun (instance of
MCSDecoder
| None (default)) – Function mapping MCS indices to modulation order and coderate. If None, it is set to an instance ofMCSDecoderNR
.transport_block_fun (instance of
TransportBlock
| None (default)) – Function computing the number and size (measured in bits) of code blocks within a transport block. If None, it is set to an instance ofTransportBlockNR
.sinr_effective_fun (instance of
EffectiveSINR
| None (default)) – Function computing the effective SINR. If None, it is set to an instance ofEESM
.load_bler_tables_from (str | list of str (default: “default”)) – Name of file(s) containing pre-computed SINR-to-BLER tables for different categories, tables indices, MCS indices, SINR and code block sizes. If “default”, then the pre-computed tables stored in “phy/abstraction/bler_tables/” folder are loaded.
snr_db_interp_min_max_delta ([3], tuple (default: (-5, 30.01, .1))) – Tuple of (min, max, delta) values [dB] defining the list of SINR [dB] values at which the BLER is interpolated, as min, min+delta, min+2*delta,…, up until max
cbs_interp_min_max_delta ([3], tuple (default: (24, 8448, 100))) – Tuple of (min, max, delta) values defining the list of code block size values at which the BLER and SINR are interpolated, as min, min+delta, min+2*delta,…,max
bler_interp_delta (float (default: 0.01)) – Spacing of the BLER grid at which SINR is interpolated
precision (None (default) | “single” | “double”) – Precision used for internal calculations and outputs. If set to None,
precision
is used.kwargs – Additional inputs for
bler_snr_interp_fun
,mcs_decoder_fun
,transport_block_fun
- Input:
mcs_index ([…, num_ut], tf.int32) – MCS index for each user
sinr ([…, num_ofdm_symbols, num_subcarriers, num_ut, num_streams_per_ut], tf.float | None (default)) – Post-equalization SINR in linear scale for each OFDM symbol, subcarrier, user and stream. If None, then
sinr_eff
andnum_allocated_re
are both required.sinr_eff ([…, num_ut], tf.float | None (default)) – Effective SINR in linear scale for each user. If None, then
sinr
is required.num_allocated_re ([…, num_ut], tf.int32 | None (default)) – Number of allocated resources in a slot, computed across OFDM symbols, subcarriers and streams, for each user. If None, then
sinr
is required.mcs_table_index ([…, num_ut], tf.int32 | int (default: 1)ß) – MCS table index. For further details, refer to the Note.
mcs_category ([…, num_ut], tf.int32 | int (default: 0)) – MCS table category. For further details, refer to the Note.
check_mcs_index_validity (bool (default: True)) – If True, an ValueError is thrown is the input MCS indices are not valid for the given configuration
- Output:
num_decoded_bits ([…, num_ut], tf.int32) – Number of successfully decoded bits for each user
harq_feedback ([…, num_ut], -1 | 0 | 1) – If 0 (1, resp.), then a NACK (ACK, resp.) is received. If -1, feedback is missing since the user is not scheduled for transmission.
sinr_eff ([…, num_ut], tf.float) – Effective SINR in linear scale for each user
tbler ([…, num_ut], tf.float) – Transport block error rate (BLER) for each user
bler ([…, num_ut], tf.float) – Block error rate (BLER) for each user
Note
In this class, the terms SNR (signal-to-noise ratio) and SINR (signal-to-interference-plus-noise ratio) can be used interchangeably. This is because the equivalent AWGN model used for BLER mapping does not explicitly account for interference.
Example
import numpy as np from sionna.sys import PHYAbstraction, EESM from sionna.phy.nr.utils import MCSDecoderNR, TransportBlockNR from sionna.phy.utils import SplineGriddataInterpolation # Instantiate the class for BLER and SINR interpolation bler_snr_interp_fun = SplineGriddataInterpolation() # Instantiate the class for mapping MCS to modulation order and coderate # in 5G NR mcs_decoder_fun = MCSDecoderNR() # Instantiate the class for computing the number and size of code blocks # within a transport block in 5G NR transport_block_fun = TransportBlockNR() # Instantiate the class for computing the effective SINR sinr_effective_fun = EESM() # By instantiating a PHYAbstraction object, precomputed BLER tables are # loaded and interpolated on a fine (SINR, code block size) grid for each MCS phy_abs = PHYAbstraction( bler_snr_interp_fun=bler_snr_interp_fun, mcs_decoder_fun=mcs_decoder_fun, transport_block_fun=transport_block_fun, sinr_effective_fun=sinr_effective_fun) # Plot a BLER table phy_abs.plot(plot_subset={'category': {0: {'index': {1: {'MCS': 14}}}}}, show=True);
# One can also compute new BLER tables # SINR values and code block sizes @ new simulations are performed snr_dbs = np.linspace(-5, 25, 5) cb_sizes = np.arange(24, 8448, 1000) # MCS values @ new simulations are performed sim_set = {'category': { 0: {'index': { 1: {'MCS': [15]} }}}} # Compute new tables new_table = phy_abs.new_bler_table( snr_dbs, cb_sizes, sim_set, max_mc_iter=15, batch_size=10, verbose=True)
- property bler_interp_delta
Get/set the spacing of the BLER grid at which SINR is interpolated
- Type:
float
- property bler_table
Collection of tables containing BLER values for different values of SNR, MCS table, MCS index and CB size.
bler_table['category'][cat]['index'][mcs_table_index]['MCS'][mcs]['CBS'][cb_size]
contains the lists of BLER values.bler_table['category'][cat]['index'][mcs_table_index]['MCS'][mcs]['SNR_db']
contains the list of SNR values.bler_table['category'][cat]['index'][mcs_table_index]['MCS'][mcs]['EbN0_db']
contains the list of values- Type:
dict (read-only)
- property bler_table_filenames
Get/set the absolute path name of the files containing BLER tables
- Type:
str | list of str
- property bler_table_interp
Tensor containing BLER values interpolated across SINR and CBS values, for different categories and MCS table indices. The first axis accounts for the category, e.g., ‘PDSCH’ or ‘PUSCH’ in 5G-NR, the second axis corresponds to the 38.214 MCS table index while the third axis carries the MCS index.
- Type:
[n_categories,n_tables,n_mcs,n_cbs_index,n_snr], tf.float (read-only)
- property cbs_interp_min_max_delta
Get/set the tuple of (min, max, delta) values defining the list of code block size values at which the BLER and SINR are interpolated, as min, min+delta, min+2*delta,…, up until max.
- Type:
[3], tuple
- get_bler(mcs_index, mcs_table_index, mcs_category, cb_size, snr_eff)[source]
Retrieves from interpolated tables the BLER corresponding to a certain table index, MCS, CB size, and SINR values provided as input. If the corresponding interpolated table is not available, it returns Inf.
- Input:
mcs_index ([…], tf.int32) – MCS index for each user
mcs_table_index ([…], tf.int.32 | int) – MCS table index for each user. For further details, refer to the Note.
mcs_category ([…], tf.int32) – MCS table category for each user. For further details, refer to the Note.
cb_size ([…], tf.int32) – Code block size for each user
snr_eff ([…], tf.float) – Effective SINR for each user
- Output:
bler ([…], tf.float) – BLER corresponding to the input channel type, table index, MCS, CB size and SINR, retrieved from internal interpolation tables
- get_idx_from_grid(val, which)[source]
Retrieves the index of a SINR of CBS value in the interpolation grid.
- Input:
val ([…], tf.float) – Values to be quantized
which (“snr | “cbs”) – Whether the values are SNR (equivalent to SINR) or CBS
- Output:
idx ([…], tf.int32) – Index of the values in the interpolation grid
- static load_table(filename)[source]
Loads a table stored in JSON file.
- Input:
filename (str) – Name of the JSON file containing the table
- Output:
dict – table loaded from file
- new_bler_table(snr_dbs, cb_sizes, sim_set, channel=None, filename=None, write_mode='w', batch_size=1000, max_mc_iter=100, target_bler=None, graph_mode='graph', early_stop=True, filename_log=None, verbose=True)[source]
Computes static tables mapping SNR values of an AWGN channel to the corresponding block error rate (BLER) via Monte-Carlo simulations for different MCS indices, code block sizes and channel types. Note that the newly computed table is merged with the internal
self.bler_table
.The simulation continues with the next SNR point after
max_mc_iter
batches of sizebatch_size
have been simulated. Early stopping allows to stop the simulation after the first error-free SNR point or after reaching a certaintarget_ber
ortarget_bler
. For more details, please seesim_ber()
.- Input:
snr_dbs (list | float) – List of SNR [dB] value(s) at which the BLER is computed
cb_sizes (list | int) – List of code block (CB) size(s) at which the BLER is computed
sim_set (dict) – Dictionary contains the list of the MCS indices at which the BLER is computed via simulation. The dictionary structure is of the kind:
sim_set['category'][category]['index'][mcs_table_index]['MCS'][mcs_list]
.channel (instance of
SingleLinkChannel
| None) – Object for simulating single-link i.e., single-carrier and single-stream, channels. If None, it is set to an instance ofCodedAWGNChannelNR
.filename (str | None (default)) – Name of JSON file where the BLER tables are saved. If None, results are not saved.
write_mode (‘w’ (default) | ‘a’) – If ‘w’, then
bler_table_filename
is rewritten. If ‘a’, then the produced results are appended tobler_table_filename
.batch_size (int (default: 2000)) – Batch size for Monte-Carlo BLER simulations
max_mc_iter (int (default: 100)) – Maximum number of Monte-Carlo iterations per SNR point
target_bler (None (default) | tf.float32) – The simulation stops after the first SNR point which achieves a lower block error rate as specified by
target_bler
. This requiresearly_stop
to be True.graph_mode (None | “graph” (default) | “xla”) – Execution mode of
EquivalentChannel
call method. If None, thenEquivalentChannel
is executed as is.num_iter_decoder (int (default: 20)) – Number of decoder iterations. See
LDPC5GDecoder
for more details.cn_update (“boxplus-phi” (default) | “boxplus” | “minsum” | “offset-minsum” | “identity” | callable) – Check node update rule. See
LDPC5GDecoder
for more details.filename_log (str | None (default)) – Name of logging file. If None, logs are not produced.
verbose (bool (default: True)) – If True, the simulation progress is visualized, as well as the names of files of results and figures
- Output:
new_table (dict) – Newly computed BLER table
- plot(plot_subset='all', show=True, save_path=None)[source]
Visualizes and/or saves to file the SINR-to-BLER tables
- Input:
plot_subset (dict | “all”) – Dictionary containing the list of MCS indices to consider, stored at
plot_subset['category'][category]['index'][mcs_table_index]['MCS']
. If “all”, then plots are produced for all available BLER tables.show (bool (default: True)) – If True, then plots are visualized
save_path (str | None (default)) – Folder path where BLER plots are saved. If None, then plots are not saved
- Output:
fignames (list) – List of names of files containing BLER plots
- property snr_db_interp_min_max_delta
Get/set the tuple of (min, max, delta) values [dB] defining the list of SINR values at which the BLER is interpolated, as min, min+delta, min+2*delta,…, up until max
- Type:
[3], tuple
- property snr_table_interp
Tensor containing SINR values interpolated across BLER and CBS values, for different categories and MCS table indices. The first axis accounts for the category, e.g., ‘PDSCH’ or ‘PUSCH’ in 5G-NR, the second axis corresponds to the 38.214 MCS table index and the third axis accounts for the MCS index.
- Type:
[n_categories,n_tables,n_mcs,n_cbs_index,n_bler], tf.float (read-only)
- References:
- [5GLENA]
S. Lagen, K. Wanuga, H. Elkotby, S. Goyal, N. Patriciello, L. Giupponi. “New radio physical layer abstraction for system-level simulations of 5G networks”. IEEE International Conference on Communications (ICC), 2020