# iNML Layout

An iNML layout places in-plane nanomagnets on a planar Cartesian grid. Each position holds a magnet type and, for
inputs and outputs, a name. Clock zones are tiles of magnets. Signal crossings are coplanar cross-wire magnets, so the
layout has no crossing layer. See [Cell Grids and Tile Clocking](../../layouts/cell_grid.html.md) for the storage and the clock zones that iNML shares
with other technologies.

### C++

**Header:** `fiction/technology/inml/layout.hpp`

### enum class [fiction](../../layouts/traits.html.md#_CPPv47fiction)::inml::magnet_type : uint8_t

Types of in-plane Nanomagnet Logic (iNML) magnets. The enumerators carry the symbols of their ASCII representation. 

*Values:*

### enumerator EMPTY

No magnet. 

### enumerator NORMAL

Regular magnet. 

### enumerator INPUT

Primary input magnet. 

### enumerator OUTPUT

Primary output magnet. 

### enumerator SLANTED_EDGE_UP_MAGNET

Magnet with an upper slanted edge. 

### enumerator SLANTED_EDGE_DOWN_MAGNET

Magnet with a lower slanted edge. 

### enumerator INVERTER_MAGNET

Inverter magnet. 

### enumerator CROSSWIRE_MAGNET

Magnet of a coplanar cross wire. 

### enumerator FANOUT_COUPLER_MAGNET

Coupler (fan-out) magnet. 

### class layout : public [fiction](../../layouts/traits.html.md#_CPPv47fiction)::[layouts](../../layouts/traits.html.md#_CPPv4N7fiction7layoutsE)::[cell_grid](../../layouts/cell_grid.html.md#_CPPv4I0EN7fiction7layouts9cell_gridE)<[magnet_type](#_CPPv4N7fiction4inml11magnet_typeE)>, public [fiction](../../layouts/traits.html.md#_CPPv47fiction)::[layouts](../../layouts/traits.html.md#_CPPv4N7fiction7layoutsE)::[tile_clocking](../../layouts/cell_grid.html.md#_CPPv4N7fiction7layouts13tile_clockingE)

An iNML layout: in-plane nanomagnets on a planar Cartesian grid. Each position holds a magnet type and, for inputs and outputs, a name. Clock zones are tiles of magnets. Signal crossings are coplanar cross-wire magnets, so the layout has no crossing layer. The layout has value semantics; copies are independent. 

### Public Functions

### inline explicit layout(const extent &size = {}, std::string name = "", const uint16_t tile_size_x = 1u, const uint16_t tile_size_y = 1u)

Creates an empty layout with open clocking.

* **Parameters:**
  * **size** – Half-open magnet sizes; a nonzero layer count selects one layer. 
  * **name** – Layout name. 
  * **tile_size_x** – Clock-zone width in magnets. 
  * **tile_size_y** – Clock-zone height in magnets. 
* **Throws:**
  std::invalid_argument – If a size exceeds the coordinate domain or a clock-zone size is zero. 

### inline layout(const extent &size, const clocking_scheme_t &scheme, std::string name = "", const uint16_t tile_size_x = 1u, const uint16_t tile_size_y = 1u)

Creates an empty layout clocked by the given scheme.

* **Parameters:**
  * **size** – Half-open magnet sizes; a nonzero layer count selects one layer. 
  * **scheme** – Clocking scheme over clock zones. 
  * **name** – Layout name. 
  * **tile_size_x** – Clock-zone width in magnets. 
  * **tile_size_y** – Clock-zone height in magnets. 
* **Throws:**
  std::invalid_argument – If a size exceeds the coordinate domain or a clock-zone size is zero. 

### inline bool operator==(const [layout](#_CPPv4N7fiction4inml6layoutE) &other) const noexcept

Compares two layouts: same magnets, names, tile size, and clocking scheme name.

* **Parameters:**
  **other** – Right-hand side layout. 
* **Returns:**
  `true` iff both layouts are identical. 

### Public Static Attributes

### static constexpr double CELL_WIDTH = 50.0

Magnet width in nm, the NMLSim default. 

### static constexpr double CELL_HEIGHT = 100.0

Magnet height in nm, the NMLSim default. 

### static constexpr double CELL_HSPACE = 10.0

Horizontal spacing between two magnets in nm, the NMLSim default. 

### static constexpr double CELL_VSPACE = 25.0

Vertical spacing between two magnets in nm, the NMLSim default. 

### Python

### *class* inml_magnet_type(\*values)

Types of in-plane Nanomagnet Logic (iNML) magnets. The enumerators
carry the symbols of their ASCII representation.

#### EMPTY *= 32*

#### NORMAL *= 120*

#### INPUT *= 105*

#### OUTPUT *= 111*

#### SLANTED_EDGE_UP_MAGNET *= 117*

#### SLANTED_EDGE_DOWN_MAGNET *= 100*

#### INVERTER_MAGNET *= 110*

#### CROSSWIRE_MAGNET *= 99*

#### FANOUT_COUPLER_MAGNET *= 102*

### *class* inml_layout

### *class* inml_layout(extent: [extent](../../layouts/coordinates.html.md#mnt.pyfiction.layouts.extent) | [tuple](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int)] | [tuple](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int)])

### *class* inml_layout(extent: [extent](../../layouts/coordinates.html.md#mnt.pyfiction.layouts.extent) | [tuple](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int)] | [tuple](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int)], clocking_scheme: [str](https://docs.python.org/3/builtins/stdtypes.html#str) = '2DDWave', layout_name: [str](https://docs.python.org/3/builtins/stdtypes.html#str) = '', tile_size_x: [int](https://docs.python.org/3/builtins/functions.html#int) = 1, tile_size_y: [int](https://docs.python.org/3/builtins/functions.html#int) = 1)

An iNML layout: in-plane nanomagnets on a planar Cartesian grid. Each
position holds a magnet type and, for inputs and outputs, a name.
Clock zones are tiles of magnets. Signal crossings are coplanar cross-
wire magnets, so the layout has no crossing layer. The layout has
value semantics; copies are independent.

#### assign_cell_name(c: [coordinate](../../layouts/coordinates.html.md#mnt.pyfiction.layouts.coordinate) | [tuple](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int)] | [tuple](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int)], n: [str](https://docs.python.org/3/builtins/stdtypes.html#str)) → [None](https://docs.python.org/3/builtins/constants.html#None)

Assigns a name to a cell. The empty string removes the name.

* **Parameters:**
  * **c** – Cell position.
  * **n** – Cell name.

#### assign_cell_type(c: [coordinate](../../layouts/coordinates.html.md#mnt.pyfiction.layouts.coordinate) | [tuple](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int)] | [tuple](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int)], ct: [inml_magnet_type](#mnt.pyfiction.inml.inml_magnet_type)) → [None](https://docs.python.org/3/builtins/constants.html#None)

Assigns a cell type to a position. Assigning `EMPTY` removes the cell
and its name.

* **Parameters:**
  * **c** – Cell position.
  * **ct** – Cell type.

#### assign_clock_number(cz: [coordinate](../../layouts/coordinates.html.md#mnt.pyfiction.layouts.coordinate) | [tuple](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int)] | [tuple](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int)], cn: [int](https://docs.python.org/3/builtins/functions.html#int)) → [None](https://docs.python.org/3/builtins/constants.html#None)

Overrides the clock number of a clock zone.

* **Parameters:**
  * **cz** – Clock zone.
  * **cn** – Clock number.
* **Raises:**
  [**MemoryError**](https://docs.python.org/3/builtins/exceptions.html#MemoryError) – If allocation fails.

#### bounding_box() → [tuple](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[coordinate](../../layouts/coordinates.html.md#mnt.pyfiction.layouts.coordinate) | [None](https://docs.python.org/3/builtins/constants.html#None), [coordinate](../../layouts/coordinates.html.md#mnt.pyfiction.layouts.coordinate) | [None](https://docs.python.org/3/builtins/constants.html#None)]

Returns the minimum and maximum corner of the bounding box.
A 2D bounding box object computes a minimum-sized box around all
non-empty coordinates in a given layout. Layouts can be of arbitrary
size and, thus, may be larger than their contained elements.
Sometimes, it might be necessary to know exactly which space the
associated layout internals occupy. A bounding box computes
coordinates that span a minimum-sized rectangle that encloses all non-
empty layout coordinates.

* **Returns:**
  The minimum  and maximum enclosing coordinate in the associated layout.

#### cells() → [list](https://docs.python.org/3/builtins/stdtypes.html#list)[[coordinate](../../layouts/coordinates.html.md#mnt.pyfiction.layouts.coordinate)]

Returns the positions of all cells, in unspecified order.

#### get_cell_name(c: [coordinate](../../layouts/coordinates.html.md#mnt.pyfiction.layouts.coordinate) | [tuple](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int)] | [tuple](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int)]) → [str](https://docs.python.org/3/builtins/stdtypes.html#str)

The name of a cell.

* **Parameters:**
  **c** – Cell position.
* **Returns:**
  Name of the cell at `c`, or the empty string if it has none.

#### get_cell_type(c: [coordinate](../../layouts/coordinates.html.md#mnt.pyfiction.layouts.coordinate) | [tuple](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int)] | [tuple](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int)]) → [inml_magnet_type](#mnt.pyfiction.inml.inml_magnet_type)

The cell type at a position.

* **Parameters:**
  **c** – Cell position.
* **Returns:**
  Cell type at `c`, `EMPTY` if no cell is there.

#### get_clock_number(c: [coordinate](../../layouts/coordinates.html.md#mnt.pyfiction.layouts.coordinate) | [tuple](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int)] | [tuple](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int)]) → [int](https://docs.python.org/3/builtins/functions.html#int)

The clock number of the clock zone that contains a cell.

* **Parameters:**
  **c** – Cell position.
* **Returns:**
  Clock number of `get_clock_zone(c)`.

#### get_clock_zone(c: [coordinate](../../layouts/coordinates.html.md#mnt.pyfiction.layouts.coordinate) | [tuple](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int)] | [tuple](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int)]) → [coordinate](../../layouts/coordinates.html.md#mnt.pyfiction.layouts.coordinate)

The clock zone that contains a cell: its tile on layer 0. Negative
axes use floor division.

* **Parameters:**
  **c** – Cell position.
* **Returns:**
  Clock zone of `c`.

#### get_clocking_scheme_name() → [str](https://docs.python.org/3/builtins/stdtypes.html#str)

Returns the name of the layout’s clocking scheme, e.g., `2DDWave` or `USE`.

#### get_layout_name() → [str](https://docs.python.org/3/builtins/stdtypes.html#str)

The layout name.

* **Returns:**
  Layout name.

#### get_tile_size_x() → [int](https://docs.python.org/3/builtins/functions.html#int)

Tile width in cells.

* **Returns:**
  Tile width.

#### get_tile_size_y() → [int](https://docs.python.org/3/builtins/functions.html#int)

Tile height in cells.

* **Returns:**
  Tile height.

#### is_clocking_scheme(name: [str](https://docs.python.org/3/builtins/stdtypes.html#str)) → [bool](https://docs.python.org/3/builtins/functions.html#bool)

Compares the clocking scheme against a name. Predefined names are
constants in `fiction::layouts::clocking`.

* **Parameters:**
  **name** – Clocking scheme name.
* **Returns:**
  `true` iff the scheme is called `name`.

#### is_empty() → [bool](https://docs.python.org/3/builtins/functions.html#bool)

Whether the grid holds no cell.

* **Returns:**
  `true` iff there is no cell.

#### is_empty_cell(c: [coordinate](../../layouts/coordinates.html.md#mnt.pyfiction.layouts.coordinate) | [tuple](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int)] | [tuple](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int)]) → [bool](https://docs.python.org/3/builtins/functions.html#bool)

Whether no cell sits at a position.

* **Parameters:**
  **c** – Cell position.
* **Returns:**
  `true` iff `c` holds no cell.

#### is_pi(c: [coordinate](../../layouts/coordinates.html.md#mnt.pyfiction.layouts.coordinate) | [tuple](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int)] | [tuple](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int)]) → [bool](https://docs.python.org/3/builtins/functions.html#bool)

Whether a cell is a primary input, i.e., of type `INPUT`.

* **Parameters:**
  **c** – Cell position.
* **Returns:**
  `true` iff `c` holds an input cell.

#### is_po(c: [coordinate](../../layouts/coordinates.html.md#mnt.pyfiction.layouts.coordinate) | [tuple](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int)] | [tuple](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int), [int](https://docs.python.org/3/builtins/functions.html#int)]) → [bool](https://docs.python.org/3/builtins/functions.html#bool)

Whether a cell is a primary output, i.e., of type `OUTPUT`.

* **Parameters:**
  **c** – Cell position.
* **Returns:**
  `true` iff `c` holds an output cell.

#### is_regularly_clocked() → [bool](https://docs.python.org/3/builtins/functions.html#bool)

Whether a regular scheme clocks the layout with no overridden zones.

* **Returns:**
  `true` iff the clocking is regular.

#### num_cells() → [int](https://docs.python.org/3/builtins/functions.html#int)

Number of cells.

* **Returns:**
  Number of cells.

#### num_clocks() → [int](https://docs.python.org/3/builtins/functions.html#int)

Number of clock phases.

* **Returns:**
  Number of clock phases.

#### num_pis() → [int](https://docs.python.org/3/builtins/functions.html#int)

Number of primary input cells.

* **Returns:**
  Number of input cells.

#### num_pos() → [int](https://docs.python.org/3/builtins/functions.html#int)

Number of primary output cells.

* **Returns:**
  Number of output cells.

#### pis() → [list](https://docs.python.org/3/builtins/stdtypes.html#list)[[coordinate](../../layouts/coordinates.html.md#mnt.pyfiction.layouts.coordinate)]

Returns the positions of all input cells, in unspecified order.

#### pos() → [list](https://docs.python.org/3/builtins/stdtypes.html#list)[[coordinate](../../layouts/coordinates.html.md#mnt.pyfiction.layouts.coordinate)]

Returns the positions of all output cells, in unspecified order.

#### replace_clocking_scheme(name: [str](https://docs.python.org/3/builtins/stdtypes.html#str)) → [None](https://docs.python.org/3/builtins/constants.html#None)

Replaces the clocking scheme by the predefined scheme of the given name. Clock-number overrides are discarded. Raises ValueError for an unknown name.

#### set_layout_name(name: [str](https://docs.python.org/3/builtins/stdtypes.html#str)) → [None](https://docs.python.org/3/builtins/constants.html#None)

Sets the layout name.

* **Parameters:**
  **name** – Layout name.

#### set_tile_size_x(size: [int](https://docs.python.org/3/builtins/functions.html#int)) → [None](https://docs.python.org/3/builtins/constants.html#None)

Sets the tile width.

* **Parameters:**
  **size** – Tile width in cells.
* **Raises:**
  [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError) – if `size` is zero.

#### set_tile_size_y(size: [int](https://docs.python.org/3/builtins/functions.html#int)) → [None](https://docs.python.org/3/builtins/constants.html#None)

Sets the tile height.

* **Parameters:**
  **size** – Tile height in cells.
* **Raises:**
  [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError) – if `size` is zero.
