 changed status to open
Alternative syntax for `# pythran block`
Issue #9
closed
An alternative syntax for # pythran block
could be:
import numpy as np # pythran import numpy as np from fluidpythran import pythran_block class MyClass: def __init__(self, a, b): self.a = a self.b = b @pythran_block def compute(self, n): a = self.a b = self.b # pythran block ( # float[][] a, b; # int n # ) > result # pythran block ( # float[][][] a, b; # int n # ) > result result = np.zeros_like(a) for _ in range(n): result += a ** 2 + b ** 3 # pythran end block return result
Advantages
 less invasive than the first syntax (see https://bitbucket.org/fluiddyn/fluidpythran/src/default/doc/examples/class_blocks.py)
 dynamically generated method: no run time performance problem (which are usually negligible anyway).
Drawbacks
 more magic and less explicit
 we would need dynamically generated Python method > less simple run type exceptions
 with this alternative syntax, we really need the
> result
(but it could be written only once)
Comments (6)

reporter 
reporter  edited description

reporter  edited description

It would be a welcome change, but I also agree it is a bit of magic as only parts of the function are pythranized. An advantage would be toggling between pure python and pythranized versions is easier. Dealing with multiple blocks within the function is not easy however.

reporter Just to see what it gives, what it gives on a real function:
class TimeSteppingPseudoSpectral(TimeSteppingBase): @pythran_block def _time_step_RK4_fluidpythran(self): dt = self.deltat diss, diss2 = self.exact_linear_coefs.get_updated_coefs() compute_tendencies = self.sim.tendencies_nonlin state_spect = self.sim.state.state_spect tendencies_0 = compute_tendencies() state_spect_tmp = self._state_spect_tmp state_spect_tmp1 = self._state_spect_tmp1 state_spect_np12_approx1 = state_spect_tmp1 # based on approximation 0 # pythran block ( # complex128[][][] state_spect, state_spect_tmp, # tendencies_0, state_spect_np12_approx1; # float64[][] diss, diss2; # float dt # ) # pythran block ( # complex128[][][] state_spect, state_spect_tmp, # tendencies_0, state_spect_np12_approx1; # complex128[][][] diss, diss2; # float dt # ) # pythran block ( # complex128[][][] state_spect, state_spect_tmp, # tendencies_0, state_spect_np12_approx1; # float64[][][] diss, diss2; # float dt # ) # pythran block ( # complex128[][][][] state_spect, state_spect_tmp, # tendencies_0, state_spect_np12_approx1; # float64[][][] diss, diss2; # float dt # ) state_spect_tmp[:] = (state_spect + dt / 6 * tendencies_0) * diss state_spect_np12_approx1[:] = ( state_spect + dt / 2 * tendencies_0 ) * diss2 # pythran end block tendencies_1 = compute_tendencies( state_spect_np12_approx1, old=tendencies_0 ) del state_spect_np12_approx1 state_spect_np12_approx2 = state_spect_tmp1 # based on approximation 1 # pythran block ( # complex128[][][] state_spect, state_spect_tmp, # state_spect_np12_approx2, tendencies_1; # float64[][] diss2; # float dt # ) # pythran block ( # complex128[][][] state_spect, state_spect_tmp, # state_spect_np12_approx2, tendencies_1; # complex128[][][] diss2; # float dt # ) # pythran block ( # complex128[][][] state_spect, state_spect_tmp, # state_spect_np12_approx2, tendencies_1; # float64[][][] diss2; # float dt # ) # pythran block ( # complex128[][][][] state_spect, state_spect_tmp, # state_spect_np12_approx2, tendencies_1; # float64[][][] diss2; # float dt # ) state_spect_tmp[:] += dt / 3 * diss2 * tendencies_1 state_spect_np12_approx2[:] = ( state_spect * diss2 + dt / 2 * tendencies_1 ) # pythran end block tendencies_2 = compute_tendencies( state_spect_np12_approx2, old=tendencies_1 ) del state_spect_np12_approx2 state_spect_np1_approx = state_spect_tmp1 # based on approximation 2 # pythran block ( # complex128[][][] state_spect, state_spect_tmp, # state_spect_np1_approx, tendencies_2; # float64[][] diss, diss2; # float dt # ) # pythran block ( # complex128[][][] state_spect, state_spect_tmp, # state_spect_np1_approx, tendencies_2; # complex128[][][] diss, diss2; # float dt # ) # pythran block ( # complex128[][][] state_spect, state_spect_tmp, # state_spect_np1_approx, tendencies_2; # float64[][][] diss, diss2; # float dt # ) # pythran block ( # complex128[][][][] state_spect, state_spect_tmp, # state_spect_np1_approx, tendencies_2; # float64[][][] diss, diss2; # float dt # ) state_spect_tmp[:] += dt / 3 * diss2 * tendencies_2 state_spect_np1_approx[:] = ( state_spect * diss + dt * diss2 * tendencies_2 ) # pythran end block tendencies_3 = compute_tendencies( state_spect_np1_approx, old=tendencies_2 ) del state_spect_np1_approx # result using the 4 approximations # pythran block ( # complex128[][][] state_spect, state_spect_tmp, tendencies_3; # float dt # ) # pythran block ( # complex128[][][][] state_spect, state_spect_tmp, tendencies_3; # float dt # ) state_spect[:] = state_spect_tmp + dt / 6 * tendencies_3 # pythran end block

reporter  changed status to closed
Obsolete (see issue
#29)  Log in to comment
Indeed, it is really nicer...
Regarding the problem of the dynamically generated method leading to less simple exceptions, we have the same problem with
# pythran class
.