Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 0 additions & 16 deletions openff/interchange/components/interchange.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,6 @@ def from_smirnoff(
"""
from openff.interchange.smirnoff._create import _create_interchange

_clear_caches()

return _create_interchange(
force_field=force_field,
topology=topology,
Expand Down Expand Up @@ -845,8 +843,6 @@ def from_foyer(
"""
from openff.interchange.foyer._create import _create_interchange

_clear_caches()

return _create_interchange(
force_field=force_field,
topology=topology,
Expand Down Expand Up @@ -1108,15 +1104,3 @@ def __repr__(self) -> str:
f"Interchange with {len(self.collections)} collections, "
f"{'' if periodic else 'non-'}periodic topology with {n_atoms} atoms."
)


def _clear_caches():
import functools
import gc

for obj in gc.get_objects():
try:
if isinstance(obj, functools._lru_cache_wrapper) and obj.__module__.startswith("openff.interchange"):
obj.cache_clear()
except ReferenceError:
continue
9 changes: 0 additions & 9 deletions openff/interchange/components/potentials.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
from __future__ import annotations

import ast
import functools
import gc
import json
from typing import TYPE_CHECKING, Annotated, Any, TypeAlias

Expand Down Expand Up @@ -291,13 +289,6 @@ def get_force_field_parameters(
def set_force_field_parameters(self, new_p: ArrayLike) -> None:
"""Set the force field parameters from a flattened representation."""

# Clear cache of all methods that are wrapped by functools.lru_cache
# A better solution might be at the level of parameter re-assignment
# See issue #1234
for obj in gc.get_objects():
if isinstance(obj, functools._lru_cache_wrapper) and obj.__module__.startswith("openff.interchange"):
obj.cache_clear()

mapping = self.get_mapping()
if new_p.shape[0] != len(mapping): # type: ignore
raise RuntimeError
Expand Down
20 changes: 20 additions & 0 deletions openff/interchange/smirnoff/_create.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,24 @@ def _preprocess_preset_charges(
return molecules_with_preset_charges


def _clear_smirnoff_creation_caches():
"""
Due to bugs in the toolkit, these caches can be invalid of a force field is modified and then
sent to (SMIRNOFF) creation pathways again. This function clears those caches - call it whenever
`Interchange.from_smirnoff` may be called multiple times on the same force field object
(including possible modifications).

https://github.com/openforcefield/openff-toolkit/issues/2065
"""
from openff.interchange.components.toolkit import _cache_angle_parameter_lookup, _cache_torsion_parameter_lookup

for obj in [
_cache_angle_parameter_lookup,
_cache_torsion_parameter_lookup,
]:
obj.cache_clear()


def _create_interchange(
force_field: ForceField,
topology: Topology | list[Molecule],
Expand All @@ -147,6 +165,8 @@ def _create_interchange(

_check_supported_handlers(force_field)

_clear_smirnoff_creation_caches()

if molecules_with_preset_charges and "VirtualSites" in force_field.registered_parameter_handlers:
warnings.warn(
"Preset charges were provided (via `charge_from_molecules`) alongside a force field that includes "
Expand Down
Loading