/[escript]/branches/arrayview_from_1695_trunk/escript/src/DataTypes.cpp
ViewVC logotype

Contents of /branches/arrayview_from_1695_trunk/escript/src/DataTypes.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1724 - (show annotations)
Mon Aug 25 05:38:57 2008 UTC (10 years, 11 months ago) by jfenwick
File size: 6328 byte(s)
Branch commit

Moved createShapeErrorMessage() into DataTypes.h
Modified functions in DataAlgorithm.h to use non-DataArrayView accesses.

Added getVector() to each of DataTagged, DataConstant, DataExpanded - This method returns 
the underlying DataVector by reference/constant reference. Note that this method does not 
exist in DataAbstract so (at the momement) in order to pull the data from something you 
need to know what you are looking at. (Lower level access is still possible via double* 
though).

DataTagged now has a getOffsetForTag method and a getDefaultOffset method.

DataMaths.h - A new file containing the reductionOps etc from DataArrayView (but without 
requiring DAV).
This file requires significant commenting improvements.


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

  ViewVC Help
Powered by ViewVC 1.1.26