c***********************************************************************
c B P A M E R I C A
c PROPRIETARY - TO BE MAINTAINED IN CONFIDENCE
c COPYRIGHTED 2008
c***********************************************************************
c
c This MPI and OpenMP template is based on trace by trace processing.
c It should be simple to modify for record by record processing.
c It assumes that there is no communication needed between MPI nodes.
c
c The standard DDS Makefile to compile this code looks like this:
c
c Name := mpi_template
c F77Srcs := mpi_template.F
c Libs := masterslave
c MP := TRUE
c MPIX := TRUE
c
c include ${DDSROOT}/etc/MakeVariables
c include ${DDSROOT}/etc/MakeRules
c
c
c Inside bp you may checkout a copy of the template from the subversion repository
c using the command: "devcode export mpi_template new_prog_name"
c
c Author: Richard.Clarke@bp.com
c
program mpi_template
implicit none
c
#include <fdds.h>
#include <pfddx.h>
#define NUMCOTAGS 1
#define NUMOPTAGS 5
#define NUMTAGS (NUMCOTAGS + NUMOPTAGS)
c
integer in_bin,out_bin,buflen,ninbuf,ntrace
integer node,np,nproc
integer istart,iend,ier
integer rank,size(RANK_MAX)
integer ss(RANK_MAX),ee(RANK_MAX),ii(RANK_MAX)
integer numcotags,numoptags,numtags
integer itags(NUMTAGS),otags(NUMTAGS)
integer cumsize(RANK_MAX)
real origin(RANK_MAX),delta(RANK_MAX)
character*(DEFNNAME_MAX) hw(NUMTAGS)
c
real buf(1),hvals(1),samples(1)
pointer(ptr_buf,buf)
pointer(ptr_hvals,hvals)
pointer(ptr_samples,samples)
c
real fmax,f1,f2,f3,f4
logical ormsby,verbose
external online_help
c
ier=fddx_initmpix(nproc,np,node,'ddsfilt',online_help)
c
numcotags = 1
ier = fdds_sprintf(hw(1),'Samples\0')
c
numoptags = 5
ier = fdds_sprintf(hw(numcotags+1),'StaCor\0')
ier = fdds_sprintf(hw(numcotags+2),'Horz01\0')
ier = fdds_sprintf(hw(numcotags+3),'Horz02\0')
ier = fdds_sprintf(hw(numcotags+4),'Horz03\0')
ier = fdds_sprintf(hw(numcotags+5),'Horz04\0')
numtags = numcotags + numoptags
c
in_bin = fddx_inp('in','stdin:', 'ddsfilt',node, buflen,
$ numcotags, numoptags, hw, itags)
c
ier = fddx_checkforerrors(np,node)
c
ier = fddx_getdim(in_bin,rank,origin,delta,size,cumsize)
c
if ( cumsize(1) > 0 ) then
ntrace = cumsize(rank)
else
ntrace = -1 * cumsize(1)
endif
ier=fdds_prtmsg('The input contains %d traces.\n\0',ntrace)
c
ier = fddx_userrange( node, rank, size, ss, ee, ii )
c
ninbuf = 10
ier = fdds_scanf('ninbuf', '%d\0', ninbuf)
ptr_buf = fdds_malloc8( dble(buflen) *ninbuf*sizeof_real)
ptr_hvals = fdds_malloc8( dble(numtags)*ninbuf*sizeof_real)
ptr_samples = fdds_malloc8( dble(size(1))*ninbuf*sizeof_real)
c
fmax = 0.0
call ReadParams(node,ormsby,fmax,f1,f2,f3,f4,verbose)
c
ier = fddx_checkforerrors(np,node)
c
ier = fddx_dict( in_bin, 'scan' )
ier = fdds_dict( 'tmp_mpi:', 'print' )
ier = fdds_history()
c
ier = fdds_printf('axis','t px py nbc\n\0')
ier = fdds_dict( 'tmp_mpi:', 'scan' )
ier = fdds_dict( 'tmp_mpi:', 'print' )
c
ier = fdds_printf('size.axis(1)','%d\n\0',size(1))
c
out_bin=fddx_outp('out','stdout:','ddsfilt',in_bin,node,np,
$ 'tmp_mpi:',numcotags,numoptags,hw,otags)
c
ier = fddx_checkforerrors(np,node)
c
ier = fddx_jobrange(ntrace,np,node,istart,iend)
c
call ProcessChunk(
$ in_bin,out_bin,istart,iend,
$ buflen,ninbuf,size(1),buf,
$ rank,cumsize,ss,ee,ii,
$ itags(1),otags(1),samples,
$ numtags-1,itags(2),otags(2),hvals)
c
ier = fddx_stop(np,node)
end
c
c***********************************************************************
c
c Routine to process a chunk of data
c
c***********************************************************************
c
subroutine ProcessChunk(
$ in_bin,out_bin,istart,iend,
$ buflen,ninbuf,nsamp,buf,
$ rank,cumsize,ss,ee,ii,
$ it_tag,ot_tag,samples,
$ numtags,itags,otags,hvals)
c
implicit none
c
#include
#include
c
integer in_bin,out_bin,ier
integer istart,iend
integer buflen,ninbuf,nsamp,ntrace,nread
integer rank,cumsize(RANK_MAX)
integer ss(RANK_MAX),ee(RANK_MAX),ii(RANK_MAX)
integer it_tag,ot_tag
integer numtags,itags(numtags),otags(numtags)
integer jj,kk,ll,itrace
real buf(buflen,ninbuf)
real samples(nsamp,ninbuf)
real hvals(numtags,ninbuf)
c
if ( fdds_isreg(in_bin) .gt. 0 ) then
ier = fdds_lseek(in_bin, 0,istart,SEEK_SET)
endif
if ( fdds_isreg(out_bin) .gt. 0 ) then
ier = fdds_lseek(out_bin,0,istart,SEEK_SET)
endif
itrace = istart
ntrace = ninbuf
do while ( itrace .le. iend )
if( 1 + iend - itrace .lt. ninbuf ) then
ntrace = 1 + iend - itrace
endif
nread=fddx_readtrace(in_bin,buflen,nsamp,ntrace,buf,
$ it_tag,samples,numtags,itags,hvals)
C$OMP PARALLEL DO DEFAULT(SHARED), PRIVATE(ll,kk)
do ll = 1,nread
C$OMP CRITICAL
c ier=fdds_prtmsg('ll=%d nread=%d\n\0',ll,nread)
C$OMP END CRITICAL
if(1.eq.fddx_trace_in_range
$ (itrace+ll-1,rank,cumsize,ss,ee,ii))then
do kk = 1,nsamp
samples(kk,ll) = itrace
end do
endif
end do
ier=fddx_writetrace(out_bin,buflen,nsamp,nread,buf,
$ ot_tag,samples,numtags,otags,hvals)
itrace = itrace + ninbuf
end do
return
end
subroutine ReadParams(node,ormsby,fmax,f1,f2,f3,f4,verbose)
implicit none
#include
integer node,ier
real fmax,f1,f2,f3,f4
logical ormsby,verbose
ier=fdds_dict('par:','scan')
ormsby = (fdds_switch('ormsby',1).eq.1)
f1 = 0.0
f2 = 0.0
f3 = fmax
f4 = fmax
ier = fdds_scanf('f1', '%f\0', f1)
ier = fdds_scanf('f2', '%f\0', f2)
ier = fdds_scanf('f3', '%f\0', f3)
ier = fdds_scanf('f4', '%f\0', f4)
if ( ormsby .eq. .true. ) then
if ( f1 .gt. f2 .or. f2.gt.f3 .or. f3.gt.f4 ) then
ier=fdds_prterr('Problem with f1=%g f2=%g f3=%g f4=%g\n\0',
$ f1,f2,f3,f4)
endif
endif
verbose = (fdds_switch('verbose',0).eq.1)
if ( node .eq. 0 ) then
ier=fdds_prtmsg('\n*** PARAMETERS ***\n\n\0')
if (ormsby) then
ier=fdds_prtmsg('Using ormsby filter.\n\0')
ier=fdds_prtmsg('f1=%g f2=%g f3=%g f4=%g\n\0',f1,f2,f3,f4)
else
ier=fdds_prtmsg('Not using ormsby filter.\n\0')
endif
ier=fdds_prtmsg('\n\0')
if (verbose) then
ier=fdds_prtmsg('Writing more verbose printout.\n\0')
else
ier=fdds_prtmsg('Writing less verbose printout.\n\0')
endif
endif
return
end
subroutine online_help()
implicit none
write(0,*) 'Read the man page!'
stop 0
return
end