description

This commit is contained in:
2025-03-24 10:30:03 +04:00
parent e780cf2143
commit cec1585b81

View File

@@ -104,6 +104,88 @@ mpjrun.sh -np 4 -dev niodev -machinesfile mach App -- 4
- Используются **настроенные типы данных MPI** (массивы фиксированной длины). 
- Ввод размера матрицы происходит через аргументы командной строки.
```java
public static void main(String[] args) {
MPI.Init(args);
int threadCount = MPI.COMM_WORLD.Size();
int rank = MPI.COMM_WORLD.Rank();
int[] matr = new int[0];
int size = 0;
long startTime = System.nanoTime();
if (rank == 0){ // Генерации матрицы в 0 процесса
Scanner s = new Scanner(System.in);
Random r = new Random();
size = Integer.parseInt(args[args.length - 1]);
System.out.println("Matrix size: " + size);
matr = new int[size * size];
for (int i = 0; i < size * size; i++) {
matr[i] = r.nextInt(10) + 1;
}
}
int[] bfSize = {size};
// Раскидывание размера матрицы по всем процесса
MPI.COMM_WORLD.Bcast(bfSize,0, 1,MPI.INT, 0);
size = bfSize[0];
if (size == 0){
return;
}
// Новый тип данных, чтобы кидать массив
Datatype dta = Datatype.Contiguous(size, MPI.INT);
dta.Commit();
// Распредение сколько каждому процессу строк оттдать
int[] sendCount = new int[threadCount];
for (int i = 1; i < threadCount; i++) {
sendCount[i] = size / (threadCount - 1);
};
for (int i = 0; i < size % (threadCount - 1); i++) {
sendCount[threadCount - 1 - i] += 1;
}
// Смещение для каждого из потоков(откуда считывать)
int[] displs = new int[threadCount];
displs[0] = 0;
for (int i = 1; i < threadCount; i++) {
displs[i] = displs[i - 1] + sendCount[i - 1];
}
int[] recBuf = new int[size * sendCount[rank]];
if (rank == 0) {
System.out.println("Start scatterv");
}
// Расспределение на процессы
MPI.COMM_WORLD.Scatterv(matr, 0, sendCount, displs, dta,
recBuf, 0, sendCount[rank], dta, 0);
System.out.println("Rank " + rank + " : " + print(recBuf));
// Расслыка процессами количества принимаемого на каждый процесс
MPI.COMM_WORLD.Bcast(sendCount, 0, sendCount.length, MPI.INT, 0);
int[] sendBuf = new int[sendCount[rank]];
if (rank != 0) { // Вычисление кому какую порцию данных дать(именно выбрать какую строчку и сколько на каждый процесс)
for (int i = 0; i < sendCount[rank]; i++) {
int sum = 1;
for (int j = 0; j < recBuf.length / sendCount[rank]; j++) {
sum *= recBuf[i * recBuf.length / sendCount[rank] + j];
}
sendBuf[i] = sum;
}
}
System.out.println("Out rank " + rank + " : " + print(sendBuf));
// Расрапдедение индексов смещения на каждый процесс
MPI.COMM_WORLD.Bcast(displs, 0, displs.length, MPI.INT, 0);
int[] recBuf2 = new int[size];
// Сбор данных на 0 процесс
MPI.COMM_WORLD.Gatherv(sendBuf, 0, sendCount[rank], MPI.INT,
recBuf2,0, sendCount, displs, MPI.INT, 0);
// Результируюший подсчет
if (rank == 0){
int resSum = Arrays.stream(recBuf2).sum();
System.out.println("Res sum: " + resSum);
System.out.println("Res time: " + (System.nanoTime() - startTime));
}
}
```
## Пример вывода
```
@@ -132,5 +214,8 @@ Stopping Process <0> on <cont1>
## Вывод
В рамках лабораторной работы была реализована система распределенных вычислений с использованием MPJ Express. Программа успешно демонстрирует работу с MPI в кластере контейнеров, включая передачу данных, выполнение расчетов и сбор результатов. Получен опыт настройки окружения и взаимодействия контейнеров через SSH.
В рамках лабораторной работы была реализована система распределенных вычислений с использованием MPJ Express.
Программа успешно демонстрирует работу с MPI в кластере контейнеров, включая передачу данных, выполнение расчетов и сбор результатов. Получен опыт настройки окружения и взаимодействия контейнеров через SSH.
В сравнении с классической реализации потоков, можно отметить что облегчается сам процесс написания кода, ведь надо написать всего лишь один экзепляр и не задумываться над распределением задач.
Но более затратно по времени развренуть и настроить общение между узлами.