cornell-zhang / heterocl

HeteroCL: A Multi-Paradigm Programming Infrastructure for Software-Defined Heterogeneous Computing
https://cornell-zhang.github.io/heterocl/
Apache License 2.0
326 stars 92 forks source link

Question about converting tensor slices #393

Closed willsharpless closed 3 years ago

willsharpless commented 3 years ago

Hi,

I have some parameter-varying models for which I use (4-degree) polynomials to fit the parameter dependence. Previously with static parameters, I had no problem using lists of python floats for hcl computation. However, to incorporate the pv, I passed lambda functions to evaluate the polynomials where I pull the coefficients of the polynomials from lists and this produces a TypeError about TensorSlice's. See this minimized example,

n=1
### Import gLV parameter interpolation coeffs
p_ic = np.random((n + n**2, 4))
p_ic = p_ic.tolist()

### Transform coeffs into array of functions (respective 4-degree polynomials)
def ipoly(i): return lambda x: p_ic[i][0] + p_ic[i][1]*x + p_ic[i][2]*x**2 + p_ic[i][3]*x**3
p_T = [ipoly(i) for i in range(np.shape(p_ic)[0])]
r = p_T[:n]
A = [[p_T[j] for j in range(i,i+n)] for i in range(n,n**2+1,n)]

then later trying to use this function

def dynamics(self, t, state):
    x1_dot = hcl.scalar(0, "x1_dot")
    T_dot = hcl.scalar(0, "T_dot")

    # for evaluating the parameter function arrays r, A
    Tcurr = state[1]

    # compute dynamics by evaluating
    x1_dot[0] = state[0] * ( self.r[0](Tcurr) + self.A[0][0](Tcurr) * state[0] )

    # # works with static params/lists of floats
    # x1_dot[0] = state[0] * ( self.r[0] + self.A[0][0] * state[0] )

    return (x1_dot[0], T_dot[0])

returns an error trace that ends with:

File "/Users/optimized_dp-master/dynamics/gLV_systems.py", line 386, in dynamics
    x1_dot[0] = state[0] * ( self.r[0](Tcurr) + self.A[0][0](Tcurr) * state[0] )
File "gLV_TempVar.py", line 46, in <lambda>
    def ipoly(i): return lambda x: p_ic[i][0] + p_ic[i][1]*x + p_ic[i][2]*x**2 + p_ic[i][3]*x**3
TypeError: unsupported operand type(s) for ** or pow(): 'TensorSlice' and 'int'

I tried to copy copy.copy(p_ic[i][0]) around the indexed values but it didn't help.

Is there a fix to this so that I don't have to significantly change the definition of r or A in the global scope? If not what are my options? Thank you in advance.

seanlatias commented 3 years ago

Currently, we don't support Python ** operation. Can you try hcl.power(x, y) instead? It returns x**y.

willsharpless commented 3 years ago

Thank you! I actually just wrote out x*x and x*x*x so that I could do np math with them too but your suggestion nonetheless fixed my problem.