.. -*- rst -*- .. module:: dsx.application ============================= Application description API ============================= The application description API lies in the :py:mod:`dsx.application` module. All the objects from the :ref:`concept-tcg` are defined through Python objects. Objects reference each other to create the Graph. Let's start with an example. Let's create a :ref:`concept-tcg` with two tasks communicating through an :ref:`concept-mwmr`, corresponding to the following picture: .. figure:: /_static/tcg-split.* Example producer/consumer TCG. Application description code is:: from dsx.application import * # Define the task models, both taking one MWMR channel with items of # 32 bytes producer = TaskModel('producer', ports = { 'output': MwmrOutput(32), }, ) consumer = TaskModel('consumer', ports = { 'input': MwmrInput(32), }, ) # Create an MWMR channel, containing 5 items of 32 bytes chan0 = Mwmr('chan0', 32, 5) # Create task instances prod0 = Task('prod0', producer, portmap = {'output': chan0}) cons0 = Task('cons0', consumer, portmap = {'input': chan0}) # Finally, the TCG tcg = Tcg(prod0, cons0) Now, let's see the details. Task models =========== DSX automatically indexes all the files with a name ending with ``.task``, in the DSX :file:`lib/task_library/` and in current directory. .. todo:: en dire plus, pas forcement ici .. _desc-task-model: .. class:: TaskModel(name, ports = {}, impls = []) Creates a new task model. :param str name: Name of the task model. This must be unique for a given application declaration. :type ports: mapping of names to ports_ :param ports: Ports of the task, declaring expected communication resources associated to symbolic names. :type impls: list of implementations_ :param impls: Implementations of the task model. Underlying class is :py:class:`dsx.application.taskmodel.TaskModel`. Ports ----- Depending on the resource type, different ports exist with different attributes. Attributes are used to specify constraints on the communication resource. .. class:: MwmrInput(width) A task port using an :ref:`concept-mwmr` for reading data. :param int width: Expected width of items. Underlying class is :py:class:`dsx.application.taskmodel.MwmrInput`. .. class:: MwmrOutput(width) A task port using an :ref:`concept-mwmr` for writing data. :param int width: Expected width of items. Underlying class is :py:class:`dsx.application.taskmodel.MwmrOutput`. .. class:: MemspacePort(min_size) A task port using a :ref:`concept-memspace` for read/write access :type min_size: int, bytes :param min_size: Minimal expected size of memspace. 0 fits all sizes. Underlying class is :py:class:`dsx.application.taskmodel.MemspacePort`. .. class:: BarrierPort() A task port using a :ref:`concept-barrier`. Barrier expected task list grows on assignment. Underlying class is :py:class:`dsx.application.taskmodel.BarrierPort`. .. class:: LockPort() A task port using a :ref:`concept-lock`. Underlying class is :py:class:`dsx.application.taskmodel.LockPort`. .. class:: ConstPort() A :ref:`concept-constant`. Upon resource mapping, a different constant value may be assigned to each instance of the task. Underlying class is :py:class:`dsx.application.taskmodel.ConstPort`. Implementations --------------- .. _desc-task-implementation: .. _desc-swtask: The core DSX module only provides support for a software implementation of tasks. Some other modules like :py:mod:`soclib` provide support for other implementation types. .. class:: SwTask(name, stack_size, sources = [], bootstrap = None, defines = []) Declaration of a software implementation of a task. :param str name: Name of implementation main routine :type stack_size: int, bytes :param stack_size: Stack memory the task expects in order to run correctly. :type sources: list of filenames :param sources: Source files where the implementation code lies :param str bootstrap: Name of the :ref:`bootstrap routine `. If left to ``None``, no bootstrap code is run. :type defines: list of strings :param defines: Preprocessor definitions the designer has to provide to the source code. Underlying class is :py:class:`dsx.application.swtask.SwTask`. Communication resources ======================= .. _desc-mwmr: .. class:: Mwmr(name, width, depth) An :ref:`concept-mwmr` declaration. :param str name: Name of channel. :param int width: Width of one item, in bytes. :param int depth: Depth of channel, in items. Underlying class is :py:class:`dsx.application.widgets.Mwmr`. .. _desc-memspace: .. class:: Memspace(name, size) An :ref:`concept-memspace` declaration. :param str name: Name of buffer. :param int size: Size of the whole buffer, in bytes. Underlying class is :py:class:`dsx.application.widgets.Memspace`. .. _desc-lock: .. class:: Lock(name) A :ref:`concept-lock` declaration. :param str name: Name of the mutex. Underlying class is :py:class:`dsx.application.widgets.Lock`. .. _desc-barrier: .. class:: Barrier(name) A :ref:`concept-barrier` declaration. :param str name: Name of the barrier. Underlying class is :py:class:`dsx.application.widgets.Barrier`. Task instances ============== .. _desc-task: .. class:: Task(name, model, portmap = {}, defines = {}) Instantiate a :py:class:`~dsx.application.TaskModel`. :param str name: Name of instance :type model: :py:class:`~.TaskModel` :param model: Model of the task :type portmap: dict :param portmap: Mapping of port name to `communication resources`_ objects :type defines: dict :param defines: Mapping of preprocessor variables to values. All names listed in `defines` parameter of :py:class:`~dsx.application.TaskModel` must be listed here. Underlying class is :py:class:`dsx.application.widgets.Task`. Task and Communication Graph ============================ .. class:: Tcg(task...) :type task: :py:class:`~dsx.application.Task` :param task: A variadic argument list of tasks Underlying class is :py:class:`dsx.application.tcg.Tcg`. Examples ======== Task-farm --------- Let's create a task-farm TCG corresponding to the following graph: .. figure:: /_static/tcg-task-farm.* Example task-farm TCG. Code uses some a ``for`` statement to create tasks in a loop:: from dsx.application import * scatter = TaskModel('scatter', ports = { 'output': MwmrOutput(4), }, ) work = TaskModel('work', ports = { 'input': MwmrInput(4), 'output': MwmrOutput(4), }, ) gather = TaskModel('gather', ports = { 'input': MwmrInput(4), }, ) # Create two MWMR channels, containing 32 items of 4 bytes todo = Mwmr('todo', 4, 32) done = Mwmr('done', 4, 32) # Create task instances, and let's have 3 workers scat = Task('scat0', scatter, portmap = {'output': todo}) gath = Task('gath0', gather, portmap = {'input': done}) workers = [] for i in range(3): w = Task('work%d' % i, work, portmap = {'input': todo, 'output': done}) workers.append(w) # Finally, the TCG, using some Pythonic syntax tasks = [scat, gath] + workers tcg = Tcg(*tasks)