Octopus
blacs_proc_grid.F90
Go to the documentation of this file.
1!! Copyright (C) 2005-2006 Heiko Appel, Florian Lorenzen
2!!
3!! This program is free software; you can redistribute it and/or modify
4!! it under the terms of the GNU General Public License as published by
5!! the Free Software Foundation; either version 2, or (at your option)
6!! any later version.
7!!
8!! This program is distributed in the hope that it will be useful,
9!! but WITHOUT ANY WARRANTY; without even the implied warranty of
10!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11!! GNU General Public License for more details.
12!!
13!! You should have received a copy of the GNU General Public License
14!! along with this program; if not, write to the Free Software
15!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16!! 02110-1301, USA.
17!!
18
19#include "global.h"
20
23 use debug_oct_m
24 use global_oct_m
25 use blacs_oct_m
26 use mpi_oct_m
29
30 implicit none
31
32 private
33
34 public :: &
40
41 integer :: BLACS_NULL_CONTEXT = -1
42
44 ! Components are public by default
45 integer :: context = -1
46 integer :: nprocs
47 integer :: nprow
48 integer :: npcol
49 integer, private :: iam
50 integer :: myrow
51 integer :: mycol
52 integer, allocatable :: usermap(:, :)
53 end type blacs_proc_grid_t
54
55contains
56
61 subroutine blacs_proc_grid_init(this, mpi_grp, procdim)
62 type(blacs_proc_grid_t), intent(inout) :: this
63 type(mpi_grp_t), intent(in) :: mpi_grp
64 integer, optional, intent(in) :: procdim(:)
65
66#ifdef HAVE_SCALAPACK
67
68 integer, parameter :: maxdims = 2
69 integer :: dims(1:2), topo, coords(1:2), ix, iy, id, xy(2)
70 logical :: periods(1:2)
71 type(MPI_Comm) :: comm
72 logical :: reorder
73 integer, allocatable :: procmap(:)
74
75 push_sub(blacs_proc_grid_init)
76
77 call mpi_topo_test(mpi_grp%comm, topo, mpi_err)
78
79 if (topo /= mpi_cart .or. present(procdim)) then
80 ! We create a new communicator with Cartesian topology
81 if (present(procdim)) then
82 dims(1) = procdim(1)
83 dims(2) = procdim(2)
84 else
85 dims(1) = mpi_grp%size
86 dims(2) = 1
87 end if
88 periods = .false.
89 reorder = .false.
90 call mpi_cart_create(mpi_grp%comm, 2, dims, periods, reorder, comm, mpi_err)
91 else
92 comm = mpi_grp%comm
93 end if
94
95 call blacs_pinfo(this%iam, this%nprocs)
96
97 ! The process ID from ScaLAPACK is not always the
98 ! same as MPI, so we need to construct a map.
99 safe_allocate(procmap(0:mpi_grp%size - 1))
100 call mpi_allgather(this%iam, 1, mpi_integer, procmap(0), 1, mpi_integer, comm, mpi_err)
101
102 assert(this%iam == procmap(mpi_grp%rank))
103
104 dims = 1
105 coords = 0
106
107 call mpi_cart_get(comm, maxdims, dims, periods, coords, mpi_err)
108
109 safe_allocate(this%usermap(1:dims(1), 1:dims(2)))
110
111 do ix = 1, dims(1)
112 xy(1) = ix - 1
113 do iy = 1, dims(2)
114 xy(2) = iy - 1
115 call mpi_cart_rank(comm, xy, id, mpi_err)
116 this%usermap(ix, iy) = procmap(id)
117 end do
118 end do
119
120 ! get the default system context
121 call blacs_get(blacs_null_context, what = 0, val = this%context)
122
123 ! now get the context associated with the map
124 call blacs_gridmap(this%context, this%usermap(1, 1), dims(1), dims(1), dims(2))
125
126 ! and fill the rest of the structure
127 call blacs_gridinfo(this%context, this%nprow, this%npcol, this%myrow, this%mycol)
128
129 !check that Blacs and MPI are consistent
130 assert(this%nprow == dims(1))
131 assert(this%npcol == dims(2))
132 assert(this%myrow == coords(1))
133 assert(this%mycol == coords(2))
135 if (topo /= mpi_cart) then
136 call mpi_comm_free(comm, mpi_err)
137 end if
139 safe_deallocate_a(procmap)
142#else
144 this%context = blacs_null_context
146#endif
147 end subroutine blacs_proc_grid_init
148
149 ! ----------------------------------------------------
150
151 subroutine blacs_proc_grid_end(this)
152 type(blacs_proc_grid_t), intent(inout) :: this
153
155
156 if (this%context /= blacs_null_context) then
157#ifdef HAVE_SCALAPACK
158 call blacs_gridexit(this%context)
159#endif
160 safe_deallocate_a(this%usermap)
161 end if
162
163 this%context = blacs_null_context
164
165 pop_sub(blacs_proc_grid_end)
166 end subroutine blacs_proc_grid_end
167
168 ! ----------------------------------------------------
169
170 subroutine blacs_proc_grid_copy(cin, cout)
171 type(blacs_proc_grid_t), intent(in) :: cin
172 type(blacs_proc_grid_t), intent(inout) :: cout
173
174 push_sub(blacs_proc_grid_copy)
175
176 call blacs_proc_grid_end(cout)
177
178 cout%context = cin%context
179
180#ifdef HAVE_SCALAPACK
181 cout%nprocs = cin%nprocs
182 cout%nprow = cin%nprow
183 cout%npcol = cin%npcol
184 cout%iam = cin%iam
185 cout%myrow = cin%myrow
186 cout%mycol = cin%mycol
187
188 if (cout%context /= blacs_null_context) then
189 ! we have to create a new context
190 call blacs_get(blacs_null_context, what = 0, val = cout%context)
191 safe_allocate_source_a(cout%usermap, cin%usermap)
192 call blacs_gridmap(cout%context, cout%usermap(1, 1), cout%nprow, cout%nprow, cout%npcol)
193 end if
194
195#endif
196 pop_sub(blacs_proc_grid_copy)
197 end subroutine blacs_proc_grid_copy
198
199
200 logical pure function blacs_proc_grid_null(this)
201 type(blacs_proc_grid_t), intent(in) :: this
202
203 blacs_proc_grid_null = this%context == blacs_null_context
204 end function blacs_proc_grid_null
205
206end module blacs_proc_grid_oct_m
207
208
209!! Local Variables:
210!! mode: f90
211!! coding: utf-8
212!! End:
This module contains interfaces for BLACS routines Interfaces are from http:
Definition: blacs.F90:27
This module provides the BLACS processor grid.
subroutine, public blacs_proc_grid_init(this, mpi_grp, procdim)
Initializes a blacs context from an MPI communicator with topological information.
subroutine, public blacs_proc_grid_end(this)
subroutine, public blacs_proc_grid_copy(cin, cout)
logical pure function, public blacs_proc_grid_null(this)
integer, public mpi_err
used to store return values of mpi calls
Definition: mpi.F90:269