#![deny(unused_variables)]
pub(crate) use clap::{ArgAction, Args, Parser, Subcommand, ValueEnum};
pub(crate) use comfy_table::{Cell, ContentArrangement, Row, Table, presets::UTF8_FULL};
pub(crate) use csv::WriterBuilder;
pub(crate) use faer::Mat as FaerMat;
pub(crate) use faer::Side;
pub(crate) use gam::alo::compute_alo_diagnostics_from_fit;
pub(crate) use gam::estimate::{
AdaptiveRegularizationOptions, BlockRole, ContinuousSmoothnessOrderStatus,
ExternalOptimOptions, ExternalOptimResult, FitOptions, FittedLinkState, ModelSummary,
ParametricTermSummary, PosteriorMeanOptions, PredictInput, SmoothTermSummary, UnifiedFitResult,
compute_continuous_smoothness_order, fit_gam, optimize_external_design, predict_gam,
saved_latent_cloglog_state_from_fit, saved_mixture_state_from_fit, saved_sas_state_from_fit,
};
pub(crate) use gam::families::bms::{
BernoulliMarginalSlopeTermSpec, DeviationBlockConfig, DeviationRuntime, LatentMeasureKind,
LatentZPolicy,
};
pub(crate) use gam::families::survival::latent::latent_hazard_loading;
pub(crate) use gam::families::scale_design::{
build_scale_deviation_operator, build_scale_deviation_transform_design,
infer_non_intercept_start_design, scale_transform_from_payload,
};
pub(crate) use gam::gamlss::{
BinomialLocationScaleTermSpec, BlockwiseTermFitResult, GaussianLocationScaleTermSpec,
};
pub(crate) use gam::generative::{generativespec_from_predict, sampleobservation_replicates};
pub(crate) use gam::hmc::NutsConfig;
pub(crate) use gam::inference::data::{
EncodedDataset as Dataset, UnseenCategoryPolicy,
load_dataset_projected as load_dataset_auto_projected,
load_datasetwith_schema_projected as load_dataset_auto_with_schema_projected,
};
pub(crate) use gam::inference::formula_dsl::{
LinkChoice, LinkFormulaSpec, LinkMode, LinkWiggleFormulaSpec, ParsedFormula, ParsedTerm,
effectivelinkwiggle_formulaspec, formula_rhs_text, parse_formula, parse_link_choice,
parse_matching_auxiliary_formula, parse_surv_interval_response, parse_surv_response,
parsed_term_column_names, require_inverse_link_supports_joint_wiggle,
require_likelihood_spec_supports_joint_wiggle, require_linkchoice_supports_joint_wiggle,
validate_auxiliary_formula_controls, validate_marginal_slope_z_column_exclusion,
};
pub(crate) use gam::inference::model::{
ColumnKindTag, DataSchema, FittedFamily, FittedModel as SavedModel, FittedModelPayload,
MODEL_PAYLOAD_VERSION, ModelKind, PredictModelClass, SavedLatentZNormalization,
load_survival_time_basis_config_from_model,
};
pub(crate) use gam::inference::model_payload_builders::{
BernoulliMarginalSlopeInputs, LatentWindowInputs, LocationScaleInputs, LocationScaleResponse,
LocationScaleWiggle, SavedModelSourceMetadata, SurvivalLocationScaleInputs,
SurvivalMarginalSlopeInputs, SurvivalTimewiggle, SurvivalTimewiggleBeta,
SurvivalTransformationInputs, TransformationNormalInputs,
assemble_bernoulli_marginal_slope_payload, assemble_latent_window_payload,
assemble_location_scale_payload, assemble_residual_cascade_payload,
assemble_spline_scan_payload, assemble_survival_location_scale_payload,
assemble_survival_marginal_slope_payload, assemble_survival_transformation_payload,
assemble_transformation_normal_payload,
};
pub(crate) use gam::inference::predict::input::build_predict_input_for_model;
pub(crate) use gam::inference::predict::linalg::{
PredictionCovarianceBackend, rowwise_local_covariances,
};
pub(crate) use gam::inference::smooth_test::{SmoothTestInput, wood_smooth_test};
pub(crate) use gam::matrix::{DesignMatrix, SymmetricMatrix};
pub(crate) use gam::mixture_link::state_fromspec;
pub(crate) use gam::predict::{
PredictableModel, predict_gam_posterior_meanwith_backend, predict_gamwith_uncertainty,
};
pub(crate) use gam::probability::{normal_cdf, standard_normal_quantile};
pub(crate) use gam::report;
pub(crate) use gam::smooth::{
BoundedCoefficientPriorSpec, LinearCoefficientGeometry, LinearTermSpec, SmoothBasisSpec,
SmoothStructureAnalysis, SmoothTermSpec, SpatialLengthScaleOptimizationOptions,
TermCollectionSpec, analyze_smooth_ownership, build_term_collection_design,
fit_term_collection_forspec, freeze_term_collection_from_design, smooth_term_feature_cols,
};
pub(crate) use gam::smooth_test::SmoothTestScale;
pub(crate) use gam::families::survival::{
PenaltyBlock, PenaltyBlocks, SurvivalMonotonicityPenalty, SurvivalSpec,
survival_event_code_from_value,
};
pub(crate) use gam::families::survival::{
SavedSurvivalTimeBasis, SurvivalBaselineConfig, SurvivalBaselineTarget, SurvivalLikelihoodMode,
SurvivalTimeBasisConfig, SurvivalTimeBuildOutput, add_survival_time_derivative_guard_offset,
baseline_chain_rule_gradient, build_survival_time_basis,
build_survival_time_offsets_for_likelihood, build_time_varying_survival_covariate_template,
center_survival_time_designs_at_anchor, evaluate_survival_time_basis_row,
initial_survival_baseline_config_for_fit, location_scale_uses_probit_survival_baseline,
marginal_slope_baseline_chain_rule_gradient, marginal_slope_baseline_chain_rule_hessian,
normalize_survival_time_pair, optimize_survival_baseline_config_with_gradient,
optimize_survival_baseline_config_with_gradient_only, parse_survival_distribution,
parse_survival_likelihood_mode, parse_survival_time_basis_config, positive_survival_time_seed,
require_structural_survival_time_basis, resolve_survival_marginal_slope_time_anchor_value,
resolve_survival_time_anchor_value, resolved_survival_time_basis_config_from_build,
survival_baseline_targetname, survival_derivative_guard_for_likelihood,
survival_likelihood_modename,
};
pub(crate) use gam::families::survival::location_scale::{
SurvivalCovariateTermBlockTemplate, SurvivalLocationScalePredictInput,
SurvivalLocationScaleTermSpec, TimeBlockInput, predict_survival_location_scale,
project_onto_linear_constraints,
};
pub(crate) use gam::families::survival::marginal_slope::SurvivalMarginalSlopeTermSpec;
pub(crate) use gam::families::survival::predict::{
apply_inverse_link_state_to_fit_result, build_saved_survival_marginal_slope_predictor,
fit_result_from_saved_model_for_prediction, require_saved_survival_likelihood_mode,
resolve_saved_survival_time_columns, resolve_survival_inverse_link_from_saved,
resolve_termspec_for_prediction, saved_baseline_timewiggle_components,
saved_survival_location_scale_fit_result, saved_survival_runtime_baseline_config,
};
pub(crate) use gam::term_builder::{
build_termspec, column_map_with_alias, enable_scale_dimensions, resolve_role_col,
};
pub(crate) use gam::transformation_normal::TransformationNormalConfig;
pub(crate) use gam::types::{
InverseLink, LikelihoodScaleMetadata, LikelihoodSpec, LinkFunction, LogLikelihoodNormalization,
MixtureLinkSpec, ResponseColumnKind, ResponseFamily, SasLinkSpec, StandardLink,
WigglePenaltyConfig,
};
pub(crate) use gam::solver::fit_orchestration::{
BernoulliMarginalSlopeFitRequest, BinomialLocationScaleFitRequest,
DispersionLocationScaleFitRequest, FitConfig, FitRequest, FitResult,
GaussianLocationScaleFitRequest, LatentBinaryFitRequest, LatentSurvivalFitRequest,
LinkWiggleConfig, PreparedSurvivalTimeStack, StandardBinomialWiggleConfig, StandardFitRequest,
SurvivalLocationScaleFitRequest, SurvivalMarginalSlopeFitRequest,
SurvivalTransformationFitRequest, SurvivalTransformationTermSpec,
TransformationNormalFitRequest, WorkflowError, fit_model, prepare_survival_time_stack,
residual_cascade_fast_path, resolve_offset_column, resolve_weight_column,
spline_scan_fast_path,
};
pub(crate) use ndarray::{Array1, Array2, ArrayView1, Axis, array, s};
pub(crate) use rand::{SeedableRng, rngs::StdRng};
pub(crate) use statrs::distribution::{ContinuousCDF, StudentsT};
pub(crate) use std::collections::{BTreeMap, BTreeSet, HashMap};
pub(crate) use std::path::{Path, PathBuf};
pub(crate) use thiserror::Error;
macro_rules! cli_out {
($($t:tt)*) => {{
use std::io::Write as _;
drop(writeln!(std::io::stdout(), $($t)*));
}};
}
macro_rules! cli_err {
($($t:tt)*) => {{
use std::io::Write as _;
drop(writeln!(std::io::stderr(), $($t)*));
}};
}
#[path = "main/cli_args.rs"]
mod cli_args;
#[path = "main/cli_errors.rs"]
mod cli_errors;
use gam::config_resolve;
#[path = "main/dataset_io.rs"]
mod dataset_io;
#[path = "main/family_resolve.rs"]
mod family_resolve;
#[path = "main/model_build.rs"]
mod model_build;
#[path = "main/model_summary.rs"]
mod model_summary;
#[path = "main/prediction_csv.rs"]
mod prediction_csv;
#[path = "main/run_diagnose.rs"]
mod run_diagnose;
#[path = "main/run_fit.rs"]
mod run_fit;
#[path = "main/run_predict.rs"]
mod run_predict;
#[path = "main/run_sample_generate_report.rs"]
mod run_sample_generate_report;
#[path = "main/run_survival.rs"]
mod run_survival;
#[path = "main/smooth_warnings.rs"]
mod smooth_warnings;
pub(crate) use cli_args::*;
pub(crate) use cli_errors::*;
pub(crate) use dataset_io::*;
pub(crate) use family_resolve::*;
pub(crate) use model_build::*;
pub(crate) use model_summary::*;
pub(crate) use prediction_csv::*;
pub(crate) use run_diagnose::*;
pub(crate) use run_fit::*;
pub(crate) use run_predict::*;
pub(crate) use run_sample_generate_report::*;
pub(crate) use run_survival::*;
pub(crate) use smooth_warnings::*;
const HARD_EXIT: fn(i32) -> ! = std::process::exit;
const CLI_WORKER_STACK_SIZE: usize = 512 << 20;
fn main() {
gam::init_parallelism();
gam::process_monitor::start();
let worker = std::thread::Builder::new()
.name("gam-cli".to_string())
.stack_size(CLI_WORKER_STACK_SIZE)
.spawn(run)
.expect("spawn gam CLI worker thread");
let result = match worker.join() {
Ok(command_result) => command_result,
Err(_) => {
drop(std::io::Write::flush(&mut std::io::stdout()));
drop(std::io::Write::flush(&mut std::io::stderr()));
HARD_EXIT(1);
}
};
if let Err(e) = result {
cli_err!("error: {e}");
if let Some(advice) = e.advice() {
cli_err!("help: {advice}");
}
drop(std::io::Write::flush(&mut std::io::stdout()));
drop(std::io::Write::flush(&mut std::io::stderr()));
HARD_EXIT(1);
}
drop(std::io::Write::flush(&mut std::io::stdout()));
drop(std::io::Write::flush(&mut std::io::stderr()));
HARD_EXIT(0);
}
fn run() -> CliResult<()> {
let cli = Cli::parse();
gam::visualizer::init_logging();
log::info!(
"[STAGE] runtime threads | rayon_current_num_threads={} | std_available_parallelism={}",
rayon::current_num_threads(),
std::thread::available_parallelism()
.map(|n| n.get())
.unwrap_or(0),
);
match cli.command {
Command::Fit(args) => run_fit(args).map_err(CliError::from),
Command::Report(args) => run_report(args).map_err(CliError::from),
Command::Predict(args) => run_predict(args).map_err(CliError::from),
Command::Diagnose(args) => run_diagnose(args).map_err(CliError::from),
Command::Sample(args) => run_sample(args).map_err(CliError::from),
Command::Generate(args) => run_generate(args).map_err(CliError::from),
}
}
#[cfg(test)]
#[path = "../tests/src_modules/cli_tests.rs"]
mod cli_tests;