Commit 66740822 authored by Oriol Tintó-Prims's avatar Oriol Tintó-Prims
Browse files

Trying to clarify retrieve_real_in_line. Using info on dimensions to find the...

Trying to clarify retrieve_real_in_line. Using info on dimensions to find the proper procedure from an interface.
parent d75f4da8
......@@ -151,6 +151,7 @@ def retrieve_real_in_line(line, vault, current_block, check=False):
if called_procedures:
for procedure_call, called_procedure in zip(procedure_calls, called_procedures):
called_arguments = find_call_arguments(procedure_call)
# TODO: NEMO specific workaround, need to be solved in a different way.
if called_procedure in ["mpp_minloc", "mpp_maxloc"]:
v, av = manage_loc_exception(called_arguments, vault, routine=current_block.routine)
all_var += v
......@@ -165,81 +166,8 @@ def retrieve_real_in_line(line, vault, current_block, check=False):
indices_to_ignore = []
if isinstance(procedure, Interface):
argument_types = [type_of_contents(argument, routine=current_block.routine, vault=vault) for argument in
called_arguments]
argument_dimensions = [dimension_of_contents(argument, routine=current_block.routine, vault=vault) for argument
in called_arguments]
keyword_arguments = [_x.split("=")[0].strip() if is_keyword_argument(_x) else False for _x in
called_arguments]
# Checking if some of the arguments does not necessarily need to be bounded to the dummy
# because there's already an existing version within the same interface with a different precision
alternative_procedures = []
for _in, _type in enumerate(argument_types):
new_argument_types = argument_types[:]
if _type == "single":
new_argument_types[_in] = "double"
elif _type == "double":
new_argument_types[_in] = "single"
else:
continue
try:
pp = match_argument_info_and_interface(new_argument_types, procedure,
argument_dimensions=argument_dimensions,
keyword_arguments=keyword_arguments, vault=vault)
alternative_procedures.append(pp)
if not check:
indices_to_ignore.append(_in)
except AssertionError:
continue
# Classical match
try:
procedure = match_argument_info_and_interface(argument_types, procedure,
argument_dimensions=argument_dimensions,
keyword_arguments=keyword_arguments, vault=vault)
except AssertionError:
if check and not alternative_procedures:
# In case there wasn't a match with the interface, check if through a variable cast it can work
# TODO: Workaround added to deal with the issue of lbc_lnk_multi in bdyice which has tons of parameters and brakes the combinatorial approach.
if called_procedure == "lbc_lnk_multi":
types_to_test = []
else:
types_to_test = create_type_combinations(argument_types)
matches = []
for t in types_to_test:
try:
m = match_argument_info_and_interface(
t,
procedure,
argument_dimensions=argument_dimensions,
keyword_arguments=keyword_arguments,
vault=vault,
)
matches.append(m)
# break
except AssertionError:
continue
if len(matches) == 1:
procedure = matches[0]
elif len(matches) > 1:
print("Multi-match!")
else:
print("No match!")
if isinstance(procedure, Interface):
print("INTERFACE: ", current_block.routine.name, procedure.name,
[at for at in argument_types], "file: ")
continue
elif check and alternative_procedures:
procedure = alternative_procedures[0]
else:
# TODO: This workaround here was required because the function dimension_of_contents still
# does not work properly.
# TODO: Probably not needed anymore
try:
procedure = match_argument_info_and_interface(argument_types, procedure,
argument_dimensions=None,
keyword_arguments=keyword_arguments, vault=vault)
except AssertionError:
raise AssertionError
procedure = find_proper_procedure_from_interface(procedure, current_block, vault, called_arguments, check,
indices_to_ignore, called_procedure )
if procedure is None:
continue
for index, argument in enumerate(called_arguments):
......@@ -327,3 +255,104 @@ def propagate_dependencies(vault, graph=None):
def var_identifier(var):
return "%s#%s#%s#%s" % (var.name, var.routine.name, var.routine.module.name, str(var.id))
def find_alternative_procedures(interface, argument_types, argument_dimensions,
keyword_arguments, vault, check, indices_to_ignore):
# Alternative procedures
alternative_procedures = []
for _in, _type in enumerate(argument_types):
new_argument_types = argument_types[:]
if _type == "single":
new_argument_types[_in] = "double"
elif _type == "double":
new_argument_types[_in] = "single"
else:
continue
try:
pp = match_argument_info_and_interface(new_argument_types, interface,
argument_dimensions=argument_dimensions,
keyword_arguments=keyword_arguments, vault=vault)
alternative_procedures.append(pp)
if not check:
indices_to_ignore.append(_in)
except AssertionError:
continue
if check and alternative_procedures:
return alternative_procedures[0]
return None
def find_proper_procedure_from_interface(interface, current_block, vault, called_arguments,
check, indices_to_ignore, called_procedure):
argument_types = [type_of_contents(argument, routine=current_block.routine, vault=vault) for argument in
called_arguments]
argument_dimensions = [dimension_of_contents(argument, routine=current_block.routine, vault=vault) for argument
in called_arguments]
keyword_arguments = [_x.split("=")[0].strip() if is_keyword_argument(_x) else False for _x in
called_arguments]
# Checking if some of the arguments does not necessarily need to be bounded to the dummy
# because there's already an existing version within the same interface with a different precision
# In case only a procedure coincides with the dimensions, return it
dimensions_of_procedures = [[v.dimension for v in [_v for _v in p.variables if _v.is_dummy_argument]]
for p in interface.procedures]
have_the_same_dimensions = [dims == argument_dimensions for dims in dimensions_of_procedures]
if sum(have_the_same_dimensions) == 1:
for procedure, coincides in zip(interface.procedures, have_the_same_dimensions):
if coincides:
return procedure
# Alternative procedures
alternative_procedures = find_alternative_procedures(interface, argument_types, argument_dimensions,
keyword_arguments, vault, check, indices_to_ignore)
if check and alternative_procedures:
return alternative_procedures
# Classical match
try:
interface = match_argument_info_and_interface(argument_types, interface,
argument_dimensions=argument_dimensions,
keyword_arguments=keyword_arguments, vault=vault)
except AssertionError:
if check and not alternative_procedures:
# In case there wasn't a match with the interface, check if through a variable cast it can work
# TODO: Workaround added to deal with the issue of lbc_lnk_multi in bdyice which has tons of parameters and brakes the combinatorial approach.
if called_procedure == "lbc_lnk_multi":
types_to_test = []
else:
types_to_test = create_type_combinations(argument_types)
matches = []
for t in types_to_test:
try:
m = match_argument_info_and_interface(
t,
interface,
argument_dimensions=argument_dimensions,
keyword_arguments=keyword_arguments,
vault=vault,
)
matches.append(m)
# break
except AssertionError:
return None
if len(matches) == 1:
return matches[0]
elif len(matches) > 1:
print("Multi-match!")
else:
print("No match!")
if isinstance(interface, Interface):
print("INTERFACE: ", current_block.routine.name, interface.name,
[at for at in argument_types], "file: ")
return None
else:
# TODO: This workaround here was required because the function dimension_of_contents still
# does not work properly.
# TODO: Probably not needed anymore
try:
interface = match_argument_info_and_interface(argument_types, interface,
argument_dimensions=None,
keyword_arguments=keyword_arguments, vault=vault)
return interface
except AssertionError:
raise AssertionError
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment