/[escript]/branches/doubleplusgood/paso/src/Distribution.cpp
ViewVC logotype

Contents of /branches/doubleplusgood/paso/src/Distribution.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4324 - (show annotations)
Wed Mar 20 00:55:44 2013 UTC (6 years, 1 month ago) by jfenwick
File size: 4548 byte(s)
continues
1
2 /*****************************************************************************
3 *
4 * Copyright (c) 2003-2013 by University of Queensland
5 * http://www.uq.edu.au
6 *
7 * Primary Business: Queensland, Australia
8 * Licensed under the Open Software License version 3.0
9 * http://www.opensource.org/licenses/osl-3.0.php
10 *
11 * Development until 2012 by Earth Systems Science Computational Center (ESSCC)
12 * Development since 2012 by School of Earth Sciences
13 *
14 *****************************************************************************/
15
16
17 /************************************************************************************/
18
19 /* Paso: distribution */
20
21 /************************************************************************************/
22
23 /* Author: Lutz Gross, l.gross@uq.edu.au */
24
25 /************************************************************************************/
26
27 #include "Distribution.h"
28 #include "PasoUtil.h"
29 #include "esysUtils/error.h" /* For checkPtr */
30
31 Paso_Distribution* Paso_Distribution_alloc( Esys_MPIInfo *mpi_info,
32 index_t *first_component,
33 index_t m, index_t b)
34 {
35 int i;
36 Paso_Distribution *out=NULL;
37 out = new Paso_Distribution;
38 if (Esys_checkPtr(out)) return NULL;
39 out->mpi_info = Esys_MPIInfo_getReference(mpi_info);
40 out->reference_counter = 0;
41 out->first_component=NULL;
42
43 out->first_component = new index_t[(mpi_info->size)+1];
44 if (Esys_checkPtr(out->first_component)) {
45 Paso_Distribution_free(out);
46 return NULL;
47 }
48 for (i=0; i<(mpi_info->size)+1; ++i) out->first_component[i]=m*first_component[i]+b;
49 out->reference_counter++;
50 return out;
51 }
52
53 void Paso_Distribution_free( Paso_Distribution *in )
54 {
55 if (in != NULL) {
56 --(in->reference_counter);
57 if (in->reference_counter<=0) {
58 Esys_MPIInfo_free( in->mpi_info );
59 delete[] in->first_component;
60 delete in;
61 }
62 }
63 }
64
65 Paso_Distribution* Paso_Distribution_getReference( Paso_Distribution *in )
66 {
67 if ( in != NULL)
68 in->reference_counter++;
69 return in;
70 }
71
72 index_t Paso_Distribution_getFirstComponent(Paso_Distribution *in ) {
73 if (in !=NULL) {
74 return in->first_component[in->mpi_info->rank];
75 } else {
76 return 0;
77 }
78 }
79 index_t Paso_Distribution_getLastComponent(Paso_Distribution *in ){
80 if (in !=NULL) {
81 return in->first_component[(in->mpi_info->rank)+1];
82 } else {
83 return 0;
84 }
85 }
86
87 dim_t Paso_Distribution_getGlobalNumComponents(Paso_Distribution *in ){
88 return Paso_Distribution_getMaxGlobalComponents(in)-Paso_Distribution_getMinGlobalComponents(in);
89 }
90 dim_t Paso_Distribution_getMyNumComponents(Paso_Distribution *in ) {
91 return Paso_Distribution_getLastComponent(in)-Paso_Distribution_getFirstComponent(in);
92 }
93
94 dim_t Paso_Distribution_getMinGlobalComponents(Paso_Distribution *in ){
95 if (in !=NULL) {
96 return in->first_component[0];
97 } else {
98 return 0;
99 }
100 }
101 dim_t Paso_Distribution_getMaxGlobalComponents(Paso_Distribution *in ){
102 if (in !=NULL) {
103 return in->first_component[in->mpi_info->size];
104 } else {
105 return 0;
106 }
107 }
108
109 /* Pseudo random numbers such that the values are independent from
110 the distribution */
111
112 static double Paso_Distribution_random_seed=.4142135623730951;
113
114 double* Paso_Distribution_createRandomVector(Paso_Distribution *in, const dim_t block )
115 {
116
117 index_t i;
118 double *out=NULL;
119 const index_t n_0 = in->first_component[in->mpi_info->rank] * block;
120 const index_t n_1 = in->first_component[in->mpi_info->rank+1] * block;
121 const index_t n = ( Paso_Distribution_getMaxGlobalComponents(in)-Paso_Distribution_getMinGlobalComponents(in) ) * block;
122 const dim_t my_n = n_1-n_0;
123
124 out=new double[my_n];
125
126 #pragma omp parallel for private(i) schedule(static)
127 for (i=0; i<my_n ;++i) {
128 out[i]=fmod( Paso_Distribution_random_seed*(n_0+i+1) ,1.);
129 }
130
131 Paso_Distribution_random_seed=fmod( Paso_Distribution_random_seed * (n+1.7), 1.);
132
133 return out;
134 }
135
136 dim_t Paso_Distribution_numPositives(const double* x, const Paso_Distribution *in, const dim_t block )
137 {
138
139 dim_t my_out, out;
140 const index_t n_0 = in->first_component[in->mpi_info->rank] * block;
141 const index_t n_1 = in->first_component[in->mpi_info->rank+1] * block;
142 const dim_t my_n = n_1-n_0;
143
144
145 my_out = Paso_Util_numPositives(my_n, x);
146
147 #ifdef ESYS_MPI
148 #pragma omp single
149 {
150 MPI_Allreduce(&my_out,&out, 1, MPI_INT, MPI_SUM, in->mpi_info->comm);
151 }
152 #else
153 out=my_out;
154 #endif
155
156 return out;
157 }
158

  ViewVC Help
Powered by ViewVC 1.1.26