Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adjoint optimization with multiple objective functions #2097

Closed
mochen4 opened this issue Jun 8, 2022 · 4 comments · Fixed by #2251
Closed

adjoint optimization with multiple objective functions #2097

mochen4 opened this issue Jun 8, 2022 · 4 comments · Fixed by #2251

Comments

@mochen4
Copy link
Collaborator

mochen4 commented Jun 8, 2022

Adjoint optimization fails if there are more than one objective functions.

mp._get_gradient(grad,scalegrad,
fields_a[0].swigobj,fields_a[1].swigobj,fields_a[2].swigobj,
fields_f[0].swigobj,fields_f[1].swigobj,fields_f[2].swigobj,
sim.gv,vol.swigobj,onp.array(frequencies),
sim.geps,finite_difference_step)
Somewhere in mp._get_gradient frees the memory of the fields, causing problems when we reuse the forward fields again for the another objective function.

The issue actually exists before #1855 , where we could make copies of forward fields before passing in mp._get_gradient. Right now, the naive fix could be installing one forward design region monitor for each objective function, so that we have a fresh copy each time we call mp._get_gradient.

@smartalecH
Copy link
Collaborator

Somewhere in mp._get_gradient frees the memory of the fields

I'm guessing this is the culprit, in meepgeom.cpp:

meep/src/meepgeom.cpp

Lines 3023 to 3029 in 91d36ba

// clear all the dft data structures
for (int i=0;i<3;i++){
for (int ii=0;ii<adjoint_dft_chunks[i].size();ii++){
delete adjoint_dft_chunks[i][ii];
delete forward_dft_chunks[i][ii];
}
}

@Andeloth
Copy link

I have been able to use multiple objective functions in the adjoint solver, so I think it might be something more specific that's causing the issue. AKA it's the combination of multiple objective functions AND something else that's causing this.

@stevengj
Copy link
Collaborator

@smartalecH, it seems odd that those chunks are being deleted in this routine, since they aren't allocated by this routine. Shouldn't they be deleted by the code that "owns" them?

@smartalecH
Copy link
Collaborator

Basically, we need a new routine that separately deletes DFT chunks when we want to. The tricky part is we need to remember when to delete them.

For example, we want to delete each adjoint chunk after we "recombine" it with the forward runs. So modifying the earlier block of code should suffice:

 // clear all the dft data structures 
 for (int i=0;i<3;i++){ 
   for (int ii=0;ii<adjoint_dft_chunks[i].size();ii++){ 
     delete adjoint_dft_chunks[i][ii]; 
   } 
 } 

However, we need to hang on to the forward chunks until we are all done looping through objective functions (and performing their recombination steps), which is done here:

self.gradient = [[
dr.get_gradient(
self.sim,
self.adjoint_design_region_monitors[ar][dri],
self.forward_design_region_monitors[dri],
self.frequencies,
self.finite_difference_step
) for dri, dr in enumerate(self.design_regions)
] for ar in range(len(self.objective_functions))]

So after this point, we can now delete the forward chunks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants