/[escript]/trunk/paso/src/Pattern.c
ViewVC logotype

Contents of /trunk/paso/src/Pattern.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1736 - (show annotations)
Fri Aug 29 02:23:16 2008 UTC (10 years, 9 months ago) by gross
File MIME type: text/plain
File size: 5021 byte(s)
This fixes a problem which is typically arising when using reduced order
with MPI and a "small" number of elements per processor. In this case it
can happen that the couple matrix is not using all entries sent to the
processor. The old implementations assumed that the indices will cover
the entire input. This assumption has been removed.


1
2 /* $Id: Pattern.c 1306 2007-09-18 05:51:09Z ksteube $ */
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 /* Paso: Pattern */
19
20 /**************************************************************/
21
22 /* Author: gross@access.edu.au */
23
24 /**************************************************************/
25
26 #include "Paso.h"
27 #include "Pattern.h"
28
29 /**************************************************************/
30
31 /* allocates a Pattern */
32
33 Paso_Pattern* Paso_Pattern_alloc(int type, dim_t input_block_size, dim_t output_block_size, dim_t numOutput, dim_t numInput, index_t* ptr, index_t* index) {
34 Paso_Pattern*out=NULL;
35 index_t index_offset=(type & PATTERN_FORMAT_OFFSET1 ? 1:0);
36 index_t loc_min_index,loc_max_index,min_index=index_offset,max_index=index_offset-1;
37 dim_t i, sum=0;
38 Paso_resetError();
39
40 if (type & PATTERN_FORMAT_SYM) {
41 Paso_setError(TYPE_ERROR,"Paso_Pattern_alloc: symmetric matrix pattern is not supported yet");
42 return NULL;
43 }
44 if (ptr!=NULL && index != NULL) {
45 #pragma omp parallel private(loc_min_index,loc_max_index,i)
46 {
47 loc_min_index=index_offset;
48 loc_max_index=index_offset-1;
49 if (type & PATTERN_FORMAT_OFFSET1) {
50 #pragma omp for schedule(static)
51 for (i=0;i<numOutput;++i) {
52 if (ptr[i]<ptr[i+1]) {
53 #ifdef USE_QSORTG
54 qsortG(&(index[ptr[i]-1]),(size_t)(ptr[i+1]-ptr[i]),sizeof(index_t),Paso_comparIndex);
55 #else
56 qsort(&(index[ptr[i]-1]),(size_t)(ptr[i+1]-ptr[i]),sizeof(index_t),Paso_comparIndex);
57 #endif
58 loc_min_index=MIN(loc_min_index,index[ptr[i]-1]);
59 loc_max_index=MAX(loc_max_index,index[ptr[i+1]-2]);
60 }
61 }
62 } else {
63 #pragma omp for schedule(static)
64 for (i=0;i<numOutput;++i) {
65 if (ptr[i]<ptr[i+1]) {
66 #ifdef USE_QSORTG
67 qsortG(&(index[ptr[i]]),(size_t)(ptr[i+1]-ptr[i]),sizeof(index_t),Paso_comparIndex);
68 #else
69 qsort(&(index[ptr[i]]),(size_t)(ptr[i+1]-ptr[i]),sizeof(index_t),Paso_comparIndex);
70 #endif
71 loc_min_index=MIN(loc_min_index,index[ptr[i]]);
72 loc_max_index=MAX(loc_max_index,index[ptr[i+1]-1]);
73 }
74 }
75 }
76 #pragma omp critical
77 {
78 min_index=MIN(loc_min_index,min_index);
79 max_index=MAX(loc_max_index,max_index);
80 }
81 }
82 if ( (min_index<index_offset) || (max_index>=numInput+index_offset) ) {
83 Paso_setError(TYPE_ERROR,"Paso_Pattern_alloc: Pattern index out of range.");
84 return NULL;
85 }
86 }
87 out=MEMALLOC(1,Paso_Pattern);
88 if (! Paso_checkPtr(out)) {
89 out->type=type;
90 out->reference_counter=1;
91 out->numOutput=numOutput;
92 out->numInput=numInput;
93 out->ptr=ptr;
94 out->index=index;
95 out->input_block_size=input_block_size;
96 out->output_block_size=output_block_size;
97 out->block_size=out->input_block_size * out->output_block_size;
98 if (out->ptr == NULL) {
99 out->len=0;
100 } else {
101 out->len=out->ptr[out->numOutput] - index_offset;
102 }
103 }
104 #ifdef Paso_TRACE
105 printf("Paso_Pattern_alloc: system matrix pattern as been allocated.\n");
106 #endif
107 return out;
108 }
109
110 /* returns a reference to in */
111
112 Paso_Pattern* Paso_Pattern_getReference(Paso_Pattern* in) {
113 if (in!=NULL) {
114 ++(in->reference_counter);
115 }
116 return in;
117 }
118
119 /* deallocates a Pattern: */
120
121 void Paso_Pattern_free(Paso_Pattern* in) {
122 if (in!=NULL) {
123 in->reference_counter--;
124 if (in->reference_counter<=0) {
125 MEMFREE(in->ptr);
126 MEMFREE(in->index);
127 MEMFREE(in);
128 #ifdef Paso_TRACE
129 printf("Paso_Pattern_free: pattern as been deallocated.\n");
130 #endif
131 }
132 }
133 }
134 /* *************************************************************/
135
136 /* some routines which help to get the matrix pattern from elements: */
137
138 /* this routine is used by qsort called in Paso_Pattern_alloc */
139
140 int Paso_comparIndex(const void *index1,const void *index2){
141 index_t Iindex1,Iindex2;
142 Iindex1=*(index_t*)index1;
143 Iindex2=*(index_t*)index2;
144 if (Iindex1<Iindex2) {
145 return -1;
146 } else {
147 if (Iindex1>Iindex2) {
148 return 1;
149 } else {
150 return 0;
151 }
152 }
153 }
154
155 bool_t Paso_Pattern_isEmpty(Paso_Pattern* in) {
156 if (in != NULL) {
157 if ((in->ptr != NULL) && (in->index != NULL)) return FALSE;
158 }
159 return TRUE;
160 }

  ViewVC Help
Powered by ViewVC 1.1.26