Skip to content

Commit 458f0a7

Browse files
committed
Merge branch 'develop' of https://github.com/stan-dev/cmdstanpy into develop
2 parents f139e2f + 5ed096e commit 458f0a7

3 files changed

Lines changed: 73 additions & 17 deletions

File tree

cmdstanpy/compiler_opts.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111

1212
STANC_OPTS = [
1313
'O',
14+
'O0',
15+
'O1',
16+
'Oexperimental',
1417
'allow-undefined',
1518
'use-opencl',
1619
'warn-uninitialized',
@@ -127,6 +130,8 @@ def validate_stanc_opts(self) -> None:
127130
return
128131
ignore = []
129132
paths = None
133+
has_o_flag = False
134+
130135
for deprecated, replacement in STANC_DEPRECATED_OPTS.items():
131136
if deprecated in self._stanc_options:
132137
if replacement:
@@ -165,6 +170,15 @@ def validate_stanc_opts(self) -> None:
165170
self._cpp_options = {'STAN_OPENCL': 'TRUE'}
166171
else:
167172
self._cpp_options['STAN_OPENCL'] = 'TRUE'
173+
elif key.startswith('O'):
174+
if has_o_flag:
175+
get_logger().warning(
176+
'More than one of (O, O1, O2, Oexperimental)'
177+
'optimizations passed. Only the last one will'
178+
'be used'
179+
)
180+
else:
181+
has_o_flag = True
168182

169183
for opt in ignore:
170184
del self._stanc_options[opt]

test/test_compiler_opts.py

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import os
44
import unittest
5+
import logging
56

67
from testfixtures import LogCapture
78

@@ -19,7 +20,7 @@ def test_opts_empty_eq(self):
1920
opts_b = None
2021
self.assertTrue(opts_a == opts_b)
2122

22-
opts_c = CompilerOptions(stanc_options={'--O'})
23+
opts_c = CompilerOptions(stanc_options={'O'})
2324
self.assertTrue(opts_a != opts_c != opts_b)
2425

2526
stanc_opts = {}
@@ -72,6 +73,44 @@ def test_opts_stanc(self):
7273
['STANCFLAGS+=--warn-uninitialized', 'STANCFLAGS+=--name=foo'],
7374
)
7475

76+
stanc_opts['O1'] = True
77+
opts = CompilerOptions(stanc_options=stanc_opts)
78+
opts.validate()
79+
self.assertEqual(
80+
opts.compose(),
81+
[
82+
'STANCFLAGS+=--warn-uninitialized',
83+
'STANCFLAGS+=--name=foo',
84+
'STANCFLAGS+=--O1',
85+
],
86+
)
87+
88+
# should add to logger
89+
stanc_opts['Oexperimental'] = True
90+
opts = CompilerOptions(stanc_options=stanc_opts)
91+
with LogCapture() as log:
92+
logging.getLogger()
93+
94+
opts.validate()
95+
96+
expect = (
97+
'More than one of (O, O1, O2, Oexperimental)'
98+
'optimizations passed. Only the last one will'
99+
'be used'
100+
)
101+
102+
log.check_present(('cmdstanpy', 'WARNING', expect))
103+
104+
self.assertEqual(
105+
opts.compose(),
106+
[
107+
'STANCFLAGS+=--warn-uninitialized',
108+
'STANCFLAGS+=--name=foo',
109+
'STANCFLAGS+=--O1',
110+
'STANCFLAGS+=--Oexperimental',
111+
],
112+
)
113+
75114
def test_opts_stanc_deprecated(self):
76115
stanc_opts = {}
77116
stanc_opts['allow_undefined'] = True

test/test_model.py

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -127,23 +127,26 @@ def test_model_bad(self):
127127
CmdStanModel(stan_file=BERN_STAN, exe_file=BERN_EXE)
128128

129129
def test_stanc_options(self):
130-
opts = {
131-
'O': True,
132-
'allow-undefined': True,
133-
'use-opencl': True,
134-
'name': 'foo',
135-
}
136-
model = CmdStanModel(
137-
stan_file=BERN_STAN, compile=False, stanc_options=opts
138-
)
139-
stanc_opts = model.stanc_options
140-
self.assertTrue(stanc_opts['O'])
141-
self.assertTrue(stanc_opts['allow-undefined'])
142-
self.assertTrue(stanc_opts['use-opencl'])
143-
self.assertTrue(stanc_opts['name'] == 'foo')
144130

145-
cpp_opts = model.cpp_options
146-
self.assertEqual(cpp_opts['STAN_OPENCL'], 'TRUE')
131+
allowed_optims = ("", "0", "1", "experimental")
132+
for optim in allowed_optims:
133+
opts = {
134+
f'O{optim}': True,
135+
'allow-undefined': True,
136+
'use-opencl': True,
137+
'name': 'foo',
138+
}
139+
model = CmdStanModel(
140+
stan_file=BERN_STAN, compile=False, stanc_options=opts
141+
)
142+
stanc_opts = model.stanc_options
143+
self.assertTrue(stanc_opts[f'O{optim}'])
144+
self.assertTrue(stanc_opts['allow-undefined'])
145+
self.assertTrue(stanc_opts['use-opencl'])
146+
self.assertTrue(stanc_opts['name'] == 'foo')
147+
148+
cpp_opts = model.cpp_options
149+
self.assertEqual(cpp_opts['STAN_OPENCL'], 'TRUE')
147150

148151
with self.assertRaises(ValueError):
149152
bad_opts = {'X': True}

0 commit comments

Comments
 (0)