Skip to content

Commit

Permalink
create a struct to hold the Microphysics runtime parameters (#1433)
Browse files Browse the repository at this point in the history
This now creates a header extern_type.H with a struct extern_t that holds all
of the runtime parameters for Microphysics. The struct is filled on initialization
and returned by init_extern_parameters(). This can replace the global version
of the runtime parameters.

This also revives the test_parameters unit test to show how to access things.
  • Loading branch information
zingale authored May 29, 2024
1 parent 41df7b4 commit 0cc5a37
Show file tree
Hide file tree
Showing 10 changed files with 168 additions and 35 deletions.
2 changes: 1 addition & 1 deletion Make.Microphysics
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ $(MICROPHYSICS_AUTO_SOURCE_DIR)/extern_parameters.H: $(EXTERN_PARAMETERS) $(EXTE
@if [ ! -d $(MICROPHYSICS_AUTO_SOURCE_DIR) ]; then mkdir -p $(MICROPHYSICS_AUTO_SOURCE_DIR); fi
$(MICROPHYSICS_HOME)/util/build_scripts/write_probin.py \
--cxx_prefix $(MICROPHYSICS_AUTO_SOURCE_DIR)/extern \
--pa "$(EXTERN_PARAMETERS)" --use_namespace
--pa "$(EXTERN_PARAMETERS)"

# for debugging
test_extern_params: $(MICROPHYSICS_AUTO_SOURCE_DIR)/extern_parameters.cpp
Expand Down
33 changes: 33 additions & 0 deletions unit_test/test_parameters/GNUmakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
PRECISION = DOUBLE
PROFILE = FALSE

DEBUG = FALSE

DIM = 3

COMP = gnu

USE_MPI = FALSE
USE_OMP = FALSE

USE_REACT = TRUE

EBASE = main

BL_NO_FORT = TRUE

# define the location of the Microphysics top directory
MICROPHYSICS_HOME := ../..

# This sets the EOS directory
EOS_DIR := helmholtz

# This sets the network directory
NETWORK_DIR := aprox19

EXTERN_SEARCH += . ..

Bpack := ./Make.package
Blocs := .

include $(MICROPHYSICS_HOME)/unit_test/Make.unit_test
3 changes: 3 additions & 0 deletions unit_test/test_parameters/Make.package
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
CEXE_sources += main.cpp

CEXE_headers += test_parameters.H
11 changes: 11 additions & 0 deletions unit_test/test_parameters/_parameters
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
@namespace: unit_test

dens_min real 1.e6
dens_max real 1.e9
temp_min real 1.e6
temp_max real 1.e12

small_temp real 1.e4
small_dens real 1.e-4

test_string string "test"
4 changes: 4 additions & 0 deletions unit_test/test_parameters/inputs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
unit_test.test_string = "this is a C++ string"
eos.eos_input_is_constant = 0

amr.probin = probin
47 changes: 47 additions & 0 deletions unit_test/test_parameters/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include <AMReX_PlotFileUtil.H>
#include <AMReX_ParmParse.H>
#include <AMReX_Print.H>

#include <AMReX_Geometry.H>
#include <AMReX_MultiFab.H>
#include <AMReX_BCRec.H>


using namespace amrex;

#include <test_parameters.H>
#include <AMReX_buildInfo.H>

#include <extern_parameters.H>
#include <unit_test.H>

int main (int argc, char* argv[])
{
amrex::Initialize(argc, argv);

main_main();

amrex::Finalize();
return 0;
}

void main_main ()
{

// do the runtime parameter initializations and microphysics inits
if (ParallelDescriptor::IOProcessor()) {
std::cout << "reading extern runtime parameters ..." << std::endl;
}

ParmParse ppa("amr");

auto params = init_unit_test();

std::cout << "in C++" << std::endl;

std::cout << " eos_input_is_constant = " << eos_rp::eos_input_is_constant << " " << params.eos.eos_input_is_constant << std::endl;
std::cout << " test_string = " << unit_test_rp::test_string << " " << params.unit_test.test_string << std::endl;
std::cout << " dens_min = " << unit_test_rp::dens_min << " " << params.unit_test.dens_min << std::endl;
std::cout << " nonaka_file = " << integrator_rp::nonaka_file << " " << params.integrator.nonaka_file << std::endl;

}
6 changes: 6 additions & 0 deletions unit_test/test_parameters/test_parameters.H
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#ifndef TEST_EOS_H
#define TEST_EOS_H

void main_main();

#endif
5 changes: 3 additions & 2 deletions unit_test/unit_test.H
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
void write_job_info(const std::string& dir);

AMREX_INLINE
void
extern_t
init_unit_test() {

// now sync with C++ and read in the C++ parameters
init_extern_parameters();
auto params = init_extern_parameters();
return params;

}
#endif
4 changes: 2 additions & 2 deletions util/build_scripts/runtime_parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,11 +173,11 @@ def get_query_struct_string(self, struct_name="params", class_name=None):
ostr += f" amrex::Vector<{self.get_cxx_decl()}> {self.name}_tmp({self.size}, {self.default_format()});\n"
ostr += f" if (pp.queryarr(\"{self.name}\", {self.name}_tmp, 0, {self.size})) {{\n"
ostr += f" for (int n = 0; n < {self.size}; n++) {{\n"
ostr += f" {cname}{struct_name}.{self.namespace}{self.namespace_suffix}.{self.cpp_var_name}[n] = {self.name}_tmp[n];\n"
ostr += f" {cname}{struct_name}.{self.namespace}.{self.cpp_var_name}[n] = {self.name}_tmp[n];\n"
ostr += " }\n\n"
ostr += " }\n\n"
else:
ostr += f"pp.query(\"{self.name}\", {cname}{struct_name}.{self.namespace}{self.namespace_suffix}.{self.cpp_var_name});\n"
ostr += f"pp.query(\"{self.name}\", {cname}{struct_name}.{self.namespace}.{self.cpp_var_name});\n"

return ostr

Expand Down
88 changes: 58 additions & 30 deletions util/build_scripts/write_probin.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import argparse
import os
import sys
import warnings

import runtime_parameters

Expand Down Expand Up @@ -64,19 +65,19 @@ def get_next_line(fin):
return line[:pos]


def parse_param_file(params_list, param_file, use_namespace=False):
def parse_param_file(params_list, param_file):
"""read all the parameters in a given parameter file and add valid
parameters to the params list.
"""

namespace = None

try:
f = open(param_file, "r")
except IOError:
f = open(param_file)
except OSError:
sys.exit(f"write_probin.py: ERROR: file {param_file} does not exist")
else:
print(f"write_probin.py: working on parameter file {param_file}...")

print(f"write_probin.py: working on parameter file {param_file}...")

line = get_next_line(f)

Expand Down Expand Up @@ -111,18 +112,13 @@ def parse_param_file(params_list, param_file, use_namespace=False):
err = 1
continue

if use_namespace:
skip_namespace_in_declare = False
else:
skip_namespace_in_declare = True

current_param = runtime_parameters.Param(name, dtype, default,
namespace=namespace, namespace_suffix="_rp",
skip_namespace_in_declare=skip_namespace_in_declare)
skip_namespace_in_declare=False)

try:
current_param.priority = int(fields[3])
except:
except IndexError:
pass

skip = 0
Expand Down Expand Up @@ -159,8 +155,7 @@ def abort(outfile):
sys.exit(1)


def write_probin(param_files,
out_file, use_namespace, cxx_prefix):
def write_probin(param_files, out_file, cxx_prefix):

""" write_probin will read through the list of parameter files and
output the new out_file """
Expand All @@ -173,7 +168,7 @@ def write_probin(param_files,
# read the parameters defined in the parameter files

for f in param_files:
err = parse_param_file(params, f, use_namespace=use_namespace)
err = parse_param_file(params, f)
if err:
abort(out_file)

Expand All @@ -188,19 +183,18 @@ def write_probin(param_files,
with open(ofile, "w") as fout:
fout.write(CXX_HEADER)

fout.write(f" void init_{cxx_base}_parameters();\n\n")
fout.write(f"#include <{cxx_base}_type.H>\n\n")
fout.write(f" {cxx_base}_t init_{cxx_base}_parameters();\n\n")

for nm in sorted(namespaces):
params_in_nm = [q for q in params if q.namespace == nm]

if use_namespace:
fout.write(f" namespace {nm}_rp {{\n")
fout.write(f" namespace {nm}_rp {{\n")

for p in params_in_nm:
fout.write(f" {p.get_declare_string(with_extern=True)}")

if use_namespace:
fout.write(" }\n")
fout.write(" }\n")

fout.write(CXX_FOOTER)

Expand All @@ -211,7 +205,7 @@ def write_probin(param_files,
for p in params:
fout.write(p.get_job_info_test())

# finally the C++ initialization routines
# now the C++ initialization routines

ofile = f"{cxx_prefix}_parameters.cpp"
with open(ofile, "w") as fout:
Expand All @@ -225,20 +219,22 @@ def write_probin(param_files,
for nm in sorted(namespaces):
params_in_nm = [q for q in params if q.namespace == nm]

if use_namespace:
fout.write(f" namespace {nm}_rp {{\n")
fout.write(f" namespace {nm}_rp {{\n")

for p in params_in_nm:
fout.write(f" {p.get_declare_string()}")

if use_namespace:
fout.write(" }\n")
fout.write(" }\n")

fout.write("\n")
fout.write(f" void init_{cxx_base}_parameters() {{\n")
fout.write(f" {cxx_base}_t init_{cxx_base}_parameters() {{\n")

# we need access to _rt
fout.write(" using namespace amrex;\n\n")
fout.write(" using namespace amrex;\n\n")

# create the struct that will hold all the parameters -- this is what
# we will return
fout.write(f" {cxx_base}_t params;\n\n")

# now write the parmparse code to get the value from the C++
# inputs. this will overwrite
Expand All @@ -255,26 +251,58 @@ def write_probin(param_files,
fout.write(f" amrex::ParmParse pp(\"{nm}\");\n")
for p in params_nm:
fout.write(f" {p.get_default_string()}")
fout.write(f" {p.get_query_string()}\n")
fout.write(f" {p.get_query_string()}")
fout.write(f" {p.get_query_struct_string(struct_name='params')}\n")
fout.write(" }\n")

fout.write(" return params;\n\n")

fout.write(" }\n")

# finally, a single file that contains all of the parameter structs

ofile = f"{cxx_prefix}_type.H"
with open(ofile, "w") as fout:
fout.write(f"#ifndef {cxx_base.upper()}_TYPE_H\n")
fout.write(f"#define {cxx_base.upper()}_TYPE_H\n\n")
fout.write("using namespace amrex::literals;\n\n")

for nm in sorted(namespaces):
params_nm = [q for q in params if q.namespace == nm]

fout.write(f"struct {nm}_param_t {{\n")
for p in params_nm:
fout.write(p.get_struct_entry())
fout.write("};\n\n")

# now the parent struct

fout.write(f"struct {cxx_base}_t {{\n")
for nm in namespaces:
fout.write(f" {nm}_param_t {nm};\n")
fout.write("};\n\n")

fout.write("#endif\n")


def main():

parser = argparse.ArgumentParser()
parser.add_argument('-o', type=str, default="", help='out_file')
parser.add_argument('--pa', type=str, help='parameter files')
parser.add_argument('--use_namespaces', action="store_true",
help="put parameters in namespaces")
help="[deprecated] put parameters in namespaces")
parser.add_argument('--cxx_prefix', type=str, default="extern",
help="a name to use in the C++ file names")

args = parser.parse_args()

if args.use_namespaces:
warnings.warn("the --use_namespaces option will be removed in the future", DeprecationWarning)

param_files = args.pa.split()

write_probin(param_files, args.o, args.use_namespaces, args.cxx_prefix)
write_probin(param_files, args.o, args.cxx_prefix)

if __name__ == "__main__":
main()

0 comments on commit 0cc5a37

Please sign in to comment.