home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 26
/
CD_ASCQ_26_1295.iso
/
vrac
/
laipe.zip
/
CMENTRY.C
< prev
next >
Wrap
C/C++ Source or Header
|
1995-07-31
|
7KB
|
254 lines
/*
;
; Program to demo parallel performance the following LAIPE function
; (1) meSolution_CSG_S that solves a system of linear equations by a
; multiple-entry solver. The left side matrix is symmetric.
;
; If a multiple-processor is available, this subroutine will be
; implemented in a loop. The loop bound begins with one to the number
; of system processors, and each loop sets the loop counter as the
; number of employed processors. Keep computer STANDING ALONE while
; running this program, and elapsed time with respect to different
; number of processors will be reported.
;
; Running this program, user has to provide the matrix order, i.e.,
; 40000, the lower bandwidth, i.e., 15, and the number of vectors in
; the right side of equations, i.e., 2. Larger order may have a better
; performance.
;
*/
/* define parameters */
#define LIMIT 7000000
/* function prototype */
float crandom( int *SEED );
void GenerateData( float *X,
float *A,
float *Solution,
int *N,
int *M,
int *Nset
);
/* main function */ main()
{
static float A[LIMIT];
float second;
float ZERO, Lower, Upper, R4TEMP;
int N, IndexA, IndexX, M, Processors, IndexWorking, Nset;
int IndexSolution, CPUs, I, II, JJ, KK;
int NoGood;
ZERO = 0.0001;
/* enter order of the system */
printf("Enter order (i.e., 40000 or something else): ");
scanf("%d", &N);
/* enter half bandwidth */
printf("Enter half bandwidth (i.e., 15 or something else): ");
scanf("%d", &M);
/* enter number of vectors */
printf("Enter number of vectors (i.e., 2 or something else): ");
scanf("%d", &Nset);
/* memory distribution */
IndexX = 0;
IndexSolution = IndexX + N * Nset;
IndexA = IndexSolution + N * Nset;
IndexWorking = IndexA + ( N - 1 ) * M + N;
/* check memory space */
if( IndexWorking + 2 * M * N >= LIMIT)
{
printf("Memory overflow\n");
exit();
}
/* get processors on board */
GetCPUs( &CPUs );
/* set processors to execute the following statements */
for ( Processors = 1; Processors <= CPUs; Processors ++)
{
SetEmployedProcessors( &Processors );
/*
; generate left side matrix and right side vector
*/
printf("\n");
printf("Generate data in a pseudo-random procedure...");
GenerateData( &A[IndexX],
&A[IndexA],
&A[IndexSolution],
&N,
&M,
&Nset
);
/* output number of employed processors */
printf("\nNumber of employed processors: %d\n", Processors);
/* start collecting elapsed time */
CollectElapsedTime();
/* solve in parallel */
meSolution_CSG_S( &A[IndexA],
&N,
&M,
&A[IndexX],
&Nset,
&A[IndexWorking],
&ZERO,
&NoGood
);
/* output elapsed time */
GetElapsedTime(&second);
printf("Solve>>> Elapsed Time (seconds): %8.2f\n", second);
/* stop if the system is not suitable for routine Decompose_DSG */
if( NoGood == 1 )
{
printf("The system is not suit for routine Decompose_CSG.\n");
exit();
}
/* calculate upper and lower bounds of relative error */
KK = IndexX;
JJ = IndexSolution;
for ( II = 1; II <= Nset; II ++)
{
Lower = ( A[JJ] - A[KK] ) / A[JJ];
Upper = Lower;
for ( I = 2; I <= N; I ++)
{
JJ = JJ + 1;
KK = KK + 1;
R4TEMP = ( A[JJ] - A[KK] ) / A[JJ];
if( R4TEMP < Lower)
Lower = R4TEMP;
else if(R4TEMP > Upper)
Upper = R4TEMP;
}
JJ = JJ + 1;
KK = KK + 1;
/* output lower bound and upper bound of the relative error */
printf("Lower and upper bound of the relative error:\n");
printf("%f %f\n", Lower, Upper);
}
}
}
/* function GenerateData */ void GenerateData( float *X,
float *A,
float *Solution,
int *N,
int *M,
int *Nset
)
/*
;
; routine to generate the left side matrix, and the right side vector
; (A)FORTRAN CALL: CALL GenerateData(X,A,Solution,N,M,Nset)
; 1.X: <R4> right side vector, dimension(N,Nset)
; 2.A: <R4> left side matrix, dimension(*)
; 3.Solution: <R4> return the solution for checking accuracy,
; dimension(N,Nset)
; 3.N: <I4> order
; 4.M: <I4> half bandwidth
; 5.Nset: <I4> number of vectors
;
*/
{
/* define macro */
#define _(X,Y) (((Y)-1)* *M + (X))
#define __(X,Y) (((Y)-1)* *N + (X))
#define min(X,Y) ((X)<(Y) ? (X):(Y))
/* locala variables */
int SEED, I, J, II;
float R4TEMP$;
/* left side matrix */
SEED = 456789;
A -= 1;
X -= 1;
Solution -= 1;
for ( I = 1; I <= *N; I ++)
for ( J = I; J <= min(I+ *M, *N); J ++)
A[_(J,I)] = crandom( &SEED ) * 100.0;
for ( I = 1; I <= *N; I ++)
for ( J = I+1; J <= min(I+ *M, *N); J ++)
if( A[_(J,I)] > A[_(I,I)])
{
R4TEMP$ = A[_(J,I)];
A[_(J,I)] = A[_(I,I)];
A[_(I,I)] = R4TEMP$;
}
for ( I = 1; I <= *N; I ++)
A[_(I,I)] = A[_(I,I)] * 50.0;
/* scale for improving accuracy */
for ( I = 1; I <= *N; I ++)
A[_(I,I)] = A[_(I,I)] * 5.0;
/* the solution */
for ( II = 1; II <= *Nset; II ++)
for ( I = 1; I <= *N; I ++)
Solution[__(I,II)] = crandom( &SEED ) * 500.0;
/* right side vector */
for ( II = 1; II <= *Nset; II ++)
{
for ( I = 1; I <= *N; I ++)
X[__(I,II)] = A[_(I,I)] * Solution[__(I,II)];
for ( I = 1; I <= *N; I ++)
for( J = I + 1;
J <= min( *N,I+ *M);
J ++)
{
X[__(I,II)] = X[__(I,II)] + A[_(J,I)] * Solution[__(J,II)];
X[__(J,II)] = X[__(J,II)] + A[_(J,I)] * Solution[__(I,II)];
}
}
return;
}
float crandom(int *seed)
{
#define m 2147483647
#define a 16807
double rtempa, rtempb;
float rtemp;
int itemp;
rtempa = (double) *seed * a;
itemp = (int) (rtempa / (double) m);
rtempb = (double) m * (double) itemp;
*seed = (int) (rtempa - rtempb);
rtemp = (double) *seed / (double) m;
return rtemp;
}