LINUX.ORG.RU

MPI вызов функций.

 ,


0

1

Доброго времени суток. Нужно решить несколько не сложных лаб с MPI. Вообще все сводится к вызовам некольких функций. Есть идеи алгоритмов решения сеих задачек, есть описания функций, но я не все понимаю. Эту темку я создаю в надежде что мне помогут закрасить белые пятная в понимании mpi. К примеру не могу разобраться с описателем типа

MPI_Datatype *mychar;
MPI_Type_vector (int count, int 3, int 2, MPI_Data_type, MPI_Char, MPI_Datatype *mychar);
MPI_Type_commit(*mychar);
Как я понимаю: MPI_Datatype - просто создает ссылку на область памяти для будущего типа. MPI_Type_vector - описывает векторный тип, с указанием количества блоков, их длины и расстояния между соседними блоками(про это stride не понимаю), потом указывается базовый тип в MPI для нового типа, и собственно область памяти, созданная MPI_Datatype, куда поместится новый тип. MPI_Type_commit - создает тип описанный в MPI_Type_vector ипомещает в память из MPI_Datatype. И как бы 3 этих шага необходимы и достаточны для описани «пользовательского» типа? Этот момент я правильно понимаю?

Ответ на: комментарий от anonymous

первая ссылка-тоже моя тема... в смысле там ее создал я. 2ю ссылку читал, но все еще не до конца понимаю. почему я решил что не понимаю-потому что код не работает... =(

crazzzzzy ()
Ответ на: комментарий от crazzzzzy

первая ссылка-тоже моя тема... в смысле там ее создал я.

это для большего понимания последующим зашедшим в тему людям. у тебя же сломалась разметка (стоит использовать теги [code])

anonymous ()

хорошо, попытаюсь ответить на твой вопрос.

MPI_Datatype - просто создает ссылку на область памяти для будущего типа.

да, но здесь нужно не это. нужно просто объявить переменную этого типа. Тип, если верить mpi.h - int. Правильная строчка должна быть примерно такой:

MPI_Datatype mychar;
// или
MPI_Datatype *mychar = (MPI_Datatype*)malloc(sizeof(MPI_Datatype));

MPI_Type_vector - описывает векторный тип, с указанием количества блоков, их длины и расстояния между соседними блоками(про это stride не понимаю), потом указывается базовый тип в MPI для нового типа, и собственно область памяти, созданная MPI_Datatype, куда поместится новый тип.

Последним параметром должен быть передан указатель на переменную типа MPI_Datatype, память в под неё должна быть уже выделена. Исправить примерно так:

MPI_Type_vector(count, 3, 2, MPI_Char, &mychar);
// или, для второго случая:
MPI_Type_vector(count, 3, 2, MPI_Char, mychar);
При вызове функции не нужно повторно указывать тип переменной. Компилятор уже знает её тип.

stride - это выравнивание элементов памяти, для повышения скорости обращения к элементам вектора. Считай тонкой настройкой вектора и если ты не знаешь зачем это надо, значит в твоей задаче это не нужно.

пример

MPI_Type_commit - создает тип описанный в MPI_Type_vector ипомещает в память из MPI_Datatype.

Объявляет о новом типе остальным потокам или кому там. Без этой строчки больше никто не узнает о новом типе.

anonymous ()
Ответ на: комментарий от anonymous

я решаю такую :«Создать описатель типа и использовать его при передаче данных в качестве шаблона для следующего преобразования: при передачестроки дублируются последовательные триады символов.» вот весь код моей программы-

#include <stdio.h>
#include <string>
#include <iostream>
#include <mpi.h>
#include <stdlib.h>

using namespace std;

int strlen(string s)
{
  int res = 0;
  while (s[res])
  {			
    res++;
  }	
  return res;
}

int block_count(int i)
{
  int ost = i % 3, result = i / 3;
  if (ost != 0)
    result++;
  return result;
}

int main(int argc, char *argv[])
{ //раздел описания
  string s;
    cin >> s;
		
  int len = 0, block_size = 3, str_length = strlen(s), block_number = block_count(strlen(s)); 
  char *streeng_for_send =  (char*)malloc(str_length);
  int rank, size, i;
	
  while (s[len])
  {
    streeng_for_send[len] = s[len];
    len++;
  }

//конец раздела описания

  MPI_Init (&argc, &argv);
  MPI_Comm_rank (MPI_COMM_WORLD, &rank);
  MPI_Comm_size (MPI_COMM_WORLD, &size);	
  MPI_Status *status;
  MPI_Datatype *mychar = (MPI_Datatype*)malloc(str_length);
  MPI_Type_vector (str_length, 3, 2, /* *MPI_Char*/, mychar);
  MPI_Type_commit(mychar);
			
  MPI_Sendrecv (*streeng_for_send, str_length, *mychar, 1, 50, *streeng_for_send, str_length * 2,  *mychar,  0, 50, /*comm*/, *status); 
		
  cout << str_length << "\n";
  cout << block_number << "\n";
	
  MPI_Finalize();
  return 0;
}

в MPI_Type_vector и MPI_Sendrecv ругается на параметры, которые сейчас закоментарены.что в моем случае надо туда указывать? и еще вопрос в том-как он должен копировать эти триады символов? или нужно разделять Sendrecv на отдельные функции, и при приеме писать код дублирования триад?

crazzzzzy ()
Ответ на: комментарий от crazzzzzy

вызов функции MPI_Type_vector:

MPI_Type_vector (str_length, 3, 2, /* *MPI_Char*/, mychar);

  • параметры blocklength и stride: Рис. 5.2..
  • параметр oldtype: зачем *, в прототипе функции указан тип MPI_Datatype, в описании MPI_Char (mpi.h):
    #define MPI_CHAR           ((MPI_Datatype)1)
    

Читай сообщения компилятора, там это было указано, давай со второй функцией попробуй разобраться. Не получится пиши.

И выделять память лишний раз, не стоило. Тут отлично смотрелся бы первый предложенный вариант.

-MPI_Datatype *mychar = (MPI_Datatype*)malloc(str_length);
+MPI_Datatype mychar;

anonymous ()
Ответ на: комментарий от anonymous

оно компилится.объявил MPI_Comm comm, и правильно написал MPI_CHAR.

int main(int argc, char *argv[])
{ //раздел описания
  string s;cin >> s;		
  int len = 0, block_size = 3, str_length = strlen(s), block_number = block_count(str_length); 
	char *streeng_for_send =  (char*)malloc(str_length);
//конец раздела описания
  int rank, size, i;
  MPI_Init (&argc, &argv);
  MPI_Comm_rank (MPI_COMM_WORLD, &rank);
  MPI_Comm_size (MPI_COMM_WORLD, &size);	
  MPI_Status status;
  MPI_Comm comm;	
  MPI_Datatype mychar;
  MPI_Type_vector (str_length, 3, 5, MPI_CHAR, &mychar);
  MPI_Type_commit(&mychar);
			
  MPI_Sendrecv(streeng_for_send, str_length, mychar, 1, 50, streeng_for_send, str_length * 2,  mychar,  0, 50, comm, &status); 
		
  for (i = 0; i < sizeof(streeng_for_send); i++)
  {
    cout << streeng_for_send[i] ;
  }
  MPI_Finalize();
  return 0;
}
но при попытке запустить:
andrey@ubuntu:~/learn/paral$ mpirun -np 1 ./try1
q
Fatal error in MPI_Sendrecv: Invalid communicator, error stack:
MPI_Sendrecv(217): MPI_Sendrecv(sbuf=0xf86070, scount=1, dtype=USER<vector>, dest=1, stag=50, rbuf=0xf86070, rcount=2, dtype=USER<vector>, src=0, rtag=50, comm=0x1, status=0x7fffaddd25f0) failed
MPI_Sendrecv(88).: Invalid communicator
происходит это. это первая задача которую я делаю на с++ в убунту без ide. после теплой и удобной вижуал студии под виндой это пока что не понятно и не привычно. не могли бы вы подсказать почему оно умерло?

crazzzzzy ()
Ответ на: комментарий от crazzzzzy

с++ в убунту без ide

$ sudo apt-get install qtcreator

Invalid communicator

вероятно с этим проблема в указанном ранее примере в этом поле находилась константа MPI_COMM_WORLD.

Обучаться лучше с запуска работающего примера и последовательного переноса кода в свою задачу.

Ваш ход.

anonymous ()
Ответ на: комментарий от anonymous

могу ответить только тем, что моя убунта 12.10 категорически отказывается устанавливать этот пакет. нету, говорит. думаю надо ее оновить как то. сейчас буду искать. а то это не единственный пакет который она отвергла

crazzzzzy ()
Ответ на: комментарий от crazzzzzy

в /etc/apt/source.list добавить репозиторий старых версий ubuntu, с соответствующей версией:

deb http://old-releases.ubuntu.com/ubuntu/ quantal universe
$ sudo apt-get update
$ sudo apt-get install qtcreator

а лучше обновить ubuntu, уже два года прошло с момента релиза.

anonymous ()
Ответ на: комментарий от anonymous

на момент написания того поста я не понимал в чем проблема. не доступны источники, с которых убунта черпала обновления. либо на них уже ничего не выкладывается.

W: Не удалось получить http://security.ubuntu.com/ubuntu/dists/quantal-security/restricted/binary-amd64/Packages  404  Not Found [IP: 91.189.91.14 80]
Ош http://security.ubuntu.com quantal-security/restricted amd64 Packages
  404  Not Found [IP: 91.189.91.14 80]
это примеры того что он пишет. а ссылки на новые я пока что не нашел

crazzzzzy ()
Ответ на: комментарий от crazzzzzy

не доступны источники, с которых убунта черпала обновления. либо на них уже ничего не выкладывается.

его там действительно нет, он считается устаревшим: Окончание срока поддержки 16 мая 2014. и искать его теперь нужно не на ubuntu.com, а на old-releases.ubuntu.com.

кто мешал зайти по ссылке в репозиторий и проверить? http://security.ubuntu.com/ubuntu/dists/

а ссылки на новые я пока что не нашел

это ж как нужно было искать?

anonymous ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.