/[escript]/trunk/finley/src/NodeFile_gather.c
ViewVC logotype

Contents of /trunk/finley/src/NodeFile_gather.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1628 - (show annotations)
Fri Jul 11 13:12:46 2008 UTC (11 years, 4 months ago) by phornby
File MIME type: text/plain
File size: 9116 byte(s)

Merge in /branches/windows_from_1456_trunk_1620_merged_in branch.

You will find a preserved pre-merge trunk in tags under tags/trunk_at_1625.
That will be useful for diffing & checking on my stupidity.

Here is a list of the conflicts and their resolution at this
point in time.


=================================================================================
(LLWS == looks like white space).

finley/src/Assemble_addToSystemMatrix.c - resolve to branch - unused var. may be wrong.....
finley/src/CPPAdapter/SystemMatrixAdapter.cpp - resolve to branch - LLWS
finley/src/CPPAdapter/MeshAdapter.cpp - resolve to branch - LLWS
paso/src/PCG.c - resolve to branch - unused var fixes.
paso/src/SolverFCT.c - resolve to branch - LLWS
paso/src/FGMRES.c - resolve to branch - LLWS
paso/src/Common.h - resolve to trunk version. It's omp.h's include... not sure it's needed,
but for the sake of saftey.....
paso/src/Functions.c - resolve to branch version, indentation/tab removal and return error
on bad unimplemented Paso_FunctionCall.
paso/src/SolverFCT_solve.c - resolve to branch version, unused vars
paso/src/SparseMatrix_MatrixVector.c - resolve to branch version, unused vars.
escript/src/Utils.cpp - resloved to branch, needs WinSock2.h
escript/src/DataExpanded.cpp - resolved to branch version - LLWS
escript/src/DataFactory.cpp - resolve to branch version
=================================================================================

This currently passes tests on linux (debian), but is not checked on windows or Altix yet.

This checkin is to make a trunk I can check out for windows to do tests on it.

Known outstanding problem is in the operator=() method of exceptions
causing warning messages on the intel compilers.

May the God of doughnuts have mercy on my soul.


1
2 /* $Id$ */
3
4 /*******************************************************
5 *
6 * Copyright 2003-2007 by ACceSS MNRF
7 * Copyright 2007 by University of Queensland
8 *
9 * http://esscc.uq.edu.au
10 * Primary Business: Queensland, Australia
11 * Licensed under the Open Software License version 3.0
12 * http://www.opensource.org/licenses/osl-3.0.php
13 *
14 *******************************************************/
15
16 /**************************************************************/
17
18 /* Finley: Mesh: NodeFile */
19
20 /* gathers the NodeFile out from the NodeFile in using the entries
21 /* in index[0:out->numNodes-1] which are between min_index and max_index (exclusive) */
22 /* the node index[i]
23
24 /**************************************************************/
25
26 #include "NodeFile.h"
27
28 /**************************************************************/
29
30 void Finley_NodeFile_gatherEntries(dim_t n, index_t* index, index_t min_index, index_t max_index,
31 index_t* Id_out, index_t* Id_in,
32 index_t* Tag_out, index_t* Tag_in,
33 index_t* globalDegreesOfFreedom_out, index_t* globalDegreesOfFreedom_in,
34 dim_t numDim, double* Coordinates_out, double* Coordinates_in)
35 {
36 dim_t i;
37 register index_t k;
38 register const index_t range=max_index-min_index;
39 const size_t numDim_size=(size_t)numDim*sizeof(double);
40
41 #pragma omp parallel for private(i,k) schedule(static)
42 for (i=0;i<n;i++) {
43 k=index[i]-min_index;
44 if ((k>=0) && (k <range)) {
45 Id_out[i]=Id_in[k];
46 Tag_out[i]=Tag_in[k];
47 globalDegreesOfFreedom_out[i]=globalDegreesOfFreedom_in[k];
48 memcpy(&(Coordinates_out[INDEX2(0,i,numDim)]), &(Coordinates_in[INDEX2(0,k,numDim)]), numDim_size);
49 }
50 }
51 }
52
53 void Finley_NodeFile_gather(index_t* index, Finley_NodeFile* in, Finley_NodeFile* out)
54 {
55 index_t min_id, max_id;
56 Finley_NodeFile_setGlobalIdRange(&min_id,&max_id,in);
57 Finley_NodeFile_gatherEntries(out->numNodes, index, min_id, max_id,
58 out->Id, in->Id,
59 out->Tag, in->Tag,
60 out->globalDegreesOfFreedom, in->globalDegreesOfFreedom,
61 out->numDim, out->Coordinates, in->Coordinates);
62 }
63
64 void Finley_NodeFile_gather_global(index_t* index, Finley_NodeFile* in, Finley_NodeFile* out)
65 {
66 index_t min_id, max_id, undefined_node;
67 Paso_MPI_rank buffer_rank, dest, source, *distribution=NULL;
68 index_t *Id_buffer=NULL, *Tag_buffer=NULL, *globalDegreesOfFreedom_buffer=NULL;
69 double* Coordinates_buffer=NULL;
70 dim_t p, buffer_len,n;
71 char error_msg[100];
72 #ifdef PASO_MPI
73 MPI_Status status;
74 #endif
75
76 /* get the global range of node ids */
77 Finley_NodeFile_setGlobalIdRange(&min_id,&max_id,in);
78 undefined_node=min_id-1;
79
80 distribution=TMPMEMALLOC(in->MPIInfo->size+1, index_t);
81
82 if ( !Finley_checkPtr(distribution) ) {
83 /* distribute the range of node ids */
84 buffer_len=Paso_MPIInfo_setDistribution(in->MPIInfo,min_id,max_id,distribution);
85 /* allocate buffers */
86 Id_buffer=TMPMEMALLOC(buffer_len,index_t);
87 Tag_buffer=TMPMEMALLOC(buffer_len,index_t);
88 globalDegreesOfFreedom_buffer=TMPMEMALLOC(buffer_len,index_t);
89 Coordinates_buffer=TMPMEMALLOC(buffer_len*out->numDim,double);
90 if (! (Finley_checkPtr(Id_buffer) || Finley_checkPtr(Tag_buffer) ||
91 Finley_checkPtr(globalDegreesOfFreedom_buffer) || Finley_checkPtr(Coordinates_buffer) ) ) {
92 /* fill Id_buffer by the undefined_node marker to check if nodes are defined */
93 #pragma omp parallel for private(n) schedule(static)
94 for (n=0;n<buffer_len;n++) Id_buffer[n]=undefined_node;
95
96 /* fill the buffer by sending portions around in a circle */
97 dest=Paso_MPIInfo_mod(in->MPIInfo->size, in->MPIInfo->rank + 1);
98 source=Paso_MPIInfo_mod(in->MPIInfo->size, in->MPIInfo->rank - 1);
99 buffer_rank=in->MPIInfo->rank;
100 for (p=0; p< in->MPIInfo->size; ++p) {
101 if (p>0) { /* the initial send can be skipped */
102 #ifdef PASO_MPI
103 MPI_Sendrecv_replace(Id_buffer, buffer_len, MPI_INT,
104 dest, in->MPIInfo->msg_tag_counter, source, in->MPIInfo->msg_tag_counter,
105 in->MPIInfo->comm,&status);
106 MPI_Sendrecv_replace(Tag_buffer, buffer_len, MPI_INT,
107 dest, in->MPIInfo->msg_tag_counter+1, source, in->MPIInfo->msg_tag_counter+1,
108 in->MPIInfo->comm,&status);
109 MPI_Sendrecv_replace(globalDegreesOfFreedom_buffer, buffer_len, MPI_INT,
110 dest, in->MPIInfo->msg_tag_counter+2, source, in->MPIInfo->msg_tag_counter+2,
111 in->MPIInfo->comm,&status);
112 MPI_Sendrecv_replace(Coordinates_buffer, buffer_len*out->numDim, MPI_DOUBLE,
113 dest, in->MPIInfo->msg_tag_counter+3, source, in->MPIInfo->msg_tag_counter+3,
114 in->MPIInfo->comm,&status);
115 #endif
116 in->MPIInfo->msg_tag_counter+=4;
117 }
118 buffer_rank=Paso_MPIInfo_mod(in->MPIInfo->size, buffer_rank-1);
119 Finley_NodeFile_scatterEntries(in->numNodes, in->Id,
120 distribution[buffer_rank], distribution[buffer_rank+1],
121 Id_buffer, in->Id,
122 Tag_buffer, in->Tag,
123 globalDegreesOfFreedom_buffer, in->globalDegreesOfFreedom,
124 out->numDim, Coordinates_buffer, in->Coordinates);
125 }
126 /* now entries are collected from the buffer again by sending the entries around in a circle */
127 dest=Paso_MPIInfo_mod(in->MPIInfo->size, in->MPIInfo->rank + 1);
128 source=Paso_MPIInfo_mod(in->MPIInfo->size, in->MPIInfo->rank - 1);
129 buffer_rank=in->MPIInfo->rank;
130 for (p=0; p< in->MPIInfo->size; ++p) {
131 Finley_NodeFile_gatherEntries(out->numNodes, index,
132 distribution[buffer_rank], distribution[buffer_rank+1],
133 out->Id, Id_buffer,
134 out->Tag, Tag_buffer,
135 out->globalDegreesOfFreedom, globalDegreesOfFreedom_buffer,
136 out->numDim, out->Coordinates, Coordinates_buffer);
137 if (p<in->MPIInfo->size-1) { /* the last send can be skipped */
138 #ifdef PASO_MPI
139 MPI_Sendrecv_replace(Id_buffer, buffer_len, MPI_INT,
140 dest, in->MPIInfo->msg_tag_counter, source, in->MPIInfo->msg_tag_counter,
141 in->MPIInfo->comm,&status);
142 MPI_Sendrecv_replace(Tag_buffer, buffer_len, MPI_INT,
143 dest, in->MPIInfo->msg_tag_counter+1, source, in->MPIInfo->msg_tag_counter+1,
144 in->MPIInfo->comm,&status);
145 MPI_Sendrecv_replace(globalDegreesOfFreedom_buffer, buffer_len, MPI_INT,
146 dest, in->MPIInfo->msg_tag_counter+2, source, in->MPIInfo->msg_tag_counter+2,
147 in->MPIInfo->comm,&status);
148 MPI_Sendrecv_replace(Coordinates_buffer, buffer_len*out->numDim, MPI_DOUBLE,
149 dest, in->MPIInfo->msg_tag_counter+3, source, in->MPIInfo->msg_tag_counter+3,
150 in->MPIInfo->comm,&status);
151 #endif
152 in->MPIInfo->msg_tag_counter+=4;
153 }
154 buffer_rank=Paso_MPIInfo_mod(in->MPIInfo->size, buffer_rank-1);
155 }
156 /* check if all nodes are set: */
157 #pragma omp parallel for private(n) schedule(static)
158 for (n=0; n< out->numNodes; ++n) {
159 if (out->Id[n] == undefined_node ) {
160 sprintf(error_msg,"Finley_NodeFile_gather_global: Node id %d is referenced but is not defined.",out->Id[n]);
161 Finley_setError(VALUE_ERROR,error_msg);
162 }
163 }
164
165 }
166 TMPMEMFREE(Id_buffer);
167 TMPMEMFREE(Tag_buffer);
168 TMPMEMFREE(globalDegreesOfFreedom_buffer);
169 TMPMEMFREE(Coordinates_buffer);
170 }
171 TMPMEMFREE(distribution);
172 /* make sure that the error is global */
173 Paso_MPIInfo_noError(in->MPIInfo);
174 }

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.26