Skip to content

Commit 6e66b6e

Browse files
authored
Merge pull request #112 from cindytsai/Refactor
All done!!! FINALLY!
2 parents 7e068dc + 5b5567e commit 6e66b6e

File tree

129 files changed

+20497
-11369
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

129 files changed

+20497
-11369
lines changed

.clang-format

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,49 @@
11
---
22
BasedOnStyle: Google
3-
AccessModifierOffset: '-4'
3+
AccessModifierOffset: -1
44
AlignAfterOpenBracket: Align
5-
AlignConsecutiveMacros: 'true'
5+
AlignConsecutiveMacros: true
66
AlignEscapedNewlines: Right
77
AlignOperands: 'true'
8-
AlignTrailingComments: 'true'
9-
AllowAllConstructorInitializersOnNextLine: 'true'
10-
AllowShortCaseLabelsOnASingleLine: 'false'
11-
AlwaysBreakBeforeMultilineStrings: 'false'
8+
AlignTrailingComments: true
9+
AllowAllArgumentsOnNextLine: true
10+
AllowAllConstructorInitializersOnNextLine: true
11+
AllowShortCaseLabelsOnASingleLine: false
12+
AlwaysBreakBeforeMultilineStrings: false
1213
AlwaysBreakTemplateDeclarations: 'Yes'
14+
BinPackArguments: false
15+
BinPackParameters: 'true'
1316
BreakBeforeBraces: Attach
17+
BreakBeforeTernaryOperators: true
1418
BreakConstructorInitializers: BeforeColon
1519
BreakInheritanceList: AfterColon
16-
ColumnLimit: '120'
20+
ColumnLimit: 90
1721
CommentPragmas: '''^ *'''
18-
CompactNamespaces: 'false'
19-
IndentCaseLabels: 'true'
22+
CompactNamespaces: false
23+
ConstructorInitializerAllOnOneLineOrOnePerLine: true
24+
DerivePointerAlignment: false
25+
IndentCaseLabels: true
2026
IndentPPDirectives: None
21-
IndentWidth: '4'
22-
KeepEmptyLinesAtTheStartOfBlocks: 'false'
27+
IndentWidth: 2
28+
KeepEmptyLinesAtTheStartOfBlocks: false
2329
Language: Cpp
24-
DerivePointerAlignment: false
25-
ReflowComments: 'true'
26-
SpaceAfterCStyleCast: 'false'
27-
SpaceAfterLogicalNot: 'false'
28-
SpaceAfterTemplateKeyword: 'false'
29-
SpaceBeforeAssignmentOperators: 'true'
30-
SpaceBeforeCtorInitializerColon: 'true'
31-
SpaceBeforeInheritanceColon: 'true'
30+
ReflowComments: true
31+
SpaceAfterCStyleCast: false
32+
SpaceAfterLogicalNot: false
33+
SpaceAfterTemplateKeyword: false
34+
SpaceBeforeAssignmentOperators: true
35+
SpaceBeforeCtorInitializerColon: true
36+
SpaceBeforeInheritanceColon: true
3237
SpaceBeforeParens: ControlStatements
33-
SpaceBeforeRangeBasedForLoopColon: 'true'
34-
SpaceInEmptyParentheses: 'false'
35-
SpacesBeforeTrailingComments: '2'
36-
SpacesInAngles: 'false'
37-
SpacesInCStyleCastParentheses: 'false'
38-
SpacesInContainerLiterals: 'false'
39-
SpacesInParentheses: 'false'
40-
SpacesInSquareBrackets: 'false'
41-
Standard: Cpp11
38+
SpaceBeforeRangeBasedForLoopColon: true
39+
SpaceInEmptyParentheses: false
40+
SpacesBeforeTrailingComments: 2
41+
SpacesInAngles: false
42+
SpacesInCStyleCastParentheses: false
43+
SpacesInContainerLiterals: false
44+
SpacesInParentheses: false
45+
SpacesInSquareBrackets: false
46+
Standard: c++14
4247
UseTab: Never
4348

4449
...

.github/Notes.md

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
# GitHub Action
22

3-
## Usage of Each Folder
3+
## File Structure
44
- **tests**: Store test related files.
55
- Test file will be run as inline python script in `libyt/example.cpp`. File name ends with `Test`.
66
- **tools**: Miscellaneous.
77
- **workflows**: Store GitHub Action yaml script.
88

9-
## Tests
9+
## Workflows
1010

11-
### DataIO
12-
- **Workflows**: `.github/workflows/build-test.yml`
13-
- **Test File**: `.github/tests/DataIOTest.py`
14-
- **Description**:
15-
- Check if `libyt/example` can successfully run in fake serial (`mpirun -np 1`) and in parallel using `mpirun`.
16-
- Check if data read by `libyt` is the same as data original in C++ array.
11+
- `cmake-build-test.yml`: Build different options of libyt on different os.
12+
- `example-test-run.yml`: Make sure the AMR example can run in parallel and in serial modes.
13+
- `unit-test.yml`: Run unit tests. Since some of the units have MPI coupled in them, we need to run the tests in parallel mode and in serial mode. For parallel mode, `openmpi` and `mpich` are tested. For serial mode, `Python3.7` ~ `Python3.14` are tested. All of them have a combination with `-DUSE_PYBIND11=ON` and `-DUSE_PYBIND11=OFF` options.
14+
- `memory-profile.yml`: Run memory profiling tests using valgrind.

.github/tests/test-DataIO/DataIOTest.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
import yt
22
import yt_libyt
3-
from mpi4py import MPI
43
import pandas as pd
54
import numpy as np
65

76
yt.enable_parallelism()
87
step = 0
9-
comm = MPI.COMM_WORLD
10-
myrank = comm.Get_rank()
8+
9+
try:
10+
from mpi4py import MPI
11+
comm = MPI.COMM_WORLD
12+
myrank = comm.Get_rank()
13+
except ImportError:
14+
myrank = 0
1115

1216
class DataIOTestFailed(Exception):
1317
"""
@@ -69,7 +73,7 @@ def test_function():
6973
# Compare them, if bigger than criteria, raise an error
7074
diff = np.sum(np.absolute(sim_data - data_io)) / (dimensions[0] * dimensions[1] * dimensions[2])
7175
if diff > DataIOTestFailed.criteria:
72-
err_msg = "On MPI rank {}, step {}, density grid (id={}) is different from simulation data {}.\n" \
76+
err_msg = "On rank {}, step {}, density grid (id={}) is different from simulation data {}.\n" \
7377
"DataIOTest FAILED.\n".format("%d" % myrank, "%d" % step, "%d" % gid, "%.10e" % diff)
7478
raise DataIOTestFailed(err_msg)
7579

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import os
2+
import argparse
3+
4+
class Bcolors:
5+
HEADER = '\033[95m'
6+
OKBLUE = '\033[94m'
7+
OKCYAN = '\033[96m'
8+
OKGREEN = '\033[92m'
9+
WARNING = '\033[93m'
10+
FAIL = '\033[91m'
11+
ENDC = '\033[0m'
12+
BOLD = '\033[1m'
13+
UNDERLINE = '\033[4m'
14+
15+
def combine_detailed_snapshot(filebase: str, combined_filename: str, mpi_rank: int, iter_total: int):
16+
"""combined_detailed_snapshot
17+
Combined individual detailed snapshots dumped by valgrind,
18+
so that it can be visualized in massif-visualizer in a time series.
19+
The time series starts at t = 0.
20+
"""
21+
22+
snapshot_flag = """#-----------\nsnapshot={}\n#-----------\n"""
23+
combined_filename_suffix = ".mem_prof"
24+
25+
# make sure the combined_filename ends with .mem_prof
26+
if not combined_filename.endswith(combined_filename_suffix):
27+
combined_filename += combined_filename_suffix
28+
29+
# make sure the file does not exist
30+
if os.path.exists(combined_filename):
31+
print(f"{Bcolors.FAIL}File {combined_filename} already exists {Bcolors.ENDC}")
32+
raise "File already exists"
33+
34+
# write the combined file
35+
with open(combined_filename, "a") as f_combined:
36+
37+
for t in range(iter_total):
38+
39+
# read raw file
40+
filename = filebase.format(mpi_rank, t)
41+
with open(filename, "r") as f:
42+
raw = f.read()
43+
print(f"Reading file {Bcolors.WARNING} {filename} {Bcolors.ENDC} ... done")
44+
45+
# ignore the heading in the file except the first one,
46+
# and we also need to append our own flag
47+
if t != 0:
48+
# write the snapshot flag
49+
f_combined.write(snapshot_flag.format(t))
50+
51+
# ignore the heading and the snapshot flag
52+
pos = raw.find(snapshot_flag.format(0))
53+
pos = pos + len(snapshot_flag.format(0))
54+
f_combined.write(raw[pos:-1])
55+
f_combined.write("\n")
56+
57+
else:
58+
f_combined.write(raw)
59+
60+
print(f"Writing file to {Bcolors.OKGREEN} {combined_filename} {Bcolors.ENDC} ... done")
61+
62+
if __name__ == "__main__":
63+
64+
parser = argparse.ArgumentParser(description="Combine detailed snapshots dumped by valgrind")
65+
parser.add_argument('--tag', metavar='tag', type=str, nargs=1,
66+
help='Tag, e.g., "BeforeFree_rank0_time0.mem_prof" has tag "BeforeFree"')
67+
parser.add_argument('--mpi_size', metavar='mpi_size', type=int, nargs=1,
68+
help='MPI size')
69+
parser.add_argument('--total_time_steps', metavar='time_steps', type=int, nargs=1,
70+
help='Total number of time steps')
71+
args = parser.parse_args()
72+
73+
# Call combine_detailed_snapshot
74+
file_base_name = args.tag[0] + "_rank{}_time{}.mem_prof"
75+
combined_file_name = args.tag[0] + "_rank{}.mem_prof"
76+
77+
for r in range(args.mpi_size[0]):
78+
combine_detailed_snapshot(file_base_name, combined_file_name.format(r), r, args.total_time_steps[0])
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import os
2+
import argparse
3+
4+
5+
class Bcolors:
6+
HEADER = '\033[95m'
7+
OKBLUE = '\033[94m'
8+
OKCYAN = '\033[96m'
9+
OKGREEN = '\033[92m'
10+
WARNING = '\033[93m'
11+
FAIL = '\033[91m'
12+
ENDC = '\033[0m'
13+
BOLD = '\033[1m'
14+
UNDERLINE = '\033[4m'
15+
16+
17+
def extract_value_from_file(folder: str or None, filename: str, attribute: str) -> dict:
18+
"""extract_value_from_file
19+
Assume attribute in a file is in a format 'attribute=value'.
20+
"""
21+
22+
file_full_name = filename if folder is None else os.path.join(folder, filename)
23+
24+
# make sure file exist and read the file
25+
if not os.path.exists(file_full_name):
26+
print(f"{Bcolors.FAIL}File {file_full_name} does not exist {Bcolors.ENDC}")
27+
raise "No such file"
28+
with open(file_full_name, "r") as f:
29+
raw = f.read()
30+
print(f"Reading file {Bcolors.WARNING} {file_full_name} {Bcolors.ENDC} ... done")
31+
32+
# find all the matching attribute
33+
found = -1
34+
extract_value = []
35+
while True:
36+
# find matching attributes
37+
found = raw.find(attribute, found + 1)
38+
if found < 0:
39+
break
40+
41+
found_newline = raw.find("\n", found)
42+
extract_value.append(int(raw[found + len(attribute) + 1: found_newline]))
43+
44+
results = dict()
45+
results[attribute] = extract_value
46+
results[attribute + "_diff"] = [extract_value[i] - extract_value[i - 1] for i in range(1, len(extract_value))]
47+
print(f"Extracting attribute {Bcolors.OKGREEN} {attribute} {Bcolors.ENDC} in {file_full_name} ... done")
48+
49+
return results
50+
51+
if __name__ == "__main__":
52+
53+
parser = argparse.ArgumentParser(description="Combine detailed snapshots dumped by valgrind")
54+
parser.add_argument('--title', metavar='title', type=str, nargs=1,
55+
help='Title')
56+
parser.add_argument('--folder', metavar='folder', type=str, nargs=1,
57+
help='Folder where the files are stored. (optional)')
58+
parser.add_argument('--tags', metavar='tags', type=str, nargs='*',
59+
help='A list of tags, e.g., "BeforeFree_rank0.mem_prof" has tag "BeforeFree"')
60+
parser.add_argument('--attr', metavar='attr', type=str, nargs=1,
61+
help='Attribute to extract in valgrind massif dump.')
62+
parser.add_argument('--mpi_size', metavar='mpi_size', type=int, nargs=1,
63+
help='MPI size')
64+
parser.add_argument('--output_filename', metavar='output_filename', type=str, nargs=1,
65+
help='Output to file.')
66+
args = parser.parse_args()
67+
68+
# Extract value and write to file
69+
with open(args.output_filename[0], "a") as f:
70+
f.write("#### " + args.title[0] + "\n\n")
71+
for tag in args.tags:
72+
for r in range(args.mpi_size[0]):
73+
filename = tag + "_rank{}.mem_prof".format(r)
74+
if args.folder is not None:
75+
attr_value = extract_value_from_file(args.folder[0], filename, args.attr[0])
76+
else:
77+
attr_value = extract_value_from_file(None, filename, args.attr[0])
78+
79+
for key in attr_value:
80+
with open(args.output_filename[0], "a") as f:
81+
f.write("**{}({}_rank{})**: ".format(key, tag, r) + str(attr_value[key]) + "\n")
82+
with open(args.output_filename[0], "a") as f:
83+
f.write("\n---\n\n")

0 commit comments

Comments
 (0)