ПВМ   ОКМ   ДМ   экономическая информатика   4GL   Теория и практика обработки информации

Параллельная виртуальная машина, PVM

Одномерное температурное уравнение

Здесь представлена программа ПВМ, которая вычисляет температурную диффузию в некой среде - в данном случае это проводник. Уравнение, описывающие одномерную температурную диффузию тонкого проводника:


\begin{displaymath}
\frac{\partial A}{\partial t}=\frac{\partial^{2}A}{\partial x^{2}}\end{displaymath}

Дискретизация:


\begin{displaymath}
\frac{A_{i+1,j}-A_{i,j}}{\Delta x}=\frac{A_{i,j+1}-2A_{i,j}+A_{i,j-1}}{\Delta x^{2}}\end{displaymath}

В результате получаем явную формулу:


\begin{displaymath}
A_{i+1,j}=A_{i,j}+\frac{\Delta t}{\Delta x^{2}}(A_{i,j+1}-2A_{i,j}+A_{i,j-1})\end{displaymath}

Начальные и граничные условия:

$A(t,0)=0,A(t,1)=0$- для всех $t$;

$A(0,x)=sin(\pi x)$- для $0\leq t\leq1$.

Псевдокодом для таких вычислений будет следующий:

for i = 1:tsteps-1;

  t = t+dt;

  a(i+1,1)=0;

  a(i+1,n+2)=0;

for j = 2:n+1;

  a(i+1,j)=a(i,j) + mu*(a(i,j+1)-2*a(i,j)+a(i,j-1));

end;

  t;

  a(i+1,1:n+2);

  plot(a(i,:))

end

Для данного примера используется модель "ведущий-ведомый". Ведущий - heat.c порождает пять копий программы heatslv. Ведомые параллельно вычисляют температурную диффузию "подсекций" проводника. На каждом шаге, ведомые обмениваются граничной информацией - в нашем случае температура проводника "определяет" границы между процессорами.

Присмотритесь к коду внимательнее. В программе heat.c массив solution будет удерживать результаты решений уравнения температурной диффузии на каждом шаге. Этот массив - в формате xgraph - будет "выходным" при завершении программы (xgraph - программа, предназначенная для вывода данных на графопостроитель). Сначала порождаются задачи heatslv. Далее, подготавливается исходный набор данных. Обратите внимание на то, что для конца проводника значением начальной температуры будет ноль.

Далее, четыре раза исполняется основная часть программы - каждый раз с новым значением $\Delta t$. Для определения количества времени, прошедшего от начала вычислений данной фазы, используется таймер. Начальный набор данных рассылается задачам heatslv. При каждой посылке совместно с начальным набором данных передаются идентификаторы задач-соседей слева и справа. Задачи heatslv будут использовать эту информацию при граничных коммуникациях. (В противном случае, нужно использовать групповые вызовы ПВМ для отображения задач на сегменты проводника. При использовании групповых вызовов, можно избежать явных указаний идентификаторов задач ведомых процессов.)

После рассылки исходных данных, ведущий процесс просто ожидает результаты. Когда результаты поступают, они интегрируются в результирующую матрицу, вычисляется затраченное время и решение записывается в xgraph-файл.

Как только все четыре фазы завершены, а результаты сохранены, ведущая программа выводит на экран информацию о временных затратах и принудительно завершает ведомые процессы.

Программа-пример heat.c:

/*

heat.c

Применение ПВМ для решения дифференциального уравнения, описывающего

простейшую температурную диффузию, с использованием 1 ведущей

программы и 5 ведомых

Ведущая программа формирует данные, посылает их ведомым и ожидает

результаты, возвращаемые ведомыми. Файлы с полученными результатами

готовы для использования программой xgraph

*/

#include "pvm3.h"

#include <stdio.h>

#include <math.h>

#include <time.h>

#define SLAVENAME "heatslv"

#define NPROC 5

#define TIMESTEP 100

#define PLOTINC 10

#define SIZE 1000

int num_data = SIZE/NPROC;

 

main()

{

  int mytid, task_ids[NPROC], i, j;

  int left, right, k, l;

  int step = TIMESTEP;

  int info;

  double init[SIZE], solution[TIMESTEP][SIZE];

  double result[TIMESTEP*SIZE/NPROC], deltax2;

  FILE *filenum;

  char *filename[4][7];

  double deltat[4];

  time_t t0;

  int etime[4];

  filename[0][0] = "graph1";

  filename[1][0] = "graph2";

  filename[2][0] = "graph3";

  filename[3][0] = "graph4";

  deltat[0] = 5.0e-1;

  deltat[1] = 5.0e-3;

  deltat[2] = 5.0e-6;

  deltat[3] = 5.0e-9;

  /* регистрация в ПВМ */

  mytid = pvm_mytid();

  /* порождение ведомых задач */

  info = pvm_spawn(SLAVENAME,(char **)0,PvmTaskDefault,"",

         NPROC,task_ids);

  /* создание исходного набора данных */

  for (i = 0; i < SIZE; i++)

    init[i] = sin(M_PI * ( (double)i / (double)(SIZE-1) ));

    init[0] = 0.0;

    init[SIZE-1] = 0.0;

    /* четырехразовое выполнение с разными значениями дельты t */

    for (l = 0; l < 4; l++) {

      deltax2 = (deltat[l]/pow(1.0/(double)SIZE,2.0));

      /*засекаем время*/

      time(&t0);

      etime[l] = t0;

      /* передача исходных данных ведомым */

      /* дополнение информацией о соседях - для реализации возможности

       обмена граничными данными */

      for (i = 0; i < NPROC; i++) {

        pvm_initsend(PvmDataDefault);

        left = (i == 0) ? 0 : task_ids[i-1];

        pvm_pkint(&left, 1, 1);

        right = (i == (NPROC-1)) ? 0 : task_ids[i+1];

        pvm_pkint(&right, 1, 1);

        pvm_pkint(&step, 1, 1);

        pvm_pkdouble(&deltax2, 1, 1)

        pvm_pkint(&num_data, 1, 1);

        pvm_pkdouble(&init[num_data*i], num_data, 1);

        pvm_send(task_ids[i], 4);

      }

      /* ожидание результатов */

      for (i = 0; i < NPROC; i++) {

        pvm_recv(task_ids[i], 7);

        pvm_upkdouble(&result[0], num_data*TIMESTEP, 1);

       /* "обновление" решения */

        for (j = 0; j < TIMESTEP; j++)

          for (k = 0; k < num_data; k++)

            solution[j][num_data*i+k] = result[wh(j,k)];

      }

      /* остановка формирования временных интервалов */

      time(&t0);

      etime[l] = t0 - etime[l];

      /* получение выходных данных */

      filenum =(fopen_filename[l][0], "w");

      fprintf(filenum,"TitleText: Wire Heat over Delta Time: %e\n",

              deltat[l]);

      fprintf(filenum,"XUnitText: Distance\nYUnitText: Heat\n");

      for (i = 0; i < TIMESTEP; i = i + PLOTINC) {

        fprintf(filenum,"\"Time index: %d\n",i);

        for (j = 0; j < SIZE; j++)

          fprintf(filenum,"%d %e\n",j, solution[i][j]);

          fprintf(filenum,"\n");

      }

      fclose (filenum);

    }

    /* вывод на экран информации о временных интервалах */

    printf("Problem size: %d\n",SIZE);

    for (i = 0; i < 4; i++)

      printf("Time for run %d: %d sec\n",i,etime[i]);

    /* принудительное завершение ведомых процессов */

    for (i = 0; i < NPROC; i++) pvm_kill(task_ids[i]);

      pvm_exit();

  }

 

  int wh(x, y)

  int x, y;

  {

    return(x*num_data+y);

  }

Программы heatslv фактически реализуют вычисление температурной диффузии "на протяжении" проводника. Ведомая программа состоит из бесконечного цикла: прием исходного набора данных, итеративное вычисление результата на основе этого набора (с обменом граничной информацией с соседями при каждой итерации) и посылка результирующего частичного решения назад ведущему процессу.

Вместо создания бесконечных циклов в ведомых задачах, можно передавать специальные сообщения с приказами о завершении. Однако, во избежание сложностей, связанных с обменом сообщениями, в ведомых задачах используются именно бесконечные циклы, а завершаются они - принудительно - из ведущей программы. Третьим вариантом может быть реализация с ведомыми, исполняющимися только один раз и самостоятельно завершающимися после обработки единственных наборов данных, полученных от ведущего. Если бы этот вариант был воплощен, то к полезной нагрузке добавилась бы бесполезная.

В течение каждого шага каждой фазы, происходит обмен граничными значениями температурных матриц. Сначала, левосторонние граничные элементы передаются задаче-соседу слева, и соответствующие граничные элементы принимаются от задачи-соседа справа. Затем, симметрично, правосторонние граничные элементы передаются правому соседу, а соответствующие - принимаются от левого. Идентификаторы задач-соседей проверяются с целью обеспечения гарантий того, что не возникнет попыток передать сообщения несуществующим задачам (или принять).

Программа-пример heatslv.c:

/*

heatslv.c

Ведомые принимают исходные данные от хоста, обмениваются граничной

информацией с соседями и вычисляют изменение температуры проводника.

Это делается за несколько итераций - "под руководством" ведущего

*/

#include "pvm3.h"

#include <stdio.h>

int num_data;

 

main()

{

  int mytid, left, right, i, j, master;

  int timestep;

  double *init, *A;

  double leftdata, rightdata, delta, leftside, rightside;

  /* регистрация в ПВМ */

  mytid = pvm_mytid();

  master = pvm_parent();

  /* прием своих данных от ведущей программы */

  while(1) {

    pvm_recv(master, 4);

    pvm_upkint(&lef, 1, 1);

    pvm_upkint(&right, 1, 1);

    pvm_upkint(&timestep, 1, 1);

    pvm_upkdouble(&delta, 1, 1);

    pvm_upkint(&num_data, 1, 1);

    init = (double *) malloc(num_data*sizeof(double));

    pvm_upkdouble(init, num_data, 1);

    /* копирование исходных данных в свой рабочий массив */

    A = (double *) malloc(num_data * timestep * sizeof(double));

    for (i = 0; i < num_data; i++) A[i] = init[i];

     /* реализация вычисления */

     for (i = 0; i < timestep-1; i++) {

      /* обмен граничной информацией со своими соседями */

      /* передача налево, прием справа */

      if (left != 0) {

        pvm_initsend(PvmDataDefault);

        pvm_pkdouble(&A[wh(i,0)],1,1);

        pvm_send(left, 5);

      }

      if (right != 0) {

        pvm_recv(right, 5);

        pvm_upkdouble(&rightdata, 1, 1);

        /* передача направо, прием слева */

        pvm_initsend(PvmDataDefault);

        pvm_pkdouble(&A[wh(i,num_data-1)],1,1);

        pvm_send(right, 6);

      }

      if (left != 0) {

        pvm_recv(left, 6);

        pvm_upkdouble(&leftdata, 1, 1);

      }

      /* выполнение вычислений данной итерации */

      for (j = 0; j < num_data; j++) {

        leftside = (j == 0) ? leftdata : A[wh(i,j-1)];

        rightside = (j == (num_data-1)) ? rightdata : A[wh(i,j+1)];

        if ((j == 0) && (left == 0))

          A[wh(i+1,j)] = 0.0;

        else if ((j == (num_data-1)) && (right == 0))

          A[wh(i+1,j)] = 0.0;

        else

          A[wh(i+1,j)] =

          A[wh(i,j)]+delta*(rightside-2*A[wh(i,j)]+leftside);

      }

    }

    /* передача результатов назад ведущей программе */

    pvm_initsend(PvmDataDefault);

    pvm_pkdouble(&A[0],num_data*timestep,1);

    pvm_send(master,7);

  }

  /* только при удачном исходе */

  pvm_exit();

}

 

int wh(x, y);

int x, y;

{

  return(x*num_data+y);

}

ПВМ   ОКМ   ДМ   экономическая информатика   4GL   Теория и практика обработки информации

Знаете ли Вы, что устойчивость оптимального плана - это свойство математических моделей, имеющих форму задачи линейного программирования, состоящее в неизменности двойственных оценок ограничений при изменениях свободных членов ограничений в определённых пределах и в неизменности значений переменных при изменениях параметров целевой функции в определённых пределах.

НОВОСТИ ФОРУМА

Форум Рыцари теории эфира


Рыцари теории эфира
 10.11.2021 - 12:37: ПЕРСОНАЛИИ - Personalias -> WHO IS WHO - КТО ЕСТЬ КТО - Карим_Хайдаров.
10.11.2021 - 12:36: СОВЕСТЬ - Conscience -> РАСЧЕЛОВЕЧИВАНИЕ ЧЕЛОВЕКА. КОМУ ЭТО НАДО? - Карим_Хайдаров.
10.11.2021 - 12:36: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от д.м.н. Александра Алексеевича Редько - Карим_Хайдаров.
10.11.2021 - 12:35: ЭКОЛОГИЯ - Ecology -> Биологическая безопасность населения - Карим_Хайдаров.
10.11.2021 - 12:34: ВОЙНА, ПОЛИТИКА И НАУКА - War, Politics and Science -> Проблема государственного терроризма - Карим_Хайдаров.
10.11.2021 - 12:34: ВОЙНА, ПОЛИТИКА И НАУКА - War, Politics and Science -> ПРАВОСУДИЯ.НЕТ - Карим_Хайдаров.
10.11.2021 - 12:34: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Вадима Глогера, США - Карим_Хайдаров.
10.11.2021 - 09:18: НОВЫЕ ТЕХНОЛОГИИ - New Technologies -> Волновая генетика Петра Гаряева, 5G-контроль и управление - Карим_Хайдаров.
10.11.2021 - 09:18: ЭКОЛОГИЯ - Ecology -> ЭКОЛОГИЯ ДЛЯ ВСЕХ - Карим_Хайдаров.
10.11.2021 - 09:16: ЭКОЛОГИЯ - Ecology -> ПРОБЛЕМЫ МЕДИЦИНЫ - Карим_Хайдаров.
10.11.2021 - 09:15: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Екатерины Коваленко - Карим_Хайдаров.
10.11.2021 - 09:13: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Вильгельма Варкентина - Карим_Хайдаров.
Bourabai Research - Технологии XXI века Bourabai Research Institution