77 fprintf(stderr,
"Error in tridiagLUGS(): NULL pointer passed for parameters.\n");
83 return(
tridiagLU(a,b,c,x,n,ns,context,m));
87 int d,i,ierr = 0,dstart,istart,p,q;
89 double *sendbuf,*recvbuf;
93 MPI_Comm *comm = (MPI_Comm*) m;
94 if (!comm)
return(
tridiagLU(a,b,c,x,n,ns,context,NULL));
95 MPI_Comm_size(*comm,&nproc);
96 MPI_Comm_rank(*comm,&rank);
98 if ((ns == 0) || (n == 0))
return(0);
104 int *N = (
int*) calloc (nproc,
sizeof(
int));
105 MPI_Allgather(&n,1,MPI_INT,N,1,MPI_INT,*comm);
106 int NT = 0;
for (i=0; i<nproc; i++) NT += N[i];
109 int *counts = (
int*) calloc ((
short)nproc,
sizeof(int));
110 int *displ = (
int*) calloc ((
short)nproc,
sizeof(int));
114 int *ns_local = (
int*) calloc ((
short)nproc,
sizeof(int));
115 for (p=0; p<nproc; p++) ns_local[p] = ns / nproc;
116 for (p=0; p<ns%nproc; p++) ns_local[p]++;
119 double *ra=NULL,*rb=NULL,*rc=NULL,*rx=NULL;
120 if (ns_local[rank] > 0) {
121 ra = (
double*) calloc (ns_local[rank]*NT,
sizeof(
double));
122 rb = (
double*) calloc (ns_local[rank]*NT,
sizeof(
double));
123 rc = (
double*) calloc (ns_local[rank]*NT,
sizeof(
double));
124 rx = (
double*) calloc (ns_local[rank]*NT,
sizeof(
double));
129 if (ns_local[rank] > 0)
130 recvbuf = (
double*) calloc (ns_local[rank]*nvar*NT,
sizeof(
double));
133 for (p = 0; p < nproc; p++) {
134 if (ns_local[p] > 0) {
136 sendbuf = (
double*) calloc (nvar*n*ns_local[p],
sizeof(
double));
137 for (d = 0; d < ns_local[p]; d++) {
138 for (i = 0; i < n; i++) {
139 sendbuf[n*nvar*d+n*0+i] = a[d+dstart+ns*i];
140 sendbuf[n*nvar*d+n*1+i] = b[d+dstart+ns*i];
141 sendbuf[n*nvar*d+n*2+i] = c[d+dstart+ns*i];
142 sendbuf[n*nvar*d+n*3+i] = x[d+dstart+ns*i];
145 dstart += ns_local[p];
149 for (q = 0; q < nproc; q++) {
150 counts[q] = nvar*N[q]*ns_local[p];
151 displ [q] = (q == 0 ? 0 : displ[q-1]+counts[q-1]);
154 MPI_Gatherv(sendbuf,nvar*n*ns_local[p],MPI_DOUBLE,
155 recvbuf,counts,displ,MPI_DOUBLE,p,*comm);
163 for (q = 0; q < nproc; q++) {
164 for (d = 0; d < ns_local[rank]; d++) {
165 for (i = 0; i < N[q]; i++) {
166 ra[d+ns_local[rank]*(istart+i)] = recvbuf[istart*nvar*ns_local[rank]+d*nvar*N[q]+0*N[q]+i];
167 rb[d+ns_local[rank]*(istart+i)] = recvbuf[istart*nvar*ns_local[rank]+d*nvar*N[q]+1*N[q]+i];
168 rc[d+ns_local[rank]*(istart+i)] = recvbuf[istart*nvar*ns_local[rank]+d*nvar*N[q]+2*N[q]+i];
169 rx[d+ns_local[rank]*(istart+i)] = recvbuf[istart*nvar*ns_local[rank]+d*nvar*N[q]+3*N[q]+i];
175 if (recvbuf) free(recvbuf);
178 ierr =
tridiagLU(ra,rb,rc,rx,NT,ns_local[rank],context,NULL);
179 if (ierr)
return(ierr);
182 if (ns_local[rank] > 0)
183 sendbuf = (
double*) calloc (ns_local[rank]*NT,
sizeof(
double));
186 for (q = 0; q < nproc; q++) {
187 for (i = 0; i < N[q]; i++) {
188 for (d = 0; d < ns_local[rank]; d++) {
189 sendbuf[istart*ns_local[rank]+d*N[q]+i] = rx[d+ns_local[rank]*(istart+i)];
195 for (p = 0; p < nproc; p++) {
196 if (ns_local[p] > 0) {
199 recvbuf = (
double*) calloc (ns_local[p]*n,
sizeof(
double));
202 for (q = 0; q < nproc; q++) {
203 counts[q] = ns_local[p]*N[q];
204 displ[q] = (q == 0 ? 0 : displ[q-1]+counts[q-1]);
206 MPI_Scatterv(sendbuf,counts,displ,MPI_DOUBLE,
207 recvbuf,ns_local[p]*n,MPI_DOUBLE,
210 for (d = 0; d < ns_local[p]; d++) {
211 for (i = 0; i < n; i++) {
212 x[d+dstart+ns*i] = recvbuf[d*n+i];
215 dstart += ns_local[p];
221 if (sendbuf) free(sendbuf);
224 if (ns_local[rank] > 0) {
Header file for TridiagLU.
int tridiagLU(double *, double *, double *, double *, int, int, void *, void *)
int tridiagLUGS(double *a, double *b, double *c, double *x, int n, int ns, void *r, void *m)