0% found this document useful (0 votes)
64 views

Ibis Tutorial

This document provides an overview of the Ibis communication library. Ibis aims to provide portable communication across heterogeneous grid environments by using Java. It has a flexible communication model based on send and receive ports that can support various connection types. Ibis provides different programming models on top of its core portability layer, including RMI, group communication, and bindings to MPI. The document discusses Ibis' design, programming models, and features like serialization.

Uploaded by

Adama Emmanuel
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
64 views

Ibis Tutorial

This document provides an overview of the Ibis communication library. Ibis aims to provide portable communication across heterogeneous grid environments by using Java. It has a flexible communication model based on send and receive ports that can support various connection types. Ibis provides different programming models on top of its core portability layer, including RMI, group communication, and bindings to MPI. The document discusses Ibis' design, programming models, and features like serialization.

Uploaded by

Adama Emmanuel
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 129

Ibis tutorial

&
hands-on session
Jason Maassen
[email protected]

Thursday 13 October 2005


Sophia Antipolis
Overview

● Philosophy / design / implementation


● Why do we need Ibis ?
● Ibis design
● Performance
● Cool features
Overview

● Programming models
● IPL (bare bones Ibis)
● RMI (remote invocation)
● GMI (group communication)
● Satin (divide and conquer)
● MPJ (MPI to Java binding)

● Hands-on session
● How to roll your own Ibis applications
We are interested in...

● Parallel applications on “the Grid”


● Single site runs
● Grid == big collection of clusters
● Only communicate within cluster
● Use fast local network (Myrinet/Infiniband/...)

● Multi site runs


● Grid == big processor pool
● Communicate between clusters
● Use regular network & internet
So why Ibis?

● Ideally, grid computing should be “fire


and forget”
● Develop application locally
● Submit to some grid scheduler which
● Finds some suitable site(s)
● Transfers your application and data to the
sites, and runs it.
● Returns the result
Problems

● Lots of problems
● Resource selection
● Data transfer
● Security and authentication
● ...
● Heterogeneity

● Globus, Gridlab (GAT), etc.


Problems
● Grids are heterogeneous:
● Intel / PowerPC / Mips / Arm / ...
● Windows / Linux / Unix / OSX / ...
● Different OS/library/tool versions

● Compiled (C/MPI) apps. huge pain:


● Need executable for every combination of
CPU/network/OS/libraries etc.
● Makes 'fire & forget' runs really hard...
Solution (partly)

● So, we use Java instead C or Fortran


● No recompilation required
● Runs (almost) anywhere
● Doesn't work on supercomputers (Hitachi
SR8000, IBM BlueGene, etc.)
● Most sites have clusters anyway
● Acceptable performance

● But ... only part of the solution!


How about 'portable'
communication?
● Class libraries are portable, but ...
● Sockets are too low-level
● RMI model/performance is limited

● Most parallel libraries not portable ...


● MpiJava requires native code
● recompilation
● no malleable runs
Ibis

● Solution: Ibis !
● A “run-anywhere” communication library
● Just send it along with your application!

● Flexible communication models


● More than just unicast communication
● More about this later
● Malleability & Fault-Tolerance
● Change number of machines during the run
Ibis

● Portability vs. performance


● On a single site run you often want to use
the fast local network

● Ibis allows specialized implementation


● Designed for Myrinet, Infiniband, etc.
● Usually use native code
● Installed in advance
● not portable
● cannot be shipped with application
Ibis

● As a result, there may be multiple Ibis'


available on a site
● Automatically choose 'best' at startup
● Based on requirements specified by
● Application & user (using properties)

● Not every impl. needs all features


● Pick one at startup that suits your needs....
Ibis Design

Ibis Portability Layer (IPL)


Ibis Design

Ibis Portability Layer (IPL)

TCP UDP P2P


Ibis Design

Ibis Portability Layer (IPL)

TCP UDP P2P GM Panda MPI


Ibis Design

RMI GMI Satin MPJ RepMI

Ibis Portability Layer (IPL)

TCP UDP P2P GM Panda MPI


Ibis Design

RMI GMI Satin MPJ RepMI

Ibis Portability Layer (IPL)

TCP UDP P2P GM Panda MPI


Ibis Design

Application

RMI GMI Satin MPJ RepMI

Ibis Portability Layer (IPL)

TCP UDP P2P GM Panda MPI


Ibis Design
Application

ProActive

RMI GMI Satin MPJ RepMI

Ibis Portability Layer (IPL)

TCP UDP P2P GM Panda MPI


Ibis Portability Layer

● Basic Ibis interface


● Reasonably simple (5 classes & 12 interf.)

● Contains methods for


● Loading an Ibis
● Malleability (adding & removing machines)
● Connection handling
● Communication primitives (low-level)
IPL Communication

● 'Low-level' communication model


● Unidirectional pipes
● Two end points
● Connection oriented

send receive
port port
Send & receive ports

● Can be connected in arbitrary ways


Send & receive ports

● Can be connected in arbitrary ways


● One to one (unicast) ...
Send & receive ports

● Can be connected in arbitrary ways


● ... one to many (multicast) ...
Send & receive ports

● Can be connected in arbitrary ways


● ... many to one ...
Send & receive ports

● Can be connected in arbitrary ways


● ... or some combination!
Send & receive ports

● Advantages:
● Very simple & abstract model
● Easy to implement using TCP/UDP/MPI/etc.
● Allows multicast, many-to-one, etc.
● Useful for parallel programs
● Allows efficient implementation
● Can be implemented using efficient low-level
primitives (i.e., mpi-broadcast)
● Other models do prevent this (e.g., RMI)
Send & receive ports

● Disadvantage:
● Simplicity may cause some overhead...
● Example: need two pairs for RPC / RMI
Port Types

● All ports have a type consisting of:


● Unique name
● Set of properties, e.g.:
● Supports unicast and multicast
● Is Reliable
● Is fifo ordered
● Supports object serialization
● ...
Port Types

● Defined at runtime
● Specify name and set of properties

● Types must match when connecting!

io n!
pt
ce
ex

X
Port Types

● Defined at runtime
● Specify name and set of properties

● Types must match when connecting!

!
ok

Port Types

● Forces programmer to specify how


each communication channel is used
● Prevents bugs
● Exception when contract is breached

● Allows efficient impl. to be selected


● Unicast only ?
● Bytes only ?
● Saves a lot of overhead!
Connection setup

● Need the ReceivePortIdentifier


● Uniquely identifies a receiveport

● Created when ReceivePort is created

● May also have unique name (String)


● Human-readable (usually)
● Use for registry lookup
Connection setup

Create ReceivePort
“server”
Connection setup

Registry

register(“server”)
Connection setup

Registry

lookup(“server”)
Connection setup

Registry

ID
Connection setup

Registry

connect
Connection setup

● Advantage of ReceivePortIdentifiers
● Hides implementation details
● Independent of
● IP-addresses
● Host names
● Port numbers
● MPI-ranks
● etc...

● Abstract way of addressing


Messages

● Ports communicate using 'messages'

● Contain read or write methods for


● Primitive types (byte, int, ...)
● Object
● Arrays slices (partial write / read in place)

● Unlimited message size


Messages

● Get WriteMessage from SendPort

WM
Messages

● Write data into WriteMessage

WM
Messages

● Finish the WriteMessage

WM
Messages

● Data is send to ReceivePort


Messages

● ReceivePort produces ReadMessage


● Explicit receive or callback (upcall)

RM
Messages

● Read data from ReadMessage

RM
Messages

● Finish the ReadMessage

RM
Messages

● Done!
Messages or streams ?

● Message size is unlimited


● Data may be forwarded at any time
● Both S. & R. messages alive at same time
● There's streaming!

WM RM
Restrictions

● Must write and read data in same order

● A port can have only one message


'alive' at a time

● Not thread safe (but ports are)

● If there is no receiver, the sender may


block (there may be flow-control)
Serialization

● Ibis supports 4 types of serialization


● Bytes (i.e., no serialization at all)
● Data (only primitive types/arrays)
● Sun (standard Sun serialization)
● Ibis (efficient Ibis serialization)

● To select one of the last two use


'Object'
Ibis Serialization

● Based on bytecode-rewriting
● Adds serialization and deserialization code
to serializable types
● Prevents reflection overhead during
(de-)serialization
● Has fallback mechanism for non-rewritten
classes

● Future work: runtime rewriting


Short Recap

● First create PortType


● PortType creates Send & ReceivePort
● Type is checked when connecting
● Use ReceivePortID's to connect
● Abstact addressing
● Use Messages to communicate
● Allows streaming
● 4 types of serialization
Creating an Ibis

● First step in application


● IPL is only abstract classes & interfaces

● Ibis selects implementation for you


● Multiple may be available
● Selected on the basis of properties
● Specify the needs of the application
Selecting an Ibis

Properties:
closed world
data ser.
explicit rec.
unicast

Ibis.createIbis(...)
Selecting an Ibis

Ibis.createIbis( ) Find all Ibis


Properties:
closed world
data ser.
explicit rec.
unicast

implementations

MPI-Ibis
TCPIbis .jar PandaIbis
application local disk
jar files
Selecting an Ibis

Ibis.createIbis( ) Select 'best'


Properties:
closed world
data ser.
explicit rec.
unicast

implementation

MPI-Ibis
TCPIbis .jar PandaIbis
application local disk
jar files
Selecting an Ibis

Ibis
return new MPI-Ibis
instance class

Ibis.createIbis( )
Properties:
closed world
data ser.
explicit rec.
unicast
Properties

● Usual Java properties


● Set of key-value pairs
● “serialization”, “object”
● “communication”, “OneToOne”
● “worldmodel”, “open”

● Very flexible
● good and bad
Properties

● Good
● Introduce features without IPL changes
● Just add more properties
● Allows impl. specific properties

● Bad
● No compile time checks (only runtime)
● Just strings
● Sensitive to typos
Example
Property Values Description

Worldmodel Open Support malleability


Closed Fixed set of machines
Serialization Byte
Data
Object
Communication OneToOne
OneToMany
ManyToOne
ExplicitReceive Support explicit rec.
AutoMessageUpcalls Automatic callback
PollingMessageUpcalls Callback triggered by
polling
ConnectionUpcalls Callback when machines
join or leave
Example

Ibis
Property TCP Panda MPI
Worldmodel Open Closed Closed
Serialization B/D/O B/D/O B/D/O
Communication OO/OM/MO OO/OM/MO OO/OM/MO
Explicit receive Yes Yes Yes
AutoMessageUpcalls Yes Yes No
PollingMessageUpcalls Yes Yes No
ConnectionUpcalls Yes Yes Yes
ConnectionDowncalls Yes No No
Malleability

● Ibis can notify the application if a


machine joins or leaves
● Callbacks/upcalls to a 'ResizeHandler'
● Calls are delivered in the same order on all
machines

● Each 'Ibis' has a unique IbisIdentifier


● Abstract identification of the machine
● Impl. using IP-addresses / MPI-ranks / etc.
Elections

● Ibis offers an 'election' mechanism


● Allows a group of machines to determine
who's in charge

● Each election
● Has a name (String)
● Produces an IbisIdentifier identifying the
winner
● Is not democratic
Other cool features

● TCP Ibis supports


● Parallel streams
● For high-latency & high-bandwidth links

● NAT / firewall traversal


● TCP splicing
● Routing messages through external point
Code example
import ibis.ipl.*;

public class Example {

public static void main(String args[]) throws Exception {

// Step 1: create ibis


StaticProperties p1 = new StaticProperties();
p1.add("communication", "OneToOne, Reliable, ExplicitReceipt");
p1.add("serialization", "object");

Ibis ibis = Ibis.createIbis(p1, null);

// Step 2: create porttype


PortType type = ibis.createPortType("Test Type", p1);

// Step 3: elect server


Registry reg = ibis.registry();
IbisIdentifier server = reg.elect("Server");
boolean amServer = server.equals(ibis.identifier());

if (amServer) {
// Step 4, create port
ReceivePort rp = type.createReceivePort("server");
rp.enableConnections();

// Step 5, receive message and read data


ReadMessage rm = rp.receive();
String tmp = (String) rm.readObject();
rm.finish();

System.out.println("Client says: " + tmp);

// Step 6, close port


rp.close();
} else {

// Step 4, create port, find receivePort and connect


SendPort sp = type.createSendPort();
sp.connect(reg.lookupReceivePort("server"));

// Step 5, get message and write data


WriteMessage wm = sp.newMessage();
wm.writeObject("Hello World");
wm.finish();

// Step 6, close port


sp.close();
}

ibis.end();
}
}
Code example
import ibis.ipl.*;

public class Example {

public static void main(String args[]) throws Exception {

// Step 1: create ibis


StaticProperties p1 = new StaticProperties();
p1.add("communication", "OneToOne, Reliable, ExplicitReceipt");
p1.add("serialization", "object");

Ibis ibis = Ibis.createIbis(p1, null);

// Step 2: create porttype


PortType type = ibis.createPortType("Test Type", p1);

// Step 3: elect server


Registry reg = ibis.registry();
IbisIdentifier server = reg.elect("Server");
boolean amServer = server.equals(ibis.identifier());

if (amServer) {

// Step 1: create ibis
// Step 4, create port
ReceivePort rp = type.createReceivePort("server");
rp.enableConnections();

StaticProperties p1 = new StaticProperties();
// Step 5, receive message and read data
ReadMessage rm = rp.receive();

p1.add("communication", "OneToOne, Reliable, ExplicitReceipt");
String tmp = (String) rm.readObject();
rm.finish();

p1.add("serialization", "object"); System.out.println("Client says: " + tmp);

// Step 6, close port


rp.close();
} else {

Ibis ibis = Ibis.createIbis(p1, null); // Step 4, create port, find receivePort and connect


SendPort sp = type.createSendPort();
sp.connect(reg.lookupReceivePort("server"));

// Step 5, get message and write data


WriteMessage wm = sp.newMessage();
wm.writeObject("Hello World");
wm.finish();

// Step 6, close port


sp.close();
}

ibis.end();
}
}
Code example
import ibis.ipl.*;

public class Example {

public static void main(String args[]) throws Exception {

// Step 1: create ibis


StaticProperties p1 = new StaticProperties();
p1.add("communication", "OneToOne, Reliable, ExplicitReceipt");
p1.add("serialization", "object");

Ibis ibis = Ibis.createIbis(p1, null);

// Step 2: create porttype


PortType type = ibis.createPortType("Test Type", p1);

// Step 3: elect server


Registry reg = ibis.registry();
IbisIdentifier server = reg.elect("Server");
boolean amServer = server.equals(ibis.identifier());

if (amServer) {
// Step 4, create port
ReceivePort rp = type.createReceivePort("server");
rp.enableConnections();

// Step 2: create porttype  // Step 5, receive message and read data


ReadMessage rm = rp.receive();

PortType type = ibis.createPortType("Test Type", p1);
String tmp = (String) rm.readObject();
rm.finish();

System.out.println("Client says: " + tmp);

// Step 6, close port


rp.close();
} else {

// Step 4, create port, find receivePort and connect


SendPort sp = type.createSendPort();
sp.connect(reg.lookupReceivePort("server"));

// Step 5, get message and write data


WriteMessage wm = sp.newMessage();
wm.writeObject("Hello World");
wm.finish();

// Step 6, close port


sp.close();
}

ibis.end();
}
}
Code example
import ibis.ipl.*;

public class Example {

public static void main(String args[]) throws Exception {

// Step 1: create ibis


StaticProperties p1 = new StaticProperties();
p1.add("communication", "OneToOne, Reliable, ExplicitReceipt");
p1.add("serialization", "object");

Ibis ibis = Ibis.createIbis(p1, null);

// Step 2: create porttype


PortType type = ibis.createPortType("Test Type", p1);

// Step 3: elect server


Registry reg = ibis.registry();
IbisIdentifier server = reg.elect("Server");
boolean amServer = server.equals(ibis.identifier());

if (amServer) {
// Step 4, create port
ReceivePort rp = type.createReceivePort("server");
rp.enableConnections();

// Step 5, receive message and read data


ReadMessage rm = rp.receive();
String tmp = (String) rm.readObject();

// Step 3: elect server rm.finish();

System.out.println("Client says: " + tmp);


Registry reg = ibis.registry(); // Step 6, close port

IbisIdentifier server = reg.elect("Server");
rp.close();
} else {

boolean amServer = server.equals(ibis.identifier());
// Step 4, create port, find receivePort and connect
SendPort sp = type.createSendPort();
sp.connect(reg.lookupReceivePort("server"));

// Step 5, get message and write data


WriteMessage wm = sp.newMessage();
wm.writeObject("Hello World");
wm.finish();

// Step 6, close port


sp.close();
}

ibis.end();
}
}
Code example
import ibis.ipl.*;

public class Example {

public static void main(String args[]) throws Exception {

// Step 1: create ibis


StaticProperties p1 = new StaticProperties();
p1.add("communication", "OneToOne, Reliable, ExplicitReceipt");
p1.add("serialization", "object");

Ibis ibis = Ibis.createIbis(p1, null);

// Step 2: create porttype


PortType type = ibis.createPortType("Test Type", p1);

// Step 3: elect server


Registry reg = ibis.registry();
IbisIdentifier server = reg.elect("Server");
boolean amServer = server.equals(ibis.identifier());

if (amServer) {
// Step 4, create port
ReceivePort rp = type.createReceivePort("server");
rp.enableConnections();

// Step 5, receive message and read data


ReadMessage rm = rp.receive();
String tmp = (String) rm.readObject();
rm.finish();

System.out.println("Client says: " + tmp);

// Step 6, close port


if (amServer) {  } else {
rp.close();

         // Step 4, create port     
// Step 4, create port, find receivePort and connect
SendPort sp = type.createSendPort();

         ReceivePort rp = type.createReceivePort("server");
sp.connect(reg.lookupReceivePort("server"));

// Step 5, get message and write data


         rp.enableConnections(); WriteMessage wm = sp.newMessage();
wm.writeObject("Hello World");
wm.finish();

// Step 6, close port


sp.close();
}

ibis.end();
}
}
Code example
import ibis.ipl.*;

public class Example {

public static void main(String args[]) throws Exception {

// Step 1: create ibis


StaticProperties p1 = new StaticProperties();
p1.add("communication", "OneToOne, Reliable, ExplicitReceipt");
p1.add("serialization", "object");

Ibis ibis = Ibis.createIbis(p1, null);

// Step 2: create porttype


PortType type = ibis.createPortType("Test Type", p1);

// Step 3: elect server


Registry reg = ibis.registry();
IbisIdentifier server = reg.elect("Server");
boolean amServer = server.equals(ibis.identifier());

if (amServer) {
// Step 4, create port

// Step 4, create port, find receivePort and connect  
ReceivePort rp = type.createReceivePort("server");
rp.enableConnections();

SendPort sp = type.createSendPort(); // Step 5, receive message and read data


ReadMessage rm = rp.receive();
String tmp = (String) rm.readObject();

sp.connect(reg.lookupReceivePort("server"));
rm.finish();

System.out.println("Client says: " + tmp);

// Step 6, close port


rp.close();
} else {

// Step 4, create port, find receivePort and connect


SendPort sp = type.createSendPort();
sp.connect(reg.lookupReceivePort("server"));

// Step 5, get message and write data


WriteMessage wm = sp.newMessage();
wm.writeObject("Hello World");
wm.finish();

// Step 6, close port


sp.close();
}

ibis.end();
}
}
Code example
import ibis.ipl.*;

public class Example {

public static void main(String args[]) throws Exception {

// Step 1: create ibis


StaticProperties p1 = new StaticProperties();
p1.add("communication", "OneToOne, Reliable, ExplicitReceipt");
p1.add("serialization", "object");

Ibis ibis = Ibis.createIbis(p1, null);

// Step 2: create porttype


PortType type = ibis.createPortType("Test Type", p1);

// Step 3: elect server


Registry reg = ibis.registry();
IbisIdentifier server = reg.elect("Server");
boolean amServer = server.equals(ibis.identifier());

if (amServer) {
// Step 4, create port

// Step 5, get message and write data
ReceivePort rp = type.createReceivePort("server");
rp.enableConnections();

WriteMessage wm = sp.newMessage(); // Step 5, receive message and read data


ReadMessage rm = rp.receive();
String tmp = (String) rm.readObject();
wm.writeObject("Hello World"); rm.finish();

wm.finish();
System.out.println("Client says: " + tmp);

// Step 6, close port


rp.close();
} else {

// Step 4, create port, find receivePort and connect


SendPort sp = type.createSendPort();
sp.connect(reg.lookupReceivePort("server"));

// Step 5, get message and write data


WriteMessage wm = sp.newMessage();
wm.writeObject("Hello World");
wm.finish();

// Step 6, close port


sp.close();
}

ibis.end();
}
}
Code example
import ibis.ipl.*;

public class Example {

public static void main(String args[]) throws Exception {

// Step 1: create ibis


StaticProperties p1 = new StaticProperties();
p1.add("communication", "OneToOne, Reliable, ExplicitReceipt");
p1.add("serialization", "object");

Ibis ibis = Ibis.createIbis(p1, null);

// Step 2: create porttype


PortType type = ibis.createPortType("Test Type", p1);

// Step 3: elect server


Registry reg = ibis.registry();
IbisIdentifier server = reg.elect("Server");
boolean amServer = server.equals(ibis.identifier());

if (amServer) {
// Step 4, create port
ReceivePort rp = type.createReceivePort("server");
rp.enableConnections();

// Step 5, receive message and read data


ReadMessage rm = rp.receive();
String tmp = (String) rm.readObject();
rm.finish();

System.out.println("Client says: " + tmp);

// Step 6, close port


rp.close();
} else {

// Step 5, receive message and read data
// Step 4, create port, find receivePort and connect
SendPort sp = type.createSendPort();

ReadMessage rm = rp.receive();
sp.connect(reg.lookupReceivePort("server"));

// Step 5, get message and write data

String tmp = (String) rm.readObject();
WriteMessage wm = sp.newMessage();
wm.writeObject("Hello World");
wm.finish();

rm.finish(); // Step 6, close port


sp.close();
}

System.out.println("Client says: " + tmp);
ibis.end();
}
}
Code example
import ibis.ipl.*;

public class Example {

public static void main(String args[]) throws Exception {

// Step 1: create ibis


StaticProperties p1 = new StaticProperties();
p1.add("communication", "OneToOne, Reliable, ExplicitReceipt");
p1.add("serialization", "object");

Ibis ibis = Ibis.createIbis(p1, null);

// Step 2: create porttype


PortType type = ibis.createPortType("Test Type", p1);

// Step 3: elect server


Registry reg = ibis.registry();
IbisIdentifier server = reg.elect("Server");
boolean amServer = server.equals(ibis.identifier());

if (amServer) {

// Step 6, close port
// Step 4, create port
ReceivePort rp = type.createReceivePort("server");
rp.enableConnections();

rp.close();
// Step 5, receive message and read data
ReadMessage rm = rp.receive();
String tmp = (String) rm.readObject();
rm.finish();

System.out.println("Client says: " + tmp);

// Step 6, close port


rp.close();
} else {

// Step 4, create port, find receivePort and connect


SendPort sp = type.createSendPort();
sp.connect(reg.lookupReceivePort("server"));

// Step 5, get message and write data


// Step 6, close port
WriteMessage wm = sp.newMessage();
wm.writeObject("Hello World");

sp.close();
wm.finish();

// Step 6, close port


sp.close();
}

ibis.end();
}
}
Code example
import ibis.ipl.*;

public class Example {

public static void main(String args[]) throws Exception {

// Step 1: create ibis


StaticProperties p1 = new StaticProperties();
p1.add("communication", "OneToOne, Reliable, ExplicitReceipt");
p1.add("serialization", "object");

Ibis ibis = Ibis.createIbis(p1, null);

// Step 2: create porttype


PortType type = ibis.createPortType("Test Type", p1);

// Step 3: elect server


Registry reg = ibis.registry();
IbisIdentifier server = reg.elect("Server");
boolean amServer = server.equals(ibis.identifier());

if (amServer) {
// Step 4, create port
ReceivePort rp = type.createReceivePort("server");
rp.enableConnections();

// Step 5, receive message and read data


ReadMessage rm = rp.receive();
String tmp = (String) rm.readObject();
rm.finish();

System.out.println("Client says: " + tmp);

// Step 6, close port


rp.close();
} else {

// Step 4, create port, find receivePort and connect


SendPort sp = type.createSendPort();
sp.connect(reg.lookupReceivePort("server"));

// Step 5, get message and write data


WriteMessage wm = sp.newMessage();
wm.writeObject("Hello World");
wm.finish();

// Step 6, close port


sp.close();
}

ibis.end();

ibis.end();
}
}
Code Example

● Live demo
Nameserver

● Used by Ibises to find each other


● Needs to be in a well known place
● Used to implements joins & leaves
● Used to implement Registry
● Supports multiple namespaces
● So 'conflicting' apps can use the same server
Higher level
programming models
● Remote Method Invocation (RMI)
● Group Method Invocation (GMI)
● Satin (Divide & Conquer)
● MPJ (MPI Java 'standard')
● Others are being developed
● Balutek (data parallel)
● Replicated Method Invocation (RepMI)
Satin

● Parallel Divide-and-conquer
● Divide work into independent parts
● Spawn sub-jobs
● Combine sub-results
● Repeat recursively
● Master-Worker is a subset of this
● Only one level of recursion
● Targeted at the grid (and clusters)
Sequential Fibonacci

public long fib(int n) {
        if (n < 2) return n;

        long x = fib(n ­ 1);
        long y = fib(n – 2);
        
        return x + y;
}
Parallel Fibonacci
interface FibInterface extends ibis.satin.Spawnable {
    public long fib(int n);
}
public long fib(int n) {
        if (n < 2) return n;

        long x = fib(n ­ 1);
        long y = fib(n – 2);
        sync();
        return x + y;
}
Parallel Fibonacci
interface FibInterface extends ibis.satin.Spawnable {
    public long fib(int n);
} Mark methods as
public long fib(int n) { Spawnable.
        if (n < 2) return n; They are allowed to

run in parallel.
        long x = fib(n ­ 1);
        long y = fib(n – 2);
        sync();
        return x + y;
}
Parallel Fibonacci
interface FibInterface extends ibis.satin.Spawnable {
    public long fib(int n);
} Mark methods as
public long fib(int n) { Spawnable.
        if (n < 2) return n; They are allowed to

run in parallel.
        long x = fib(n ­ 1);
        long y = fib(n – 2);
Wait until spawned
        sync();
methods are done.
        return x + y;
}
Satin features

● Satin distributes jobs across machines

● Load-balancing is done automatically


● Algorithm has been proven to be optimal
on homogeneous systems
● Additional highly-efficient grid-aware
algorithms
Satin features

● Malleability
● Add/remove machines on the fly

● Fault-tolerance
● When a machine leave suddenly (crashes)
the others continue the computation and
automatically recompute the lost work

● Shared Objects (added recently)


● Allows machines to share 'global data'
Satin Applications

● More interesting applications


● Numerical functions
● N-body simulations
● Game-tree search
● Raytracer
● Satisfiability solver
● Grammar-based text analysis
● Bioinformatics applications
● ...
Ibis RMI

● Replacement for Sun RMI


● Has the same interface
● Used different stub compiler (rmic)
● Generates Ibis specific stubs/skeletons

interface
object
reference

thread
Ibis RMI

● Replacement for Sun RMI


● Has the same interface
● Used different stub compiler (rmic)
● Generates Ibis specific stubs/skeletons
interface

stub skel object


reference

thread

network
Ibis RMI

● Not interoperable with Sun RMI


● uses a different protocol

● No socket factories
● Ibis doesn't have to use sockets!

● No activatable objects
GMI

● Generalized RMI model


● Allows communication with groups
● A single stub refers to an entire group

● Allows more 'advanced' communication


● By offering different ways of forwarding a
method invocation and handling the reply
GMI

● Group
● Contains 1 or more objects
● Fixed size (set when it is created)
● All objects must implement the same
group interface
● But objects may have different type!
● Unique name
● Used in lookup (produces group reference)
● Group members have rank
● Ranks are 'per-group'
GMI Example

group

object

group
interface

reference
object

group
interface
object
GMI Implementation

skel object

interface

stub skel object


reference

skel object
GMI Implementation

JVM 2

skel object

interface

stub skel object


reference
JVM 3
JVM 1

skel object

JVM 4
Group operations

● The group reference can be configured


● How is a method invocation handled
● How is the method result handled
● Configuration per method

● Implemented by selecting different


communication code in the generated
stubs and skeletons
Invocation Schemes
● Single
● Forward to 1 object in group
● Group
● Forward to all objects in group
● Personalized
● Forward to all objects, but personalize
parameters for each target
● Combined
● Combine several invocation into one, then
foward to the group using one of the above
Single

foo()
Single

o o()
f
Group

foo()
Group

o o()
f

foo()

foo(
)
Personalized

foo([1,2,3])
Personalized

( [ 1])
foo

foo([2])

foo(
[ 3])
Combined

foo([1])

foo([2])
Combined

fo
o ([
1]
)
foo([1,2])

)
[ 2]
o(
fo
Combined

] )
1,2
( [
foo
foo([1,2])

foo
([1
,2]
)
Reply handling schemes
● Discard
● Return
● Forward
● Reply is forwarded to a seperate object
● Combine
● Multiple replies are combined into one
● Personalize
● A personalized result is returned to each
participant of a combined invocation
GMI Communication
Operation Invocation Reply
RMI Single Return
Async. RMI Single Discard
Future Single Forward

Broadcast Group Discard


Scatter Personalized Discard
Reduce results Group Combine (binomial)
Gather results Group Combine (flat)

Reduce inv. Combine + Single Discard


Gather inv. Combine + Single Discard
Code example
public interface i_SimpleGroup extends GroupInterface {
    void ping();
}

public class SimpleGroup extends GroupMember implements i_SimpleGroup {

    public SimpleGroup() {
        super();
    }
    
    public void ping() { 
        System.out.println("ping");
    }
}

public class MulticastNoReply {
    public static void main(String[] args) throws Exception {
        
        int rank = Group.rank();
        int size = Group.size();
            
        // Create the group  
        if (rank == 0) { 
            Group.create("GroupNoReply", i_SimpleGroup.class, size);
        } 
            
        // Everyone adds an object 
        SimpleGroup s = new SimpleGroup();              
        Group.join("GroupNoReply", s);
            
        if (rank == 0) {            
            // Perform lookup to get group reference
            i_SimpleGroup g = (i_SimpleGroup) Group.lookup("GroupNoReply");
    
            // Configure reference to perform group invocation
            GroupMethod m = Group.findMethod(g,"void ping()");
            m.configure(new GroupInvocation(), new DiscardReply());
                
            // Perform the invocation  
            g.ping();
        }
            
        // Done
        Group.exit();
    }
}
Code example
public interface i_SimpleGroup extends GroupInterface {
    void ping();
}

public class SimpleGroup extends GroupMember implements i_SimpleGroup {

    public SimpleGroup() {
        super();
    }
public interface i_SimpleGroup extends GroupInterface {
    
    public void ping() { 
    void ping();
        System.out.println("ping");
    }
} }

public class MulticastNoReply {
    public static void main(String[] args) throws Exception {
        
        int rank = Group.rank();
        int size = Group.size();
            
        // Create the group  
        if (rank == 0) { 
            Group.create("GroupNoReply", i_SimpleGroup.class, size);
        } 
            
        // Everyone adds an object 
        SimpleGroup s = new SimpleGroup();              
        Group.join("GroupNoReply", s);
            
        if (rank == 0) {            
            // Perform lookup to get group reference
            i_SimpleGroup g = (i_SimpleGroup) Group.lookup("GroupNoReply");
    
            // Configure reference to perform group invocation
            GroupMethod m = Group.findMethod(g,"void ping()");
            m.configure(new GroupInvocation(), new DiscardReply());
                
            // Perform the invocation  
            g.ping();
        }
            
        // Done
        Group.exit();
    }
}
Code example
public interface i_SimpleGroup extends GroupInterface {
    void ping();
}

public class SimpleGroup extends GroupMember implements i_SimpleGroup {

    public SimpleGroup() {
        super();
    }
    
    public void ping() { 
        System.out.println("ping");
    }
}

public class MulticastNoReply {
    public static void main(String[] args) throws Exception {
        
        int rank = Group.rank();
        int size = Group.size();
            
public class SimpleGroup extends GroupMember implements i_SimpleGroup {
        // Create the group  
        if (rank == 0) { 
            Group.create("GroupNoReply", i_SimpleGroup.class, size);
    public SimpleGroup() {
        } 
            
        super();
        // Everyone adds an object 
        SimpleGroup s = new SimpleGroup();              
    }         Group.join("GroupNoReply", s);
            
             if (rank == 0) {            
            // Perform lookup to get group reference
    public void ping() { 
            i_SimpleGroup g = (i_SimpleGroup) Group.lookup("GroupNoReply");
    
        System.out.println("ping");
            // Configure reference to perform group invocation
            GroupMethod m = Group.findMethod(g,"void ping()");
    }             m.configure(new GroupInvocation(), new DiscardReply());
                
}             // Perform the invocation  
            g.ping();
        }
            
        // Done
        Group.exit();
    }
}
Code example
public interface i_SimpleGroup extends GroupInterface {
    void ping();
}

public class SimpleGroup extends GroupMember implements i_SimpleGroup {

    public SimpleGroup() {
        super();
    }
    
    public void ping() { 
        System.out.println("ping");
    }
}

public class MulticastNoReply {
    public static void main(String[] args) throws Exception {
        
        int rank = Group.rank();
        int size = Group.size();
            
        // Create the group  
        if (rank == 0) { 
            Group.create("GroupNoReply", i_SimpleGroup.class, size);
        } 
public class MulticastNoReply {
            
        // Everyone adds an object 
    public static void main(String[] args) throws Exception {
        SimpleGroup s = new SimpleGroup();              
        Group.join("GroupNoReply", s);
                     
        if (rank == 0) {            
        int rank = Group.rank();
            // Perform lookup to get group reference
            i_SimpleGroup g = (i_SimpleGroup) Group.lookup("GroupNoReply");
        int size = Group.size();
    
            // Configure reference to perform group invocation
            GroupMethod m = Group.findMethod(g,"void ping()");
            m.configure(new GroupInvocation(), new DiscardReply());
                
            // Perform the invocation  
            g.ping();
        }
            
        // Done
        Group.exit();
    }
}
Code example
public interface i_SimpleGroup extends GroupInterface {
    void ping();
}

public class SimpleGroup extends GroupMember implements i_SimpleGroup {

    public SimpleGroup() {
        super();
    }
    
    public void ping() { 
        System.out.println("ping");
    }
}

public class MulticastNoReply {
    public static void main(String[] args) throws Exception {
        
        int rank = Group.rank();
        int size = Group.size();
            
        // Create the group  
        if (rank == 0) { 
            Group.create("GroupNoReply", i_SimpleGroup.class, size);
        } 
            
        // Everyone adds an object 
        SimpleGroup s = new SimpleGroup();              
        Group.join("GroupNoReply", s);
            
        if (rank == 0) {            
// Create the group  
            // Perform lookup to get group reference
            i_SimpleGroup g = (i_SimpleGroup) Group.lookup("GroupNoReply");
if (rank == 0) { 
    
            // Configure reference to perform group invocation
    Group.create("GroupNoReply", i_SimpleGroup.class, size);
            GroupMethod m = Group.findMethod(g,"void ping()");
            m.configure(new GroupInvocation(), new DiscardReply());
}                  
            // Perform the invocation  
            g.ping();
        }
            
        // Done
        Group.exit();
    }
}
Code example
public interface i_SimpleGroup extends GroupInterface {
    void ping();
}

public class SimpleGroup extends GroupMember implements i_SimpleGroup {

    public SimpleGroup() {
        super();
    }
    
    public void ping() { 
        System.out.println("ping");
    }
}

public class MulticastNoReply {
    public static void main(String[] args) throws Exception {
        
        int rank = Group.rank();
        int size = Group.size();
            
        // Create the group  
        if (rank == 0) { 
            Group.create("GroupNoReply", i_SimpleGroup.class, size);
        } 
            
        // Everyone adds an object 
        SimpleGroup s = new SimpleGroup();              
        Group.join("GroupNoReply", s);
            
        if (rank == 0) {            
            // Perform lookup to get group reference
            i_SimpleGroup g = (i_SimpleGroup) Group.lookup("GroupNoReply");
     // Everyone adds an object 
            // Configure reference to perform group invocation
SimpleGroup s = new SimpleGroup();    
            GroupMethod m = Group.findMethod(g,"void ping()");
            m.configure(new GroupInvocation(), new DiscardReply());
Group.join("GroupNoReply", s);
                
            // Perform the invocation  
            
            g.ping();
        }
            
        // Done
        Group.exit();
    }
}
Code example
public interface i_SimpleGroup extends GroupInterface {
    void ping();
}

public class SimpleGroup extends GroupMember implements i_SimpleGroup {

    public SimpleGroup() {
if (rank == 0) {            
        super();
    }
    // Perform lookup to get group reference
    
    public void ping() { 
    i_SimpleGroup g = (i_SimpleGroup) Group.lookup("GroupNoReply");
        System.out.println("ping");
    }
     }

// Configure reference to perform group invocation
public class MulticastNoReply {
    public static void main(String[] args) throws Exception {
GroupMethod m = Group.findMethod(g,"void ping()");
        
        int rank = Group.rank();
m.configure(new GroupInvocation(), new DiscardReply());
        int size = Group.size();
            
                
        // Create the group  
        if (rank == 0) { 
    // Perform the invocation  
            Group.create("GroupNoReply", i_SimpleGroup.class, size);
        } 
    g.ping();
            
        // Everyone adds an object 
}         SimpleGroup s = new SimpleGroup();              
        Group.join("GroupNoReply", s);
            
        if (rank == 0) {            
            // Perform lookup to get group reference
            i_SimpleGroup g = (i_SimpleGroup) Group.lookup("GroupNoReply");
    
            // Configure reference to perform group invocation
            GroupMethod m = Group.findMethod(g,"void ping()");
            m.configure(new GroupInvocation(), new DiscardReply());
                
            // Perform the invocation  
            g.ping();
        }
            
        // Done
        Group.exit();
    }
}
Code example
public interface i_SimpleGroup extends GroupInterface {
    void ping();
}

public class SimpleGroup extends GroupMember implements i_SimpleGroup {

    public SimpleGroup() {
        super();
    }
    
    public void ping() { 
        System.out.println("ping");
    }
}

public class MulticastNoReply {
    public static void main(String[] args) throws Exception {
        
        int rank = Group.rank();
        int size = Group.size();
            
        // Create the group  
        if (rank == 0) { 
            Group.create("GroupNoReply", i_SimpleGroup.class, size);
        } 
            
        // Everyone adds an object 
        SimpleGroup s = new SimpleGroup();              
        Group.join("GroupNoReply", s);
            
        if (rank == 0) {            
            // Perform lookup to get group reference
            i_SimpleGroup g = (i_SimpleGroup) Group.lookup("GroupNoReply");
    
            // Configure reference to perform group invocation
            GroupMethod m = Group.findMethod(g,"void ping()");
            m.configure(new GroupInvocation(), new DiscardReply());
                
// Done
            // Perform the invocation  
            g.ping();
        }
            
Group.exit();
        // Done
        Group.exit();
    }
}
Code Example

● Live demo
Function Objects

● Some operations need user defined


functions
● Personalizing a method invocation
● Combining a result or invocation
● Forwarding of results

● GMI uses function objects


● Extend a class from the GMI package
Result Combiners

● Use 'combiner' to merge the results of


an invocation
● FlatCombiner
● Combines all results in one go
● Similar to 'gather' operation of MPI
● BinomialCombiner
● Pairwise combines results
● Similar to 'reduce' operation of MPI
FlatCombiner

public class FlatCombiner {

    public boolean combine(boolean[] results, Exception[] ex)
    public byte combine(byte[] results, Exception[] ex)
    public char combine(char[] results, Exception[] ex)
    public short combine(short[] results, Exception[] ex)
    public int combine(int[] results, Exception[] ex)
    public long combine(long[] results, Exception[] ex)
    public float combine(float[] results, Exception[] ex)
    public double combine(double[] results, Exception[] ex)

    public Object combine(Object[] results, Exception[] ex)

    public void combine(Exception[] exceptions)
}
FlatCombiner

public class MyCombiner extends FlatCombiner {

    public int combine(int[] results, Exception[] ex) {
       
        int sum = 0;
 
        for (int i=0;i<results.length;i++) {
            sum += results[i];
        }
   
        return sum; 
    }  
}
FlatCombiner

// Get a group reference
X g = (X) Group.lookup("your group");
    

// Configure reference to perform group invocation, 
// and combine the replies using 'MyCombiner'
GroupMethod m = Group.findMethod(g, "int get()");
m.configure(new GroupInvocation(), 
            new CombineReply(new MyCombiner()));
                

// Perform the invocation  
int result = g.get();
FlatCombiner

get()
FlatCombiner

e t ()
g

get()

get
()
FlatCombiner

42

64

8
FlatCombiner
MyCombiner

combine([42,64,8], [])
FlatCombiner
MyCombiner

114
FlatCombiner

114
FlatCombiner Demo

● Live demo
After the Break

● Hands-on session
● Installing ibis
● Running applications
● Scripts and command line
● Writing your own applications

You might also like