def algorithm(A): B = hcl.bitcast(A, hcl.Float(32)) return B
def graph_6D(): V_f = hcl.placeholder(tuple(g.pts_each_dim), name="V_f", dtype=hcl.Float()) V_init = hcl.placeholder(tuple(g.pts_each_dim), name="V_init", dtype=hcl.Float()) l0 = hcl.placeholder(tuple(g.pts_each_dim), name="l0", dtype=hcl.Float()) t = hcl.placeholder((2, ), name="t", dtype=hcl.Float()) # Positions vector x1 = hcl.placeholder((g.pts_each_dim[0], ), name="x1", dtype=hcl.Float()) x2 = hcl.placeholder((g.pts_each_dim[1], ), name="x2", dtype=hcl.Float()) x3 = hcl.placeholder((g.pts_each_dim[2], ), name="x3", dtype=hcl.Float()) x4 = hcl.placeholder((g.pts_each_dim[3], ), name="x4", dtype=hcl.Float()) x5 = hcl.placeholder((g.pts_each_dim[4], ), name="x5", dtype=hcl.Float()) x6 = hcl.placeholder((g.pts_each_dim[5], ), name="x6", dtype=hcl.Float()) def graph_create(V_new, V_init, x1, x2, x3, x4, x5, x6, t, l0): # Specify intermediate tensors deriv_diff1 = hcl.compute(V_init.shape, lambda *x: 0, "deriv_diff1") deriv_diff2 = hcl.compute(V_init.shape, lambda *x: 0, "deriv_diff2") deriv_diff3 = hcl.compute(V_init.shape, lambda *x: 0, "deriv_diff3") deriv_diff4 = hcl.compute(V_init.shape, lambda *x: 0, "deriv_diff4") deriv_diff5 = hcl.compute(V_init.shape, lambda *x: 0, "deriv_diff5") deriv_diff6 = hcl.compute(V_init.shape, lambda *x: 0, "deriv_diff6") # Maximum derivative for each dim max_deriv1 = hcl.scalar(-1e9, "max_deriv1") max_deriv2 = hcl.scalar(-1e9, "max_deriv2") max_deriv3 = hcl.scalar(-1e9, "max_deriv3") max_deriv4 = hcl.scalar(-1e9, "max_deriv4") max_deriv5 = hcl.scalar(-1e9, "max_deriv5") max_deriv6 = hcl.scalar(-1e9, "max_deriv6") # Min derivative for each dim min_deriv1 = hcl.scalar(1e9, "min_deriv1") min_deriv2 = hcl.scalar(1e9, "min_deriv2") min_deriv3 = hcl.scalar(1e9, "min_deriv3") min_deriv4 = hcl.scalar(1e9, "min_deriv4") min_deriv5 = hcl.scalar(1e9, "min_deriv5") min_deriv6 = hcl.scalar(1e9, "min_deriv6") # These variables are used to dissipation calculation max_alpha1 = hcl.scalar(-1e9, "max_alpha1") max_alpha2 = hcl.scalar(-1e9, "max_alpha2") max_alpha3 = hcl.scalar(-1e9, "max_alpha3") max_alpha4 = hcl.scalar(-1e9, "max_alpha4") max_alpha5 = hcl.scalar(-1e9, "max_alpha5") max_alpha6 = hcl.scalar(-1e9, "max_alpha6") def step_bound(): # Function to calculate time step stepBoundInv = hcl.scalar(0, "stepBoundInv") stepBound = hcl.scalar(0, "stepBound") stepBoundInv[0] = max_alpha1[0] / g.dx[0] + max_alpha2[0] / g.dx[1] + max_alpha3[0] / g.dx[2] + max_alpha4[ 0] / g.dx[3] \ + max_alpha5[0] / g.dx[4] + max_alpha6[0] / g.dx[5] stepBound[0] = 0.8 / stepBoundInv[0] with hcl.if_(stepBound > t[1] - t[0]): stepBound[0] = t[1] - t[0] # Update the lower time ranges t[0] = t[0] + stepBound[0] # t[0] = min_deriv2[0] return stepBound[0] def maxVWithV0(i, j, k, l, m, n): # Take the max with hcl.if_(V_new[i, j, k, l, m, n] < l0[i, j, k, l, m, n]): V_new[i, j, k, l, m, n] = l0[i, j, k, l, m, n] # Max(V, g ) def maxVWithCStraint(i, j, k, l, m, n): with hcl.if_(V_new[i, j, k, l, m, n] < 5.0): V_new[i, j, k, l, m, n] = 1.0 # Min with V_before def minVWithVInit(i, j, k, l, m, n): with hcl.if_(V_new[i, j, k, l, m, n] > V_init[i, j, k, l, m, n]): V_new[i, j, k, l, m, n] = V_init[i, j, k, l, m, n] # Calculate Hamiltonian for every grid point in V_init with hcl.Stage("Hamiltonian"): with hcl.for_(0, V_init.shape[0], name="i") as i: with hcl.for_(0, V_init.shape[1], name="j") as j: with hcl.for_(0, V_init.shape[2], name="k") as k: with hcl.for_(0, V_init.shape[3], name="l") as l: with hcl.for_(0, V_init.shape[4], name="m") as m: with hcl.for_(0, V_init.shape[5], name="n") as n: # Variables to calculate dV_dx dV_dx1_L = hcl.scalar(0, "dV_dx1_L") dV_dx1_R = hcl.scalar(0, "dV_dx1_R") dV_dx1 = hcl.scalar(0, "dV_dx1") dV_dx2_L = hcl.scalar(0, "dV_dx2_L") dV_dx2_R = hcl.scalar(0, "dV_dx2_R") dV_dx2 = hcl.scalar(0, "dV_dx2") dV_dx3_L = hcl.scalar(0, "dV_dx3_L") dV_dx3_R = hcl.scalar(0, "dV_dx3_R") dV_dx3 = hcl.scalar(0, "dV_dx3") dV_dx4_L = hcl.scalar(0, "dV_dx4_L") dV_dx4_R = hcl.scalar(0, "dV_dx4_R") dV_dx4 = hcl.scalar(0, "dV_dx4") dV_dx5_L = hcl.scalar(0, "dV_dx5_L") dV_dx5_R = hcl.scalar(0, "dV_dx5_R") dV_dx5 = hcl.scalar(0, "dV_dx5") dV_dx6_L = hcl.scalar(0, "dV_dx6_L") dV_dx6_R = hcl.scalar(0, "dV_dx6_R") dV_dx6 = hcl.scalar(0, "dV_dx6") # No tensor slice operation # dV_dx_L[0], dV_dx_R[0] = spa_derivX(i, j, k) dV_dx1_L[0], dV_dx1_R[0] = spa_derivX1_6d( i, j, k, l, m, n, V_init, g) dV_dx2_L[0], dV_dx2_R[0] = spa_derivX2_6d( i, j, k, l, m, n, V_init, g) dV_dx3_L[0], dV_dx3_R[0] = spa_derivX3_6d( i, j, k, l, m, n, V_init, g) dV_dx4_L[0], dV_dx4_R[0] = spa_derivX4_6d( i, j, k, l, m, n, V_init, g) dV_dx5_L[0], dV_dx5_R[0] = spa_derivX5_6d( i, j, k, l, m, n, V_init, g) dV_dx6_L[0], dV_dx6_R[0] = spa_derivX6_6d( i, j, k, l, m, n, V_init, g) # Saves spatial derivative diff into tables deriv_diff1[i, j, k, l, m, n] = dV_dx1_R[0] - dV_dx1_L[0] deriv_diff2[i, j, k, l, m, n] = dV_dx2_R[0] - dV_dx2_L[0] deriv_diff3[i, j, k, l, m, n] = dV_dx3_R[0] - dV_dx3_L[0] deriv_diff4[i, j, k, l, m, n] = dV_dx4_R[0] - dV_dx4_L[0] deriv_diff5[i, j, k, l, m, n] = dV_dx5_R[0] - dV_dx5_L[0] deriv_diff6[i, j, k, l, m, n] = dV_dx6_R[0] - dV_dx6_L[0] # Calculate average gradient dV_dx1[0] = (dV_dx1_L + dV_dx1_R) / 2 dV_dx2[0] = (dV_dx2_L + dV_dx2_R) / 2 dV_dx3[0] = (dV_dx3_L + dV_dx3_R) / 2 dV_dx4[0] = (dV_dx4_L + dV_dx4_R) / 2 dV_dx5[0] = (dV_dx5_L + dV_dx5_R) / 2 dV_dx6[0] = (dV_dx6_L + dV_dx6_R) / 2 # Find optimal control uOpt = my_object.opt_ctrl( t, (x1[i], x2[j], x3[k], x4[l], x5[m], x6[n]), (dV_dx1[0], dV_dx2[0], dV_dx3[0], dV_dx4[0], dV_dx5[0], dV_dx6[0])) # Find optimal disturbance dOpt = my_object.optDstb( (dV_dx1[0], dV_dx2[0], dV_dx3[0], dV_dx4[0], dV_dx5[0], dV_dx6[0])) # Find rates of changes based on dynamics equation dx1_dt, dx2_dt, dx3_dt, dx4_dt, dx5_dt, dx6_dt = my_object.dynamics( t, (x1[i], x2[j], x3[k], x4[l], x5[m], x6[n]), uOpt, dOpt) # Calculate Hamiltonian terms: V_new[i, j, k, l, m, n] = -(dx1_dt * dV_dx1[0] + dx2_dt * dV_dx2[0] + dx3_dt * dV_dx3[0] + dx4_dt * dV_dx4[0] + dx5_dt * dV_dx5[0] + dx6_dt * dV_dx6[0]) # Get derivMin with hcl.if_(dV_dx1_L[0] < min_deriv1[0]): min_deriv1[0] = dV_dx1_L[0] with hcl.if_(dV_dx1_R[0] < min_deriv1[0]): min_deriv1[0] = dV_dx1_R[0] with hcl.if_(dV_dx2_L[0] < min_deriv2[0]): min_deriv2[0] = dV_dx2_L[0] with hcl.if_(dV_dx2_R[0] < min_deriv2[0]): min_deriv2[0] = dV_dx2_R[0] with hcl.if_(dV_dx3_L[0] < min_deriv3[0]): min_deriv3[0] = dV_dx3_L[0] with hcl.if_(dV_dx3_R[0] < min_deriv3[0]): min_deriv3[0] = dV_dx3_R[0] with hcl.if_(dV_dx4_L[0] < min_deriv4[0]): min_deriv4[0] = dV_dx4_L[0] with hcl.if_(dV_dx4_R[0] < min_deriv4[0]): min_deriv4[0] = dV_dx4_R[0] with hcl.if_(dV_dx5_L[0] < min_deriv5[0]): min_deriv5[0] = dV_dx5_L[0] with hcl.if_(dV_dx5_R[0] < min_deriv5[0]): min_deriv5[0] = dV_dx5_R[0] with hcl.if_(dV_dx6_L[0] < min_deriv6[0]): min_deriv6[0] = dV_dx6_L[0] with hcl.if_(dV_dx6_R[0] < min_deriv6[0]): min_deriv6[0] = dV_dx6_R[0] # Get derivMax with hcl.if_(dV_dx1_L[0] > max_deriv1[0]): max_deriv1[0] = dV_dx1_L[0] with hcl.if_(dV_dx1_R[0] > max_deriv1[0]): max_deriv1[0] = dV_dx1_R[0] with hcl.if_(dV_dx2_L[0] > max_deriv2[0]): max_deriv2[0] = dV_dx2_L[0] with hcl.if_(dV_dx2_R[0] > max_deriv2[0]): max_deriv2[0] = dV_dx2_R[0] with hcl.if_(dV_dx3_L[0] > max_deriv3[0]): max_deriv3[0] = dV_dx3_L[0] with hcl.if_(dV_dx3_R[0] > max_deriv3[0]): max_deriv3[0] = dV_dx3_R[0] with hcl.if_(dV_dx4_L[0] > max_deriv4[0]): max_deriv4[0] = dV_dx4_L[0] with hcl.if_(dV_dx4_R[0] > max_deriv4[0]): max_deriv4[0] = dV_dx4_R[0] with hcl.if_(dV_dx5_L[0] > max_deriv5[0]): max_deriv5[0] = dV_dx5_L[0] with hcl.if_(dV_dx5_R[0] > max_deriv5[0]): max_deriv5[0] = dV_dx5_R[0] with hcl.if_(dV_dx6_L[0] > max_deriv6[0]): max_deriv6[0] = dV_dx6_L[0] with hcl.if_(dV_dx6_R[0] > max_deriv6[0]): max_deriv6[0] = dV_dx6_R[0] # Calculate dissipation amount with hcl.Stage("Dissipation"): # uOptL1 = hcl.scalar(0, "uOptL1") # uOptL2 = hcl.scalar(0, "uOptL2") # uOptL3 = hcl.scalar(0, "uOptL3") # uOptL4 = hcl.scalar(0, "uOptL4") # uOptU1 = hcl.scalar(0, "uOptU1") # uOptU2 = hcl.scalar(0, "uOptU2") # uOptU3 = hcl.scalar(0, "uOptU3") # uOptU4 = hcl.scalar(0, "uOptU4") # dOptL1 = hcl.scalar(0, "dOptL1") # dOptL2 = hcl.scalar(0, "dOptL2") # dOptL3 = hcl.scalar(0, "dOptL3") # dOptL4 = hcl.scalar(0, "dOptL4") # dOptU1 = hcl.scalar(0, "dOptU1") # dOptU2 = hcl.scalar(0, "dOptU2") # dOptU3 = hcl.scalar(0, "dOptU3") # dOptU4 = hcl.scalar(0, "dOptU4") # Storing alphas alpha1 = hcl.scalar(0, "alpha1") alpha2 = hcl.scalar(0, "alpha2") alpha3 = hcl.scalar(0, "alpha3") alpha4 = hcl.scalar(0, "alpha4") alpha5 = hcl.scalar(0, "alpha5") alpha6 = hcl.scalar(0, "alpha6") # Find LOWER BOUND optimal disturbance dOptL = my_object.optDstb( (min_deriv1[0], min_deriv2[0], min_deriv3[0], min_deriv4[0], min_deriv5[0], min_deriv6[0])) # Find UPPER BOUND optimal disturbance dOptU = my_object.optDstb( (max_deriv1[0], max_deriv2[0], max_deriv3[0], max_deriv4[0], max_deriv5[0], max_deriv6[0])) with hcl.for_(0, V_init.shape[0], name="i") as i: with hcl.for_(0, V_init.shape[1], name="j") as j: with hcl.for_(0, V_init.shape[2], name="k") as k: with hcl.for_(0, V_init.shape[3], name="l") as l: with hcl.for_(0, V_init.shape[4], name="m") as m: with hcl.for_(0, V_init.shape[5], name="n") as n: dx_LL1 = hcl.scalar(0, "dx_LL1") dx_LL2 = hcl.scalar(0, "dx_LL2") dx_LL3 = hcl.scalar(0, "dx_LL3") dx_LL4 = hcl.scalar(0, "dx_LL4") dx_LL5 = hcl.scalar(0, "dx_LL5") dx_LL6 = hcl.scalar(0, "dx_LL6") dx_UL1 = hcl.scalar(0, "dx_UL1") dx_UL2 = hcl.scalar(0, "dx_UL2") dx_UL3 = hcl.scalar(0, "dx_UL3") dx_UL4 = hcl.scalar(0, "dx_UL4") dx_UL5 = hcl.scalar(0, "dx_UL5") dx_UL6 = hcl.scalar(0, "dx_UL6") # dx_LU1 = hcl.scalar(0, "dx_LU1") dx_LU2 = hcl.scalar(0, "dx_LU2") dx_LU3 = hcl.scalar(0, "dx_LU3") dx_LU4 = hcl.scalar(0, "dx_LU4") dx_LU5 = hcl.scalar(0, "dx_LU5") dx_LU6 = hcl.scalar(0, "dx_LU6") dx_UU1 = hcl.scalar(0, "dx_UU1") dx_UU2 = hcl.scalar(0, "dx_UU2") dx_UU3 = hcl.scalar(0, "dx_UU3") dx_UU4 = hcl.scalar(0, "dx_UU4") dx_UU5 = hcl.scalar(0, "dx_UU5") dx_UU6 = hcl.scalar(0, "dx_UU6") # Find LOWER BOUND optimal control uOptL = my_object.opt_ctrl( t, (x1[i], x2[j], x3[k], x4[l], x5[m], x6[n]), (min_deriv1[0], min_deriv2[0], min_deriv3[0], min_deriv4[0], min_deriv5[0], min_deriv6[0])) # Find UPPER BOUND optimal control uOptU = my_object.opt_ctrl( t, (x1[i], x2[j], x3[k], x4[l], x5[m], x6[n]), (max_deriv1[0], max_deriv2[0], max_deriv3[0], max_deriv4[0], max_deriv5[0], max_deriv6[0])) # Get upper bound and lower bound rates of changes dx_LL1[0], dx_LL2[0], dx_LL3[0], dx_LL4[ 0], dx_LL5[0], dx_LL6[ 0] = my_object.dynamics( t, (x1[i], x2[j], x3[k], x4[l], x5[m], x6[n]), uOptL, dOptL) # Get absolute value of each dx_LL1[0] = my_abs(dx_LL1[0]) dx_LL2[0] = my_abs(dx_LL2[0]) dx_LL3[0] = my_abs(dx_LL3[0]) dx_LL4[0] = my_abs(dx_LL4[0]) dx_LL5[0] = my_abs(dx_LL5[0]) dx_LL6[0] = my_abs(dx_LL6[0]) dx_UL1[0], dx_UL2[0], dx_UL3[0], dx_UL4[ 0], dx_UL5[0], dx_UL6[ 0] = my_object.dynamics( t, (x1[i], x2[j], x3[k], x4[l], x5[m], x6[n]), uOptU, dOptL) # Get absolute value of each dx_UL1[0] = my_abs(dx_UL1[0]) dx_UL2[0] = my_abs(dx_UL2[0]) dx_UL3[0] = my_abs(dx_UL3[0]) dx_UL4[0] = my_abs(dx_UL4[0]) dx_UL5[0] = my_abs(dx_UL5[0]) dx_UL6[0] = my_abs(dx_UL6[0]) # Set maximum alphas alpha1[0] = my_max(dx_UL1[0], dx_LL1[0]) alpha2[0] = my_max(dx_UL2[0], dx_LL2[0]) alpha3[0] = my_max(dx_UL3[0], dx_LL3[0]) alpha4[0] = my_max(dx_UL4[0], dx_LL4[0]) alpha5[0] = my_max(dx_UL5[0], dx_LL5[0]) alpha6[0] = my_max(dx_UL6[0], dx_LL6[0]) dx_LU1[0], dx_LU2[0], dx_LU3[0], dx_LU4[ 0], dx_LU5[0], dx_LU6[ 0] = my_object.dynamics( t, (x1[i], x2[j], x3[k], x4[l], x5[m], x6[n]), uOptL, dOptU) # Get absolute value of each dx_LU1[0] = my_abs(dx_LU1[0]) dx_LU2[0] = my_abs(dx_LU2[0]) dx_LU3[0] = my_abs(dx_LU3[0]) dx_LU4[0] = my_abs(dx_LU4[0]) dx_LU5[0] = my_abs(dx_LU5[0]) dx_LU6[0] = my_abs(dx_LU6[0]) alpha1[0] = my_max(alpha1[0], dx_LU1[0]) alpha2[0] = my_max(alpha2[0], dx_LU2[0]) alpha3[0] = my_max(alpha3[0], dx_LU3[0]) alpha4[0] = my_max(alpha4[0], dx_LU4[0]) alpha5[0] = my_max(alpha5[0], dx_LU5[0]) alpha6[0] = my_max(alpha6[0], dx_LU6[0]) dx_UU1[0], dx_UU2[0], dx_UU3[0], dx_UU4[ 0], dx_UU5[0], dx_UU6[ 0] = my_object.dynamics( t, (x1[i], x2[j], x3[k], x4[l], x5[m], x6[n]), uOptU, dOptU) dx_UU1[0] = my_abs(dx_UU1[0]) dx_UU2[0] = my_abs(dx_UU2[0]) dx_UU3[0] = my_abs(dx_UU3[0]) dx_UU4[0] = my_abs(dx_UU4[0]) dx_UU5[0] = my_abs(dx_UU5[0]) dx_UU6[0] = my_abs(dx_UU6[0]) alpha1[0] = my_max(alpha1[0], dx_UU1[0]) alpha2[0] = my_max(alpha2[0], dx_UU2[0]) alpha3[0] = my_max(alpha3[0], dx_UU3[0]) alpha4[0] = my_max(alpha4[0], dx_UU4[0]) alpha5[0] = my_max(alpha5[0], dx_UU5[0]) alpha6[0] = my_max(alpha6[0], dx_UU6[0]) diss = hcl.scalar(0, "diss") diss[0] = 0.5 * (deriv_diff1[i, j, k, l, m, n] * alpha1[0] + deriv_diff2[ i, j, k, l, m, n] * alpha2[0] \ + deriv_diff3[i, j, k, l, m, n] * alpha3[0] + deriv_diff4[ i, j, k, l, m, n] * alpha4[0] \ + deriv_diff5[i, j, k, l, m, n] * alpha5[0] + deriv_diff6[ i, j, k, l, m, n] * alpha6[0]) # Finally V_new[i, j, k, l, m, n] = -(V_new[i, j, k, l, m, n] - diss[0]) # Get maximum alphas in each dimension # Calculate alphas with hcl.if_(alpha1 > max_alpha1): max_alpha1[0] = alpha1[0] with hcl.if_(alpha2 > max_alpha2): max_alpha2[0] = alpha2[0] with hcl.if_(alpha3 > max_alpha3): max_alpha3[0] = alpha3[0] with hcl.if_(alpha4 > max_alpha4): max_alpha4[0] = alpha4[0] with hcl.if_(alpha5 > max_alpha5): max_alpha5[0] = alpha5[0] with hcl.if_(alpha6 > max_alpha6): max_alpha6[0] = alpha6[0] # Determine time step delta_t = hcl.compute((1, ), lambda x: step_bound(), name="delta_t") # hcl.update(t, lambda x: t[x] + delta_t[x]) # Integrate # if compMethod == 'HJ_PDE': result = hcl.update( V_new, lambda i, j, k, l, m, n: V_init[i, j, k, l, m, n] + V_new[ i, j, k, l, m, n] * delta_t[0]) if compMethod == 'maxVWithV0': result = hcl.update( V_new, lambda i, j, k, l, m, n: maxVWithV0(i, j, k, l, m, n)) if compMethod == 'maxVWithCStraint': result = hcl.update( V_new, lambda i, j, k, l, m, n: maxVWithCStraint(i, j, k, l, m, n)) if compMethod == 'minVWithVInit': result = hcl.update( V_new, lambda i, j, k, l, m, n: minVWithVInit(i, j, k, l, m, n)) # Copy V_new to V_init hcl.update(V_init, lambda i, j, k, l, m, n: V_new[i, j, k, l, m, n]) return result s = hcl.create_schedule([V_f, V_init, x1, x2, x3, x4, x5, x6, t, l0], graph_create) ##################### CODE OPTIMIZATION HERE ########################### print("Optimizing\n") # Accessing the hamiltonian and dissipation stage s_H = graph_create.Hamiltonian s_D = graph_create.Dissipation # Thread parallelize hamiltonian and dissipation s[s_H].parallel(s_H.i) s[s_D].parallel(s_D.i) # Inspect IR # if args.llvm: # print(hcl.lower(s)) # Return executable return (hcl.build(s))
def relay_parser(model, shape, frontend='keras', dtype=hcl.Float()): hcl.init(dtype) defined_inputs = {} node_map = {} for item in shape: defined_inputs[item] = None if frontend == 'keras': try: keras_model = keras.models.load_model(model) except BaseException: keras_model = model module, params = relay_front.from_keras(keras_model, shape) if debug_mode: print(module) body = module.functions[module.global_var_map_["main"]] build_node_map(body.body, True, node_map, [0]) def gen_call(node, name, opname): args = [] var = [] type_dict = {name: Call} env = {} for arg in node.args: temp_var, temp_type, temp_env = parse_rec(arg) if isinstance(arg, Var): var.append(temp_var[0]) var = partial_flatten(var) args.append(temp_env[fst(temp_var[0])]) elif isinstance(arg, Constant): var.append(temp_var) var = partial_flatten(var) args.append(temp_env[temp_var[0]]) env.update(temp_env) elif isinstance(arg, Call): var.append(temp_var) var = partial_flatten(var) args.append(temp_env[temp_var[-1]][0]) env.update(temp_env) elif isinstance(arg, TupleGetItem): if temp_env[temp_var[-1]][1] == Var: item, item_name, temp_type, temp_env, inst_var = get_item( temp_env[temp_var[-1]]) var.append(inst_var) var = partial_flatten(var) args.append(item) env.update(temp_env) else: args.append(temp_env[temp_var[-1]][0]) var.append(temp_var) var = partial_flatten(var) env.update(temp_env) elif isinstance(arg, Tuple): tup_var = temp_var[-1] temp_var = partial_flatten(temp_var) var.append(temp_var) var = partial_flatten(var) tup_env = {} t_name = temp_env[tup_var][0] t_res = temp_env[tup_var][1] t_dict = temp_env[tup_var][2] t_env = temp_env[tup_var][3] tup_env[tup_var] = (t_name, t_res, t_dict, t_env) args.append(tup_var) env.update(tup_env) update_if(env, t_env) type_dict.update(temp_type) var.append(name) kwargs = {} for i in range(len(args)): if hasattr(args[i], "name"): if args[i].name in var: env[args[i].name] = args[i] if opname in _attrib: for attr in _attrib[opname]: kwargs[attr] = getattr(node.attrs, attr) env[name] = (name, _convert_map[opname], tuple(args), kwargs) else: env[name] = (name, tuple(args)) if isinstance(node.op, Function): temp_var, temp_type, temp_env = parse_rec(node.op) var.append(opname) type_dict.update({opname: Function}) env[opname] = (temp_var, temp_type, temp_env) return var, type_dict, env def parse_rec(node, init=False, global_env={}): if isinstance(node, (Call, Tuple)): if node_map[node][1] > 0: name = "%" + str(node_map[node][0]) var = [name] type_dict = {} env = {} env[name] = global_env[name] return var, type_dict, env else: node_map[node][1] += 1 if isinstance(node, Function): name = "%" + str(len(node_map)) if debug_mode: print("Function: ", name) var = [name] type_dict = {name: Function} env = {} temp_var, temp_type, temp_env = parse_rec(node.body, global_env) if init: var = temp_var type_dict = temp_type env = temp_env else: env = update_if( env, { name: (full_flatten(temp_var), temp_type, temp_env, len(node_map)) }) elif isinstance(node, Var): name = node.name_hint var = [name] type_dict = {name: Var} ty = node.type_annotation env = {} if node.name_hint in shape: dtype = ty.dtype if defined_inputs[name] is None: env[name] = hcl.placeholder(shape[name], name, dtype) defined_inputs[name] = env[name] else: env[name] = defined_inputs[name] else: env[name] = get_type(ty, name) if debug_mode: print("Var: " + name) elif isinstance(node, Constant): name = "con(" + str(node.data) + ")" if debug_mode: print("Constant: " + name) var = [name] type_dict = {name: Constant} env = {} env[name] = hcl.scalar(float(node.data.asnumpy())) elif isinstance(node, TupleGetItem): index = node.index tup = node.tuple_value if isinstance(tup, Var): var_name = tup.vid.name_hint name = "get_" + var_name + "_" + str(index) ty = tup.type_annotation var = [name] type_dict = {name: TupleGetItem} env = {} env[name] = (name, Var, get_type(ty, var_name), index) elif isinstance(tup, Call): name = '%' + str(node_map[tup][0]) get_name = 'get' + str(node_map[tup][0]) + "_" + str(index) if not hasattr(tup.op, "name"): opname = '%' + str(node_map[tup][0] - 1) else: opname = tup.op.name var, type_dict, env = gen_call(tup, name, opname) var.append(get_name) type_dict.update({get_name: TupleGetItem}) env[get_name] = (get_name, TupleGetItem, name, index) if debug_mode: print("TupleGet: " + get_name) elif isinstance(node, Let): name = node.var.vid.name_hint if debug_mode: print("Let: " + name) var = [name] type_dict = {name: Let} env = {} args = [] kwargs = {} ty = node.var.type_annotation bind_var = get_type(ty, name) value = node.value temp_var, temp_type, temp_env = parse_rec(value) if isinstance(value, Var): env = update_if(env, { name: (Var, bind_var, temp_type, temp_env[fst(temp_var[0])]) }) elif isinstance(value, Function): env = update_if(env, { name: (Function, bind_var, temp_var, temp_type, temp_env) }) elif isinstance(value, Tuple): env = update_if( env, {name: (Tuple, bind_var, temp_var, temp_type, temp_env)}) elif isinstance(value, TupleGetItem): item, get_name, get_type_, get_env, _ = get_item( temp_env[temp_var[0]]) temp_var = [get_name] temp_type = {get_name: get_type_} temp_env = {get_name: item} env = update_if( env, { name: (get_type_[get_name], bind_var, temp_var, temp_type, temp_env) }) elif isinstance(value, Call): if not hasattr(value.op, "name"): opname = "%" + str(node_map[tup][0]) else: opname = value.op.name args = temp_env[temp_var[-1]][0] env = update_if(env, temp_env) for i in range(len(args)): if hasattr(args[i], "name"): if args[i].name in temp_var: env[args[i].name] = args[i] if opname in _attrib: for attr in _attrib[opname]: kwargs[attr] = getattr(value.attrs, attr) env[name] = (Call, bind_var, temp_var, temp_type, temp_env) type_dict = update_if(type_dict, temp_type) temp_var, temp_type, temp_env = parse_rec(node.body) var.append(temp_var) type_dict = update_if(type_dict, temp_type) env = update_if(env, temp_env) elif isinstance(node, If): print("If not instantiated yet") elif isinstance(node, Tuple): name = "%" + str(node_map[node][0]) if debug_mode: print("Tuple: " + name) var = [] type_dict = {name: Tuple} env = {} tup_type_dict = {} tup_res = [] tup = [] tup_env = {} for field in node.fields: temp_var, temp_type, temp_env = parse_rec(field) tup.append(temp_var) tup_res.append(temp_var[-1]) tup_type_dict.update(temp_type) tup_env.update(temp_env) var.append(tup) var.append([name]) var = partial_flatten(var) update_if(type_dict, tup_type_dict) env.update(tup_env) env[name] = (name, tup_res, tup_type_dict, tup_env) elif isinstance(node, Call): if not hasattr(node.op, "name"): opname = '%' + str(node_map[node][0]) else: opname = node.op.name name = '%' + str(node_map[node][0]) if debug_mode: print("Call " + name + ":" + opname) var, type_dict, env = gen_call(node, name, opname) if not isinstance(node, Function): global_env[name] = env[name] return var, type_dict, env out_var, out_type, out_env = parse_rec(body, True) return out_var, out_type, out_env, params
def value_iteration_6D(MDP_obj): def solve_Vopt(Vopt, actions, intermeds, trans, interpV, gamma, epsilon, iVals, sVals, bounds, goal, ptsEachDim, count, maxIters, useNN): reSweep = hcl.scalar(1, "reSweep") oldV = hcl.scalar(0, "oldV") newV = hcl.scalar(0, "newV") with hcl.while_(hcl.and_(reSweep[0] == 1, count[0] < maxIters[0])): reSweep[0] = 0 # Perform value iteration by sweeping in direction 1 with hcl.Stage("Sweep_1"): with hcl.for_(0, Vopt.shape[0], name="i") as i: with hcl.for_(0, Vopt.shape[1], name="j") as j: with hcl.for_(0, Vopt.shape[2], name="k") as k: with hcl.for_(0, Vopt.shape[3], name="l") as l: with hcl.for_(0, Vopt.shape[4], name="m") as m: with hcl.for_(0, Vopt.shape[5], name="n") as n: oldV[0] = Vopt[i, j, k, l, m, n] updateVopt(MDP_obj, i, j, k, l, m, n, iVals, sVals, actions, Vopt, intermeds, trans, interpV, gamma, bounds, goal, ptsEachDim, useNN) newV[0] = Vopt[i, j, k, l, m, n] evaluateConvergence( newV, oldV, epsilon, reSweep) count[0] += 1 # Perform value iteration by sweeping in direction 2 with hcl.Stage("Sweep_2"): with hcl.if_(useNN[0] == 1): with hcl.for_(1, Vopt.shape[0] + 1, name="i") as i: with hcl.for_(1, Vopt.shape[1] + 1, name="j") as j: with hcl.for_(1, Vopt.shape[2] + 1, name="k") as k: with hcl.for_(0, Vopt.shape[3], name="l") as l: with hcl.for_(0, Vopt.shape[4], name="m") as m: with hcl.for_(0, Vopt.shape[5], name="n") as n: i2 = Vopt.shape[0] - i j2 = Vopt.shape[1] - j k2 = Vopt.shape[2] - k oldV[0] = Vopt[i2, j2, k2, l, m, n] updateVopt(MDP_obj, i2, j2, k2, l, m, n, iVals, sVals, actions, Vopt, intermeds, trans, interpV, gamma, bounds, goal, ptsEachDim, useNN) newV[0] = Vopt[i2, j2, k2, l, m, n] evaluateConvergence( newV, oldV, epsilon, reSweep) count[0] += 1 # Perform value iteration by sweeping in direction 3 with hcl.Stage("Sweep_3"): with hcl.if_(useNN[0] == 1): with hcl.for_(1, Vopt.shape[0] + 1, name="i") as i: with hcl.for_(0, Vopt.shape[1], name="j") as j: with hcl.for_(0, Vopt.shape[2], name="k") as k: with hcl.for_(0, Vopt.shape[3], name="l") as l: with hcl.for_(0, Vopt.shape[4], name="m") as m: with hcl.for_(0, Vopt.shape[5], name="n") as n: i2 = Vopt.shape[0] - i oldV[0] = Vopt[i2, j, k, l, m, n] updateVopt(MDP_obj, i2, j, k, l, m, n, iVals, sVals, actions, Vopt, intermeds, trans, interpV, gamma, bounds, goal, ptsEachDim, useNN) newV[0] = Vopt[i2, j, k, l, m, n] evaluateConvergence( newV, oldV, epsilon, reSweep) count[0] += 1 # Perform value iteration by sweeping in direction 4 with hcl.Stage("Sweep_4"): with hcl.if_(useNN[0] == 1): with hcl.for_(0, Vopt.shape[0], name="i") as i: with hcl.for_(1, Vopt.shape[1] + 1, name="j") as j: with hcl.for_(0, Vopt.shape[2], name="k") as k: with hcl.for_(0, Vopt.shape[3], name="l") as l: with hcl.for_(0, Vopt.shape[4], name="m") as m: with hcl.for_(0, Vopt.shape[5], name="n") as n: j2 = Vopt.shape[1] - j oldV[0] = Vopt[i, j2, k, l, m, n] updateVopt(MDP_obj, i, j2, k, l, m, n, iVals, sVals, actions, Vopt, intermeds, trans, interpV, gamma, bounds, goal, ptsEachDim, useNN) newV[0] = Vopt[i, j2, k, l, m, n] evaluateConvergence( newV, oldV, epsilon, reSweep) count[0] += 1 # Perform value iteration by sweeping in direction 5 with hcl.Stage("Sweep_5"): with hcl.if_(useNN[0] == 1): with hcl.for_(0, Vopt.shape[0], name="i") as i: with hcl.for_(0, Vopt.shape[1], name="j") as j: with hcl.for_(1, Vopt.shape[2] + 1, name="k") as k: with hcl.for_(0, Vopt.shape[3], name="l") as l: with hcl.for_(0, Vopt.shape[4], name="m") as m: with hcl.for_(0, Vopt.shape[5], name="n") as n: k2 = Vopt.shape[2] - k oldV[0] = Vopt[i, j, k2, l, m, n] updateVopt(MDP_obj, i, j, k2, l, m, n, iVals, sVals, actions, Vopt, intermeds, trans, interpV, gamma, bounds, goal, ptsEachDim, useNN) newV[0] = Vopt[i, j, k2, l, m, n] evaluateConvergence( newV, oldV, epsilon, reSweep) count[0] += 1 # Perform value iteration by sweeping in direction 6 with hcl.Stage("Sweep_6"): with hcl.if_(useNN[0] == 1): with hcl.for_(1, Vopt.shape[0] + 1, name="i") as i: with hcl.for_(1, Vopt.shape[1] + 1, name="j") as j: with hcl.for_(0, Vopt.shape[2], name="k") as k: with hcl.for_(0, Vopt.shape[3], name="l") as l: with hcl.for_(0, Vopt.shape[4], name="m") as m: with hcl.for_(0, Vopt.shape[5], name="n") as n: i2 = Vopt.shape[0] - i j2 = Vopt.shape[1] - j oldV[0] = Vopt[i2, j2, k, l, m, n] updateVopt(MDP_obj, i2, j2, k, l, m, n, iVals, sVals, actions, Vopt, intermeds, trans, interpV, gamma, bounds, goal, ptsEachDim, useNN) newV[0] = Vopt[i2, j2, k, l, m, n] evaluateConvergence( newV, oldV, epsilon, reSweep) count[0] += 1 # Perform value iteration by sweeping in direction 7 with hcl.Stage("Sweep_7"): with hcl.if_(useNN[0] == 1): with hcl.for_(1, Vopt.shape[0] + 1, name="i") as i: with hcl.for_(0, Vopt.shape[1], name="j") as j: with hcl.for_(1, Vopt.shape[2] + 1, name="k") as k: with hcl.for_(0, Vopt.shape[3], name="l") as l: with hcl.for_(0, Vopt.shape[4], name="m") as m: with hcl.for_(0, Vopt.shape[5], name="n") as n: i2 = Vopt.shape[0] - i k2 = Vopt.shape[2] - k oldV[0] = Vopt[i2, j, k2, l, m, n] updateVopt(MDP_obj, i2, j, k2, l, m, n, iVals, sVals, actions, Vopt, intermeds, trans, interpV, gamma, bounds, goal, ptsEachDim, useNN) newV[0] = Vopt[i2, j, k2, l, m, n] evaluateConvergence( newV, oldV, epsilon, reSweep) count[0] += 1 # Perform value iteration by sweeping in direction 8 with hcl.Stage("Sweep_8"): with hcl.if_(useNN[0] == 1): with hcl.for_(0, Vopt.shape[0], name="i") as i: with hcl.for_(1, Vopt.shape[1] + 1, name="j") as j: with hcl.for_(1, Vopt.shape[2] + 1, name="k") as k: with hcl.for_(0, Vopt.shape[3], name="l") as l: with hcl.for_(0, Vopt.shape[4], name="m") as m: with hcl.for_(0, Vopt.shape[5], name="n") as n: j2 = Vopt.shape[1] - j k2 = Vopt.shape[2] - k oldV[0] = Vopt[i, j2, k2, l, m, n] updateVopt(MDP_obj, i, j2, k2, l, m, n, iVals, sVals, actions, Vopt, intermeds, trans, interpV, gamma, bounds, goal, ptsEachDim, useNN) newV[0] = Vopt[i, j2, k2, l, m, n] evaluateConvergence( newV, oldV, epsilon, reSweep) count[0] += 1 ###################################### SETUP PLACEHOLDERS ###################################### # Initialize the HCL environment hcl.init() hcl.config.init_dtype = hcl.Float() # NOTE: trans is a tensor with size = maximum number of transitions # NOTE: intermeds must have size [# possible actions] # NOTE: transition must have size [# possible outcomes, #state dimensions + 1] Vopt = hcl.placeholder(tuple(MDP_obj._ptsEachDim), name="Vopt", dtype=hcl.Float()) gamma = hcl.placeholder((0, ), "gamma") count = hcl.placeholder((0, ), "count") maxIters = hcl.placeholder((0, ), "maxIters") epsilon = hcl.placeholder((0, ), "epsilon") actions = hcl.placeholder(tuple(MDP_obj._actions.shape), name="actions", dtype=hcl.Float()) intermeds = hcl.placeholder(tuple([MDP_obj._actions.shape[0]]), name="intermeds", dtype=hcl.Float()) trans = hcl.placeholder(tuple(MDP_obj._trans.shape), name="successors", dtype=hcl.Float()) bounds = hcl.placeholder(tuple(MDP_obj._bounds.shape), name="bounds", dtype=hcl.Float()) goal = hcl.placeholder(tuple(MDP_obj._goal.shape), name="goal", dtype=hcl.Float()) ptsEachDim = hcl.placeholder(tuple([6]), name="ptsEachDim", dtype=hcl.Float()) sVals = hcl.placeholder(tuple([6]), name="sVals", dtype=hcl.Float()) iVals = hcl.placeholder(tuple([6]), name="iVals", dtype=hcl.Float()) interpV = hcl.placeholder((0, ), "interpols") useNN = hcl.placeholder((0, ), "useNN") # Create a static schedule -- graph s = hcl.create_schedule([ Vopt, actions, intermeds, trans, interpV, gamma, epsilon, iVals, sVals, bounds, goal, ptsEachDim, count, maxIters, useNN ], solve_Vopt) # Use this graph and build an executable return hcl.build(s, target="llvm")
from collections import OrderedDict import heterocl as hcl import heterocl.tvm as tvm import numpy as np dtype = hcl.Float() sum = hcl.reducer(0, lambda x, y: x + y, dtype) max = hcl.reducer(-1, lambda x, y: tvm.make.Max(x, y), dtype) def simplify(expr): return tvm.ir_pass.Simplify(expr) if isinstance(expr, tvm.expr.Expr) else expr #def pad(data, pad_before, pad_after=None, pad_value=0.0): # n = len(data.shape) # pad_after = pad_after if pad_after else pad_before # out_shape = tuple( # tvm.ir_pass.Simplify( # (data.shape[i] + tvm.const(pad_before[i]) + tvm.const(pad_after[i]))) for i in range(n)) # def _pad(*indices): # not_zero = [] # index_tuple = [] # for i in range(n): # if equal_const_int(pad_before[i], 0) and equal_const_int(pad_after[i], 0): # index_tuple.append(indices[i]) # else: # index_tuple.append(indices[i] - pad_before[i]) # not_zero.append(indices[i] >= pad_before[i])
#heterocl Canny Filter from PIL import Image import heterocl as hcl import numpy as np import math import imageio hcl.init(init_dtype=hcl.Float()) #image path path = "home.jpg" img = Image.open(path) width, height = img.size #initialize placeholders A = hcl.placeholder((height, width, 3), "A", dtype=hcl.Float()) Gx = hcl.placeholder((3, 3), "Gx", dtype=hcl.Float()) Gy = hcl.placeholder((3, 3), "Gy", dtype=hcl.Float()) hcl_A = hcl.asarray(np.asarray(img)) hcl_Gx = hcl.asarray(np.array([[1, 0, -1], [2, 0, -2], [1, 0, -1]])) hcl_Gy = hcl.asarray(np.array([[1, 2, 1], [0, 0, 0], [-1, -2, -1]])) #output hcl_img = hcl.asarray(np.zeros((height, width))) #=======================================sobel_algo============================================ def sobel(A, Gx, Gy): B = hcl.compute((height, width),
def graph_3D_2nd_ENO(my_object, g, compMethod): V_f = hcl.placeholder(tuple(g.pts_each_dim), name="V_f", dtype=hcl.Float()) V_init = hcl.placeholder(tuple(g.pts_each_dim), name="V_init", dtype=hcl.Float()) l0 = hcl.placeholder(tuple(g.pts_each_dim), name="l0", dtype=hcl.Float()) t = hcl.placeholder((2, ), name="t", dtype=hcl.Float()) probe = hcl.placeholder(tuple(g.pts_each_dim), name="probe", dtype=hcl.Float()) #my_object = dynamics_obj #g = grid # Positions vector x1 = hcl.placeholder((g.pts_each_dim[0], ), name="x1", dtype=hcl.Float()) x2 = hcl.placeholder((g.pts_each_dim[1], ), name="x2", dtype=hcl.Float()) x3 = hcl.placeholder((g.pts_each_dim[2], ), name="x3", dtype=hcl.Float()) def graph_create(V_new, V_init, x1, x2, x3, t, l0): # Specify intermediate tensors deriv_diff1 = hcl.compute(V_init.shape, lambda *x: 0, "deriv_diff1") deriv_diff2 = hcl.compute(V_init.shape, lambda *x: 0, "deriv_diff2") deriv_diff3 = hcl.compute(V_init.shape, lambda *x: 0, "deriv_diff3") # Maximum derivative for each dim max_deriv1 = hcl.scalar(-1e9, "max_deriv1") max_deriv2 = hcl.scalar(-1e9, "max_deriv2") max_deriv3 = hcl.scalar(-1e9, "max_deriv3") # Min derivative for each dim min_deriv1 = hcl.scalar(1e9, "min_deriv1") min_deriv2 = hcl.scalar(1e9, "min_deriv2") min_deriv3 = hcl.scalar(1e9, "min_deriv3") # These variables are used to dissipation calculation max_alpha1 = hcl.scalar(-1e9, "max_alpha1") max_alpha2 = hcl.scalar(-1e9, "max_alpha2") max_alpha3 = hcl.scalar(-1e9, "max_alpha3") def step_bound(): # Function to calculate time step stepBoundInv = hcl.scalar(0, "stepBoundInv") stepBound = hcl.scalar(0, "stepBound") stepBoundInv[0] = max_alpha1[0] / g.dx[0] + max_alpha2[0] / g.dx[ 1] + max_alpha3[0] / g.dx[2] stepBound[0] = 0.8 / stepBoundInv[0] with hcl.if_(stepBound > t[1] - t[0]): stepBound[0] = t[1] - t[0] t[0] = t[0] + stepBound[0] return stepBound[0] # Min with V_before def minVWithVInit(i, j, k): with hcl.if_(V_new[i, j, k] > V_init[i, j, k]): V_new[i, j, k] = V_init[i, j, k] def maxVWithVInit(i, j, k): with hcl.if_(V_new[i, j, k] < V_init[i, j, k]): V_new[i, j, k] = V_init[i, j, k] def maxVWithV0(i, j, k): # Take the max with hcl.if_(V_new[i, j, k] < l0[i, j, k]): V_new[i, j, k] = l0[i, j, k] def minVWithV0(i, j, k): with hcl.if_(V_new[i, j, k] > l0[i, j, k]): V_new[i, j, k] = l0[i, j, k] # Calculate Hamiltonian for every grid point in V_init with hcl.Stage("Hamiltonian"): with hcl.for_( 0, V_init.shape[0], name="i" ) as i: # Plus 1 as for loop count stops at V_init.shape[0] with hcl.for_(0, V_init.shape[1], name="j") as j: with hcl.for_(0, V_init.shape[2], name="k") as k: # Variables to calculate dV_dx dV_dx_L = hcl.scalar(0, "dV_dx_L") dV_dx_R = hcl.scalar(0, "dV_dx_R") dV_dx = hcl.scalar(0, "dV_dx") # Variables to calculate dV_dy dV_dy_L = hcl.scalar(0, "dV_dy_L") dV_dy_R = hcl.scalar(0, "dV_dy_R") dV_dy = hcl.scalar(0, "dV_dy") # Variables to calculate dV_dtheta dV_dT_L = hcl.scalar(0, "dV_dT_L") dV_dT_R = hcl.scalar(0, "dV_dT_R") dV_dT = hcl.scalar(0, "dV_dT") # Variables to keep track of dynamics # dx_dt = hcl.scalar(0, "dx_dt") # dy_dt = hcl.scalar(0, "dy_dt") # dtheta_dt = hcl.scalar(0, "dtheta_dt") # No tensor slice operation dV_dx_L[0], dV_dx_R[0] = spa_derivX(i, j, k, V_init, g) dV_dy_L[0], dV_dy_R[0] = spa_derivY(i, j, k, V_init, g) dV_dT_L[0], dV_dT_R[0] = spa_derivT(i, j, k, V_init, g) # Saves spatial derivative diff into tables deriv_diff1[i, j, k] = dV_dx_R[0] - dV_dx_L[0] deriv_diff2[i, j, k] = dV_dy_R[0] - dV_dy_L[0] deriv_diff3[i, j, k] = dV_dT_R[0] - dV_dT_L[0] # Calculate average gradient dV_dx[0] = (dV_dx_L + dV_dx_R) / 2 dV_dy[0] = (dV_dy_L + dV_dy_R) / 2 dV_dT[0] = (dV_dT_L + dV_dT_R) / 2 # Use method of DubinsCar to solve optimal control instead uOpt = my_object.opt_ctrl( t, (x1[i], x2[j], x3[k]), (dV_dx[0], dV_dy[0], dV_dT[0])) dOpt = my_object.optDstb( t, (x1[i], x2[j], x3[k]), (dV_dx[0], dV_dy[0], dV_dT[0])) # Calculate dynamical rates of changes dx_dt, dy_dt, dtheta_dt = my_object.dynamics( t, (x1[i], x2[j], x3[k]), uOpt, dOpt) # Calculate Hamiltonian terms: V_new[i, j, k] = -(dx_dt * dV_dx[0] + dy_dt * dV_dy[0] + dtheta_dt * dV_dT[0]) #probe[i, j, k] = V_new[i, j, k] # Get derivMin with hcl.if_(dV_dx_L[0] < min_deriv1[0]): min_deriv1[0] = dV_dx_L[0] with hcl.if_(dV_dx_R[0] < min_deriv1[0]): min_deriv1[0] = dV_dx_R[0] with hcl.if_(dV_dy_L[0] < min_deriv2[0]): min_deriv2[0] = dV_dy_L[0] with hcl.if_(dV_dy_R[0] < min_deriv2[0]): min_deriv2[0] = dV_dy_R[0] with hcl.if_(dV_dT_L[0] < min_deriv3[0]): min_deriv3[0] = dV_dT_L[0] with hcl.if_(dV_dT_R[0] < min_deriv3[0]): min_deriv3[0] = dV_dT_R[0] # Get derivMax with hcl.if_(dV_dx_L[0] > max_deriv1[0]): max_deriv1[0] = dV_dx_L[0] with hcl.if_(dV_dx_R[0] > max_deriv1[0]): max_deriv1[0] = dV_dx_R[0] with hcl.if_(dV_dy_L[0] > max_deriv2[0]): max_deriv2[0] = dV_dy_L[0] with hcl.if_(dV_dy_R[0] > max_deriv2[0]): max_deriv2[0] = dV_dy_R[0] with hcl.if_(dV_dT_L[0] > max_deriv3[0]): max_deriv3[0] = dV_dT_L[0] with hcl.if_(dV_dT_R[0] > max_deriv3[0]): max_deriv3[0] = dV_dT_R[0] # Calculate the dissipation with hcl.Stage("Dissipation"): # Storing alphas dOptL1 = hcl.scalar(0, "dOptL1") dOptL2 = hcl.scalar(0, "dOptL2") dOptL3 = hcl.scalar(0, "dOptL3") # Find UPPER BOUND optimal disturbance dOptU1 = hcl.scalar(0, "dOptU1") dOptU2 = hcl.scalar(0, "dOptU2") dOptU3 = hcl.scalar(0, "dOptU3") alpha1 = hcl.scalar(0, "alpha1") alpha2 = hcl.scalar(0, "alpha2") alpha3 = hcl.scalar(0, "alpha3") # Lower bound optimal control uOptL1 = hcl.scalar(0, "uOptL1") uOptL2 = hcl.scalar(0, "uOptL2") uOptL3 = hcl.scalar(0, "uOptL3") # Find UPPER BOUND optimal disturbance uOptU1 = hcl.scalar(0, "uOptU1") uOptU2 = hcl.scalar(0, "uOptU2") uOptU3 = hcl.scalar(0, "uOptU3") with hcl.for_(0, V_init.shape[0], name="i") as i: with hcl.for_(0, V_init.shape[1], name="j") as j: with hcl.for_(0, V_init.shape[2], name="k") as k: dx_LL1 = hcl.scalar(0, "dx_LL1") dx_LL2 = hcl.scalar(0, "dx_LL2") dx_LL3 = hcl.scalar(0, "dx_LL3") dx_UL1 = hcl.scalar(0, "dx_UL1") dx_UL2 = hcl.scalar(0, "dx_UL2") dx_UL3 = hcl.scalar(0, "dx_UL3") dx_UU1 = hcl.scalar(0, "dx_UU1") dx_UU2 = hcl.scalar(0, "dx_UU2") dx_UU3 = hcl.scalar(0, "dx_UU3") dx_LU1 = hcl.scalar(0, "dx_LU1") dx_LU2 = hcl.scalar(0, "dx_LU2") dx_LU3 = hcl.scalar(0, "dx_LU3") # Find LOWER BOUND optimal disturbance dOptL1[0], dOptL2[0], dOptL3[0] = my_object.optDstb(t, (x1[i], x2[j], x3[k]),\ (min_deriv1[0], min_deriv2[0],min_deriv3[0])) # probe[i, j, k] = dOptL1[0] + dOptL2[0] + dOptL3[0] dOptU1[0], dOptU2[0], dOptU3[0] = my_object.optDstb(t, (x1[i], x2[j], x3[k]),\ (max_deriv1[0], max_deriv2[0],max_deriv3[0])) # probe[i, j, k] = dOptL1[0] + dOptL2[0] + dOptL3[0] # Find LOWER BOUND optimal control uOptL1[0], uOptL2[0], uOptL3[0] = my_object.opt_ctrl(t, (x1[i], x2[j], x3[k]), \ (min_deriv1[0], min_deriv2[0],min_deriv3[0])) # probe[i, j, k] = uOptL1[0] + uOptL2[0] + uOptL3[0] # Find UPPER BOUND optimal control uOptU1[0], uOptU2[0], uOptU3[0] = my_object.opt_ctrl( t, (x1[i], x2[j], x3[k]), (max_deriv1[0], max_deriv2[0], max_deriv3[0])) #probe[i, j, k] = uOptU1[0] + uOptU2[0] + uOptU3[0] # Find magnitude of rates of changes dx_LL1[0], dx_LL2[0], dx_LL3[0] = my_object.dynamics(t, (x1[i], x2[j], x3[k]), (uOptL1[0], uOptL2[0], uOptL3[0]), \ (dOptL1[0], dOptL2[0], dOptL3[0])) dx_LL1[0] = my_abs(dx_LL1[0]) dx_LL2[0] = my_abs(dx_LL2[0]) dx_LL3[0] = my_abs(dx_LL3[0]) #probe[i, j, k] = dx_LL1[0] + dx_LL2[0] + dx_LL3[0] dx_LU1[0], dx_LU2[0], dx_LU3[0] = my_object.dynamics(t, (x1[i], x2[j], x3[k]), (uOptL1[0], uOptL2[0], uOptL3[0]), \ (dOptU1[0], dOptU2[0], dOptU3[0])) dx_LU1[0] = my_abs(dx_LU1[0]) dx_LU2[0] = my_abs(dx_LU2[0]) dx_LU3[0] = my_abs(dx_LU3[0]) # Calculate alpha alpha1[0] = my_max(dx_LL1[0], dx_LU1[0]) alpha2[0] = my_max(dx_LL2[0], dx_LU2[0]) alpha3[0] = my_max(dx_LL3[0], dx_LU3[0]) # dx_UL3 = hcl.scalar(0, "dx_UL3") # dx_UL1[0], dx_UL2[0], dx_UL3[0], dx_UL4[0] = my_object.dynamics(t, (x1[i], x2[j], x3[k], x4[l]), # uOptU, dOptL) dx_UL1[0], dx_UL2[0], dx_UL3[0]= my_object.dynamics(t, (x1[i], x2[j], x3[k]),\ (uOptU1[0], uOptU2[0], uOptU3[0]), \ (dOptL1[0], dOptL2[0], dOptL3[0])) dx_UL1[0] = my_abs(dx_UL1[0]) dx_UL2[0] = my_abs(dx_UL2[0]) dx_UL3[0] = my_abs(dx_UL3[0]) # Calculate alpha alpha1[0] = my_max(alpha1[0], dx_UL1[0]) alpha2[0] = my_max(alpha2[0], dx_UL2[0]) alpha3[0] = my_max(alpha3[0], dx_UL3[0]) dx_UU1[0], dx_UU2[0], dx_UU3[0] = my_object.dynamics(t, (x1[i], x2[j], x3[k]), (uOptU1[0], uOptU2[0], uOptU3[0]),\ (dOptU1[0], dOptU2[0], dOptU3[0])) dx_UU1[0] = my_abs(dx_UU1[0]) dx_UU2[0] = my_abs(dx_UU2[0]) dx_UU3[0] = my_abs(dx_UU3[0]) # Calculate alpha alpha1[0] = my_max(alpha1[0], dx_UU1[0]) alpha2[0] = my_max(alpha2[0], dx_UU2[0]) alpha3[0] = my_max(alpha3[0], dx_UU3[0]) #probe[i, j, k] = alpha1[0] + alpha2[0] + alpha3[0] diss = hcl.scalar(0, "diss") diss[0] = 0.5 * (deriv_diff1[i, j, k] * alpha1[0] + deriv_diff2[i, j, k] * alpha2[0] + deriv_diff3[i, j, k] * alpha3[0]) # probe[i, j, k] = alpha2[0] # Finally V_new[i, j, k] = -(V_new[i, j, k] - diss[0]) # probe[i, j, k] = alpha3[0] # Get maximum alphas in each dimension # Calculate alphas with hcl.if_(alpha1[0] > max_alpha1[0]): max_alpha1[0] = alpha1[0] with hcl.if_(alpha2[0] > max_alpha2[0]): max_alpha2[0] = alpha2[0] with hcl.if_(alpha3[0] > max_alpha3[0]): max_alpha3[0] = alpha3[0] # Determine time step delta_t = hcl.compute((1, ), lambda x: step_bound(), name="delta_t") # Integrate result = hcl.update( V_new, lambda i, j, k: V_init[i, j, k] + V_new[i, j, k] * delta_t[0]) # Different computation method check if compMethod == 'maxVWithV0': result = hcl.update(V_new, lambda i, j, k: maxVWithV0(i, j, k)) if compMethod == 'minVWithV0': result = hcl.update(V_new, lambda i, j, k: minVWithV0(i, j, k)) if compMethod == 'minVWithVInit': result = hcl.update(V_new, lambda i, j, k: minVWithVInit(i, j, k)) if compMethod == 'maxVWithVInit': result = hcl.update(V_new, lambda i, j, k: maxVWithVInit(i, j, k)) # Copy V_new to V_init hcl.update(V_init, lambda i, j, k: V_new[i, j, k]) return result s = hcl.create_schedule([V_f, V_init, x1, x2, x3, t, l0], graph_create) ##################### CODE OPTIMIZATION HERE ########################### print("Optimizing\n") # Accessing the hamiltonian and dissipation stage s_H = graph_create.Hamiltonian s_D = graph_create.Dissipation # Thread parallelize hamiltonian and dissipation s[s_H].parallel(s_H.i) s[s_D].parallel(s_D.i) # Inspect IR # if args.llvm: #print(hcl.lower(s)) # Return executable return (hcl.build(s))
""" import heterocl as hcl ############################################################################## # Data Types Supported by HeteroCL # -------------------------------- # HeteroCL supports both bit-accurate data types and floating points. We show # some examples below. If no argument is provided, the default bitwidth for # each type is 32. hcl.Int(15) # 15-bit signed integer hcl.UInt(24) # 24-bit unsigned integer hcl.Fixed(13, 5) # 13-bit signed fixed point with 5 fractional bits hcl.UFixed(44, 30) # 44-bit unsigned fixed point with 30 fractional bits hcl.Float(32) # single-precision floating point hcl.Float(64) # double-precision floating point ############################################################################## # These data types can be used in ``hcl.init`` to set the default data type hcl.init(hcl.Float()) ############################################################################## # Data Type Customization # ----------------------- # Another important hardware customization is data type customization, which # can be data quantization or downsizing a data type. Data quantization has # been proved to improve hardware efficiency in many accelerators. In HeteroCL, # to apply data type customization, we need to use ``hcl.create_scheme``,
def top( input, filter, bias, ): f_conv = hcl.compute( (final_extent_0, final_extent_1, final_extent_2, final_extent_3), lambda x, y, z, w: 0, name="f_conv", dtype=hcl.Float(bits=32)) with hcl.Stage("f_conv"): with hcl.for_(final_min_3, final_extent_3, name="f_conv_s0_n") as f_conv_s0_n: with hcl.for_(final_min_2, final_extent_2, name="f_conv_s0_z") as f_conv_s0_z: with hcl.for_(final_min_1, final_extent_1, name="f_conv_s0_y") as f_conv_s0_y: with hcl.for_(final_min_0, final_extent_0, name="f_conv_s0_x") as f_conv_s0_x: f_conv[f_conv_s0_x, f_conv_s0_y, f_conv_s0_z, f_conv_s0_n] = bias[f_conv_s0_z] with hcl.for_(final_min_3, final_extent_3, name="f_conv_s1_n") as f_conv_s1_n: with hcl.for_(final_min_2, final_extent_2, name="f_conv_s1_z") as f_conv_s1_z: with hcl.for_(final_min_1, final_extent_1, name="f_conv_s1_y") as f_conv_s1_y: with hcl.for_(final_min_0, final_extent_0, name="f_conv_s1_x") as f_conv_s1_x: with hcl.for_(0, 32, name="f_conv_s1_r__z") as f_conv_s1_r__z: with hcl.for_( 0, 3, name="f_conv_s1_r__y") as f_conv_s1_r__y: with hcl.for_(0, 3, name="f_conv_s1_r__x" ) as f_conv_s1_r__x: f_conv[ f_conv_s1_x, f_conv_s1_y, f_conv_s1_z, f_conv_s1_n] = ( f_conv[f_conv_s1_x, f_conv_s1_y, f_conv_s1_z, f_conv_s1_n] + (filter[ f_conv_s1_r__x, f_conv_s1_r__y, f_conv_s1_r__z, f_conv_s1_z] * input[ (f_conv_s1_r__x + f_conv_s1_x), (f_conv_s1_r__y + f_conv_s1_y), f_conv_s1_r__z, f_conv_s1_n])) f_relu = hcl.compute( (final_extent_0, final_extent_1, final_extent_2, final_extent_3), lambda x, y, z, w: 0, name="f_relu", dtype=hcl.Float(bits=32)) with hcl.Stage("f_relu"): with hcl.for_(final_min_3, final_extent_3, name="f_relu_s0_n") as f_relu_s0_n: with hcl.for_(final_min_2, final_extent_2, name="f_relu_s0_z") as f_relu_s0_z: with hcl.for_(final_min_1, final_extent_1, name="f_relu_s0_y") as f_relu_s0_y: with hcl.for_(final_min_0, final_extent_0, name="f_relu_s0_x") as f_relu_s0_x: f_relu[f_relu_s0_x, f_relu_s0_y, f_relu_s0_z, f_relu_s0_n] = hcl.select( f_conv[f_relu_s0_x, f_relu_s0_y, f_relu_s0_z, f_relu_s0_n] > hcl.cast( dtype=hcl.Float(bits=32), expr=0.000000), f_conv[f_relu_s0_x, f_relu_s0_y, f_relu_s0_z, f_relu_s0_n], hcl.cast(dtype=hcl.Float(bits=32), expr=0.000000)) final = hcl.compute((64, 64, 32, 4), lambda x, y, z, w: 0, name="final", dtype=hcl.Float(bits=32)) with hcl.Stage("final"): with hcl.for_(final_min_3, final_extent_3, name="final_s0_n") as final_s0_n: with hcl.for_(final_min_2, final_extent_2, name="final_s0_z") as final_s0_z: with hcl.for_(final_min_1, final_extent_1, name="final_s0_y") as final_s0_y: with hcl.for_(final_min_0, final_extent_0, name="final_s0_x") as final_s0_x: final[final_s0_x, final_s0_y, final_s0_z, final_s0_n] = f_relu[final_s0_x, final_s0_y, final_s0_z, final_s0_n] return final
def graph_4D(my_object, g, compMethod, accuracy): V_f = hcl.placeholder(tuple(g.pts_each_dim), name="V_f", dtype=hcl.Float()) V_init = hcl.placeholder(tuple(g.pts_each_dim), name="V_init", dtype=hcl.Float()) l0 = hcl.placeholder(tuple(g.pts_each_dim), name="l0", dtype=hcl.Float()) t = hcl.placeholder((2, ), name="t", dtype=hcl.Float()) probe = hcl.placeholder(tuple(g.pts_each_dim), name="probe", dtype=hcl.Float()) # Positions vector x1 = hcl.placeholder((g.pts_each_dim[0], ), name="x1", dtype=hcl.Float()) x2 = hcl.placeholder((g.pts_each_dim[1], ), name="x2", dtype=hcl.Float()) x3 = hcl.placeholder((g.pts_each_dim[2], ), name="x3", dtype=hcl.Float()) x4 = hcl.placeholder((g.pts_each_dim[3], ), name="x4", dtype=hcl.Float()) def graph_create(V_new, V_init, x1, x2, x3, x4, t, l0, probe): # Specify intermediate tensors deriv_diff1 = hcl.compute(V_init.shape, lambda *x: 0, "deriv_diff1") deriv_diff2 = hcl.compute(V_init.shape, lambda *x: 0, "deriv_diff2") deriv_diff3 = hcl.compute(V_init.shape, lambda *x: 0, "deriv_diff3") deriv_diff4 = hcl.compute(V_init.shape, lambda *x: 0, "deriv_diff4") # Maximum derivative for each dim max_deriv1 = hcl.scalar(-1e9, "max_deriv1") max_deriv2 = hcl.scalar(-1e9, "max_deriv2") max_deriv3 = hcl.scalar(-1e9, "max_deriv3") max_deriv4 = hcl.scalar(-1e9, "max_deriv4") # Min derivative for each dim min_deriv1 = hcl.scalar(1e9, "min_deriv1") min_deriv2 = hcl.scalar(1e9, "min_deriv2") min_deriv3 = hcl.scalar(1e9, "min_deriv3") min_deriv4 = hcl.scalar(1e9, "min_deriv4") # These variables are used to dissipation calculation max_alpha1 = hcl.scalar(-1e9, "max_alpha1") max_alpha2 = hcl.scalar(-1e9, "max_alpha2") max_alpha3 = hcl.scalar(-1e9, "max_alpha3") max_alpha4 = hcl.scalar(-1e9, "max_alpha4") def step_bound(): # Function to calculate time step stepBoundInv = hcl.scalar(0, "stepBoundInv") stepBound = hcl.scalar(0, "stepBound") stepBoundInv[0] = max_alpha1[0] / g.dx[0] + max_alpha2[0] / g.dx[1] + max_alpha3[0] / g.dx[2] + max_alpha4[0] / \ g.dx[3] stepBound[0] = 0.8 / stepBoundInv[0] with hcl.if_(stepBound > t[1] - t[0]): stepBound[0] = t[1] - t[0] # Update the lower time ranges t[0] = t[0] + stepBound[0] # t[0] = min_deriv2[0] return stepBound[0] # Min with V_before def minVWithVInit(i, j, k, l): with hcl.if_(V_new[i, j, k, l] > V_init[i, j, k, l]): V_new[i, j, k, l] = V_init[i, j, k, l] def maxVWithVInit(i, j, k, l): with hcl.if_(V_new[i, j, k, l] < V_init[i, j, k, l]): V_new[i, j, k, l] = V_init[i, j, k, l] def maxVWithV0(i, j, k, l): # Take the max with hcl.if_(V_new[i, j, k, l] < l0[i, j, k, l]): V_new[i, j, k, l] = l0[i, j, k, l] def minVWithV0(i, j, k, l): with hcl.if_(V_new[i, j, k, l] > l0[i, j, k, l]): V_new[i, j, k, l] = l0[i, j, k, l] # Calculate Hamiltonian for every grid point in V_init with hcl.Stage("Hamiltonian"): with hcl.for_(0, V_init.shape[0], name="i") as i: with hcl.for_(0, V_init.shape[1], name="j") as j: with hcl.for_(0, V_init.shape[2], name="k") as k: with hcl.for_(0, V_init.shape[3], name="l") as l: # Variables to calculate dV_dx dV_dx1_L = hcl.scalar(0, "dV_dx1_L") dV_dx1_R = hcl.scalar(0, "dV_dx1_R") dV_dx1 = hcl.scalar(0, "dV_dx1") dV_dx2_L = hcl.scalar(0, "dV_dx2_L") dV_dx2_R = hcl.scalar(0, "dV_dx2_R") dV_dx2 = hcl.scalar(0, "dV_dx2") dV_dx3_L = hcl.scalar(0, "dV_dx3_L") dV_dx3_R = hcl.scalar(0, "dV_dx3_R") dV_dx3 = hcl.scalar(0, "dV_dx3") dV_dx4_L = hcl.scalar(0, "dV_dx4_L") dV_dx4_R = hcl.scalar(0, "dV_dx4_R") dV_dx4 = hcl.scalar(0, "dV_dx4") # No tensor slice operation # dV_dx_L[0], dV_dx_R[0] = spa_derivX(i, j, k) if accuracy == "low": dV_dx1_L[0], dV_dx1_R[0] = spa_derivX1_4d( i, j, k, l, V_init, g) dV_dx2_L[0], dV_dx2_R[0] = spa_derivX2_4d( i, j, k, l, V_init, g) dV_dx3_L[0], dV_dx3_R[0] = spa_derivX3_4d( i, j, k, l, V_init, g) dV_dx4_L[0], dV_dx4_R[0] = spa_derivX4_4d( i, j, k, l, V_init, g) if accuracy == "high": dV_dx1_L[0], dV_dx1_R[0] = secondOrderX1_4d( i, j, k, l, V_init, g) dV_dx2_L[0], dV_dx2_R[0] = secondOrderX2_4d( i, j, k, l, V_init, g) dV_dx3_L[0], dV_dx3_R[0] = secondOrderX3_4d( i, j, k, l, V_init, g) dV_dx4_L[0], dV_dx4_R[0] = secondOrderX4_4d( i, j, k, l, V_init, g) # Saves spatial derivative diff into tables deriv_diff1[i, j, k, l] = dV_dx1_R[0] - dV_dx1_L[0] deriv_diff2[i, j, k, l] = dV_dx2_R[0] - dV_dx2_L[0] deriv_diff3[i, j, k, l] = dV_dx3_R[0] - dV_dx3_L[0] deriv_diff4[i, j, k, l] = dV_dx4_R[0] - dV_dx4_L[0] # Calculate average gradient dV_dx1[0] = (dV_dx1_L + dV_dx1_R) / 2 dV_dx2[0] = (dV_dx2_L + dV_dx2_R) / 2 dV_dx3[0] = (dV_dx3_L + dV_dx3_R) / 2 dV_dx4[0] = (dV_dx4_L + dV_dx4_R) / 2 #probe[i,j,k,l] = dV_dx2[0] # Find optimal control uOpt = my_object.opt_ctrl( t, (x1[i], x2[j], x3[k], x4[l]), (dV_dx1[0], dV_dx2[0], dV_dx3[0], dV_dx4[0])) # Find optimal disturbance dOpt = my_object.opt_dstb( t, (x1[i], x2[j], x3[k], x4[l]), (dV_dx1[0], dV_dx2[0], dV_dx3[0], dV_dx4[0])) # Find rates of changes based on dynamics equation dx1_dt, dx2_dt, dx3_dt, dx4_dt = my_object.dynamics( t, (x1[i], x2[j], x3[k], x4[l]), uOpt, dOpt) # Calculate Hamiltonian terms: V_new[i, j, k, l] = -( dx1_dt * dV_dx1[0] + dx2_dt * dV_dx2[0] + dx3_dt * dV_dx3[0] + dx4_dt * dV_dx4[0]) # Debugging # V_new[i, j, k, l] = dV_dx2[0] probe[i, j, k, l] = V_init[i, j, k, l] # Get derivMin with hcl.if_(dV_dx1_L[0] < min_deriv1[0]): min_deriv1[0] = dV_dx1_L[0] with hcl.if_(dV_dx1_R[0] < min_deriv1[0]): min_deriv1[0] = dV_dx1_R[0] with hcl.if_(dV_dx2_L[0] < min_deriv2[0]): min_deriv2[0] = dV_dx2_L[0] with hcl.if_(dV_dx2_R[0] < min_deriv2[0]): min_deriv2[0] = dV_dx2_R[0] with hcl.if_(dV_dx3_L[0] < min_deriv3[0]): min_deriv3[0] = dV_dx3_L[0] with hcl.if_(dV_dx3_R[0] < min_deriv3[0]): min_deriv3[0] = dV_dx3_R[0] with hcl.if_(dV_dx4_L[0] < min_deriv4[0]): min_deriv4[0] = dV_dx4_L[0] with hcl.if_(dV_dx4_R[0] < min_deriv4[0]): min_deriv4[0] = dV_dx4_R[0] # Get derivMax with hcl.if_(dV_dx1_L[0] > max_deriv1[0]): max_deriv1[0] = dV_dx1_L[0] with hcl.if_(dV_dx1_R[0] > max_deriv1[0]): max_deriv1[0] = dV_dx1_R[0] with hcl.if_(dV_dx2_L[0] > max_deriv2[0]): max_deriv2[0] = dV_dx2_L[0] with hcl.if_(dV_dx2_R[0] > max_deriv2[0]): max_deriv2[0] = dV_dx2_R[0] with hcl.if_(dV_dx3_L[0] > max_deriv3[0]): max_deriv3[0] = dV_dx3_L[0] with hcl.if_(dV_dx3_R[0] > max_deriv3[0]): max_deriv3[0] = dV_dx3_R[0] with hcl.if_(dV_dx4_L[0] > max_deriv4[0]): max_deriv4[0] = dV_dx4_L[0] with hcl.if_(dV_dx4_R[0] > max_deriv4[0]): max_deriv4[0] = dV_dx4_R[0] # Calculate dissipation amount with hcl.Stage("Dissipation"): # Storing alphas dOptL1 = hcl.scalar(0, "dOptL1") dOptL2 = hcl.scalar(0, "dOptL2") dOptL3 = hcl.scalar(0, "dOptL3") dOptL4 = hcl.scalar(0, "dOptL4") # Find UPPER BOUND optimal disturbance dOptU1 = hcl.scalar(0, "dOptL1") dOptU2 = hcl.scalar(0, "dOptL2") dOptU3 = hcl.scalar(0, "dOptL3") dOptU4 = hcl.scalar(0, "dOptL4") alpha1 = hcl.scalar(0, "alpha1") alpha2 = hcl.scalar(0, "alpha2") alpha3 = hcl.scalar(0, "alpha3") alpha4 = hcl.scalar(0, "alpha4") """ NOTE: If optimal adversarial disturbance is not dependent on states , the below approximate LOWER/UPPER BOUND optimal disturbance is accurate. If that's not the case, move the next two statements into the nested loops and modify the states passed in as my_object.opt_dstb(t, (x1[i], x2[j], x3[k], x4[l], ...), ...). The reason we don't have this line in the nested loop by default is to avoid redundant computations for certain systems where disturbance are not dependent on states. In general, dissipation amount can just be approximates. """ dOptL1[0], dOptL2[0], dOptL3[0], dOptL4[0] = my_object.opt_dstb(t, (x1[0], x2[0], x3[0], x4[0]), (min_deriv1[0], min_deriv2[0], \ min_deriv3[0], min_deriv4[0])) dOptU1[0], dOptL2[0], dOptL3[0], dOptL4[0] = my_object.opt_dstb(t, (x1[0], x2[0], x3[0], x4[0]), (max_deriv1[0], max_deriv2[0], \ max_deriv3[0], max_deriv4[0])) uOptL1 = hcl.scalar(0, "uOptL1") uOptL2 = hcl.scalar(0, "uOptL2") uOptL3 = hcl.scalar(0, "uOptL3") uOptL4 = hcl.scalar(0, "uOptL4") # Find UPPER BOUND optimal disturbance uOptU1 = hcl.scalar(0, "uOptU1") uOptU2 = hcl.scalar(0, "uOptU2") uOptU3 = hcl.scalar(0, "uOptU3") uOptU4 = hcl.scalar(0, "uOptU4") with hcl.for_(0, V_init.shape[0], name="i") as i: with hcl.for_(0, V_init.shape[1], name="j") as j: with hcl.for_(0, V_init.shape[2], name="k") as k: with hcl.for_(0, V_init.shape[3], name="l") as l: dx_LL1 = hcl.scalar(0, "dx_LL1") dx_LL2 = hcl.scalar(0, "dx_LL2") dx_LL3 = hcl.scalar(0, "dx_LL3") dx_LL4 = hcl.scalar(0, "dx_LL4") dx_UL1 = hcl.scalar(0, "dx_UL1") dx_UL2 = hcl.scalar(0, "dx_UL2") dx_UL3 = hcl.scalar(0, "dx_UL3") dx_UL4 = hcl.scalar(0, "dx_UL4") dx_UU1 = hcl.scalar(0, "dx_UU1") dx_UU2 = hcl.scalar(0, "dx_UU2") dx_UU3 = hcl.scalar(0, "dx_UU3") dx_UU4 = hcl.scalar(0, "dx_UU4") dx_LU1 = hcl.scalar(0, "dx_LU1") dx_LU2 = hcl.scalar(0, "dx_LU2") dx_LU3 = hcl.scalar(0, "dx_LU3") dx_LU4 = hcl.scalar(0, "dx_LU4") # dOptL1[0], dOptL2[0], dOptL3[0], dOptL4[0] = my_object.opt_dstb(t, (x1[i], x2[j], x3[k], x4[l]), # (min_deriv1[0], min_deriv2[0], \ # min_deriv3[0], min_deriv4[0])) # dOptU1[0], dOptL2[0], dOptL3[0], dOptL4[0] = my_object.opt_dstb(t, (x1[i], x2[j], x3[k], x4[l]), # (max_deriv1[0], max_deriv2[0], \ # max_deriv3[0], max_deriv4[0])) # Find LOWER BOUND optimal control uOptL1[0], uOptL2[0], uOptL3[0], uOptL4[ 0] = my_object.opt_ctrl( t, (x1[i], x2[j], x3[k], x4[l]), (min_deriv1[0], min_deriv2[0], min_deriv3[0], min_deriv4[0])) # Find UPPER BOUND optimal control uOptU1[0], uOptU2[0], uOptU3[0], uOptU4[ 0] = my_object.opt_ctrl( t, (x1[i], x2[j], x3[k], x4[l]), (max_deriv1[0], max_deriv2[0], max_deriv3[0], max_deriv4[0])) # Find magnitude of rates of changes dx_LL1[0], dx_LL2[0], dx_LL3[0], dx_LL4[0] = my_object.dynamics(t, (x1[i], x2[j], x3[k], x4[l]), (uOptL1[0], uOptL2[0],uOptL3[0], uOptL4[0]),\ (dOptL1[0], dOptL2[0], dOptL3[0], dOptL4[0])) dx_LL1[0] = my_abs(dx_LL1[0]) dx_LL2[0] = my_abs(dx_LL2[0]) dx_LL3[0] = my_abs(dx_LL3[0]) dx_LL4[0] = my_abs(dx_LL4[0]) dx_LU1[0], dx_LU2[0], dx_LU3[0], dx_LU4[0] = my_object.dynamics(t, (x1[i], x2[j], x3[k], x4[l]), (uOptL1[0], uOptL2[0],uOptL3[0], uOptL4[0]), \ (dOptU1[0], dOptU2[0], dOptU3[0], dOptU4[0])) dx_LU1[0] = my_abs(dx_LU1[0]) dx_LU2[0] = my_abs(dx_LU2[0]) dx_LU3[0] = my_abs(dx_LU3[0]) dx_LU4[0] = my_abs(dx_LU4[0]) # Calculate alpha alpha1[0] = my_max(dx_LL1[0], dx_LU1[0]) alpha2[0] = my_max(dx_LL2[0], dx_LU2[0]) alpha3[0] = my_max(dx_LL3[0], dx_LU3[0]) alpha4[0] = my_max(dx_LL4[0], dx_LU4[0]) dx_UL1[0], dx_UL2[0], dx_UL3[0], dx_UL4[0] = my_object.dynamics(t, (x1[i], x2[j], x3[k], x4[l]),\ (uOptU1[0], uOptU2[0], uOptU3[0], uOptU4[0]), \ (dOptL1[0], dOptL2[0], dOptL3[0], dOptL4[0])) dx_UL1[0] = my_abs(dx_UL1[0]) dx_UL2[0] = my_abs(dx_UL2[0]) dx_UL3[0] = my_abs(dx_UL3[0]) dx_UL4[0] = my_abs(dx_UL4[0]) # Calculate alpha alpha1[0] = my_max(alpha1[0], dx_UL1[0]) alpha2[0] = my_max(alpha2[0], dx_UL2[0]) alpha3[0] = my_max(alpha3[0], dx_UL3[0]) alpha4[0] = my_max(alpha4[0], dx_UL4[0]) dx_UU1[0], dx_UU2[0], dx_UU3[0], dx_UU4[0] = my_object.dynamics(t, (x1[i], x2[j], x3[k], x4[l]), (uOptU1[0], uOptU2[0], uOptU3[0], uOptU4[0]),\ (dOptU1[0], dOptU2[0], dOptU3[0], dOptU4[0])) dx_UU1[0] = my_abs(dx_UU1[0]) dx_UU2[0] = my_abs(dx_UU2[0]) dx_UU3[0] = my_abs(dx_UU3[0]) dx_UU4[0] = my_abs(dx_UU4[0]) # Calculate alphas alpha1[0] = my_max(alpha1[0], dx_UU1[0]) alpha2[0] = my_max(alpha2[0], dx_UU2[0]) alpha3[0] = my_max(alpha3[0], dx_UU3[0]) alpha4[0] = my_max(alpha4[0], dx_UU4[0]) diss = hcl.scalar(0, "diss") diss[0] = 0.5 * ( deriv_diff1[i, j, k, l] * alpha1[0] + deriv_diff2[i, j, k, l] * alpha2[0] + deriv_diff3[i, j, k, l] * alpha3[0] + deriv_diff4[i, j, k, l] * alpha4[0]) #probe[i, j, k, l] = alpha1[0] # Finally V_new[i, j, k, l] = -(V_new[i, j, k, l] - diss[0]) # Get maximum alphas in each dimension with hcl.if_(alpha1[0] > max_alpha1[0]): max_alpha1[0] = alpha1[0] with hcl.if_(alpha2[0] > max_alpha2[0]): max_alpha2[0] = alpha2[0] with hcl.if_(alpha3[0] > max_alpha3[0]): max_alpha3[0] = alpha3[0] with hcl.if_(alpha4[0] > max_alpha4[0]): max_alpha4[0] = alpha4[0] # Determine time step delta_t = hcl.compute((1, ), lambda x: step_bound(), name="delta_t") # Integrate result = hcl.update( V_new, lambda i, j, k, l: V_init[i, j, k, l] + V_new[i, j, k, l] * delta_t[0]) # Different computation method check if compMethod == 'maxVWithV0': result = hcl.update(V_new, lambda i, j, k, l: maxVWithV0(i, j, k, l)) if compMethod == 'minVWithV0': result = hcl.update(V_new, lambda i, j, k, l: minVWithV0(i, j, k, l)) if compMethod == 'minVWithVInit': result = hcl.update(V_new, lambda i, j, k, l: minVWithVInit(i, j, k, l)) if compMethod == 'maxVWithVInit': result = hcl.update(V_new, lambda i, j, k, l: maxVWithVInit(i, j, k, l)) # Copy V_new to V_init hcl.update(V_init, lambda i, j, k, l: V_new[i, j, k, l]) return result s = hcl.create_schedule([V_f, V_init, x1, x2, x3, x4, t, l0, probe], graph_create) ##################### CODE OPTIMIZATION HERE ########################### print("Optimizing\n") # Accessing the hamiltonian and dissipation stage s_H = graph_create.Hamiltonian s_D = graph_create.Dissipation # Thread parallelize hamiltonian and dissipation s[s_H].parallel(s_H.i) s[s_D].parallel(s_D.i) # Inspect IR # if args.llvm: # print(hcl.lower(s)) # Return executable return (hcl.build(s))
final_extent_0, name="final_s0_x") as final_s0_x: final[final_s0_x, final_s0_y, final_s0_z, final_s0_n] = f_relu[final_s0_x, final_s0_y, final_s0_z, final_s0_n] return final input = hcl.placeholder(( 67, 67, 32, 4, ), name="input", dtype=hcl.Float(bits=32)) filter = hcl.placeholder(( 3, 3, 32, 32, ), name="filter", dtype=hcl.Float(bits=32)) bias = hcl.placeholder((32, ), name="bias", dtype=hcl.Float(bits=32)) s = hcl.create_schedule([ input, filter, bias, ], top) f = hcl.build(s)
def main(): ################### PARSING ARGUMENTS FROM USERS ##################### parser = ArgumentParser() parser.add_argument("-p", "--plot", default=False, type=bool) args = parser.parse_args() hcl.init() hcl.config.init_dtype = hcl.Float() ################## DATA SHAPE PREPARATION FOR GRAPH FORMATION #################### V_f = hcl.placeholder(tuple(g.pts_each_dim), name="V_f", dtype=hcl.Float()) V_init = hcl.placeholder(tuple(g.pts_each_dim), name="V_init", dtype=hcl.Float()) x = hcl.placeholder((4, g.pts_each_dim[0]), name="x", dtype=hcl.Float()) t = hcl.placeholder((1, ), name="t", dtype=hcl.Float()) # Deriv diff tensor deriv_diff1 = hcl.Tensor((tuple(g.pts_each_dim)), name="deriv_diff1") deriv_diff2 = hcl.Tensor((tuple(g.pts_each_dim)), name="deriv_diff2") deriv_diff3 = hcl.Tensor((tuple(g.pts_each_dim)), name="deriv_diff3") deriv_diff4 = hcl.Tensor((tuple(g.pts_each_dim)), name="deriv_diff4") ################# INITIALIZE DATA TO BE INPUT INTO GRAPH ########################## V_0 = hcl.asarray(my_shape) V_1 = hcl.asarray(np.zeros(tuple(g.pts_each_dim))) t_minh = hcl.asarray(np.zeros(1)) x = np.zeros(4, g.pts_each_dim[0]) for i in range(0, 4): for j in range(0, g.pts_each_dim[i]): x[i, j] = g.xs[i][j] # Convert x to hcl array type x = hcl.asarray(x) ##################### CREATE SCHEDULE############## # Create schedule s = hcl.create_schedule([V_f, V_init, x, t], graph_4D) # Inspect the LLVM code print(hcl.lower(s)) ##################### CODE OPTIMIZATION HERE ########################### # Accessing the hamiltonian stage s_H = graph_4D.Hamiltonian # ################ GET EXECUTABLE AND USE THE EXECUTABLE ############ # Get executable solve_pde = hcl.build(s) # Variables used for timing execution_time = 0 lookback_time = 0 while lookback_time <= lookback_length: # Start timing start = time.time() # Printing some info #print("Look back time is (s): {:.5f}".format(lookback_time)) # Run the execution and pass input into graph solve_pde(V_1, V_0, list_theta, t_minh) if lookback_time != 0: # Exclude first time of the computation execution_time += time.time() - start lookback_time += np.asscalar(t_minh.asnumpy()) # Some information printing #print(t_minh) print( "Computational time to integrate (s): {:.5f}".format(time.time() - start)) V_1 = V_1.asnumpy() V_1 = np.swapaxes(V_1, 0, 2) #V = np.swapaxes(V, 1,2) #probe = probe.asnumpy() #probe = np.swapaxes(probe, 0, 2) #probe = np.swapaxes(probe, 1, 2) #print(V) #V_1 = V_1.asnumpy() # Time info printing print("Total kernel time (s): {:.5f}".format(execution_time)) print("Finished solving\n") ##################### PLOTTING ##################### if args.plot: print("Plotting beautiful plots. Please wait\n") fig = go.Figure( data=go.Isosurface(x=g.mg_X.flatten(), y=g.mg_Y.flatten(), z=g.mg_T.flatten(), value=V_1.flatten(), colorscale='jet', isomin=0, surface_count=1, isomax=0, caps=dict(x_show=True, y_show=True))) fig.show() print("Please check the plot on your browser.")
import heterocl as hcl import numpy as np from gemm_main import * dtypes = [hcl.Int(32), hcl.Float(), hcl.Fixed(32, 16)] for dtype in dtypes: time_gemm(dtype, 10, 10, 10, 'vhls_csim')
def sobel(): hcl.init(init_dtype=hcl.Float()) path = pathlib.Path(__file__).parent.absolute() path = str(path) + '/test_report_data/rose-grayscale.jpg' img = imageio.imread(path) height, width, rgb = img.shape imgF = hcl.placeholder((height, width, 3), "Image") Gx = hcl.placeholder((3, 3), "Gx") Gy = hcl.placeholder((3, 3), "Gy") def sobel_kernel(imgF, Gx, Gy): def pad(x, y, z): out = hcl.scalar(0, "out") with hcl.if_(hcl.and_(x > 0, y > 0)): out.v = imgF[x - 1, y - 1, z] with hcl.else_(): out.v = 0 return out.v P = hcl.compute((height + 2, width + 2, 3), lambda x, y, z: pad(x, y, z), "P") A = hcl.compute((height + 2, width + 2), lambda x, y: P[x][y][0] + P[x][y][1] + P[x][y][2], "A") r = hcl.reduce_axis(0, 3) c = hcl.reduce_axis(0, 3) resX = hcl.compute((height, width), lambda x, y: hcl.sum( A[x + r, y + c] * Gx[r, c], axis=[r, c], name="sum1"), "X") t = hcl.reduce_axis(0, 3) g = hcl.reduce_axis(0, 3) resY = hcl.compute((height, width), lambda x, y: hcl.sum( A[x + t, y + g] * Gy[t, g], axis=[t, g], name="sum2"), "Y") R = hcl.compute((height, width), lambda x, y: hcl.sqrt(resX[x][ y] * resX[x][y] + resY[x][y] * resY[x][y]), "R") norm = hcl.scalar(255 / 4328) return hcl.compute((height, width), lambda x, y: R[x][y] * norm.v, "F") s = hcl.create_schedule([imgF, Gx, Gy], sobel_kernel) sA = sobel_kernel.A sX = sobel_kernel.X sY = sobel_kernel.Y LBX = s.reuse_at(sA._op, s[sX], sX.axis[0], "LBX") LBY = s.reuse_at(sA._op, s[sY], sY.axis[0], "LBY") WBX = s.reuse_at(LBX, s[sX], sX.axis[1], "WBX") WBY = s.reuse_at(LBY, s[sY], sY.axis[1], "WBY") s.partition(LBX, dim=1) s.partition(LBY, dim=1) s.partition(WBX) s.partition(WBY) s.partition(Gx) s.partition(Gy) sP = sobel_kernel.P sR = sobel_kernel.R sF = sobel_kernel.F s[sX].pipeline(sX.axis[1]) s[sY].pipeline(sY.axis[1]) s[sR].pipeline(sR.axis[1]) s[sF].pipeline(sF.axis[1]) target = hcl.platform.zc706 target.config(compile="vivado_hls", mode="csyn") hcl_img = hcl.asarray(img) hcl_Gx = hcl.asarray(np.array([[-1, -2, -1], [0, 0, 0], [1, 2, 1]])) hcl_Gy = hcl.asarray(np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]])) hcl_F = hcl.asarray(np.zeros((height, width))) f = hcl.build(s, target) f(hcl_img, hcl_Gx, hcl_Gy, hcl_F) return f.report()
def HJSolver(dynamics_obj, grid, init_value, tau, compMethod, plot_option): print("Welcome to optimized_dp \n") ################### PARSING ARGUMENTS FROM USERS ##################### parser = ArgumentParser() parser.add_argument("-p", "--plot", default=True, type=bool) # # Print out LLVM option only # parser.add_argument("-l", "--llvm", default=False, type=bool) args = parser.parse_args() hcl.init() hcl.config.init_dtype = hcl.Float(32) ################# INITIALIZE DATA TO BE INPUT INTO EXECUTABLE ########################## print("Initializing\n") V_0 = hcl.asarray(init_value) V_1 = hcl.asarray(np.zeros(tuple(grid.pts_each_dim))) l0 = hcl.asarray(init_value) probe = hcl.asarray(np.zeros(tuple(grid.pts_each_dim))) #obstacle = hcl.asarray(cstraint_values) list_x1 = np.reshape(grid.vs[0], grid.pts_each_dim[0]) list_x2 = np.reshape(grid.vs[1], grid.pts_each_dim[1]) list_x3 = np.reshape(grid.vs[2], grid.pts_each_dim[2]) if grid.dims >= 4: list_x4 = np.reshape(grid.vs[3], grid.pts_each_dim[3]) if grid.dims >= 5: list_x5 = np.reshape(grid.vs[4], grid.pts_each_dim[4]) if grid.dims >= 6: list_x6 = np.reshape(grid.vs[5], grid.pts_each_dim[5]) # Convert to hcl array type list_x1 = hcl.asarray(list_x1) list_x2 = hcl.asarray(list_x2) list_x3 = hcl.asarray(list_x3) if grid.dims >= 4: list_x4 = hcl.asarray(list_x4) if grid.dims >= 5: list_x5 = hcl.asarray(list_x5) if grid.dims >= 6: list_x6 = hcl.asarray(list_x6) # Get executable if grid.dims == 3: solve_pde = graph_3D(dynamics_obj, grid, compMethod) if grid.dims == 4: solve_pde = graph_4D(dynamics_obj, grid, compMethod) if grid.dims == 5: solve_pde = graph_5D(dynamics_obj, grid, compMethod) if grid.dims == 6: solve_pde = graph_6D(dynamics_obj, grid, compMethod) # Print out code for different backend #print(solve_pde) ################ USE THE EXECUTABLE ############ # Variables used for timing execution_time = 0 iter = 0 tNow = tau[0] for i in range(1, len(tau)): #tNow = tau[i-1] t_minh = hcl.asarray(np.array((tNow, tau[i]))) while tNow <= tau[i] - 1e-4: tmp_arr = V_0.asnumpy() # Start timing iter += 1 start = time.time() print("Started running\n") # Run the execution and pass input into graph if grid.dims == 3: solve_pde(V_1, V_0, list_x1, list_x2, list_x3, t_minh, l0) if grid.dims == 4: solve_pde(V_1, V_0, list_x1, list_x2, list_x3, list_x4, t_minh, l0, probe) if grid.dims == 5: solve_pde(V_1, V_0, list_x1, list_x2, list_x3, list_x4, list_x5, t_minh, l0) if grid.dims == 6: solve_pde(V_1, V_0, list_x1, list_x2, list_x3, list_x4, list_x5, list_x6, t_minh, l0) tNow = np.asscalar((t_minh.asnumpy())[0]) # Calculate computation time execution_time += time.time() - start # Some information printing print(t_minh) print("Computational time to integrate (s): {:.5f}".format( time.time() - start)) # Time info printing print("Total kernel time (s): {:.5f}".format(execution_time)) print("Finished solving\n") ##################### PLOTTING ##################### if args.plot: # plot Value table when speed is maximum plot_isosurface(grid, V_1.asnumpy(), plot_option)