source: anuga_core/source/anuga_parallel/parallel_api.py @ 3904

Last change on this file since 3904 was 3904, checked in by nick, 17 years ago

change to pass geo_reference

File size: 5.7 KB
Line 
1"""Trying to lump parallel stuff into simpler interface
2
3
4"""
5
6# Parallelism
7
8# The abstract Python-MPI interface
9from anuga_parallel.parallel_abstraction import size, rank, get_processor_name
10from anuga_parallel.parallel_abstraction import finalize, send, receive
11from anuga_parallel.parallel_abstraction import pypar_available, barrier
12
13
14# ANUGA parallel engine (only load if pypar can)
15if pypar_available:
16    from anuga_parallel.build_commun  import send_submesh
17    from anuga_parallel.build_commun  import rec_submesh
18    from anuga_parallel.build_commun  import extract_hostmesh
19    from anuga_parallel.parallel_shallow_water import Parallel_Domain
20
21    # Mesh partitioning using Metis
22    from anuga_parallel.build_submesh import build_submesh
23    from anuga_parallel.build_local   import build_local_mesh
24    from anuga_parallel.pmesh_divide  import pmesh_divide_metis
25
26
27#------------------------------------------------------------------------------
28# Read in processor information
29#------------------------------------------------------------------------------
30
31numprocs = size()
32myid = rank()
33processor_name = get_processor_name()
34print 'I am processor %d of %d on node %s' %(myid, numprocs, processor_name)
35
36
37
38
39def distribute(domain, verbose=False):
40    """ Distribute the domain to all processes
41    """
42
43
44    # FIXME: Dummy assignment (until boundaries are refactored to
45    # be independent of domains until they are applied)
46    bdmap = {}
47    for tag in domain.get_boundary_tags():
48        bdmap[tag] = None
49   
50   
51    domain.set_boundary(bdmap)
52
53
54
55
56    if not pypar_available: return domain # Bypass
57
58    # For some obscure reason this communication must happen prior to
59    # the more complex mesh distribution - Oh Well!
60    if myid == 0:
61        domain_name = domain.get_name()
62        domain_dir = domain.get_datadir()
63        georef = domain.geo_reference
64       
65        # FIXME - what other attributes need to be transferred?
66
67        for p in range(1, numprocs):
68            send((domain_name, domain_dir, georef), p)
69    else:
70        if verbose: print 'P%d: Receiving domain attributes' %(myid)
71
72        domain_name, domain_dir, georef = receive(0)
73
74
75
76    # Distribute boundary conditions
77    # FIXME: This cannot handle e.g. Time_boundaries due to
78    # difficulties pickling functions
79    if myid == 0:
80        boundary_map = domain.boundary_map
81        for p in range(1, numprocs):
82            send(boundary_map, p)
83    else:
84        if verbose: print 'P%d: Receiving boundary map' %(myid)       
85
86        boundary_map = receive(0)
87       
88
89
90
91    if myid == 0:
92        # Partition and distribute mesh.
93        # Structures returned is in the
94        # correct form for the ANUGA data structure
95
96
97        points, vertices, boundary, quantities,\
98                ghost_recv_dict, full_send_dict,\
99                = distribute_mesh(domain)
100
101        if verbose: print 'Communication done'
102       
103    else:
104        # Read in the mesh partition that belongs to this
105        # processor
106        if verbose: print 'P%d: Receiving submeshes' %(myid)               
107        points, vertices, boundary, quantities,\
108                ghost_recv_dict, full_send_dict,\
109                = rec_submesh(0)
110
111
112    #------------------------------------------------------------------------
113    # Build the domain for this processor using partion structures
114    #------------------------------------------------------------------------
115    domain = Parallel_Domain(points, vertices, boundary,
116                             full_send_dict  = full_send_dict,
117                             ghost_recv_dict = ghost_recv_dict)
118
119    #------------------------------------------------------------------------
120    # Transfer initial conditions to each subdomain
121    #------------------------------------------------------------------------
122    for q in quantities:
123        domain.set_quantity(q, quantities[q]) 
124
125
126    #------------------------------------------------------------------------
127    # Transfer boundary conditions to each subdomain
128    #------------------------------------------------------------------------
129    boundary_map['ghost'] = None  # Add binding to ghost boundary
130    domain.set_boundary(boundary_map)
131
132
133    #------------------------------------------------------------------------
134    # Transfer other attributes to each subdomain
135    #------------------------------------------------------------------------
136    domain.set_name(domain_name)
137    domain.set_datadir(domain_dir)     
138    domain.geo_reference = georef   
139
140    #------------------------------------------------------------------------
141    # Return parallel domain to all nodes
142    #------------------------------------------------------------------------
143    return domain   
144
145
146
147
148
149
150
151def distribute_mesh(domain):
152
153    numprocs = size()
154
155   
156    # Subdivide the mesh
157    print 'Subdivide mesh'
158    nodes, triangles, boundary, triangles_per_proc, quantities = \
159           pmesh_divide_metis(domain, numprocs)
160
161
162    # Build the mesh that should be assigned to each processor,
163    # this includes ghost nodes and the communication pattern
164    print 'Build submeshes'   
165    submesh = build_submesh(nodes, triangles, boundary,\
166                            quantities, triangles_per_proc)
167
168    # Send the mesh partition to the appropriate processor
169    print 'Distribute submeshes'       
170    for p in range(1, numprocs):
171      send_submesh(submesh, triangles_per_proc, p)
172
173    # Build the local mesh for processor 0
174    points, vertices, boundary, quantities, ghost_recv_dict, full_send_dict = \
175              extract_hostmesh(submesh, triangles_per_proc)
176
177    # Return structures necessary for building the parallel domain
178    return points, vertices, boundary, quantities, \
179           ghost_recv_dict, full_send_dict
180   
181
182
183
Note: See TracBrowser for help on using the repository browser.