cmdstanpy 1.2.4__tar.gz → 1.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cmdstanpy-1.2.4/cmdstanpy.egg-info → cmdstanpy-1.3.0}/PKG-INFO +7 -4
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/cmdstanpy/__init__.py +4 -0
- cmdstanpy-1.3.0/cmdstanpy/_version.py +3 -0
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/cmdstanpy/cmdstan_args.py +38 -152
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/cmdstanpy/compilation.py +20 -19
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/cmdstanpy/install_cmdstan.py +12 -13
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/cmdstanpy/install_cxx_toolchain.py +5 -4
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/cmdstanpy/model.py +269 -115
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/cmdstanpy/progress.py +2 -0
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/cmdstanpy/stanfit/__init__.py +67 -58
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/cmdstanpy/stanfit/gq.py +58 -62
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/cmdstanpy/stanfit/laplace.py +51 -30
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/cmdstanpy/stanfit/mcmc.py +114 -98
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/cmdstanpy/stanfit/metadata.py +34 -6
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/cmdstanpy/stanfit/mle.py +52 -15
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/cmdstanpy/stanfit/pathfinder.py +18 -22
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/cmdstanpy/stanfit/runset.py +11 -11
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/cmdstanpy/stanfit/vb.py +66 -17
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/cmdstanpy/utils/__init__.py +6 -25
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/cmdstanpy/utils/cmdstan.py +24 -16
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/cmdstanpy/utils/command.py +5 -19
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/cmdstanpy/utils/data_munging.py +4 -3
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/cmdstanpy/utils/filesystem.py +39 -6
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/cmdstanpy/utils/json.py +1 -0
- cmdstanpy-1.3.0/cmdstanpy/utils/logging.py +62 -0
- cmdstanpy-1.3.0/cmdstanpy/utils/stancsv.py +670 -0
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0/cmdstanpy.egg-info}/PKG-INFO +7 -4
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/cmdstanpy.egg-info/SOURCES.txt +2 -0
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/cmdstanpy.egg-info/requires.txt +3 -1
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/pyproject.toml +7 -3
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/test/test_cmdstan_args.py +7 -16
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/test/test_laplace.py +44 -0
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/test/test_log_prob.py +1 -1
- cmdstanpy-1.3.0/test/test_logging.py +67 -0
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/test/test_metadata.py +0 -1
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/test/test_model.py +38 -2
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/test/test_optimize.py +27 -0
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/test/test_pathfinder.py +4 -4
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/test/test_sample.py +189 -82
- cmdstanpy-1.3.0/test/test_stancsv.py +675 -0
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/test/test_utils.py +38 -24
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/test/test_variational.py +44 -0
- cmdstanpy-1.2.4/cmdstanpy/_version.py +0 -3
- cmdstanpy-1.2.4/cmdstanpy/utils/logging.py +0 -25
- cmdstanpy-1.2.4/cmdstanpy/utils/stancsv.py +0 -486
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/LICENSE.md +0 -0
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/MANIFEST.in +0 -0
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/README.md +0 -0
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/cmdstanpy/py.typed +0 -0
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/cmdstanpy.egg-info/dependency_links.txt +0 -0
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/cmdstanpy.egg-info/entry_points.txt +0 -0
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/cmdstanpy.egg-info/top_level.txt +0 -0
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/setup.cfg +0 -0
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/test/test_compiler_opts.py +0 -0
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/test/test_compliance.py +0 -0
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/test/test_cxx_installation.py +0 -0
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/test/test_generate_quantities.py +0 -0
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/test/test_install_cmdstan.py +0 -0
- {cmdstanpy-1.2.4 → cmdstanpy-1.3.0}/test/test_runset.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: cmdstanpy
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.0
|
|
4
4
|
Summary: Python interface to CmdStan
|
|
5
5
|
Author: Stan Dev Team
|
|
6
6
|
License: BSD-3-Clause
|
|
@@ -14,7 +14,7 @@ Classifier: Intended Audience :: Science/Research
|
|
|
14
14
|
Classifier: Natural Language :: English
|
|
15
15
|
Classifier: Programming Language :: Python
|
|
16
16
|
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
17
|
-
Requires-Python: >=3.
|
|
17
|
+
Requires-Python: >=3.9
|
|
18
18
|
Description-Content-Type: text/markdown
|
|
19
19
|
License-File: LICENSE.md
|
|
20
20
|
Requires-Dist: pandas
|
|
@@ -23,6 +23,7 @@ Requires-Dist: tqdm
|
|
|
23
23
|
Requires-Dist: stanio<2.0.0,>=0.4.0
|
|
24
24
|
Provides-Extra: all
|
|
25
25
|
Requires-Dist: xarray; extra == "all"
|
|
26
|
+
Requires-Dist: polars>=1.8.2; extra == "all"
|
|
26
27
|
Provides-Extra: test
|
|
27
28
|
Requires-Dist: flake8; extra == "test"
|
|
28
29
|
Requires-Dist: pylint; extra == "test"
|
|
@@ -31,16 +32,18 @@ Requires-Dist: pytest-cov; extra == "test"
|
|
|
31
32
|
Requires-Dist: pytest-order; extra == "test"
|
|
32
33
|
Requires-Dist: mypy; extra == "test"
|
|
33
34
|
Requires-Dist: xarray; extra == "test"
|
|
35
|
+
Requires-Dist: polars>=1.8.2; extra == "test"
|
|
34
36
|
Provides-Extra: docs
|
|
35
37
|
Requires-Dist: sphinx<6,>5; extra == "docs"
|
|
36
38
|
Requires-Dist: pydata-sphinx-theme<0.9; extra == "docs"
|
|
37
39
|
Requires-Dist: nbsphinx; extra == "docs"
|
|
38
40
|
Requires-Dist: ipython; extra == "docs"
|
|
39
|
-
Requires-Dist: ipykernel; extra == "docs"
|
|
41
|
+
Requires-Dist: ipykernel<7; extra == "docs"
|
|
40
42
|
Requires-Dist: ipywidgets; extra == "docs"
|
|
41
43
|
Requires-Dist: sphinx-copybutton; extra == "docs"
|
|
42
44
|
Requires-Dist: xarray; extra == "docs"
|
|
43
45
|
Requires-Dist: matplotlib; extra == "docs"
|
|
46
|
+
Dynamic: license-file
|
|
44
47
|
|
|
45
48
|
# CmdStanPy
|
|
46
49
|
|
|
@@ -37,6 +37,8 @@ from .stanfit import (
|
|
|
37
37
|
from .utils import (
|
|
38
38
|
cmdstan_path,
|
|
39
39
|
cmdstan_version,
|
|
40
|
+
disable_logging,
|
|
41
|
+
enable_logging,
|
|
40
42
|
install_cmdstan,
|
|
41
43
|
set_cmdstan_path,
|
|
42
44
|
set_make_env,
|
|
@@ -63,4 +65,6 @@ __all__ = [
|
|
|
63
65
|
'show_versions',
|
|
64
66
|
'rebuild_cmdstan',
|
|
65
67
|
'cmdstan_version',
|
|
68
|
+
"enable_logging",
|
|
69
|
+
"disable_logging",
|
|
66
70
|
]
|
|
@@ -1,23 +1,16 @@
|
|
|
1
1
|
"""
|
|
2
2
|
CmdStan arguments
|
|
3
3
|
"""
|
|
4
|
+
|
|
4
5
|
import os
|
|
5
6
|
from enum import Enum, auto
|
|
6
7
|
from time import time
|
|
7
|
-
from typing import Any,
|
|
8
|
+
from typing import Any, Mapping, Optional, Union
|
|
8
9
|
|
|
9
10
|
import numpy as np
|
|
10
11
|
from numpy.random import default_rng
|
|
11
12
|
|
|
12
|
-
from cmdstanpy import
|
|
13
|
-
from cmdstanpy.utils import (
|
|
14
|
-
cmdstan_path,
|
|
15
|
-
cmdstan_version_before,
|
|
16
|
-
create_named_text_file,
|
|
17
|
-
get_logger,
|
|
18
|
-
read_metric,
|
|
19
|
-
write_stan_json,
|
|
20
|
-
)
|
|
13
|
+
from cmdstanpy.utils import cmdstan_path, cmdstan_version_before, get_logger
|
|
21
14
|
|
|
22
15
|
OptionalPath = Union[str, os.PathLike, None]
|
|
23
16
|
|
|
@@ -64,10 +57,9 @@ class SamplerArgs:
|
|
|
64
57
|
save_warmup: bool = False,
|
|
65
58
|
thin: Optional[int] = None,
|
|
66
59
|
max_treedepth: Optional[int] = None,
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
] = None,
|
|
70
|
-
step_size: Union[float, List[float], None] = None,
|
|
60
|
+
metric_type: Optional[str] = None,
|
|
61
|
+
metric_file: Union[str, list[str], None] = None,
|
|
62
|
+
step_size: Union[float, list[float], None] = None,
|
|
71
63
|
adapt_engaged: bool = True,
|
|
72
64
|
adapt_delta: Optional[float] = None,
|
|
73
65
|
adapt_init_phase: Optional[int] = None,
|
|
@@ -82,9 +74,8 @@ class SamplerArgs:
|
|
|
82
74
|
self.save_warmup = save_warmup
|
|
83
75
|
self.thin = thin
|
|
84
76
|
self.max_treedepth = max_treedepth
|
|
85
|
-
self.
|
|
86
|
-
self.
|
|
87
|
-
self.metric_file: Union[str, List[str], None] = None
|
|
77
|
+
self.metric_type: Optional[str] = metric_type
|
|
78
|
+
self.metric_file: Union[str, list[str], None] = metric_file
|
|
88
79
|
self.step_size = step_size
|
|
89
80
|
self.adapt_engaged = adapt_engaged
|
|
90
81
|
self.adapt_delta = adapt_delta
|
|
@@ -161,8 +152,9 @@ class SamplerArgs:
|
|
|
161
152
|
):
|
|
162
153
|
if self.step_size <= 0:
|
|
163
154
|
raise ValueError(
|
|
164
|
-
'Argument "step_size" must be > 0, '
|
|
165
|
-
|
|
155
|
+
'Argument "step_size" must be > 0, found {}.'.format(
|
|
156
|
+
self.step_size
|
|
157
|
+
)
|
|
166
158
|
)
|
|
167
159
|
else:
|
|
168
160
|
if len(self.step_size) != chains:
|
|
@@ -176,124 +168,15 @@ class SamplerArgs:
|
|
|
176
168
|
'Argument "step_size" must be > 0, '
|
|
177
169
|
'chain {}, found {}.'.format(i + 1, step_size)
|
|
178
170
|
)
|
|
179
|
-
if self.
|
|
180
|
-
if
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
elif self.metric in ['dense', 'dense_e']:
|
|
184
|
-
self.metric_type = 'dense_e'
|
|
185
|
-
elif self.metric in ['unit', 'unit_e']:
|
|
186
|
-
self.metric_type = 'unit_e'
|
|
187
|
-
else:
|
|
188
|
-
if not os.path.exists(self.metric):
|
|
189
|
-
raise ValueError('no such file {}'.format(self.metric))
|
|
190
|
-
dims = read_metric(self.metric)
|
|
191
|
-
if len(dims) == 1:
|
|
192
|
-
self.metric_type = 'diag_e'
|
|
193
|
-
else:
|
|
194
|
-
self.metric_type = 'dense_e'
|
|
195
|
-
self.metric_file = self.metric
|
|
196
|
-
elif isinstance(self.metric, dict):
|
|
197
|
-
if 'inv_metric' not in self.metric:
|
|
198
|
-
raise ValueError(
|
|
199
|
-
'Entry "inv_metric" not found in metric dict.'
|
|
200
|
-
)
|
|
201
|
-
dims = list(np.asarray(self.metric['inv_metric']).shape)
|
|
202
|
-
if len(dims) == 1:
|
|
203
|
-
self.metric_type = 'diag_e'
|
|
204
|
-
else:
|
|
205
|
-
self.metric_type = 'dense_e'
|
|
206
|
-
dict_file = create_named_text_file(
|
|
207
|
-
dir=_TMPDIR, prefix="metric", suffix=".json"
|
|
208
|
-
)
|
|
209
|
-
write_stan_json(dict_file, self.metric)
|
|
210
|
-
self.metric_file = dict_file
|
|
211
|
-
elif isinstance(self.metric, (list, tuple)):
|
|
212
|
-
if len(self.metric) != chains:
|
|
213
|
-
raise ValueError(
|
|
214
|
-
'Number of metric files must match number of chains,'
|
|
215
|
-
' found {} metric files for {} chains.'.format(
|
|
216
|
-
len(self.metric), chains
|
|
217
|
-
)
|
|
218
|
-
)
|
|
219
|
-
if all(isinstance(elem, dict) for elem in self.metric):
|
|
220
|
-
metric_files: List[str] = []
|
|
221
|
-
for i, metric in enumerate(self.metric):
|
|
222
|
-
metric_dict: Dict[str, Any] = metric # type: ignore
|
|
223
|
-
if 'inv_metric' not in metric_dict:
|
|
224
|
-
raise ValueError(
|
|
225
|
-
'Entry "inv_metric" not found in metric dict '
|
|
226
|
-
'for chain {}.'.format(i + 1)
|
|
227
|
-
)
|
|
228
|
-
if i == 0:
|
|
229
|
-
dims = list(
|
|
230
|
-
np.asarray(metric_dict['inv_metric']).shape
|
|
231
|
-
)
|
|
232
|
-
else:
|
|
233
|
-
dims2 = list(
|
|
234
|
-
np.asarray(metric_dict['inv_metric']).shape
|
|
235
|
-
)
|
|
236
|
-
if dims != dims2:
|
|
237
|
-
raise ValueError(
|
|
238
|
-
'Found inconsistent "inv_metric" entry '
|
|
239
|
-
'for chain {}: entry has dims '
|
|
240
|
-
'{}, expected {}.'.format(
|
|
241
|
-
i + 1, dims, dims2
|
|
242
|
-
)
|
|
243
|
-
)
|
|
244
|
-
dict_file = create_named_text_file(
|
|
245
|
-
dir=_TMPDIR, prefix="metric", suffix=".json"
|
|
246
|
-
)
|
|
247
|
-
write_stan_json(dict_file, metric_dict)
|
|
248
|
-
metric_files.append(dict_file)
|
|
249
|
-
if len(dims) == 1:
|
|
250
|
-
self.metric_type = 'diag_e'
|
|
251
|
-
else:
|
|
252
|
-
self.metric_type = 'dense_e'
|
|
253
|
-
self.metric_file = metric_files
|
|
254
|
-
elif all(isinstance(elem, str) for elem in self.metric):
|
|
255
|
-
metric_files = []
|
|
256
|
-
for i, metric in enumerate(self.metric):
|
|
257
|
-
assert isinstance(metric, str) # typecheck
|
|
258
|
-
if not os.path.exists(metric):
|
|
259
|
-
raise ValueError('no such file {}'.format(metric))
|
|
260
|
-
if i == 0:
|
|
261
|
-
dims = read_metric(metric)
|
|
262
|
-
else:
|
|
263
|
-
dims2 = read_metric(metric)
|
|
264
|
-
if len(dims) != len(dims2):
|
|
265
|
-
raise ValueError(
|
|
266
|
-
'Metrics files {}, {},'
|
|
267
|
-
' inconsistent metrics'.format(
|
|
268
|
-
self.metric[0], metric
|
|
269
|
-
)
|
|
270
|
-
)
|
|
271
|
-
if dims != dims2:
|
|
272
|
-
raise ValueError(
|
|
273
|
-
'Metrics files {}, {},'
|
|
274
|
-
' inconsistent metrics'.format(
|
|
275
|
-
self.metric[0], metric
|
|
276
|
-
)
|
|
277
|
-
)
|
|
278
|
-
metric_files.append(metric)
|
|
279
|
-
if len(dims) == 1:
|
|
280
|
-
self.metric_type = 'diag_e'
|
|
281
|
-
else:
|
|
282
|
-
self.metric_type = 'dense_e'
|
|
283
|
-
self.metric_file = metric_files
|
|
284
|
-
else:
|
|
285
|
-
raise ValueError(
|
|
286
|
-
'Argument "metric" must be a list of pathnames or '
|
|
287
|
-
'Python dicts, found list of {}.'.format(
|
|
288
|
-
type(self.metric[0])
|
|
289
|
-
)
|
|
290
|
-
)
|
|
291
|
-
else:
|
|
171
|
+
if self.metric_type is not None:
|
|
172
|
+
if self.metric_type in ['diag', 'dense', 'unit']:
|
|
173
|
+
self.metric_type += '_e'
|
|
174
|
+
if self.metric_type not in ['diag_e', 'dense_e', 'unit_e']:
|
|
292
175
|
raise ValueError(
|
|
293
|
-
'
|
|
294
|
-
'
|
|
295
|
-
|
|
296
|
-
|
|
176
|
+
'Argument "metric" must be one of [diag, dense, unit,'
|
|
177
|
+
' diag_e, dense_e, unit_e], found {}.'.format(
|
|
178
|
+
self.metric_type
|
|
179
|
+
)
|
|
297
180
|
)
|
|
298
181
|
|
|
299
182
|
if self.adapt_delta is not None:
|
|
@@ -330,7 +213,8 @@ class SamplerArgs:
|
|
|
330
213
|
|
|
331
214
|
if self.fixed_param and (
|
|
332
215
|
self.max_treedepth is not None
|
|
333
|
-
or self.
|
|
216
|
+
or self.metric_type is not None
|
|
217
|
+
or self.metric_file is not None
|
|
334
218
|
or self.step_size is not None
|
|
335
219
|
or not (
|
|
336
220
|
self.adapt_delta is None
|
|
@@ -343,7 +227,7 @@ class SamplerArgs:
|
|
|
343
227
|
'When fixed_param=True, cannot specify adaptation parameters.'
|
|
344
228
|
)
|
|
345
229
|
|
|
346
|
-
def compose(self, idx: int, cmd:
|
|
230
|
+
def compose(self, idx: int, cmd: list[str]) -> list[str]:
|
|
347
231
|
"""
|
|
348
232
|
Compose CmdStan command for method-specific non-default arguments.
|
|
349
233
|
"""
|
|
@@ -369,7 +253,7 @@ class SamplerArgs:
|
|
|
369
253
|
cmd.append(f'stepsize={self.step_size}')
|
|
370
254
|
else:
|
|
371
255
|
cmd.append(f'stepsize={self.step_size[idx]}')
|
|
372
|
-
if self.
|
|
256
|
+
if self.metric_type is not None:
|
|
373
257
|
cmd.append(f'metric={self.metric_type}')
|
|
374
258
|
if self.metric_file is not None:
|
|
375
259
|
if not isinstance(self.metric_file, list):
|
|
@@ -467,7 +351,7 @@ class OptimizeArgs:
|
|
|
467
351
|
positive_float(self.tol_param, 'tol_param')
|
|
468
352
|
positive_int(self.history_size, 'history_size')
|
|
469
353
|
|
|
470
|
-
def compose(self, _idx: int, cmd:
|
|
354
|
+
def compose(self, _idx: int, cmd: list[str]) -> list[str]:
|
|
471
355
|
"""compose command string for CmdStan for non-default arg values."""
|
|
472
356
|
cmd.append('method=optimize')
|
|
473
357
|
if self.algorithm:
|
|
@@ -511,7 +395,7 @@ class LaplaceArgs:
|
|
|
511
395
|
raise ValueError(f'Invalid path for mode file: {self.mode}')
|
|
512
396
|
positive_int(self.draws, 'draws')
|
|
513
397
|
|
|
514
|
-
def compose(self, _idx: int, cmd:
|
|
398
|
+
def compose(self, _idx: int, cmd: list[str]) -> list[str]:
|
|
515
399
|
"""compose command string for CmdStan for non-default arg values."""
|
|
516
400
|
cmd.append('method=laplace')
|
|
517
401
|
cmd.append(f'mode={self.mode}')
|
|
@@ -579,7 +463,7 @@ class PathfinderArgs:
|
|
|
579
463
|
positive_int(self.num_draws, 'num_draws')
|
|
580
464
|
positive_int(self.num_elbo_draws, 'num_elbo_draws')
|
|
581
465
|
|
|
582
|
-
def compose(self, _idx: int, cmd:
|
|
466
|
+
def compose(self, _idx: int, cmd: list[str]) -> list[str]:
|
|
583
467
|
"""compose command string for CmdStan for non-default arg values."""
|
|
584
468
|
cmd.append('method=pathfinder')
|
|
585
469
|
|
|
@@ -624,12 +508,13 @@ class PathfinderArgs:
|
|
|
624
508
|
class GenerateQuantitiesArgs:
|
|
625
509
|
"""Arguments needed for generate_quantities method."""
|
|
626
510
|
|
|
627
|
-
def __init__(self, csv_files:
|
|
511
|
+
def __init__(self, csv_files: list[str]) -> None:
|
|
628
512
|
"""Initialize object."""
|
|
629
513
|
self.sample_csv_files = csv_files
|
|
630
514
|
|
|
631
515
|
def validate(
|
|
632
|
-
self,
|
|
516
|
+
self,
|
|
517
|
+
chains: Optional[int] = None, # pylint: disable=unused-argument
|
|
633
518
|
) -> None:
|
|
634
519
|
"""
|
|
635
520
|
Check arguments correctness and consistency.
|
|
@@ -642,7 +527,7 @@ class GenerateQuantitiesArgs:
|
|
|
642
527
|
'Invalid path for sample csv file: {}'.format(csv)
|
|
643
528
|
)
|
|
644
529
|
|
|
645
|
-
def compose(self, idx: int, cmd:
|
|
530
|
+
def compose(self, idx: int, cmd: list[str]) -> list[str]:
|
|
646
531
|
"""
|
|
647
532
|
Compose CmdStan command for method-specific non-default arguments.
|
|
648
533
|
"""
|
|
@@ -681,7 +566,8 @@ class VariationalArgs:
|
|
|
681
566
|
self.output_samples = output_samples
|
|
682
567
|
|
|
683
568
|
def validate(
|
|
684
|
-
self,
|
|
569
|
+
self,
|
|
570
|
+
chains: Optional[int] = None, # pylint: disable=unused-argument
|
|
685
571
|
) -> None:
|
|
686
572
|
"""
|
|
687
573
|
Check arguments correctness and consistency.
|
|
@@ -705,7 +591,7 @@ class VariationalArgs:
|
|
|
705
591
|
positive_int(self.output_samples, 'output_samples')
|
|
706
592
|
|
|
707
593
|
# pylint: disable=unused-argument
|
|
708
|
-
def compose(self, idx: int, cmd:
|
|
594
|
+
def compose(self, idx: int, cmd: list[str]) -> list[str]:
|
|
709
595
|
"""
|
|
710
596
|
Compose CmdStan command for method-specific non-default arguments.
|
|
711
597
|
"""
|
|
@@ -747,7 +633,7 @@ class CmdStanArgs:
|
|
|
747
633
|
self,
|
|
748
634
|
model_name: str,
|
|
749
635
|
model_exe: OptionalPath,
|
|
750
|
-
chain_ids: Optional[
|
|
636
|
+
chain_ids: Optional[list[int]],
|
|
751
637
|
method_args: Union[
|
|
752
638
|
SamplerArgs,
|
|
753
639
|
OptimizeArgs,
|
|
@@ -757,8 +643,8 @@ class CmdStanArgs:
|
|
|
757
643
|
PathfinderArgs,
|
|
758
644
|
],
|
|
759
645
|
data: Union[Mapping[str, Any], str, None] = None,
|
|
760
|
-
seed: Union[int,
|
|
761
|
-
inits: Union[int, float, str,
|
|
646
|
+
seed: Union[int, list[int], None] = None,
|
|
647
|
+
inits: Union[int, float, str, list[str], None] = None,
|
|
762
648
|
output_dir: OptionalPath = None,
|
|
763
649
|
sig_figs: Optional[int] = None,
|
|
764
650
|
save_latent_dynamics: bool = False,
|
|
@@ -959,11 +845,11 @@ class CmdStanArgs:
|
|
|
959
845
|
*,
|
|
960
846
|
diagnostic_file: Optional[str] = None,
|
|
961
847
|
profile_file: Optional[str] = None,
|
|
962
|
-
) ->
|
|
848
|
+
) -> list[str]:
|
|
963
849
|
"""
|
|
964
850
|
Compose CmdStan command for non-default arguments.
|
|
965
851
|
"""
|
|
966
|
-
cmd:
|
|
852
|
+
cmd: list[str] = []
|
|
967
853
|
if idx is not None and self.chain_ids is not None:
|
|
968
854
|
if idx < 0 or idx > len(self.chain_ids) - 1:
|
|
969
855
|
raise ValueError(
|
|
@@ -11,7 +11,7 @@ import subprocess
|
|
|
11
11
|
from copy import copy
|
|
12
12
|
from datetime import datetime
|
|
13
13
|
from pathlib import Path
|
|
14
|
-
from typing import Any,
|
|
14
|
+
from typing import Any, Iterable, Optional, Union
|
|
15
15
|
|
|
16
16
|
from cmdstanpy.utils import get_logger
|
|
17
17
|
from cmdstanpy.utils.cmdstan import (
|
|
@@ -19,6 +19,7 @@ from cmdstanpy.utils.cmdstan import (
|
|
|
19
19
|
cmdstan_path,
|
|
20
20
|
cmdstan_version,
|
|
21
21
|
cmdstan_version_before,
|
|
22
|
+
stanc_path,
|
|
22
23
|
)
|
|
23
24
|
from cmdstanpy.utils.command import do_command
|
|
24
25
|
from cmdstanpy.utils.filesystem import SanitizedOrTmpFilePath
|
|
@@ -80,8 +81,8 @@ class CompilerOptions:
|
|
|
80
81
|
def __init__(
|
|
81
82
|
self,
|
|
82
83
|
*,
|
|
83
|
-
stanc_options: Optional[
|
|
84
|
-
cpp_options: Optional[
|
|
84
|
+
stanc_options: Optional[dict[str, Any]] = None,
|
|
85
|
+
cpp_options: Optional[dict[str, Any]] = None,
|
|
85
86
|
user_header: OptionalPath = None,
|
|
86
87
|
) -> None:
|
|
87
88
|
"""Initialize object."""
|
|
@@ -115,12 +116,12 @@ class CompilerOptions:
|
|
|
115
116
|
)
|
|
116
117
|
|
|
117
118
|
@property
|
|
118
|
-
def stanc_options(self) ->
|
|
119
|
+
def stanc_options(self) -> dict[str, Union[bool, int, str, Iterable[str]]]:
|
|
119
120
|
"""Stanc compiler options."""
|
|
120
121
|
return self._stanc_options
|
|
121
122
|
|
|
122
123
|
@property
|
|
123
|
-
def cpp_options(self) ->
|
|
124
|
+
def cpp_options(self) -> dict[str, Union[bool, int]]:
|
|
124
125
|
"""C++ compiler options."""
|
|
125
126
|
return self._cpp_options
|
|
126
127
|
|
|
@@ -164,8 +165,8 @@ class CompilerOptions:
|
|
|
164
165
|
del self._stanc_options[deprecated]
|
|
165
166
|
else:
|
|
166
167
|
get_logger().warning(
|
|
167
|
-
'compiler option "%s" is deprecated and '
|
|
168
|
-
'
|
|
168
|
+
'compiler option "%s" is deprecated and should '
|
|
169
|
+
'not be used',
|
|
169
170
|
deprecated,
|
|
170
171
|
)
|
|
171
172
|
for key, val in self._stanc_options.items():
|
|
@@ -224,8 +225,8 @@ class CompilerOptions:
|
|
|
224
225
|
val = self._cpp_options[key]
|
|
225
226
|
if not isinstance(val, int) or val < 0:
|
|
226
227
|
raise ValueError(
|
|
227
|
-
f'{key} must be a non-negative integer
|
|
228
|
-
f' found {val}.'
|
|
228
|
+
f'{key} must be a non-negative integer '
|
|
229
|
+
f'value, found {val}.'
|
|
229
230
|
)
|
|
230
231
|
|
|
231
232
|
def validate_user_header(self) -> None:
|
|
@@ -297,7 +298,7 @@ class CompilerOptions:
|
|
|
297
298
|
elif path not in self._stanc_options['include-paths']:
|
|
298
299
|
self._stanc_options['include-paths'].append(path)
|
|
299
300
|
|
|
300
|
-
def compose_stanc(self, filename_in_msg: Optional[str]) ->
|
|
301
|
+
def compose_stanc(self, filename_in_msg: Optional[str]) -> list[str]:
|
|
301
302
|
opts = []
|
|
302
303
|
|
|
303
304
|
if filename_in_msg is not None:
|
|
@@ -321,7 +322,7 @@ class CompilerOptions:
|
|
|
321
322
|
opts.append(f'--{key}')
|
|
322
323
|
return opts
|
|
323
324
|
|
|
324
|
-
def compose(self, filename_in_msg: Optional[str] = None) ->
|
|
325
|
+
def compose(self, filename_in_msg: Optional[str] = None) -> list[str]:
|
|
325
326
|
"""
|
|
326
327
|
Format makefile options as list of strings.
|
|
327
328
|
|
|
@@ -343,7 +344,7 @@ class CompilerOptions:
|
|
|
343
344
|
|
|
344
345
|
def src_info(
|
|
345
346
|
stan_file: str, compiler_options: CompilerOptions
|
|
346
|
-
) ->
|
|
347
|
+
) -> dict[str, Any]:
|
|
347
348
|
"""
|
|
348
349
|
Get source info for Stan program file.
|
|
349
350
|
|
|
@@ -351,7 +352,7 @@ def src_info(
|
|
|
351
352
|
:meth:`CmdStanModel.src_info`, and should not be called directly.
|
|
352
353
|
"""
|
|
353
354
|
cmd = (
|
|
354
|
-
[
|
|
355
|
+
[stanc_path()]
|
|
355
356
|
# handle include-paths, allow-undefined etc
|
|
356
357
|
+ compiler_options.compose_stanc(None)
|
|
357
358
|
+ ['--info', str(stan_file)]
|
|
@@ -362,15 +363,15 @@ def src_info(
|
|
|
362
363
|
f"Failed to get source info for Stan model "
|
|
363
364
|
f"'{stan_file}'. Console:\n{proc.stderr}"
|
|
364
365
|
)
|
|
365
|
-
result:
|
|
366
|
+
result: dict[str, Any] = json.loads(proc.stdout)
|
|
366
367
|
return result
|
|
367
368
|
|
|
368
369
|
|
|
369
370
|
def compile_stan_file(
|
|
370
371
|
src: Union[str, Path],
|
|
371
372
|
force: bool = False,
|
|
372
|
-
stanc_options: Optional[
|
|
373
|
-
cpp_options: Optional[
|
|
373
|
+
stanc_options: Optional[dict[str, Any]] = None,
|
|
374
|
+
cpp_options: Optional[dict[str, Any]] = None,
|
|
374
375
|
user_header: OptionalPath = None,
|
|
375
376
|
) -> str:
|
|
376
377
|
"""
|
|
@@ -479,7 +480,7 @@ def compile_stan_file(
|
|
|
479
480
|
"If the issue persists please open a bug report"
|
|
480
481
|
)
|
|
481
482
|
raise ValueError(
|
|
482
|
-
f"Failed to compile Stan model '{src}'.
|
|
483
|
+
f"Failed to compile Stan model '{src}'. Console:\n{console}"
|
|
483
484
|
)
|
|
484
485
|
return str(exe_target)
|
|
485
486
|
|
|
@@ -491,7 +492,7 @@ def format_stan_file(
|
|
|
491
492
|
canonicalize: Union[bool, str, Iterable[str]] = False,
|
|
492
493
|
max_line_length: int = 78,
|
|
493
494
|
backup: bool = True,
|
|
494
|
-
stanc_options: Optional[
|
|
495
|
+
stanc_options: Optional[dict[str, Any]] = None,
|
|
495
496
|
) -> None:
|
|
496
497
|
"""
|
|
497
498
|
Run stanc's auto-formatter on the model code. Either saves directly
|
|
@@ -518,7 +519,7 @@ def format_stan_file(
|
|
|
518
519
|
|
|
519
520
|
try:
|
|
520
521
|
cmd = (
|
|
521
|
-
[
|
|
522
|
+
[stanc_path()]
|
|
522
523
|
# handle include-paths, allow-undefined etc
|
|
523
524
|
+ CompilerOptions(stanc_options=stanc_options).compose_stanc(None)
|
|
524
525
|
+ [str(stan_file)]
|
|
@@ -17,6 +17,7 @@ Optional command line arguments:
|
|
|
17
17
|
--cores: int, number of cores to use when building, defaults to 1
|
|
18
18
|
-c, --compiler : flag, add C++ compiler to path (Windows only)
|
|
19
19
|
"""
|
|
20
|
+
|
|
20
21
|
import argparse
|
|
21
22
|
import json
|
|
22
23
|
import os
|
|
@@ -30,7 +31,7 @@ import urllib.request
|
|
|
30
31
|
from collections import OrderedDict
|
|
31
32
|
from pathlib import Path
|
|
32
33
|
from time import sleep
|
|
33
|
-
from typing import TYPE_CHECKING, Any, Callable,
|
|
34
|
+
from typing import TYPE_CHECKING, Any, Callable, Optional, Union
|
|
34
35
|
|
|
35
36
|
from tqdm.auto import tqdm
|
|
36
37
|
|
|
@@ -85,7 +86,7 @@ MAKE = os.getenv('MAKE', 'make' if not is_windows() else 'mingw32-make')
|
|
|
85
86
|
EXTENSION = '.exe' if is_windows() else ''
|
|
86
87
|
|
|
87
88
|
|
|
88
|
-
def get_headers() ->
|
|
89
|
+
def get_headers() -> dict[str, str]:
|
|
89
90
|
"""Create headers dictionary."""
|
|
90
91
|
headers = {}
|
|
91
92
|
GITHUB_PAT = os.environ.get("GITHUB_PAT") # pylint:disable=invalid-name
|
|
@@ -287,13 +288,13 @@ def build(verbose: bool = False, progress: bool = True, cores: int = 1) -> None:
|
|
|
287
288
|
raise CmdStanInstallError(f'Command "make build" failed\n{str(e)}')
|
|
288
289
|
if not os.path.exists(os.path.join('bin', 'stansummary' + EXTENSION)):
|
|
289
290
|
raise CmdStanInstallError(
|
|
290
|
-
f'bin/stansummary{EXTENSION} not found'
|
|
291
|
-
'
|
|
291
|
+
f'bin/stansummary{EXTENSION} not found, please rebuild or '
|
|
292
|
+
'report a bug!'
|
|
292
293
|
)
|
|
293
294
|
if not os.path.exists(os.path.join('bin', 'diagnose' + EXTENSION)):
|
|
294
295
|
raise CmdStanInstallError(
|
|
295
|
-
f'bin/stansummary{EXTENSION} not found'
|
|
296
|
-
'
|
|
296
|
+
f'bin/stansummary{EXTENSION} not found, please rebuild or '
|
|
297
|
+
'report a bug!'
|
|
297
298
|
)
|
|
298
299
|
|
|
299
300
|
if is_windows():
|
|
@@ -417,8 +418,8 @@ def install_version(
|
|
|
417
418
|
)
|
|
418
419
|
if overwrite and os.path.exists('.'):
|
|
419
420
|
print(
|
|
420
|
-
'Overwrite requested, remove existing build
|
|
421
|
-
'{}'.format(cmdstan_version)
|
|
421
|
+
'Overwrite requested, remove existing build '
|
|
422
|
+
'of version {}'.format(cmdstan_version)
|
|
422
423
|
)
|
|
423
424
|
clean_all(verbose)
|
|
424
425
|
print('Rebuilding version {}'.format(cmdstan_version))
|
|
@@ -496,10 +497,8 @@ def retrieve_version(version: str, progress: bool = True) -> None:
|
|
|
496
497
|
break
|
|
497
498
|
except urllib.error.HTTPError as e:
|
|
498
499
|
raise CmdStanRetrieveError(
|
|
499
|
-
'HTTPError: {}\
|
|
500
|
-
'
|
|
501
|
-
e.code, version
|
|
502
|
-
)
|
|
500
|
+
'HTTPError: {}\nVersion {} not available from '
|
|
501
|
+
'github.com.'.format(e.code, version)
|
|
503
502
|
) from e
|
|
504
503
|
except urllib.error.URLError as e:
|
|
505
504
|
print(
|
|
@@ -645,7 +644,7 @@ def run_install(args: Union[InteractiveSettings, InstallationSettings]) -> None:
|
|
|
645
644
|
compile_example(args.verbose)
|
|
646
645
|
|
|
647
646
|
|
|
648
|
-
def parse_cmdline_args() ->
|
|
647
|
+
def parse_cmdline_args() -> dict[str, Any]:
|
|
649
648
|
parser = argparse.ArgumentParser("install_cmdstan")
|
|
650
649
|
parser.add_argument(
|
|
651
650
|
'--interactive',
|
|
@@ -12,6 +12,7 @@ Optional command line arguments:
|
|
|
12
12
|
-m --no-make : don't install mingw32-make (Windows RTools 4.0 only)
|
|
13
13
|
--progress : flag, when specified show progress bar for RTools download
|
|
14
14
|
"""
|
|
15
|
+
|
|
15
16
|
import argparse
|
|
16
17
|
import os
|
|
17
18
|
import platform
|
|
@@ -21,7 +22,7 @@ import sys
|
|
|
21
22
|
import urllib.request
|
|
22
23
|
from collections import OrderedDict
|
|
23
24
|
from time import sleep
|
|
24
|
-
from typing import Any
|
|
25
|
+
from typing import Any
|
|
25
26
|
|
|
26
27
|
from cmdstanpy import _DOT_CMDSTAN
|
|
27
28
|
from cmdstanpy.utils import pushd, validate_dir, wrap_url_progress_hook
|
|
@@ -44,7 +45,7 @@ def usage() -> None:
|
|
|
44
45
|
)
|
|
45
46
|
|
|
46
47
|
|
|
47
|
-
def get_config(dir: str, silent: bool) ->
|
|
48
|
+
def get_config(dir: str, silent: bool) -> list[str]:
|
|
48
49
|
"""Assemble config info."""
|
|
49
50
|
config = []
|
|
50
51
|
if platform.system() == 'Windows':
|
|
@@ -260,7 +261,7 @@ def get_toolchain_version(name: str, version: str) -> str:
|
|
|
260
261
|
return toolchain_folder
|
|
261
262
|
|
|
262
263
|
|
|
263
|
-
def run_rtools_install(args:
|
|
264
|
+
def run_rtools_install(args: dict[str, Any]) -> None:
|
|
264
265
|
"""Main."""
|
|
265
266
|
if platform.system() not in {'Windows'}:
|
|
266
267
|
raise NotImplementedError(
|
|
@@ -333,7 +334,7 @@ def run_rtools_install(args: Dict[str, Any]) -> None:
|
|
|
333
334
|
install_mingw32_make(toolchain_folder, verbose)
|
|
334
335
|
|
|
335
336
|
|
|
336
|
-
def parse_cmdline_args() ->
|
|
337
|
+
def parse_cmdline_args() -> dict[str, Any]:
|
|
337
338
|
parser = argparse.ArgumentParser()
|
|
338
339
|
parser.add_argument('--version', '-v', help="version, defaults to latest")
|
|
339
340
|
parser.add_argument(
|