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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1736 - (hide annotations)
Fri Aug 29 02:23:16 2008 UTC (12 years, 6 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 ksteube 1313
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 gross 1736 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 ksteube 1313 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 gross 1736 if ( (min_index<index_offset) || (max_index>=numInput+index_offset) ) {
83     Paso_setError(TYPE_ERROR,"Paso_Pattern_alloc: Pattern index out of range.");
84 ksteube 1313 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 gross 1736 out->numInput=numInput;
93 ksteube 1313 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