Personal tools
User menu

Iterators

Jump to: navigation, search

Iterators allow the replication of an individual process inside a process network. This page describes the principle of iterators based on the process network specification even though the same feature is available for the architecture and mapping specification, as well.

Example

The iterator concept extends both the process network specification and the specification of the functionality of a process. In the following, the output_consumer process is replicated N times. First, the XML specification of the process is illustrated:

  1. <variable value="4" name="N"/>
  2.  
  3. <process name="consumer">
  4.   <iterator variable="row" range="N">
  5.     <iterator variable="col" range="N">
  6.       <port type="input" name="matrixC">
  7.         <append function="row"/>
  8.         <append function="col"/>
  9.       </port>
  10.     </iterator>
  11.   </iterator>
  12.   <source type="c" location="consumer.c"/>
  13. </process>

Next, the fire function of the process is illustrated:

  1. #define PORT_MATRIXC "matrixC"
  2.  
  3. int consumer_fire(DALProcess *p) {
  4.   double matrixC_value;
  5.   int row, col;
  6.   CREATEPORTVAR(port);
  7.  
  8.   for (row = 0; row < NUMBER_OF_ROWS_COLS; row++) {
  9.     for (col = 0; col < NUMBER_OF_ROWS_COLS; col++) {
  10.       CREATEPORT(port, PORT_MATRIXC, 2,
  11.               row, NUMBER_OF_ROWS_COLS,
  12.               col, NUMBER_OF_ROWS_COLS);
  13.       DAL_read((void*)port, &matrixC_value, sizeof(double), p);
  14.     }
  15.   }
  16.   return 0;
  17. }

In the following, the above illustrated extension is detailed.

XML Specification

The following elements can additionally be used to specify a process network in XML.

Element variable

variable elements must occur as the first children of the root element. The schema definition does not allow any other location. The variable element has two attributes: name and value. The name attribute contains a string that can be referenced from within the append element or the iterator element. During the flattening process, the pre-processor replaces the name placeholder with the corresponding value, an integer value stored in the attribute value.

<variable name="N" value="4"/>

While flattening, all occurrences of N in iterator or append elements will be replaced by the integer 4.

Element function

This element must occur right after the variable elements as a child of the root element. It cannot occur anywhere else in the XML file. The function element has one attribute name which contains a string denoting the name of the function. If present, the element must contain a complete Java function as content. See below for an example of a function element:

<function name="myFunction">
  int myFunction(int input1, int input2) {
    return (int) Math.pow((double) input1, (double) input2);
  }
</function>

The function must return an int and may accept an arbitrary number of int parameters. The functions can be used to calculate more complicated function attributes for the append elements:

<append function="myFunction(in1, in2)"/>

Element iterator

The iterator element can be used to replicate process, sw_channel, port, or connection elements several times. To do so, the variable attribute has to be set and in the range attribute the upper limit for the iterator has to be set. If the range is N, for instance, the nested elements inside the iterator will be replicated N times. To actually create different instance of the iterated elements, the append element is used. When an iterator is flattened, the variable given in the variable attribute takes values from 0 to N - 1.

Below is an example that shows the usage of an iterator:

  1. <iterator variable="i" range="N">
  2.   <process name="square" basename="generator" id="1" type="local">
  3.     <append function="i"/>
  4.     ...
  5.   </process>
  6.  
  7.   <sw_channel type="fifo" size="10" name="C2" basename="C2" id="1">
  8.     <append function="i"/>
  9.     ...
  10.   </sw_channel>
  11. </iterator>

Iterators may be nested to generate multi-dimensional arrays of iterated elements.

Element append

This element may be used within several elements to modify the element's name. The append element has one attribute function which is a string. The string must have one out of four formats and evaluate to an integer value:

  • iterator variables, e.g., i, j, k
  • pure integers, e.g., 1, 2, 3
  • variables, e.g., N
  • functions, e.g., myFunction(2, 4)

The function attribute may contain also simple arithmetical functions, such as function="2 * i" based on the format specified above.

When an iterator is used to create an instance of process, sw_channel or port, only the first form is permitted in an append element within this iterator, as shown in the example below. All four forms are allowed when the append element appears as a child in a connection element, or when it appears as a child of process, sw_channel, or port within a connection element.

The names of process, channel, port, and connection elements can be modified with more than one append element. The name of the iterated elements will be built according to the sequence of the append elements:

  1. <iterator variable="i" range="2">
  2.   <interator variable="j" range="3">
  3.     <process name="square" basename="square" id="1">
  4.       <append function="i"/>
  5.       <append function="j"/>
  6.     </process>
  7.   </iterator>
  8. </iterator>

will be expanded during the flattening process to square_0_0, square_0_1, square_0_2, square_1_0, square_1_1, and square_1_2.

Process Specification

Iterated processes have a similar behavior and, therefore, possess the same source code file. Nevertheless, two additional features are added. The first one allows to read from or write to a port that is not yet known when the process is specified. This particularly applies to the child and parent processes of a iterated process. The second features allows to obtain the current position of a process inside all replicated processes.

Iterated Ports

The source processes of a replicated process have to write to a FIFO channel that is not known when the application is specified and similarly, the sink processes of a replicated process have to read from a FIFO channel that is not known when the application is specified. Therefore, the following function primitives are used in DAL to iterate over a set of ports.

  • For each iterated port which is accessed within a process, a port macro must be declared in the header file of a process. This declaration takes the same form as for an ordinary port, but the name of the port is now the basename of the iterated port as specified in the process network XML file:
    #define PORT_Y portbasename
  • In the C file, use the CREATEPORTVAR(buffer) macro (which has a tool-chain specific implementation) to create a buffer where the reference to an iterated port can be saved. The variable name can be chosen arbitrarily (as long as it does not conflict with any other variable):
    CREATEPORTVAR(port);
  • In the C file, use the CREATEPORT() macro (which also has a tool-chain specific implementation) to create a reference to an iterated port and save it in the previously generated buffer. The signature of the CREATEPORT() macro is as follows: CREATEPORT(buffer, basename, numberOfIteratorDimensions, index0, range0, [index1, range1, [index2, range2, [index3, range3]]]):
    • buffer is the buffer created by CREATEPORTVAR(buffer)
    • basename is the basename of the port. Similar to the rule for the ordinary port, only the defined macro may be used.
    • numberOfIteratorDimensions is the number of dimensions of this port, that is, the number of nested iterator parent elements.
    • index0 gives the index of the port in the first dimension. The same applies for index1, index2, index3 for the other (up to four) dimensions.
    • range0 is the range of the iterator in the first dimension. The same applies for range1, range2, range3 for the other (up to four) dimensions.

    An example is shown below:

    CREATEPORT(port, PORT_Y, 2,
               row, NUMBER_OF_ROWS, col, NUMBER_OF_COLS);
  • Use the variable specified in CREATEPORT() within a call to a communication primitive:
    DAL_read((void*)port, &buffer, 4, p);

Retrieving the Index of a Process

Sometimes, it is desirable that the replicated processes behave slightly different depending on their position in the process network. The macro GETINDEX(dim) can be used to retrieve the iteration index of a process in the dim-th dimension.

!!! Dieses Dokument stammt aus dem ETH Web-Archiv und wird nicht mehr gepflegt !!!
!!! This document is stored in the ETH Web archive and is no longer maintained !!!