
/*
   ParallelFetchMat.c
 */

#ifdef HAVE_CONFIG_H
	#include "config.h"
#else
#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
#endif

#include "stdio.h"
#include "../shared/shared.h"

#if defined(_PARALLEL_) && defined(_HAVE_PETSC_)

#undef __FUNCT__
#define __FUNCT__ "ParallelFetchMat"
#define CLEANUP ParallelFetchMatLocalCleanup();

void ParallelFetchMat(double** pmatrix,int* pmatrix_rows,int* pmatrix_cols,FILE* fid){

	/*output: */
	int matrix_rows,matrix_cols;
	double* matrix=NULL;
	extern int my_rank;
	extern int num_procs;

	/*We have to read a matrix from disk. First read the dimensions of the matrix, then the whole matrix: */
	/*numberofelements: */
	if(my_rank==0){  
		if(fread(&matrix_rows,sizeof(int),1,fid)!=1) throw ErrorException(__FUNCT__,"could not read number of rows for matrix ");
	}

	MPI_Bcast(&matrix_rows,1,MPI_INT,0,MPI_COMM_WORLD); 

	if(my_rank==0){  
		if(fread(&matrix_cols,sizeof(int),1,fid)!=1) throw ErrorException(__FUNCT__,"  could not read number of columns for matrix ");
	}
	MPI_Bcast(&matrix_cols,1,MPI_INT,0,MPI_COMM_WORLD); 

	/*Now allocate matrix: */
	if(matrix_rows*matrix_cols){
		matrix=(double*)xmalloc(matrix_rows*matrix_cols*sizeof(double));

		/*Read matrix on node 0, then broadcast: */
		if(my_rank==0){  
			if(fread(matrix,matrix_rows*matrix_cols*sizeof(double),1,fid)!=1) throw ErrorException(__FUNCT__," could not read matrix ");
		}
		
		MPI_Bcast(matrix,matrix_rows*matrix_cols,MPI_DOUBLE,0,MPI_COMM_WORLD); 
	}


	/*Assign output pointers: */
	if (pmatrix)*pmatrix=matrix;
	if (pmatrix_rows)*pmatrix_rows=matrix_rows;
	if (pmatrix_cols)*pmatrix_cols=matrix_cols;

}

#endif //#if defined(_PARALLEL_) && defined(_HAVE_PETSC_)
