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

Diff of /branches/split/escriptcore/src/SplitWorld.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 4730 by jfenwick, Mon Mar 10 00:24:45 2014 UTC revision 4731 by jfenwick, Mon Mar 10 04:16:07 2014 UTC
# Line 17  Line 17 
17  #include "WorldSplitter.h"  #include "WorldSplitter.h"
18  #include "AbstractDomain.h"  #include "AbstractDomain.h"
19  #include "DomainException.h"  #include "DomainException.h"
20    #include "SplitWorldException.h"
21    
22    #include <iostream>
23    
24  using namespace boost::python;  using namespace boost::python;
25  using namespace escript;  using namespace escript;
# Line 26  WorldSplitter::WorldSplitter(unsigned in Line 29  WorldSplitter::WorldSplitter(unsigned in
29  {  {
30      int gsize;      int gsize;
31      int grank;      int grank;
32      if ((MPI_Comm_size(global, &gsize)!=MPI_SUCCESS) || (MPI_Comm_size(global, &grank)!=MPI_SUCCESS))      if ((MPI_Comm_size(global, &gsize)!=MPI_SUCCESS) || (MPI_Comm_rank(global, &grank)!=MPI_SUCCESS))
33      {      {
34      throw DomainException("MPI appears to be inoperative.");      throw DomainException("MPI appears to be inoperative.");
35      }      }
# Line 34  WorldSplitter::WorldSplitter(unsigned in Line 37  WorldSplitter::WorldSplitter(unsigned in
37      {      {
38      throw DomainException("WorldSplitter error: requested number of groups is not a factor of global communicator size.");      throw DomainException("WorldSplitter error: requested number of groups is not a factor of global communicator size.");
39      }      }
40      int res=MPI_Comm_split(MPI_COMM_WORLD, grank/gsize, grank%gsize, &subcom);      int wsize=gsize/numgroups;  // each world has this many processes
41        int res=MPI_Comm_split(MPI_COMM_WORLD, grank/wsize, grank%wsize, &subcom);
42      if (res!=MPI_SUCCESS)      if (res!=MPI_SUCCESS)
43      {      {
44      throw DomainException("WorldSplitter error: Unable to form communicator.");      throw DomainException("WorldSplitter error: Unable to form communicator.");
45      }      }
 std::cerr << subcom << std::endl;      
46      localworld=SubWorld_ptr(new SubWorld(subcom));      localworld=SubWorld_ptr(new SubWorld(subcom));
47        localid=grank/wsize;
48  }  }
49    
50  // We may need to look into this more closely.  // We may need to look into this more closely.
# Line 88  object WorldSplitter::buildDomains(tuple Line 92  object WorldSplitter::buildDomains(tuple
92      return object();    // return None      return object();    // return None
93  }  }
94    
95    /** a list of tuples/sequences:  (Job class, number of instances)*/
96    void WorldSplitter::runJobs(boost::python::list l)
97    {
98        // first count up how many jobs we have in total
99        unsigned int numjobs=0;
100        std::vector<object> classvec;
101        std::vector<unsigned int> countvec;
102        std::vector<unsigned int> partialcounts;
103        for (int i=0;i<len(l);++i)
104        {
105        extract<tuple> ex(l[i]);
106        if (!ex.check())
107        {
108            throw SplitWorldException("runJobs takes a list of tuples (jobclass, number).");
109        }
110        tuple t=ex();
111        if (len(t)!=2)
112        {
113            throw SplitWorldException("runJobs takes a list of tuples (jobclass, number).");
114        }
115        extract<unsigned int> ex2(t[1]);
116        unsigned int c=0;
117        if (!ex2.check() || ((c=ex2())==0))
118        {
119            throw SplitWorldException("Number of jobs must be a strictly positive integer.");
120          
121        }
122        classvec.push_back(t[0]);
123        countvec.push_back(c);
124        numjobs+=c;
125        partialcounts.push_back(numjobs);
126        }
127        unsigned int classnum=0;
128        unsigned int lowend=1;
129        unsigned int highend=lowend+numjobs/groupcount+(numjobs%groupcount);
130    std::cout << localid << std::endl;
131        for (int i=1;i<=localid;++i)
132        {
133        lowend=highend;
134        highend=lowend+numjobs/groupcount;
135        if (i<numjobs%groupcount)
136        {
137            highend++;
138        }
139        }
140    std::cout << "There are " << numjobs << " jobs with range [" << lowend << ", " << highend << ")\n";    
141        // We could do something more clever about trying to fit Jobs to subworlds
142        // to ensure that instances sharing the same Job class would share the same
143        // world as much as possible but for now we'll do this:
144        for (unsigned int j=1;j<=numjobs;++j)       // job #0 is a sentinel
145        {
146        if (j>partialcounts[classnum])
147        {
148            classnum++; // we dont' need to loop this because each count >0
149        }
150        // now if this is one of the job numbers in our local range,
151        // create an instance of the appropriate class
152        if (j>=lowend and j<highend)
153        {
154    std::cout << "Added job\n";  
155            object o=classvec[classnum](localworld->getDomain(), object(j));
156            localworld->addJob(o);
157        }
158        }
159        
160        // now we actually need to run the jobs
161        // everybody will be executing their localworld's jobs
162        localworld->runJobs();
163    }
164    
165  namespace escript  namespace escript
166  {  {
167    

Legend:
Removed from v.4730  
changed lines
  Added in v.4731

  ViewVC Help
Powered by ViewVC 1.1.26