IFPACK  Development
 All Classes Namespaces Files Functions Variables Enumerations Friends Pages
Numbering_dh.c
1 /*@HEADER
2 // ***********************************************************************
3 //
4 // Ifpack: Object-Oriented Algebraic Preconditioner Package
5 // Copyright (2002) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ***********************************************************************
40 //@HEADER
41 */
42 
43 #include "Numbering_dh.h"
44 #include "Mat_dh.h"
45 #include "Hash_i_dh.h"
46 #include "Mem_dh.h"
47 #include "shellSort_dh.h"
48 #include "Parser_dh.h"
49 
50 
51 #undef __FUNC__
52 #define __FUNC__ "Numbering_dhCreate"
53 void
54 Numbering_dhCreate (Numbering_dh * numb)
55 {
56  START_FUNC_DH
57  struct _numbering_dh *tmp =
58  (struct _numbering_dh *) MALLOC_DH (sizeof (struct _numbering_dh));
59  CHECK_V_ERROR;
60  *numb = tmp;
61 
62  tmp->size = 0;
63  tmp->first = 0;
64  tmp->m = 0;
65  tmp->num_ext = 0;
66  tmp->num_extLo = 0;
67  tmp->num_extHi = 0;
68  tmp->idx_ext = NULL;
69  tmp->idx_extLo = NULL;
70  tmp->idx_extHi = NULL;
71  tmp->idx_ext = NULL;
72  tmp->debug = Parser_dhHasSwitch (parser_dh, "-debug_Numbering");
73 END_FUNC_DH}
74 
75 #undef __FUNC__
76 #define __FUNC__ "Numbering_dhDestroy"
77 void
78 Numbering_dhDestroy (Numbering_dh numb)
79 {
80  START_FUNC_DH if (numb->global_to_local != NULL)
81  {
82  Hash_i_dhDestroy (numb->global_to_local);
83  CHECK_V_ERROR;
84  }
85  if (numb->idx_ext != NULL)
86  {
87  FREE_DH (numb->idx_ext);
88  CHECK_V_ERROR;
89  }
90  FREE_DH (numb);
91  CHECK_V_ERROR;
92 END_FUNC_DH}
93 
94 
95 /*
96 The internal indices are numbered 0 to nlocal-1 so they do not
97 need to be sorted. The external indices are sorted so that
98 the indices from a given processor are stored contiguously.
99 Then in the matvec, no reordering of the data is needed.
100 */
101 
102 #undef __FUNC__
103 #define __FUNC__ "Numbering_dhSetup"
104 void
105 Numbering_dhSetup (Numbering_dh numb, Mat_dh mat)
106 {
107  START_FUNC_DH int i, len, *cval = mat->cval;
108  int num_ext, num_extLo, num_extHi;
109  int m = mat->m, size;
110  Hash_i_dh global_to_local_hash;
111  int first = mat->beg_row, last = first + m;
112  int *idx_ext;
113  int data;
114 /* int debug = false; */
115 
116 /* if (logFile != NULL && numb->debug) debug = true; */
117 
118  numb->first = first;
119  numb->m = m;
120 
121  /* Allocate space for look-up tables */
122 
123  /* initial guess: there are at most 'm' external indices */
124  numb->size = size = m;
125  Hash_i_dhCreate (&(numb->global_to_local), m);
126  CHECK_V_ERROR;
127 
128  global_to_local_hash = numb->global_to_local;
129  idx_ext = numb->idx_ext = (int *) MALLOC_DH (size * sizeof (int));
130  CHECK_V_ERROR;
131 
132  /* find all external indices; at the end of this block,
133  idx_ext[] will contain an unsorted list of external indices.
134  */
135  len = mat->rp[m];
136  num_ext = num_extLo = num_extHi = 0;
137  for (i = 0; i < len; i++)
138  { /* for each nonzero "index" in the matrix */
139  int index = cval[i];
140 
141  /* Only interested in external indices */
142  if (index < first || index >= last)
143  {
144 
145  /* if index hasn't been previously inserted, do so now. */
146  data = Hash_i_dhLookup (global_to_local_hash, cval[i]);
147  CHECK_V_ERROR;
148 
149  if (data == -1)
150  { /* index hasn't been inserted, so do so now */
151 
152  /* reallocate idx_ext array if we're out of
153  space. The global_to_local hash table may also need
154  to be enlarged, but the hash object will take care of that.
155  */
156  if (m + num_ext >= size)
157  {
158  int newSize = size * 1.5; /* heuristic */
159  int *tmp = (int *) MALLOC_DH (newSize * sizeof (int));
160  CHECK_V_ERROR;
161  memcpy (tmp, idx_ext, size * sizeof (size));
162  FREE_DH (idx_ext);
163  CHECK_V_ERROR;
164  size = numb->size = newSize;
165  numb->idx_ext = idx_ext = tmp;
166  SET_INFO ("reallocated ext_idx[]");
167  }
168 
169  /* insert external index */
170  Hash_i_dhInsert (global_to_local_hash, index, num_ext);
171  CHECK_V_ERROR;
172  idx_ext[num_ext] = index;
173 
174  num_ext++;
175  if (index < first)
176  {
177  num_extLo++;
178  }
179  else
180  {
181  num_extHi++;
182  }
183  }
184  }
185  }
186 
187  numb->num_ext = num_ext;
188  numb->num_extLo = num_extLo;
189  numb->num_extHi = num_extHi;
190  numb->idx_extLo = idx_ext;
191  numb->idx_extHi = idx_ext + num_extLo;
192 
193  /* sort the list of external indices, then redo the hash
194  table; the table is used to convert external indices
195  in Numbering_dhGlobalToLocal()
196  */
197  shellSort_int (num_ext, idx_ext);
198 
199  Hash_i_dhReset (global_to_local_hash);
200  CHECK_V_ERROR;
201  for (i = 0; i < num_ext; i++)
202  {
203  Hash_i_dhInsert (global_to_local_hash, idx_ext[i], i + m);
204  CHECK_V_ERROR;
205  }
206 END_FUNC_DH}
207 
208 #undef __FUNC__
209 #define __FUNC__ "Numbering_dhGlobalToLocal"
210 void
211 Numbering_dhGlobalToLocal (Numbering_dh numb, int len,
212  int *global, int *local)
213 {
214  START_FUNC_DH int i;
215  int first = numb->first;
216  int last = first + numb->m;
217  int data;
218  Hash_i_dh global_to_local = numb->global_to_local;
219 
220  for (i = 0; i < len; i++)
221  {
222  int idxGlobal = global[i];
223  if (idxGlobal >= first && idxGlobal < last)
224  {
225  local[i] = idxGlobal - first;
226  /* note: for matvec setup, numb->num_extLo = 0. */
227  }
228  else
229  {
230  data = Hash_i_dhLookup (global_to_local, idxGlobal);
231  CHECK_V_ERROR;
232  if (data == -1)
233  {
234  sprintf (msgBuf_dh, "global index %i not found in map\n",
235  idxGlobal);
236  SET_V_ERROR (msgBuf_dh);
237  }
238  else
239  {
240  local[i] = data;
241  }
242  }
243  }
244 END_FUNC_DH}
Definition: Mat_dh.h:68