devitocodes / devito

DSL and compiler framework for automated finite-differences and stencil computation
http://www.devitoproject.org
MIT License
537 stars 221 forks source link

Equation is not affine w.r.t the target, #2289

Closed gfkdliucheng closed 6 months ago

gfkdliucheng commented 6 months ago

def solver(I, w, dt, T): """ Solve u'' + w2u = 0 for t in (0,T], u(0)=I and u'(0)=0, by a central finite difference method with time step dt. """ dt = float(dt) Nt = int(round(T/dt)) t = Dimension('t', spacing=Constant('h_t')) u = TimeFunction(name='u', dimensions=(t,), shape=(Nt+1,), space_order=2) u.data[:] = I eqn = u.dt2 + (w2)u stencil = Eq(u.forward, solve(eqn, u.forward)) op = Operator(stencil) op.apply(h_t=dt, t_M=Nt-1) return u.data, np.linspace(0, Nt*dt, Nt+1)

I = 1 w = 2np.pi dt = 0.05 num_periods = 5 P = 2np.pi/w # one period T = P*num_periods u, t = solver(I, w, dt, T)

errors are as follows: Equation is not affine w.r.t the target, falling back to standardsympy.solve that may be slow /tmp/devito-jitcache-uid1000/d8ebcf7bd2f4100cee32a40cc01b7a94b4c2516d.c: In function 'Kernel': /tmp/devito-jitcache-uid1000/d8ebcf7bd2f4100cee32a40cc01b7a94b4c2516d.c:41:57: error: array subscript is not an integer 41 | u[t + 1] = -3.94784176043574e+1Fr0h_th_t + 2.0Fu[-39r0] - 1.0Fu[-39r0 - 1]; | ^ /tmp/devito-jitcache-uid1000/d8ebcf7bd2f4100cee32a40cc01b7a94b4c2516d.c:41:74: error: array subscript is not an integer 41 | u[t + 1] = -3.94784176043574e+1Fr0h_th_t + 2.0Fu[-39r0] - 1.0Fu[-39r0 - 1]; | ^ FAILED compiler invocation: gcc -march=native -O3 -g -fPIC -Wall -std=c99 -Wno-unused-result -Wno-unused-variable -Wno-unused-but-set-variable -ffast-math -mprefer-vector-width=512 -shared -fopenmp /tmp/devito-jitcache-uid1000/d8ebcf7bd2f4100cee32a40cc01b7a94b4c2516d.c -lm -o /tmp/devito-jitcache-uid1000/d8ebcf7bd2f4100cee32a40cc01b7a94b4c2516d.so

mloubout commented 6 months ago
t = Dimension('t', spacing=Constant('h_t'))
u = TimeFunction(name='u', dimensions=(t,),
                 shape=(Nt+1,), space_order=2)
    t = TimeDimension('t', spacing=Constant('h_t'))

    u = TimeFunction(name='u', dimensions=(t,),
                    shape=(Nt+1,), space_order=2, time_order=2)

and should be all good

gfkdliucheng commented 6 months ago

e it's not a program issue, this is from the official dem

The problem still exists, it seems like it's not a program issue, this is the official demo.

mloubout commented 6 months ago

The problem still exists

Not sure what you mean, if you follow the above change it all works fine

In [16]: from devito import *
    ...: import numpy as np
    ...: 
    ...: def solver(I, w, dt, T):
    ...:     """
    ...:     Solve u'' + w**2*u = 0 for t in (0,T], u(0)=I and u'(0)=0,
    ...:     by a central finite difference method with time step dt.
    ...:     """
    ...:     dt = float(dt)
    ...:     Nt = int(round(T/dt))
    ...:     t = TimeDimension('t', spacing=Constant('h_t'))
    ...: 
    ...:     u = TimeFunction(name='u', dimensions=(t,),
    ...:                     shape=(Nt+1,), space_order=2, time_order=2)
    ...: 
    ...:     u.data[:] = I
    ...:     eqn = u.dt2 + (w**2)*u
    ...:     stencil = Eq(u.forward, solve(eqn, u.forward))
    ...:     op = Operator(stencil)
    ...:     op.apply(h_t=dt, t_M=Nt-1)
    ...:     return u.data, np.linspace(0, Nt*dt, Nt+1)
    ...: 
    ...: I = 1
    ...: w = 2*np.pi
    ...: dt = 0.05
    ...: num_periods = 5
    ...: P = 2*np.pi/w # one period
    ...: T = P*num_periods
    ...: u, t = solver(I, w, dt, T)
Operator `Kernel` ran in 0.01 s
gfkdliucheng commented 6 months ago

The problem still exists

Not sure what you mean, if you follow the above change it all works fine

In [16]: from devito import *
    ...: import numpy as np
    ...: 
    ...: def solver(I, w, dt, T):
    ...:     """
    ...:     Solve u'' + w**2*u = 0 for t in (0,T], u(0)=I and u'(0)=0,
    ...:     by a central finite difference method with time step dt.
    ...:     """
    ...:     dt = float(dt)
    ...:     Nt = int(round(T/dt))
    ...:     t = TimeDimension('t', spacing=Constant('h_t'))
    ...: 
    ...:     u = TimeFunction(name='u', dimensions=(t,),
    ...:                     shape=(Nt+1,), space_order=2, time_order=2)
    ...: 
    ...:     u.data[:] = I
    ...:     eqn = u.dt2 + (w**2)*u
    ...:     stencil = Eq(u.forward, solve(eqn, u.forward))
    ...:     op = Operator(stencil)
    ...:     op.apply(h_t=dt, t_M=Nt-1)
    ...:     return u.data, np.linspace(0, Nt*dt, Nt+1)
    ...: 
    ...: I = 1
    ...: w = 2*np.pi
    ...: dt = 0.05
    ...: num_periods = 5
    ...: P = 2*np.pi/w # one period
    ...: T = P*num_periods
    ...: u, t = solver(I, w, dt, T)
Operator `Kernel` ran in 0.01 s

Thank you, bro