import mpi.MPI;
import java.util.Arrays;
public class MPIAHCalculation {
public static void main(String[] args) {
MPI.Init(args);
int rank = MPI.COMM_WORLD.Rank();
int size = MPI.COMM_WORLD.Size();
final int H = 100; // Assume H is predefined.
int[][] MX = new int[H][H];
int[][] MR = new int[H][H];
int[] Z = new int[H];
int[] C = new int[H];
int D = 0;
if (rank == 0) {
// Initialize data in rank 0
MX = fillMatrix(H, H, 1);
MR = fillMatrix(H, H, 1);
Z = fillVector(H, 1);
C = fillVector(H, 1);
D = 5; // Example constant
}
// Broadcast matrices and constants to all processes
for (int i = 0; i < H; i++) {
MPI.COMM_WORLD.Bcast(MX[i], 0, H, MPI.INT, 0);
MPI.COMM_WORLD.Bcast(MR[i], 0, H, MPI.INT, 0);
}
MPI.COMM_WORLD.Bcast(Z, 0, H, MPI.INT, 0);
MPI.COMM_WORLD.Bcast(C, 0, H, MPI.INT, 0);
MPI.COMM_WORLD.Bcast(new int[]{D}, 0, 1, MPI.INT, 0);
// Divide work among processes
int rowsPerProcess = H / size;
int startRow = rank * rowsPerProcess;
int endRow = (rank == size - 1) ? H : startRow + rowsPerProcess;
// Compute AH locally
int[] localAH = new int[endRow - startRow];
int c = Arrays.stream(C).min().orElse(Integer.MAX_VALUE);
for (int i = startRow; i < endRow; i++) {
localAH[i - startRow] = c * Z[i] + D * matrixRowDot(MX, MR, i);
}
// Gather results at rank 0
int[] AH = null;
if (rank == 0) {
AH = new int[H];
}
MPI.COMM_WORLD.Gather(localAH, 0, endRow - startRow, MPI.INT, AH, 0, rowsPerProcess, MPI.INT, 0);
if (rank == 0) {
System.out.println("AH: " + Arrays.toString(AH));
}
MPI.Finalize();
}
// Utility method to fill a matrix with a specific value
public static int[][] fillMatrix(int rows, int cols, int value) {
int[][] matrix = new int[rows][cols];
for (int i = 0; i < rows; i++) {
Arrays.fill(matrix[i], value);
}
return matrix;
}
// Utility method to fill a vector with a specific value
public static int[] fillVector(int size, int value) {
int[] vector = new int[size];
Arrays.fill(vector, value);
return vector;
}
// Compute dot product of matrix row and vector
public static int matrixRowDot(int[][] matrix1, int[][] matrix2, int row) {
int sum = 0;
for (int i = 0; i < matrix1[row].length; i++) {
sum += matrix1[row][i] * matrix2[i][row]; // Adjusted dot product logic
}
return sum;
}
}
aW1wb3J0IG1waS5NUEk7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOwoKcHVibGljIGNsYXNzIE1QSUFIQ2FsY3VsYXRpb24gewoKICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHsKICAgICAgICBNUEkuSW5pdChhcmdzKTsKICAgICAgICAKICAgICAgICBpbnQgcmFuayA9IE1QSS5DT01NX1dPUkxELlJhbmsoKTsKICAgICAgICBpbnQgc2l6ZSA9IE1QSS5DT01NX1dPUkxELlNpemUoKTsKCiAgICAgICAgZmluYWwgaW50IEggPSAxMDA7IC8vIEFzc3VtZSBIIGlzIHByZWRlZmluZWQuCiAgICAgICAgaW50W11bXSBNWCA9IG5ldyBpbnRbSF1bSF07CiAgICAgICAgaW50W11bXSBNUiA9IG5ldyBpbnRbSF1bSF07CiAgICAgICAgaW50W10gWiA9IG5ldyBpbnRbSF07CiAgICAgICAgaW50W10gQyA9IG5ldyBpbnRbSF07CiAgICAgICAgaW50IEQgPSAwOwoKICAgICAgICBpZiAocmFuayA9PSAwKSB7CiAgICAgICAgICAgIC8vIEluaXRpYWxpemUgZGF0YSBpbiByYW5rIDAKICAgICAgICAgICAgTVggPSBmaWxsTWF0cml4KEgsIEgsIDEpOwogICAgICAgICAgICBNUiA9IGZpbGxNYXRyaXgoSCwgSCwgMSk7CiAgICAgICAgICAgIFogPSBmaWxsVmVjdG9yKEgsIDEpOwogICAgICAgICAgICBDID0gZmlsbFZlY3RvcihILCAxKTsKICAgICAgICAgICAgRCA9IDU7IC8vIEV4YW1wbGUgY29uc3RhbnQKICAgICAgICB9CgogICAgICAgIC8vIEJyb2FkY2FzdCBtYXRyaWNlcyBhbmQgY29uc3RhbnRzIHRvIGFsbCBwcm9jZXNzZXMKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IEg7IGkrKykgewogICAgICAgICAgICBNUEkuQ09NTV9XT1JMRC5CY2FzdChNWFtpXSwgMCwgSCwgTVBJLklOVCwgMCk7CiAgICAgICAgICAgIE1QSS5DT01NX1dPUkxELkJjYXN0KE1SW2ldLCAwLCBILCBNUEkuSU5ULCAwKTsKICAgICAgICB9CiAgICAgICAgTVBJLkNPTU1fV09STEQuQmNhc3QoWiwgMCwgSCwgTVBJLklOVCwgMCk7CiAgICAgICAgTVBJLkNPTU1fV09STEQuQmNhc3QoQywgMCwgSCwgTVBJLklOVCwgMCk7CiAgICAgICAgTVBJLkNPTU1fV09STEQuQmNhc3QobmV3IGludFtde0R9LCAwLCAxLCBNUEkuSU5ULCAwKTsKCiAgICAgICAgLy8gRGl2aWRlIHdvcmsgYW1vbmcgcHJvY2Vzc2VzCiAgICAgICAgaW50IHJvd3NQZXJQcm9jZXNzID0gSCAvIHNpemU7CiAgICAgICAgaW50IHN0YXJ0Um93ID0gcmFuayAqIHJvd3NQZXJQcm9jZXNzOwogICAgICAgIGludCBlbmRSb3cgPSAocmFuayA9PSBzaXplIC0gMSkgPyBIIDogc3RhcnRSb3cgKyByb3dzUGVyUHJvY2VzczsKCiAgICAgICAgLy8gQ29tcHV0ZSBBSCBsb2NhbGx5CiAgICAgICAgaW50W10gbG9jYWxBSCA9IG5ldyBpbnRbZW5kUm93IC0gc3RhcnRSb3ddOwogICAgICAgIGludCBjID0gQXJyYXlzLnN0cmVhbShDKS5taW4oKS5vckVsc2UoSW50ZWdlci5NQVhfVkFMVUUpOwoKICAgICAgICBmb3IgKGludCBpID0gc3RhcnRSb3c7IGkgPCBlbmRSb3c7IGkrKykgewogICAgICAgICAgICBsb2NhbEFIW2kgLSBzdGFydFJvd10gPSBjICogWltpXSArIEQgKiBtYXRyaXhSb3dEb3QoTVgsIE1SLCBpKTsKICAgICAgICB9CgogICAgICAgIC8vIEdhdGhlciByZXN1bHRzIGF0IHJhbmsgMAogICAgICAgIGludFtdIEFIID0gbnVsbDsKICAgICAgICBpZiAocmFuayA9PSAwKSB7CiAgICAgICAgICAgIEFIID0gbmV3IGludFtIXTsKICAgICAgICB9CiAgICAgICAgTVBJLkNPTU1fV09STEQuR2F0aGVyKGxvY2FsQUgsIDAsIGVuZFJvdyAtIHN0YXJ0Um93LCBNUEkuSU5ULCBBSCwgMCwgcm93c1BlclByb2Nlc3MsIE1QSS5JTlQsIDApOwoKICAgICAgICBpZiAocmFuayA9PSAwKSB7CiAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiQUg6ICIgKyBBcnJheXMudG9TdHJpbmcoQUgpKTsKICAgICAgICB9CgogICAgICAgIE1QSS5GaW5hbGl6ZSgpOwogICAgfQoKICAgIC8vIFV0aWxpdHkgbWV0aG9kIHRvIGZpbGwgYSBtYXRyaXggd2l0aCBhIHNwZWNpZmljIHZhbHVlCiAgICBwdWJsaWMgc3RhdGljIGludFtdW10gZmlsbE1hdHJpeChpbnQgcm93cywgaW50IGNvbHMsIGludCB2YWx1ZSkgewogICAgICAgIGludFtdW10gbWF0cml4ID0gbmV3IGludFtyb3dzXVtjb2xzXTsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJvd3M7IGkrKykgewogICAgICAgICAgICBBcnJheXMuZmlsbChtYXRyaXhbaV0sIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hdHJpeDsKICAgIH0KCiAgICAvLyBVdGlsaXR5IG1ldGhvZCB0byBmaWxsIGEgdmVjdG9yIHdpdGggYSBzcGVjaWZpYyB2YWx1ZQogICAgcHVibGljIHN0YXRpYyBpbnRbXSBmaWxsVmVjdG9yKGludCBzaXplLCBpbnQgdmFsdWUpIHsKICAgICAgICBpbnRbXSB2ZWN0b3IgPSBuZXcgaW50W3NpemVdOwogICAgICAgIEFycmF5cy5maWxsKHZlY3RvciwgdmFsdWUpOwogICAgICAgIHJldHVybiB2ZWN0b3I7CiAgICB9CgogICAgLy8gQ29tcHV0ZSBkb3QgcHJvZHVjdCBvZiBtYXRyaXggcm93IGFuZCB2ZWN0b3IKICAgIHB1YmxpYyBzdGF0aWMgaW50IG1hdHJpeFJvd0RvdChpbnRbXVtdIG1hdHJpeDEsIGludFtdW10gbWF0cml4MiwgaW50IHJvdykgewogICAgICAgIGludCBzdW0gPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWF0cml4MVtyb3ddLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIHN1bSArPSBtYXRyaXgxW3Jvd11baV0gKiBtYXRyaXgyW2ldW3Jvd107IC8vIEFkanVzdGVkIGRvdCBwcm9kdWN0IGxvZ2ljCiAgICAgICAgfQogICAgICAgIHJldHVybiBzdW07CiAgICB9Cn0K