Skip to content

Commit

Permalink
Release v0.12.1
Browse files Browse the repository at this point in the history
Signed-off-by: The Sionna Team <[email protected]>
  • Loading branch information
gmarcusm committed Jan 4, 2023
1 parent ce9bbaf commit eb1d5c4
Show file tree
Hide file tree
Showing 17 changed files with 110 additions and 65 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ In order to run the tutorial notebooks on your machine, you also need [Jupyter](
You can alternatively test them on [Google Colab](https://colab.research.google.com/).
Although not necessary, we recommend running Sionna in a [Docker container](https://www.docker.com).

Sionna requires [TensorFlow 2.7-2.10](https://www.tensorflow.org/install) and Python 3.6-3.9. We recommend Ubuntu 20.04. TensorFlow 2.6 still works but is not recommended because of known, unpatched CVEs.
Sionna requires [TensorFlow 2.7-2.11](https://www.tensorflow.org/install) and Python 3.6-3.9. We recommend Ubuntu 20.04. TensorFlow 2.6 still works but is not recommended because of known, unpatched CVEs.

We refer to the [TensorFlow GPU support tutorial](https://www.tensorflow.org/install/gpu) for GPU support and the required driver setup.

Expand All @@ -35,7 +35,7 @@ On macOS, you need to install [tensorflow-macos](https://github.com/apple/tensor
```
>>> import sionna
>>> print(sionna.__version__)
0.12.0
0.12.1
```

3.) Once Sionna is installed, you can run the [Sionna "Hello, World!" example](https://nvlabs.github.io/sionna/examples/Hello_World.html), have a look at the [quick start guide](https://nvlabs.github.io/sionna/quickstart.html), or at the [tutorials](https://nvlabs.github.io/sionna/tutorials.html).
Expand Down Expand Up @@ -94,7 +94,7 @@ We recommend to do this within a [virtual environment](https://docs.python.org/3
```
>>> import sionna
>>> print(sionna.__version__)
0.12.0
0.12.1
```

## License and Citation
Expand Down
6 changes: 3 additions & 3 deletions doc/source/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ You can alternatively test them on `Google Colab <https://colab.research.google.
Although not necessary, we recommend running Sionna in a `Docker container <https://www.docker.com>`_.

.. note::
Sionna requires `TensorFlow 2.7-2.10 <https://www.tensorflow.org/install>`_ and Python 3.6-3.9.
Sionna requires `TensorFlow 2.7-2.11 <https://www.tensorflow.org/install>`_ and Python 3.6-3.9.
We recommend Ubuntu 20.04.

We refer to the `TensorFlow GPU support tutorial <https://www.tensorflow.org/install/gpu>`_ for GPU support and the required driver setup.
Expand Down Expand Up @@ -37,7 +37,7 @@ e.g., using `conda <https://docs.conda.io>`_. On macOS, you need to install `ten
>>> import sionna
>>> print(sionna.__version__)
0.12.0
0.12.1
3.) Once Sionna is installed, you can run the `Sionna "Hello, World!" example <https://nvlabs.github.io/sionna/examples/Hello_World.html>`_, have a look at the `quick start guide <https://nvlabs.github.io/sionna/quickstart.html>`_, or at the `tutorials <https://nvlabs.github.io/sionna/tutorials.html>`_.

Expand Down Expand Up @@ -109,4 +109,4 @@ e.g., using `conda <https://docs.conda.io>`_.
>>> import sionna
>>> print(sionna.__version__)
0.12.0
0.12.1
10 changes: 10 additions & 0 deletions doc/source/made_with_sionna.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@ List of Projects

If you want your paper and code be listed here, please send an email to `[email protected] <mailto:[email protected]>`_ with links to the paper (e.g., `arXiv <https://arxiv.org>`_) and code repository (e.g., `GitHub <https://github.com>`_).

DUIDD: Deep-Unfolded Interleaved Detection and Decoding for MIMO Wireless Systems
*********************************************************************************
.. made-with-sionna::
:title: Bit Error and Block Error Rate Training for ML-Assisted Communication
:authors: Reinhard Wiesmayr, Chris Dick, Jakob Hoydis, Christoph Studer
:year: 2022
:version: 0.11
:link_arxiv: https://arxiv.org/abs/2212.07816
:link_github: https://github.com/IIP-Group/DUIDD
:abstract: Iterative detection and decoding (IDD) is known to achieve near-capacity performance in multi-antenna wireless systems. We propose deep-unfolded interleaved detection and decoding (DUIDD), a new paradigm that reduces the complexity of IDD while achieving even lower error rates. DUIDD interleaves the inner stages of the data detector and channel decoder, which expedites convergence and reduces complexity. Furthermore, DUIDD applies deep unfolding to automatically optimize algorithmic hyperparameters, soft-information exchange, message damping, and state forwarding. We demonstrate the efficacy of DUIDD using NVIDIA's Sionna link-level simulator in a 5G-near multi-user MIMO-OFDM wireless system with a novel low-complexity soft-input soft-output data detector, an optimized low-density parity-check decoder, and channel vectors from a commercial ray-tracer. Our results show that DUIDD outperforms classical IDD both in terms of block error rate and computational complexity.

Bit Error and Block Error Rate Training for ML-Assisted Communication
*********************************************************************
Expand Down
2 changes: 1 addition & 1 deletion examples/OFDM_MIMO_Detection.ipynb

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
tensorflow >=2.7.4, !=2.8.0, !=2.8.1, !=2.8.2, !=2.8.3, !=2.9.0, !=2.9.1 ; sys_platform != "darwin"
tensorflow-macos >=2.7 ; sys_platform == "darwin"
numpy
scipy
scipy >=1.6.0
matplotlib
importlib_resources
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ install_requires =
tensorflow-macos >=2.7 ; sys_platform == "darwin"
numpy
matplotlib
scipy
scipy >=1.6.0
importlib_resources

[options.package_data]
Expand Down
2 changes: 1 addition & 1 deletion sionna/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"""This is the Sionna library.
"""

__version__ = '0.12.0'
__version__ = '0.12.1'

from . import utils
from .constants import *
Expand Down
6 changes: 3 additions & 3 deletions sionna/fec/crc.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import numpy as np
import tensorflow as tf
from tensorflow.keras.layers import Layer
from sionna.fec.utils import int_mod_2

class CRCEncoder(Layer):
"""CRCEncoder(crc_degree, output_dtype=tf.float32, **kwargs)
Expand Down Expand Up @@ -223,9 +224,8 @@ def call(self, inputs):
x_crc = tf.matmul(x_exp32, self._g_mat_crc) # calculate crc bits

# take modulo 2 of x_crc (bitwise operations instead of tf.mod)
x_crc_uint8 = tf.cast(x_crc, tf.uint8)
x_bin = tf.bitwise.bitwise_and(x_crc_uint8, tf.constant(1, tf.uint8))
x_crc = tf.cast(x_bin, dtype=self.dtype)
x_crc = int_mod_2(x_crc)
x_crc = tf.cast(x_crc, dtype=self.dtype)

x_conc = tf.concat([x_exp, x_crc], -1)
x_out = tf.squeeze(x_conc, axis=-2)
Expand Down
40 changes: 14 additions & 26 deletions sionna/fec/ldpc/decoding.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,21 +224,6 @@ class LDPCBPDecoder(Layer):
If the shape of ``pcm`` is invalid or contains other values than
`0` or `1` or dtype is not `tf.float32`.
AssertionError
If ``trainable`` is not `bool`.
AssertionError
If ``track_exit`` is not `bool`.
AssertionError
If ``hard_out`` is not `bool`.
AssertionError
If ``stateful`` is not `bool`.
AssertionError
If ``cn_type`` is not `str`.
ValueError
If ``num_iter`` is not an integer greater (or equal) `0`.
Expand Down Expand Up @@ -328,7 +313,7 @@ def __init__(self,
# clipping value for the atanh function is applied (tf.float32 is used)
self._atanh_clip_value = 1 - 1e-7
# internal value for llr clipping
self._llr_max = 20
self._llr_max = tf.constant(20., tf.float32)

# init code parameters
self._num_cns = pcm.shape[0] # total number of check nodes
Expand Down Expand Up @@ -444,6 +429,17 @@ def num_iter(self, num_iter):
assert num_iter>=0, 'num_iter cannot be negative.'
self._num_iter = tf.constant(num_iter, dtype=tf.int32)

@property
def llr_max(self):
"""Max LLR value used for internal calculations and rate-matching."""
return self._llr_max

@llr_max.setter
def llr_max(self, value):
"""Max LLR value used for internal calculations and rate-matching."""
assert value>=0, 'llr_max cannot be negative.'
self._llr_max = tf.cast(value, dtype=tf.float32)

def show_weights(self, size=7):
"""Show histogram of trainable weights.
Expand Down Expand Up @@ -1212,8 +1208,6 @@ def __init__(self,
assert isinstance(return_infobits, bool), 'return_info must be bool.'
self._return_infobits = return_infobits

self._llr_max = 20 # internal max value for LLR initialization

assert isinstance(output_dtype, tf.DType), \
'output_dtype must be tf.DType.'
if output_dtype not in (tf.float16, tf.float32, tf.float64):
Expand Down Expand Up @@ -1258,8 +1252,6 @@ def __init__(self,
# no pruning; same length as before
self._n_pruned = encoder._n_ldpc



super().__init__(pcm,
trainable,
cn_type,
Expand All @@ -1274,11 +1266,6 @@ def __init__(self,
# Public methods and properties
#########################################

@property
def llr_max(self):
"""Max LLR value used for rate-matching."""
return self._llr_max

@property
def encoder(self):
"""LDPC Encoder used for rate-matching/recovery."""
Expand Down Expand Up @@ -1380,7 +1367,8 @@ def call(self, inputs):
[batch_size, nb_par_bits])

# negative sign due to logit definition
z = -self._llr_max * tf.ones([batch_size, k_filler], self._output_dtype)
z = -tf.cast(self._llr_max, self._output_dtype) \
* tf.ones([batch_size, k_filler], self._output_dtype)

llr_5g = tf.concat([x1, z, x2], 1)

Expand Down
8 changes: 6 additions & 2 deletions sionna/fec/linear/decoding.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,11 +338,15 @@ def _find_mrb(self, gm):
"""

bs = tf.shape(gm)[0]
s = gm.shape
idx_pivot = tf.TensorArray(tf.int64, self._k, dynamic_size=False)

# bring gm in systematic form (by so-called pivot method)
for idx_c in tf.range(self._k):

# ensure shape to avoid XLA incompatibility with TF2.11 in tf.range
gm = tf.ensure_shape(gm, s)

# find pivot (i.e., first pos with index 1)
idx_p = tf.argmax(gm[:, idx_c, :], axis=-1)

Expand Down Expand Up @@ -425,15 +429,15 @@ def call(self, inputs):
# clip inputs
llr_ch = tf.clip_by_value(llr_ch, -self._llr_max, self._llr_max)

# Step 1: sort LLRs
# step 1: sort LLRs
idx_sort = tf.argsort(tf.abs(llr_ch), direction="DESCENDING")

# permute gm per batch sample individually
gm = tf.broadcast_to(tf.expand_dims(self._gm, axis=0),
(bs, self._k,self._n))
gm_sort = tf.gather(gm, idx_sort, batch_dims=1, axis=-1)

# Step 2: Find most reliable basis (MRB)
# step 2: Find most reliable basis (MRB)
gm_mrb, idx_mrb = self._find_mrb(gm_sort)

# apply corresponding mrb permutations
Expand Down
6 changes: 3 additions & 3 deletions sionna/fec/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1449,9 +1449,9 @@ def int_mod_2(x):
"""

x_int8 = tf.cast(x, tf.int8)
y_int8 = tf.bitwise.bitwise_and(x_int8, tf.constant(1, tf.int8))
return tf.cast(y_int8, x.dtype)
x_int32 = tf.cast(x, tf.int32)
y_int32 = tf.bitwise.bitwise_and(x_int32, tf.constant(1, tf.int32))
return tf.cast(y_int32, x.dtype)

###########################################################
# Deprecated aliases that will not be included in the next
Expand Down
13 changes: 8 additions & 5 deletions sionna/mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,13 +248,16 @@ def __init__(self,
assert isinstance(trainable, bool), "trainable must be boolean"
self._trainable = trainable

assert isinstance(num_bits_per_symbol, int),\
# allow float inputs that represent int
assert isinstance(num_bits_per_symbol, (float,int)),\
"num_bits_per_symbol must be integer"

assert (num_bits_per_symbol%1==0),\
"num_bits_per_symbol must be integer"
num_bits_per_symbol = int(num_bits_per_symbol)

if self._constellation_type=="qam":
assert num_bits_per_symbol%2 == 0 and num_bits_per_symbol>0,\
"num_bits_per_symbol must be a mutliple of 2"
"num_bits_per_symbol must be a multiple of 2"
self._num_bits_per_symbol = int(num_bits_per_symbol)

assert initial_value is None, "QAM must not have an initial value"
Expand Down Expand Up @@ -574,8 +577,8 @@ class SymbolLogits2LLRs(Layer):
prior : [num_bits_per_symbol] or [...n, num_bits_per_symbol], tf.float
Prior for every bit as LLRs.
It can be provided either as a tensor of shape `[num_bits_per_symbol]` for the
entire input batch, or as a tensor that is "broadcastable"
It can be provided either as a tensor of shape `[num_bits_per_symbol]`
for the entire input batch, or as a tensor that is "broadcastable"
to `[..., n, num_bits_per_symbol]`.
Only required if the ``with_prior`` flag is set.
Expand Down
8 changes: 4 additions & 4 deletions test/unit/channel/test_3gpp_channel_lsp.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ def test_asa_dist(self, model, submodel):
b = (np.log10(104)-mu)/std
samples_ref = self.limited_normal(TestLSP.BATCH_SIZE, a, b, mu, std)
# KS-test does not work great with discontinuties.
# Therefore, we test only the contunuous part of the CDF, and also test
# Therefore, we test only the continuous part of the CDF, and also test
# that the maximum value allowed is not exceeded
maxval = np.max(samples)
samples = samples[samples < np.log10(104)]
Expand All @@ -333,7 +333,7 @@ def test_asd_dist(self, model, submodel):
b = (np.log10(104)-mu)/std
samples_ref = self.limited_normal(TestLSP.BATCH_SIZE, a, b, mu, std)
# KS-test does not work great with discontinuties.
# Therefore, we test only the contunuous part of the CDF, and also test
# Therefore, we test only the continuous part of the CDF, and also test
# that the maximum value allowed is not exceeded
maxval = np.max(samples)
samples = samples[samples < np.log10(104)]
Expand All @@ -352,7 +352,7 @@ def test_zsa_dist(self, model, submodel):
b = (np.log10(52)-mu)/std
samples_ref = self.limited_normal(TestLSP.BATCH_SIZE, a, b, mu, std)
# KS-test does not work great with discontinuties.
# Therefore, we test only the contunuous part of the CDF, and also test
# Therefore, we test only the continuous part of the CDF, and also test
# that the maximum value allowed is not exceeded
maxval = np.max(samples)
samples = samples[samples < np.log10(52)]
Expand All @@ -373,7 +373,7 @@ def test_zsd_dist(self, model, submodel):
b = (np.log10(52)-mu)/std
samples_ref = self.limited_normal(TestLSP.BATCH_SIZE, a, b, mu, std)
# KS-test does not work great with discontinuties.
# Therefore, we test only the contunuous part of the CDF, and also test
# Therefore, we test only the continuous part of the CDF, and also test
# that the maximum value allowed is not exceeded
maxval = np.max(samples)
samples = samples[samples < np.log10(52)]
Expand Down
2 changes: 1 addition & 1 deletion test/unit/fec/test_crc.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ def test_valid_crc(self):
re-encoding always yields a valid CRC.
"""

shapes = [[100, 10], [50, 3, 3], [100, 2, 3, 4, 100]]
shapes = [[100, 10], [50, 3, 3], [100, 2, 3, 4, 100], [1,int(1e6)]]
source = BinarySource()

for pol in VALID_POLS:
Expand Down
4 changes: 2 additions & 2 deletions test/unit/fec/test_fec_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -503,10 +503,10 @@ def test_mod2(self):
s = [10, 20, 30]

# int inputs
x = tf.random.uniform(s, minval=-1000, maxval=1000, dtype=tf.int32)
x = tf.random.uniform(s, minval=-2**30, maxval=2**30, dtype=tf.int32)

y = int_mod_2(x)
y_ref = tf.math.mod(tf.cast(x, tf.float32), 2.)
y_ref = tf.math.mod(tf.cast(x, tf.float64), 2.)
self.assertTrue(np.array_equal(y.numpy(), y_ref.numpy()))

# float inputs
Expand Down
Loading

0 comments on commit eb1d5c4

Please sign in to comment.