Skip to content

Commit 7acff8d

Browse files
committed
Restructure output directory
And don't use `atmos.p.output_dir` The output structure looks like this: ``` coupler_output_dir_amip/ ├── checkpoints │ └── checkpoints for the various models ├── output_0000/ │ ├── atmos/ │ │ └── output of the atmos model │ └── ocean/ │ └── output of the ocean model ├── output_0001/ │ └── ... component model outputs in their folders ... ├── output_0002/ │ └── ... component model outputs in their folders ... └── output_active -> output_0002/ ```
1 parent 4f0169a commit 7acff8d

File tree

4 files changed

+57
-34
lines changed

4 files changed

+57
-34
lines changed

Project.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Artifacts = "56f22d72-fd6d-98f1-02f0-08ddc0907c33"
88
ClimaComms = "3a4d1b5c-c61d-41fd-a00a-5873ba7a1b0d"
99
ClimaCore = "d414da3d-4745-48bb-8d80-42e94e092884"
1010
ClimaCoreTempestRemap = "d934ef94-cdd4-4710-83d6-720549644b70"
11+
ClimaUtilities = "b3f4f4ca-9299-4f7f-bd9b-81e1242a7513"
1112
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
1213
JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819"
1314
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
@@ -22,6 +23,7 @@ Artifacts = "1"
2223
ClimaComms = "0.5.6, 0.6"
2324
ClimaCore = "0.14.19"
2425
ClimaCoreTempestRemap = "0.3"
26+
ClimaUtilities = "0.1.14"
2527
Dates = "1"
2628
JLD2 = "0.4, 0.5"
2729
Logging = "1"

experiments/ClimaEarth/components/atmosphere/climaatmos.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ FluxCalculator.get_surface_params(sim::ClimaAtmosSimulation) = CAP.surface_fluxe
293293
### ClimaAtmos.jl model-specific functions (not explicitly required by ClimaCoupler.jl)
294294
###
295295
"""
296-
get_atmos_config_dict(coupler_dict::Dict, job_id::String)
296+
get_atmos_config_dict(coupler_dict::Dict, job_id::String, atmos_output_dir)
297297
298298
Returns the specified atmospheric configuration (`atmos_config`) overwitten by arguments
299299
in the coupler dictionary (`config_dict`).
@@ -313,7 +313,7 @@ The TOML parameter file to use is chosen using the following priority:
313313
If a coupler TOML file is provided, it is used. Otherwise we use an atmos TOML
314314
file if it's provided. If neither is provided, we use a default coupler TOML file.
315315
"""
316-
function get_atmos_config_dict(coupler_dict::Dict, job_id::String)
316+
function get_atmos_config_dict(coupler_dict::Dict, job_id::String, atmos_output_dir)
317317
atmos_config_file = coupler_dict["atmos_config_file"]
318318
atmos_config_repo = coupler_dict["atmos_config_repo"]
319319
# override default or specified configs with coupler arguments, and set the correct atmos config_file
@@ -357,7 +357,7 @@ function get_atmos_config_dict(coupler_dict::Dict, job_id::String)
357357
end
358358

359359
# Specify atmos output directory to be inside the coupler output directory
360-
atmos_output_dir = joinpath(coupler_dict["coupler_output_dir"], job_id, "clima_atmos")
360+
atmos_config["output_dir_style"] = "RemovePreexisting"
361361
atmos_config["output_dir"] = atmos_output_dir
362362

363363
# Access extra atmosphere diagnostics from coupler so we can rename for atmos code

experiments/ClimaEarth/run_amip.jl

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -126,30 +126,31 @@ add_extra_diagnostics!(config_dict)
126126
plot_diagnostics,
127127
) = get_coupler_args(config_dict)
128128

129+
#=
130+
### I/O Directory Setup `setup_output_dirs` returns `dir_paths.output =
131+
COUPLER_OUTPUT_DIR`, which is the directory where the output of the simulation
132+
will be saved, `dir_paths.artifacts` is the directory where the plots (from
133+
postprocessing and the conservation checks) of the simulation will be saved,
134+
#and `dir_paths.checkpoints`, where restart files are saved.
135+
=#
136+
137+
COUPLER_OUTPUT_DIR = joinpath(output_dir_root, job_id)
138+
dir_paths = Utilities.setup_output_dirs(output_dir = COUPLER_OUTPUT_DIR, comms_ctx = comms_ctx)
139+
@info "Coupler output directory $(dir_paths.output)"
140+
@info "Coupler artifacts directory $(dir_paths.artifacts)"
141+
@info "Coupler checkpoint directory $(dir_paths.checkpoints)"
142+
129143
## get component model dictionaries (if applicable)
130144
## Note this step must come after parsing the coupler config dictionary, since
131145
## some parameters are passed from the coupler config to the component model configs
132-
atmos_config_dict = get_atmos_config_dict(config_dict, job_id)
146+
atmos_output_dir = joinpath(dir_paths.output, "clima_atmos")
147+
atmos_config_dict = get_atmos_config_dict(config_dict, job_id, atmos_output_dir)
133148
(; dt_rad, output_default_diagnostics) = get_atmos_args(atmos_config_dict)
134149

135150
## set unique random seed if desired, otherwise use default
136151
Random.seed!(random_seed)
137152
@info "Random seed set to $(random_seed)"
138153

139-
tspan = (t_start, t_end)
140-
141-
#=
142-
### I/O Directory Setup
143-
`Utilities.setup_output_dirs` returns `dir_paths.output = COUPLER_OUTPUT_DIR`, which is the directory where the output of the simulation will be saved, and `dir_paths.artifacts` is the directory where
144-
the plots (from postprocessing and the conservation checks) of the simulation will be saved. `dir_paths.regrid` is the directory where the regridding
145-
temporary files will be saved.
146-
=#
147-
148-
COUPLER_OUTPUT_DIR = joinpath(output_dir_root, job_id)
149-
dir_paths = Utilities.setup_output_dirs(output_dir = COUPLER_OUTPUT_DIR, comms_ctx = comms_ctx)
150-
@info "Coupler output directory $(dir_paths.output)"
151-
@info "Coupler artifacts directory $(dir_paths.artifacts)"
152-
153154
#=
154155
## Data File Paths
155156
=#
@@ -855,13 +856,12 @@ if ClimaComms.iamroot(comms_ctx)
855856

856857
# define variable names and output directories for each diagnostic
857858
amip_short_names_atmos = ["ta", "ua", "hus", "clw", "pr", "ts", "toa_fluxes_net"]
858-
output_dir_atmos = atmos_sim.integrator.p.output_dir
859859
amip_short_names_coupler = ["F_turb_energy"]
860860
output_dir_coupler = dir_paths.output
861861

862862
# Check if all output variables are available in the specified directories
863863
make_diagnostics_plots(
864-
output_dir_atmos,
864+
atmos_output_dir,
865865
dir_paths.artifacts,
866866
short_names = amip_short_names_atmos,
867867
output_prefix = "atmos_",
@@ -877,16 +877,15 @@ if ClimaComms.iamroot(comms_ctx)
877877
# Check this because we only want monthly data for making plots
878878
if t_end > 84600 * 31 * 3 && output_default_diagnostics
879879
include("leaderboard/leaderboard.jl")
880-
diagnostics_folder_path = atmos_sim.integrator.p.output_dir
881880
leaderboard_base_path = dir_paths.artifacts
882-
compute_leaderboard(leaderboard_base_path, diagnostics_folder_path)
881+
compute_leaderboard(leaderboard_base_path, atmos_output_dir)
883882
end
884883
end
885884
## plot extra atmosphere diagnostics if specified
886885
if plot_diagnostics
887886
@info "Plotting diagnostics"
888887
include("user_io/diagnostics_plots.jl")
889-
make_diagnostics_plots(atmos_sim.integrator.p.output_dir, dir_paths.artifacts)
888+
make_diagnostics_plots(atmos_output_dir, dir_paths.artifacts)
890889
end
891890

892891
## plot all model states and coupler fields (useful for debugging)

src/Utilities.jl

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import Artifacts
1010
import ClimaComms
1111
import ClimaCore as CC
1212
import Logging
13+
import ClimaUtilities.OutputPathGenerator: generate_output_path
1314

1415
export swap_space!, get_device, get_comms_context, show_memory_usage, setup_output_dirs, time_to_seconds
1516

@@ -100,33 +101,52 @@ Create output directories for the experiment. If `comms_ctx` is provided, only t
100101
By default, the regrid directory is created as a temporary directory inside the output directory,
101102
and the artifacts directory is created inside the output directory with the name `artifacts/`.
102103
104+
`ClimaUtilities.OutputPathGenerator` is used so that simulations can be re-run and re-started.
105+
The output path looks like:
106+
```
107+
coupler_output_dir_amip/
108+
├── checkpoints
109+
│ └── checkpoints for the various models
110+
├── artifacts
111+
│ └── plots produced by the postporcessing step
112+
├── output_0000/
113+
│ ├── atmos/
114+
│ │ └── output of the atmos model
115+
│ └── ocean/
116+
│ └── output of the ocean model
117+
├── output_0001/
118+
│ └── ... component model outputs in their folders ...
119+
├── output_0002/
120+
│ └── ... component model outputs in their folders ...
121+
└── output_active -> output_0002/
122+
```
123+
103124
# Arguments
104125
- `output_dir::String`: The directory where the output files will be stored. Default is the current directory.
105126
- `regrid_dir::String`: The directory where the regridded files will be stored. Default is `output_dir/regrid_tmp/`.
127+
- `checkpoint_dir::String`: The directory where the checkpoint files will be stored. Default is `output_dir/checkpoints/`.
106128
- `artifacts_dir::String`: The directory where the artifacts will be stored. Default is `output_dir/artifacts/`.
107129
- `comms_ctx::Union{Nothing, ClimaComms.AbstractCommsContext}`: The communicator context. If provided, only the root process will create the directories.
108130
109131
# Returns
110132
- A tuple with the paths to the output, regrid, and artifacts directories.
111133
"""
112-
function setup_output_dirs(; output_dir = nothing, artifacts_dir = nothing, comms_ctx)
113-
if output_dir === nothing
114-
output_dir = "."
115-
end
116-
if artifacts_dir === nothing
117-
artifacts_dir = joinpath(output_dir, "artifacts")
118-
end
119-
120-
@info(output_dir)
134+
function setup_output_dirs(;
135+
output_dir = pwd(),
136+
artifacts_dir = joinpath(output_dir, "artifacts"),
137+
checkpoints_dir = joinpath(output_dir, "checkpoints"),
138+
comms_ctx,
139+
)
140+
output_dir = generate_output_path(output_dir)
121141
regrid_dir = nothing
122142
if ClimaComms.iamroot(comms_ctx)
123-
mkpath(output_dir)
124143
mkpath(artifacts_dir)
144+
mkpath(checkpoints_dir)
125145
regrid_dir = mktempdir(output_dir, prefix = "regrid_tmp_")
126146
end
127147
regrid_dir = ClimaComms.bcast(comms_ctx, regrid_dir)
128148

129-
return (; output = output_dir, artifacts = artifacts_dir, regrid = regrid_dir)
149+
return (; output = output_dir, artifacts = artifacts_dir, regrid = regrid_dir, checkpoints = checkpoints_dir)
130150
end
131151

132152
"""
@@ -152,4 +172,6 @@ function time_to_seconds(s::String)
152172
end
153173
error("Uncaught case in computing time from given string.")
154174
end
175+
176+
155177
end # module

0 commit comments

Comments
 (0)