Skip to content

Commit 4e85726

Browse files
Joe-DownsJoseph Downs
authored andcommitted
WIP: call c_header from Makefile
1 parent 8d8f554 commit 4e85726

File tree

2 files changed

+109
-37
lines changed

2 files changed

+109
-37
lines changed

ompi/mpi/bindings/ompi_bindings/c_header.py renamed to ompi/mpi/bindings/c_header.py

Lines changed: 96 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,30 @@
1+
# Copyright (c) 2025 Joe Downs. All rights reserved.
2+
#
3+
# $COPYRIGHT$
4+
#
5+
# Additional copyrights may follow
6+
#
7+
# $HEADER$
8+
#
9+
10+
import argparse
111
import re
2-
import textwrap
3-
import consts
4-
from consts import Lang
12+
import json
13+
from pathlib import Path
514

615
import pympistandard as std
716

817
# ============================= Constants / Globals ============================
18+
DIR = Path(".")
19+
OUTPUT = DIR / "mpi.h"
20+
JSON_PATH = DIR / "abi.json"
921

1022
ABI_INTERNAL = "_ABI_INTERNAL"
1123

12-
categories = {}
13-
mangle_names = True
24+
categories_dict = {}
25+
MANGLE_NAMES = False
1426

15-
internal_datatypes = [
27+
INTERNAL_DATATYPES = [
1628
"MPI_Comm",
1729
"MPI_Datatype",
1830
"MPI_Errhandler",
@@ -26,15 +38,78 @@
2638
"MPI_Win",
2739
]
2840

41+
ENUM_CATEGORIES = [
42+
"ERROR_CLASSES",
43+
"MODE_CONSTANTS",
44+
"ASSORTED_CONSTANTS",
45+
"THREADS_CONSTANTS",
46+
"FILE_OPERATIONS_CONSTANTS",
47+
"DATATYPE_DECODING_CONSTANTS",
48+
"F90_DATATYPE_MATCHING_CONSTANTS",
49+
"COMMUNICATOR_GROUP_COMP_RESULTS",
50+
"TOPOLOGIES",
51+
"COMMUNICATOR_SPLIT_TYPE",
52+
"WINDOW_LOCK_TYPE_CONSTANTS",
53+
"WINDOW_CREATE_FLAVORS",
54+
"WINDOW_MODELS",
55+
"FILE_POS_CONSTANTS",
56+
"FILE_OP_CONSTANTS",
57+
"ENV_INQ_AND_ATTR_KEYS",
58+
"FORTRAN_STATUS_ARRAY_SIZE_AND_INDEX_C",
59+
"C_PREPROCESSOR_CONSTANTS_FORTRAN_PARAMETERS",
60+
"TOOL_INFO_IFACE_VERBOSITY_LEVELS",
61+
"TOOL_INFO_IFACE_VAR_ASSOCIATIONS",
62+
"TOOL_INFO_IFACE_VAR_SCOPES",
63+
"TOOL_INFO_IFACE_PVAR_CLASSES",
64+
"TOOL_INFO_IFACE_SOURCE_ORDERINGS",
65+
"TOOL_INFO_IFACE_CB_SAFETY_REQ_LEVELS",
66+
]
67+
68+
69+
# ============================== Argument Parsing ==============================
70+
parser = argparse.ArgumentParser()
71+
parser.add_argument("--abi-json", type=str, help=f"path to ABI JSON file [{DIR}/]")
72+
parser.add_argument("-o", "--output", type=str, help="output directory for the header file")
73+
parser.add_argument("--mangle-names", help="enable name mangling for constants and datatypes", action="store_true")
74+
parser.add_argument("--no-mangle", help="disable name mangling (default)", action="store_true")
75+
76+
args = parser.parse_args()
77+
78+
if args.abi_json:
79+
JSON_PATH = Path(args.abi_json)
80+
if args.mangle_names:
81+
MANGLE_NAMES = True
82+
if args.no_mangle:
83+
MANGLE_NAMES = False
84+
if args.output:
85+
OUTPUT = Path(args.output)
86+
87+
# ================================== Load JSON =================================
88+
with open(JSON_PATH) as f:
89+
abi = json.load(f)
90+
91+
CONSTS = abi["constants"]
92+
CATEGORIES = abi["categories"]
93+
94+
# ==============================================================================
95+
2996
# Populating the `categories` dictionary
30-
for category in consts.categories.values():
97+
for category in CATEGORIES.values():
3198
name = category["name"]
32-
categories[name] = []
33-
for value in consts.consts.values():
99+
categories_dict[name] = []
100+
for value in CONSTS.values():
34101
if value["category"] == name:
35-
categories[name].append(value)
102+
categories_dict[name].append(value)
36103

37104
# ================================== Functions =================================
105+
# TODO: we need to add/fix/figure out the pympistandard's way for properly
106+
# defining callback functions
107+
def cb_declaration(proc_expression):
108+
func_str = str(proc_expression).replace(r"\ldots", "...")
109+
func_str_list = func_str.split()
110+
func_name, arg_1 = func_str_list[2].split("(")
111+
decl_string = f"{' '.join(func_str_list[:2])} ({func_name})({arg_1} {' '.join(func_str_list[3:])};\n"
112+
return decl_string
38113

39114
def output_constant(const, use_enum: bool, mangle_name: bool):
40115
name = const["name"]
@@ -57,7 +132,7 @@ def output_constant(const, use_enum: bool, mangle_name: bool):
57132

58133
# ========================= Manipulate Template Header =========================
59134
lines = []
60-
with open(consts.DIR / "abi.h.in", 'r') as header_in:
135+
with open(DIR / "abi.h.in", 'r') as header_in:
61136
lines = header_in.readlines()
62137

63138
# Match lines that start with `$CATEGORY:`. Any amount of whitespace is allowed
@@ -74,13 +149,13 @@ def output_constant(const, use_enum: bool, mangle_name: bool):
74149
category = category.group(1)
75150
use_enum = False
76151
# Only some values should be in `enums`, otherwise just use `#define`s
77-
if category in consts.ENUM_CATEGORIES:
152+
if category in ENUM_CATEGORIES:
78153
use_enum = True
79154
if use_enum:
80155
output.append("enum {\n")
81156
# Print out each `#define` / assignment for the constants
82-
for constant in categories[category]:
83-
line = output_constant(constant, use_enum, mangle_names)
157+
for constant in categories_dict[category]:
158+
line = output_constant(constant, use_enum, MANGLE_NAMES)
84159
if line is not None:
85160
output.append(line)
86161
if use_enum:
@@ -89,15 +164,6 @@ def output_constant(const, use_enum: bool, mangle_name: bool):
89164
output.append(line)
90165

91166
# ============================= Function Prototypes ============================
92-
# TODO: we need to add/fix/figure out the pympistandard's way for properly
93-
# defining callback functions
94-
def cb_declaration(proc_expression):
95-
func_str = str(proc_expression).replace(r"\ldots", "...")
96-
func_str_list = func_str.split()
97-
func_name, arg_1 = func_str_list[2].split("(")
98-
decl_string = f"{' '.join(func_str_list[:2])} ({func_name})({arg_1} {' '.join(func_str_list[3:])};\n"
99-
return decl_string
100-
101167
std.use_api_version()
102168

103169
output.append("\n")
@@ -134,12 +200,15 @@ def cb_declaration(proc_expression):
134200

135201
# Iterate through all lines and replace datatypes with their internal ABI
136202
# counterparts
137-
if mangle_names:
203+
if MANGLE_NAMES:
138204
for i, line in enumerate(output):
139205
mangled_line = line
140-
for datatype in internal_datatypes:
141-
mangled_line = mangled_line.replace(datatype, f"{datatype}{ABI_INTERNAL}")
206+
for datatype in INTERNAL_DATATYPES:
207+
# Need to include the extra space here or else we'll edit functions
208+
# like "MPI_Group_difference"
209+
datatype_pattern = r"([\( ]?)(" + datatype + r")([; \*]{1})"
210+
mangled_line = re.sub(datatype_pattern, f"\\g<1>\\g<2>{ABI_INTERNAL}\\g<3>", mangled_line)
142211
output[i] = mangled_line
143212

144-
with open(consts.DIR / "abi.h", 'tw') as header_out:
213+
with open(OUTPUT, 'tw') as header_out:
145214
header_out.writelines(output)

ompi/mpi/c/Makefile.am

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -567,17 +567,20 @@ abi.h: $(prototype_sources)
567567
header \
568568
--srcdir $(srcdir) \
569569
$(prototype_sources)
570-
standard_abi/mpi.h: $(prototype_sources)
570+
# Non-mangled version
571+
standard_abi/mpi.h: $(top_srcdir)/docs/mpi-standard-apis.json c_header.py
571572
mkdir -p standard_abi
572-
$(OMPI_V_GEN) $(PYTHON) $(top_srcdir)/ompi/mpi/bindings/bindings.py \
573-
--builddir $(abs_top_builddir) \
574-
--srcdir $(abs_top_srcdir) \
575-
--output $@ \
576-
c \
577-
header \
578-
--srcdir $(srcdir) \
579-
--external \
580-
$(prototype_sources)
573+
$(OMPI_V_GEN) $(PYTHON) c_header.py \
574+
--abi-json $(top_srcdir)/docs/mpi-standard-apis.json \
575+
--output $(top_srcdir)/ompi/mpi/c/standard_abi/mpi.h
576+
577+
# Mangled version
578+
abi.h: $(top_srcdir)/docs/mpi-standard-apis.json c_header.py
579+
$(OMPI_V_GEN) $(PYTHON) c_header.py \
580+
--output $(top_srcdir)/ompi/mpi/c/abi.h \
581+
--abi-json $(top_srcdir)/docs/mpi-standard-apis.json \
582+
--mangle-names
583+
581584
%_abi_generated.c: %.c.in
582585
$(OMPI_V_GEN) $(PYTHON) $(top_srcdir)/ompi/mpi/bindings/bindings.py \
583586
--builddir $(abs_top_builddir) \

0 commit comments

Comments
 (0)