home   contents  previous      next        up

Виртуальные топологии ОС PARIX

В ОС PARIX имеются синхронные и асинхронные операции обмена сообщениями, работающие с понятием виртуальной топологии - топологии сети, образуемой виртуальными каналами. ОС PARIX предлагает богатый набор типов топологий - конвейер (Pipe),кольцо (Ring), двух/трех (2D/3D) мерные решетки (Grid) и торы (Torus), гиперкуб (HCube), клика (Clique), дерево (Tree и RTree). Более того, пользователь может создавать свои собственные топологии сетей, образованных виртуальными каналами.

Для каждого стандартного типа XXX топологии имеются функции, обеспечивающие создание, удаление коммуникационной сети с соответствующей топологией XXX.


int MakeXXX (	int RequestId,
             	dims . . .,
		int xmin, int xmax,
		int ymin, int ymax,
		int zmin, int zmax),

int FreeXXX (int topId),

XXXData_t * GetXXX_Data(int topId)
MakeXXX создает коммуникационную сеть с соответствующей топологией XXX размерностью dim, которая отображается на подмножество процессоров, описываемое параметрами xmin, xmax, ymin, ymax, zmin. Только процессоры, имеющие в разделе координаты (x, y, z) такие, что xmin <= x <= xmax , ymin <= y <= ymax и zmin <= z <= zmax будут использоваться в этой сети. Сети с топологией XXX (а именно ее каналам) необходимо сопоставить уникальный идентификатор канала, передаваемый через параметр RequestId и используемый ОС для того, чтобы различать сообщения, передаваемые по каналам разных сетей. Функция возвращает идентификатор сети (топологии). Каждый узел сети имеет каналы, связывающие его с соседними узлами. Количество каналов зависит от вида топологии сети. Для указания каналов используются целые значения от 0 до <число соседних узлов>-1, называемые логическими каналами. Например, все узлы сети с топологией кольцо имеют два канала для двух направлений - вперед, назад, которым сопоставлены логические каналы 1 и 0 соответственно. В сети с топологией клика каждый узел имеет каналы, связывающие его со всеми остальными узлами сети, - логический канал i представляет виртуальный канал, ведущий из узла с номером n к узлу с номером, получающимся из x инвертированием i-го бита (x ^ (1<<i)).

Функция FreeXXX удаляет сеть, имеющую указанный идентификатор. Функция GetXXX_Data возвращает указатель на дескриптор сети с указанным идентификатором. Дескриптор имеет следующий вид

struct XXXData_t {
char type; /* содержит имя топологии вида: XXX_TYPE (например. RING_TYPE) */
int status; /* указывает статус процессора, характеризующий его отношение к сети, его положение в сети. Например, для конвейера это значения PIPE_HEAD, PIPE_IN и PIPE_TAIL. Если процессор не входит в соответствующую сеть, то он имеет статус XXX_NONE (например. PIPE_NONE). */
xxx_t id; /* идентифицирует положение процессора в топологии. Например, для конвейера это значение в диапазоне 0 .. <длина_конвейера>-1, причем процессор со статусом PIPE_HEAD имеет id =0 , а процессор со статусом PIPE_TAIL - id = <длина_конвейера>-1 */
xxx_t dims; /* хранит размерности топологии. Например, для 2D решетки это ее ширина и высота */
};

Функции
int Send (int TopId, int LogLinkId, void *Data, int Size)
int Recv (int TopId, int LogLinkId, void *Data, int Size)
реализуют синхронный обмен сообщениями в сети с топологией, имеющей идентификатор TopId. Параметр LogLinkId указывает, какой логический канал топологии следует использовать для приема/передачи сообщения.

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

#include <virt_top.h>
#define BACKWARD 	0
#define FORWARD 	1
   int topId;
   int reqId = 0;
   PipeData_t * pipeData;
   int prev; 
   topId = MakePipe (reqId, pipe_len, MINSLICE, MAXSLICE,
		      MINSLICE, MAXSLICE, MINSLICE,MAXSLICE);
   pipeData = GetPipe_Data (topId);

   switch (pipeData->status)
   {
	case PIPE_NONE:
	break;
	case PIPE_HEAD:
	   Send (topId, FORWARD, (char *)&pipeData->id, sizeof (int));
	break;
	case PIPE_IN:
	   Recv (topId, BACKWARD, &prev,sizeof (int));
	   Send (topId, FORWARD, (char *)&pipeData->id, sizeof (int));
	break;
	case PIPE_TAIL:
	   Recv (topId, BACKWARD, &prev,sizeof (int));
	break;
   }
   FreePipe (topId);   
Используя функции
int NewTop (int nLinks),
int AddTop (int TopId, LinkCB_t *Link),
пользователь может создавать свои собственные топологии сетей виртуальных каналов. Функция NewTop, с вызова которой начинается процедура формирования топологии, создает в памяти вызвавшего ее процессора некоторую внутреннюю таблицу под предполагаемое количество (nLinks) каналов, и возвращает идентификатор топологии. Идентификатор с этого момента представляет вновь образованную топологию. Внутренняя таблица будет хранить указатели на дескрипторы виртуальных каналов топологии. Если количество созданных каналов превысит nLinks, то ОС увеличит размер таблицы на некоторую величину.

Функция AddTop добавляет новый виртуальный канал Link к топологии TopId и возвращает идентификатор представляющего его логического канала (LogLinkId). С этого момента логический канал LinkId топологии TopId можно использовать для обмена сообщениями. Функция
LinkCB_t *GetLinkCB (int TopId, int LogLinkId, int *Error)
позволяет получить указатель на виртуальный канал логического канала LinkId топологии TopId. Удалить топологию, е§ каналы можно с помощью функции
int FreeTop (int TopId),
которая удаляет внутренние структуры топологии, неявно освобождает каждый канал сети и внутренние данные, используемые при асинхронных коммуникациях.

Каждая топология имеет свои ей присущие свойства такие, как размерности dim_x, dim_y, dim_z трехмерных реш§тки и тора, глубина дерева и число потомком у его вершин. Функция
int AddTop_Data (int TopId, void *Data)
позволяет связать с топологией е§ атрибуты, хранящиеся в дескрипторе Data. Затем их можно будет извлечь с помощью функции
void *GetTopData (int TopId, int *Error)
В следующем примере функция mkHCube создает сеть с топологией гиперкуб

int mkHCube(void)
{ int mask, err;
  int reqId = 0;
  int top = NewTop(0);
  
  for (mask=1; mask < PC_nProcs; mask << 1)
     AddTop(top, ConnectLink(PC_MyID ^ mask, reqId, $err));

  return top;
}

Следующий набор функций, реализует асинхронные обмены сообщениями по каналам виртуальных топологий.
int AInit (int TopId, int Threads, int Size)
int ASend (int TopId, int LogLinkId, byte *Data, int Size, int *Result)
int ARecv (int TopId, int LogLinkId, byte *Data, int Size, int *Result)
int ASync (int TopId, int LogLinkId)
int AExit (int TopId)
Асинхронная связь обеспечивает параллельное выполнение вычислений и коммуникаций. Во всех функциях параметр TopId указывает топологию (сеть каналов), которая будет использоваться для обмена сообщениями. Перед использованием асинхронной связи, необходимо вызвать функцию Ainit, которая инициализирует все структуры данных, используемые операциями обмена сообщениями ASend и Arecv. Параметры Ainit определяют количественные характеристики асинхронной связи - параметр Threads задает максимальное число сопроцессов, которые могут одновременно существовать в процессе асинхронной связи, параметр Size - максимальный размер памяти, который можно использовать для осуществления асинхронной связи. Если Size = 0, то посылаемые данные не будут копироваться во временный буфер. Если Ainit вызывается повторно, то она только устанавливает новые значения параметров связи. Для приема и передачи сообщений служат функции ASend и Arecv. Завершаться асинхронная связь должна вызовом AExit, которая ждет завершения всех коммуникаций, затем прерывает выполнение сопроцессов, активированных в процессе асинхронной связи, и освобождает память, использовавшуюся при этом. Функция ASync только ждет завершения всех коммуникаций, но не прерывает выполнение сопроцессов.


home   contents  previous      next        up