Skip to content

fix: Use foreach/doSNOW for restart write.ensemble.configs to restore logger output#4018

Open
S1DDHEY wants to merge 2 commits into
PecanProject:developfrom
S1DDHEY:fix/3581-restart-write-configs-foreach
Open

fix: Use foreach/doSNOW for restart write.ensemble.configs to restore logger output#4018
S1DDHEY wants to merge 2 commits into
PecanProject:developfrom
S1DDHEY:fix/3581-restart-write-configs-foreach

Conversation

@S1DDHEY

@S1DDHEY S1DDHEY commented May 31, 2026

Copy link
Copy Markdown
Contributor

Description

Fixes #3581
Replaces the restart-path parallel dispatch for write.ensemble.configs() in sda.enkf_MultiSite.R from furrr::future_map2() to foreach + doSNOW, matching the existing non-restart code path.

This fixes missing/delayed PEcAn.logger output

Testing

  • Ran module test successfully (0 Failed)
  • Verified worker-side logging from write.ensemble.configs() is emitted by reproducing the “multi-path input with no <samplingspace>” error under foreach/doSNOW (captured via PEcAn.logger::logger.setOutputFile() from the worker).

@mdietze mdietze requested a review from DongchenZ June 1, 2026 13:28

@DongchenZ DongchenZ left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good to me.

@mdietze mdietze enabled auto-merge June 1, 2026 16:46

@infotroph infotroph left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Sorry to jump in after approval, but this looks to me like it will make sda.enkf.multisite stop respecting the run_parallel flag and instead use n-1 cores no matter what the user requests. @DongchenZ am I missing another place the parallel setting gets passed around?

@S1DDHEY

S1DDHEY commented Jun 12, 2026

Copy link
Copy Markdown
Contributor Author

@infotroph sorry for the late reply, this patch would make restart path ignore the control$run_parallel. I also noticed the existing non-restart foreach path already does that. Would you prefer I keep this PR narrow and fix only the restart path, or update both foreach config-writing paths so run_parallel is respected consistently?

@S1DDHEY S1DDHEY requested a review from DongchenZ June 20, 2026 22:45
@infotroph

Copy link
Copy Markdown
Member

existing non-restart foreach path already does that

Good catch. If it's easy to fix in this PR go for it, but not required.

But more importantly for this PR, how sure are you that this actually fixes the issue? I don't see either approach printing to the console:

> f <- function(msg) {
+   Sys.sleep(2)
+   PEcAn.logger::logger.warn(msg)
+   msg
+ }
> library(foreach)
> cl <- parallel::makeCluster(7)
> doSNOW::registerDoSNOW(cl)
> res_foreach <- foreach::foreach(x=LETTERS[1:10]) %dopar% {f(x)}
> parallel::stopCluster(cl)
> foreach::registerDoSEQ()
> 
> future::plan(future::multicore, workers = 7)
> res_furrr <- furrr::future_map(LETTERS[1:10], f)
>

Note that no logger output is shown in either case.

You mentioned using logger.setOutputFile() as part of your test -- can you show a reprex? Unless the SDA process does its own log redirection I doubt most users will be incorporating that into their runs.

@S1DDHEY

S1DDHEY commented Jun 26, 2026

Copy link
Copy Markdown
Contributor Author

@infotroph After digging a bit more, I think you’re right, switching from furrr to foreach/doSNOW alone doesn’t actually prove the issue is fixed. I don’t see the SDA/workflow path doing any explicit capture or replay of worker stderr, so even if the worker emits PEcAn.logger messages, that doesn’t guarantee they show up in the main console in normal runs.

A probable fix seems like it would be to stop relying on worker console output entirely and instead return log messages from each worker as part of the task result, then print them in the parent process after collection. In other words, have the worker return something like list(result = ..., logs = ...), and let the main process emit those logs. That should work regardless of whether the backend is furrr or foreach, and it would avoid depending on backend-specific stdout/stderr behavior.

It wouldn’t be truly live streaming, but it should make the messages reliably visible in normal SDA runs and is a lot easier to reason about and test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The message will not be printed if we run the write.config function inside the future_map.

3 participants