Applications of Diffusing
Computation
This module describes diffusing computation algorithms by which an
agent learns properties of the network in which the agent is situated.
Diffusing computations are used by an agent to learn properties of
the network in which the agent is embedded. We will first look at
cases in which the network is static and then study an algorithm
in which an agent learns properties of the network while the
network is changing.
In this problem, agents are in a static network. If there is an edge
from an agent \(x\) to an agent \(y\), in the network, then there is an edge in the
reverse direction.
Acquiring Graph Information
Associated with each agent \(x\) is some constant value, \(x.v\),
where \(x.v\) is arbitrary. For example \(x.v\) could
be: the coordinates of agent \(x\) in 3D space, or agent \(x\)'s
lists of assets and liabilities, or the files for which it has
exclusive locks.
An agent, called the
initiator, starts a computation by which it learns
the values of all the agents in the network. When the the
computation terminates, the initiator will have a set
\(initiator.values\) where the elements of the set
are pairs \((x, x.v)\), with one element for each agent in the system.
We first give the program and then prove its correctness. The
program is a simple version of a diffusing computation. The simplification
comes from the facts that:
-
Each agent becomes active only when it receives its first
message. It doesn't change its active/idle state when it
receives subsequent messages.
So each agent changes from idle to active exactly once.
-
After an agent sets its parent to a non-null value, it does not
change its parents thereafter. So, the tree grows, and once an
edge of the tree is created that edge is never changed.
-
For each channel \(c\), exactly one message and exactly one
ack traverses the channel in the algorithm
By contrast, in a general diffusing computation an agent may
become active multiple times because each time an idle agent receives a
message it becomes active. In the general case, edges of the tree
are created and may be later deleted.
Associated with each agent \(x\) is a local boolean variable
\(x.received\_all\_acks\) which is True exactly when agent \(x\) has
received acks for all the messages that it has sent.
Each ack has a field called values which is a set. The elements
of this set are pairs \((x, x.v)\) where \(x\) is an agent.
Simpler Version
Initially, \(x.parent = null\) for all agents \(x\) other than the
initiator.
The initiator starts the computation by executing the following
program:
initiator.values = {(initiator, initiator.v)}
send a message to each neighbor of the initiator
Next we give the program for an agent \(x\)
other than the initiator.
1: if (x.parent == null) and (x receives a message from y):
x.parent = y
// x.parent does not change from now onwards.
x.values = {(x, x.v)}
send a message to each neighbor of x other than x.parent
2: if (x.parent != null) and (x receives a message from y):
send ack(values = {}) to y
3: if x receives an ack
// set x.values to the union of x.values and ack.values.
x.values = union(x.values, ack.values)
if x.received_all_acks:
send ack(values=x.values) to x.parent
Proof outline
The steps of the proof are as follows:
-
An agent \(x\) changes \(x.parent\) exactly once from \(null\) to a
non-\(null\) value.
The initiator is the ancestor of all agents \(x\) for which
\(x.parent\) is not null.
The tree propagates to span all agents reachable from the initiator.
-
For each agent \(x\), its value \((x, x.v)\) is propagated exactly once
to its parent. This value is then propagated along edges of
the tree through ancestors of \(x\) to the initiator.
Examples
The algorithm can be optimized for problems in
which the initiator has to discover different kinds of information
about graphs. For example, if agents have colors and the initiator has
to discover the numbers of agents of each color, then
values
can be counts of agents of each color, and counts can be summed
instead of taking unions of sets.
Example
Next, we look at an example of an algorithm in which an
agent acquires a specific kind of graph information.
An agent has a color, either red or blue, and the color does not
change. The
initiator has to discover whether there exists at least one red agent
in the network.
An optimization is that if the diffusing computation reaches a red
agent then the red agent does not diffuse the
computation even further. We give the optimized algorithm,
program
2, below. It's proof of correctness is similar to the proof of
program given above.
Program 2: Detecting a red agent
1: if (x.parent == null) and (x receives a message from y):
x.parent = y
if x.color == red:
send ack(color=red) to y
else:
send a message to all neighbors of x other than y
2: if (x.parent != null) and x receives a message from y:
send ack(color=x.color) to y
3: if (x receives an ack A) and (x has not sent an ack to x.parent):
if A.color == red:
send ack(color=red) to x.parent
elif x.received_all_acks:
send ack(color=blue) to x.parent
If the initiator receives at least one red ack then the network has a
red agent. If the initiator receives only blue acks then the network
has no red agent.
Termination Detection Revisited
We described the problem of detecting that a computation has terminated in
the module on global snapshot applications. We also described an
algorithm to solve that problem in the module. Now we give another
algorithm to solve the same problem. This algorithm combines diffusing
computation and the snapshot algorithm, and is a small modification of
program 2.
Problem Specification
For convenience, the problem definition from the earlier
module is repeated here.
An agent is either idle or active. An idle agent
remains idle until it receives a message. An idle agent does not
send messages. An active agent may send messages. An active agent
may become idle at any point. An idle agent becomes active when it
receives a message.
Initially all agents are active and all channels are empty.
A terminated state of the system is one in which all agents
are idle and all channels are empty. terminated is stable:
a system in a terminated state remains terminated thereafter. A
system may or may not enter a terminated state.
Our task is to develop an algorithm that detects that a system has
entered a terminated state.
Algorithm
In analogy with
program 2, let's give colors to agents.
Let's specify that an agent that is
idle throughout the snapshot algorithm is colored blue. An agent that
is active at any point during the snapshot algorithm is colored red. The initiator
has to discover whether any agent is red.
The differences between
termination detection and the problem of detecting a red agent
are that (1) agent
colors may change during termination detection, and (2)
termination detection has to detect properties of channels --- namely
whether channels are empty --- in addition to detecting properties of
agents. A surprising
result is that program 2, with the addition of a statement to deal
with channels, can be
used for termination detection.
In the modified algorithm, the initiator takes its local snapshot when
it initiates the algorithm. All
other agents take their local snapshot when they set their parents to
non-null values.
The statement that we add is:
4: if (x.parent != null) and x receives a message:
if x has not sent an ack to x.parent:
send ack(color=red) to x.parent
Proof outline
Consider the following modification to the snapshot algorithm: replace
the
ack and
message of program 2 by
markers of the snapshot algorithm. The resulting program is identical
to the snapshot algorithm with two differences:
-
An ack in program 2 may be sent later than a marker is sent in a
snapshot algorithm. In the snapshot algorithm, when an agent receives a
marker for the first time it sends markers immediately.
In the modified
algorithm, however, an agent may not immediately send an ack when it
receives a command. This is because of the elif clause in
statement 3: an agent sends an ack only after receiving acks for all the
messages that it sent.
-
The snapshot algorithm takes snapshots of channels as well as
agents. The modified algorithm doesn't mention channels.
Next, we address these two differences.
Late arrivals of markers don't matter for the purposes of detecting
termination. If computation has terminated then agents will be idle
when markers arrive, regardless of when they arrive. Likewise, the
algorithm records channel states as empty, regardless of when markers
arrive.
If \(x\) receives no messages after it takes its local snapshot and
before receiving markers on all its incoming channels then all its
incoming channels are empty. Statement 4 identifies the computation as
not terminated when \(x\) receives a message.
Communication Deadlock Detection
Communication deadlock is identical to termination detection with one
difference. An idle agent in
termination detection becomes active if it receives a message from
any
agent. By contrast, in the communication deadlock problem, an idle
agent becomes active only if receives
a message from a set of agents
for which it is waiting.
An earlier
module
on deadlock detection developed algorithms to detect deadlock when
an idle agent became active only if it received messages or resources
from
all the agents for which it is waiting. In the
communication-deadlock case, an
idle agent became active if it receives messages
from
any of the agents for which it is waiting.
Problem Specification
An agent is either
active or
waiting.
Associated with each waiting agent \(x\) is a non-empty set
\(x.waits\) of agents;
\(x\) becomes active if it receives a message
from any agent in \(x.waits\), and \(x\) remains waiting if it
receives a message from an agent that is not in \(x.waits\).
A waiting agent does not send messages.
Active agents may send messages.
The Algorithm
The algorithm for communication deadlock detection is the same as that
for termination detection except that the network is restricted to
agents that are waiting. The network has a channel between a pair of
agents if either agent in the pair is waiting for the other.
Review
-
Modify the algorithm to count the number of red agents to count
agents of all colors. Assume that colors of agents don't change.
-
Now consider the case where each agent is either red or blue. A blue
agent can become red. A red agent does not change its color. Develop
an algorithm to obtain a lower bound on the number of red agents and
an upper bound on the number of blue agents. The algorithm should
get good bounds. (Obviously 0 is a lower bound and N, the number of
agents is an upper bound.)
K. Mani Chandy,
Emeritus Simon Ramo Professor,
California Institute of Technology