CS代考 FIT3143 Lab Week 10

FIT3143 Lab Week 10
Lecturers: ABM Russel (MU Australia) and (MU Malaysia)
MPI VIRTUAL TOPOLOGY + COMM SPLIT &
PIPELINE COMPUTATION

Copyright By PowCoder代写 加微信 powcoder

OBJECTIVES
● The purpose of this lab is to first learn how to combine MPI Virtual Topologies with MPI Comm Split. Then, this lab explores integrating a thread into an MPI process.
● This lab also explores pipeline computation using MPI.
INSTRUCTIONS
● Download and set up the Linux VM [Refer to Lab Week 1]
● Setup eFolio (including Git) and share with tutor and partner [Refer to Lab Week 1]
DESCRIPTION:
● Combining MPI virtual topology functions and MPI Comm Split.
● Integrating a thread into an MPI process function.
● Design and implement an MPI pipeline computation program.
WHAT TO SUBMIT:
1. E-folio document containing algorithm or code description, analysis of results, screenshot of the running programs and git repository URL. E-folio template for this lab can be found in Week 10 of Moodle.
2. CodeandsupportingfilesintheGit.
3. This is an assessed lab. Therefore, you are required to submit both the E-folio document, code file(s) and text files into Moodle. Submission link is available in Week 10 of Moodle. Each student makes a submission. Although you are working in a team of two (or three) members and your submitted files will be the same within a team, each team member is required to make a submission independently in Moodle.

EVALUATION CRITERIA
This Lab-work is part of grading, with 12 maximum marks, which is then scaled to 3 percentage points of the overall unit marks.
Task 4 2 3
LAB ACTIVITIES (12 MARKS)
Task1 – Placing the Slaves into a virtual topology – Worked Example (No marks for this activity)
This task continues from Lab Week 09’s Task 4. Here, the slaves are first placed in a 2D virtual topology (using MPI Cartesian functions). Each slave then sends a series of messages to the Master, which prints the message.
Sample solution:
#include
#include
#include
#include
#include
#include
#define MSG_EXIT 1
#define MSG_PRINT_ORDERED 2
#define MSG_PRINT_UNORDERED 3
int master_io(MPI_Comm world_comm, MPI_Comm comm);
int slave_io(MPI_Comm world_comm, MPI_Comm comm);
int main(int argc, char **argv)
int rank, size;
MPI_Comm new_comm;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_split( MPI_COMM_WORLD,rank == size-1, 0, &new_comm);
// color will either be 0 or 1
if (rank == size-1)
master_io( MPI_COMM_WORLD, new_comm );
Code compiles without errors and executed correctly (2 marks)
Sufficient code comments
Questions or instructions fully answered
Proper presentation of results and analysis (3 marks)

slave_io( MPI_COMM_WORLD, new_comm );
MPI_Finalize();
return 0; }
/* This is the master */
int master_io(MPI_Comm world_comm, MPI_Comm comm)
int i, size, nslaves, firstmsg;
char buf[256], buf2[256];
MPI_Status status;
MPI_Comm_size(world_comm, &size );
nslaves = size – 1;
while (nslaves > 0) {
MPI_Recv(buf, 256, MPI_CHAR, MPI_ANY_SOURCE,
MPI_ANY_TAG, world_comm, &status );
switch (status.MPI_TAG) {
case MSG_EXIT: nslaves–; break;
case MSG_PRINT_UNORDERED:
fputs( buf, stdout );
case MSG_PRINT_ORDERED:
firstmsg = status.MPI_SOURCE;
for (i=0; i 0) {
MPI_Recv(buf, 256, MPI_CHAR, MPI_ANY_SOURCE,
MPI_ANY_TAG, MPI_COMM_WORLD, &status );
switch (status.MPI_TAG) {
case MSG_EXIT: nslaves–; break;
case MSG_PRINT_UNORDERED:
printf(“Thread prints: %s”, buf);
fflush(stdout);
case MSG_PRINT_ORDERED:
firstmsg = status.MPI_SOURCE;
for (i=0; i
#include
#include
#include
#include “mpi.h”
#define SENTINEL 0.0
int main(int argc, char *argv[])
FILE *pInfile;
double x0, x1, x2, x3, x4;
double *pX4Buff = NULL;
int fileElementCount = 0;
int counter = 0;
int my_rank;

MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
MPI_Comm_size(MPI_COMM_WORLD, &p);
switch (my_rank)
pInfile = fopen(“ExpResults.txt”,”r”);
fscanf(pInfile, “%d”, &fileElementCount);
pX4Buff = (double*)malloc(fileElementCount *
sizeof(double));
memset(pX4Buff, 0, fileElementCount *
sizeof(double));
// Send the counter to the last process
MPI_Send(&fileElementCount, 1, MPI_INT, (p – 1), 0,
MPI_COMM_WORLD);
// Read each element from the file
while(counter < fileElementCount) MPI_COMM_WORLD); fscanf(pInfile, "%f", &x); x1 = x0 - (4 * x0) + 7; MPI_Send(&x1, 1, MPI_DOUBLE, 1, 0, counter++; calculation // File end, send a SENTINEL value to complete fclose(pInfile); pInfile = NULL; x1 = SENTINEL; MPI_Send(&x1, 1, MPI_DOUBLE, 1, 0, MPI_COMM_WORLD); // Wait for buffer from last node MPI_Recv((void*)pX4Buff, counter, MPI_DOUBLE, (p - 1), 0, MPI_COMM_WORLD, &status); // Print results for(int i = 0; i < counter; i++) printf("Result[%d]: %g\n", i, pX4Buff[i]); free(pX4Buff); pX4Buff = NULL; MPI_Recv(&x1, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &status); if(x1 != SENTINEL) x2 = pow(x1, 3) + sin(x1/8); x2 = SENTINEL; MPI_Send(&x2, 1, MPI_DOUBLE, 2, 0, MPI_COMM_WORLD); } while (x1 != SENTINEL); MPI_Recv(&x2, 1, MPI_DOUBLE, 1, 0, MPI_COMM_WORLD, &status); if(x2 != SENTINEL) x3 = (2 * pow(x2, 4)) + cos(4 * x2) + (3 x3 = SENTINEL; MPI_Send(&x3, 1, MPI_DOUBLE, 3, 0, MPI_COMM_WORLD); } while (x2 != SENTINEL); // Get the file element count first MPI_Recv(&fileElementCount, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &status); pX4Buff = (double*)malloc(fileElementCount * sizeof(double)); memset(pX4Buff, 0, fileElementCount * sizeof(double)); // Now, receive the pipelined data counter = 0; MPI_Recv(&x3, 1, MPI_DOUBLE, 2, 0, MPI_COMM_WORLD, &status); (tan(x3) / 3); if(x3 != SENTINEL) x4 = (3 * pow(x3, 2)) - (2 * x3) + // Save the result into buffer & increment the buffer counter pX4Buff[counter] = x4; counter++; } } while (x3 != SENTINEL); // End of file reached, send the buffer back to the if(counter > 0)
MPI_Send(pX4Buff, counter, MPI_DOUBLE, 0, 0,
MPI_COMM_WORLD);
// Clean up
free(pX4Buff);
pX4Buff = NULL;
} default: {
printf(“Process %d unused.\n”,my_rank);
MPI_Finalize();
return 0; }

Task 4 – Pipeline computing exercise using MPI – To be completed (12 Marks)
In mathematics, a quadratic equation represents a univariate polynomial equation of the second degree. A general quadratic equation can be described as:
𝑎𝑥2 + 𝑏𝑥 + 𝑐 = 0 (1.1)
where x represents the unknown variable and a, b and c are the quadratic coefficients (a ≠ 0). A quadratic
equation with real and complex coefficients has two solutions, called roots (x1 and x2).
The discriminant, d, is computed as: 𝑑 = 𝑏2 − 4𝑎𝑐. If d is positive, the quadratic equation has two distinct real
roots (i.e., x1 ≠ x2) such that:
𝑥1 = −𝑏+√𝑑 , 𝑥2 = −𝑏−√𝑑 2𝑎 2𝑎
If d is negative, the quadratic equation has two distinct complex roots (i.e., x1 ≠ x2) such that:
𝑥1 =−𝑏+𝑖√|𝑑|,𝑥2 =−𝑏−𝑖√|𝑑| (1.4) 2𝑎 2𝑎 2𝑎 2𝑎
Figure T4-1 illustrates the content of a text file, quad.txt, which contains a set of quadratic coefficients. The first row element in quad.txt represents the number of coefficients (a, b and c) rows in this file. The second row displays the legend text for these coefficients and the third row onwards contains the coefficient content.
Figure T4-1: Content of quad.txt
Using the C programming language with a parallel programming implementation using the Message Passing Interface (MPI):
If d is zero, the quadratic equation has only one real root (i.e., x1 = x2) such that: 𝑥1 = 𝑥2 =−𝑏
100 abc 1.0 -4.0 3.0 1.0 2.0 1.0 1.0 -4.0 4.0 1.0 -4.0 5.0
Row count in the file
Legend text

a) Write a program to compute the quadratic roots of each row coefficient in quad.txt file.
i. Only the root rank (or first node) is permitted to access the quad.txt file.
ii. The root rank reads coefficients of each row from quad.txt file and computes the discriminant, d, which
is then transmitted to the subsequent node along with the a and b coefficients.
b) Continuing from part (a), the second node receives the computed d and a and b coefficients (per row) from
the first node and computes the root values.
i. This node computes x1 and x2 based on the computed value of d.
ii. Note: If d < 0, the roots are calculated as x1_real, x1_img and x2_real, x2_img. iii. The computed root values are then transmitted to the third node. c) Continuing from part (b), the third node receives the computed root values from the second node and writes these root values into a new text file, roots.txt. Figure T4-2 illustrates a sample content of the computed root value in the roots.txt file. Figure T4-2: Content of roots.txt Complete parts (a), (b) and (c). Use a parallel pipeline structure in reading the coefficients from the file, computing the roots and writing the computed roots into file. Note: The total number of nodes in this pipeline architecture should be three (The first node reads a row coefficient and computes d, the second node computes the roots and the third node writes the computed roots into a new file). Create your own version of quad.txt as seen in Figure T4-1. You need not create a large number of entries for your version of quad.txt. A smaller number of entries would suffice to test the program. You may refer to the following C code to get you started. #include
#include
#include
#include
int main() {
FILE *pInfile;
float a_coeff, b_coeff, c_coeff, x1, x2, disc; float x1r, x1i, x2r, x2i;
int fileElementCount = 0, constNeg = -1;;
int my_rank;
MPI_Status status;
x1 x2 x1_real 3.0 1.0
x1_img x2_real x2_img
Row count in the file
Legend text
-0.3 -4.2 -1.1 -3.0
6,000 rows
MPI_Init(&argc, &argv);

MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); MPI_Comm_size(MPI_COMM_WORLD, &p);
// WRITE PART(a) HERE
switch (my_rank){
// CONTINUE WITH PART (a) HERE
// WRITE PART (b) HERE
// WRITE PART (c) HERE
MPI_Finalize();

程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com