Using Pari-Distributed

General Information

First, have a look at the diagram of the architecture of Pari-Distributed below.

Diagram of Pari-Distributed architecture

As you can see, the proper functioning of Pari-Distributed depends on having the Compute or 'listener' nodes available to do computations, and the control nodes available to send instructions, keep track of available nodes, and display output.

How to Run Pari-Distributed

Before you can run Pari-Distributed across multiple computers, make sure you set the file ~/.erlang.cookie appropriately on each node. See Official Documentation for an explanation.

First, you'll need to start the Node Tracker. The job of this process is to keep track of which nodes are available, and relay this information to the Work Unit Distributor , or 'dWU' node. To start nodetracker, compile the nodetracker module


and run nodetrack:start(...) with two arguments: a list of 'listener' nodes, and the Distribute Work Unit node. For example,

nodetracker:start([first@localhost, second@Gondor, third@myHost] , dWUnode@localhost).

The node tracker will now start attempting to contact the listener nodes you've specified, relaying information to the Distribute Work Unit node you've specified. Before starting the listener node on each host, it is important to name it appropriately. In the example above, nodetracker expects the nodes to be named "first" , "second" "third" , and dWUnode, and to be running on hosts "localhost" , "Gondor" , "myHost" , and "localhost" , respectively. To start the node "first@localhost", you should start the erlang shell with:

erl -sname first

executed on host "localhost" (or, the same host that the nodetracker process is running on).

Once you've got the Erlang shell running under the appropriate name, it's time to start a listener node. Compile the main module for Pari-Distributed, localmessages:


and start the listener node:


Within a few seconds of being started, each listener node should start receiving messages from the nodetracker, querying the node's availability.

Finally, it's time to start the Work Unit Distributor, and assign computations to the listener nodes. Start up another Erlang shell, compile the localmessages module:


and run the start_talk function,

localmessages:start_talk(StartPoint , EndPoint, WorkUnitSize, IndexTrackerNode).

where StartPoint and EndPoint are integers representing the start and end of the range of values you'll be running a for loop over in the Pari/GP calculation, WorkUnitSize is an integer representing the number of index values each node will work on at a time, and IndexTrackerNode is the name of the process running the index tracker (as of now this is the same node you're running start_talk on, e.g. mytalknode@localhost).

For example, to run have your listener nodes compute some loop over the range of 1000 to 8500 in chunks of 100, you would use the command:

localmessages:start_talk(1000 , 8500, 100, talknode@localhost).

With talknode@localhost being the node responsible for running the index tracker, which, for now, is automatically the same host you'd be executing the start_talk(..) command above on.

When you're done running one or several successive start_talk(...) iterations, you'll probably want to kill the nodetracker process, and the listener nodes. You can do this with a single command, namely:


Where Node_Tracker_Node is the address of the node you instantiated nodetracker on. For example, if it is running under the Erlang shell named "NodeTracking@myHostName", execute:


which will kill the nodetracker and all listener nodes.

Full example session with two nodes

Let's take a simple example where we're running P-D on two nodes, whose hostnames are Gondor and Isengard. We'll run the control nodes on Gondor (we're assuming they don't suck up too many CPU cycles), and we'll run one listener node on Gondor and Isengard each. First, we start nodetracker on Gondor:

josh@Gondor:~/distr-pari$ erl -sname nodetracker
Erlang (BEAM) emulator version 5.5.2 [source] [async-threads:0] [kernel-poll:false]

Eshell V5.5.2 (abort with ^G)

We've just started an Erlang shell, named 'nodetracker' , on which we will run the nodetracker process like so:

(nodetracker@Gondor)2> c(nodetrack).
(nodetracker@Gondor)3> nodetrack:start([firstListener@Gondor , secondListener@Isengard], talk@Gondor).

The nodetracker will immediately begin attempting to contact the two listener nodes (firstListener@Gondor and secondListener@Isengard) we've passed in as arguments. It will start printing output like so:

DWU_Node is :talk@Gondor
All nodes: [firstListener@Gondor,secondListener@Isengard]
First node unchecked is: firstListener@Gondor (nodetracker@Gondor)4>
Tail unchecked is: [secondListener@Isengard]
Length of all is 2 Length of unchecked is 2
Nodetracker timed out waiting on -nodealive- from: firstListener@Gondor

You might notice that it complains about timing out waiting for a response from the listener nodes. This is fine, because we haven't started them yet. We will do so now, from another terminal on host Gondor, like so:

josh@Gondor:~/distr-pari$ erl -sname firstListener
Erlang (BEAM) emulator version 5.5.2 [source] [async-threads:0] [kernel-poll:false]

Eshell V5.5.2 (abort with ^G)
(firstListener@Gondor)1> c(localmessages).
(firstListener@Gondor)2> localmessages:start_listen().
Received isnodealive from parent
Received isnodealive from parent

A second or two after running 'localmessages:start_listen().', you should start start seeing output indicating that your listener node is receiving communications from the nodetracker. If you check the nodetracker process, it should now start printing lines saying "Confirmed that node: firstListener@Gondor is alive."

Next, start the second listener process on host Isengard in the exact same fashion:

josh@Isengard:~/distr-pari$ erl -sname secondListener
Erlang (BEAM) emulator version 5.5.2 [source] [async-threads:0] [kernel-poll:false]

Eshell V5.5.2 (abort with ^G)
(secondListener@Isengard)1> c(localmessages).
(secondListener@Isengard)2> localmessages:start_listen().
Received isnodealive from parent
Received isnodealive from parent

Finally, we can start the process to distribute work nodes to the two listener nodes, like so:

josh@Gondor:~/distr-pari$ erl -sname talk
Erlang (BEAM) emulator version 5.5.2 [source] [async-threads:0] [kernel-poll:false]

Eshell V5.5.2 (abort with ^G)
(talk@Gondor)1> c(localmessages).
(talk@Gondor)2> localmessages:start_talk(900,1000,25,talk@Gondor).

You should now, finally, start receiving the results of your desired computations from your compute nodes. In this case, we are using the default file which tells the nodes to look for prime numbers within a certain range. The output will look something like this:

Received start point from tracker:

---Received node alive info from nodetracker! for node: firstListener@Gondor
Executing talk_waitmsgs, waiting for :--Output Data Missing--
Output from subprocess:

Valid XHTML 1.0 Strict