|
МВС-1000 / Документация
Инструкция прикладному программисту
по коммуникационной среде Router+ для МВС-1000.
На МВС-1000 кластерной архитектуры с
коммуникационной сетью, отличной от Ethernet, коммуникационная библиотека Router в настоящее время не
поддерживается. Для переноса прикладных программ, использующих Router на уровне базовых
возможностей, В. А. Абрамовой разработана реализация основных функций
Router на MPI. Реализация в виде исходных текстов:
func.h
#define r_write mpi_r_write
#define w_write mpi_w_write
#define t_write mpi_t_write
#define r_read mpi_r_read
#define w_read mpi_w_read
#define t_read mpi_t_read
#define sysProcNumGet mpi_sysProcNumGet
#define sysProcTotalGet mpi_sysProcTotalGet
/* int r_write( int channo, char *what, int leng );
int w_write( int channo );
int r_read( int channo, char *what, int leng );
int w_read( int channo );
int t_write( int channo );
int t_read( int channo );
double ttime(void);
int sysProcNumGet(void);
int sysProcTotalGet(void);
*/
func.c
#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
#include "func.h"
#define FALSE 0
static MPI_Request hs_req[640];
static MPI_Request hr_req[640];
static int hs_guard[640];
static int hr_guard[640];
int r_write( int channo, char *what, int leng )
{
int rz;
/* printf("func: before mpi_isend channo=%d len=%d\n",
channo, leng); */
if(hs_guard[channo] != 0)
printf("func: second r_write without w_write\n");
rz = MPI_Isend(what, leng, MPI_BYTE, channo, 17,
MPI_COMM_WORLD, &hs_req[channo]);
/* printf("func: after mpi_isend rz=%d\n", rz);*/
return(rz);
}
/* wait for write over function: */
int w_write( int channo )
{
MPI_Status status;
/* printf("func: before mpi_w_write chan=%d\n",channo);*/
MPI_Wait(&hs_req[channo],&status);
hs_guard[channo]=0;
/* printf("func: after mpi_w_write \n");*/
return(1);
}
/* test functions: */
int t_write( int channo )
{ int flag;
MPI_Status status;
MPI_Test(&hs_req[channo], &flag, &status);
if(flag != FALSE)
hs_guard[channo]=0;
return (flag);
}
/* start read function: */
int r_read( int channo, char *what, int leng )
{
int rz;
if(hr_guard[channo] != 0)
printf("func: second r_read without w_read\n");
rz = MPI_Irecv(what, leng, MPI_BYTE, channo, 17,
MPI_COMM_WORLD, &hr_req[channo]);
/* printf("func: after mpi_irecv rz=%d\n", rz);*/
return(rz);
}
/* wait for read over function: */
int w_read( int channo )
{
MPI_Status status;
/* printf("func: before mpi_w_read chan=%d\n",channo);*/
MPI_Wait(&hr_req[channo],&status);
hr_guard[channo]=0;
/* printf("func: after mpi_w_read chan=%d\n",channo);*/
return (1);
}
/* test functions: */
int t_read( int channo )
{ int flag;
MPI_Status status;
MPI_Test(&hr_req[channo], &flag, &status);
if(flag != FALSE)
hr_guard[channo]=0;
return (flag);
}
int sysProcNumGet (void)
{ int rz;
for(rz=0;rz!=640; rz++)
{ hr_guard[rz]=0;
hs_guard[rz]=0;
}
MPI_Comm_rank(MPI_COMM_WORLD,&rz);
return (rz);
}
int sysProcTotalGet(void)
{ int rz;
MPI_Comm_size(MPI_COMM_WORLD,&rz);
return (rz);
}
void grab_server(void){}
void ungrab_server(void){}
Пример программы tnet на базе этой реализации:
tnet.c
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include "func.h"
#define SIZMES 250000
static int *buffers[1000];
int main( int argc, char *argv[] )
{
int i, j, k, times, my_number, total;
double starttime;
/***/
printf( "Starting\n" );
/*
if ( !rf_create() )
{
printf( "rf_create error\n" );
return( -1 );
}
*/
MPI_Init( &argc, &argv );
my_number = sysProcNumGet();
total = sysProcTotalGet();
for ( i = 0; i < total; i++ )
{
if ( (buffers[i] = malloc( SIZMES*sizeof( int ) )) == NULL )
{
printf( "No memory\n" );
return( -1 );
}
}
printf( "Hellow, I am tnet, #%d Total %d\n",
my_number, total );
times = 1000000;
printf( "Running all routes %d times\n", times );
starttime = MPI_Wtime();
while ( times-- )
{
for ( i = 0; i < total; i++ )
{
if ( i != my_number )
{
for ( k = 0; k < SIZMES; k++ ) (buffers[i])[k] = -1;
r_read( i, (char*)buffers[i], SIZMES*sizeof( int ) );
}
}
j = 0;
for ( k = 0; k < SIZMES; k++ )
(buffers[my_number])[k] = my_number + k;
for ( i = 0; i < total; i++ )
{
if ( i != my_number )
{
r_write( i, (char*)buffers[my_number], SIZMES*sizeof( int ) );
w_write( i );
}
}
/*
for ( i = 0; i < total; i++ )
{
if ( i != my_number )
{
w_write( i );
}
}
*/
for ( i = 0; i < total; i++ )
{
if ( i != my_number )
{
w_read( i );
for ( k = 0; k < SIZMES; k++ )
{
if ( (buffers[i])[k] != (i+k) )
{
printf( "Processor %d received %d instead of %d from %d\n",
my_number, (buffers[i])[k], i+k, i );
j++;
}
}
}
}
if ( !my_number )
{
printf( "Processor %d received from all with %d errors in"
" %f seconds\n",
my_number, j, (float)(MPI_Wtime()-starttime) );
fflush( stdout );
}
}
printf( "I am almost over\n" );
fflush( stdout );
MPI_Finalize();
printf( "I am over\n" );
fflush( stdout );
return( 0 );
}
Из примера видно, как именно следует оформлять инициализирующую часть программы (в этой части
предлагаемая реализация Router
несколько отличается от разработанных ранее).
|
|