Skip to content

Commit

Permalink
Merge pull request #21 from climbfuji/gmtb-gfsphysics-pgi-support
Browse files Browse the repository at this point in the history
Add support for PGI compiler to FV3+CCPP - gmtb-gfsphysics
  • Loading branch information
climbfuji authored Dec 13, 2017
2 parents f87010f + e7045bc commit 5bb13ab
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 6 deletions.
25 changes: 19 additions & 6 deletions makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ VER_PATCH = 0

FFLAGS += -I../fms -I../fms/include -fPIC

CPPDEFS = -DNEW_TAUCTMAX -DSMALL_PE -DNEMS_GSM
CPPDEFS += -DNEW_TAUCTMAX -DSMALL_PE -DNEMS_GSM

SRCS_f = \
./physics/cnvc90.f \
Expand Down Expand Up @@ -144,14 +144,15 @@ SRCS_F90 = \
./GFS_layer/GFS_radiation_driver.F90 \
./GFS_layer/GFS_restart.F90 \
./GFS_layer/GFS_typedefs.F90 \
./IPD_layer/IPD_driver_cap.F90 \
./IPD_layer/IPD_driver.F90 \
./IPD_layer/IPD_typedefs.F90


SRCS_c =

DEPEND_FILES = $(SRCS_f) $(SRCS_f90) $(SRCS_F) $(SRCS_F90)
CAPS_F90 = \
./IPD_layer/IPD_driver_cap.F90

DEPEND_FILES = $(SRCS_f) $(SRCS_f90) $(SRCS_F) $(SRCS_F90) $(CAPS_F90)

OBJS_f = $(SRCS_f:.f=.o)
OBJS_f90 = $(SRCS_f90:.f90=.o)
Expand All @@ -161,10 +162,12 @@ OBJS_c = $(SRCS_c:.c=.o)

OBJS = $(OBJS_f) $(OBJS_f90) $(OBJS_F) $(OBJS_F90) $(OBJS_c)

CAPS = $(CAPS_F90:.F90=.o)

all default: depend $(LIBRARY)

$(LIBRARY): $(OBJS)
$(FC) -shared -Wl,-soname,$(LIBRARY).$(VER_MAJOR) $(OBJS) $(LDFLAGS) $(NCEPLIBS) -o $(LIBRARY).$(VER_MAJOR).$(VER_MINOR).$(VER_PATCH)
$(LIBRARY): $(OBJS) $(CAPS)
$(FC) -shared -Wl,-soname,$(LIBRARY).$(VER_MAJOR) $(OBJS) $(CAPS) $(LDFLAGS) $(NCEPLIBS) -o $(LIBRARY).$(VER_MAJOR).$(VER_MINOR).$(VER_PATCH)
ln -sf $(LIBRARY).$(VER_MAJOR).$(VER_MINOR).$(VER_PATCH) $(LIBRARY)
ln -sf $(LIBRARY).$(VER_MAJOR).$(VER_MINOR).$(VER_PATCH) $(LIBRARY).$(VER_MAJOR)

Expand All @@ -177,6 +180,16 @@ $(LIBRARY): $(OBJS)
./GFS_layer/GFS_diagnostics.o : ./GFS_layer/GFS_diagnostics.F90
$(FC) $(FFLAGS) $(OTHER_FFLAGS) -O0 -c $< -o $@

ifneq (,$(findstring PGIFIX,$(CPPDEFS)))
$(CAPS):
$(FC) $(FFLAGS) $(OTHER_FFLAGS) -c $< -o $@
# Apply a fix specific to the PGI compiler (rename objects in cap object files)
./pgifix.py $@
else
$(CAPS):
$(FC) $(FFLAGS) $(OTHER_FFLAGS) -c $< -o $@
endif

.PHONY: clean
clean:
@echo "Cleaning gfsphysics ... "
Expand Down
78 changes: 78 additions & 0 deletions pgifix.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#!/usr/bin/env python

import argparse
import os
import subprocess
import sys

parser = argparse.ArgumentParser(description='Fix cap objects produced by PGI compiler')
parser.add_argument("cap")

def parse_args():
args = parser.parse_args()
cap = args.cap
return cap

def execute(cmd, debug = True, abort = True):
"""Runs a local command in a shell. Waits for completion and
returns status, stdout and stderr. If abort = True, abort in
case an error occurs during the execution of the command."""

if debug:
print 'Executing "{0}"'.format(cmd)
p = subprocess.Popen(cmd, stdout = subprocess.PIPE,
stderr = subprocess.PIPE, shell = True)
(stdout, stderr) = p.communicate()
status = p.returncode
if debug:
message = 'Execution of "{0}" returned with exit code {1}\n'.format(cmd, status)
message += ' stdout: "{0}"\n'.format(stdout.rstrip('\n'))
message += ' stderr: "{0}"'.format(stderr.rstrip('\n'))
print message
if not status == 0:
message = 'Execution of command {0} failed, exit code {1}\n'.format(cmd, status)
message += ' stdout: "{0}"\n'.format(stdout.rstrip('\n'))
message += ' stderr: "{0}"'.format(stderr.rstrip('\n'))
if abort:
raise Exception(message)
else:
print message
return (status, stdout.rstrip('\n'), stderr.rstrip('\n'))

def correct_cap_object_names(fixcmd, cap):
(cappath, capname) = os.path.split(cap)
pgiprefix = capname.rstrip('.o').lower() + '_'
# Get list of all symbols in cap object
nmcmd = 'nm {0}'.format(cap)
(status, stdout, stderr) = execute(nmcmd)
del nmcmd
# Parse all symbols and generate objcopy command
for line in stdout.split('\n'):
try:
(address, symboltype, objectname) = line.split()
except ValueError:
continue
if not symboltype == 'T':
continue
if objectname.startswith(pgiprefix):
newname = objectname[len(pgiprefix):]
if newname.endswith('_cap'):
fixcmd += '--redefine-sym {0}={1} '.format(objectname, newname)
return fixcmd

def correct_object_names(fixcmd, cap):
tmp = cap + '.tmp'
fixcmd += '{0} {1}'.format(cap, tmp)
execute(fixcmd)
mvcmd = 'mv -v {0} {1}'.format(tmp, cap)
execute(mvcmd)

def main():
cap = parse_args()
fixcmd = 'objcopy '
fixcmd = correct_cap_object_names(fixcmd, cap)
if not fixcmd == 'objcopy ':
correct_object_names(fixcmd, cap)

if __name__ == '__main__':
main()

0 comments on commit 5bb13ab

Please sign in to comment.