Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 24.12.2009, 12:27   #1
mages
 
Регистрация: 23.12.2009
Сообщений: 9
По умолчанию Параллельное программирование

Здравствуйте ! возникла проблема с программой.
Делаю зачетную работу; Дана квадратная матрица NxM. Найти максимальные элементы каждой строки (N кратно количеству процессов).
Написал программу, на 6 процессах на матрице 6х6 вроде бы работает нормально, находит максимальные элементы строки, но! ставит их не в том порядке как надо.
пример матрицы 6 на 6
6 6
1 2 3 4 5 6
1 2 3 4 5 7
1 2 3 4 5 8
1 2 3 4 5 9
1 2 3 4 5 10
1 2 3 4 5 11
ответ;
6
12 и дальше уже по другому порядке
7 или 9
9 или 7
10 или 11
11 или 10
Подобные вещи и на 4 процессах при матрице 4 на 4.
а вот и решение

Код:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <mpi.h>


void Init(FILE *f, int m,int n, double *B)
{int i,j; 
 for(i=0;i<m;i++) {
 for(j=0;j<n;j++)fscanf(f,"%lf",&B[i*m+j]);}
 fscanf(f,"\n"); 
 for(i=0;i<m;i++)
 {
  for(j=0;j<n;j++)
  printf("%4.lf",B[i*m+j]);
  printf("\n");
 }
}
  

  double Max( double *B,int m,int n)
 {
  int i,j; 
  double  max1;
  max1 = B[0];
  for(i = 0; i < m; i++)
   { max1=B[0];
     for(j = 0; j < n; j++)     
    { if (B[i*m+j] > max1)
      max1 = B[i*m+j];}
      //for(i=0;i<k;i++)
      printf("max=%lf\n",max1);
    }
   }  
  
  
  void print(double *B,int m,int n)
  {
   int i,j;
   for(i=0;i<m;i++){  
   for(j=0;j<n;j++) printf("%4.0lf",B[i*m+j]); printf("\n");
  }
 }
  
 
  int main (int argc,char *argv[])
  { 
   FILE *f=fopen("input.txt","r");
   int i,np,rk,m,n,chunk=1; 
   double *B,*Bloc,t;
  
  MPI_Init(&argc,&argv);
  MPI_Comm_size(MPI_COMM_WORLD,&np);
  MPI_Comm_rank(MPI_COMM_WORLD,&rk);
  if(rk==0)
  { 
   fscanf(f,"%d ",&m); fscanf(f,"%d\n",&n);
   chunk=m/np;
   B=(double *)malloc(m*n*sizeof(double));
  }
  MPI_Bcast(&m,1, MPI_INT,0, MPI_COMM_WORLD);
  MPI_Bcast(&chunk,1, MPI_INT,0, MPI_COMM_WORLD);
  Bloc=(double *)malloc(chunk*n*sizeof(double));
  
  if (rk==0)
  {
   Init(f,m,n,B);
   t=MPI_Wtime();
  }
  MPI_Scatter(B,m*chunk,MPI_DOUBLE,Bloc,m*chunk,MPI_DOUBLE,0,MPI_COMM_WORLD);
  Max(Bloc,chunk,n);
  MPI_Gather(Bloc,m*chunk,MPI_DOUBLE,B,m*chunk,MPI_DOUBLE,0,MPI_COMM_WORLD);
  
  if(rk==0)
  {
   t=MPI_Wtime()-t;
   printf("%lf sec. \n",t);
   // print(B,m,n);
  }
   //MPI_Finalize();
  return 0;
}
что в программе не так?

Последний раз редактировалось mages; 24.12.2009 в 18:26.
mages вне форума Ответить с цитированием
Старый 24.12.2009, 13:38   #2
RoS
Форумчанин
 
Аватар для RoS
 
Регистрация: 13.12.2009
Сообщений: 272
По умолчанию

Цитата:
Дана квадратная матрица NxM
ПО-моему матрица квадратная требует только один индекс о_0
По теме - с MPI не знаком в принципе
Если я помог вам - порадуйте меня, нажмите на весы слева
RoS вне форума Ответить с цитированием
Старый 24.12.2009, 16:16   #3
BleStaR
Форумчанин
 
Регистрация: 25.09.2009
Сообщений: 234
По умолчанию

Это конечно не ответ на твой вопрос, но как минимум:
Твой кусок из функции Max:
Код:
max1 = B[0];
for(i = 0; i < m; i++)
{ max1=B[0];
первая строка не нужна (инициализации все равно будет внутри цикла), и внутри цикла тебе нужно брать первый элемент строки, а не массива.
Т.е.
Код:
for(i = 0; i < m; i++)
{ max1=B[i*m];
BleStaR вне форума Ответить с цитированием
Старый 24.12.2009, 16:36   #4
m0nax
Форумчанин
 
Аватар для m0nax
 
Регистрация: 25.09.2009
Сообщений: 525
По умолчанию

код не читал, но как я понял тут речь про потоки(или процессы)
Цитата:
ставит их не в том порядке как надо
дык это нормально совершенно, а как же иначе?

вся суть потоков как раз в том что они работают независимо друг от друга(ну в простых случаях), запускаются они как хотят и завершаются когда хотят

если сделать ожидание завершения предыдущего потока то пропадет вообще весь смысл параллельного выполнения, будет тот же самый линейный main
m0nax вне форума Ответить с цитированием
Старый 24.12.2009, 17:29   #5
BleStaR
Форумчанин
 
Регистрация: 25.09.2009
Сообщений: 234
По умолчанию

m0nax
в коде зря не разбирался (сам в MPI всего 40 мин)
Про потоки ты прав - работают сами по себе и завершаются когда хотят, с процессами вроде история такая же. Но в коде испльзуются функция которая собирает даные от процессов в буфер, причем в правильном порядке (т.е. по порядку создания процессов) не зависимо от того какой из них закончил раньше.
BleStaR вне форума Ответить с цитированием
Старый 24.12.2009, 17:35   #6
BleStaR
Форумчанин
 
Регистрация: 25.09.2009
Сообщений: 234
По умолчанию

mages вновь по поводу функции Max: моя ошибка (все же правильно max1=B[0]
Но для чего ты обрабатываешь ее через два for'a?
Ты передаешь туда Bloc - который представляет собой строку из твоего B. Вполне можно и одним обойтись да и лишние параметры не надо будет передавать (количество строк)
BleStaR вне форума Ответить с цитированием
Старый 24.12.2009, 17:45   #7
mages
 
Регистрация: 23.12.2009
Сообщений: 9
По умолчанию

так щас фором и б разберусь значит ) если что не так напишу.
а порядок ответов да , может быть разброс это нормально ) долго очень доходило
mages вне форума Ответить с цитированием
Старый 24.12.2009, 17:55   #8
BleStaR
Форумчанин
 
Регистрация: 25.09.2009
Сообщений: 234
По умолчанию

mages касательно твоего вопроса.
Ошибка:
В каждом из твоих процессов вызывается функция Max которая в конечном итоге выводит на экран максимальное в строке. Но процессы(как обсуждалось выше) работают самостоятельно и кто будет первый кто последний не известно (поэтому порядок вывода ты не можешь контролировать). Ты используешь функцию MPI_Gather, которая должна собрать все данные с процессов. Но в дальнейшем ты ни где пользуешься результатом работы этой функции.

Вариант решения:
Введи еще одну переменную max в Main в ней сохраняй результат работы функции Max. И еще один массив (masMax[m]) для записывания этих данных. Процессы вычислят максимальные и отдадут их root'у. Который их собирает в masMax после чего выводит его.
BleStaR вне форума Ответить с цитированием
Старый 24.12.2009, 17:57   #9
mages
 
Регистрация: 23.12.2009
Сообщений: 9
По умолчанию

так проблемка снова, если я делаю 6 процессов и матрицу 3 на 3 , то не находит максимум. но вот если max1=B[0] изменить то без разницы кажется, это и то правильные чтоле о0
mages вне форума Ответить с цитированием
Старый 24.12.2009, 18:00   #10
mages
 
Регистрация: 23.12.2009
Сообщений: 9
По умолчанию

BleStaR помоги как програмку подправить
mages вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
стандартная сортировка пузырьком. параллельное программирование. lamont61 Помощь студентам 2 11.12.2009 15:12
Параллельное программирование Renegad Фриланс 5 10.06.2008 18:11
Реализация модели эволюции клетки. Параллельное программирование на языке с. Заноза Помощь студентам 4 03.04.2008 22:13
Параллельное программирование Ugly Win Api 7 16.03.2008 15:33