Разница в производительности, которую вы видите, связана с внутренними структурами данных в OpenMDAO.Ваша модель, когда заданы аналитические производные, указывается с использованием разреженного формата (это хорошо, так как он очень разреженный!).Но для того, чтобы действительно воспользоваться этим преимуществом, вам нужно использовать формат собранной матрицы для хранения частичных производных данных и прямой решатель для вычисления разреженной факторизации LU.Как только вы добавите эти функции в свою модель, производительность для аналитики будет выше, чем в CS.
Расхождение возникает потому, что когда вы используете чистый CS, вы сохраняете производные в плотный формат, который ведет себя как собранная матрица.Но когда вы указали аналитические производные, вы не получили эту выгоду по умолчанию.таким образом, были некоторые основные различия в том, как фреймворк обрабатывал каждый случай.
Вот обновленный скрипт, который показывает правильную производительность (я сделал размер ввода меньше, чтобы он работал быстрее)
import time
import numpy as np
# dim1,dim2,dim3=10,40,30
dim1,dim2,dim3=10,40,5
ran1=np.random.random([dim1,dim2,dim3])*5
ran2=np.random.random([dim1,dim2,dim3])*10
from openmdao.api import Problem, Group, IndepVarComp, ExplicitComponent, DirectSolver
class FDPartialComp(ExplicitComponent):
def setup(self):
self.add_input('var1', val=np.ones([dim1,dim2,dim3]))
self.add_input('var2', val=np.ones([dim1,dim2,dim3]))
self.add_output('f', shape=(dim1,))
self.flag=0
self.cou=0
self.partcou=0
if self.flag:
self.declare_partials('*', '*', method='cs')
else:
self.declare_partials('f', 'var1',cols=np.arange(dim2*dim3*dim1),rows=np.repeat(np.arange(dim1),dim2*dim3))
self.declare_partials('f', 'var2' ,cols=np.arange(dim2*dim3*dim1),rows=np.repeat(np.arange(dim1),dim2*dim3))
def compute(self, inputs, outputs):
self.cou+=1
# print(self.cou)
var1 = inputs['var1']
var2 = inputs['var2']
m=3
outputs['f'] = np.sum((var2*var1**m),axis=(1,2))
def compute_partials(self, inputs, partials):
if self.flag:
pass
else:
m=3
var1 = inputs['var1']
var2 = inputs['var2']
partials['f','var1'] = (var1**m*m*var2/var1).flatten()
partials['f','var2' ]= (var1**m).flatten()
self.partcou+=1
# print(self.partcou)
model = Group()
comp = IndepVarComp()
comp.add_output('var1', ran1)
comp.add_output('var2', ran2)
#comp.add_output('var1', np.ones([dim1,dim2,dim3])*5)
#comp.add_output('var2', np.ones([dim1,dim2,dim3])*10)
model.add_subsystem('input', comp,promotes=['*'])
model.add_subsystem('example', FDPartialComp(),promotes=['*'])
model.linear_solver = DirectSolver(assemble_jac=True)
problem = Problem(model=model)
problem.setup(check=True, mode='fwd')
problem.final_setup()
# exit()
#problem.run_model()
st=time.time()
totals = problem.compute_totals(['f'], ['var1','var2'])
#problem.check_partials(compact_print=True,method='cs')
print(time.time()-st)
print(problem._mode)