A reentrant example that runs two threads then run two instances of the solver in each thread.
/
#include <pthread.h>
#include <spm.h>
typedef struct solve_param {
double dparm[DPARM_SIZE];
char *filename;
spm_driver_t driver;
int check;
int scatter;
int id;
int rc;
} solve_param_t;
static void *solve_smp(void *arg)
{
spmatrix_t *spm;
spmatrix_t spm2;
void *x, *b, *x0 = NULL;
size_t size;
int check;
int scatter;
int rc;
int nrhs = 1;
solve_param_t param = *(solve_param_t *)arg;
}
check = param.check;
scatter = param.scatter;
{
int i;
}
param.iparm, param.dparm,
bindtab );
free( bindtab );
}
#if defined(PASTIX_WITH_MPI)
{
int size, rank;
MPI_Comm_size( MPI_COMM_WORLD, &size );
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
if( size > 1 ) {
if ( rank == 0 ) {
fprintf( stderr, "\nWarning: Reentrant doesn't work with multiple MPI instances\n" );
fprintf( stderr, "Quitting now\n" );
}
exit(0);
}
}
#endif
spm = malloc( sizeof( spmatrix_t ) );
if ( scatter ) {
rc = spmReadDriverDist( param.driver, param.filename, spm, MPI_COMM_WORLD );
}
else {
rc = spmReadDriver( param.driver, param.filename, spm );
}
if ( rc != SPM_SUCCESS ) {
return NULL;
}
spmPrintInfo( spm, stdout );
rc = spmCheckAndCorrect( spm, &spm2 );
if ( rc != 0 ) {
spmExit( spm );
*spm = spm2;
rc = 0;
}
if ( spm->flttype == SpmPattern ) {
spmGenFakeValues( spm );
}
double normA = spmNorm( SpmFrobeniusNorm, spm );
spmScal( 1./normA, spm );
size = pastix_size_of( spm->flttype ) * spm->nexp * nrhs;
x = malloc( size );
b = malloc( size );
if ( check )
{
if ( check > 1 ) {
x0 = malloc( size );
}
spmGenRHS( SpmRhsRndX, nrhs, spm, x0, spm->nexp, b, spm->nexp );
memcpy( x, b, size );
}
else {
spmGenRHS( SpmRhsRndB, nrhs, spm, NULL, spm->nexp, x, spm->nexp );
spmScalMat( 1./normA, spm, nrhs, b, spm->nexp );
memcpy( b, x, size );
}
if ( check )
{
spm, x0, spm->nexp, b, spm->nexp, x, spm->nexp );
if ( x0 ) {
free( x0 );
}
}
spmExit( spm );
free( x );
free( b );
free( spm );
return NULL;
}
int main (int argc, char **argv)
{
double dparm[DPARM_SIZE];
spm_driver_t driver;
char *filename = NULL;
int nbcallingthreads = 2;
solve_param_t *solve_param;
pthread_t *threads;
int scatter = 0;
int check = 1;
int rc = 0;
int i;
iparm, dparm,
&check, &scatter, &driver, &filename );
solve_param = (solve_param_t*) malloc(nbcallingthreads * sizeof(solve_param_t));
threads = (pthread_t*) malloc(nbcallingthreads * sizeof(pthread_t));
for (i = 0; i < nbcallingthreads; i++)
{
memcpy(solve_param[i].iparm, iparm, sizeof(solve_param[i].iparm));
memcpy(solve_param[i].dparm, dparm, sizeof(solve_param[i].dparm));
solve_param[i].check = check;
solve_param[i].scatter = scatter;
solve_param[i].id = i;
solve_param[i].driver = driver;
solve_param[i].filename = filename;
solve_param[i].rc = 0;
pthread_create(&threads[i], NULL, solve_smp, (void *)&solve_param[i]);
}
for (i = 0; i < nbcallingthreads; i++) {
pthread_join(threads[i],(void**)NULL);
rc += solve_param[i].rc;
}
free( filename );
free( threads );
free( solve_param );
return rc;
}
BEGIN_C_DECLS typedef int pastix_int_t
void pastixFinalize(pastix_data_t **pastix_data)
Finalize the solver instance.
void pastixInitParam(pastix_int_t *iparm, double *dparm)
Initialize the iparm and dparm arrays to their default values.
void pastixInitWithAffinity(pastix_data_t **pastix_data, PASTIX_Comm pastix_comm, pastix_int_t *iparm, double *dparm, const int *bindtab)
Initialize the solver instance with a bintab array to specify the thread binding.
@ DPARM_EPSILON_REFINEMENT
void pastixGetOptions(int argc, char **argv, pastix_int_t *iparm, double *dparm, int *check, int *scatter, spm_driver_t *driver, char **filename)
PaStiX helper function to read command line options in examples.
int pastix_task_refine(pastix_data_t *pastix_data, pastix_int_t n, pastix_int_t nrhs, void *B, pastix_int_t ldb, void *X, pastix_int_t ldx)
Perform iterative refinement.
int pastix_task_analyze(pastix_data_t *pastix_data, const spmatrix_t *spm)
Perform all the preprocessing steps: ordering, symbolic factorization, reordering,...
int pastix_task_solve(pastix_data_t *pastix_data, pastix_int_t m, pastix_int_t nrhs, void *B, pastix_int_t ldb)
Solve the given problem.
int pastix_task_numfact(pastix_data_t *pastix_data, spmatrix_t *spm)
Perform all the numerical factorization steps: fill the internal block CSC and the solver matrix stru...
Main PaStiX data structure.