Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update master from gmtb/develop 2019/10/16 #230

Merged
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
d9f538e
scripts/common.py, scripts/ccpp_prebuild.py: move definition of CCPP_…
climbfuji Sep 12, 2019
7f3c188
scripts/metadata2html.py: add batch processing option using CCPP preb…
climbfuji Sep 12, 2019
258bc8e
doc/CCPPtechnical/source/ScientificDocRules.inc: update documentation…
climbfuji Sep 12, 2019
513d6e3
Update of scripts and documentation to address reviewer comments
climbfuji Sep 13, 2019
6abc50e
Merge pull request #223 from climbfuji/gmtb_develop_metadata2html_bat…
climbfuji Sep 13, 2019
ee4cf5f
scripts/metavar.py, scripts/parse_tools/parse_checkers.py: re-enable …
climbfuji Sep 13, 2019
62d4c41
Merge branch 'master' of https://github.com/NCAR/ccpp-framework into …
climbfuji Sep 13, 2019
470d27e
Merge branch 'gmtb/develop' of https://github.com/NCAR/ccpp-framework…
climbfuji Sep 13, 2019
9088a6c
Merge pull request #224 from climbfuji/myj_with_dom_mods
climbfuji Sep 19, 2019
00e63a1
doc/CCPPtechnical/source/BuildingRunningHostModels.rst: remove docume…
climbfuji Sep 20, 2019
5b472cd
Merge pull request #225 from climbfuji/remove_transition_mode
climbfuji Sep 23, 2019
94a426e
- Remove CCPPtechnical directory.
Sep 23, 2019
4f60488
Merge pull request #226 from JulieSchramm/gmtb/develop
climbfuji Sep 26, 2019
6dc90b3
Modifications of code generator to support out-of-source builds, requ…
climbfuji Aug 29, 2019
5a67e43
scripts/mkstatic.py: add missing guard for filepath being empty
climbfuji Aug 29, 2019
e742528
scripts/mkdoc.py: add missing guard for filepath being empty
climbfuji Oct 10, 2019
1358ecf
scripts/ccpp_prebuild.py: write html and latex variable tables to bui…
climbfuji Oct 10, 2019
0e3f90b
Merge branch 'gmtb/develop' of https://github.com/NCAR/ccpp-framework…
climbfuji Oct 16, 2019
8553108
Improvements of prebuild scripts based on reviewer comments; use stan…
climbfuji Oct 18, 2019
dcb3a83
Merge branch 'ccpp_prebuild_out_of_source_build' of https://github.co…
climbfuji Oct 21, 2019
82329df
scripts/ccpp_prebuild.py: write schemes and caps with path
climbfuji Oct 22, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 7 additions & 15 deletions scripts/ccpp_prebuild.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@
# Standard modules
import argparse
import collections
import importlib
import itertools
import logging
import os
import re
import sys

# Local modules
# CCPP framework imports
from common import encode_container, decode_container, decode_container_as_dict, execute
from common import CCPP_INTERNAL_VARIABLES, CCPP_STATIC_API_MODULE
from common import CCPP_INTERNAL_VARIABLES, CCPP_STATIC_API_MODULE, CCPP_INTERNAL_VARIABLE_DEFINITON_FILE
from common import split_var_name_and_array_reference
from metadata_parser import merge_dictionaries, parse_scheme_tables, parse_variable_tables
from mkcap import Cap, CapsMakefile, CapsCMakefile, SchemesMakefile, SchemesCMakefile
Expand All @@ -32,15 +33,6 @@
# BASEDIR is the current directory where this script is executed
BASEDIR = os.getcwd()

# SCRIPTDIR is the directory where the ccpp_prebuild.py and its Python modules are located
SCRIPTDIR = os.path.abspath(os.path.split(__file__)[0])

# SRCDIR is the directory where the CCPP framework source code (C, Fortran) is located
SRCDIR = os.path.abspath(os.path.join(SCRIPTDIR, '..', 'src'))

# Definition of variables (metadata tables) that are provided by CCPP
CCPP_INTERNAL_VARIABLE_DEFINITON_FILE = os.path.join(SRCDIR, 'ccpp_types.F90')

###############################################################################
# Functions and subroutines #
###############################################################################
Expand Down Expand Up @@ -71,10 +63,10 @@ def import_config(configfile):

# Import the host-model specific CCPP prebuild config;
# split into path and module name for import
configpath = os.path.abspath(os.path.split(configfile)[0])
configmodule = os.path.split(configfile)[1].rstrip('.py')
configpath = os.path.abspath(os.path.dirname(configfile))
configmodule = os.path.splitext(os.path.basename(configfile))[0]
sys.path.append(configpath)
ccpp_prebuild_config = __import__(configmodule)
ccpp_prebuild_config = importlib.import_module(configmodule)

# Definitions in host-model dependent CCPP prebuild config script
config['variable_definition_files'] = ccpp_prebuild_config.VARIABLE_DEFINITION_FILES
Expand All @@ -99,7 +91,7 @@ def import_config(configfile):
# Template code in host-model dependent CCPP prebuild config script
config['ccpp_data_structure'] = ccpp_prebuild_config.CCPP_DATA_STRUCTURE

# Add model-intependent, CCPP-internal variable definition files
# Add model-independent, CCPP-internal variable definition files
config['variable_definition_files'].append(CCPP_INTERNAL_VARIABLE_DEFINITON_FILE)

# To handle new metadata: import DDT references (if exist)
Expand Down
11 changes: 11 additions & 0 deletions scripts/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import keyword
import logging
import os
import re
import subprocess
import sys
Expand All @@ -14,6 +15,16 @@

CCPP_TYPE = 'ccpp_t'

# SCRIPTDIR is the directory where ccpp_prebuild.py and its Python modules are located
SCRIPTDIR = os.path.abspath(os.path.dirname(__file__))

# SRCDIR is the directory where the CCPP framework source code (C, Fortran) is located
SRCDIR = os.path.abspath(os.path.join(SCRIPTDIR, os.pardir, 'src'))

# Definition of variables (metadata tables) that are provided by CCPP
CCPP_INTERNAL_VARIABLE_DEFINITON_FILE = os.path.join(SRCDIR, 'ccpp_types.F90')

# List of internal variables provided by the CCPP
CCPP_INTERNAL_VARIABLES = {
CCPP_ERROR_FLAG_VARIABLE : 'cdata%errflg',
CCPP_ERROR_MSG_VARIABLE : 'cdata%errmsg',
Expand Down
84 changes: 75 additions & 9 deletions scripts/metadata2html.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,89 @@

import argparse
import logging
import importlib
import os
import sys

# CCPP framework imports
from common import CCPP_INTERNAL_VARIABLE_DEFINITON_FILE
from parse_tools import init_log, set_log_level
from metadata_table import MetadataHeader

###############################################################################
# Set up the command line argument parser and other global variables #
###############################################################################

parser = argparse.ArgumentParser()
parser.add_argument('--metafile', '-m', action='store',
help='name of metadata file to convert',
required=True)
method = parser.add_mutually_exclusive_group(required=True)
method.add_argument('--config', '-c', action='store',
help='path to CCPP prebuild configuration file')
method.add_argument('--metafile', '-m', action='store',
help='name of metadata file to convert (requires -o)')
parser.add_argument('--outputdir', '-o', action='store',
help='directory where to write the html files',
required=True)
required='--metafile' in sys.argv or '-m' in sys.argv)

attributes = [ 'local_name', 'standard_name', 'long_name', 'units',
# List and order of variable attributes to output to HTML
ATTRIBUTES = [ 'local_name', 'standard_name', 'long_name', 'units',
'type', 'dimensions', 'kind', 'intent', 'optional' ]

###############################################################################
# Functions and subroutines #
###############################################################################

def parse_arguments():
"""Parse command line arguments."""
args = parser.parse_args()
config = args.config
filename = args.metafile
outdir = args.outputdir
return (filename, outdir)
return (config, filename, outdir)

def import_config(configfile, logger):
"""Import the configuration from a given configuration file"""

if not os.path.isfile(configfile):
raise Exception("Configuration file {0} not found".format(configfile))

# Import the host-model specific CCPP prebuild config;
# split into path and module name for import
configpath = os.path.abspath(os.path.dirname(configfile))
configmodule = os.path.splitext(os.path.basename(configfile))[0]
sys.path.append(configpath)
ccpp_prebuild_config = importlib.import_module(configmodule)

config = {}
# Definitions in host-model dependent CCPP prebuild config script
config['variable_definition_files'] = ccpp_prebuild_config.VARIABLE_DEFINITION_FILES
config['scheme_files'] = ccpp_prebuild_config.SCHEME_FILES
# Add model-independent, CCPP-internal variable definition files
config['variable_definition_files'].append(CCPP_INTERNAL_VARIABLE_DEFINITON_FILE)
# Output directory for converted metadata tables
config['metadata_html_output_dir'] = ccpp_prebuild_config.METADATA_HTML_OUTPUT_DIR

return config

def get_metadata_files_from_config(config, logger):
"""Create a list of metadata filenames for a CCPP prebuild configuration"""
filenames = []
for sourcefile in config['variable_definition_files'] + config['scheme_files'].keys():
metafile = os.path.splitext(sourcefile)[0]+'.meta'
if os.path.isfile(metafile):
filenames.append(metafile)
else:
# DH* Warn for now, raise exception later when
# old metadata format is no longer supported
logger.warn("Metadata file {} for source file {} not found, assuming old metadata format".format(
metafile, sourcefile))
return filenames

def get_output_directory_from_config(config, logger):
"""Return the html output directory for a CCPP prebuild configuration"""
outdir = config['metadata_html_output_dir']
if not os.path.isdir(outdir):
raise Exception("Output directory {} for converted metadata tables does not exist".format(outdir))
return outdir

def convert_to_html(filename_in, outdir, logger):
"""Convert a metadata file into html (one html file for each table)"""
Expand All @@ -34,7 +93,7 @@ def convert_to_html(filename_in, outdir, logger):
logger.info("Converting file {} to HTML".format(filename_in))
metadata_headers = MetadataHeader.parse_metadata_file(filename_in)
for metadata_header in metadata_headers:
filename_out = metadata_header.to_html(outdir, attributes)
filename_out = metadata_header.to_html(outdir, ATTRIBUTES)
if filename_out:
logger.info(" ... wrote {}".format(filename_out))

Expand All @@ -43,8 +102,15 @@ def main():
logger = init_log('metadata2html')
set_log_level(logger, logging.INFO)
# Convert metadata file
(filename, outdir) = parse_arguments()
convert_to_html(filename, outdir, logger)
(configfile, filename, outdir) = parse_arguments()
if configfile:
config = import_config(configfile, logger)
filenames = get_metadata_files_from_config(config, logger)
outdir = get_output_directory_from_config(config, logger)
for filename in filenames:
convert_to_html(filename, outdir, logger)
else:
convert_to_html(filename, outdir, logger)

if __name__ == '__main__':
main()
7 changes: 1 addition & 6 deletions scripts/metavar.py
Original file line number Diff line number Diff line change
Expand Up @@ -369,12 +369,7 @@ class Var(object):
VariableProperty('dimensions', list,
check_fn_in=check_dimensions),
VariableProperty('type', str,
# DH* Avoid checking of DDTs being registered or not,
# this only works if all DDTs required in one metadata
# are defined in that file and/or parsed beforehand.
#check_fn_in=check_fortran_type),
# *DH
),
check_fn_in=check_fortran_type),
VariableProperty('kind', str,
optional_in=True,
default_fn_in=default_kind_val),
Expand Down
16 changes: 9 additions & 7 deletions scripts/parse_tools/parse_checkers.py
Original file line number Diff line number Diff line change
Expand Up @@ -354,13 +354,15 @@ def check_fortran_type(typestr, error=False):
match = registered_fortran_ddt_name(typestr)
dt = " derived"
# End if
if match is None:
if error:
raise CCPPError("'{}' is not a valid{} Fortran type".format(typestr, dt))
else:
typestr = None
# End if
# End if
# DH* 20190913 - skip checking if a DDT is registered at this time
#if match is None:
# if error:
# raise CCPPError("'{}' is not a valid{} Fortran type".format(typestr, dt))
# else:
# typestr = None
# # End if
## End if
# *DH 20190913
Comment on lines +357 to +365
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sort of change is going to make it difficult to keep the capgen development branch up to date with master. Can we find some other technique (e.g., some variable test) to ensure that this clause is not triggered for master but is active for feature/capgen?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest to worry about this once capgen is merged into master - until then, the logic in the master-version of the scripts that capgen would be using would require this change as well, because it assumes that (a) all DDTs used are defined in the same metadata file (which is certainly not going to be the case) and that they are defined in the metadata file before they are used. I understand that the feature/capgen version completes the analysis phase and then knows about all DDTs, but the current version in the master branch does not.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will accept that, however, this means that master and feature/capgen will diverge until then. Adding more logic to keep the if statement from being triggered in master, will allow updates to feature/capgen.

return typestr

########################################################################
Expand Down