⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpptest.c

📁 MPICH是MPI的重要研究,提供了一系列的接口函数,为并行计算的实现提供了编程环境.
💻 C
📖 第 1 页 / 共 2 页
字号:
	}	for (k=1; k<5; k++) {	    if (!SmoothList( twin, CommTest, msgctx )) break;	}	/* Final output */	if (myproc == 0) 	    OutputTestList( twin, outctx, proc1, proc2, distance );    }/* Generate output to be used as input to a graphics program */    if (doinfo && myproc == 0) {	RateoutputGraph( outctx, 			 sumlen, sumtime, sumlentime, sumlen2, sumtime2, 			 ntest, &s, &r );	DrawGraph( outctx, first, last, s, r );    }}/*****************************************************************************   Utility routines *****************************************************************************//*   This routine computes a good number of repititions to use based on    previous computations */int ComputeGoodReps( double t1, int len1, double t2, int len2, int len ){    double s, r;    int    reps;    r = (t2 - t1) / (len2 - len1);    s = t1 - r * len1;    if (s <= 0.0) s = 0.0;    reps = Tgoal / (s + r * len );     if (reps < 1) reps = 1;/*printf( "Reps = %d (%d,%d,%d)\n", reps, len1, len2, len ); fflush( stdout ); */    return reps;}#ifdef FOO/*  This runs the tests for a single size.  It adapts to the number of   tests necessary to get a reliable value for the minimum time.  It also keeps track of the average and maximum times (which are unused  for now).  We can estimate the variance of the trials by using the following   formulas:  variance = (1/N) sum (t(i) - (s+r n(i))**2           = (1/N) sum (t(i)**2 - 2 t(i)(s + r n(i)) + (s+r n(i))**2)	   = (1/N) (sum t(i)**2 - 2 s sum t(i) - 2 r sum t(i)n(i) + 	      sum (s**2 + 2 r s n(i) + r**2 n(i)**2))  Since we compute the parameters s and r, we need only maintain              sum t(i)**2              sum t(i)n(i)              sum n(i)**2  We already keep all of these in computing the (s,r) parameters; this is  simply a different computation.  In the case n == constant (that is, inside a single test), we can use  a similar test to estimate the variance of the individual measurements.  In this case,   variance = (1/N) sum (t(i) - s**2           = (1/N) sum (t(i)**2 - 2 t(i)s + s**2)	   = (1/N) (sum t(i)**2 - 2 s sum t(i) + sum s**2)  Here, s = sum t(i)/N  (For purists, the divison should be slightly different from (1/N) in the  variance formula.  I'll deal with that later.)  tmax = max time observed  tmean = mean time observed */#endif void PrintHelp( char *argv[] ) {  if (__MYPROCID != 0) return;  fprintf( stderr, "%s - test individual communication speeds\n", argv[0] );  fprintf( stderr, "Test a single communication link by various methods.  The tests are \n\combinations of\n\  Protocol: \n\  -sync        Blocking sends/receives    (default)\n\  -async       NonBlocking sends/receives\n\  -force       Ready-receiver (with a null message)\n\  -persistant  Persistant communication (only with MPI)\n\  -vector      Data is separated by constant stride (only with MPI, using UBs)\n\  -vectortype  Data is separated by constant stride (only with MPI, using \n\               MPI_Type_vector)\n\\n\  Message data:\n\  -cachesize n Perform test so that cached data is NOT reused\n\\n\  -vstride n   For -vector, set the stride between elements\n\  Message pattern:\n\  -roundtrip   Roundtrip messages         (default)\n\  -head        Head-to-head messages\n\    \n" );  fprintf( stderr, "  Message test type:\n\  (if not specified, only communication tests run)\n\  -overlap     Overlap computation with communication (see -size)\n\  -overlapmsgsize nn\n\               Size of messages to overlap with is nn bytes.\n\  -bisect      Bisection test (all processes participate)\n\  -bisectdist n Distance between processes\n\    \n" );  fprintf( stderr, "  Message sizes:\n\  -size start end stride                  (default 0 1024 32)\n\               Messages of length (start + i*stride) for i=0,1,... until\n\               the length is greater than end.\n\  -sizelist n1,n2,...\n\               Messages of length n1, n2, etc are used.  This overrides \n\               -size\n\  -logscale    Messages of length 2**i are used.  The -size argument\n\               may be used to set the limits\n\  -auto        Compute message sizes automatically (to create a smooth\n\               graph.  Use -size values for lower and upper range\n\  -autodx n    Minimum number of bytes between samples when using -auto\n\  -autorel d   Relative error tolerance when using -auto (0.02 by default)\n");  fprintf( stderr, "\n\  Number of tests\n\  -reps n      Number of times message is sent (default %d)\n\  -autoreps    Compute the number of times a message is sent automatically\n\  -tgoal  d    Time that each test should take, in seconds.  Use with \n\               -autoreps\n\  -rthresh d   Fractional threshold used to determine when minimum time\n\               has been found.  The default is 0.05.\n\  -sample_reps n   Number of times a full test is run inorder to find the\n\               minimum average time.  The default is 30\n\  -max_run_time n  Maximum number of seconds for all tests.  The default\n\               is %d\n\\n", DEFAULT_REPS, (int)max_run_time );fprintf( stderr, "  -gop [ options ]:\n" );PrintGOPHelp();PrintGraphHelp();PrintPatternHelp(); }/*    Re-initialize the variables used to estimate the time that it   takes to send data */void ClearTimes(){    sumtime	   = 0.0;    sumlentime = 0.0;    sumlen	   = 0.0;    sumlen2	   = 0.0;    sumtime2   = 0.0;    ntest	   = 0;}/**************************************************************************** * New code that uses a list to manage all timing experiments ****************************************************************************//* Setup the results array */static TwinResults *twin_avail = 0;TwinResults *AllocResultsArray( int nsizes ){    TwinResults *new;    int         i;    new = (TwinResults *)calloc( nsizes+1, sizeof(TwinResults) );    if (!new) MPI_Abort( MPI_COMM_WORLD, 1 );    for (i=1; i<nsizes-1; i++) {	new[i].next = &new[i+1];	new[i].prev = &new[i-1];    }    new[0].next	       = &new[1];    new[0].prev	       = 0;    new[nsizes-1].next = 0;    new[nsizes-1].prev = &new[nsizes-2];    /* Note that the last member (new[nsizes]) has null prev and next */    return new;}/* Initialize the results array for a strided set of data */void SetResultsForStrided( int first, int last, int incr, TwinResults *twin ){    int i = 0, len;    for (len=first; len<=last; len += incr) {	twin[i].len = len;	twin[i].t   = HUGE_VAL;	i++;    }    /* Fixup list */    twin[i-1].next = 0;    twin[i].prev   = 0;    /* Setup to the avail list */    twin_avail = &twin[i];}/* Initialize the results array of a given list of data */void SetResultsForList( int sizelist[], int nsizes, TwinResults *twin ){    int i = 0;    for (i=0; i<nsizes; i++) {	twin[i].len = sizelist[i];	twin[i].t   = HUGE_VAL;    }    /* Fixup list */    twin[i-1].next = 0;    twin[i].prev   = 0;    /* Setup to the avail list */    twin_avail = &twin[i];}/* Run a test for a single entry in the list. Return 1 if the test   was accepted, 0 otherwise */int RunTest( TwinResults *twin_p, double (*CommTest)(int,int,void *),		  void *msgctx, double wtick ){    double t;    t = (*CommTest)( twin_p->reps, twin_p->len, msgctx );    /* t is the time overall repititions */    CheckTimeLimit();    /* Ignore times that are much shorter than the clock resolution */    if (t > 10*wtick) {	twin_p->sum_time += t;	twin_p->ntests   += twin_p->reps;	/* Now, convert t to a per-loop time */	t = t / twin_p->reps;	if (t < twin_p->t) twin_p->t = t;	if (t > twin_p->max_time) twin_p->max_time = t;	return 1;    }    return 0;}/* For each message length in the list, run the experiement CommTest */void RunTestList( TwinResults *twin, double (*CommTest)(int,int,void *),		  void *msgctx ){    double wtick;    TwinResults *twin_p = twin;        wtick = MPI_Wtick();    while (twin_p) {	(void)RunTest( twin_p, CommTest, msgctx, wtick );	twin_p = twin_p->next;    }}/* This estimates the time at twin_p using a linear interpolation from the   surrounding entries */double LinearTimeEst( TwinResults *twin_p, double min_dx ){    double t_prev, t_next, t_est, dn_prev, dn_next;    /* Look at adjacent times */    if (twin_p->prev) {	t_prev = twin_p->prev->t;	dn_prev = twin_p->len - twin_p->prev->len;    }    else {	t_prev = twin_p->t;	dn_prev = min_dx;    }    if (twin_p->next) {	t_next = twin_p->next->t;	dn_next = twin_p->next->len - twin_p->len;    }    else {	t_next = twin_p->t;	dn_next = min_dx;    }    /* Compute linear estimate, adjusting for the possibly unequal       interval sizes, at twin_p->len. */    t_est = t_prev + (dn_prev/(dn_next + dn_prev))*(t_next-t_prev);    return t_est;}/* Add an entry to the list half way (in length) betwen prev and next */TwinResults *InsertElm( TwinResults *prev, TwinResults *next ){    TwinResults *tnew;    tnew = twin_avail;    twin_avail = twin_avail->next;    twin_avail->prev = 0;        tnew->next = next;    tnew->prev = prev;    prev->next = tnew;    next->prev = tnew;    tnew->len  = (prev->len + next->len) / 2;    tnew->reps = next->reps;    tnew->t    = HUGE_VAL;/*    printf( "%d running test with reps=%d, len=%d\n", 	    __MYPROCID, tnew->reps, (int)tnew->len );fflush(stdout); */    return tnew;}/* This is a breadth-first refinement approach.  Each call to this routine   adds one level of refinement */int RefineTestList( TwinResults *twin, double (*CommTest)(int,int,void*),		    void *msgctx, int min_dx, double autorel ){    double t_offset, t_center, wtick;    double abstol = 1.0e-10;    int do_refine, n_refined = 0;    TwinResults *twin_p = twin, *tnew;    /* There is a dummy empty entry at the end of the list */    if (!twin_avail->next) return 0;        wtick = MPI_Wtick();        if (min_dx < 1) min_dx = 1;    while (twin_p && twin_avail) {	/* Compute error estimate, adjusting for the possibly unequal	 interval sizes.  t_center is the linear interpolation at tnew_p->len,	 t_offset is the difference with the computed value */	t_center = LinearTimeEst( twin_p, min_dx );	t_offset = fabs(twin_p->t - t_center);	do_refine = t_offset > autorel * t_center + abstol;	MPI_Bcast( &do_refine, 1, MPI_INT, 0, MPI_COMM_WORLD );	if (do_refine) {	    /* update the list by refining both segments */	    if (twin_p->prev && twin_avail &&		min_dx < twin_p->len - twin_p->prev->len) {		tnew = InsertElm( twin_p->prev, twin_p );		n_refined += RunTest( tnew, CommTest, msgctx, wtick );	    }	    if (twin_p->next && twin_avail && 		min_dx < twin_p->next->len - twin_p->len) {		tnew = InsertElm( twin_p, twin_p->next );		n_refined += RunTest( tnew, CommTest, msgctx, wtick );		/* Skip this new element in this time through the loop */		twin_p = twin_p->next;	    }	}	twin_p = twin_p->next;    }    MPI_Bcast( &n_refined, 1, MPI_INT, 0, MPI_COMM_WORLD );    return n_refined;}/* Initialize the number of repititions to use in the basic test */void SetRepsForList( TwinResults *twin, int reps ){    TwinResults *twin_p = twin;        while (twin_p) {	twin_p->reps = reps;	twin_p = twin_p->next;    }}/* Smooth the entries in the list by looking for anomolous results and    rerunning those tests */int SmoothList( TwinResults *twin, double (*CommTest)(int,int,void*),		void *msgctx ){    double wtick, t_est;    int do_test;    TwinResults *twin_p = twin;    int n_smoothed = 0;        wtick = MPI_Wtick();    while (twin_p) {	/* Look at adjacent times */	if (__MYPROCID == 0) {	    t_est = LinearTimeEst( twin_p, 4.0 );	    do_test = (twin_p->t > 1.1 * t_est);	}	MPI_Bcast( &do_test, 1, MPI_INT, 0, MPI_COMM_WORLD );	if (do_test) {	    n_smoothed += RunTest( twin_p, CommTest, msgctx, wtick );	}	twin_p = twin_p->next;    }    MPI_Bcast( &n_smoothed, 1, MPI_INT, 0, MPI_COMM_WORLD );    return n_smoothed;}/* Output the results using the chosen graphics output package */void OutputTestList( TwinResults *twin, void *outctx, int proc1, int proc2, 		     int distance ){    TwinResults *twin_p = twin;    double rate;    while (twin_p) {	/* Compute final quantities */	if (twin_p->t > 0) 	    rate = ((double)twin_p->len) / twin_p->t;	else	    rate = 0.0;	DataoutGraph( outctx, proc1, proc2, distance, 		      (int)twin_p->len, twin_p->t * TimeScale,		      twin_p->t * TimeScale, 		      rate * RateScale, 		      twin_p->sum_time / twin_p->ntests * TimeScale, 		      twin_p->max_time * TimeScale );	twin_p = twin_p->next;    }}void CheckTimeLimit( void ){    /* Check for max time exceeded */    if (__MYPROCID == 0 && MPI_Wtime() - start_time > max_run_time) {	fprintf( stderr, "Exceeded %f seconds, aborting\n", max_run_time );	MPI_Abort( MPI_COMM_WORLD, 1 );    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -