Skip to content

Commit

Permalink
core/pipe: rename PipeInput/PipeOutput to InputPort/OutputPort
Browse files Browse the repository at this point in the history
for clarity.
  • Loading branch information
vsergeev committed Oct 22, 2020
1 parent 27cd244 commit 16685b3
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 115 deletions.
24 changes: 12 additions & 12 deletions docs/5.architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -321,24 +321,24 @@ After a block is instantiated, it can be connected into a flow graph under a
Blocks](#composite-blocks) section below.

When the `add_type_signature()` method is called in a block's `instantiate()`
constructor, it builds `PipeInput` and `PipeOutput` containers for each
constructor, it builds `InputPort` and `OutputPort` containers for each
specified input and output port of the block, and stores them in arrays under
the `.inputs` and `.outputs` members. These containers are the actual "ports"
connected in a flow graph. They contain a name and block owner, and are later
populated with their concrete data type and a shared `Pipe` object.

The act of connecting two blocks in a flow graph is registering the block's
`PipeInput` instance as the key and the `PipeOutput` instance as a value in a
`InputPort` instance as the key and the `OutputPort` instance as a value in a
hash table owned by a `CompositeBlock`, thereby building a graph of input and
output connections.

When a connection is made, a `Pipe` object is also created and registered under
both `PipeInput` and `PipeOutput` containers of the connected blocks. This
both `InputPort` and `OutputPort` containers of the connected blocks. This
`Pipe` object provides an interface for the serialization and deserialization
of sample vectors between blocks. The `Pipe` is how a block reads or writes
vectors of samples from or to another block.

Code reference: [Block class](../radio/core/block.lua), [PipeInput, PipeOutput,
Code reference: [Block class](../radio/core/block.lua), [InputPort, OutputPort,
Pipe classes](../radio/core/pipe.lua).

#### Differentiation
Expand All @@ -361,7 +361,7 @@ that implements `to_json()`. In those cases, `differentiate()` calls the
function predicate with the input type and expects a boolean result to indicate
if the input type is compatible.

The result of differentiation is that the `PipeInput` and `PipeOutput` ports in
The result of differentiation is that the `InputPort` and `OutputPort` ports in
the block's `.inputs` and `.outputs` take on the concrete data types specified
in the selected type signature, and the block's `initialize()` and `process()`
methods are bound to the ones specified in the type signature. The concrete
Expand Down Expand Up @@ -506,9 +506,9 @@ inputs or outputs, hierarchical blocks also specify a type signature with
`add_type_signature()` for their boundary inputs and outputs.

When a `CompositeBlock` adds a type signature, instead of building the
`PipeInput` and `PipeOutput` input and output ports under the `.inputs` and
`InputPort` and `OutputPort` input and output ports under the `.inputs` and
`.outputs` arrays as a normal block would, the `CompositeBlock` builds
`AliasedPipeInput` and `AliasedPipeOutput` ports, respectively. These are
`AliasedInputPort` and `AliasedOutputPort` ports, respectively. These are
special input and output ports that alias existing input and output ports
inside a flow graph.

Expand All @@ -523,20 +523,20 @@ Code reference: [CompositeBlock class](../radio/core/composite.lua).
A `CompositeBlock` used for a top-level block builds a flow graph by connecting
block ports with the [`connect()`](0.reference-manual.md#compositeblockconnect)
method. The data structure for the flow graph is a table that maps block
`PipeInput` instances to `PipeOutput` instances. In other words, it is a hash
`InputPort` instances to `OutputPort` instances. In other words, it is a hash
table of input port to output port, for each connection between blocks in the
graph.

##### Connection

When a connection is made with `connect()` on a top-level `CompositeBlock`, the
`PipeInput` and `PipeOutput` ports are looked up in the blocks and added to the
`InputPort` and `OutputPort` ports are looked up in the blocks and added to the
connections table, and a `Pipe` object is created and registered under both
`PipeInput` and `PipeOutput` port instances.
`InputPort` and `OutputPort` port instances.

If a hierarchical block is connected into a top-level block, then its
`AliasedPipeInput` and `AliasedPipeOutput` ports are followed to the underlying
real `PipeInput` and `PipeOutput` ports, and those are the input and output
`AliasedInputPort` and `AliasedOutputPort` ports are followed to the underlying
real `InputPort` and `OutputPort` ports, and those are the input and output
port instances registered in the flow graph. This means that the hierarchical
block does not exist in a top-level flow graph; it's just a convenience for
composing blocks.
Expand Down
12 changes: 6 additions & 6 deletions radio/core/block.lua
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,10 @@ function Block:add_type_signature(inputs, outputs, process_func, initialize_func
end

if not self.inputs then
-- Create inputs with a PipeInput for each input
-- Create inputs with a InputPort for each input
self.inputs = {}
for i = 1, #inputs do
self.inputs[i] = pipe.PipeInput(self, inputs[i].name)
self.inputs[i] = pipe.InputPort(self, inputs[i].name)
end
else
-- Check input count
Expand All @@ -102,10 +102,10 @@ function Block:add_type_signature(inputs, outputs, process_func, initialize_func
end

if not self.outputs then
-- Create outputs with a PipeOutput for each output
-- Create outputs with a OutputPort for each output
self.outputs = {}
for i = 1, #outputs do
self.outputs[i] = pipe.PipeOutput(self, outputs[i].name)
self.outputs[i] = pipe.OutputPort(self, outputs[i].name)
end
else
-- Check output count
Expand Down Expand Up @@ -248,7 +248,7 @@ function Block:__tostring()
if self.inputs[i].pipe then
local pipe = self.inputs[i].pipe or self.inputs[i].real_input.pipe
if pipe then
strs[#strs + 1] = string.format(" .%-5s [%s] <- {%s.%s}", self.inputs[i].name, self.inputs[i].data_type and self.inputs[i].data_type.type_name or "Unknown Type", pipe.pipe_output.owner.name, pipe.pipe_output.name)
strs[#strs + 1] = string.format(" .%-5s [%s] <- {%s.%s}", self.inputs[i].name, self.inputs[i].data_type and self.inputs[i].data_type.type_name or "Unknown Type", pipe.output.owner.name, pipe.output.name)
else
strs[#strs + 1] = string.format(" .%-5s <- unconnected", self.inputs[i].name)
end
Expand All @@ -260,7 +260,7 @@ function Block:__tostring()
if #pipes > 0 then
local connections = {}
for i=1, #pipes do
connections[i] = string.format("%s.%s", pipes[i].pipe_input.owner.name, pipes[i].pipe_input.name)
connections[i] = string.format("%s.%s", pipes[i].input.owner.name, pipes[i].input.name)
end
strs[#strs + 1] = string.format(" .%-5s [%s] -> {%s}", self.outputs[i].name, self.outputs[i].data_type and self.outputs[i].data_type.type_name or "Unknown Type", table.concat(connections, ", "))
else
Expand Down
118 changes: 59 additions & 59 deletions radio/core/composite.lua
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,17 @@ end
function CompositeBlock:add_type_signature(inputs, outputs)
block.Block.add_type_signature(self, inputs, outputs)

-- Replace PipeInput's with AliasedPipeInput's
-- Replace InputPort's with AliasedInputPort's
for i = 1, #self.inputs do
if class.isinstanceof(self.inputs[i], pipe.PipeInput) then
self.inputs[i] = pipe.AliasedPipeInput(self, self.inputs[i].name)
if class.isinstanceof(self.inputs[i], pipe.InputPort) then
self.inputs[i] = pipe.AliasedInputPort(self, self.inputs[i].name)
end
end

-- Replace PipeOutput's with AliasedPipeOutput's
-- Replace OutputPort's with AliasedOutputPort's
for i = 1, #self.outputs do
if class.isinstanceof(self.outputs[i], pipe.PipeOutput) then
self.outputs[i] = pipe.AliasedPipeOutput(self, self.outputs[i].name)
if class.isinstanceof(self.outputs[i], pipe.OutputPort) then
self.outputs[i] = pipe.AliasedOutputPort(self, self.outputs[i].name)
end
end
end
Expand Down Expand Up @@ -113,70 +113,70 @@ function CompositeBlock:connect(...)
return self
end

function CompositeBlock:_connect_by_name(src, src_pipe_name, dst, dst_pipe_name)
-- Look up pipe objects
local src_pipe = util.array_search(src.outputs, function (p) return p.name == src_pipe_name end) or
util.array_search(src.inputs, function (p) return p.name == src_pipe_name end)
local dst_pipe = util.array_search(dst.outputs, function (p) return p.name == dst_pipe_name end) or
util.array_search(dst.inputs, function (p) return p.name == dst_pipe_name end)
assert(src_pipe, string.format("Output port \"%s\" of block \"%s\" not found.", src_pipe_name, src.name))
assert(dst_pipe, string.format("Input port \"%s\" of block \"%s\" not found.", dst_pipe_name, dst.name))
function CompositeBlock:_connect_by_name(src, src_port_name, dst, dst_port_name)
-- Look up port objects
local src_port = util.array_search(src.outputs, function (p) return p.name == src_port_name end) or
util.array_search(src.inputs, function (p) return p.name == src_port_name end)
local dst_port = util.array_search(dst.outputs, function (p) return p.name == dst_port_name end) or
util.array_search(dst.inputs, function (p) return p.name == dst_port_name end)
assert(src_port, string.format("Output port \"%s\" of block \"%s\" not found.", src_port_name, src.name))
assert(dst_port, string.format("Input port \"%s\" of block \"%s\" not found.", dst_port_name, dst.name))

-- If this is a block to block connection in a top composite block
if src ~= self and dst ~= self then
-- Map aliased outputs and inputs to their real pipes
src_pipe = class.isinstanceof(src_pipe, pipe.AliasedPipeOutput) and src_pipe.real_output or src_pipe
dst_pipes = class.isinstanceof(dst_pipe, pipe.AliasedPipeInput) and dst_pipe.real_inputs or {dst_pipe}
-- Map aliased outputs and inputs to their real ports
src_port = class.isinstanceof(src_port, pipe.AliasedOutputPort) and src_port.real_output or src_port
dst_ports = class.isinstanceof(dst_port, pipe.AliasedInputPort) and dst_port.real_inputs or {dst_port}

for i = 1, #dst_pipes do
for i = 1, #dst_ports do
-- Assert input is not already connected
assert(not self._connections[dst_pipes[i]], string.format("Input port \"%s\" of block \"%s\" already connected.", dst_pipes[i].name, dst_pipes[i].owner.name))
assert(not self._connections[dst_ports[i]], string.format("Input port \"%s\" of block \"%s\" already connected.", dst_ports[i].name, dst_ports[i].owner.name))

-- Create a pipe from output to input
local p = pipe.Pipe(src_pipe, dst_pipes[i])
local p = pipe.Pipe(src_port, dst_ports[i])
-- Link the pipe to the input and output ends
src_pipe.pipes[#src_pipe.pipes+1] = p
dst_pipes[i].pipe = p
src_port.pipes[#src_port.pipes+1] = p
dst_ports[i].pipe = p

-- Update our connections table
self._connections[dst_pipes[i]] = src_pipe
self._connections[dst_ports[i]] = src_port

debug.printf("[CompositeBlock] Connected output %s.%s to input %s.%s\n", src.name, src_pipe.name, dst.name, dst_pipe.name)
debug.printf("[CompositeBlock] Connected output %s.%s to input %s.%s\n", src.name, src_port.name, dst.name, dst_port.name)
end
else
-- Otherwise, we are aliasing an input or output of a composite block

-- Map src and dst pipe to alias pipe and real pipe
local alias_pipe = (src == self) and src_pipe or dst_pipe
local target_pipe = (src == self) and dst_pipe or src_pipe
-- Map src and dst ports to alias port and target port
local alias_port = (src == self) and src_port or dst_port
local target_port = (src == self) and dst_port or src_port

if class.isinstanceof(alias_pipe, pipe.AliasedPipeInput) and class.isinstanceof(target_pipe, pipe.PipeInput) then
if class.isinstanceof(alias_port, pipe.AliasedInputPort) and class.isinstanceof(target_port, pipe.InputPort) then
-- If we are aliasing a composite block input to a concrete block input

alias_pipe.real_inputs[#alias_pipe.real_inputs + 1] = target_pipe
debug.printf("[CompositeBlock] Aliased input %s.%s to input %s.%s\n", alias_pipe.owner.name, alias_pipe.name, target_pipe.owner.name, target_pipe.name)
elseif class.isinstanceof(alias_pipe, pipe.AliasedPipeOutput) and class.isinstanceof(target_pipe, pipe.PipeOutput) then
alias_port.real_inputs[#alias_port.real_inputs + 1] = target_port
debug.printf("[CompositeBlock] Aliased input %s.%s to input %s.%s\n", alias_port.owner.name, alias_port.name, target_port.owner.name, target_port.name)
elseif class.isinstanceof(alias_port, pipe.AliasedOutputPort) and class.isinstanceof(target_port, pipe.OutputPort) then
-- If we are aliasing a composite block output to a concrete block output

assert(not alias_pipe.real_output, "Aliased output already connected.")
alias_pipe.real_output = target_pipe
debug.printf("[CompositeBlock] Aliased output %s.%s to output %s.%s\n", alias_pipe.owner.name, alias_pipe.name, target_pipe.owner.name, target_pipe.name)
elseif class.isinstanceof(alias_pipe, pipe.AliasedPipeInput) and class.isinstanceof(target_pipe, pipe.AliasedPipeInput) then
assert(not alias_port.real_output, "Aliased output already connected.")
alias_port.real_output = target_port
debug.printf("[CompositeBlock] Aliased output %s.%s to output %s.%s\n", alias_port.owner.name, alias_port.name, target_port.owner.name, target_port.name)
elseif class.isinstanceof(alias_port, pipe.AliasedInputPort) and class.isinstanceof(target_port, pipe.AliasedInputPort) then
-- If we are aliasing a composite block input to a composite block input

-- Absorb destination alias real inputs
for i = 1, #target_pipe.real_inputs do
alias_pipe.real_inputs[#alias_pipe.real_inputs + 1] = target_pipe.real_inputs[i]
for i = 1, #target_port.real_inputs do
alias_port.real_inputs[#alias_port.real_inputs + 1] = target_port.real_inputs[i]
end
debug.printf("[CompositeBlock] Aliased input %s.%s to input %s.%s\n", alias_pipe.owner.name, alias_pipe.name, target_pipe.owner.name, target_pipe.name)
elseif class.isinstanceof(alias_pipe, pipe.AliasedPipeOutput) and class.isinstanceof(target_pipe, pipe.AliasedPipeOutput) then
debug.printf("[CompositeBlock] Aliased input %s.%s to input %s.%s\n", alias_port.owner.name, alias_port.name, target_port.owner.name, target_port.name)
elseif class.isinstanceof(alias_port, pipe.AliasedOutputPort) and class.isinstanceof(target_port, pipe.AliasedOutputPort) then
-- If we are aliasing a composite block output to a composite block output

assert(not alias_pipe.real_output, "Aliased output already connected.")
alias_pipe.real_output = target_pipe.real_output
debug.printf("[CompositeBlock] Aliased output %s.%s to output %s.%s\n", alias_pipe.owner.name, alias_pipe.name, target_pipe.owner.name, target_pipe.name)
assert(not alias_port.real_output, "Aliased output already connected.")
alias_port.real_output = target_port.real_output
debug.printf("[CompositeBlock] Aliased output %s.%s to output %s.%s\n", alias_port.owner.name, alias_port.name, target_port.owner.name, target_port.name)
else
error("Malformed pipe connection.")
error("Malformed port connection.")
end
end
end
Expand All @@ -190,23 +190,23 @@ local function crawl_connections(connections)
repeat
local new_blocks_found = false

for pipe_input, pipe_output in pairs(connections_copy) do
local src = pipe_output.owner
local dst = pipe_input.owner
for input, output in pairs(connections_copy) do
local src = output.owner
local dst = input.owner

for _, block in ipairs({src, dst}) do
-- If we haven't seen this block before
if not blocks[block] then
-- Add all of the block's inputs our connections table
for i=1, #block.inputs do
if block.inputs[i].pipe then
connections_copy[block.inputs[i]] = block.inputs[i].pipe.pipe_output
connections_copy[block.inputs[i]] = block.inputs[i].pipe.output
end
end
-- Add all of the block's outputs to to our connection table
for i=1, #block.outputs do
for j=1, #block.outputs[i].pipes do
local input = block.outputs[i].pipes[j].pipe_input
local input = block.outputs[i].pipes[j].input
connections_copy[input] = block.outputs[i]
end
end
Expand All @@ -227,9 +227,9 @@ local function build_dependency_graph(connections)
local graph = {}

-- Add dependencies between connected blocks
for pipe_input, pipe_output in pairs(connections) do
local src = pipe_output.owner
local dst = pipe_input.owner
for input, output in pairs(connections) do
local src = output.owner
local dst = input.owner

if graph[src] == nil then
graph[src] = {}
Expand All @@ -249,9 +249,9 @@ local function build_reverse_dependency_graph(connections)
local graph = {}

-- Add dependencies between connected blocks
for pipe_input, pipe_output in pairs(connections) do
local src = pipe_output.owner
local dst = pipe_input.owner
for input, output in pairs(connections) do
local src = output.owner
local dst = input.owner

if graph[src] == nil then
graph[src] = {dst}
Expand Down Expand Up @@ -405,8 +405,8 @@ function CompositeBlock:_prepare_to_run()
end

-- Initialize all pipes
for pipe_input, pipe_output in pairs(all_connections) do
pipe_input.pipe:initialize()
for input, output in pairs(all_connections) do
input.pipe:initialize()
end

debug.print("[CompositeBlock] Flow graph:")
Expand Down Expand Up @@ -554,9 +554,9 @@ function CompositeBlock:start(multiprocess)
end

-- Close all pipe inputs and outputs in the top-level process
for pipe_input, pipe_output in pairs(all_connections) do
pipe_input:close()
pipe_output:close()
for input, output in pairs(all_connections) do
input:close()
output:close()
end

-- Mark ourselves as running
Expand Down
Loading

0 comments on commit 16685b3

Please sign in to comment.