|
78 | 78 | #' For [standalone generated quantities][model-method-generate-quantities] the |
79 | 79 | #' returned list also includes the following components: |
80 | 80 | #' |
| 81 | +#' * `time`: Run time information for the individual processes, with one row in |
| 82 | +#' the `chains` data frame per CSV file. The returned object is the same as for |
| 83 | +#' the [$time()][fit-method-time] method except the total run time can't be |
| 84 | +#' inferred directly from the CSV files (they may have been generated in |
| 85 | +#' parallel) and is therefore `NA`. For CmdStan versions before 2.39 the |
| 86 | +#' individual process times are reported as zero. |
81 | 87 | #' * `generated_quantities`: A [`draws_array`][posterior::draws_array] of |
82 | 88 | #' the generated quantities. |
83 | 89 | #' |
@@ -456,6 +462,7 @@ read_cmdstan_csv <- function(files, |
456 | 462 | } |
457 | 463 | list( |
458 | 464 | metadata = metadata, |
| 465 | + time = list(total = NA_integer_, chains = metadata$time), |
459 | 466 | generated_quantities = draws |
460 | 467 | ) |
461 | 468 | } else if (metadata$method == "pathfinder") { |
@@ -653,6 +660,21 @@ for (method in unavailable_methods_CmdStanFit_CSV) { |
653 | 660 |
|
654 | 661 | # csv reading internals --------------------------------------------------- |
655 | 662 |
|
| 663 | +parse_generated_quantities_time <- function(line) { |
| 664 | + suffix <- "seconds (Generated Quantities)" |
| 665 | + line <- trimws(line) |
| 666 | + if (!startsWith(line, "Elapsed Time:") || !endsWith(line, suffix)) { |
| 667 | + return(NULL) |
| 668 | + } |
| 669 | + time <- trimws(sub(suffix, "", line, fixed = TRUE)) |
| 670 | + time <- trimws(sub("Elapsed Time:", "", time, fixed = TRUE)) |
| 671 | + time <- suppressWarnings(as.double(time)) |
| 672 | + if (is.na(time)) { |
| 673 | + return(NULL) |
| 674 | + } |
| 675 | + time |
| 676 | +} |
| 677 | + |
656 | 678 | #' Reads the sampling arguments and the diagonal of the |
657 | 679 | #' inverse mass matrix from the comments in a CSV file. |
658 | 680 | #' |
@@ -786,6 +808,11 @@ read_csv_metadata <- function(csv_file) { |
786 | 808 | tmp <- gsub("seconds (Total)", "", tmp, fixed = TRUE) |
787 | 809 | tmp <- trimws(gsub(" Elapsed Time: ", "", tmp, fixed = TRUE)) |
788 | 810 | total_time <- as.numeric(tmp) |
| 811 | + } else { |
| 812 | + generated_quantities_time <- parse_generated_quantities_time(tmp) |
| 813 | + if (!is.null(generated_quantities_time)) { |
| 814 | + total_time <- generated_quantities_time |
| 815 | + } |
789 | 816 | } |
790 | 817 | if (!is.null(csv_file_info$method) && |
791 | 818 | csv_file_info$method == "diagnose" && |
@@ -827,6 +854,11 @@ read_csv_metadata <- function(csv_file) { |
827 | 854 | sampling = sampling_time, |
828 | 855 | total = total_time |
829 | 856 | ) |
| 857 | + } else if (csv_file_info$method == "generate_quantities") { |
| 858 | + csv_file_info$time <- data.frame( |
| 859 | + chain_id = csv_file_info$id, |
| 860 | + total = total_time |
| 861 | + ) |
830 | 862 | } |
831 | 863 | csv_file_info$model <- NULL |
832 | 864 | csv_file_info$engaged <- NULL |
|
0 commit comments