A 2D rectangular grid implementation of the Space behaviour.
This is the default space for systolic arrays. It provides the same
coordinate semantics as ExSystolic.Grid but through the Space
behaviour interface, making it interchangeable with future space
implementations (graph, hierarchical, etc.).
Coordinate system
{row, col}with row increasing southward, col increasing eastward.- Indices start at 0.
Port layout
Every PE in a Grid2D has four directional ports: :north, :south,
:east, :west. Boundary PEs have nil neighbours on their
outward-facing ports.
Link directions
Grid2D supports two connect/2 directions:
:west_to_east-- links flow eastward: boundary links enter column 0 via the:westport, internal links connect column c (:east) to column c+1 (:west).:north_to_south-- links flow southward: boundary links enter row 0 via the:northport, internal links connect row r (:south) to row r+1 (:north).
Relationship to ExSystolic.Grid
Grid2D and Grid share the same coordinate semantics. Grid
remains available for direct use; Grid2D adds the Space behaviour
layer that enables pluggable topology.
Summary
Functions
Returns all valid coordinates in the grid, row-major order.
Returns boundary and internal links for a Grid2D direction.
Returns the neighbours of a coordinate within a grid of the given size.
Validates and normalizes a coordinate.
Returns the port names for a Grid2D coordinate.
Types
@type coord() :: {non_neg_integer(), non_neg_integer()}
Functions
Returns all valid coordinates in the grid, row-major order.
Examples
iex> ExSystolic.Space.Grid2D.coords(rows: 2, cols: 2)
[{0, 0}, {0, 1}, {1, 0}, {1, 1}]
@spec links( keyword(), atom() ) :: [ExSystolic.Link.t()]
Returns boundary and internal links for a Grid2D direction.
Directions
:west_to_east-- boundary links enter column 0 from the west; internal links connect each column's:eastto the next column's:west.:north_to_south-- boundary links enter row 0 from the north; internal links connect each row's:southto the next row's:north.
Returns an empty list for unrecognized directions.
Examples
iex> ExSystolic.Space.Grid2D.links([rows: 2, cols: 2], :west_to_east) |> length()
4
iex> ExSystolic.Space.Grid2D.links([rows: 2, cols: 2], :west_to_east) |> Enum.any?(&(&1.from == {{0, -1}, :east}))
true
iex> ExSystolic.Space.Grid2D.links([rows: 2, cols: 2], :north_to_south) |> length()
4
iex> ExSystolic.Space.Grid2D.links([rows: 1, cols: 1], :unknown)
[]
Returns the neighbours of a coordinate within a grid of the given size.
Boundary positions return nil for out-of-bounds neighbours.
Coordinate system: {row, col} with row increasing southward and
col increasing eastward. This matches ExSystolic.Grid.
Examples
iex> ExSystolic.Space.Grid2D.neighbors({1, 1}, rows: 3, cols: 3)
%{north: {0, 1}, south: {2, 1}, east: {1, 2}, west: {1, 0}}
iex> ExSystolic.Space.Grid2D.neighbors({0, 0}, rows: 3, cols: 3)
%{north: nil, south: {1, 0}, east: {0, 1}, west: nil}
iex> ExSystolic.Space.Grid2D.neighbors({2, 2}, rows: 3, cols: 3)
%{north: {1, 2}, south: nil, east: nil, west: {2, 1}}
Validates and normalizes a coordinate.
Accepts {row, col} tuples where both are non-negative integers.
Examples
iex> ExSystolic.Space.Grid2D.normalize({1, 2})
{:ok, {1, 2}}
iex> ExSystolic.Space.Grid2D.normalize({-1, 0})
{:error, :invalid_coordinate}
iex> ExSystolic.Space.Grid2D.normalize("not_a_coord")
{:error, :invalid_coordinate}
Returns the port names for a Grid2D coordinate.
Always returns [:north, :south, :east, :west] regardless of
position (boundary PEs still have the ports; they simply have no
neighbour connected on those ports).
Examples
iex> ExSystolic.Space.Grid2D.ports({0, 0}, rows: 2, cols: 2)
[:north, :south, :east, :west]