Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python and RFNOC: Atomic item size with FFT blocks #634

Closed
LorenzoMinutolo opened this issue Oct 4, 2022 · 4 comments
Closed

Python and RFNOC: Atomic item size with FFT blocks #634

LorenzoMinutolo opened this issue Oct 4, 2022 · 4 comments

Comments

@LorenzoMinutolo
Copy link

LorenzoMinutolo commented Oct 4, 2022

Issue Description

After adding the FFT block to a RFNOC design and successfully compiling the firmware, I cannot commit the graph due to an error generated on graph.commit() in my Python script. Specifically the error is:
RuntimeError: ValueError: samples per package must not be smaller than atomic item size
Which should stem from a mismatch in the samples per packet setup. I do take care of this aspect by setting the spp at the beginning and configuring each block with the same value.

Setup Details

[INFO] [UHD] linux; GNU C++ version 11.2.0; Boost_107400; UHD_4.2.0.1-0-g321295fb, Python 3.10
The USRP I am using is a x300 with a WBX daughterboard connected via a single 10Gbe. The NIC is an Intel X710.

Expected Behavior

The script should commit the graph without issues. Or at least tell me which block is causing the problem.

Actual Behaviour

RuntimeError: ValueError: samples per package must not be smaller than atomic item size

Steps to reproduce the problem

Compile a firmware with the FFT block. The usrp_probe returns:

|   |   * 0/SEP#6:0==>0/FFT#0:0
|   |   * 0/FFT#0:0==>0/SEP#6:0
|   |   * 0/SEP#0:0==>0/DUC#0:0
|   |   * 0/DUC#0:0==>0/Radio#0:0
|   |   * 0/Radio#0:0==>0/DDC#0:0
|   |   * 0/DDC#0:0==>0/SEP#0:0
|   |   * 0/Radio#0:1==>0/DDC#0:1
|   |   * 0/DDC#0:1==>0/SEP#1:0
|   |   * 0/SEP#2:0==>0/DUC#1:0
|   |   * 0/DUC#1:0==>0/Radio#1:0
|   |   * 0/Radio#1:0==>0/DDC#1:0
|   |   * 0/DDC#1:0==>0/SEP#2:0
|   |   * 0/Radio#1:1==>0/DDC#1:1
|   |   * 0/DDC#1:1==>0/SEP#3:0
|   |   * 0/SEP#4:0==>0/Replay#0:0
|   |   * 0/Replay#0:0==>0/SEP#4:0
|   |   * 0/SEP#5:0==>0/Replay#0:1
|   |   * 0/Replay#0:1==>0/SEP#5:0

Run the following code:

import numpy as np
import uhd
args = "addr=<address of the USRP>"
graph = uhd.rfnoc.RfnocGraph(args)

radio_ID_A = uhd.rfnoc.BlockID(0, "Radio", 0);
radio_block_A = graph.get_block(radio_ID_A);
radio_ctrl_A = uhd.rfnoc.RadioControl(radio_block_A)

set_freq = int(300e6)
spp = 512
radio_ctrl_A.set_tx_frequency(set_freq, 0)
tx_freq = radio_ctrl_A.get_tx_frequency(0)
radio_ctrl_A.set_rx_frequency(set_freq, 0)
rx_freq = radio_ctrl_A.get_rx_frequency(0)

radio_ctrl_A.set_properties(f'spp={spp}', 0)
radio_ctrl_A.set_rx_antenna('RX2',0)
radio_ctrl_A.set_rate(int(200e6))

DDC_ID = graph.find_blocks("DDC")[0]
DDC_block = graph.get_block(DDC_ID)
DDC_control = uhd.rfnoc.DdcBlockControl(DDC_block)
DDC_control.set_input_rate(int(200e6), 0)
DDC_control.set_output_rate(int(5e6), 0)

FFT_ID = graph.find_blocks("FFT")[0]
FFT_block = graph.get_block(FFT_ID)
FFT_control = uhd.rfnoc.FftBlockControl(FFT_block)
FFT_control.set_magnitude(uhd.libpyuhd.rfnoc.fft_magnitude.COMPLEX)
FFT_control.set_direction(uhd.libpyuhd.rfnoc.fft_direction.FORWARD)
FFT_control.set_shift_config(uhd.libpyuhd.rfnoc.fft_shift.NORMAL)
FFT_control.set_length(int(spp))

stream_args = uhd.usrp.StreamArgs('fc32','sc16')
stream_args.args = uhd.types.DeviceAddr(f'spp={spp}')
rx_stream = graph.create_rx_streamer(1, stream_args)

graph.connect(
    radio_ID_A,0,
    DDC_ID,0,
    False
)
graph.connect(
    DDC_ID,0,
    FFT_ID,0,
    False
)
graph.connect(
    FFT_ID,0,
    rx_stream,0
)
graph.commit()
@LorenzoMinutolo
Copy link
Author

LorenzoMinutolo commented Oct 4, 2022

Interestingly this version of the code commits the graph successfully.

args = "addr=<address of the USRP>"
spp = 128
graph = uhd.rfnoc.RfnocGraph(args)
radio_ID_A = uhd.rfnoc.BlockID(0, "Radio", 0)
FFT_ID = graph.find_blocks("FFT")[0]

DDC_ID = graph.find_blocks("DDC")[0]
DDC_block = graph.get_block(DDC_ID)
DDC_control = uhd.rfnoc.DdcBlockControl(DDC_block)
DDC_control.set_input_rate(int(200e6), 0)
DDC_control.set_output_rate(int(5e6), 0)

stream_args = uhd.usrp.StreamArgs('fc32','sc16')
rx_stream = graph.create_rx_streamer(1, stream_args)

uhd.rfnoc.connect_through_blocks(graph,radio_ID_A,0,DDC_ID,0)

FFT_block = graph.get_block(FFT_ID)
FFT_control = uhd.rfnoc.FftBlockControl(FFT_block)
FFT_control.set_magnitude(uhd.libpyuhd.rfnoc.fft_magnitude.COMPLEX)
FFT_control.set_direction(uhd.libpyuhd.rfnoc.fft_direction.FORWARD)
FFT_control.set_shift_config(uhd.libpyuhd.rfnoc.fft_shift.NORMAL)
FFT_control.set_length(int(spp))

radio_block_A = graph.get_block(radio_ID_A)
radio_ctrl_A = uhd.rfnoc.RadioControl(radio_block_A)
radio_ctrl_A.set_properties(f'spp={spp}', 0)
radio_ctrl_A.set_rx_antenna('RX2',0)

graph.connect(DDC_ID, 0, FFT_ID, 0,False)
graph.connect(FFT_ID, 0, rx_stream, 0,False)

graph.commit()

The main differences are:

  1. the use of the function connect_through_blocks instead of just connect for connecting the radio block. What is the difference between these functions?
  2. I am not setting the spp for the streamer. Whenever I do that, the original error is thrown.

Also: does the order in which I declare/connect blocks matter?

I just noticed that changing the spp above 256 makes the script throw the original error. Does this rings a bell to anyone?

Thanks,
Lorenzo

@mbr0wn
Copy link
Contributor

mbr0wn commented Nov 8, 2022

Hey @LorenzoMinutolo, we are aware of this issue. In fact, we had already fixed it in f163af4, but we had to revert it in 036f7a3 because it broke some streaming tests. It's on our backlog to put the fix in again.

@cstandy
Copy link

cstandy commented Sep 16, 2024

Hi @mbr0wn, we are facing the same issue with AIS and SPP. I am using the C++-based UHD RFNoC library on UHD 4.5. This issue forces my SPP to be 4x my FFT size since each sample is 4 bytes in sc16. I use USRP X310, MTU 9000, and a 10G link. The largest FFT size I can do is also 256, where the desired values are 1024/2048/4096. Do you have any updates on this issue? Thank you.

@mbr0wn
Copy link
Contributor

mbr0wn commented Nov 12, 2024

This issue was resolved with e89efc3. It is curently available on master branch and will be in the next release of UHD.

@mbr0wn mbr0wn closed this as completed Nov 12, 2024
@EttusResearch EttusResearch locked as resolved and limited conversation to collaborators Nov 12, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants