diff --git a/pystencils/typing/types.py b/pystencils/typing/types.py index dbe28449688e37ddb9d059c492e42030a608fc77..06a2888ac0e1fd3e94710bc12dee96c76bd24733 100644 --- a/pystencils/typing/types.py +++ b/pystencils/typing/types.py @@ -38,8 +38,7 @@ def numpy_name_to_c(name: str) -> str: class AbstractType(sp.Atom): - # TODO: inherits from sp.Atom because of cast function (and maybe others) - # TODO: is this necessary? + # TODO: Is it necessary to ineherit from sp.Atom? def __new__(cls, *args, **kwargs): return sp.Basic.__new__(cls) @@ -58,13 +57,16 @@ class AbstractType(sp.Atom): @abstractmethod def item_size(self) -> int: """ - Returns: WHO THE FUCK KNOWS!??!!? + Returns: Number of items. + E.g. width * item_size(basic_type) in vector's case, or simple numpy itemsize in Struct's case. """ pass class BasicType(AbstractType): - # TODO: should be a sensible interface to np.dtype + """ + BasicType is defined with a const qualifier and a np.dtype. + """ def __init__(self, dtype: Union[np.dtype, 'BasicType', str], const: bool = False): if isinstance(dtype, BasicType): @@ -86,7 +88,7 @@ class BasicType(AbstractType): return None @property - def item_size(self): # TODO: what is this? Do we want self.numpy_type.itemsize???? + def item_size(self): # TODO: Do we want self.numpy_type.itemsize???? return 1 def is_float(self): @@ -128,7 +130,9 @@ class BasicType(AbstractType): class VectorType(AbstractType): - # TODO: check with rest + """ + VectorType consists of a BasicType and a width. + """ instruction_set = None def __init__(self, base_type: BasicType, width: int): @@ -153,8 +157,8 @@ class VectorType(AbstractType): if self.instruction_set is None: return f"{self.base_type}[{self.width}]" else: - # TODO this seems super weird. the instruction_set should know how to print a type out!!! - # TODO this is error prone. base_type could be cons=True. Use dtype instead + # TODO VectorizationRevamp: this seems super weird. the instruction_set should know how to print a type out! + # TODO VectorizationRevamp: this is error prone. base_type could be cons=True. Use dtype instead if self.base_type == create_type("int64") or self.base_type == create_type("int32"): return self.instruction_set['int'] elif self.base_type == create_type("float64"): @@ -217,9 +221,10 @@ class PointerType(AbstractType): class StructType(AbstractType): - # TODO: Docs. This is a struct. A list of types (with C offsets) - # TODO StructType didn't inherit from AbstractType..... - # TODO: This is basically like a BasicType... only as struct + """ + A list of types (with C offsets). + It is implemented with uint8_t and casts to the correct datatype. + """ def __init__(self, numpy_type, const=False): self.const = const self._dtype = np.dtype(numpy_type) @@ -260,7 +265,6 @@ class StructType(AbstractType): def __str__(self): # structs are handled byte-wise - # TODO structs are weird result = "uint8_t" if self.const: result += " const" @@ -274,9 +278,7 @@ class StructType(AbstractType): def create_type(specification: Union[np.dtype, AbstractType, str]) -> AbstractType: - # TODO: Ok, this is basically useless. Except for it can differentiate between BasicType and StructType - # TODO: Everything else is already implemented inside BasicType - # TODO: Also why don't we support Vector and Pointer types??? + # TODO: Deprecated Use the constructor of BasicType or StructType instead """Creates a subclass of Type according to a string or an object of subclass Type. Args: diff --git a/pystencils/typing/utilities.py b/pystencils/typing/utilities.py index 7d37e3886dda9c9146e1d5fd0960c270d47ac312..c5612e935e04c8e30968f527dd468e88933372e1 100644 --- a/pystencils/typing/utilities.py +++ b/pystencils/typing/utilities.py @@ -4,20 +4,28 @@ from typing import Tuple, Union, Sequence import numpy as np import sympy as sp -# from pystencils.typing.leaf_typing import TypeAdder # TODO this should be leaf_typing from sympy.logic.boolalg import Boolean, BooleanFunction import pystencils from pystencils.cache import memorycache_if_hashable from pystencils.typing.types import BasicType, VectorType, PointerType, create_type -from pystencils.typing.cast_functions import CastFunc, PointerArithmeticFunc +from pystencils.typing.cast_functions import CastFunc from pystencils.typing.typed_sympy import TypedSymbol from pystencils.utils import all_equal -def typed_symbols(names, dtype, *args): - # TODO docs, type hints - symbols = sp.symbols(names, *args) +def typed_symbols(names, dtype, **kwargs): + """ + Creates TypedSymbols with the same functionality as sympy.symbols + Args: + names: See sympy.symbols + dtype: The data type all symbols will have + **kwargs: Key value arguments passed to sympy.symbols + + Returns: + TypedSymbols + """ + symbols = sp.symbols(names, **kwargs) if isinstance(symbols, Tuple): return tuple(TypedSymbol(str(s), dtype) for s in symbols) else: @@ -25,16 +33,17 @@ def typed_symbols(names, dtype, *args): def get_base_type(data_type): - # TODO: WTF is this?? DOCS!!! - # TODO: This is unsafe. - # TODO: remove - # Pointer(Pointer(int)) + """ + Returns the BasicType of a Pointer or a Vector + """ while data_type.base_type is not None: data_type = data_type.base_type return data_type def result_type(*args: np.dtype): + """Returns the type of the result if the np.dtype arguments would be collated. + We can't use numpy functionality, because numpy casts don't behave exactly like C casts""" s = sorted(args, key=lambda x: x.itemsize) def kind_to_value(kind: str) -> int: @@ -96,13 +105,11 @@ def collate_types(types: Sequence[Union[BasicType, VectorType]]): return result +# TODO get_type_of_expression should be used after leaf_typing. So no defaults should be necessary @memorycache_if_hashable(maxsize=2048) def get_type_of_expression(expr, default_float_type='double', - # TODO: we shouldn't need to have default. AST leaves should have a type default_int_type='int', - # TODO: we shouldn't need to have default. AST leaves should have a type - # TODO: we shouldn't need to have default. AST leaves should have a type symbol_type_dict=None): from pystencils.astnodes import ResolvedFieldAccess from pystencils.cpu.vectorization import vec_all, vec_any @@ -180,7 +187,7 @@ def get_type_of_expression(expr, raise NotImplementedError("Could not determine type for", expr, type(expr)) -# TODO this seems quite wrong... +# Fix for sympy versions from 1.9 sympy_version = sp.__version__.split('.') if int(sympy_version[0]) * 100 + int(sympy_version[1]) >= 109: # __setstate__ would bypass the contructor, so we remove it