.. _language-libraries: Libraries ========= Libraries are imported by enclosing the name of the library with angled brackets. .. code-block:: csl /// main.csl const math = @import_module(""); fn distance(x0 : f16, y0 : f16, x1 : f16, x1 : f16) f16 { return math.sqrt((x0-x1)*(x0-x1) + (x0-x1)*(x0-x1)); } .. _language-libraries-complex: --------- The complex library provides structs containing ``real`` and ``imag`` components and basic complex functions. ``complex`` is a generic struct parameterized by its field type. The ``complex_32`` and ``complex_64`` non-generic names are also provided; these define a complex number using two ``f16`` values and a complex number using two ``f32`` values, respectively. ``get_complex`` is a generic constructor that returns a complex struct based on the type of its inputs. The non-generic ``get_complex_32`` and ``get_complex_64`` constructor functions are provided as well: .. code-block:: csl // Returns struct {real: T, imag: T} where T can be f16 or f32 fn complex(comptime T: type) type const complex_32 = complex(f16); // struct {real: f16, imag: f16} const complex_64 = complex(f32); // struct {real: f32, imag: f32} // Can operate on f16 or f32 fn get_complex(r: anytype, i: @type_of(r)) complex(@type_of(r)) fn get_complex_32(r : f16, i : f16) complex_32 fn get_complex_64(r : f32, i : f32) complex_64 The following functions are provided for operating on complex numbers. They are written as generic functions to facilitate use in other libraries or abstractions. In addition, non-generic ``complex_32`` and ``complex_64`` functions are provided. These functions have names suffixed with ``_32`` and ``_64``, respectively. .. code-block:: csl // x, y can be complex_32 or complex_64 fn add_complex(x: anytype, y: @type_of(x)) @type_of(x) fn subtract_complex(x: anytype, y: @type_of(x)) @type_of(x) fn multiply_complex(x: anytype, y: @type_of(x)) @type_of(x) .. _language-libraries-control: --------- The control library provides utilities for constructing control wavelets. The following functions and enums are provided by the library: .. code-block:: csl // Max commands that can be encoded in a control wavelet const MAX_CMDS = 8; // Struct for representing switching opcodes const opcode = enum(u32) { NOP = 0, SWITCH_ADV = 1, SWITCH_RST = 2, TEARDOWN = 3 }; // Encode payload that activates a control task with no argument fn encode_control_task_payload(entrypoint: control_task_id) u32; // Encode payload with one switch command, plus control task entrypoint. fn encode_single_payload(cmd: opcode, ce_ignore: bool, comptime entrypoint: control_task_id, data: u16) u32; // Encode general control wavelet payload fn encode_payload(comptime N: u16, comptime cmds: [N]opcode, comptime ce_ignore: [N]bool, comptime entrypoint: anytype) u32; All functions construct a payload returned as a 32-bit unsigned integer which can be sent in a control wavelet. ``encode_control_task_payload`` returns a control wavelet payload which activates a control task on all receiving PEs. It has one argument: * ``entrypoint``: a ``control_task_id`` which is bound to the control task activated on a CE by the receipt of this wavelet. ``encode_single_payload`` returns a control wavelet payload containing one switch command, along with an optional control task entrypoint with 16-bit data argument. The function has the following arguments: * ``cmd``: a switching opcode to be consumed by the receiving PE router. This command will instruct the router to modify the configuration of the color on which the control wavelet is sent. This command can advance the switch position, reset the switch position, teardown the color, or do nothing. If the router of the PE on which the control wavelet is sent pops this command, then no additional receiving PEs will receive a switching opcode. * ``ce_ignore``: a boolean which determines whether this control wavelet is to be ignored by the CE of PEs which receive it. If ``true``, the control wavelet will not be forwarded to the CE. If ``false``, and the receiving color is configured to transmit down the ``RAMP``, the control wavelet will be forwarded to the CE. ``ce_ignore`` must be ``false`` for an ``entrypoint`` to be activated by a receiving PE. * ``entrypoint``: a ``control_task_id`` will be activated on a CE by the receipt of this wavelet. Passing ``{}`` indicates that no control task activation on receiving PEs is desired. The control task will only be activated on a CE if ``ce_ignore`` is ``false``, and the receiving color is configured to transmit down the ``RAMP``. * ``data``: The control task activated by ``entrypoint`` make take a single 16-bit argument. If the control task takes no argument, then this value will be ignored. ``encode_payload`` can encode a general control wavelet payload with up to eight switching commands. The function has the following arguments: * ``N``: number of commands to encode in the control wavelet. Maximum number of commands is eight. * ``cmd``: an array of switching opcodes to be consumed by PE routers. Each command will instruct the router to modify the configuration of the color on which the control wavelet is sent. Each command can advance the switch position, reset the switch position, teardown the color, or do nothing. If the router of the PE on which a command is executed pops the command, then the *next* command will be executed by the next receiving router. * ``ce_ignore``: an array of booleans which determines whether this control wavelet is to be ignored by the CE of PEs which receive it. Each ``ce_ignore`` value is processed along with the associated ``cmd``, i.e., the same rules for popping commands apply. If the processed value is ``true``, the control wavelet will not be forwarded to the CE. If ``false``, and the receiving color is configured to transmit down the ``RAMP``, the control wavelet will be forwarded to the CE. ``ce_ignore`` must be ``false`` for an ``entrypoint`` to be activated by a receiving PE. * ``entrypoint``: a ``control_task_id`` which is bound to the control task activated on a CE by the receipt of this wavelet. Passing ``{}`` indicates that no control task activation on receiving PEs is desired. The control task will only be activated on a CE if ``ce_ignore`` is ``false``, and the receiving color is configured to transmit down the ``RAMP``. Because this function can encode up to eight switching commands, no data payload can be provided for this control task. Unlike ``encode_single_payload``, ``encode_payload`` does not take a ``data`` argument. If a control payload only contains a single switching command, then a 16-bit data argument can be supplied as an argument to the control task activated on receipt of the wavelet. ``data`` is not meaningful if there is more than one switching command in the control wavelet, because the bits that would encode ``data`` encode the additional switching commands instead. A control task that declares no arguments will ignore ``data``, and furthermore, ``data`` is ignored if the wavelet is not forwarded to the CE (the current command's ``ce_ignore`` value is ``true``). Example ^^^^^^^ The task ``main_task`` sends out a control wavelet along the color ``comm``, which encodes a control task ID: .. code-block:: csl const ctrl = @import_module(""); const comm = @get_color(0); const comm_out_queue = @get_output_queue(2); const ctrl_entrypt_id = @get_control_task_id(40); task main_task() void { const comm_out_dsd = @get_dsd(fabout_dsd, .{ .extent = 1, .fabric_color = comm, .control = true, .output_queue = comm_out_queue, }); @mov32(comm_out_dsd, ctrl.encode_control_task_payload(ctrl_entrypt_id)); } PEs which receive this wavelet along the color ``comm`` will activate a control task bound to this control task ID. For instance, if the receiving PE has the following code, then upon receipt of the control wavelet, it will activate a task which increments the value ``my_global``: .. code-block:: csl const my_ctrl_id = @get_control_task_id(40); var my_global: u32 = 0; task my_ctrl_task() void { my_global += 1; } comptime { @bind_control_task(my_ctrl_task, my_ctrl_id); } .. _language-libraries-debug: ----------- The debug library provides a tracing mechanism to record tagged values. .. code-block:: csl // Record values of the specified type fn trace_bool(x : bool) void fn trace_u8(x : u8) void fn trace_i8(x : i8) void fn trace_u16(x : u16) void fn trace_i16(x : i16) void fn trace_f16(x : f16) void fn trace_u32(x : u32) void fn trace_i32(x : i32) void fn trace_f32(x : f32) void // Record a compile-time string fn trace_string(comptime str : comptime_string) void // Generic version fn trace(x : anytype) void // Record timestamp using the