/[escript]/branches/trilinos_from_5897/escriptcore/src/DataTypes.cpp
ViewVC logotype

Contents of /branches/trilinos_from_5897/escriptcore/src/DataTypes.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5963 - (show annotations)
Mon Feb 22 06:59:27 2016 UTC (3 years, 3 months ago) by caltinay
File size: 6634 byte(s)
sync and fix.

1
2 /*****************************************************************************
3 *
4 * Copyright (c) 2003-2016 by The 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 2012-2013 by School of Earth Sciences
13 * Development from 2014 by Centre for Geoscience Computing (GeoComp)
14 *
15 *****************************************************************************/
16
17 #define ESNEEDPYTHON
18 #include "esysUtils/first.h"
19
20
21 #include "DataTypes.h"
22 #include <sstream>
23 #include <boost/python/extract.hpp>
24 #include <boost/python/tuple.hpp>
25 #include "DataException.h"
26
27 namespace bp = boost::python;
28
29 namespace {
30
31 using namespace escript;
32 using namespace escript::DataTypes;
33
34 /*
35 \brief
36 Calculate the slice range from the given python key object
37 Used by getSliceRegion - since it is not used anywhere else, I have elected not to declare it
38 in the header.
39 Returns the python slice object key as a pair of ints where the first
40 member is the start and the second member is the end. the presence of a possible
41 step attribute with value different from one will throw an exception
42
43 /param key - Input - key object specifying slice range.
44 */
45 std::pair<int,int>
46 getSliceRange(const bp::object& key, int shape)
47 {
48 /* default slice range is range of entire shape dimension */
49 int s0=0, s1=shape;;
50 bp::extract<int> slice_int(key);
51 if (slice_int.check()) {
52 /* if the key is a single int set start=key and end=key */
53 /* in this case, we want to return a rank-1 dimension object from
54 this object, taken from a single index value for one of this
55 object's dimensions */
56 s0=slice_int();
57 s1=s0;
58 } else {
59 /* if key is a pair extract begin and end values */
60 bp::extract<int> step(key.attr("step"));
61 if (step.check() && step()!=1) {
62 throw DataException("Error - Data does not support increments in slicing ");
63 } else {
64 bp::extract<int> start(key.attr("start"));
65 if (start.check()) {
66 s0=start();
67 }
68 bp::extract<int> stop(key.attr("stop"));
69 if (stop.check()) {
70 s1=stop();
71 }
72 }
73 }
74 if (s0 < 0)
75 throw DataException("Error - slice index out of range.");
76 if (s0 == s1 && s1 >= shape)
77 throw DataException("Error - slice index out of range.");
78 if (s0 != s1 && s1>shape)
79 throw DataException("Error - slice index out of range.");
80 if (s0 > s1)
81 throw DataException("Error - lower index must less or equal upper index.");
82 return std::pair<int,int>(s0,s1);
83 }
84 } // anonymous namespace
85
86
87 namespace escript
88 {
89 namespace DataTypes
90 {
91
92 int
93 noValues(const ShapeType& shape)
94 {
95 ShapeType::const_iterator i;
96 //
97 // An empty shape vector means rank 0 which contains 1 value
98 int noValues=1;
99 for (i=shape.begin();i!=shape.end();i++) {
100 noValues*=(*i);
101 }
102 return noValues;
103 }
104
105 int
106 noValues(const RegionLoopRangeType& region)
107 {
108 //
109 // An empty region vector means rank 0 which contains 1 value
110 int noValues=1;
111 unsigned int i;
112 for (i=0;i<region.size();i++) {
113 noValues*=region[i].second-region[i].first;
114 }
115 return noValues;
116 }
117
118 std::string
119 shapeToString(const DataTypes::ShapeType& shape)
120 {
121 std::stringstream temp;
122 temp << "(";
123 unsigned int i;
124 for (i=0;i<shape.size();i++) {
125 temp << shape[i];
126 if (i < shape.size()-1) {
127 temp << ",";
128 }
129 }
130 temp << ")";
131 return temp.str();
132 }
133
134
135
136
137
138 DataTypes::RegionType
139 getSliceRegion(const DataTypes::ShapeType& shape, const bp::object& key)
140 {
141 int slice_rank, i;
142 int this_rank=shape.size();
143 RegionType out(this_rank);
144 /* allow for case where key is singular eg: [1], this implies we
145 want to generate a rank-1 dimension object, as opposed to eg: [1,2]
146 which implies we want to take a rank dimensional object with one
147 dimension of size 1 */
148 bp::extract<bp::tuple> key_tuple(key);
149 if (key_tuple.check()) {
150 slice_rank=bp::extract<int> (key.attr("__len__")());
151 /* ensure slice is correctly dimensioned */
152 if (slice_rank>this_rank) {
153 throw DataException("Error - rank of slices does not match rank of slicee");
154 } else {
155 /* calculate values for slice range */
156 for (i=0;i<slice_rank;i++) {
157 out[i]=getSliceRange(key[i],shape[i]);
158 }
159 }
160 } else {
161 slice_rank=1;
162 if (slice_rank>this_rank) {
163 throw DataException("Error - rank of slices does not match rank of slicee");
164 } else {
165 out[0]=getSliceRange(key,shape[0]);
166 }
167 }
168 for (i=slice_rank;i<this_rank;i++) {
169 out[i]=std::pair<int,int>(0,shape[i]);
170 }
171 return out;
172 }
173
174 DataTypes::ShapeType
175 getResultSliceShape(const RegionType& region)
176 {
177 int dimSize;
178 ShapeType result;
179 RegionType::const_iterator i;
180 for (i=region.begin();i!=region.end();i++) {
181 dimSize=((i->second)-(i->first));
182 if (dimSize!=0) {
183 result.push_back(dimSize);
184 }
185 }
186 return result;
187 }
188
189 DataTypes::RegionLoopRangeType
190 getSliceRegionLoopRange(const DataTypes::RegionType& region)
191 {
192 DataTypes::RegionLoopRangeType region_loop_range(region.size());
193 unsigned int i;
194 for (i=0;i<region.size();i++) {
195 if (region[i].first==region[i].second) {
196 region_loop_range[i].first=region[i].first;
197 region_loop_range[i].second=region[i].second+1;
198 } else {
199 region_loop_range[i].first=region[i].first;
200 region_loop_range[i].second=region[i].second;
201 }
202 }
203 return region_loop_range;
204 }
205
206
207 std::string
208 createShapeErrorMessage(const std::string& messagePrefix,
209 const DataTypes::ShapeType& other,
210 const DataTypes::ShapeType& thisShape)
211 {
212 std::stringstream temp;
213 temp << messagePrefix
214 << " This shape: " << shapeToString(thisShape)
215 << " Other shape: " << shapeToString(other);
216 return temp.str();
217 }
218
219 } // end namespace DataTypes
220 } // end namespace escript
221

  ViewVC Help
Powered by ViewVC 1.1.26