Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions benchmarks/benchmark.py
Original file line number Diff line number Diff line change
Expand Up @@ -403,10 +403,10 @@ def benchmark(
n,
(arg_overload, cpp_arg_template, stan_arg),
) in enumerate(zip(arg_overloads, cpp_arg_templates, stan_args)):
if stan_arg.endswith("]"):
stan_arg2, vec = stan_arg.split("[")
n_vec, inner_type = parse_array(stan_arg)
if n_vec:
benchmark_name += (
"_" + arg_overload + "_" + stan_arg2 + str(len(vec))
"_" + arg_overload + "_" + inner_type + str(n_vec)
)
else:
benchmark_name += "_" + arg_overload + "_" + stan_arg
Expand Down
3 changes: 2 additions & 1 deletion test/expressions/expression_test_helpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,8 @@ struct test_functor {
auto operator()(T... args) const {
using Ret_scal = return_type_t<T...>;
return stan::test::make_arg<Eigen::Matrix<Ret_scal, Eigen::Dynamic, 1>>(
math::sum(std::vector<Ret_scal>{sum_if_number(args)...}));
math::sum(std::vector<Ret_scal>{
static_cast<Ret_scal>(sum_if_number(args))...}));
}
};

Expand Down
8 changes: 4 additions & 4 deletions test/expressions/test_expression_testing_framework.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,25 @@ def assertStdoutContains(self, content, stdout, stderr):
self.assertTrue(content in stdout, msg = error_template.format(content, stdout, stderr))

def testExpressionNotAcceptedFailure(self):
return_code, stdout, stderr = self.runCommand((sys.executable, "./runTests.py", "./test/expressions", "-e1", "--make-only", "--only-functions", "matrix bad_no_expressions(matrix)"))
return_code, stdout, stderr = self.runCommand((sys.executable, "./runTests.py", "./test/expressions", "-e1", "--make-only", "--only-functions", "bad_no_expressions(matrix) => real"))
self.assertNotEqual(return_code, 0)

def testMultipleEvaluationsFailure(self):
return_code, stdout, stderr = self.runCommand((sys.executable, "./runTests.py", "./test/expressions", "-e1", "--only-functions", "matrix bad_multiple_evaluations(matrix)"))
return_code, stdout, stderr = self.runCommand((sys.executable, "./runTests.py", "./test/expressions", "-e1", "--only-functions", "bad_multiple_evaluations(matrix) => matrix"))
self.assertNotEqual(return_code, 0)
self.assertStdoutContains("[ FAILED ] ExpressionTestPrim.bad_multiple_evaluations0", stdout, stderr)
self.assertStdoutContains("[ FAILED ] ExpressionTestRev.bad_multiple_evaluations0", stdout, stderr)
self.assertStdoutContains("[ FAILED ] ExpressionTestFwd.bad_multiple_evaluations0", stdout, stderr)

def testWrongResultFailure(self):
return_code, stdout, stderr = self.runCommand((sys.executable, "./runTests.py", "./test/expressions", "-e1", "--only-functions", "real bad_wrong_value(matrix)"))
return_code, stdout, stderr = self.runCommand((sys.executable, "./runTests.py", "./test/expressions", "-e1", "--only-functions", "bad_wrong_value(matrix) => real"))
self.assertNotEqual(return_code, 0)
self.assertStdoutContains("[ FAILED ] ExpressionTestPrim.bad_wrong_value0", stdout, stderr)
self.assertStdoutContains("[ FAILED ] ExpressionTestRev.bad_wrong_value0", stdout, stderr)
self.assertStdoutContains("[ FAILED ] ExpressionTestFwd.bad_wrong_value0", stdout, stderr)

def testWrongDerivativeFailure(self):
return_code, stdout, stderr = self.runCommand((sys.executable, "./runTests.py", "./test/expressions", "-e1", "--only-functions", "real bad_wrong_derivatives(vector)"))
return_code, stdout, stderr = self.runCommand((sys.executable, "./runTests.py", "./test/expressions", "-e1", "--only-functions", "bad_wrong_derivatives(vector) => real"))
self.assertNotEqual(return_code, 0)
self.assertStdoutContains("[ OK ] ExpressionTestPrim.bad_wrong_derivatives0", stdout, stderr)
self.assertStdoutContains("[ FAILED ] ExpressionTestRev.bad_wrong_derivatives0", stdout, stderr)
Expand Down
137 changes: 76 additions & 61 deletions test/sig_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,28 +12,42 @@

arg_types = {
"int": "int",
"int[]": "std::vector<int>",
"int[,]": "std::vector<std::vector<int>>",
"array[] int": "std::vector<int>",
"array[,] int": "std::vector<std::vector<int>>",
"real": "SCALAR",
"real[]": "std::vector<SCALAR>",
"real[,]": "std::vector<std::vector<SCALAR>>",
"array[] real": "std::vector<SCALAR>",
"array[,] real": "std::vector<std::vector<SCALAR>>",
"vector": "Eigen::Matrix<SCALAR, Eigen::Dynamic, 1>",
"vector[]": "std::vector<Eigen::Matrix<SCALAR, Eigen::Dynamic, 1>>",
"array[] vector": "std::vector<Eigen::Matrix<SCALAR, Eigen::Dynamic, 1>>",
"row_vector": "Eigen::Matrix<SCALAR, 1, Eigen::Dynamic>",
"row_vector[]": "std::vector<Eigen::Matrix<SCALAR, 1, Eigen::Dynamic>>",
"array[] row_vector": "std::vector<Eigen::Matrix<SCALAR, 1, Eigen::Dynamic>>",
"matrix": "Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic>",
"rng": "std::minstd_rand",
"ostream_ptr": "std::ostream*",
}

scalar_stan_types = ("int", "real", "rng", "ostream_ptr")

def parse_array(stan_arg):
"""
parses stan array type
:param stan_arg: stan type, possibly an array
:return: number of nested arrays, inner type
"""
if stan_arg.startswith("array["):
print(stan_arg)
commas, inner_type = stan_arg.lstrip("array[").split("]")
return len(commas)+1, inner_type
return 0, stan_arg

def get_cpp_type(stan_type):
n_vec = 0
if stan_type.endswith("]"):
stan_type, vec = stan_type.split("[")
n_vec = len(vec)
res = arg_types[stan_type]
"""
Determines cpp type that implements given stan type.
:param stan_type: stan type
:return: cpp type
"""
n_vec, inner_type = parse_array(stan_type)
res = arg_types[inner_type]
for i in range(n_vec):
res = "std::vector<{}>".format(res)
return res
Expand Down Expand Up @@ -149,51 +163,51 @@ def get_cpp_type(stan_type):
]

internal_signatures = [
"vector unit_vector_constrain(vector)",
"vector unit_vector_constrain(vector, real)",
"vector unit_vector_free(vector)",
"vector positive_ordered_constrain(vector)",
"vector positive_ordered_constrain(vector, real)",
"vector positive_ordered_free(vector)",
"vector ordered_constrain(vector)",
"vector ordered_constrain(vector, real)",
"vector ordered_free(vector)",
"vector simplex_constrain(vector)",
"vector simplex_constrain(vector, real)",
"vector simplex_free(vector)",
"int is_cholesky_factor(matrix)",
"int is_cholesky_factor_corr(matrix)",
"int is_column_index(matrix, int)",
"int is_column_index(vector, int)",
"int is_corr_matrix(matrix)",
"int is_cholesky_factor(matrix)",
"int is_lower_triangular(matrix)",
"int is_mat_finite(matrix)",
"int is_mat_finite(vector)",
"int is_matching_dims(matrix, matrix)",
"int is_matching_dims(vector, matrix)",
"int is_matching_dims(matrix, vector)",
"int is_matching_dims(row_vector, matrix)",
"int is_matching_dims(matrix, row_vector)",
"int is_matching_dims(matrix, matrix)",
"int is_matching_dims(row_vector, row_vector)",
"int is_matching_dims(vector, row_vector)",
"int is_matching_dims(row_vector, vector)",
"int is_matching_dims(vector, vector)",
"int is_pos_definite(matrix)",
"int is_square(matrix)",
"int is_square(vector)",
"int is_square(row_vector)",
"int is_symmetric(matrix)",
"int is_unit_vector(vector)",
"unit_vector_constrain(vector) => vector",
"unit_vector_constrain(vector, real) => vector",
"unit_vector_free(vector) => vector",
"positive_ordered_constrain(vector) => vector",
"positive_ordered_constrain(vector, real) => vector",
"positive_ordered_free(vector) => vector",
"ordered_constrain(vector) => vector",
"ordered_constrain(vector, real) => vector",
"ordered_free(vector) => vector",
"simplex_constrain(vector) => vector",
"simplex_constrain(vector, real) => vector",
"simplex_free(vector) => vector",
"is_cholesky_factor(matrix) => int",
"is_cholesky_factor_corr(matrix) => int",
"is_column_index(matrix, int) => int",
"is_column_index(vector, int) => int",
"is_corr_matrix(matrix) => int",
"is_cholesky_factor(matrix) => int",
"is_lower_triangular(matrix) => int",
"is_mat_finite(matrix) => int",
"is_mat_finite(vector) => int",
"is_matching_dims(matrix, matrix) => int",
"is_matching_dims(vector, matrix) => int",
"is_matching_dims(matrix, vector) => int",
"is_matching_dims(row_vector, matrix) => int",
"is_matching_dims(matrix, row_vector) => int",
"is_matching_dims(matrix, matrix) => int",
"is_matching_dims(row_vector, row_vector) => int",
"is_matching_dims(vector, row_vector) => int",
"is_matching_dims(row_vector, vector) => int",
"is_matching_dims(vector, vector) => int",
"is_pos_definite(matrix) => int",
"is_square(matrix) => int",
"is_square(vector) => int",
"is_square(row_vector) => int",
"is_symmetric(matrix) => int",
"is_unit_vector(vector) => int",
# variadic functions: these are tested with one vector for variadic args
"real[,] ode_adams((real, vector, ostream_ptr, vector) => vector, vector, real, real[], ostream_ptr, vector)",
"real[,] ode_adams_tol((real, vector, ostream_ptr, vector) => vector, vector, real, real[], real, real, real, ostream_ptr, vector)",
"real[,] ode_bdf((real, vector, ostream_ptr, vector) => vector, vector, real, real[], ostream_ptr, vector)",
"real[,] ode_bdf_tol((real, vector, ostream_ptr, vector) => vector, vector, real, real[], real, real, real, ostream_ptr, vector)",
"real[,] ode_rk45((real, vector, ostream_ptr, vector) => vector, vector, real, real[], ostream_ptr, vector)",
"real[,] ode_rk45_tol((real, vector, ostream_ptr, vector) => vector, vector, real, real[], real, real, real, ostream_ptr, vector)",
"real reduce_sum(real[], int, vector)",
"ode_adams((real, vector, ostream_ptr, vector) => vector, vector, real, array[] real, ostream_ptr, vector) => array[,] real",
"ode_adams_tol((real, vector, ostream_ptr, vector) => vector, vector, real, array[] real, real, real, real, ostream_ptr, vector) => array[,] real",
"ode_bdf((real, vector, ostream_ptr, vector) => vector, vector, real, array[] real, ostream_ptr, vector) => array[,] real",
"ode_bdf_tol((real, vector, ostream_ptr, vector) => vector, vector, real, array[] real, real, real, real, ostream_ptr, vector) => array[,] real",
"ode_rk45((real, vector, ostream_ptr, vector) => vector, vector, real, array[] real, ostream_ptr, vector) => array[,] real",
"ode_rk45_tol((real, vector, ostream_ptr, vector) => vector, vector, real, array[] real, real, real, real, ostream_ptr, vector) => array[,] real",
"reduce_sum(array[] real, int, vector) => real",
]


Expand All @@ -208,7 +222,7 @@ def parse_signature_file(sig_file):
for signature in sig_file:
signature = part_sig + signature
part_sig = ""
if not signature.endswith(")\n"):
if signature.endswith(",\n"):
part_sig = signature
continue
res.append(signature)
Expand Down Expand Up @@ -249,11 +263,12 @@ def parse_signature(signature):
:param signature: stanc3 function signature
:return: return type, fucntion name and list of function argument types
"""
return_type, rest = signature.split(" ", 1)
rest, return_type = signature.rsplit(" => ", 1)
function_name, rest = rest.split("(", 1)
args = re.findall(r"(?:[(][^()]+[)][^,()]+)|(?:[^,()]+(?:,*[]])?)", rest)
args = [i.strip() for i in args if i.strip()]
return return_type, function_name, args
args = re.findall(r"(?:[(][^()]+[)][^,()]+)|(?:[^,()]+(?:,*[]][^,()]+)?)", rest)
# regex parts: ^^^^^^functor^^^^^^ ^^^^any other arg^^^^^^^
args = [i.lstrip("data").strip() if "data" in i else i.strip() for i in args if i.strip()]
return return_type.strip(), function_name, args


def handle_function_list(functions_input):
Expand Down Expand Up @@ -283,6 +298,6 @@ def reference_vector_argument(arg):
:param arg: argument
:return: reference argument
"""
if arg in ("real[]", "row_vector"):
if arg in ("array[] real", "row_vector"):
return "vector"
return arg