Common Vision Blox 15.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Friends Modules Pages
Image Manager/CVBpy/Rdma

This example program is located in your CVB installation under %CVB%Tutorial/Image Manager/CVBpy/Rdma.

rdma.py:

# @brief Example for RDMA for GEV acquisition.
# This enables high data rates with without CPU load
import cvb
from timeit import default_timer as timer
TIMEOUT_MS = 3000
NUM_ELEMENTS_TO_ACQUIRE = 5000 # number of elements to be acquired
FEEDBACK_INTERVAL = NUM_ELEMENTS_TO_ACQUIRE / 10 # print progress
NUM_FLOW_SETS = 10 # number flow sets to announce (usually buffers)
# RDMA transfer is part of the socket driver (GevSD) so the filter driver (GevFD) must be ignored.
devices = cvb.DeviceFactory.discover_from_root(cvb.DiscoverFlags.IgnoreVins | cvb.DiscoverFlags.IgnoreGevFD)
# The following will only work if there is a RDMA capable device connected to an RDMA capable
# network interface. Usually also a driver that allows user space access is required. See also
# * Windows: Network Direct Service Provider Interface (NDSPI)
# * Linux: librdmacm.so and libibverbs.so
item = devices[0]
# RDMA must be switched on explicitly otherwise the classic GVSP protocol will be used.
# This is just a request and may fail silently if RDMA is not supported.
# To verify that RDMA is supported and switched on you can check
# the "GevDataStreamingMode" in the TLDevice (cvb.NodeMapID.TLDevice) node map and validate that it is
# set to "RDMA". The "RDMA" entry is only available if the device is RDMA capable.
item.set_parameter("UseRdma", "1")
with cvb.DeviceFactory.open(item.access_token, cvb.AcquisitionStack.GenTL) as device:
node_map = device.node_maps[cvb.NodeMapID.Device]
payload_size = node_map.node("PayloadSize").value
# Note that RDMA requires GenDC containers as payload.
# The container will automatically be mapped to a composite for
# further processing.
stream = device.stream(cvb.CompositeStream)
# The default and minimal number of flow sets is three but it is usually
# advisable to increase the number so that about one second can be buffered.
stream.register_managed_flow_set_pool(NUM_FLOW_SETS)
stream.start()
start = timer()
for i in range(NUM_ELEMENTS_TO_ACQUIRE):
composite, status, _ = stream.wait_for(TIMEOUT_MS)
with composite:
part = composite[0]
# try to get the composite's first element as an image
if i and i % FEEDBACK_INTERVAL == 0:
if isinstance(part, cvb.Image):
img: cvb.Image = part
print(f"acquired images: {i} | size: {img.width} x {img.height}")
else:
print(f"acquired composites: {i} which is not an image")
end = timer()
duration = end - start
# For RDMA streaming the data rate is usually interesting...
data_rate = payload_size * NUM_ELEMENTS_TO_ACQUIRE / (1000000 * duration)
stream.try_abort()
print(f"\nacquired {NUM_ELEMENTS_TO_ACQUIRE} buffers in {(duration * 1000):.2f} ms ( {data_rate:.2f} MB/s )")
Union[cvb.GenICamDevice, cvb.VinDevice, cvb.EmuDevice, cvb.VideoDevice, cvb.NonStreamingDevice] open(str provider, int acquisition_stack=cvb.AcquisitionStack.PreferVin)
List[cvb.DiscoveryInformation] discover_from_root(int flags=cvb.DiscoverFlags.FindAll, int time_span=300)