Using submatrices in primitives

Submatrices are not currently useful in general-purpose dataflow primitives. Rather, they were developed to provide an efficient means of referencing portions of a single larger matrix in the multi-dimensional synchronous dataflow (MDSDF) domain.

A short summary: unlike other domains, the MDSDF kernel does not transfer particles through FIFO buffers. Instead, each geodesic keeps a single copy of a ”parent” matrix, that represents the ”current” two-dimensional datablock. Each time a primitive fires, it obtains a submatrix that references this parent matrix with the getOutput() function of the MDSDF input port class. For example, a primitive might contain:

FloatSubMatrix* data = (FloatSubMatrix*)(input.getInput());

Note that this is not really getting a matrix, but a submatrix that references a region of the current data matrix. The size of the submatrix has been set by the primitive in its initialization code by calling the setMDSDFParams() function of the port. To write data to the output matrix, the primitive gets a submatrix which references a region of the current output matrix and writes to it with a matrix operator. For example,

FloatSubMatrix* result = (FloatSubMatrix*)(output.getOutput());
result = -data;

Because the submatrices are only references to the current matrix on each arc, they must be deleted after use:

delete &data;
delete &result;

Here is a simplified example of a complete  MDSDF primitive:

defprimitive
{
  name        { SimpleAdd }
  domain      { MDSDF }
  desc
  {
    Does a matrix addition of two input matrices A and B to produce matrix C.
    All matrices must have the same dimensions.
  }

  input
  {
    name { A_Input }
    type { float_matrix_env }
  }

  input
  {
    name { B_Input }
    type { float_matrix_env }
  }

  output
  {
    name { Output }
    type { float_matrix_env }
  }

  defparameter
  {
    name        { numRows }
    type        { int }
    default     { "2" }
    desc        { "The number of rows in the input/output matricies." }
  }

  defparameter
  {
    name        { numCols }
    type        { int }
    default     { "2" }
    desc        { "The number of columns in the input/output matricies." }
  }

  location { MDSDF library }

  ccinclude { "kernel/SubMatrix.h" }

  setup
  {
    A_Input.setMDSDFParams(int(numRows), int(numCols));
    B_Input.setMDSDFParams(int(numRows), int(numCols));
    Output.setMDSDFParams(int(numRows), int(numCols));
  }

  go
  {
    // get a SubMatrix from the buffer
    FloatSubMatrix& tASubmatrix = *(FloatSubMatrix*)(A_Input.getInput());
    FloatSubMatrix& tBSubmatrix = *(FloatSubMatrix*)(B_Input.getInput());
    FloatSubMatrix& tResult = *(FloatSubMatrix*)(Output.getOutput());

    // compute product, putting tResult into output
    tResult = tASubmatrix + tBSubmatrix;

    delete &tASubmatrix;
    delete &tBSubmatrix;
    delete &tResult;
  }
}