1

I received a code from github. I wish to incorporate the part of the code in our in-house Fortran code.

The code from github is:

program main
  implicit none
  integer i,ni,nj,images
  integer,dimension (128) :: iseed
  real(8) diff,norm
  real(8),parameter :: pi=3.14159265358979312d0
  real(8),allocatable,dimension(:) :: xi,ui,ud,xj,gj
  ni = 1000 !10000
  nj = 1000 !500000
  allocate( xi(3*ni),ui(3*ni),ud(3*ni),xj(3*nj),gj(3*nj) )
  do i = 1,128
     iseed(i) = 0
  enddo
  call random_seed(put=iseed)
  call random_number(xi)
  call random_number(xj)
  call random_number(gj)
  do i = 1,nj
     xj(3*i-2) = 5*(xj(3*i-2) - 0.5) * pi
     xj(3*i-1) = 5*(xj(3*i-1) - 0.5) * pi
     xj(3*i-0) = 5*(xj(3*i-0) - 0.5) * pi
     gj(3*i-2) = (gj(3*i-2) - 0.5) / ni
     gj(3*i-1) = (gj(3*i-1) - 0.5) / ni
     gj(3*i-0) = (gj(3*i-0) - 0.5) / ni
  enddo
  do i = 1,ni
     xi(3*i-2) = 3*(xi(3*i-2) - 0.5) * pi
     xi(3*i-1) = 3*(xi(3*i-1) - 0.5) * pi
     xi(3*i-0) = 3*(xi(3*i-0) - 0.5) * pi
     ui(3*i-2) = 0
     ui(3*i-1) = 0
     ui(3*i-0) = 0
  enddo
  images = 0
  call fmm_init(images)
  call fmm_biot_savart(ni,xi,ui,nj,xj,gj)
  call fmm_finalize()
  deallocate( xi,ui,ud,xj,gj )
end program main

And the make file for this is:

include ../Makefile.include
lib_serial_ij: serial_wrapper_ij.o $(OBJECT)
    ar -cr libfmm.a serial_wrapper_ij.o $(OBJECT)
    ranlib libfmm.a

test_serial_ij: test_serial_ij.o
    make lib_serial_ij
    $(FC) $? -L. -lfmm $(LFLAGS)
    ./a.out

And Makefile.include is:

.SUFFIXES: .cxx .cu .f90 .o
.PHONY: docs

CUDA_INSTALL_PATH = /usr/local/cuda

DEVICE  = cpu
#~ DEVICE  = gpu

CXX     = mpicxx -g -O3 -lstdc++ -fPIC -fopenmp -ffast-math -funroll-loops -rdynamic -Wfatal-errors -I../include
NVCC    = nvcc -Xcompiler "-fopenmp -O3" -lstdc++ -use_fast_math -I../include
FC      = mpif90 -g -O3 -fPIC -fopenmp -funroll-loops -rdynamic -I../include
FCC      = mpif90 -c -O3 -fPIC -fopenmp -funroll-loops -rdynamic -I../include
LFLAGS  = -D$(DEVICE) -lstdc++ -ldl -lm
LFLAGS  += -lmpi_cxx
LFLAGS  += -lpthread

ifeq ($(DEVICE),gpu)
LFLAGS  += -lcudart
endif
OBJECT  = ../kernel/$(DEVICE)Laplace.o ../kernel/$(DEVICE)BiotSavart.o\
    ../kernel/$(DEVICE)Stretching.o ../kernel/$(DEVICE)Gaussian.o\
    ../kernel/$(DEVICE)CoulombVdW.o

.cxx.o:
    $(CXX) -c $? -o $@ $(LFLAGS)
.cu.o:
    $(NVCC) -c $? -o $@ $(LFLAGS)
.f90.o:
    $(FC) -c $? -o $@

Now I wish to change the code a bit, instead of the main program I wish it as subroutine so that I can call it in our in-house code. The name of the subroutine is FMM_ij looks like:

subroutine FMM_ij (n_s,n_t,v_x,v_y,v_z,xi,ui,xj,gj)
!###########################!
integer, intent (in) :: n_s, n_t
real*8, intent (out) :: v_x(n_t)
real*8, intent (out) :: v_y(n_t)
real*8, intent (out) :: v_z(n_t)
real*8, intent (in) :: xi(3*n_t)
real*8, intent (in) :: ui(3*n_t)
real*8, intent (in) :: xj(3*n_s)
real*8, intent (in) :: gj(3*n_s)
!###########################!
integer i,images
real(8),parameter :: pi=3.14159265358979312d0
!###########################!

images = 0
print*, n_t,n_s,size(xi),size(ui),size(xj),size(gj)
print*, xi(500),ui(500),xj(500),gj(500)
call fmm_init(images)
call fmm_biot_savart(n_t,xi,ui,n_s,xj,gj)

do i = 1,n_t
    v_x(i) = ui(3*i-2)
    v_y(i) = ui(3*i-1)
    v_z(i) = ui(3*i-0)
enddo

call fmm_finalize()
end subroutine FMM_ij

What changes I should do in Makefile so that I get an object file of the subroutine FMM_ij and can call this subroutine in any other program? Thanks a lot.

Ian Bush
  • 6,996
  • 1
  • 21
  • 27
  • 2
    Firstly, please note that `real*8` and `real(8)` are not the same. See https://stackoverflow.com/questions/3170239/fortran-integer4-vs-integer4-vs-integerkind-4/24927806 Secondly, work in steps. First make a working subroutine and call it by some very simple code or insert it temporarilly directly into the existing source file. Only later care about integrating it into your Makefile in a separate source file. – Vladimir F Героям слава Nov 15 '21 at 09:17

0 Answers0