Introduction
This article demonstrates the implementation of MPI programs using Java* so you can understand how to create, compile, and run MPI programs using Java.
Prerequisites
- Check if your system meets the software and hardware requirements from Intel® oneAPI DPC++/C++ Compiler System Requirements page, and then download either the Intel® oneAPI HPC Toolkit or a stand-alone version of the Intel® oneAPI DPC++/C++ Compiler.
- Check if your system meets the software and hardware requirements from Intel® MPI Library System Requirements page, and then download either the Intel® oneAPI HPC Toolkit or a stand-alone version of the Intel® MPI Library.
Install the Java* Development Kit.
C Program to Estimate PI Using MPI Code
The following sample C code explains how to calculate the PI value using MPI.
/* File: ComputePi.c
* Purpose: Estimates pi using the Leibniz formula parallelized with MPI
* Compile: mpiicpc pi-mpi.c
* Run: mpirun -n <number of processes> ./a.out
*/
#include <stdio.h>
#include <math.h>
#include <mpi.h>
int main(int argc, char **argv) {
MPI_Init(&argc, &argv);
int i, intervals,rank,size, count,start,end;
double Partial_sum=0.0, total_sum=0.0, pi;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
if (rank == 0) {
// printf("Number of intervals: ");
// scanf("%d", &intervals);
intervals=100000;
}
MPI_Bcast(&intervals, 1, MPI_INT, 0, MPI_COMM_WORLD);
count = intervals /size;
start = count * rank;
end = count * rank + count;
for(i=start;i< end;i=i++)
{
Partial_sum += pow(-1, i) / (2*i+1);
}
MPI_Reduce(&Partial_sum,&total_sum,1,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD);
if (rank==0){
pi = 4 * total_sum;
printf("\nPI = %.10lf", pi);
}
MPI_Finalize();
return 0;
}
Compilation
$ mpiicc -cc=icx sample.c
Execution
$ mpirun -n 10 ./a.out
Expected output
PI = 3.1415826536
Equivalent Java Program to Estimate PI Using MPI
In this section, you learn how to migrate to Java code from the existing C program provided in the previous section.
Intel® MPI Library provides an experimental feature to enable support for Java MPI applications. It also provides Java bindings for a subset of MPI-2 routines.
You can find all supported MPI routines in the Java Bindings for MPI-2 Routines article. All the classes belong to the MPI package.
You need to check the equivalent Java methods for the original C routines and thus you need to replace the original C routine with ClassName.Method(args) to implement the equivalent Java code.
Below are the C routines used in the previous section’s code, followed by their equivalent Java methods that need to be used for implementing ComputePi in Java:
Java Class |
Methods |
Original C Routine/Parameter |
MPI |
MPI.init MPI.Finalize |
MPI_Init MPI_Finalize |
Collective |
Collective.reduce() Collective.Bcast() |
MPI_Reduce MPI_Bcast |
Comm
|
Comm.WORLD Comm.WORLD.getRank() Comm.WORLD.getsize() |
MPI_COMM_WORLD MPI_Comm_rank(MPI_Comm comm,int* rank) MPI_Comm_size(MPI_Comm comm,int* size) |
Datatype |
Datatype.DOUBLE |
MPI_DOUBLE |
Op |
Op.MPI_SUM |
MPI_SUM |
Now you have an equivalent Java code estimating PI value using MPI. For a clear understanding on how original C routines were modified to their equivalent Java methods, we kept the original C code in comments.
/* File: ComputePi.java */
import java.lang.Math;
import mpi.*;
class ComputePi {
public static void main(String args[]) throws Exception{
MPI.Init(args);
int i,rank,size, count,start,end;
double Partial_sum=0.0, pi;
//MPI_Comm_rank(MPI_COMM_WORLD, &rank);
rank=Comm.WORLD.getRank();
//MPI_Comm_size(MPI_COMM_WORLD, &size);
size=Comm.WORLD.getSize();
int intervals[]=new int[1];
if (rank == 0) {
intervals[0]=100000;
}
//MPI_Bcast(&intervals, 1, MPI_INT, 0, MPI_COMM_WORLD);
Collective.bcast(intervals, 1, Datatype.LONG, 0, Comm.WORLD);
count = intervals[0] /size;
start = count * rank;
end = count * rank + count;
for(i=start;i< end; i=i+1)
{
Partial_sum += Math.pow(-1, i) / (2*i+1);
}
double sBuf[]={ Partial_sum},
total_sum[]=new double[1];
//MPI_Reduce(&Partial_sum,&total_sum,1,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD);
Collective.reduce(sBuf, total_sum, 1, Datatype.DOUBLE, Op.MPI_SUM,0,Comm.WORLD);
if (rank==0){
pi = 4 * total_sum[0];
System.out.println("PI = " + pi);
}
// MPI_Finalize();
MPI.Finalize();
}
}
Building Java MPI Applications
Follow these steps to set up the environment and build your Java application using Intel MPI Library.
- Source mpivars.sh from the Intel® MPI Library package to set up all required environment variables, including LIBRARY_PATH and CLASSPATH.
- Build your Java application with Intel MPI Library as shown in the following instructions.
javac ComputePi.java
Running Java Applications with Intel MPI Library
Follow these steps to set up the environment and run your Java MPI application:
- Source mpivars.sh from the Intel MPI Library package to set up all required environment variables, including LIBRARY_PATH and CLASSPATH.
- Update CLASSPATH with the path to the jar application or pass it explicitly with the -cp option of the Java command.
Example:
export CLASSPATH=<path-to-the-application>:$CLASSPATH
- Run your application using the following command:
$ mpirun <options> java <app>
where:
<options> is a list of mpirun options.
<app> is the main class of your Java application.
For example:
$ mpirun -n 8 -ppn 1 -f ./hostfile java ComputePI
The following is a screenshot of building and running a Java application with Intel MPI Library.
Limitations
Intel MPI Library provides an experimental feature to enable support for Java MPI applications. It also provides Java bindings for a subset of MPI-2 routines.
You can find all supported MPI routines in the Java Bindings for MPI-2 Routines article.
Source Code
Download the attachment MPI_JAVA.zip for the source code used in the previously mentioned article.
Summary
This short article demonstrated the use of MPI in Java programs along with the build and run procedure using Intel MPI Library. For more details, refer to the Intel MPI Library developer reference and developer guide.