Add more datatype tests. One to check all communications to self, it is used
to compute the overhead of the convertor (and all convertor related operations). The second will check the position setting on the convertor. Not yet completed ... This commit was SVN r10432.
Этот коммит содержится в:
родитель
ec28040c58
Коммит
1e4199ee61
@ -9,7 +9,7 @@
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
check_PROGRAMS = ddt_test checksum
|
||||
check_PROGRAMS = ddt_test checksum position to_self
|
||||
|
||||
TESTS = $(check_PROGRAMS)
|
||||
|
||||
@ -20,3 +20,11 @@ ddt_test_LDADD = $(top_builddir)/ompi/libmpi.la
|
||||
checksum_SOURCES = checksum.c
|
||||
checksum_LDFLAGS = $(WRAPPER_EXTRA_LDFLAGS)
|
||||
checksum_LDADD = $(top_builddir)/ompi/libmpi.la
|
||||
|
||||
position_SOURCES = position.c
|
||||
position_LDFLAGS = $(WRAPPER_EXTRA_LDFLAGS)
|
||||
position_LDADD = $(top_builddir)/ompi/libmpi.la
|
||||
|
||||
to_self_SOURCES = to_self.c
|
||||
to_self_LDFLAGS = $(WRAPPER_EXTRA_LDFLAGS)
|
||||
to_self_LDADD = $(top_builddir)/ompi/libmpi.la
|
||||
|
20
test/datatype/position.c
Обычный файл
20
test/datatype/position.c
Обычный файл
@ -0,0 +1,20 @@
|
||||
/* -*- Mode: C; c-basic-offset:4 ; -*- */
|
||||
/*
|
||||
* Copyright (c) 2004-2006 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#include "ompi_config.h"
|
||||
#include "ompi/datatype/convertor.h"
|
||||
#include "ompi/datatype/datatype.h"
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
return 0;
|
||||
}
|
399
test/datatype/to_self.c
Обычный файл
399
test/datatype/to_self.c
Обычный файл
@ -0,0 +1,399 @@
|
||||
/* -*- Mode: C; c-basic-offset:4 ; -*- */
|
||||
/*
|
||||
* Copyright (c) 2004-2006 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#include "mpi.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef HAVE_OPEN_MPI
|
||||
#include "ompi_config.h"
|
||||
#include "ompi/datatype/convertor.h"
|
||||
#include "ompi/datatype/datatype.h"
|
||||
#include "ompi/datatype/convertor_internal.h"
|
||||
#include "ompi/datatype/datatype_internal.h"
|
||||
#define MPI_DDT_DUMP(ddt) ompi_ddt_dump( (ddt) )
|
||||
#else
|
||||
#define MPI_DDT_DUMP(ddt)
|
||||
#endif /* OPEN_MPI */
|
||||
|
||||
/* Create a datatype similar to the one use by HPL */
|
||||
static MPI_Datatype
|
||||
create_indexed_constant_gap_ddt( int number, /* number of repetitions */
|
||||
int contig_size, /* number of elements in a contiguous chunk */
|
||||
int gap_size ) /* number of elements in a gap */
|
||||
{
|
||||
MPI_Datatype dt, *types;
|
||||
int i, *bLength;
|
||||
MPI_Aint* displ;
|
||||
|
||||
types = (MPI_Datatype*)malloc( sizeof(MPI_Datatype) * number );
|
||||
bLength = (int*)malloc( sizeof(int) * number );
|
||||
displ = (MPI_Aint*)malloc( sizeof(MPI_Aint) * number );
|
||||
|
||||
types[0] = MPI_DOUBLE;
|
||||
bLength[0] = contig_size;
|
||||
displ[0] = 0;
|
||||
for( i = 1; i < number; i++ ) {
|
||||
types[i] = MPI_DOUBLE;
|
||||
bLength[i] = contig_size;
|
||||
displ[i] = displ[i-1] + sizeof(double) * (contig_size + gap_size);
|
||||
}
|
||||
MPI_Type_struct( number, bLength, displ, types, &dt );
|
||||
MPI_DDT_DUMP( dt );
|
||||
free(types);
|
||||
free(bLength);
|
||||
free(displ);
|
||||
MPI_Type_commit( &dt );
|
||||
return dt;
|
||||
}
|
||||
|
||||
static MPI_Datatype
|
||||
create_optimized_indexed_constant_gap_ddt( int number, /* number of repetitions */
|
||||
int contig_size, /* number of elements in a contiguous chunk */
|
||||
int gap_size ) /* number of elements in a gap */
|
||||
{
|
||||
MPI_Datatype dt;
|
||||
|
||||
MPI_Type_vector( number, contig_size, (contig_size + gap_size), MPI_DOUBLE, &dt );
|
||||
MPI_Type_commit( &dt );
|
||||
MPI_DDT_DUMP( dt );
|
||||
return dt;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
int i[2];
|
||||
float f;
|
||||
} internal_struct;
|
||||
typedef struct {
|
||||
int v1;
|
||||
int gap1;
|
||||
internal_struct is[3];
|
||||
} ddt_gap;
|
||||
|
||||
static MPI_Datatype
|
||||
create_indexed_gap_ddt( void )
|
||||
{
|
||||
ddt_gap dt[2];
|
||||
MPI_Datatype dt1, dt2, dt3;
|
||||
int bLength[2] = { 2, 1 };
|
||||
MPI_Datatype types[2] = { MPI_INT, MPI_FLOAT };
|
||||
MPI_Aint displ[2];
|
||||
|
||||
MPI_Address( &(dt[0].is[0].i[0]), &(displ[0]) );
|
||||
MPI_Address( &(dt[0].is[0].f), &(displ[1]) );
|
||||
displ[1] -= displ[0];
|
||||
displ[0] -= displ[0];
|
||||
MPI_Type_struct( 2, bLength, displ, types, &dt1 );
|
||||
/*MPI_DDT_DUMP( dt1 );*/
|
||||
MPI_Type_contiguous( 3, dt1, &dt2 );
|
||||
/*MPI_DDT_DUMP( dt2 );*/
|
||||
bLength[0] = 1;
|
||||
bLength[1] = 1;
|
||||
MPI_Address( &(dt[0].v1), &(displ[0]) );
|
||||
MPI_Address( &(dt[0].is[0]), &(displ[1]) );
|
||||
displ[1] -= displ[0];
|
||||
displ[0] -= displ[0];
|
||||
types[0] = MPI_INT;
|
||||
types[1] = dt2;
|
||||
MPI_Type_struct( 2, bLength, displ, types, &dt3 );
|
||||
/*MPI_DDT_DUMP( dt3 );*/
|
||||
MPI_Type_free( &dt1 );
|
||||
MPI_Type_free( &dt2 );
|
||||
MPI_Type_contiguous( 10, dt3, &dt1 );
|
||||
MPI_DDT_DUMP( dt1 );
|
||||
MPI_Type_free( &dt3 );
|
||||
MPI_Type_commit( &dt1 );
|
||||
return dt1;
|
||||
}
|
||||
|
||||
static MPI_Datatype
|
||||
create_indexed_gap_optimized_ddt( void )
|
||||
{
|
||||
MPI_Datatype dt1, dt2, dt3;
|
||||
int bLength[3];
|
||||
MPI_Datatype types[3];
|
||||
MPI_Aint displ[3];
|
||||
|
||||
MPI_Type_contiguous( 40, MPI_BYTE, &dt1 );
|
||||
MPI_Type_create_resized( dt1, 0, 44, &dt2 );
|
||||
|
||||
bLength[0] = 4;
|
||||
bLength[1] = 9;
|
||||
bLength[2] = 36;
|
||||
|
||||
types[0] = MPI_BYTE;
|
||||
types[1] = dt2;
|
||||
types[2] = MPI_BYTE;
|
||||
|
||||
displ[0] = 0;
|
||||
displ[1] = 8;
|
||||
displ[2] = 44 * 9 + 8;
|
||||
|
||||
MPI_Type_struct( 3, bLength, displ, types, &dt3 );
|
||||
|
||||
MPI_Type_free( &dt1 );
|
||||
MPI_Type_free( &dt2 );
|
||||
MPI_DDT_DUMP( dt3 );
|
||||
MPI_Type_commit( &dt3 );
|
||||
return dt3;
|
||||
}
|
||||
|
||||
static void print_result( int length, int cycles, double time )
|
||||
{
|
||||
double bandwidth, clock_prec;
|
||||
|
||||
clock_prec = MPI_Wtick();
|
||||
bandwidth = (length * clock_prec * cycles) / (1024.0 * 1024.0) / (time * clock_prec);
|
||||
printf( "%8d\t%.6f\t%.4f MB/s\n", length, time / cycles, bandwidth );
|
||||
}
|
||||
|
||||
static int isend_recv( int cycles,
|
||||
MPI_Datatype sdt, int scount, void* sbuf,
|
||||
MPI_Datatype rdt, int rcount, void* rbuf )
|
||||
{
|
||||
int sres, rres, myself, tag = 0, i, slength, rlength;
|
||||
MPI_Status status;
|
||||
MPI_Request req;
|
||||
double tstart, tend;
|
||||
|
||||
MPI_Type_size( sdt, &slength );
|
||||
slength *= scount;
|
||||
MPI_Type_size( rdt, &rlength );
|
||||
rlength *= rcount;
|
||||
|
||||
MPI_Comm_rank( MPI_COMM_WORLD, &myself );
|
||||
|
||||
tstart = MPI_Wtime();
|
||||
for( i = 0; i < cycles; i++ ) {
|
||||
#ifndef FAST
|
||||
sres = MPI_Isend( sbuf, scount, sdt, myself, tag, MPI_COMM_WORLD, &req );
|
||||
rres = MPI_Recv( rbuf, rcount, rdt, myself, tag, MPI_COMM_WORLD, &status );
|
||||
MPI_Wait( &req, &status );
|
||||
/*MPI_Request_free( &req );*/
|
||||
#else
|
||||
sres = ftmpi_mpi_isend( sbuf, scount, sdt, myself, tag, MPI_COMM_WORLD, &req );
|
||||
rres = ftmpi_mpi_recv( rbuf, rcount, rdt, myself, tag, MPI_COMM_WORLD, &status );
|
||||
ftmpi_request_free( &req );
|
||||
#endif
|
||||
}
|
||||
tend = MPI_Wtime();
|
||||
print_result( rlength, cycles, tend - tstart );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int irecv_send( int cycles,
|
||||
MPI_Datatype sdt, int scount, void* sbuf,
|
||||
MPI_Datatype rdt, int rcount, void* rbuf )
|
||||
{
|
||||
int sres, rres, myself, tag = 0, i, slength, rlength;
|
||||
MPI_Request req;
|
||||
MPI_Status status;
|
||||
double tstart, tend;
|
||||
|
||||
MPI_Type_size( sdt, &slength );
|
||||
slength *= scount;
|
||||
MPI_Type_size( rdt, &rlength );
|
||||
rlength *= rcount;
|
||||
|
||||
MPI_Comm_rank( MPI_COMM_WORLD, &myself );
|
||||
|
||||
tstart = MPI_Wtime();
|
||||
for( i = 0; i < cycles; i++ ) {
|
||||
#ifndef FAST
|
||||
rres = MPI_Irecv( rbuf, rcount, rdt, myself, tag, MPI_COMM_WORLD, &req );
|
||||
sres = MPI_Send( sbuf, scount, sdt, myself, tag, MPI_COMM_WORLD );
|
||||
MPI_Wait( &req, &status );
|
||||
/*MPI_Request_free( &req );*/
|
||||
#else
|
||||
rres = ftmpi_mpi_irecv( rbuf, rcount, rdt, myself, tag, MPI_COMM_WORLD, &req );
|
||||
sres = ftmpi_mpi_send( sbuf, scount, sdt, myself, tag, MPI_COMM_WORLD );
|
||||
ftmpi_request_free( &req );
|
||||
#endif
|
||||
}
|
||||
tend = MPI_Wtime();
|
||||
print_result( rlength, cycles, tend - tstart );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int isend_irecv_wait( int cycles,
|
||||
MPI_Datatype sdt, int scount, void* sbuf,
|
||||
MPI_Datatype rdt, int rcount, void* rbuf )
|
||||
{
|
||||
int sres, rres, myself, tag = 0, i, slength, rlength;
|
||||
MPI_Request sreq, rreq;
|
||||
MPI_Status status;
|
||||
double tstart, tend;
|
||||
|
||||
MPI_Type_size( sdt, &slength );
|
||||
slength *= scount;
|
||||
MPI_Type_size( rdt, &rlength );
|
||||
rlength *= rcount;
|
||||
|
||||
MPI_Comm_rank( MPI_COMM_WORLD, &myself );
|
||||
|
||||
tstart = MPI_Wtime();
|
||||
for( i = 0; i < cycles; i++ ) {
|
||||
#ifndef FAST
|
||||
sres = MPI_Isend( sbuf, scount, sdt, myself, tag, MPI_COMM_WORLD, &sreq );
|
||||
rres = MPI_Irecv( rbuf, rcount, rdt, myself, tag, MPI_COMM_WORLD, &rreq );
|
||||
MPI_Wait( &sreq, &status );
|
||||
MPI_Wait( &rreq, &status );
|
||||
/*MPI_Request_free( &sreq );*/
|
||||
/*MPI_Request_free( &rreq );*/
|
||||
#else
|
||||
sres = ftmpi_mpi_isend( sbuf, scount, sdt, myself, tag, MPI_COMM_WORLD, &sreq );
|
||||
rres = ftmpi_mpi_irecv( rbuf, rcount, rdt, myself, tag, MPI_COMM_WORLD, &rreq );
|
||||
ftmpi_wait( &sreq, &status );
|
||||
ftmpi_request_free( &sreq );
|
||||
ftmpi_request_free( &rreq );
|
||||
#endif
|
||||
}
|
||||
tend = MPI_Wtime();
|
||||
print_result( rlength, cycles, tend - tstart );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int irecv_isend_wait( int cycles,
|
||||
MPI_Datatype sdt, int scount, void* sbuf,
|
||||
MPI_Datatype rdt, int rcount, void* rbuf )
|
||||
{
|
||||
int sres, rres, myself, tag = 0, i, slength, rlength;
|
||||
MPI_Request sreq, rreq;
|
||||
MPI_Status status;
|
||||
double tstart, tend;
|
||||
|
||||
MPI_Type_size( sdt, &slength );
|
||||
slength *= scount;
|
||||
MPI_Type_size( rdt, &rlength );
|
||||
rlength *= rcount;
|
||||
|
||||
MPI_Comm_rank( MPI_COMM_WORLD, &myself );
|
||||
|
||||
tstart = MPI_Wtime();
|
||||
for( i = 0; i < cycles; i++ ) {
|
||||
#ifndef FAST
|
||||
rres = MPI_Irecv( rbuf, rcount, rdt, myself, tag, MPI_COMM_WORLD, &rreq );
|
||||
sres = MPI_Isend( sbuf, scount, sdt, myself, tag, MPI_COMM_WORLD, &sreq );
|
||||
MPI_Wait( &sreq, &status );
|
||||
MPI_Wait( &rreq, &status );
|
||||
/*MPI_Request_free( &sreq );*/
|
||||
/*MPI_Request_free( &rreq );*/
|
||||
#else
|
||||
rres = ftmpi_mpi_irecv( rbuf, rcount, rdt, myself, tag, MPI_COMM_WORLD, &rreq );
|
||||
sres = ftmpi_mpi_isend( sbuf, scount, sdt, myself, tag, MPI_COMM_WORLD, &sreq );
|
||||
ftmpi_wait( &sreq, &status );
|
||||
ftmpi_request_free( &sreq );
|
||||
ftmpi_request_free( &rreq );
|
||||
#endif
|
||||
}
|
||||
tend = MPI_Wtime();
|
||||
print_result( rlength, cycles, tend - tstart );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_test_for_ddt( MPI_Datatype sddt, MPI_Datatype rddt, int length )
|
||||
{
|
||||
int i;
|
||||
MPI_Aint extent;
|
||||
char *sbuf, *rbuf;
|
||||
|
||||
MPI_Type_extent( sddt, &extent );
|
||||
sbuf = (char*)malloc( length );
|
||||
rbuf = (char*)malloc( length );
|
||||
printf( "# Isend recv\n" );
|
||||
for( i = 1; i <= (length/extent); i *= 2 ) {
|
||||
isend_recv( 10, sddt, i, sbuf, rddt, i, rbuf );
|
||||
}
|
||||
printf( "# Irecv send\n" );
|
||||
for( i = 1; i <= (length/extent); i *= 2 ) {
|
||||
irecv_send( 10, sddt, i, sbuf, rddt, i, rbuf );
|
||||
}
|
||||
printf( "# Irecv Isend Wait\n" );
|
||||
for( i = 1; i <= (length/extent); i *= 2 ) {
|
||||
irecv_isend_wait( 10, sddt, i, sbuf, rddt, i, rbuf );
|
||||
}
|
||||
printf( "# Irecv Isend Wait\n" );
|
||||
for( i = 1; i <= (length/extent); i *= 2 ) {
|
||||
isend_irecv_wait( 10, sddt, i, sbuf, rddt, i, rbuf );
|
||||
}
|
||||
free( sbuf );
|
||||
free( rbuf );
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define DO_CONTIG 0x01
|
||||
#define DO_CONSTANT_GAP 0x02
|
||||
#define DO_INDEXED_GAP 0x04
|
||||
#define DO_OPTIMIZED_INDEXED_GAP 0x08
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
int rc;
|
||||
int length = 1024 * 1024;
|
||||
int rank, size;
|
||||
MPI_Datatype ddt;
|
||||
int run_tests = DO_CONTIG | DO_CONSTANT_GAP | DO_INDEXED_GAP | DO_OPTIMIZED_INDEXED_GAP;
|
||||
/*int run_tests = DO_CONSTANT_GAP;*/
|
||||
|
||||
rc = MPI_Init (&argc, &argv);
|
||||
|
||||
rc = MPI_Comm_rank (MPI_COMM_WORLD, &rank);
|
||||
rc = MPI_Comm_size (MPI_COMM_WORLD, &size);
|
||||
|
||||
if( rank != 0 ) {
|
||||
MPI_Finalize();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if( run_tests & DO_CONTIG ) {
|
||||
printf( "\ncontiguous datatype\n\n" );
|
||||
do_test_for_ddt( MPI_INT, MPI_INT, length );
|
||||
}
|
||||
|
||||
if( run_tests & DO_INDEXED_GAP ) {
|
||||
printf( "\nindexed gap\n\n" );
|
||||
ddt = create_indexed_gap_ddt();
|
||||
/*MPI_DDT_DUMP( ddt );*/
|
||||
do_test_for_ddt( ddt, ddt, length );
|
||||
MPI_Type_free( &ddt );
|
||||
}
|
||||
|
||||
if( run_tests & DO_OPTIMIZED_INDEXED_GAP ) {
|
||||
printf( "\noptimized indexed gap\n\n" );
|
||||
ddt = create_indexed_gap_optimized_ddt();
|
||||
/*MPI_DDT_DUMP( ddt );*/
|
||||
do_test_for_ddt( ddt, ddt, length );
|
||||
MPI_Type_free( &ddt );
|
||||
}
|
||||
|
||||
if( run_tests & DO_CONSTANT_GAP ) {
|
||||
printf( "\nconstant indexed gap\n\n" );
|
||||
ddt = create_indexed_constant_gap_ddt( 80, 100, 1 );
|
||||
/*MPI_DDT_DUMP( ddt );*/
|
||||
do_test_for_ddt( ddt, ddt, length );
|
||||
MPI_Type_free( &ddt );
|
||||
}
|
||||
|
||||
if( run_tests & DO_CONSTANT_GAP ) {
|
||||
printf( "\noptimized constant indexed gap\n\n" );
|
||||
ddt = create_optimized_indexed_constant_gap_ddt( 80, 100, 1 );
|
||||
/*MPI_DDT_DUMP( ddt );*/
|
||||
do_test_for_ddt( ddt, ddt, length );
|
||||
MPI_Type_free( &ddt );
|
||||
}
|
||||
|
||||
MPI_Finalize ();
|
||||
exit(0);
|
||||
}
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user