File: process_prequest_message.F

package info (click to toggle)
aces3 3.0.6-7
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 82,460 kB
  • sloc: fortran: 225,647; ansic: 20,413; cpp: 4,349; makefile: 953; sh: 137
file content (149 lines) | stat: -rwxr-xr-x 5,901 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
C  Copyright (c) 2003-2010 University of Florida
C
C  This program is free software; you can redistribute it and/or modify
C  it under the terms of the GNU General Public License as published by
C  the Free Software Foundation; either version 2 of the License, or
C  (at your option) any later version.

C  This program is distributed in the hope that it will be useful,
C  but WITHOUT ANY WARRANTY; without even the implied warranty of
C  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
C  GNU General Public License for more details.

C  The GNU General Public License is included in this distribution
C  in the file COPYRIGHT.
      subroutine process_prequest_message(node, server_table,
     *                                   nserver_table)
c---------------------------------------------------------------------------
c   This subroutine handles the processing and manages state transitions
c   of a prequest message.
c---------------------------------------------------------------------------
      implicit none
      include 'server.h'
      include 'mpif.h'
      include 'parallel_info.h'
      include 'dbugcom.h'
      include 'server_stat.h'
#ifdef ALTIX
      include 'sheap.h'
#endif

      integer nserver_table
      integer server_table(lserver_table_entry,nserver_table)
      integer node
      integer i, iblock
      integer*8 indblk, get_index_from_base
      integer*8 ind1, ind2
      integer ptr, ptr2, msgbuffer, state, ierr
      integer memloc, diskloc, size, ifile
      integer status(MPI_STATUS_SIZE)
      logical flag, restore_data_flag
      double precision x(1)
#ifdef ALTIX
      pointer (dptr, x)
#else
      common x
#endif
      double precision xmin, xmax

#ifdef ALTIX
      dptr = dshptr
#endif
      state = server_msg(c_msg_state,node)
c      print *,'PREQ MSG: line ',server_msg(c_msg_current_line,node),
c     *     ' node ',node,' state ',state,' cause ',
c     *     server_msg(c_msg_cause,node), 
c     *     ' clean ptr ',
c     *     clean_block_ptr,' nclean ',nclean_blocks
      if (state .eq. begin_state .or. 
     *    state .eq. wait_for_block_state) then

c---------------------------------------------------------------------------
c   Force the data into memory.  
c---------------------------------------------------------------------------
 
         call claim_memory_block(node, server_table, nserver_table,
     *                            .true.)

         if (server_msg(c_msg_state, node) .eq. null_state) then
            server_msg(c_msg_state, node) = prequest_intermediate_state
         else
c            print *,'CLAIM FAILED: cause ',server_msg(c_msg_cause,node)
            return   ! claim did not work, retry later.
         endif
      endif
          
      if (server_msg(c_msg_state,node) .eq. 
     *                 prequest_intermediate_state) then

c--------------------------------------------------------------------------
c   Lookup the addresses of the data block and the msgbuffer data block.
c--------------------------------------------------------------------------

         ptr       = server_msg(c_msg_stptr,node)
         memloc    = server_table(c_server_memloc,ptr)
         msgbuffer = server_msg(c_msg_msgbuffer,node)

         indblk    = get_index_from_base(base_mem_addr, x, 2)
         ind1      = indblk + (memloc-1)*server_mem_blocksize
         ind2      = indblk +(msgbuffer-1)*server_mem_blocksize

c---------------------------------------------------------------------------
c   Copy the slice of data from the data block (ind1) into the msgbuffer 
c   (ind2).
c---------------------------------------------------------------------------

         call prequest_copy_slice(node, x(ind1), x(ind2),
     *                   server_table, nserver_table)

c---------------------------------------------------------------------------
c   Post a mpi_isend using the msgbuffer as the data address.
c---------------------------------------------------------------------------

         size = server_msg(c_msg_size,node)
         call mpi_isend(x(ind2), size, mpi_double_precision,
     *               server_msg(c_msg_source,node),
     *               server_msg(c_msg_tag,node),mpi_comm_world,
     *               server_msg(c_msg_request,node), ierr)

c--------------------------------------------------------------------------
c   Release the data block by turning off the server_table flags.  This 
c   allows the block to be reused in other messages at this point.
c---------------------------------------------------------------------------

          server_table(c_server_flags,ptr) = xor(server_busy_flag,
     *              server_table(c_server_flags,ptr))
          server_table(c_server_busy_node,ptr) = 0
          call push_clean_block(memloc,server_table, nserver_table)

c---------------------------------------------------------------------------
c   Enter the "wait_for_send" state.
c---------------------------------------------------------------------------

         server_msg(c_msg_state,node) = wait_for_send_state
      endif

      if (server_msg(c_msg_state,node) .eq.
     *                         wait_for_send_state) then

c-------------------------------------------------------------------------
c   Test for completion of the send.
c-------------------------------------------------------------------------

         if (server_msg(c_msg_request,node) .eq. 
     *                               MPI_REQUEST_NULL) then
            flag = .true.
         else
            call mpi_test(server_msg(c_msg_request,node), flag,
     *                 status, ierr)
         endif

         if (flag) then
c            print *,'PREQ line ',server_msg(c_msg_current_line,node),
c     *            ' for node ',node,' completed!!!'
            server_msg(c_msg_state,node) = null_state   ! done
         endif
      endif

      return
      end