.. _language-task-ids: Task Identifiers and Task Execution =================================== The term "task identifier" or "task ID" is used to refer to a numerical value that can be associated with a task. A task ID is associated with a task through a process called "binding" that is carried out by special builtins depending on the type of task. There exist three types of tasks, each with an associated task ID handle type. These three types of tasks are: * Data Tasks * Local Tasks * Control Tasks The following three sections explain the semantics of each task type, how they can be bound to task IDs, and how they can be scheduled for execution. .. _language-data-tasks: Data Tasks ----------------- Data tasks are wavelet-triggered tasks (WTTs) that are associated with a ``data_task_id``, which is constructed from a routable identifier, known as a ``color`` (see :ref:`language-routable-identifiers`) using ``@get_data_task_id`` (see :ref:`language-builtins-get-data-task-id`), and can be bound to a data task using ``@bind_data_task`` (see :ref:`language-builtins-bind-data-task`). .. _language-routable-identifiers: Routable Identifiers (Colors) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ For ``wse1`` and ``wse2``, the IDs 0 to 23 (inclusive) are recognized by the hardware as virtual communication channels for passing wavelets between PEs. These IDs are sometimes referred to as the routable "colors" and can be constructed using ``@get_color`` (see :ref:`language-builtins-get-color`). Note that these IDs are the only ones that can be used with the ``@set_color_config`` and ``@set_local_color_config`` builtins (see :ref:`language-builtins-set-color-config`). Execution Semantics ^^^^^^^^^^^^^^^^^^^ A data task can be scheduled for execution if and only if it is bound to a data task ID that is activated and unblocked. A data task is activated by receiving a wavelet along a given color. That color (or routable identifier) is the color that was used to create the ``data_task_id`` bound to the respective data task. A data task must have at least one input argument representing the wavelet's payload. If it has more than one input argument then the wavelet's payload is equally split among those input arguments. All data task IDs that are bound to a data task are initially unblocked. They can be explicitly blocked using ``@block`` (see :ref:`language-builtins-block`) during the evaluation of a top-level comptime block or at runtime. Once blocked, a data task ID can be unblocked explicitly using ``@unblock`` (see :ref:`language-builtins-unblock`) or upon completion of asynchronous fabric DSD operations (see :ref:`language-dsds-async-completion`). .. _language-local-tasks: Local Tasks ----------- Local tasks, or self-activated tasks, are associated with a ``local_task_id``, which is constructed from an activatable identifier (see :ref:`language-activatable-identifiers`) using ``@get_local_task_id`` (see :ref:`language-builtins-get-local-task-id`) and then bound to a local task using ``@bind_local_task`` (see :ref:`language-builtins-bind-local-task`). .. _language-activatable-identifiers: Activatable Identifiers ^^^^^^^^^^^^^^^^^^^^^^^ On ``wse1`` and ``wse2``, the IDs 0 to 30 (inclusive) can be used to construct ``local_task_id`` values that can then be used to activate local tasks, which is why they are referred to as "activatable" identifiers. IDs 29 and 30 should generally be avoided in programs as they are used for system tasks. ID 29 is bound to a teardown task that runs when the tile is in teardown mode and ID 30 is bound to a timer task. Execution Semantics ^^^^^^^^^^^^^^^^^^^ A local task can be scheduled for execution if and only if is is bound to a local task ID that is activated and unblocked. Local tasks accept no input arguments and can be activated explicitly using the ``@activate`` builtin (see :ref:`language-builtins-activate`) or upon completion of an asynchronous fabric (see :ref:`language-dsds-async-completion`) or FIFO (see :ref:`language-dsds-fifo-activate-push-pop`) DSD operation. All local task IDs that are bound to a local task are initially unblocked. They can be explicitly blocked using ``@block`` (see :ref:`language-builtins-block`) during the evaluation of a top-level comptime block or at runtime. Once blocked, a local task ID can be unblocked explicitly using ``@unblock`` (see :ref:`language-builtins-unblock`) or upon completion of asynchronous fabric DSD operations (see :ref:`language-dsds-async-completion`). .. _language-control-tasks: Control Tasks ------------- Control tasks are control wavelet-triggered tasks that are associated with a ``control_task_id``, which is constructed from a control identifier (see :ref:`language-control-identifiers`) using ``@get_control_task_id`` (see :ref:`language-builtins-get-control-task-id`) and then bound to a control task using ``@bind_control_task`` (see :ref:`language-builtins-bind-control-task`). .. _language-control-identifiers: Control Identifiers ^^^^^^^^^^^^^^^^^^^ On ``wse1`` and ``wse2``, the IDs 0 to 63 (inclusive) can be used to create ``control_task_id`` values. Execution Semantics ^^^^^^^^^^^^^^^^^^^ A control task bound to a ``control_task_id`` value ``CID`` is scheduled for execution if and only if the following two conditions are met: * A control wavelet carrying the ``CID`` value in its payload is received. * The communication channel that is used to receive the aforementioned control wavelet is unblocked. The second condition needs to be explicitly satisfied using ``@unblock`` (see :ref:`language-builtins-unblock`) during the evaluation of a top-level comptime block or at runtime. The input to ``@unblock`` should be the routable identifier (value of type ``color``) associated with the control wavelet's input communication channel. Note that if the same communication channel is bound to a data task as well, then this unblocking is not necessary. The payload of a control wavelet consists of the ``control_task_id`` value and a data section. Both can be passed as input arguments to the control task.