Skip to content

Commit 532c963

Browse files
committed
Remove remaining deprecations, very old cmdstan version checks
1 parent 58ce09e commit 532c963

16 files changed

+175
-296
lines changed

cmdstanpy/cmdstan_args.py

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import numpy as np
1111
from numpy.random import default_rng
1212

13-
from cmdstanpy.utils import cmdstan_path, cmdstan_version_before, get_logger
13+
from cmdstanpy.utils import get_logger
1414

1515
OptionalPath = str | os.PathLike | None
1616

@@ -748,15 +748,6 @@ def validate(self) -> None:
748748
'Argument "sig_figs" must be an integer between 1 and 18,'
749749
' found {}'.format(self.sig_figs)
750750
)
751-
# TODO: remove at some future release
752-
if cmdstan_version_before(2, 25):
753-
self.sig_figs = None
754-
get_logger().warning(
755-
'Argument "sig_figs" invalid for CmdStan versions < 2.25, '
756-
'using version %s in directory %s',
757-
os.path.basename(cmdstan_path()),
758-
os.path.dirname(cmdstan_path()),
759-
)
760751

761752
if self.seed is None:
762753
rng = default_rng()

cmdstanpy/compilation.py

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
EXTENSION,
1818
cmdstan_path,
1919
cmdstan_version,
20-
cmdstan_version_before,
2120
stanc_path,
2221
)
2322
from cmdstanpy.utils.command import do_command
@@ -463,32 +462,13 @@ def format_stan_file(
463462
)
464463

465464
if canonicalize:
466-
if cmdstan_version_before(2, 29):
467-
if isinstance(canonicalize, bool):
468-
cmd.append('--print-canonical')
469-
else:
470-
raise ValueError(
471-
"Invalid arguments passed for current CmdStan"
472-
+ " version({})\n".format(
473-
cmdstan_version() or "Unknown"
474-
)
475-
+ "--canonicalize requires 2.29 or higher"
476-
)
465+
if isinstance(canonicalize, str):
466+
cmd.append('--canonicalize=' + canonicalize)
467+
elif isinstance(canonicalize, Iterable):
468+
cmd.append('--canonicalize=' + ','.join(canonicalize))
477469
else:
478-
if isinstance(canonicalize, str):
479-
cmd.append('--canonicalize=' + canonicalize)
480-
elif isinstance(canonicalize, Iterable):
481-
cmd.append('--canonicalize=' + ','.join(canonicalize))
482-
else:
483-
cmd.append('--print-canonical')
484-
485-
# before 2.29, having both --print-canonical
486-
# and --auto-format printed twice
487-
if not (cmdstan_version_before(2, 29) and canonicalize):
488-
cmd.append('--auto-format')
470+
cmd.append('--print-canonical')
489471

490-
if not cmdstan_version_before(2, 29):
491-
cmd.append(f'--max-line-length={max_line_length}')
492472
elif max_line_length != 78:
493473
raise ValueError(
494474
"Invalid arguments passed for current CmdStan version"

cmdstanpy/install_cxx_toolchain.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ def get_toolchain_name() -> str:
236236
return ''
237237

238238

239-
# TODO(2.0): drop 3.5 support
239+
# TODO(2.0): consider something other than RTools
240240
def get_url(version: str) -> str:
241241
"""Return URL for toolchain."""
242242
url = ''

cmdstanpy/model.py

Lines changed: 29 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from concurrent.futures import ThreadPoolExecutor
1414
from io import StringIO
1515
from multiprocessing import cpu_count
16-
from typing import Any, Callable, Mapping, Sequence, TypeVar
16+
from typing import Any, Callable, Mapping, Sequence
1717

1818
import numpy as np
1919
import pandas as pd
@@ -37,6 +37,7 @@
3737
CmdStanMLE,
3838
CmdStanPathfinder,
3939
CmdStanVB,
40+
PrevFit,
4041
RunSet,
4142
from_csv,
4243
)
@@ -56,7 +57,6 @@
5657
from . import progress as progbar
5758

5859
OptionalPath = str | os.PathLike | None
59-
Fit = TypeVar('Fit', CmdStanMCMC, CmdStanMLE, CmdStanVB)
6060

6161

6262
class CmdStanModel:
@@ -164,9 +164,7 @@ def __init__(
164164
)
165165

166166
# try to detect models w/out parameters, needed for sampler
167-
if (not cmdstan_version_before(2, 27)) and cmdstan_version_before(
168-
2, 36
169-
):
167+
if cmdstan_version_before(2, 36):
170168
model_info = self.src_info()
171169
if 'parameters' in model_info:
172170
self._fixed_param |= len(model_info['parameters']) == 0
@@ -238,7 +236,7 @@ def src_info(self) -> dict[str, Any]:
238236
If stanc is older than 2.27 or if the stan
239237
file cannot be found, returns an empty dictionary.
240238
"""
241-
if self.stan_file is None or cmdstan_version_before(2, 27):
239+
if self.stan_file is None:
242240
return {}
243241
return compilation.src_info(str(self.stan_file), self._stanc_options)
244242

@@ -404,12 +402,6 @@ def optimize(
404402
jacobian=jacobian,
405403
)
406404

407-
if jacobian and cmdstan_version_before(2, 32, self.exe_info()):
408-
raise ValueError(
409-
"Jacobian adjustment for optimization is only supported "
410-
"in CmdStan 2.32 and above."
411-
)
412-
413405
with (
414406
temp_single_json(data) as _data,
415407
temp_inits(inits, allow_multiple=False) as _inits,
@@ -734,34 +726,23 @@ def sample(
734726
if chains == 1:
735727
force_one_process_per_chain = True
736728

737-
if (
738-
force_one_process_per_chain is None
739-
and not cmdstan_version_before(2, 28, info_dict)
740-
and stan_threads == 'true'
741-
):
729+
if force_one_process_per_chain is None and stan_threads == 'true':
742730
one_process_per_chain = False
743731
num_threads = parallel_chains * num_threads
744732
parallel_procs = 1
745733
if force_one_process_per_chain is False:
746-
if not cmdstan_version_before(2, 28, info_dict):
747-
one_process_per_chain = False
748-
num_threads = parallel_chains * num_threads
749-
parallel_procs = 1
750-
if stan_threads == 'false':
751-
get_logger().warning(
752-
'Stan program not compiled for threading, '
753-
'process will run chains sequentially. '
754-
'For multi-chain parallelization, recompile '
755-
'the model with argument '
756-
'"cpp_options={\'STAN_THREADS\':\'TRUE\'}.'
757-
)
758-
else:
734+
one_process_per_chain = False
735+
num_threads = parallel_chains * num_threads
736+
parallel_procs = 1
737+
if stan_threads == 'false':
759738
get_logger().warning(
760-
'Installed version of CmdStan cannot multi-process '
761-
'chains, will run %d processes. '
762-
'Run "install_cmdstan" to upgrade to latest version.',
763-
chains,
739+
'Stan program not compiled for threading, '
740+
'process will run chains sequentially. '
741+
'For multi-chain parallelization, recompile '
742+
'the model with argument '
743+
'"cpp_options={\'STAN_THREADS\':\'TRUE\'}.'
764744
)
745+
765746
os.environ['STAN_NUM_THREADS'] = str(num_threads)
766747

767748
if chain_ids is None:
@@ -958,15 +939,15 @@ def sample(
958939
def generate_quantities(
959940
self,
960941
data: Mapping[str, Any] | str | os.PathLike | None = None,
961-
previous_fit: Fit | list[str] | None = None,
942+
previous_fit: PrevFit | list[str] | None = None,
962943
seed: int | None = None,
963944
gq_output_dir: OptionalPath = None,
964945
sig_figs: int | None = None,
965946
show_console: bool = False,
966947
refresh: int | None = None,
967948
time_fmt: str = "%Y%m%d%H%M%S",
968949
timeout: float | None = None,
969-
) -> CmdStanGQ[Fit]:
950+
) -> CmdStanGQ[PrevFit]:
970951
"""
971952
Run CmdStan's generate_quantities method which runs the generated
972953
quantities block of a model given an existing sample.
@@ -1032,7 +1013,16 @@ def generate_quantities(
10321013
:return: CmdStanGQ object
10331014
"""
10341015

1035-
if isinstance(previous_fit, (CmdStanMCMC, CmdStanMLE, CmdStanVB)):
1016+
if isinstance(
1017+
previous_fit,
1018+
(
1019+
CmdStanMCMC,
1020+
CmdStanMLE,
1021+
CmdStanVB,
1022+
CmdStanLaplace,
1023+
CmdStanPathfinder,
1024+
),
1025+
):
10361026
fit_object = previous_fit
10371027
fit_csv_files = previous_fit.runset.csv_files
10381028
elif isinstance(previous_fit, list):
@@ -1042,7 +1032,7 @@ def generate_quantities(
10421032
)
10431033
try:
10441034
fit_csv_files = previous_fit
1045-
fit_object: Fit = from_csv(fit_csv_files) # type: ignore
1035+
fit_object: PrevFit = from_csv(fit_csv_files) # type: ignore
10461036
except ValueError as e:
10471037
raise ValueError(
10481038
'Invalid sample from Stan CSV files, error:\n\t{}\n\t'
@@ -1064,11 +1054,6 @@ def generate_quantities(
10641054
'to generate additional quantities of interest.'
10651055
)
10661056
elif isinstance(fit_object, CmdStanMLE):
1067-
if cmdstan_version_before(2, 31):
1068-
raise RuntimeError(
1069-
"Method generate_quantities was not "
1070-
"available for non-HMC until CmdStan 2.31"
1071-
)
10721057
chains = 1
10731058
chain_ids = [1]
10741059
if fit_object._save_iterations:
@@ -1077,11 +1062,6 @@ def generate_quantities(
10771062
'to generate additional quantities of interest.'
10781063
)
10791064
else: # isinstance(fit_object, CmdStanVB)
1080-
if cmdstan_version_before(2, 31):
1081-
raise RuntimeError(
1082-
"Method generate_quantities was not "
1083-
"available for non-HMC until CmdStan 2.31"
1084-
)
10851065
chains = 1
10861066
chain_ids = [1]
10871067

@@ -1492,19 +1472,6 @@ def pathfinder(
14921472
"""
14931473

14941474
exe_info = self.exe_info()
1495-
if cmdstan_version_before(2, 33, exe_info):
1496-
raise ValueError(
1497-
"Method 'pathfinder' not available for CmdStan versions "
1498-
"before 2.33"
1499-
)
1500-
1501-
if (not psis_resample or not calculate_lp) and cmdstan_version_before(
1502-
2, 34, exe_info
1503-
):
1504-
raise ValueError(
1505-
"Arguments 'psis_resample' and 'calculate_lp' are only "
1506-
"available for CmdStan versions 2.34 and later"
1507-
)
15081475

15091476
if num_threads is not None:
15101477
if (
@@ -1613,11 +1580,6 @@ def log_prob(
16131580
unconstrained parameters of the model.
16141581
"""
16151582

1616-
if cmdstan_version_before(2, 31, self.exe_info()):
1617-
raise ValueError(
1618-
"Method 'log_prob' not available for CmdStan versions "
1619-
"before 2.31"
1620-
)
16211583
with (
16221584
temp_single_json(data) as _data,
16231585
temp_single_json(params) as _params,
@@ -1729,11 +1691,7 @@ def laplace_sample(
17291691
17301692
:return: A :class:`CmdStanLaplace` object.
17311693
"""
1732-
if cmdstan_version_before(2, 32, self.exe_info()):
1733-
raise ValueError(
1734-
"Method 'laplace_sample' not available for CmdStan versions "
1735-
"before 2.32"
1736-
)
1694+
17371695
if opt_args is not None and mode is not None:
17381696
raise ValueError(
17391697
"Cannot specify both 'opt_args' and 'mode' arguments"

cmdstanpy/stanfit/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
)
1414
from cmdstanpy.utils import check_sampler_csv, get_logger, stancsv
1515

16-
from .gq import CmdStanGQ
16+
from .gq import CmdStanGQ, PrevFit
1717
from .laplace import CmdStanLaplace
1818
from .mcmc import CmdStanMCMC
1919
from .metadata import InferenceMetadata
@@ -31,6 +31,7 @@
3131
"CmdStanGQ",
3232
"CmdStanLaplace",
3333
"CmdStanPathfinder",
34+
"PrevFit",
3435
]
3536

3637

cmdstanpy/stanfit/gq.py

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,25 @@
3535
stancsv,
3636
)
3737

38+
from .laplace import CmdStanLaplace
3839
from .mcmc import CmdStanMCMC
3940
from .metadata import InferenceMetadata
4041
from .mle import CmdStanMLE
42+
from .pathfinder import CmdStanPathfinder
4143
from .runset import RunSet
4244
from .vb import CmdStanVB
4345

44-
Fit = TypeVar('Fit', CmdStanMCMC, CmdStanMLE, CmdStanVB)
46+
PrevFit = TypeVar(
47+
'PrevFit',
48+
CmdStanMCMC,
49+
CmdStanMLE,
50+
CmdStanVB,
51+
CmdStanLaplace,
52+
CmdStanPathfinder,
53+
)
4554

4655

47-
class CmdStanGQ(Generic[Fit]):
56+
class CmdStanGQ(Generic[PrevFit]):
4857
"""
4958
Container for outputs from CmdStan generate_quantities run.
5059
Created by :meth:`CmdStanModel.generate_quantities`.
@@ -53,7 +62,7 @@ class CmdStanGQ(Generic[Fit]):
5362
def __init__(
5463
self,
5564
runset: RunSet,
56-
previous_fit: Fit,
65+
previous_fit: PrevFit,
5766
) -> None:
5867
"""Initialize object."""
5968
if not runset.method == Method.GENERATE_QUANTITIES:
@@ -63,7 +72,7 @@ def __init__(
6372
)
6473
self.runset = runset
6574

66-
self.previous_fit: Fit = previous_fit
75+
self.previous_fit: PrevFit = previous_fit
6776

6877
self._draws: np.ndarray = np.array(())
6978
self._metadata = self._validate_csv_files()
@@ -401,7 +410,12 @@ def draws_pd(
401410

402411
@overload
403412
def draws_xr(
404-
self: CmdStanGQ[CmdStanMLE] | CmdStanGQ[CmdStanVB],
413+
self: (
414+
CmdStanGQ[CmdStanMLE]
415+
| CmdStanGQ[CmdStanVB]
416+
| CmdStanGQ[CmdStanLaplace]
417+
| CmdStanGQ[CmdStanPathfinder]
418+
),
405419
vars: str | list[str] | None = None,
406420
inc_warmup: bool = False,
407421
inc_sample: bool = False,
@@ -565,10 +579,7 @@ def stan_variable(self, var: str, **kwargs: bool) -> np.ndarray:
565579
+ ", ".join(model_var_names | gq_var_names)
566580
)
567581
if var not in gq_var_names:
568-
# TODO(2.0) atleast1d may not be needed
569-
return np.atleast_1d( # type: ignore
570-
self.previous_fit.stan_variable(var, **kwargs)
571-
)
582+
return self.previous_fit.stan_variable(var, **kwargs)
572583

573584
# is gq variable
574585
self._assemble_generated_quantities()
@@ -718,11 +729,3 @@ def save_csvfiles(self, dir: str | None = None) -> None:
718729
cmdstanpy.from_csv
719730
"""
720731
self.runset.save_csvfiles(dir)
721-
722-
# TODO(2.0): remove
723-
@property
724-
def mcmc_sample(self) -> CmdStanMCMC | CmdStanMLE | CmdStanVB:
725-
get_logger().warning(
726-
"Property `mcmc_sample` is deprecated, use `previous_fit` instead"
727-
)
728-
return self.previous_fit

0 commit comments

Comments
 (0)