| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444 |
- /*
- * -- High Performance Computing Linpack Benchmark (HPL)
- * HPL - 2.0 - September 10, 2008
- * Antoine P. Petitet
- * University of Tennessee, Knoxville
- * Innovative Computing Laboratory
- * (C) Copyright 2000-2008 All Rights Reserved
- *
- * -- Copyright notice and Licensing terms:
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions, and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgement:
- * This product includes software developed at the University of
- * Tennessee, Knoxville, Innovative Computing Laboratory.
- *
- * 4. The name of the University, the name of the Laboratory, or the
- * names of its contributors may not be used to endorse or promote
- * products derived from this software without specific written
- * permission.
- *
- * -- Disclaimer:
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- * ---------------------------------------------------------------------
- */
- /*
- * Include files
- */
- #include "hpl.h"
- #ifdef STDC_HEADERS
- void HPL_pdtest
- (
- HPL_T_test * TEST,
- HPL_T_grid * GRID,
- HPL_T_palg * ALGO,
- const int N,
- const int NB
- )
- #else
- void HPL_pdtest
- ( TEST, GRID, ALGO, N, NB )
- HPL_T_test * TEST;
- HPL_T_grid * GRID;
- HPL_T_palg * ALGO;
- const int N;
- const int NB;
- #endif
- {
- /*
- * Purpose
- * =======
- *
- * HPL_pdtest performs one test given a set of parameters such as the
- * process grid, the problem size, the distribution blocking factor ...
- * This function generates the data, calls and times the linear system
- * solver, checks the accuracy of the obtained vector solution and
- * writes this information to the file pointed to by TEST->outfp.
- *
- * Arguments
- * =========
- *
- * TEST (global input) HPL_T_test *
- * On entry, TEST points to a testing data structure: outfp
- * specifies the output file where the results will be printed.
- * It is only defined and used by the process 0 of the grid.
- * thrsh specifies the threshhold value for the test ratio.
- * Concretely, a test is declared "PASSED" if and only if the
- * following inequality is satisfied:
- * ||Ax-b||_oo / ( epsil *
- * ( || x ||_oo * || A ||_oo + || b ||_oo ) *
- * N ) < thrsh.
- * epsil is the relative machine precision of the distributed
- * computer. Finally the test counters, kfail, kpass, kskip and
- * ktest are updated as follows: if the test passes, kpass is
- * incremented by one; if the test fails, kfail is incremented
- * by one; if the test is skipped, kskip is incremented by one.
- * ktest is left unchanged.
- *
- * GRID (local input) HPL_T_grid *
- * On entry, GRID points to the data structure containing the
- * process grid information.
- *
- * ALGO (global input) HPL_T_palg *
- * On entry, ALGO points to the data structure containing the
- * algorithmic parameters to be used for this test.
- *
- * N (global input) const int
- * On entry, N specifies the order of the coefficient matrix A.
- * N must be at least zero.
- *
- * NB (global input) const int
- * On entry, NB specifies the blocking factor used to partition
- * and distribute the matrix A. NB must be larger than one.
- *
- * ---------------------------------------------------------------------
- */
- /*
- * .. Local Variables ..
- */
- #ifdef HPL_DETAILED_TIMING
- double HPL_w[HPL_TIMING_N];
- #endif
- HPL_T_pmat mat;
- double wtime[1];
- int info[3];
- double Anorm1, AnormI, Gflops, Xnorm1, XnormI,
- BnormI, resid0, resid1;
- double * Bptr;
- void * vptr = NULL;
- static int first=1;
- int ii, ip2, mycol, myrow, npcol, nprow, nq;
- char ctop, cpfact, crfact;
- /* ..
- * .. Executable Statements ..
- */
-
- (void) HPL_grid_info( GRID, &nprow, &npcol, &myrow, &mycol );
- mat.n = N; mat.nb = NB; mat.info = 0;
- mat.mp = HPL_numroc( N, NB, NB, myrow, 0, nprow );
- nq = HPL_numroc( N, NB, NB, mycol, 0, npcol );
- mat.nq = nq + 1;
- /*
- * Allocate matrix, right-hand-side, and vector solution x. [ A | b ] is
- * N by N+1. One column is added in every process column for the solve.
- * The result however is stored in a 1 x N vector replicated in every
- * process row. In every process, A is lda * (nq+1), x is 1 * nq and the
- * workspace is mp.
- *
- * Ensure that lda is a multiple of ALIGN and not a power of 2
- */
- mat.ld = ( ( Mmax( 1, mat.mp ) - 1 ) / ALGO->align ) * ALGO->align;
- do
- {
- ii = ( mat.ld += ALGO->align ); ip2 = 1;
- while( ii > 1 ) { ii >>= 1; ip2 <<= 1; }
- }
- while( mat.ld == ip2 );
- /*
- * Allocate dynamic memory
- */
- vptr = (void*)malloc( ( (size_t)(ALGO->align) +
- (size_t)(mat.ld+1) * (size_t)(mat.nq) ) *
- sizeof(double) );
- info[0] = (vptr == NULL); info[1] = myrow; info[2] = mycol;
- (void) HPL_all_reduce( (void *)(info), 3, HPL_INT, HPL_max,
- GRID->all_comm );
- if( info[0] != 0 )
- {
- if( ( myrow == 0 ) && ( mycol == 0 ) )
- HPL_pwarn( TEST->outfp, __LINE__, "HPL_pdtest",
- "[%d,%d] %s", info[1], info[2],
- "Memory allocation failed for A, x and b. Skip." );
- (TEST->kskip)++;
- return;
- }
- /*
- * generate matrix and right-hand-side, [ A | b ] which is N by N+1.
- */
- mat.A = (double *)HPL_PTR( vptr,
- ((size_t)(ALGO->align) * sizeof(double) ) );
- mat.X = Mptr( mat.A, 0, mat.nq, mat.ld );
- HPL_pdmatgen( GRID, N, N+1, NB, mat.A, mat.ld, HPL_ISEED );
- #ifdef HPL_CALL_VSIPL
- mat.block = vsip_blockbind_d( (vsip_scalar_d *)(mat.A),
- (vsip_length)(mat.ld * mat.nq),
- VSIP_MEM_NONE );
- #endif
- /*
- * Solve linear system
- */
- HPL_ptimer_boot(); (void) HPL_barrier( GRID->all_comm );
- HPL_ptimer( 0 );
- HPL_pdgesv( GRID, ALGO, &mat );
- HPL_ptimer( 0 );
- #ifdef HPL_CALL_VSIPL
- (void) vsip_blockrelease_d( mat.block, VSIP_TRUE );
- vsip_blockdestroy_d( mat.block );
- #endif
- /*
- * Gather max of all CPU and WALL clock timings and print timing results
- */
- HPL_ptimer_combine( GRID->all_comm, HPL_AMAX_PTIME, HPL_WALL_PTIME,
- 1, 0, wtime );
- if( ( myrow == 0 ) && ( mycol == 0 ) )
- {
- if( first )
- {
- HPL_fprintf( TEST->outfp, "%s%s\n",
- "========================================",
- "========================================" );
- HPL_fprintf( TEST->outfp, "%s%s\n",
- "T/V N NB P Q",
- " Time Gflops" );
- HPL_fprintf( TEST->outfp, "%s%s\n",
- "----------------------------------------",
- "----------------------------------------" );
- if( TEST->thrsh <= HPL_rzero ) first = 0;
- }
- /*
- * 2/3 N^3 - 1/2 N^2 flops for LU factorization + 2 N^2 flops for solve.
- * Print WALL time
- */
- Gflops = ( ( (double)(N) / 1.0e+9 ) *
- ( (double)(N) / wtime[0] ) ) *
- ( ( 2.0 / 3.0 ) * (double)(N) + ( 3.0 / 2.0 ) );
- // FILE *perf_file;
- char name[50] = "/shared/DEMOS/RCCE/LINPACK/perf.";
- // char name[50] = "perf.";
- char postfix[50];
- sprintf(postfix, "%d", RCCE_num_ues());
- strcat(name, postfix);
- printf("Core %d opens file %s and writes %d\n", RCCE_ue(), name, (int)(1000*Gflops));
- // perf_file = fopen(name,"w");
- // fprintf(perf_file, "%d", (int)(1000*Gflops));
- // fclose(perf_file);
- cpfact = ( ( (HPL_T_FACT)(ALGO->pfact) ==
- (HPL_T_FACT)(HPL_LEFT_LOOKING) ) ? (char)('L') :
- ( ( (HPL_T_FACT)(ALGO->pfact) == (HPL_T_FACT)(HPL_CROUT) ) ?
- (char)('C') : (char)('R') ) );
- crfact = ( ( (HPL_T_FACT)(ALGO->rfact) ==
- (HPL_T_FACT)(HPL_LEFT_LOOKING) ) ? (char)('L') :
- ( ( (HPL_T_FACT)(ALGO->rfact) == (HPL_T_FACT)(HPL_CROUT) ) ?
- (char)('C') : (char)('R') ) );
- if( ALGO->btopo == HPL_1RING ) ctop = '0';
- else if( ALGO->btopo == HPL_1RING_M ) ctop = '1';
- else if( ALGO->btopo == HPL_2RING ) ctop = '2';
- else if( ALGO->btopo == HPL_2RING_M ) ctop = '3';
- else if( ALGO->btopo == HPL_BLONG ) ctop = '4';
- else /* if( ALGO->btopo == HPL_BLONG_M ) */ ctop = '5';
- if( wtime[0] > HPL_rzero )
- HPL_fprintf( TEST->outfp,
- "W%c%1d%c%c%1d%c%1d%12d %5d %5d %5d %18.4f %18.3e\n",
- ( GRID->order == HPL_ROW_MAJOR ? 'R' : 'C' ),
- ALGO->depth, ctop, crfact, ALGO->nbdiv, cpfact, ALGO->nbmin,
- N, NB, nprow, npcol, wtime[0], Gflops );
- }
- #ifdef HPL_DETAILED_TIMING
- HPL_ptimer_combine( GRID->all_comm, HPL_AMAX_PTIME, HPL_WALL_PTIME,
- HPL_TIMING_N, HPL_TIMING_BEG, HPL_w );
- if( ( myrow == 0 ) && ( mycol == 0 ) )
- {
- HPL_fprintf( TEST->outfp, "%s%s\n",
- "--VVV--VVV--VVV--VVV--VVV--VVV--VVV--V",
- "VV--VVV--VVV--VVV--VVV--VVV--VVV--VVV-" );
- /*
- * Recursive panel factorization
- */
- if( HPL_w[HPL_TIMING_RPFACT-HPL_TIMING_BEG] > HPL_rzero )
- HPL_fprintf( TEST->outfp,
- "Max aggregated wall time rfact . . . : %18.2f\n",
- HPL_w[HPL_TIMING_RPFACT-HPL_TIMING_BEG] );
- /*
- * Panel factorization
- */
- if( HPL_w[HPL_TIMING_PFACT-HPL_TIMING_BEG] > HPL_rzero )
- HPL_fprintf( TEST->outfp,
- "+ Max aggregated wall time pfact . . : %18.2f\n",
- HPL_w[HPL_TIMING_PFACT-HPL_TIMING_BEG] );
- /*
- * Panel factorization (swap)
- */
- if( HPL_w[HPL_TIMING_MXSWP-HPL_TIMING_BEG] > HPL_rzero )
- HPL_fprintf( TEST->outfp,
- "+ Max aggregated wall time mxswp . . : %18.2f\n",
- HPL_w[HPL_TIMING_MXSWP-HPL_TIMING_BEG] );
- /*
- * Update
- */
- if( HPL_w[HPL_TIMING_UPDATE-HPL_TIMING_BEG] > HPL_rzero )
- HPL_fprintf( TEST->outfp,
- "Max aggregated wall time update . . : %18.2f\n",
- HPL_w[HPL_TIMING_UPDATE-HPL_TIMING_BEG] );
- /*
- * Update (swap)
- */
- if( HPL_w[HPL_TIMING_LASWP-HPL_TIMING_BEG] > HPL_rzero )
- HPL_fprintf( TEST->outfp,
- "+ Max aggregated wall time laswp . . : %18.2f\n",
- HPL_w[HPL_TIMING_LASWP-HPL_TIMING_BEG] );
- /*
- * Upper triangular system solve
- */
- if( HPL_w[HPL_TIMING_PTRSV-HPL_TIMING_BEG] > HPL_rzero )
- HPL_fprintf( TEST->outfp,
- "Max aggregated wall time up tr sv . : %18.2f\n",
- HPL_w[HPL_TIMING_PTRSV-HPL_TIMING_BEG] );
- if( TEST->thrsh <= HPL_rzero )
- HPL_fprintf( TEST->outfp, "%s%s\n",
- "========================================",
- "========================================" );
- }
- #endif
- /*
- * Quick return, if I am not interested in checking the computations
- */
- if( TEST->thrsh <= HPL_rzero )
- { (TEST->kpass)++; if( vptr ) free( vptr ); return; }
- /*
- * Check info returned by solve
- */
- if( mat.info != 0 )
- {
- if( ( myrow == 0 ) && ( mycol == 0 ) )
- HPL_pwarn( TEST->outfp, __LINE__, "HPL_pdtest", "%s %d, %s",
- "Error code returned by solve is", mat.info, "skip" );
- (TEST->kskip)++;
- if( vptr ) free( vptr ); return;
- }
- /*
- * Check computation, re-generate [ A | b ], compute norm 1 and inf of A and x,
- * and norm inf of b - A x. Display residual checks.
- */
- HPL_pdmatgen( GRID, N, N+1, NB, mat.A, mat.ld, HPL_ISEED );
- Anorm1 = HPL_pdlange( GRID, HPL_NORM_1, N, N, NB, mat.A, mat.ld );
- AnormI = HPL_pdlange( GRID, HPL_NORM_I, N, N, NB, mat.A, mat.ld );
- /*
- * Because x is distributed in process rows, switch the norms
- */
- XnormI = HPL_pdlange( GRID, HPL_NORM_1, 1, N, NB, mat.X, 1 );
- Xnorm1 = HPL_pdlange( GRID, HPL_NORM_I, 1, N, NB, mat.X, 1 );
- /*
- * If I am in the col that owns b, (1) compute local BnormI, (2) all_reduce to
- * find the max (in the col). Then (3) broadcast along the rows so that every
- * process has BnormI. Note that since we use a uniform distribution in [-0.5,0.5]
- * for the entries of B, it is very likely that BnormI (<=,~) 0.5.
- */
- Bptr = Mptr( mat.A, 0, nq, mat.ld );
- if( mycol == HPL_indxg2p( N, NB, NB, 0, npcol ) ){
- if( mat.mp > 0 )
- {
- BnormI = Bptr[HPL_idamax( mat.mp, Bptr, 1 )]; BnormI = Mabs( BnormI );
- }
- else
- {
- BnormI = HPL_rzero;
- }
- (void) HPL_all_reduce( (void *)(&BnormI), 1, HPL_DOUBLE, HPL_max,
- GRID->col_comm );
- }
- (void) HPL_broadcast( (void *)(&BnormI), 1, HPL_DOUBLE,
- HPL_indxg2p( N, NB, NB, 0, npcol ),
- GRID->row_comm );
- /*
- * If I own b, compute ( b - A x ) and ( - A x ) otherwise
- */
- if( mycol == HPL_indxg2p( N, NB, NB, 0, npcol ) )
- {
- HPL_dgemv( HplColumnMajor, HplNoTrans, mat.mp, nq, -HPL_rone,
- mat.A, mat.ld, mat.X, 1, HPL_rone, Bptr, 1 );
- }
- else if( nq > 0 )
- {
- HPL_dgemv( HplColumnMajor, HplNoTrans, mat.mp, nq, -HPL_rone,
- mat.A, mat.ld, mat.X, 1, HPL_rzero, Bptr, 1 );
- }
- else { for( ii = 0; ii < mat.mp; ii++ ) Bptr[ii] = HPL_rzero; }
- /*
- * Reduce the distributed residual in process column 0
- */
- if( mat.mp > 0 )
- (void) HPL_reduce( Bptr, mat.mp, HPL_DOUBLE, HPL_sum, 0,
- GRID->row_comm );
- /*
- * Compute || b - A x ||_oo
- */
- resid0 = HPL_pdlange( GRID, HPL_NORM_I, N, 1, NB, Bptr, mat.ld );
- /*
- * Computes and displays norms, residuals ...
- */
- if( N <= 0 )
- {
- resid1 = HPL_rzero;
- }
- else
- {
- resid1 = resid0 / ( TEST->epsil * ( AnormI * XnormI + BnormI ) * (double)(N) );
- }
- if( resid1 < TEST->thrsh ) (TEST->kpass)++;
- else (TEST->kfail)++;
- if( ( myrow == 0 ) && ( mycol == 0 ) )
- {
- HPL_fprintf( TEST->outfp, "%s%s\n",
- "----------------------------------------",
- "----------------------------------------" );
- HPL_fprintf( TEST->outfp, "%s%16.7f%s%s\n",
- "||Ax-b||_oo/(eps*(||A||_oo*||x||_oo+||b||_oo)*N)= ", resid1,
- " ...... ", ( resid1 < TEST->thrsh ? "PASSED" : "FAILED" ) );
- if( resid1 >= TEST->thrsh )
- {
- HPL_fprintf( TEST->outfp, "%s%18.6f\n",
- "||Ax-b||_oo . . . . . . . . . . . . . . . . . = ", resid0 );
- HPL_fprintf( TEST->outfp, "%s%18.6f\n",
- "||A||_oo . . . . . . . . . . . . . . . . . . . = ", AnormI );
- HPL_fprintf( TEST->outfp, "%s%18.6f\n",
- "||A||_1 . . . . . . . . . . . . . . . . . . . = ", Anorm1 );
- HPL_fprintf( TEST->outfp, "%s%18.6f\n",
- "||x||_oo . . . . . . . . . . . . . . . . . . . = ", XnormI );
- HPL_fprintf( TEST->outfp, "%s%18.6f\n",
- "||x||_1 . . . . . . . . . . . . . . . . . . . = ", Xnorm1 );
- HPL_fprintf( TEST->outfp, "%s%18.6f\n",
- "||b||_oo . . . . . . . . . . . . . . . . . . . = ", BnormI );
- }
- }
- if( vptr ) free( vptr );
- /*
- * End of HPL_pdtest
- */
- }
|