CVBpy 15.0
All Classes Namespaces Functions Variables Enumerations Enumerator Properties Modules Pages
cvb/Rdma
1# @brief Example for RDMA for GEV acquisition.
2
3# This enables high data rates with without CPU load
4
5import cvb
6
7from timeit import default_timer as timer
8
9TIMEOUT_MS = 3000
10NUM_ELEMENTS_TO_ACQUIRE = 5000 # number of elements to be acquired
11FEEDBACK_INTERVAL = NUM_ELEMENTS_TO_ACQUIRE / 10 # print progress
12NUM_FLOW_SETS = 10 # number flow sets to announce (usually buffers)
13
14
15# RDMA transfer is part of the socket driver (GevSD) so the filter driver (GevFD) must be ignored.
16devices = cvb.DeviceFactory.discover_from_root(cvb.DiscoverFlags.IgnoreVins | cvb.DiscoverFlags.IgnoreGevFD)
17
18# The following will only work if there is a RDMA capable device connected to an RDMA capable
19# network interface. Usually also a driver that allows user space access is required. See also
20# * Windows: Network Direct Service Provider Interface (NDSPI)
21# * Linux: librdmacm.so and libibverbs.so
22item = devices[0]
23# RDMA must be switched on explicitly otherwise the classic GVSP protocol will be used.
24# This is just a request and may fail silently if RDMA is not supported.
25# To verify that RDMA is supported and switched on you can check
26# the "GevDataStreamingMode" in the TLDevice (cvb.NodeMapID.TLDevice) node map and validate that it is
27# set to "RDMA". The "RDMA" entry is only available if the device is RDMA capable.
28item.set_parameter("UseRdma", "1")
29
30with cvb.DeviceFactory.open(item.access_token, cvb.AcquisitionStack.GenTL) as device:
31 node_map = device.node_maps[cvb.NodeMapID.Device]
32 payload_size = node_map.node("PayloadSize").value
33 # Note that RDMA requires GenDC containers as payload.
34 # The container will automatically be mapped to a composite for
35 # further processing.
36 stream = device.stream(cvb.CompositeStream)
37
38 # The default and minimal number of flow sets is three but it is usually
39 # advisable to increase the number so that about one second can be buffered.
40 stream.register_managed_flow_set_pool(NUM_FLOW_SETS)
41
42 stream.start()
43 start = timer()
44 for i in range(NUM_ELEMENTS_TO_ACQUIRE):
45 composite, status, _ = stream.wait_for(TIMEOUT_MS)
46 with composite:
47 part = composite[0]
48 # try to get the composite's first element as an image
49 if i and i % FEEDBACK_INTERVAL == 0:
50 if isinstance(part, cvb.Image):
51 img: cvb.Image = part
52 print(f"acquired images: {i} | size: {img.width} x {img.height}")
53 else:
54 print(f"acquired composites: {i} which is not an image")
55
56 end = timer()
57 duration = end - start
58 # For RDMA streaming the data rate is usually interesting...
59 data_rate = payload_size * NUM_ELEMENTS_TO_ACQUIRE / (1000000 * duration)
60 stream.try_abort()
61
62 print(f"\nacquired {NUM_ELEMENTS_TO_ACQUIRE} buffers in {(duration * 1000):.2f} ms ( {data_rate:.2f} MB/s )")
63
64
65
The composite stream class.
Definition: __init__.py:841
Union[cvb.GenICamDevice, cvb.VinDevice, cvb.EmuDevice, cvb.VideoDevice, cvb.NonStreamingDevice] open(str provider, int acquisition_stack=cvb.AcquisitionStack.PreferVin)
Opens a device with the given provider and acquisition stack.
Definition: __init__.py:1629
List[cvb.DiscoveryInformation] discover_from_root(int flags=cvb.DiscoverFlags.FindAll, int time_span=300)
Discovers available devices / nodes depending on the given flags.
Definition: __init__.py:1609
The Common Vision Blox image.
Definition: __init__.py:2097