Ports

A Port is actually is a bunch of pins (See Pins for mor information on pins.). As such, the connection, disconnection and data transfer are very similar to those of pins. Basically, there are two type of port: Outport and Inport. The data flows from outside of a component to its inside through an Inport while data flows from inside of the component to its outside through an Outport.

Construction of Ports

A port (both Inport and Outport) is constructed by specifying its element type T, the number of pins npins and the buffer length of its pins.


julia> Outport{Bool}(5)
5-element Outport{Outpin{Bool}}:
 Outpin(eltype:Bool, isbound:false)
 Outpin(eltype:Bool, isbound:false)
 Outpin(eltype:Bool, isbound:false)
 Outpin(eltype:Bool, isbound:false)
 Outpin(eltype:Bool, isbound:false)

julia> Outport{Int}(2)
2-element Outport{Outpin{Int64}}:
 Outpin(eltype:Int64, isbound:false)
 Outpin(eltype:Int64, isbound:false)

julia> Outport(3)
3-element Outport{Outpin{Float64}}:
 Outpin(eltype:Float64, isbound:false)
 Outpin(eltype:Float64, isbound:false)
 Outpin(eltype:Float64, isbound:false)

julia> Outport()
1-element Outport{Outpin{Float64}}:
 Outpin(eltype:Float64, isbound:false)

julia> Inport{Bool}(5)
5-element Inport{Inpin{Bool}}:
 Inpin(eltype:Bool, isbound:false)
 Inpin(eltype:Bool, isbound:false)
 Inpin(eltype:Bool, isbound:false)
 Inpin(eltype:Bool, isbound:false)
 Inpin(eltype:Bool, isbound:false)

julia> Inport{Int}(2)
2-element Inport{Inpin{Int64}}:
 Inpin(eltype:Int64, isbound:false)
 Inpin(eltype:Int64, isbound:false)

julia> Inport(3)
3-element Inport{Inpin{Float64}}:
 Inpin(eltype:Float64, isbound:false)
 Inpin(eltype:Float64, isbound:false)
 Inpin(eltype:Float64, isbound:false)

julia> Inport()
1-element Inport{Inpin{Float64}}:
 Inpin(eltype:Float64, isbound:false)

Connection and Disconnection of Ports

The ports can be connected to and disconnected from each other. See the following example.

Let us construct and Outport and an Inport and connect them together.

julia> op1 = Outport(2)
2-element Outport{Outpin{Float64}}:
 Outpin(eltype:Float64, isbound:false)
 Outpin(eltype:Float64, isbound:false)

julia> ip1 = Inport(2)
2-element Inport{Inpin{Float64}}:
 Inpin(eltype:Float64, isbound:false)
 Inpin(eltype:Float64, isbound:false)

julia> ls = connect!(op1, ip1)
2-element Array{Link{Float64},1}:
 Link(state:open, eltype:Float64, isreadable:false, iswritable:false)
 Link(state:open, eltype:Float64, isreadable:false, iswritable:false)

Note that we connected all pins of op to ip. We cannot connect the ports partially.

julia> op2, ip21, ip22 = Outport(5), Inport(2), Inport(3)
(Outport(numpins:5, eltype:Outpin{Float64}), Inport(numpins:2, eltype:Inpin{Float64}), Inport(numpins:3, eltype:Inpin{Float64}))

julia> ls1 = connect!(op2[1:2], ip21)
2-element Array{Link{Float64},1}:
 Link(state:open, eltype:Float64, isreadable:false, iswritable:false)
 Link(state:open, eltype:Float64, isreadable:false, iswritable:false)

julia> ls2 = connect!(op2[3:5], ip22)
3-element Array{Link{Float64},1}:
 Link(state:open, eltype:Float64, isreadable:false, iswritable:false)
 Link(state:open, eltype:Float64, isreadable:false, iswritable:false)
 Link(state:open, eltype:Float64, isreadable:false, iswritable:false)

The connectedness of ports can be checked.

julia> isconnected(op2[1], ip21[1])
true

julia> isconnected(op2[1], ip21[2])
false

julia> isconnected(op2[1:2], ip21)
true

julia> isconnected(op2[3:5], ip22)
true

julia> isconnected(op2[5], ip22[3])
true

Connected ports can be disconnected.

julia> disconnect!(op2[1], ip21[1])
missing

julia> disconnect!(op2[2], ip21[2])
missing

julia> disconnect!(op2[3:5], ip22)

Now check again the connectedness,

julia> isconnected(op2[1], ip21[1])
false

julia> isconnected(op2[1], ip21[2])
false

julia> isconnected(op2[1:2], ip21)
false

julia> isconnected(op2[3:5], ip22)
false

julia> isconnected(op2[5], ip22[3])
false

Data Flow Through Ports

Data flow through the ports is very similar to the case in pins(see Data Flow Through Pins for information about data flow through pins). Running tasks must be bound to the links of pins of the ports for data flow through the ports.

Let us construct an Outport and an Inport, connect them together with links and perform data transfer from the Outport to the Inport through the links.

julia> op3, ip3 = Outport(2), Inport(2)
(Outport(numpins:2, eltype:Outpin{Float64}), Inport(numpins:2, eltype:Inpin{Float64}))

julia> ls = connect!(op3, ip3)
2-element Array{Link{Float64},1}:
 Link(state:open, eltype:Float64, isreadable:false, iswritable:false)
 Link(state:open, eltype:Float64, isreadable:false, iswritable:false)

julia> t = @async while true
           val = take!(ip3)
           all(val .=== NaN) && break
           println("Took " * string(val))
       end
Task (runnable) @0x00007f1fd477b340

julia> put!(op3, 1.);
Took [1.0, 1.0]

julia> ip3[1].link.buffer
64-element Buffer{Cyclic,Float64,1}:
 1.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 ⋮
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0

Note that the data flowing through the links are also written into the buffers of links.

Indexing and Iteration of Ports

Ports can be indexed similarly to the arrays in Julia. When indexed, the corresponding pin of the port is returned.

julia> op4 = Outport(3)
3-element Outport{Outpin{Float64}}:
 Outpin(eltype:Float64, isbound:false)
 Outpin(eltype:Float64, isbound:false)
 Outpin(eltype:Float64, isbound:false)

julia> op4[1]
Outpin(eltype:Float64, isbound:false)

julia> op4[end]
Outpin(eltype:Float64, isbound:false)

julia> op4[:]
3-element Array{Outpin{Float64},1}:
 Outpin(eltype:Float64, isbound:false)
 Outpin(eltype:Float64, isbound:false)
 Outpin(eltype:Float64, isbound:false)

julia> op4[1] = Outpin()
Outpin(eltype:Float64, isbound:false)

julia> op4[1:2] = [Outpin(), Outpin()]
2-element Array{Outpin{Float64},1}:
 Outpin(eltype:Float64, isbound:false)
 Outpin(eltype:Float64, isbound:false)

The iteration of Ports in a loop is also possible. When iterated, the pins of the Port is returned.

julia> ip5 = Inport(3)
3-element Inport{Inpin{Float64}}:
 Inpin(eltype:Float64, isbound:false)
 Inpin(eltype:Float64, isbound:false)
 Inpin(eltype:Float64, isbound:false)

julia> for pin in ip5
           @show pin
       end
pin = Inpin(eltype:Float64, isbound:false)
pin = Inpin(eltype:Float64, isbound:false)
pin = Inpin(eltype:Float64, isbound:false)

Full API

Causal.InportType
struct Inport{P} <: AbstractPort{P}

Constructs an Inport with numpins Inpin.

Fields

  • pins::Array{P,1} where P

    Pins of the port

!!! warning Element type of an Inport must be Inpin. See also Inpin

Example

julia> Inport{Int}(2)
2-element Inport{Inpin{Int64}}:
 Inpin(eltype:Int64, isbound:false)
 Inpin(eltype:Int64, isbound:false)

julia> Inport()
1-element Inport{Inpin{Float64}}:
 Inpin(eltype:Float64, isbound:false)
source
Causal.OutportType
struct Outport{P} <: AbstractPort{P}

Constructs an Outport with numpins Outpin.

Fields

  • pins::Array{P,1} where P

    Pins of the output port

  • id::Base.UUID

    Unique identifier

!!! warning Element type of an Outport must be Outpin. See also Outpin

Example

julia> Outport{Int}(2)
2-element Outport{Outpin{Int64}}:
 Outpin(eltype:Int64, isbound:false)
 Outpin(eltype:Int64, isbound:false)

julia> Outport()
1-element Outport{Outpin{Float64}}:
 Outpin(eltype:Float64, isbound:false)
source
Base.getindexMethod
getindex(port, idx)

Returns elements from port at index idx. Same as port[idx].

Example

julia> op = Outport(3)
3-element Outport{Outpin{Float64}}:
 Outpin(eltype:Float64, isbound:false)
 Outpin(eltype:Float64, isbound:false)
 Outpin(eltype:Float64, isbound:false)

julia> op[1]
Outpin(eltype:Float64, isbound:false)

julia> op[end]
Outpin(eltype:Float64, isbound:false)

julia> op[:]
3-element Array{Outpin{Float64},1}:
 Outpin(eltype:Float64, isbound:false)
 Outpin(eltype:Float64, isbound:false)
 Outpin(eltype:Float64, isbound:false)
source
Base.put!Method
put!(outport, vals)

Puts vals to outport. Each item in vals is putted to the links of the outport.

Warning

The outport must be writable to be read. That is, there must be a runnable tasks bound to links of the outport that reads data from outport.

Example

julia> op, ip = Outport(), Inport() 
(Outport(numpins:1, eltype:Outpin{Float64}), Inport(numpins:1, eltype:Inpin{Float64}))

julia> ls = connect!(op, ip)
1-element Array{Link{Float64},1}:
 Link(state:open, eltype:Float64, isreadable:false, iswritable:false)

julia> t = @async while true 
       val = take!(ip)
       all(val .=== NaN) && break 
       println("Took " * string(val))
       end;

julia> put!(op, [1.])
Took [1.0]
1-element Array{Float64,1}:
 1.0

julia> put!(op, [NaN])
1-element Array{Float64,1}:
 NaN
source
Base.setindex!Method
setindex!(port, item, idx)

Sets item to port at index idx. Same as port[idx] = item.

Example

julia> op = Outport(3)
3-element Outport{Outpin{Float64}}:
 Outpin(eltype:Float64, isbound:false)
 Outpin(eltype:Float64, isbound:false)
 Outpin(eltype:Float64, isbound:false)

julia> op[1] = Outpin()
Outpin(eltype:Float64, isbound:false)

julia> op[end] = Outpin()
Outpin(eltype:Float64, isbound:false)

julia> op[1:2] = [Outpin(), Outpin()]
2-element Array{Outpin{Float64},1}:
 Outpin(eltype:Float64, isbound:false)
 Outpin(eltype:Float64, isbound:false)
source
Base.take!Method
take!(inport)

Takes an element from inport. Each link of the inport is a read and a vector containing the results is returned.

Warning

The inport must be readable to be read. That is, there must be a runnable tasks bound to links of the inport that writes data to inport.

Example

julia> op, ip = Outport(), Inport()
(Outport(numpins:1, eltype:Outpin{Float64}), Inport(numpins:1, eltype:Inpin{Float64}))

julia> ls = connect!(op, ip)
1-element Array{Link{Float64},1}:
 Link(state:open, eltype:Float64, isreadable:false, iswritable:false)

julia> t = @async for val in 1 : 5 
       put!(op, [val])
       end;

julia> take!(ip)
1-element Array{Float64,1}:
 1.0

julia> take!(ip)
1-element Array{Float64,1}:
 2.0
source
Causal.similarMethod
similar(outport)
similar(outport, numpins)

Returns a new port that is similar to port with the same element type. The number of links in the new port is nlinks and data buffer length is ln.

source