/[escript]/trunk/escript/src/Utils.cpp
ViewVC logotype

Annotation of /trunk/escript/src/Utils.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2635 - (hide annotations)
Thu Aug 27 04:54:41 2009 UTC (10 years, 7 months ago) by jfenwick
File size: 7640 byte(s)
A bunch of changes related to saveDataCSV.
[Not completed or unit tested yet]

Added saveDataCSV to util.py
AbstractDomain (and MeshAdapter) have a commonFunctionSpace method to 
take a group of FunctionSpaces and return something they can all be interpolated to.

Added pointToStream() in DataTypes to help print points.

added actsConstant() to data - required because DataConstant doesn't store samples the same way other Data do.
1 gross 391
2 ksteube 1312 /*******************************************************
3 ksteube 1811 *
4 jfenwick 2548 * Copyright (c) 2003-2009 by University of Queensland
5 ksteube 1811 * Earth Systems Science Computational Center (ESSCC)
6     * http://www.uq.edu.au/esscc
7     *
8     * Primary Business: Queensland, Australia
9     * Licensed under the Open Software License version 3.0
10     * http://www.opensource.org/licenses/osl-3.0.php
11     *
12     *******************************************************/
13 ksteube 1312
14 ksteube 1811
15 ksteube 1806 #include <string.h>
16    
17 jfenwick 2635 // added for saveCSV
18     #include <boost/python.hpp>
19     #include "Data.h"
20    
21 jgs 474 #include "Utils.h"
22 gross 797 #include "DataVector.h"
23 gross 391
24 jgs 478 #ifdef _OPENMP
25     #include <omp.h>
26     #endif
27    
28 ksteube 1561 #ifdef PASO_MPI
29     #include <mpi.h>
30     #endif
31    
32 phornby 1628 #ifdef _WIN32
33     #include <WinSock2.h>
34 phornby 1835 #else
35     #include <unistd.h>
36 phornby 1628 #endif
37    
38 gross 391 namespace escript {
39    
40 ksteube 1247 int getSvnVersion()
41     {
42     #ifdef SVN_VERSION
43     return SVN_VERSION;
44     #else
45     return 0;
46     #endif
47     }
48    
49 ksteube 1620 /* This is probably not very robust, but it works on Savanna today and is useful for performance analysis */
50     int get_core_id() {
51     int processor_num=-1;
52     #ifdef CORE_ID1
53     FILE *fp;
54     int i, count_spaces=0;
55     char fname[100];
56     char buf[1000];
57    
58     sprintf(fname, "/proc/%d/stat", getpid());
59     fp = fopen(fname, "r");
60     if (fp == NULL) return(-1);
61     fgets(buf, 1000, fp);
62     fclose(fp);
63    
64     for (i=strlen(buf)-1; i>=0; i--) {
65     if (buf[i] == ' ') count_spaces++;
66     if (count_spaces == 4) break;
67     }
68     processor_num = atoi(&buf[i+1]);
69     #endif
70     return(processor_num);
71     }
72    
73    
74 ksteube 1561 void printParallelThreadCnt()
75     {
76     int mpi_iam=0, mpi_num=1;
77 ksteube 1568 char hname[64];
78 ksteube 1561
79 ksteube 1705 #ifdef HAVE_GETHOSTNAME
80 ksteube 1568 gethostname(hname, 64);
81 ksteube 1806 hname[63] = '\0';
82 ksteube 1705 #else
83     strcpy(hname, "unknown host");
84     #endif
85 ksteube 1567
86 ksteube 1561 #ifdef PASO_MPI
87     MPI_Comm_rank(MPI_COMM_WORLD, &mpi_iam);
88     MPI_Comm_size(MPI_COMM_WORLD, &mpi_num);
89     #endif
90    
91     #pragma omp parallel
92     {
93     int omp_iam=0, omp_num=1;
94     #ifdef _OPENMP
95     omp_iam = omp_get_thread_num(); /* Call in a parallel region */
96     omp_num = omp_get_num_threads();
97     #endif
98 jfenwick 2607 #pragma omp critical (printthrdcount)
99 ksteube 1620 printf("printParallelThreadCounts: MPI=%03d/%03d OpenMP=%03d/%03d running on %s core %d\n",
100     mpi_iam, mpi_num, omp_iam, omp_num, hname, get_core_id());
101 ksteube 1561 }
102     }
103    
104 gross 391 void setNumberOfThreads(const int num_threads)
105     {
106    
107     #ifdef _OPENMP
108     omp_set_num_threads(num_threads);
109     #endif
110    
111     }
112    
113     int getNumberOfThreads()
114     {
115     #ifdef _OPENMP
116     return omp_get_max_threads();
117     #else
118     return 1;
119     #endif
120    
121     }
122    
123 gross 2313 ESCRIPT_DLL_API int getMPISizeWorld() {
124 ksteube 1805 int mpi_num = 1;
125     #ifdef PASO_MPI
126     MPI_Comm_size(MPI_COMM_WORLD, &mpi_num);
127     #endif
128     return mpi_num;
129     }
130    
131 gross 2313 ESCRIPT_DLL_API int getMPIRankWorld() {
132 ksteube 1805 int mpi_iam = 0;
133     #ifdef PASO_MPI
134     MPI_Comm_rank(MPI_COMM_WORLD, &mpi_iam);
135     #endif
136     return mpi_iam;
137     }
138    
139 gross 2308 ESCRIPT_DLL_API int getMPIWorldMax(const int val) {
140     #ifdef PASO_MPI
141     int val2 = val;
142     int out = val;
143     MPI_Allreduce( &val2, &out, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD );
144     #else
145     int out = val;
146     #endif
147     return out;
148     }
149    
150 jfenwick 2607 ESCRIPT_DLL_API int getMPIWorldSum(const int val) {
151     #ifdef PASO_MPI
152     int val2 = val;
153     int out = 0;
154     MPI_Allreduce( &val2, &out, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD );
155     #else
156     int out = val;
157     #endif
158     return out;
159     }
160 gross 2308
161 gross 2313 ESCRIPT_DLL_API double getMachinePrecision() {
162 gross 2100 return DBL_EPSILON;
163     }
164 gross 2313 ESCRIPT_DLL_API double getMaxFloat() {
165 gross 2100 return DBL_MAX;
166     }
167 gross 2313 ESCRIPT_DLL_API void MPIBarrierWorld() {
168     #ifdef PASO_MPI
169     MPI_Barrier(MPI_COMM_WORLD );
170     #endif
171     }
172 gross 2100
173 jfenwick 2635 ESCRIPT_DLL_API
174     void
175     saveDataCSV(const std::string& filename, boost::python::dict arg, const std::string& sep, const std::string& csep,
176     bool append)
177     {
178     using std::cout;
179     using std::endl;
180     boost::python::list keys=arg.keys();
181     int numdata = boost::python::extract<int>(arg.attr("__len__")());
182     if (numdata<1)
183     {
184     throw DataException("saveDataCSVcpp: no data to save specified.");
185     }
186     std::vector<int> step(numdata);
187     std::vector<std::string> names(numdata);
188     std::vector<Data> data(numdata);
189     std::vector<const DataAbstract::ValueType::value_type*> samples(numdata);
190     std::vector<int> offset(numdata);
191     std::vector<int> fstypes(numdata); // FunctionSpace types for each data
192 gross 2100
193 jfenwick 2635 // We need to interpret the samples correctly even if they are different types
194     // for this reason, we should interate over samples
195     for (int i=0;i<numdata;++i)
196     {
197     names[i]=boost::python::extract<std::string>(keys[i]);
198     data[i]=boost::python::extract<escript::Data>(arg[keys[i]]);
199     step[i]=(data[i].actsConstant()?0:DataTypes::noValues(data[i].getDataPointShape()));
200     fstypes[i]=data[i].getFunctionSpace().getTypeCode();
201     if (i>0)
202     {
203     if (data[i].getDomain()!=data[i-1].getDomain())
204     {
205     throw DataException("saveDataCSVcpp: all data must be on the same domain.");
206     }
207     }
208     }
209     int bestfnspace=0;
210     if (!data[0].getDomain()->commonFunctionSpace(fstypes, bestfnspace))
211     {
212     throw DataException("saveDataCSVcpp: FunctionSpaces of data are incompatible");
213     }
214     // now we interpolate all data to the same type
215     FunctionSpace best(data[0].getDomain(),bestfnspace);
216     for (int i=0;i<numdata;++i)
217     {
218     data[i]=data[i].interpolate(best);
219     }
220     int numsamples=data[0].getNumSamples(); // these must be the same for all data
221     int dpps=data[0].getNumDataPointsPerSample();
222    
223    
224     std::ofstream os;
225     if (append)
226     {
227     os.open(filename.c_str(), std::ios_base::app);
228     }
229     else
230     {
231     os.open(filename.c_str());
232     }
233     if (!os.is_open())
234     {
235     throw DataException("saveDataCSVcpp: unable to open file for writing");
236     }
237    
238     bool first=true;
239     for (int i=0;i<numdata;++i)
240     {
241     const DataTypes::ShapeType& s=data[i].getDataPointShape();
242     switch (data[i].getDataPointRank())
243     {
244     case 0: if (!first)
245     {
246     os << sep;
247     }
248     else
249     {
250     first=false;
251     }
252     os << names[i]; break;
253     case 1: for (int j=0;j<s[0];++j)
254     {
255     if (!first)
256     {
257     os << sep;
258     }
259     else
260     {
261     first=false;
262     }
263     os << names[i] << csep << j;
264     }
265     break;
266     case 2: for (int j=0;j<s[0];++j)
267     {
268     for (int k=0;k<s[1];++k)
269     {
270     if (!first)
271     {
272     os << sep;
273     }
274     else
275     {
276     first=false;
277     }
278     os << names[i] << csep << k << csep << j;
279     }
280     }
281     break;
282     case 3: for (int j=0;j<s[0];++j)
283     {
284     for (int k=0;k<s[1];++k)
285     {
286     for (int l=0;l<s[2];++l)
287     {
288     if (!first)
289     {
290     os << sep;
291     }
292     else
293     {
294     first=false;
295     }
296     os << names[i] << csep << k << csep << j << csep << l;
297     }
298     }
299     }
300     break;
301     case 4: for (int j=0;j<s[0];++j)
302     {
303     for (int k=0;k<s[1];++k)
304     {
305     for (int l=0;l<s[2];++l)
306     {
307     for (int m=0;m<s[3];++m)
308     {
309     if (!first)
310     {
311     os << sep;
312     }
313     else
314     {
315     first=false;
316     }
317     os << names[i] << csep << k << csep << j << csep << l << csep << m;
318     }
319     }
320     }
321     }
322     break;
323     default:
324     throw DataException("saveDataCSV: Illegal rank");
325     }
326     }
327     os << endl;
328    
329     //the use of shared_ptr here is just to ensure the buffer group is freed
330     //I would have used scoped_ptr but they don't work in vectors
331     std::vector<boost::shared_ptr<BufferGroup> > bg(numdata);
332     for (int d=0;d<numdata;++d)
333     {
334     bg[d].reset(data[d].allocSampleBuffer());
335     }
336    
337     try{
338     for (int i=0;i<numsamples;++i)
339     {
340     for (int d=0;d<numdata;++d)
341     {
342     samples[d]=data[d].getSampleDataRO(i,bg[d].get());
343     }
344     for (int j=0;j<dpps;++j)
345     {
346     bool needsep=false;
347     for (int d=0;d<numdata;++d)
348     {
349     DataTypes::pointToStream(os, samples[d], data[d].getDataPointShape(), offset[d], needsep, sep);
350     needsep=true;
351     offset[d]+=step[d];
352     }
353     os << endl;
354     }
355     for (int d=0;d<numdata;++d)
356     {
357     offset[d]=0;
358     }
359     }
360     } catch (...)
361     {
362     os.close();
363     throw;
364     }
365     os.close();
366     }
367    
368 gross 391 } // end of namespace

  ViewVC Help
Powered by ViewVC 1.1.26