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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4802 - (show annotations)
Wed Mar 26 05:48:28 2014 UTC (5 years, 5 months ago) by jfenwick
File size: 4376 byte(s)
Some work towards exporting.
1
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 #include "boost/python/import.hpp"
18 #include "SubWorld.h"
19 #include "SplitWorldException.h"
20
21 #include <iostream>
22
23 using namespace escript;
24 namespace bp=boost::python;
25 using namespace esysUtils;
26
27 SubWorld::SubWorld(JMPI& comm)
28 :mpiinfo(comm), domain((AbstractDomain*)0)
29 {
30
31
32 }
33
34 SubWorld::~SubWorld()
35 {
36 }
37
38 JMPI& SubWorld::getMPI()
39 {
40 return mpiinfo;
41 }
42
43 void SubWorld::setDomain(Domain_ptr d)
44 {
45 domain=d;
46 }
47
48 Domain_ptr SubWorld::getDomain()
49 {
50 return domain;
51 }
52
53 void SubWorld::addJob(boost::python::object j)
54 {
55 jobvec.push_back(j);
56 }
57
58 void SubWorld::clearJobs()
59 {
60 jobvec.clear();
61 }
62
63 // Deal with the i-th job's exports
64 bool SubWorld::processExports(size_t i, std::string& errmsg)
65 {
66 bp::dict expmap=bp::extract<bp::dict>(jobvec[i].attr("exportedvalues"))();
67 bp::list items=expmap.items();
68 size_t l=bp::len(items);
69 for (int j=0;j<l;++j)
70 {
71 bp::object o1=items[j][0];
72 bp::object o2=items[j][1];
73 bp::extract<std::string> ex1(o1);
74 if (!ex1.check())
75 {
76 errmsg="Job attempted export using a name which was not a string.";
77 return false;
78 }
79 std::string name=ex1();
80 std::map<std::string, Reducer_ptr>::iterator it=reducemap.find(name);
81 if (it==reducemap.end())
82 {
83 errmsg="Attempt to export variable \""+name+"\". SplitWorld was not told about this variable.";
84 return false;
85 }
86 // so now we know it is a known name, we check that it is not None and that it is compatible
87 if (o2.is_none())
88 {
89 errmsg="Attempt to export variable \""+name+"\" with value of None, this is not permitted.";
90 return false;
91 }
92 if (!(it->second)->valueCompatible(o2))
93 {
94 errmsg="Attempt to export variable \""+name+"\" with an incompatible value.";
95 return false;
96 }
97 if (!(it->second)->reduceLocalValue(o2, errmsg))
98 {
99 return false; // the error string will be set by the reduceLocalValue
100 }
101 }
102 return true;
103 }
104
105 // clears out all the old import and export values from _Jobs_
106 // does not clear values out of reducers
107 void SubWorld::clearImportExports()
108 {
109 for (size_t i=0;i<jobvec.size();++i)
110 {
111 jobvec[i].attr("clearImports")();
112 jobvec[i].attr("clearExports")();
113 }
114 }
115
116 // if 4, a Job performed an invalid export
117 // if 3, a Job threw an exception
118 // if 2, a Job did not return a bool
119 // if 1, at least one Job returned False
120 // if 0, all jobs in this world returned True
121 char SubWorld::runJobs(std::string& errormsg)
122 {
123 errormsg.clear();
124 bp::object gettrace=bp::import("traceback").attr("format_exc");
125 int ret=0;
126 try
127 {
128 for (size_t i=0;i<jobvec.size();++i)
129 {
130 boost::python::object result=jobvec[i].attr("work")();
131 boost::python::extract<bool> ex(result);
132 if (!ex.check() || (result.is_none()))
133 {
134 return 2;
135 }
136 // now we check the exports from that Job,
137 // Do names and type match?
138 if (!processExports(i, errormsg))
139 {
140 return 4;
141 }
142 // check to see if we need to keep running
143 if (!ex())
144 {
145 ret=1;
146 }
147
148 }
149 }
150 catch (boost::python::error_already_set e)
151 {
152 using namespace boost::python;
153 PyObject* ptype=0;
154 PyObject* pvalue=0;
155 PyObject* ptraceback=0;
156 PyErr_Fetch(&ptype, &pvalue, &ptraceback);
157 PyErr_NormalizeException(&ptype, &pvalue, &ptraceback);
158
159 PyObject* errobj=PyObject_Str(pvalue);
160
161 errormsg=PyString_AsString(errobj);
162 Py_XDECREF(errobj);
163
164 Py_XDECREF(ptype);
165 Py_XDECREF(pvalue);
166 Py_XDECREF(ptraceback);
167
168 return 3;
169 }
170 return ret;
171 }
172
173 void SubWorld::addVariable(std::string& name, Reducer_ptr& rp)
174 {
175 if (reducemap.find(name)!=reducemap.end())
176 {
177 std::ostringstream oss;
178 oss << "There is already a variable called " << name;
179 throw SplitWorldException(oss.str());
180 }
181 reducemap[name]=rp;
182 }
183
184 void SubWorld::removeVariable(std::string& s)
185 {
186 reducemap.erase(s);
187 }
188

  ViewVC Help
Powered by ViewVC 1.1.26