-
Notifications
You must be signed in to change notification settings - Fork 11
Pythonsupport
Almost every aspect of the GRAS C++ API has Python bindings. So the GRAS API can be used as effectivly in Python as it is in C++. Further, IP written in either language can easily interoperate with the other; allowing users to easily cross language boundaries.
The best demonstration of this Python support is to see the coding guide. For every feature is a C++ example and a matching Python example: https://github.com/guruofquality/gras/wiki/Codeguide
The goal is to allow the user to write blocks in 100% python.
The typical GNU Radio coding model is
- write signal processing in C++
- connect the flow graph in python
This is smart. Python is not fast, but efficient to code. C++ is faster, but more effort is required. But why not code the signal processing blocks themselves in python?
The benefits:
- Quickly develop and debug your algorithm, before implementing it in C++.
- If the processing can be handled in python, why not leave it in python?
- Do work with external libraries with python bindings, like Numpy.
So, writing signal processing in python is a time saver at the very least, and doing so isn't necessarily going to be a performance issue.
Using this feature, users can get access to all available API functionality in a typical C++ block. Users can:
- Write a signal processing work() function that will be called by the scheduler
- Access to standard block methods like configuration, item counts, produce, consume...
- Access to stream tags, msgs, properties
The block input and output signatures are specified as numpy dtypes. Numpy dtypes can represent any array structure of arbitrary complexity; and because of python's duck typing, the work arrays come to the user shaped/formatted by this signature. No typecasting, authoring a work() routine is incredibly strait-forward.
import gras class Add2X(gras.Block): def __init__(self, sig): gras.Block.__init__(self, name = "Add2X", in_sig = [sig, sig], out_sig = [sig], ) def work(self, ins, outs): nitems = min(*map(len, (ins[0], ins[1], outs[0]))) outs[0][:nitems] = ins[0][:nitems] + ins[1][:nitems] self.consume(0, nitems) self.consume(1, nitems) self.produce(0, nitems)
See how simple it can be with these demo blocks used for testing purposes: https://github.com/guruofquality/gras/blob/master/tests/demo_blocks.py