/[escript]/branches/split/escriptcore/src/SubWorld.cpp
ViewVC logotype

Annotation of /branches/split/escriptcore/src/SubWorld.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4808 - (hide annotations)
Thu Mar 27 05:34:14 2014 UTC (5 years, 4 months ago) by jfenwick
File size: 7098 byte(s)
More work towards export
1 jfenwick 4730
2     /*****************************************************************************
3     *
4     * Copyright (c) 2014 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 2012-2013 by School of Earth Sciences
13     * Development from 2014 by Centre for Geoscience Computing (GeoComp)
14     *
15     *****************************************************************************/
16    
17 jfenwick 4745 #include "boost/python/import.hpp"
18 jfenwick 4730 #include "SubWorld.h"
19 jfenwick 4802 #include "SplitWorldException.h"
20 jfenwick 4730
21 jfenwick 4745 #include <iostream>
22    
23 jfenwick 4730 using namespace escript;
24 jfenwick 4745 namespace bp=boost::python;
25 jfenwick 4747 using namespace esysUtils;
26 jfenwick 4730
27 jfenwick 4747 SubWorld::SubWorld(JMPI& comm)
28     :mpiinfo(comm), domain((AbstractDomain*)0)
29 jfenwick 4730 {
30    
31    
32     }
33    
34     SubWorld::~SubWorld()
35     {
36     }
37    
38 jfenwick 4747 JMPI& SubWorld::getMPI()
39 jfenwick 4730 {
40 jfenwick 4747 return mpiinfo;
41 jfenwick 4730 }
42    
43     void SubWorld::setDomain(Domain_ptr d)
44     {
45     domain=d;
46     }
47    
48 jfenwick 4731 Domain_ptr SubWorld::getDomain()
49     {
50     return domain;
51     }
52 jfenwick 4730
53 jfenwick 4731 void SubWorld::addJob(boost::python::object j)
54     {
55     jobvec.push_back(j);
56     }
57    
58 jfenwick 4745 void SubWorld::clearJobs()
59     {
60     jobvec.clear();
61     }
62    
63 jfenwick 4808 // takes an vector of bools of size 2*number of variables
64     // Each entry in the first group is true if this subworld has at least one job which exports that variable.
65     // Each entry in the second group is true if there is at least one Job in this world which wishes
66     // to import that variable.
67     // The order of the variables is determined by the order of keys in the reducemap
68     // Q: Why does it take chars then?
69     // A: Because I want raw storage that I can pass via MPI and bool is special cased.
70     bool SubWorld::localTransport(std::vector<char>& vb, std::string& errmsg)
71     {
72     for (size_t i=0;i<jobvec.size();++i)
73     {
74     bp::dict expmap=bp::extract<bp::dict>(jobvec[i].attr("exportedvalues"))();
75     bp::list items=expmap.items();
76     size_t l=bp::len(items);
77     for (int j=0;j<l;++j)
78     {
79     bp::object o1=items[j][0];
80     bp::object o2=items[j][1];
81     bp::extract<std::string> ex1(o1);
82     if (!ex1.check())
83     {
84     errmsg="Job attempted export using a name which was not a string.";
85     return false;
86     }
87     std::string name=ex1();
88     std::map<std::string, Reducer_ptr>::iterator it=reducemap.find(name);
89     if (it==reducemap.end())
90     {
91     errmsg="Attempt to export variable \""+name+"\". SplitWorld was not told about this variable.";
92     return false;
93     }
94     // so now we know it is a known name, we check that it is not None and that it is compatible
95     if (o2.is_none())
96     {
97     errmsg="Attempt to export variable \""+name+"\" with value of None, this is not permitted.";
98     return false;
99     }
100     if (!(it->second)->valueCompatible(o2))
101     {
102     errmsg="Attempt to export variable \""+name+"\" with an incompatible value.";
103     return false;
104     }
105     if (!(it->second)->reduceLocalValue(o2, errmsg))
106     {
107     return false; // the error string will be set by the reduceLocalValue
108     }
109     }
110     }
111    
112     // If we get here, all of the (local) exports worked
113     // Now, lets make a record for distrubtion
114     size_t l=reducemap.size();
115     vb.resize(l*2);
116     size_t i=0;
117     for (str2reduce::iterator it=reducemap.begin();it!=reducemap.end();++it, ++i)
118     {
119     if (it->second->hasValue())
120     {
121     vb[i]=1;
122     }
123     else
124     {
125     vb[i]=0;
126     }
127     if (importmap[it->first])
128     {
129     vb[i+l]=1;
130     }
131     else
132     {
133     vb[i+l]=0;
134     }
135     }
136     return true;
137     }
138     /*
139 jfenwick 4802 // Deal with the i-th job's exports
140 jfenwick 4808 bool SubWorld::processExportsLocal(size_t i, std::string& errmsg)
141 jfenwick 4802 {
142     bp::dict expmap=bp::extract<bp::dict>(jobvec[i].attr("exportedvalues"))();
143     bp::list items=expmap.items();
144     size_t l=bp::len(items);
145     for (int j=0;j<l;++j)
146     {
147     bp::object o1=items[j][0];
148     bp::object o2=items[j][1];
149     bp::extract<std::string> ex1(o1);
150     if (!ex1.check())
151     {
152     errmsg="Job attempted export using a name which was not a string.";
153     return false;
154     }
155     std::string name=ex1();
156     std::map<std::string, Reducer_ptr>::iterator it=reducemap.find(name);
157     if (it==reducemap.end())
158     {
159     errmsg="Attempt to export variable \""+name+"\". SplitWorld was not told about this variable.";
160     return false;
161     }
162     // so now we know it is a known name, we check that it is not None and that it is compatible
163     if (o2.is_none())
164     {
165     errmsg="Attempt to export variable \""+name+"\" with value of None, this is not permitted.";
166     return false;
167     }
168     if (!(it->second)->valueCompatible(o2))
169     {
170     errmsg="Attempt to export variable \""+name+"\" with an incompatible value.";
171     return false;
172     }
173     if (!(it->second)->reduceLocalValue(o2, errmsg))
174     {
175     return false; // the error string will be set by the reduceLocalValue
176     }
177     }
178     return true;
179 jfenwick 4808 }*/
180     /*
181 jfenwick 4745
182 jfenwick 4808 void SubWorld::populateVarMoveInfo(vector<char>& vb)
183     {
184     size_t l=reducemap.size();
185     vb.resize(l*2);
186     for (str2reduce::iterator it=reducemap.begin(), int i=0;it!=reducemap.end();++it, ++i)
187     {
188     if (it->second->hasValue())
189     {
190     vb[i]=1;
191     }
192     else
193     {
194     vb[i]=0;
195     }
196     if (importmap[it->first])
197     {
198     vb[i+l]=1;
199     }
200     else
201     {
202     vb[i+l]=0;
203     }
204     }
205     }*/
206    
207 jfenwick 4802 // clears out all the old import and export values from _Jobs_
208     // does not clear values out of reducers
209     void SubWorld::clearImportExports()
210     {
211     for (size_t i=0;i<jobvec.size();++i)
212     {
213     jobvec[i].attr("clearImports")();
214     jobvec[i].attr("clearExports")();
215     }
216     }
217    
218     // if 4, a Job performed an invalid export
219 jfenwick 4734 // if 3, a Job threw an exception
220     // if 2, a Job did not return a bool
221     // if 1, at least one Job returned False
222     // if 0, all jobs in this world returned True
223 jfenwick 4746 char SubWorld::runJobs(std::string& errormsg)
224 jfenwick 4731 {
225 jfenwick 4746 errormsg.clear();
226 jfenwick 4745 bp::object gettrace=bp::import("traceback").attr("format_exc");
227 jfenwick 4734 int ret=0;
228     try
229 jfenwick 4731 {
230 jfenwick 4734 for (size_t i=0;i<jobvec.size();++i)
231     {
232     boost::python::object result=jobvec[i].attr("work")();
233     boost::python::extract<bool> ex(result);
234 jfenwick 4745 if (!ex.check() || (result.is_none()))
235 jfenwick 4734 {
236     return 2;
237     }
238 jfenwick 4802 // check to see if we need to keep running
239 jfenwick 4734 if (!ex())
240     {
241     ret=1;
242     }
243 jfenwick 4802
244 jfenwick 4734 }
245 jfenwick 4745 }
246     catch (boost::python::error_already_set e)
247 jfenwick 4734 {
248 jfenwick 4745 using namespace boost::python;
249 jfenwick 4746 PyObject* ptype=0;
250     PyObject* pvalue=0;
251     PyObject* ptraceback=0;
252     PyErr_Fetch(&ptype, &pvalue, &ptraceback);
253     PyErr_NormalizeException(&ptype, &pvalue, &ptraceback);
254 jfenwick 4745
255 jfenwick 4746 PyObject* errobj=PyObject_Str(pvalue);
256    
257     errormsg=PyString_AsString(errobj);
258     Py_XDECREF(errobj);
259    
260     Py_XDECREF(ptype);
261     Py_XDECREF(pvalue);
262     Py_XDECREF(ptraceback);
263 jfenwick 4745
264 jfenwick 4734 return 3;
265     }
266     return ret;
267 jfenwick 4747 }
268 jfenwick 4802
269 jfenwick 4808 // if manual import is false, add this new variable to all the Jobs in this world
270     void SubWorld::addVariable(std::string& name, Reducer_ptr& rp, bool manualimport)
271 jfenwick 4802 {
272     if (reducemap.find(name)!=reducemap.end())
273     {
274     std::ostringstream oss;
275     oss << "There is already a variable called " << name;
276     throw SplitWorldException(oss.str());
277     }
278     reducemap[name]=rp;
279 jfenwick 4808 if (!manualimport)
280     {
281     for (size_t i=0;i<jobvec.size();++i)
282     {
283     jobvec[i].attr("requestImport")(name);
284     }
285     }
286 jfenwick 4802 }
287    
288     void SubWorld::removeVariable(std::string& s)
289     {
290     reducemap.erase(s);
291     }
292    

  ViewVC Help
Powered by ViewVC 1.1.26