def compute_linear_gradient_manually(args,model,data_tr,data_te,device):
N_tr = len(data_tr)
N_te = len(data_te)
kernel_tr = torch.zeros(N_tr,N_tr).to(device)
kernel_te = torch.zeros(N_te,N_tr).to(device)
for i in range(N_tr):
grad_tr = compute_layer_gradient(args,model,data_tr[i])
for j in range(N_tr):
grad_tr_ = compute_layer_gradient(args,model,data_tr[j])
kernel_tr[i][j] = torch.mm(grad_tr,grad_tr_.t())
for k in range(N_te):
grad_tr_ = compute_layer_gradient(args,model,data_te[k])
kernel_te[i][k] = torch.mm(grad_tr,grad_tr_.t())
return kernel_tr,kernel_te
def compute_layer_gradient(args,model,data):
p = ((torch.mm(data.view(-1,3072),model.weight1)+model.bias1)>0).float()
weight2_grad = ((torch.mm(data.view(-1,3072),model.weight1)+model.bias1)*p).t()
weight1_grad = torch.mm(data.view(-1,3072).t(),model.weight2.t()*p)
bias1_grad = math.sqrt(1/width)*model.weight2.t()*p.view(-1,width)
grad = torch.cat([weight1_grad.view(-1,3072*width),bias1_grad.view(-1,width),weight2_grad.view(-1,width)],dim=1)
return grad
I am using CUDA to compute two matrices kernel_tr and kernel_te. The function compute_layer_gradient returns a 1*m vector and data_tr and data_te are two matrices.
But the memory keeps increasing and I have tried using del grad_tr_ or something like that but it doesn't work.
How to correctly release the memory in this loop?
Related
I've been trying to set up a script to automatically assign connector displacement boundary conditions. When I run the script it all looks fine in the GUI (wires are created, BCs are created and assigned the right value), but when I submit I get the following error: "Element connectivity is missing for element x of type "CONN3D2" and the element connectivity is in fact missing in the input file. I assign the edges by using the midpoints between the wire start and ends, but for some reason it doesn't assign them to the elements. This is my connector assignment function:
def assignConnectors(self):
p = self.m.parts[self.partName]
a = self.m.rootAssembly
a.Instance(name=self.instanceName, part=p, dependent=ON)
e = a.edges
n = a.instances[self.instanceName].nodes
#allelements = p.Set(name='allElements', elements=self.listObjElem)
elset = a.instances[self.instanceName].elements
elsetAssembly = a.Set('assemblyElements', elements=elset)
a.regenerate()
v1 = a.instances[self.instanceName].vertices
rows = len(self.listConstraints)
columns = len(self.listConstraints[0])
total = rows*columns
listObjNode=[];
self.listObjElem=[];
self.listObjConnector=[];
for j,pairElem in enumerate(self.listElem):
p1 = a.getCoordinates(self.listNodes[pairElem[0]-1])
p2 = a.getCoordinates(self.listNodes[pairElem[1]-1])
#print(p1,p2)
wires = a.WirePolyLine(points=((p1,p2),), mergeType=IMPRINT, meshable=OFF)
a.regenerate()
pt1 = a.getCoordinates(self.listNodes[pairElem[0]-1])
pt2 = a.getCoordinates(self.listNodes[pairElem[1]-1])
print(pt1,pt2)
pt11 = np.asarray(pt1[0])
pt12 = np.asarray(pt1[1])
pt13 = np.asarray(pt1[2])
pt21 = np.asarray(pt2[0])
pt22 = np.asarray(pt2[1])
pt23 = np.asarray(pt2[2])
new_p1 = (pt11+pt21)/2
new_p2 = (pt12+pt22)/2
new_p3 = (pt13+pt23)/2
new_p = tuple([new_p1,new_p2,new_p3])
print(new_p)
a = self.m.rootAssembly
e = a.edges
edges1 = e.findAt((new_p, ))
print(edges1)
region = a.Set(edges = edges1, name='Set'+str(j))
self.m.ConnectorSection(name='ConnSect-1'+str(j),translationalType=AXIAL)
csa = a.SectionAssignment(sectionName='ConnSect-1'+str(j), region=region)
self.m.ConnDisplacementBC(name='BC-'+str(j+total), createStepName=self.stepName, fastenerSetName='Set'+str(j), u1=float(self.listElongations[j]), u2=UNSET, u3=UNSET, ur1=UNSET, ur2=UNSET, ur3=UNSET, amplitude=UNSET, fixed=OFF, distributionType=UNIFORM)
a.regenerate()
Am I assigning the elements wrong somehow?
Thanks a lot for any help!
This is the code. I think the solver could be glpk instead of gurobi. I got the error before it tries to solve the problem.
from pyomo.environ import *
from pyomo.opt import SolverFactory, SolverStatus
PrintSolverOutput = False ###
model = ConcreteModel()
model.dual = Suffix(direction =Suffix.IMPORT)
model.X = Var(I,T, within = NonNegativeReals)
model.In = Var(I,T, within = NonNegativeReals)
model.S = Var(T, within = NonNegativeReals)
def Objetivo(model):
return (sum(C[i]*model.X[i,t]*((1+tau[i])**(t-1))+Ch[i]*model.In[i,t]
for i in I for t in T)
+sum(Cs*model.S[t]
for t in T)
)
model.Total_Cost = Objective(rule = Objetivo, sense= minimize)
def Balance(model,i,t):
if t==1:
return model.X[i,t]+I0[i]-model.In[i,t]==D[i,t]
elif t>=2:
return model.X[i,t]+model.IN[i,t-1]-model.In[i,t]==D[i,t]
def Horas(model, t):
return sum(r[i]*model.X[i,t] for i in I) <= H+model.S[t]
def Limite(model,t):
return model.S[T]<=LS
model.RBalance = Constraint(I,T,rule=Balance)
model.RHoras = Constraint(T,rule=Horas)
model.RLimiteoras = Constraint(T,rule=Limite)
opt = SolverFactory("gurobi")
This is the data
I forgot to put the data before.
T = [1,2,3,4,5,6]
I = ['A','B']
D = {('A',1):300,
('A',2):400,
('A',3):500,
('A',4):600,
('A',5):800,
('A',6):700,
('B',1):700,
('B',2):600,
('B',3):500,
('B',4):400,
('B',5):300,
('B',6):400}
tau = {'A':0.02,'B':0.01}
r = {'A':5,'B':3}
H = 3520
LS = 800
C = {'A':150,'B':120}
Ch = {'A':8,'B':4}
Cs = 6
I0 = {'A':100,'B':250}
error
The code is from a youtube tutorial and it worked for him but not for me. Why?
Aside from fixing two typos in your code, this model computes and solves for me without that error. Make these fixes, run it again, re-post the exact error with line number and the exact code that produces the error if stuck...
I am trying to implement in my simulation this code:
https://numpy.org/doc/stable/reference/random/multithreading.html
but I can't work it out.
If I follow the example in the link, I get
mrng = MultithreadedRNG(10000000, seed=0)
mrng.fill()
print(mrng.values[-1])
> 0.0
and all the other values are 0 too.
If I give a smaller input number, as 40, I get
mrng = MultithreadedRNG(40)
mrng.fill()
print(mrng.values[-1])
> array([1.08305179e-311, 1.08304781e-311, 1.36362118e-321, nan,
6.95195359e-310, ...., 7.27916164e-095, 3.81693953e+180])
What am I doing wrong? I just would like to implement this multiprocessing code to a random bits (0 / 1) generator.
There is a bug in the example, I believe. You have to wrap PCG64 into Generator interface.
Try code below
class MultithreadedRNG(object):
def __init__(self, n, seed=None, threads=None):
rg = PCG64(seed)
if threads is None:
threads = multiprocessing.cpu_count()
self.threads = threads
self._random_generators = [Generator(rg)]
last_rg = rg
for _ in range(0, threads-1):
new_rg = last_rg.jumped()
self._random_generators.append(Generator(new_rg))
last_rg = new_rg
self.n = n
self.executor = concurrent.futures.ThreadPoolExecutor(threads)
self.values = np.empty(n)
self.step = np.ceil(n / threads).astype(np.int_)
def fill(self):
def _fill(gen, out, first, last):
gen.standard_normal(out=out[first:last])
futures = {}
for i in range(self.threads):
args = (_fill,
self._random_generators[i],
self.values,
i * self.step,
(i + 1) * self.step)
futures[self.executor.submit(*args)] = i
concurrent.futures.wait(futures)
def __del__(self):
self.executor.shutdown(False)
Didn't test it much, but values looks ok
I am trying to run a NEAT algorithm using this python implementation. This is the original file from the library that is relevant for my question:
from neat.graphs import feed_forward_layers
class FeedForwardNetwork(object):
def __init__(self, inputs, outputs, node_evals):
self.input_nodes = inputs
self.output_nodes = outputs
self.node_evals = node_evals
self.values = dict((key, 0.0) for key in inputs + outputs)
def activate(self, inputs):
if len(self.input_nodes) != len(inputs):
raise RuntimeError("Expected {0:n} inputs, got {1:n}".format(len(self.input_nodes), len(inputs)))
for k, v in zip(self.input_nodes, inputs):
self.values[k] = v
for node, act_func, agg_func, bias, response, links in self.node_evals:
node_inputs = []
for i, w in links:
node_inputs.append(self.values[i] * w)
s = agg_func(node_inputs)
self.values[node] = act_func(bias + response * s)
return [self.values[i] for i in self.output_nodes]
#staticmethod
def create(genome, config):
""" Receives a genome and returns its phenotype (a FeedForwardNetwork). """
# Gather expressed connections.
connections = [cg.key for cg in genome.connections.values() if cg.enabled]
layers = feed_forward_layers(config.genome_config.input_keys, config.genome_config.output_keys, connections)
node_evals = []
for layer in layers:
for node in layer:
inputs = []
node_expr = [] # currently unused
for conn_key in connections:
inode, onode = conn_key
if onode == node:
cg = genome.connections[conn_key]
inputs.append((inode, cg.weight))
node_expr.append("v[{}] * {:.7e}".format(inode, cg.weight))
ng = genome.nodes[node]
aggregation_function = config.genome_config.aggregation_function_defs.get(ng.aggregation)
activation_function = config.genome_config.activation_defs.get(ng.activation)
node_evals.append((node, activation_function, aggregation_function, ng.bias, ng.response, inputs))
return FeedForwardNetwork(config.genome_config.input_keys, config.genome_config.output_keys, node_evals)
Since I evaluate the performance of my neural networks on a large dataset, I wanted to speed up the activate method using numba jit. In order to not fall back into numbas object mode I had to update the implementation of the activate method (and hence also the fields of the FeedForwardNetwork class) using only datatypes supported by numba. This is what I came up with (create is the same as before):
from neat.graphs import feed_forward_layers
from neat.six_util import itervalues
import numba
from numba import jit, njit
from numba.typed import List, Dict
import numpy as np
import math
#jit(nopython=True)
def activate(input_nodes, output_nodes, node_evals_node, node_evals_bias, node_evals_resp, node_evals_ins_nodes, node_evals_ins_conns, values, inputs):
for i in range(input_nodes.size):
values[input_nodes[i]] = inputs[i]
for node in range(len(node_evals_node)):
s = 0
for pred in range(len(node_evals_ins_nodes[node])):
s += values[node_evals_ins_nodes[node][pred]] * node_evals_ins_conns[node][pred]
values[node_evals_node[node]] = math.tanh(node_evals_bias[node] + node_evals_resp[node] * s)
return [values[output_nodes[i]] for i in range(output_nodes.size)]
class FeedForwardNetwork(object):
def __init__(self, inputs, outputs, node_evals):
self.input_nodes = np.array(inputs)
self.output_nodes = np.array(outputs)
# NODE_EVALS decomposition
self.node_evals_node = np.reshape(np.array(node_evals)[:, 0:1], (len(node_evals),)).astype(np.int64)
self.node_evals_bias = np.reshape(np.array(node_evals)[:, 3:4], (len(node_evals),)).astype(np.float64)
self.node_evals_resp = np.reshape(np.array(node_evals)[:, 4:5], (len(node_evals),)).astype(np.float64)
temp = np.array(node_evals)[:, 5:6]
self.node_evals_ins_nodes = List()
self.node_evals_ins_conns = List()
for node in range(temp.size):
l = List()
m = List()
for predecessor in range(len(temp[node])):
l.append(temp[0][node][predecessor][0])
m.append(temp[0][node][predecessor][1])
self.node_evals_ins_nodes.append(l)
self.node_evals_ins_conns.append(m)
self.values = Dict()
# Set types of dict
self.values[0] = float(1)
self.values.pop(0)
This is the code I call the create and activate method in:
def eval_single_genome(genome, config, thread_id, result):
net = neat.nn.FeedForwardNetwork.create(genome, config)
error_sum = 0
for i, row in PRICES.iterrows():
prediction = feed_forward.activate(net.input_nodes, net.output_nodes, net.node_evals_node, net.node_evals_bias, net.node_evals_resp, net.node_evals_ins_nodes, net.node_evals_ins_conns, net.values, np.array([0]))
error_sum += (prediction - PRICES.iloc[i]['open']) ** 2
result[thread_id] = error_sum
The code compiles and runs without errors or warnings which (as far as I've understood) indicates that numba should be able to optimize my implementation. But adding/removing the #jit(nopython=True)decorator doesn't change the runtime at all.
Did I overlook something? Or is there just nothing that numba can improve in my case?
So, I am trying to solve an optimization problem. What I am trying to figure out is that when I run the code, my function call "to_fp_Cx" throws an error and I don't understand why.
The traceback keeps pointing to the functions I have defined. I tested these functions independently by calling it with different values and that worked as expected. So, I am not sure what is happening.
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-41-3f717a4f07e1> in <module>
37 # intermediate variables with explicit equations
38
---> 39 if(fload_c3_1 < 0.1):
40 alt_fload_c3_1 = m.Intermediate(0)
41 else:
~\AppData\Local\Continuum\anaconda3\lib\site-packages\gekko\gk_operators.py in __len__(self)
23 return self.name
24 def __len__(self):
---> 25 return len(self.value)
26 def __getitem__(self,key):
27 return self.value[key]
~\AppData\Local\Continuum\anaconda3\lib\site-packages\gekko\gk_operators.py in __len__(self)
142
143 def __len__(self):
--> 144 return len(self.value)
145
146 def __getitem__(self,key):
TypeError: object of type 'int' has no len()
As the name suggests, I am a python noob and I am bamboozled. Any help would be appreciated. Thanks
import numpy as np
# import gekko, pip install if needed
from gekko import GEKKO
# Compressor Performance curves
# Fraction capacity to Fractional power conversion
# Compressor C3
def to_fp_c3(fc):
a = 5.16102738
b = -16.25992208
c = 18.52731113
d = -8.859480201
e = 2.096698885
f = 0.334319989
if (fc < 0.1):
fp = 0.0
else:
fp = (a*fc**5)+(b*fc**4)+(c*fc**3)+(d*fc**2)+(e*fc**1)+(f*fc**0)
return fp
...
### Optimization Model ####
# create new model
m = GEKKO(remote = False)
# Solver option - 1: APOPT, 2: BPOPT, 3: IPOPT 0:Benchmark all available
m.options.SOLVER = 3
# declare model parameters
maxcap_c3_1 = m.Param(value = 900)
maxcap_c3_2 = m.Param(value = 900)
load = m.Param(value = 1500)
## Model variables
# load distribution
fload_c3_1 = m.Var(value=0.50,lb=0.0,ub=1.0, integer = False)
fload_c3_2 = m.Var(value=0.50,lb=0.0,ub=1.0, integer = False)
# declare variables and initial guesses
#totalpowerdraw = m.Var()
# intermediate variables with explicit equations
if(fload_c3_1 < 0.1):
alt_fload_c3_1 = m.Intermediate(0)
else:
alt_fload_c3_1 = m.Intermediate(fload_c3_1)
if(fload_c3_2 < 0.1):
alt_fload_c3_2 = m.Intermediate(0)
else:
alt_fload_c3_2 = m.Intermediate(fload_c3_2)
assignedload_c3_1 = m.Intermediate(alt_fload_c3_1 * maxcap_c3_1)
assignedload_c3_2 = m.Intermediate(alt_fload_c3_2 * maxcap_c3_2)
powerdraw_c3_1 = m.Intermediate(to_fp_c3(alt_fload_c3_1) * maxcap_c3_1)
powerdraw_c3_2 = m.Intermediate(to_fp_c3(alt_fload_c3_2) * maxcap_c3_2)
totalpowerdraw = m.Intermediate(powerdraw_c3_1 + powerdraw_c3_2)
# implicit equations
m.Equation(load == assignedload_c3_1 + assignedload_c3_2 )
# minimize weight1
m.Obj(totalpowerdraw)
# solve optimization
m.solve() # remote=False for local solve
print ('')
print ('--- Results of the Optimization Problem ---')
print (alt_fload_c3_1.value, powerdraw_c3_1.value)
print (alt_fload_c3_1.value, powerdraw_c3_2.value)
Try the m.if3() (or m.if2()) function from Gekko to make the conditional statement switch based on a Gekko variable. There is more information on conditional statements in Question about the conditional statement ('m.if3') in the GEKKO
# use gekko if3 (or if2)
alt_fload_c3_1 = m.if3(fload_c3_1-0.1,0,fload_c3_1)
alt_fload_c3_2 = m.if3(fload_c3_2-0.1,0,fload_c3_2)
Here is a version of your program that gives a successful solution.
import numpy as np
from gekko import GEKKO
# Compressor Performance curves
# Fraction capacity to Fractional power conversion
# Compressor C3
def to_fp_c3(fc):
a = 5.16102738
b = -16.25992208
c = 18.52731113
d = -8.859480201
e = 2.096698885
f = 0.334319989
fp = m.if3(fc-0.1,0,(a*fc**5)+(b*fc**4)+(c*fc**3)\
+(d*fc**2)+(e*fc**1)+(f*fc**0))
return fp
### Optimization Model ####
# create new model
m = GEKKO(remote = False)
# declare model parameters
maxcap_c3_1 = m.Param(value = 900)
maxcap_c3_2 = m.Param(value = 900)
load = m.Param(value = 1500)
## Model variables
# load distribution
fload_c3_1 = m.Var(value=0.50,lb=0.0,ub=1.0, integer = False)
fload_c3_2 = m.Var(value=0.50,lb=0.0,ub=1.0, integer = False)
# use gekko if3 (or if2)
alt_fload_c3_1 = m.if3(fload_c3_1-0.1,0,fload_c3_1)
alt_fload_c3_2 = m.if3(fload_c3_2-0.1,0,fload_c3_2)
assignedload_c3_1 = m.Intermediate(alt_fload_c3_1 * maxcap_c3_1)
assignedload_c3_2 = m.Intermediate(alt_fload_c3_2 * maxcap_c3_2)
powerdraw_c3_1 = m.Intermediate(to_fp_c3(alt_fload_c3_1) * maxcap_c3_1)
powerdraw_c3_2 = m.Intermediate(to_fp_c3(alt_fload_c3_2) * maxcap_c3_2)
totalpowerdraw = m.Intermediate(powerdraw_c3_1 + powerdraw_c3_2)
# implicit equations
m.Equation(load == assignedload_c3_1 + assignedload_c3_2 )
# minimize weight1
m.Obj(totalpowerdraw)
# solve optimization
m.solve() # remote=False for local solve
print ('')
print ('--- Results of the Optimization Problem ---')
print (alt_fload_c3_1.value, powerdraw_c3_1.value)
print (alt_fload_c3_1.value, powerdraw_c3_2.value)
with the solution:
---------------------------------------------------
Solver : APOPT (v1.0)
Solution time : 0.0313 sec
Objective : 1576.7914326000025
Successful solution
---------------------------------------------------
--- Results of the Optimization Problem ---
[0.66761123885] [677.4476587]
[0.66761123885] [899.3437739]
You have to use this
If(fload_c3_1.value < 0.1):