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
2 changes: 1 addition & 1 deletion devito/ir/cgen/printer.py
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ def _print_DefFunction(self, expr):
return f"{expr.name}{template}({args})"

def _print_SizeOf(self, expr):
return f'sizeof({self._print(expr.intype)}{self._print(expr.stars)})'
return f'sizeof({self._print(expr.ctype)}{self._print(expr.stars)})'

def _print_MathFunction(self, expr):
return f"{self.ns(expr)}{self._print_DefFunction(expr)}"
Expand Down
36 changes: 30 additions & 6 deletions devito/symbolics/extended_sympy.py
Original file line number Diff line number Diff line change
Expand Up @@ -980,7 +980,6 @@ class SizeOf(DefFunction):
__rargs__ = ('intype', 'stars')

def __new__(cls, intype, stars=None, **kwargs):
stars = stars or ''
if not isinstance(intype, (str, ReservedWord)):
ctype = dtype_to_ctype(intype)
for k, v in ctypes_vector_mapper.items():
Expand All @@ -990,15 +989,40 @@ def __new__(cls, intype, stars=None, **kwargs):
else:
intype = ctypes_to_cstr(ctype)

newobj = super().__new__(cls, 'sizeof', arguments=f'{intype}{stars}', **kwargs)
newobj.stars = stars
newobj.intype = intype
stars = stars or ''
if not all(c == '*' for c in str(stars)):
raise ValueError("`stars` must be a string of zero or more `*` characters")

if not isinstance(intype, (str, ReservedWord)):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure i understand how can end up here. Line 983-990 already enforce that, it cannot be not a str at this point

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reconstruction voodoo IIRC

intype = ctypes_vector_mapper[intype].__name__

return newobj
return super().__new__(cls, 'sizeof', arguments=(intype, stars), **kwargs)

@property
def args(self):
return super().args[1]
return self._arguments

@property
def intype(self):
return self.arguments[0]

@cached_property
def ctype(self):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks quite weird to have to compare those str

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SizeOf was fundamentally broken even before the tweaks in the last merged PR. The new tests exposes them. I admit it gave me a headache or two this morning to come up with something "sufficiently clean", I guess that's the best I can do for now

for v in ctypes_vector_mapper.values():
if str(self.intype) == v.__name__:
return v
return self.intype

@property
def stars(self):
return self.arguments[1]

def __str__(self):
try:
intype = ctypes_to_cstr(self.ctype)
except TypeError:
intype = str(self.ctype)
return f"sizeof({intype}{self.stars})"


def rfunc(func, item, *args):
Expand Down
26 changes: 25 additions & 1 deletion tests/test_symbolics.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from ctypes import c_void_p
from ctypes import c_uint64, c_void_p

import numpy as np
import pytest
Expand Down Expand Up @@ -1262,6 +1262,30 @@ def test_print_div():
assert cstr == 'sizeof(int)/sizeof(long)'


def test_sizeof():
sizeof_ctype = SizeOf(c_uint64)
str_pointer0 = SizeOf('float', stars='*')
str_pointer1 = SizeOf('float', '*')
str_simple = SizeOf('int')
complex_size = SizeOf(np.complex64)

assert sizeof_ctype.arguments == (ReservedWord('unsigned long'), ReservedWord(''))
assert str_pointer0.arguments == (ReservedWord('float'), ReservedWord('*'))
assert complex_size.arguments == (ReservedWord('c_complex'), ReservedWord(''))

# Printing
assert ccode(sizeof_ctype) == 'sizeof(unsigned long)'
assert ccode(str_pointer0) == ccode(str_pointer1) == 'sizeof(float*)'
assert ccode(str_simple) == 'sizeof(int)'
assert str(complex_size) == 'sizeof(c_complex)'
assert ccode(complex_size) == 'sizeof(float _Complex)'

# Reconstruction
assert ccode(str_pointer0.func(*str_pointer0.args)) == 'sizeof(float*)'
assert ccode(str_pointer0.func('int', stars='**')) == 'sizeof(int**)'
assert ccode(complex_size.func(*complex_size.args)) == 'sizeof(float _Complex)'


def test_customdtype_complex():
"""
Test that `CustomDtype` doesn't brak is_imag
Expand Down
Loading