Jan 30

AXUM PART ONE

Editor’s Note: most of the information provided below comes from the Axum Programmers Guide.. It is my only source of material at the moment, so please follow along with the article and start to imagine the possibilities.

http://msdn.microsoft.com/en-us/devlabs/dd795202

image

What is Axum ?

From the Axum Programmers Guide:

“Writing a parallel program typically requires partitioning the solution into a number of parallel tasks. Some problems are easily amenable to parallelization because the tasks can run independently of each other. In other problems the tasks have interdependencies and require coordination..

….With Axum, we offer a language that allows programmers to arrange coordination between components in a way that is close to their natural conception of the solution. In other words, if you can model your solution in terms of interactive components, encoding it in Axum will be straightforward, and you will likely avoid many common concurrency-related bugs.


An obvious motivation for writing a parallel program is to make it run faster. Closely related to that is a desire to make the program do more while it’s running. This is especially important for interactive applications that must process user input while performing a background task.


Very often, responsiveness of interactive applications is hindered by long-latency components such as I/O or user input. For example, an email client must wait for the data from the server, which might be behind a slow network. It is desirable that such an application remains responsive while requesting data from the server.


One of the goals of Axum is to let you program without worrying about concurrency – your program becomes fast and responsive by default, not as a result of an afterthought or a retrofit.


In addition to enabling the new capabilities for working with concurrency, Axum takes away one capability that historically has proven to cause problems – that is unrestricted ability to share and mutate state from different threads. Axum isolation model ensures “disciplined” access to shared state that prevents many common programming errors.
Finally, please remember that Axum is an experiment. We want to make it better and we need to know what you think. We will appreciate your comments about the language, and how you think you can use it for building your own software. Please share your thoughts, comments and suggestions with us and your fellow Axum users via MSDN forums at http://social.msdn.microsoft.com/Forums/en/axum. “

Agents and Asynchronous Programming

Hello World Axum Style

   1:  using System;
   2:  agent Program : Microsoft.Axum.ConsoleApplication
   3:  {
   4:  override int Run(String[] args)
   5:  {
   6:  Console.WriteLine("Hello, World!");
   7:  }
   8:  }


The program starts with the keyword agent. The concept of an agent in Axum derives from what is known in computer science as the “actor model”. In this model, actors represent autonomous entities that communicate with each other via messages, act on the data they receive from other actors, spawn off other actors and so on.
In Axum, actors are represented by agents. Writing a program in Axum is all about defining agents and arranging interaction between them.
Agent-based programming is different from object-oriented programming in many important ways. First of all, unlike objects, agents do not provide public methods or exhibit their state. You cannot “reach into” an agent and modify any of its fields. You cannot call a method on an agent and wait for it complete. Instead, you can send it a message, and arrange for the agent to “get back to you” with a response.

Being a .NET language, Axum can naturally use libraries written in any other .NET language such as C#, VB.Net or F#.

Message Passing (Ports, Asnyc , and Derivation)

Agents are components that perform actions on data – that data normally comes in and goes out of the agent via a channel. To accommodate different types of data, a channel has one or more ports.

   1:  using System;
   2:  agent Program : channel Microsoft.Axum.Application
   3:  {
   4:  public Program()
   5:  {
   6:  // Receive command line arguments from port CommandLine
   7:  String [] args = receive(PrimaryChannel::CommandLine);
   8:  // Send a message to port ExitCode:
   9:  PrimaryChannel::ExitCode <-- 0;
  10:  }
  11:  }

 

Channels versus Derived Agents

Implementing a channel is different – syntactically and semantically – from deriving from a base agent. When an agent derives from another agent, it extends it by overriding some virtual methods, and potentially adding more of its own.

When an agent implements a channel, it “attaches” itself to the implementing end of that channel and becomes the “server” of messages on that channel.

The other or the using end of the channel is only visible to the “client”, or the component (typically another agent) on the other end of the channel.

image

Channels exist to transmit messages between agents. Channels define what kind of data can go into and out of them, but unlike agents, they don’t perform any transformation of that data.

Semantics of Axum Messages

Axum offers two distinct approaches to orchestration: control-flow-based and data-flow-based orchestration. Often, the two are combined for ultimate expressiveness and power.

Messages are sent to and received from the interaction points. An interaction point from which a message originates is called the source, and the destination is called the target. An interaction point can be both a source and a target, meaning that it can both send and receive messages. This allows composition of multiple interaction points into dataflow networks.  A dataflow network is a messaging construct that receives data, does something with it – in other words, performs a transformation – and produces a result.

Dataflow Networks with Calculations

Fibonacci in Axum

This example can be found more in-depth in the Axum Programmers Guide, with much better coverage than I am giving it which is here to explain dataflow networks in parallel..

   1:  using System;
   2:  using Microsoft.Axum;
   3:  using System.Concurrency.Messaging;
   4:  agent MainAgent : channel Microsoft.Axum.Application
   5:  {
   6:  function int Fibonacci(int n)
   7:  {
   8:  Independent nodes in a dataflow network can execute concurrently
   9:  8
  10:  if( n<=1 ) return n;
  11:  return Fibonacci(n-1) + Fibonacci(n-2);
  12:  }
  13:  int numCount = 10;
  14:  void ProcessResult(int n)
  15:  {
  16:  Console.WriteLine(n);
  17:  if( --numCount == 0 )
  18:  PrimaryChannel::ExitCode <-- 0;
  19:  }
  20:  public MainAgent()
  21:  {
  22:  var numbers = new OrderedInteractionPoint<int>();
  23:  // Create pipeline:
  24:  numbers ==> Fibonacci ==> ProcessResult;
  25:  // Send messages to numbers:
  26:  for( int i=0; i<numCount; i++ )
  27:  numbers <-- 42-i;
  28:  }
  29:  }

 

This example of a dataflow network is a messaging construct that receives data, does something with it – in other words, performs a transformation – and produces a result. Using a dataflow network can be advantageous if some nodes of the network are independent of each other and therefore can execute concurrently.

The Parallel Approach aka “Pipelines”
Unlike control-flow logic that is based on conditional statements, loops, and method calls, data-flow networks base their logic on forwarding, filtering, broadcasting, load-balancing, and joining messages that pass through the network. It’s a different and complementary approach to handling messages.  Dataflow networks that forward messages from one node to another are commonly called pipelines.

Specifying how the data travels through the network and datatypes

“The two agents communicating over a channel are decoupled from each other: one doesn’t know or care how the other one is implemented. The “contract” between them is specified by the channel only. To borrow an analogy from the OOP, the channel acts as an interface, and the agent as the class implementing the interface..”

A Mailbox  like System

When using a channel, you send data into the input ports, and receive data from the output ports. That is, input ports act as targets, and output ports as sources.
When implementing a channel, the input ports are seen as sources and the output ports as targets.

Schemas in Axum

A schema is a type that defines required and/or optional fields, but no methods. The concept is very similar to XML schema. When an instance of a schema crosses a process or computer boundary in a message, the data payload is deeply serialized. You can only declare fields in schema whose types can be serialized using .NET-serialization. When the message is sent locally (in-process), deep serialization is not required – however the fields in the schema are considered immutable. Schemas are declared with the keyword schema, followed by the schema’s name, followed by a semicolon-separated list of fields enclosed in curly-braces:

   1:  schema Customer
   2:  {
   3:  required string Name;
   4:  optional string Address;
   5:  }

Required and the optional fields allows for loose coupling between different schemas, or between schemas and different types with the same “shape”. This is important when the communicating parties cannot all use the same type of schema.

A type can be converted (or coerced) to another type of the same shape using the coerce operator.

   1:  class CustomerData
   2:  {
   3:  public string Name;
   4:  }

 

An instance of schema Customer can be coerced to type CustomerData, even though it is missing the optional field Address:

   1:  Customer c = new Customer{Name = "Artur", Address = "One Microsoft Way"};
   2:  CustomerData cd = coerce<CustomerData>(c);

 

Schemas are also helpful when combining different data types into a single container type, instances of which can be sent in one message.

Request-reply ports

Sending a message to a request-reply port returns a correlator, from which you receive the requested value. Request-reply ports allow more than one request to be processed, we this gives more time while these requests are being processed.

Protocols

A channel works by specifying the channel’s protocol. The protocol is a finite state machine, with states and transitions between those states defined by the designer of the channel.

The protocol always starts in a special state called Start. When a new message arrives on any of the channel ports, the protocol can either transition to another valid state – if that transition is specified in the protocol – or trigger a protocol violation exception if no valid transition exists.

   1:  channel Adder
   2:  {
   3:  input int Num1;
   4:  input int Num2;
   5:  output int Sum;
   6:  Start: { Num1 -> GotNum1; }
   7:  GotNum1: { Num2 -> GotNum2; }
   8:  GotNum2: { Sum -> End; }
   9:  }

Domains and State Sharing

Domains allow agents to share state with one another.  Like regular classes, domains can contain fields and methods, but more importantly, domain declarations can include agent declarations. The instances of agents declared within a domain can access that domain’s fields.

Message-passing requires the data in the message to be either deeply copied or immutable. Sometimes it is more efficient, or simpler, to let agents share the data safely. A domain allows a group of agents to safely share state, at the same time isolating that state from everyone else.

   1:  domain Chatroom
   2:  {
   3:  private string m_Topic;
   4:  private int m_UserCount;
   5:  reader agent User : channel UserCommunication
   6:  {
   7:  // ...
   8:  }
   9:  writer agent Administrator : channel AdminCommunication
  10:  {
  11:  // ...
  12:  }
  13:  }

 

In this example from the programmers guide, there are  two types of agents – the User and the Administrator. The chatroom lets multiple users exchange messages with each other (or with the administrator), and read domain state. There is no change to the domain state. The administrator is the only type of agent that can modify domain state in the example.

Read/Write locks and Synchronization

An agent declared with the reader keyword is only allowed to read domain state, while writer agents can both read and write the state. An agent declared as neither reader nor writer can only read the non-changing state of the domain.

the enclosing domain’s fields and methods can be accessed via the parent keyword

   1:  reader agent User : channel UserCommunication
   2:  {
   3:  public User()
   4:  {
   5:  if( parent.m_Topic.Contains("Axum") )
   6:  {
   7:  // Start talking to other users in this chatroom
   8:  }
   9:  else
  10:  {
  11:  // Do nothing and leave
  12:  }
  13:  }
  14:  }

The keyword parent is only required when you need to disambiguate between domain members and other symbols with the same name. Agents are similarly restricted from mutating the global state of the system.

An agent cannot write to a static field or call a method that can (even potentially) modify a static field.  Code  may not compile until you mark the agent as writer, or mark the class isolated. Writer agents within the same domain cannot execute in parallel. An application with a single domain where all agents are declared as writers is effectively single-threaded.

you execute code that potentially modifies shared state – the unsafe keyword. As the name suggests, using unsafe is, well, not safe, and you should only use it if you know for sure that the code either does not modify shared state, or such modification is benign.

   1:  reader agent User : channel UserCommunication
   2:  {
   3:  private WriteLog(string str)
   4:  {
   5:  unsafe
   6:  {
   7:  Logger.WriteLine(str);
   8:  }
   9:  }
  10:  }


Hosting Agents

Hosting associates the agent type with the domain and the address. An agent is a service that implements a channel. Multiple agents types can implement the same channel type.When the service provided by the agent is no longer required, the agent type can be evicted from the domain:

   1:  Evict("myAgent");

 

Axum Benefits

Axum certainly has a lot of benefits over the traditional methodologies and a solid asynchronous foundation enabling parallel programming. What might this be useful for though ?  Well lets talk about predictability algorithms for a moment. Let’s use belief propagation and see how this new “style” of computing might benefit something like this..

Belief Propagation hits a home run with Axum

Belief propagation is a message passing algorithm for performing inference on graphical models, such as Bayesian networks and Markov random fields. It calculates the marginal distribution for each unobserved node, conditional on any observed nodes.

Belief propagation is commonly used in artificial intelligence and information theory and has demonstrated empirical success in numerous applications including low-density parity-check codes, turbo codes, free energy approximation, and satisfy ability.

One well known and semi recent use of belief propagation:

Efficient Belief Propagation for Early Vision -
Pedro F. Felzenszwalb and Daniel P. Huttenlocher
International Journal of Computer Vision, Vol. 70, No. 1, October 2006

image

 

The original algorithm was first proposed by Judea Pearl in 1982, Who formulated this algorithm on trees, and was later extended to poly trees. It has since been shown to be a useful approximate algorithm on general graphs.

If X=(Xv) is a set of discrete random variables with a joint mass function p, the marginal distribution of a single Xi is simply the summation of p over all other variables:

image

Belief propagation algorithms are normally presented as messages update equations on a factor graph, involving messages between variable nodes and their neighboring factor nodes and vice versa. Messages between regions in a graph is one way of generalizing the belief propagation algorithm.

This is just one example of where the parallel advantages of Axum and use would be translate very well to code. Belief propagation algorithms are normally presented as messages update equations on a factor graph, involving messages between variable nodes and their neighboring factor nodes and vice versa.

Considering messages between regions in a graph is one way of generalizing the belief propagation algorithm, it is not a stretch of the imagination, that this could fit well plugged into Axum .This could potentially increase the algorithms performance and scalability for many applications.