Please anone help me with this screen shots of test runs please Write a parallel
ID: 3766319 • Letter: P
Question
Please anone help me with this screen shots of test runs please
Write a parallel program with MPI that supports the following computation.
1). It generates five processes P0, P1, P2, P3, and P4.
2). Main process gets a number n from key board, then initiates MPI.
3) Process Pi (i=0,1,2,3) uses n to call the following two functions.
a) function prime(int n) finds the smallest prime number q that q=8m+(2i+1) >n for some integer m. Note a prime number p is an integer that is not product of two integers less than p.
b) function twin(int n) finds the least twin number (q, q+2) that q=8m+(2i+1)> n for some integer m. A pair (q,q+2) is a twin if both q and q+2 are prime numbers.
4) P4 gets all four results from the other four processes and returns the least prime number and twin.
For example, if n=10, P0 returns 11 and (11,13), P1 returns 13 and (17, 19), P2 returns 17 and (17, 19), and P3 returns 19 and (29,31). Finally, P4 returns 11 and (11,13).
All the five processes share the same program.
Your complete C++ code for this project with summary in a word document, please have readable code
Screenshots of test runs
please anyone help me with this program its urgent
Explanation / Answer
We can select an integrand and limits of integration so the integral mathematically is equal to p. This makes checking the correctness of the program straightforward. A simple C program implementing this algorithm follows:
01
static long num_steps = 100000;
02
03
double step;
04
05
void main ()
06
07
{
08
09
int i;
10
11
double x, pi, sum = 0.0;
12
13
step = 1.0/(double) num_steps;
14
15
for (i=0;i<= num_steps; i++){
16
17
x = (i+0.5)*step;
18
19
sum = sum + 4.0/(1.0+x*x);
20
21
}
22
23
pi = step * sum;
24
25
}
OpenMP
OpenMP [omp] is an industry standard API for writing parallel application programs for shared memory computers. The primary goal of OpenMP is to make the loop oriented programs common in high performance computing easier to write. Constructs were included in OpenMP to support SPMD, Master worker, pipeline and most other types of parallel algorithms as well [Mattson05].
OpenMP has been a very successful parallel language. It is available on every shared memory computer on the market. Recently Intel© has created a variation on OpenMP to support clusters as well. OpenMP supports a style of programming where parallelism is added incrementally so an existing sequential program evolves into a parallel program. This advantage, however, is also OpenMP’s greatest weakness. By using incremental parallelism, a programmer might miss the large scale restructuring of a program often required to get the most performance.
OpenMP is a continuously evolving standard. An industry group called “the Ope nMP Architecture Review Board” meets regularly to develop new extensions to the language. The next release of OpenMP (version 3.0) will include a task queue capability. This will allow OpenMP to handle a wider range of control structures as well as more general recursive algorithms.
OpenMP Overview
OpenMP is based on the fork-join programming model. A running OpenMP program starts as a single thread. When the programmer wishes to exploit concurrency in the program, additional threads are forked to create a team of threads. These threads execute in parallel across a region of code called a parallel region. At the end of the parallel region, the threads wait until all of the threads have finished their work, and then they join back together. At that point, the original or “master” thread continues until the next parallel region is encountered (or the end of the program).
The language constructs in OpenMP are defined in terms of compiler directives that tell the compiler what to do in order to implement the desired parallelism. In C and C++ these directives are defined in terms of pragmas.
The OpenMP pragma have the same form in every case
1
#pragma omp construct_name one_or_more_clauses
The construct_name defines the parallel action desired by the programmer while the clauses modify that action or control the data environment seen by the threads.
OpenMP is an explicit parallel programming language. If a thread is created or work is mapped onto that thread, the programmer must specify the desired action. Therefore, even a simple API such as OpenMP has a wide range of constructs and clauses the programmer must learn. Fortunately, a great deal can be done with OpenMP using only a small subset of the full language.
To create a thread in OpenMP, you use the “parallel” construct.
1
#pragma omp parallel
2
3
{
4
5
…. A block of statements
6
7
}
When used by itself without any modifying clauses, the program creates a number of threads chosen by the runtime environment (often equal to the number of processors or cores). Each thread will execute the block of statements following the parallel pragma. This can be almost any set of legal statements in C, the only exception being that you must not branch into our out of the block of statements. This makes sense if you think about it. If the threads are going to all execute the set of statements and if the resulting behavior of the program is to make sense, then you can’t have arbitrary threads branching into or out of the construct within the parallel region. This is a common constraint in OpenMP. We call this block of statement lacking such branches a “structured block”.
You can do a great deal of parallel programming by having each thread execute the same statements. But to experience the full power of OpenMP, we need to do more. We need to share the work of executing the set of statements among the threads. We call this type of behavior “work sharing”. The most common work-sharing construct is the loop construct which in C is the for the for loop
1
#pragma omp for
This only works for simple loops with the canonical form
1
for(i=lower_limit; i<upper_limit; inc_exp)
The for construct takes the iterations of the loop and parcels them out among a team of threads created earlier with a parallel construct. The loop limits and the expression to increment the loop index (inc_exp) must all be fully determined at compile time and any constants used in these expressions must be the same among all the threads in the team. This makes sense if you think about it. The system needs to figure out how many iterations of the loop there will be and them map them onto sets that can be handed out to the team of threads. This can only be done in a consistent and well behaved manner if all the threads compute the same index sets.
Notice that the for construct does not create threads. You can only do this with a parallel construct. As a short cut, you can put the parallel and for construct together in one pragma.
1
#pragma omp parallel for
This creates a team of threads to execute the iterations of an immediately following loop.
The iterations of the loop must be independent so that the result of the loop is the same regardless of the order the iterations are executed or which threads execute which iteration of the loop. If one thread writes a variable and another thread reads that variable, then we have a loop-carried dependence and program will generate incorrect results. The programmer must carefully analyze the body of a loop to make sure there are no loop carried dependencies. In many cases, the loop carried dependency arises from a variable used to hold intermediate results used within a given iteration of the loop. In this case, you can remove the loop carried dependency by declaring that each thread is to have its own value for the variable. This can be done with a private clause. For example, if a loop uses a variable named “tmp” to hold a temporary value, you could add the following clause to an OpenMP construct so it can be used inside the loop body without causing any loop carried dependencies
1
private(tmp)
Another common situation occurs when a variable appears inside a loop and is used to accumulate values from each iteration. For example, you may have a loop that sums the results of a computation into a single value. This is a common issue in parallel programming. It is called a reduction. In OpenMP, we have a reduction clause
1
reduction(+:sum)
As with the private clause, this is added to an OpenMP construct to tell the compiler to expect a reduction. A temporary private variable is created, and is used to create a partial result of the accumulation operation for each thread. Than at the end of the construct, the values from each thread are combined to yield the final answer. The operation used in the reduction is also specific in the clause. In this case, the operation is “+”. OpenMP defines the value for the private variable used in the reduction based on the identity for the mathematical operation in question. For examp le, for “+”, this value is zero.
There is much more to OpenMP, but with these two constructs and two clauses, we can explain how to parallelize the p program.
The OpenMP p Program
To keep things simple, we will leave the number of steps to be used fixed. And we will only work with the default number of threads. In the serial p program there is a single loop to parallelize. The iterations of the loop are completely independent except for the value of the dependent variable “x” and the accumulation variable “sum”. Notice that “x” is used as temporary storage for the computation within a loop iteration. Hence we can deal with this variable by making it local to each thread with a private clause
1
private(x)
Technically, the loop control index creates a loop carried dependence. OpenMP, however, understands that the loop control index needs to be local to each thread so it automatically makes that index private to each thread.
The accumulation variable, “sum”, is used in a summation. This is a classic reduction so we can use the reduction clause:
1
reduction(+:sum)
Adding these clauses to the “parallel for” construct we have our p program parallelized with OpenMP.
01
#include "omp.h"
02
03
static long num_steps = 100000; double step;
04
05
void main ()
06
07
{
08
09
int i;
10
11
double x, pi, sum = 0.0;
12
13
step = 1.0/(double) num_steps;
14
15
#pragma omp parallel for private(x) reduction(+:sum)
16
17
for (i=0;i<= num_steps; i++){
18
19
x = (i+0.5)*step;
20
21
sum = sum + 4.0/(1.0+x*x);
22
23
}
24
25
pi = step * sum;
26
27
}
Note that we also included the standard include file for OpenMP
1
#include "omp.h"
.
1
int my_id, numprocs;
2
3
MPI_Init(&argc, &argv) ;
4
5
MPI_Comm_Rank(MPI_COMM_WORLD, &my_id) ;
6
7
MPI_Comm_Size(MPI_COMM_WORLD, &numprocs) ;
1
int MPI_Finalize();
In between these routines, is the work of the MPI program. Most of the program is regular serial code in the language of your choice. As mentioned before, while every process is executing the same code, the behavior of the program is different based on the process rank. At points where communication or some other interaction between processes is required, MPI routines are insterted. The first version of MPI had over 120 routines and the later version (MPI 2.0) was even larger. Most programs, however, use only a tiny subset of MPI functions. We will talk about only one; a routine to carry out a reduction and return the final reduced result to one of the processes in the group.
1
int MPI_Reduce(void* sendbuf, void* recvbuf,
2
3
int count, MPI_Datatype datatype, MPI_OP op,
4
5
int root, MPI_COMM comm.)
The MPI p Program
The MPI p program is a straightforward modification of the original serial code. To keep things as simple as possible, we will continue to set the number of steps in the program itself rather than input the value and broadcast it to the other processes.
The program opens with the MPI include file to define datatypes, constants and the routines in MPI. We then include the standard trio of routines to initialize the MPI environment and make the basic parameters (number of processes and rank) available to the program.
01
#include "mpi.h"
02
03
static long num_steps = 100000;
04
05
void main (int argc, char *argv[])
06
07
{
08
09
int i, my_id, numprocs;
10
11
double x, pi, step, sum = 0.0 ;
12
13
step = 1.0/(double) num_steps ;
14
15
MPI_Init(&argc, &argv) ;
16
17
MPI_Comm_Rank(MPI_COMM_WORLD, &my_id) ;
18
19
MPI_Comm_Size(MPI_COMM_WORLD, &numprocs) ;
20
21
my_steps = num_steps/numprocs ;
22
23
for (i=my_id; i<num_steps; i+numprocs)
24
25
{
26
27
x = (i+0.5)*step;
28
29
sum += 4.0/(1.0+x*x);
30
31
}
32
33
sum *= step ;
34
35
MPI_Reduce(&sum, &pi, 1, MPI_DOUBLE, MPI_SUM, 0,
36
37
MPI_COMM_WORLD) ;
38
39
MPI_Finalize(ierr);
40
41
}
1
MPI_Reduce(&sum, &pi, 1, MPI_DOUBLE, MPI_SUM, 0,
2
3
MPI_COMM_WORLD) ;
.
The Java threads pprogram
In this simple example we show how one would write a parallelized version of p program with help of “plain” Java threads:
01
public class PI1 {
02
03
static long num_steps = 100000;
04
05
static double step;
06
07
static double sum = 0.0;
08
09
static int part_step;
10
11
static class PITask extends Thread {
12
13
int part_number;
14
15
double x = 0.0;
16
17
double sum = 0.0;
18
19
public PITask(int part_number) {
20
21
this.part_number = part_number;
22
23
}
24
25
public void run() {
26
27
for (int i = part_number; i < num_steps; i += part_step)
28
29
{
30
31
x = (i + 0.5) * step;
32
33
sum += 4.0 / (1.0 + x * x);
34
35
}
36
37
}
38
39
}
40
41
public static void main(String[] args) {
42
43
;
44
45
int i;
46
47
double pi;
48
49
step = 1.0 / (double) num_steps;
50
51
part_step = Runtime.getRuntime().availableProcessors();
52
53
PITask[] part_sums = new PITask[part_step];
54
55
for (i = 0; i < part_step; i++) {
56
57
(part_sums[i] = new PITask(i)).start();
58
59
}
60
61
for (i = 0; i < part_step; i++) {
62
63
try {
64
65
part_sums[i].join();
66
67
} catch (InterruptedException e) {
68
69
}
70
71
sum += part_sums[i].sum;
72
73
}
74
75
pi = step * sum;
76
77
System.out.println(pi);
78
79
}
80
81
}
01
import EDU.oswego.cs.dl.util.concurrent.FJTask;
02
03
import EDU.oswego.cs.dl.util.concurrent.FJTaskRunnerGroup;
04
05
public class PI2 {
06
07
static int num_steps = 100000;
08
09
static double step;
10
11
static double sum = 0.0;
12
13
static int part_step;
14
15
static class PITask extends FJTask {
16
17
int i = 0;
18
19
double sum = 0.0;
20
21
public PITask(int i) {
22
23
this.i = i;
24
25
}
26
27
public void run() {
28
29
double x = (i + 0.5) * step;
30
31
sum += 4.0 / (1.0 + x * x);
32
33
}
34
35
}
36
37
public static void main(String[] args) {
38
39
int i;
40
41
double pi;
42
43
step = 1.0 / (double) num_steps;
44
45
try {
46
47
FJTaskRunnerGroup g = new FJTaskRunnerGroup(Runtime.getRuntime()
48
49
.availableProcessors());
50
51
;
52
53
PITask[] tasks = new PITask[num_steps];
54
55
for (i = 0; i < num_steps; i++) {
56
57
tasks[i] = new PITask(i);
58
59
}
60
61
g.invoke(new FJTask.Par(tasks));
63
for (i = 0; i < num_steps; i++) {
64
65
sum += tasks[i].sum;
66
67
}
68
69
pi = step * sum;
70
71
System.out.println(pi);
72
73
;
74
75
System.out.println(Math.PI);
76
77
} catch (InterruptedException ie) {
78
79
}
80
81
}
82
83
}
01
static long num_steps = 100000;
02
03
double step;
04
05
void main ()
06
07
{
08
09
int i;
10
11
double x, pi, sum = 0.0;
12
13
step = 1.0/(double) num_steps;
14
15
for (i=0;i<= num_steps; i++){
16
17
x = (i+0.5)*step;
18
19
sum = sum + 4.0/(1.0+x*x);
20
21
}
22
23
pi = step * sum;
24
25
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.