Skip to content

Commit

Permalink
pr #2231 Merge branch 'master' into 2213_psyir_public_var_error
Browse files Browse the repository at this point in the history
  • Loading branch information
rupertford committed Jul 27, 2023
2 parents 279d8aa + d2fe7a3 commit ef3f0b1
Show file tree
Hide file tree
Showing 28 changed files with 691 additions and 451 deletions.
4 changes: 4 additions & 0 deletions changelog
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,10 @@
179) PR #2230 for #2228. Improve reporting of errors due to kernel
functors not explicitly included in algorithm use statements.

180) PR #2207 for #1419. Split the DataSymbol constant_value attribute
into is_constant (bool) and initial_value (PSyIR Node). This allows
parsing Fortran declarations with initial_value that are not constant.

release 2.3.1 17th of June 2022

1) PR #1747 for #1720. Adds support for If blocks to PSyAD.
Expand Down
21 changes: 14 additions & 7 deletions doc/developer_guide/psyir_symbols.rst
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,8 @@ the subclass. For example:

Sometimes providing additional properties of the new sub-class is desirable,
and sometimes even mandatory (e.g. a `DataSymbol` must always have a datatype
and optionally a constant_value parameter). For this reason the specialise
and optionally is_constant and initial_value parameters). For this reason
the specialise
method implementation provides the same interface as the constructor
of the symbol type in order to provide the same behaviour and default values
as the constructor. For instance, in the `DataSymbol` case the following
Expand All @@ -241,15 +242,21 @@ specialisations are possible:
>>> sym = Symbol("a")
>>> # The following statement would fail because it doesn't have a datatype
>>> # sym.specialise(DataSymbol)
>>> # The following statement is valid and constant_value is set to None
>>> # The following statement is valid (in this case initial_value will
>>> # default to None and is_constant to False):
>>> sym.specialise(DataSymbol, datatype=INTEGER_TYPE)

>>> sym2 = Symbol("b")
>>> # The following statement would fail because the constant_value doesn't
>>> # match the datatype of the symbol
>>> # sym2.specialise(DataSymbol, datatype=INTEGER_TYPE, constant_value=3.14)
>>> # The following statement is valid and constant_value is set to 3
>>> sym2.specialise(DataSymbol, datatype=INTEGER_TYPE, constant_value=3)
>>> # The following statement would fail because the initial_value doesn't
>>> # match the datatype of the symbol:
>>> # sym2.specialise(DataSymbol, datatype=INTEGER_TYPE, initial_value=3.14)
>>> # The following statement is valid and initial_value is set to 3
>>> # (and is_constant will default to False):
>>> sym2.specialise(DataSymbol, datatype=INTEGER_TYPE, initial_value=3)
>>> print(sym2.initial_value)
Literal[value:'3', Scalar<INTEGER, UNDEFINED>]
>>> print(sym2.is_constant)
False


Routine Interfaces
Expand Down
8 changes: 5 additions & 3 deletions doc/user_guide/psyir.rst
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ example:
>>> int_type = ScalarType(ScalarType.Intrinsic.INTEGER,
... ScalarType.Precision.SINGLE)
>>> bool_type = ScalarType(ScalarType.Intrinsic.BOOLEAN, 4)
>>> symbol = DataSymbol("rdef", int_type, constant_value=4)
>>> symbol = DataSymbol("rdef", int_type, initial_value=4)
>>> scalar_type = ScalarType(ScalarType.Intrinsic.REAL, symbol)

For convenience PSyclone predefines a number of scalar datatypes:
Expand Down Expand Up @@ -522,10 +522,12 @@ as keyword arguments. For example, the following code:
symbol_table.new_symbol(root_name="something",
symbol_type=DataSymbol,
datatype=REAL_TYPE,
constant_value=3)
is_constant=True,
initial_value=3)
declares a symbol named "something" of REAL_TYPE datatype where the
constant_value argument will be passed to the DataSymbol constructor.
``is_constant`` and ``initial_value`` arguments will be passed to the
DataSymbol constructor.

An example of using the ``new_symbol()`` method can be found in the
PSyclone ``examples/psyir`` directory.
Expand Down
4 changes: 2 additions & 2 deletions examples/psyir/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
C representation of the PSyIR.
'''
from __future__ import print_function
from psyclone.psyir.nodes import Reference, Literal, UnaryOperation, \
BinaryOperation, NaryOperation, Assignment, IfBlock, Loop, \
Container, ArrayReference, Call, Routine, FileContainer
Expand Down Expand Up @@ -80,7 +79,8 @@ def create_psyir_tree():
real_kind = symbol_table.new_symbol(root_name="RKIND",
symbol_type=DataSymbol,
datatype=INTEGER_TYPE,
constant_value=8)
is_constant=True,
initial_value=8)
routine_symbol = RoutineSymbol("my_sub")

# Array using precision defined by another symbol
Expand Down
5 changes: 2 additions & 3 deletions examples/psyir/create_structure_types.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# -----------------------------------------------------------------------------
# BSD 3-Clause License
#
# Copyright (c) 2020-2022, Science and Technology Facilities Council
# Copyright (c) 2020-2023, Science and Technology Facilities Council
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -43,7 +43,6 @@
>>> python create_structure_types.py
'''
from __future__ import print_function
from psyclone.psyir.nodes import Literal, KernelSchedule, Container, \
StructureReference, ArrayOfStructuresReference, Assignment, \
BinaryOperation, Range
Expand All @@ -58,7 +57,7 @@
CONTAINER_SYMBOL_TABLE = SymbolTable()
REAL_KIND = CONTAINER_SYMBOL_TABLE.new_symbol(
root_name="RKIND", symbol_type=DataSymbol, datatype=INTEGER_TYPE,
constant_value=8)
is_constant=True, initial_value=8)

# Shorthand for a scalar type with REAL_KIND precision
SCALAR_TYPE = ScalarType(ScalarType.Intrinsic.REAL, REAL_KIND)
Expand Down
Binary file modified psyclone.pdf
Binary file not shown.
3 changes: 2 additions & 1 deletion src/psyclone/psyad/domain/common/adjoint_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ def create_real_comparison(sym_table, kernel, var1, var2):
overall_tol = sym_table.new_symbol("overall_tolerance",
symbol_type=DataSymbol,
datatype=var1.datatype,
constant_value=INNER_PRODUCT_TOLERANCE)
is_constant=True,
initial_value=INNER_PRODUCT_TOLERANCE)
# TODO #1161 - the PSyIR does not support `SPACING`
assign = freader.psyir_from_statement(
f"MachineTol = SPACING ( MAX( ABS({var1.name}), ABS({var2.name}) ) )",
Expand Down
14 changes: 9 additions & 5 deletions src/psyclone/psyad/tl2ad.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,9 +279,9 @@ def _add_precision_symbol(symbol, table):
if symbol.name in table:
return

if symbol.is_automatic or symbol.is_modulevar:
table.add(symbol.copy())
elif symbol.is_import:
if symbol.is_import:
# Handle imported symbols first because they may also be constants
# while the reverse is not true.
contr_sym = symbol.interface.container_symbol
try:
kind_contr_sym = table.lookup(contr_sym.name)
Expand All @@ -292,6 +292,8 @@ def _add_precision_symbol(symbol, table):
kind_symbol = symbol.copy()
kind_symbol.interface = ImportInterface(kind_contr_sym)
table.add(kind_symbol)
elif symbol.is_automatic or symbol.is_modulevar or symbol.is_constant:
table.add(symbol.copy())
else:
raise NotImplementedError(
f"One or more variables have a precision specified by symbol "
Expand Down Expand Up @@ -396,7 +398,8 @@ def generate_adjoint_test(tl_psyir, ad_psyir,
dim_size_sym = symbol_table.new_symbol("array_extent",
symbol_type=DataSymbol,
datatype=INTEGER_TYPE,
constant_value=TEST_ARRAY_DIM_SIZE)
is_constant=True,
initial_value=TEST_ARRAY_DIM_SIZE)

# Create symbols for the results of the inner products
inner1 = symbol_table.new_symbol("inner1", symbol_type=DataSymbol,
Expand Down Expand Up @@ -439,7 +442,8 @@ def generate_adjoint_test(tl_psyir, ad_psyir,
new_dim_args_map[arg] = symbol_table.new_symbol(
arg.name, symbol_type=DataSymbol,
datatype=arg.datatype,
constant_value=Reference(dim_size_sym))
is_constant=True,
initial_value=Reference(dim_size_sym))

# Create necessary variables for the kernel arguments.
inputs = []
Expand Down
28 changes: 18 additions & 10 deletions src/psyclone/psyir/backend/fortran.py
Original file line number Diff line number Diff line change
Expand Up @@ -553,15 +553,17 @@ def gen_vardecl(self, symbol, include_visibility=False):
:rtype: str
:raises VisitorError: if the symbol is of DeferredType.
:raises VisitorError: if the symbol is of UnknownType other than \
:raises VisitorError: if the symbol is of UnknownType other than
UnknownFortranType.
:raises VisitorError: if the symbol is of known type but does not \
specify a variable declaration (it is not a local declaration or \
:raises VisitorError: if the symbol is of known type but does not
specify a variable declaration (it is not a local declaration or
an argument declaration).
:raises VisitorError: if the symbol is a runtime constant but does not
have a StaticInterface.
:raises InternalError: if the symbol is a ContainerSymbol or an import.
:raises InternalError: if the symbol is a RoutineSymbol other than \
:raises InternalError: if the symbol is a RoutineSymbol other than
UnknownFortranType.
:raises InternalError: if visibility is to be included but is not \
:raises InternalError: if visibility is to be included but is not
either PUBLIC or PRIVATE.
'''
Expand Down Expand Up @@ -644,9 +646,15 @@ def gen_vardecl(self, symbol, include_visibility=False):
# Specify name
result += f" :: {symbol.name}"

# Specify initialization expression
if isinstance(symbol, DataSymbol) and symbol.is_constant:
result += " = " + self._visit(symbol.constant_value)
# Specify initialisation expression
if isinstance(symbol, DataSymbol) and symbol.initial_value:
if not symbol.is_static:
raise VisitorError(
f"{type(symbol).__name__} '{symbol.name}' has an initial "
f"value ({self._visit(symbol.initial_value)}) and "
f"therefore (in Fortran) must have a StaticInterface. "
f"However it has an interface of '{symbol.interface}'.")
result += " = " + self._visit(symbol.initial_value)

return result + "\n"

Expand Down Expand Up @@ -848,10 +856,10 @@ def _gen_parameter_decls(self, symbol_table, is_module_scope=False):
decln_inputs[symbol.name] = set()
read_write_info = ReadWriteInfo()
self._dep_tools.get_input_parameters(read_write_info,
symbol.constant_value)
symbol.initial_value)
# The dependence analysis tools do not include symbols used to
# define precision so check for those here.
for lit in symbol.constant_value.walk(Literal):
for lit in symbol.initial_value.walk(Literal):
if isinstance(lit.datatype.precision, DataSymbol):
read_write_info.add_read(
Signature(lit.datatype.precision.name))
Expand Down
Loading

0 comments on commit ef3f0b1

Please sign in to comment.