Skip to content

Commit

Permalink
Fix excessive memory usage in cf due to deep copies
Browse files Browse the repository at this point in the history
  • Loading branch information
stefraynaud committed Oct 20, 2023
1 parent 587b678 commit 31965e2
Showing 1 changed file with 5 additions and 21 deletions.
26 changes: 5 additions & 21 deletions xoa/cf.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,6 @@ class SGLocator(object):
_compile_sg_match_(re_match, valid_attrs, formats, root_patterns, location_pattern)

def __init__(self, name_format=None, valid_locations=None, encoding=None):

# Init
self.formats = self.formats.copy()
self.re_match = self.re_match.copy()
Expand Down Expand Up @@ -592,14 +591,12 @@ def patch_attrs(self, attrs, patch, loc=None, standardize=True, replace=False):

# Loop patching on attributes
for attr, value in patch.items():

# Skip
if value is None or (attr in attrs and not replace):
continue

# Attr with loc
if attr in self.valid_attrs:

# List
if isinstance(value, list):
if attr in attrs:
Expand Down Expand Up @@ -672,7 +669,7 @@ def format_dataarray(
patch_attrs
"""
if copy:
da = da.copy()
da = da.copy(deep=False)

# Location argument
loc = self.parse_loc_arg(loc) # specified
Expand Down Expand Up @@ -781,7 +778,6 @@ class CFSpecs(object):
"""

def __init__(self, cfg=None, default=True, user=True, name=None, cache=None):

# Initialiase categories
self._cfs = {}
catcls = {"data_vars": CFVarSpecs, "coords": CFCoordSpecs}
Expand Down Expand Up @@ -823,7 +819,6 @@ def _load_cfg_as_dict_(self, cfg, cache=None):
or (isinstance(cfg, dict) and "register" in cfg and cfg["register"]["name"])
)
if cache:

# Init cache
if isinstance(cfg, str):
cache_key = cfg
Expand Down Expand Up @@ -979,7 +974,6 @@ def set_specs(self, category, name, **specs):
self.load_cfg(data)

def _post_process_(self):

# Inits
items = {}
for category in self.categories:
Expand Down Expand Up @@ -1051,7 +1045,6 @@ def _process_entry_(self, category, name):

# Inherits from other specs (merge specs with dict_merge)
if "inherit" in specs and specs["inherit"]:

# From what?
from_name = specs["inherit"]
if ":" in from_name:
Expand Down Expand Up @@ -1263,7 +1256,7 @@ def _format_obj_(
"""
# Copy
if copy:
obj = obj.copy()
obj = obj.copy(deep=False)

# Init rename dict
rename_args = {}
Expand Down Expand Up @@ -2180,7 +2173,7 @@ def infer_coords(self, ds):
for da in ds.data_vars.values():
if self.coords.match(da):
ds = ds.set_coords(da.name)
return ds.copy()
return ds.copy(deep=False)


class _CFCatSpecs_(object):
Expand Down Expand Up @@ -2373,7 +2366,6 @@ def match(self, da, cf_name=None, loc=None):
else:
names = self.names
for name_ in names:

# Get match specs
if isinstance(name_, dict):
match_specs = name_
Expand Down Expand Up @@ -2576,7 +2568,6 @@ def get_attrs(
# Loop
attrs = {}
for key in specs["attrs"].keys():

# No lists or tuples
value = specs["attrs"][key]
if isinstance(value, list):
Expand Down Expand Up @@ -2715,15 +2706,15 @@ def format_dataarray(
if rename:
copy = True
if copy:
da = da.copy()
da = da.copy(deep=False)

# Names
if cf_name is None:
cf_name = self.match(da)
if cf_name is None:
if not rename:
return
return da.copy() if copy else None
return da.copy(deep=False) if copy else None
assert cf_name in self.names
old_name = da.name
new_name = self.get_name(cf_name, specialize=specialize) # if specialize else cf_name
Expand All @@ -2734,7 +2725,6 @@ def format_dataarray(

# Attributes
if attrs is True:

# Get attributes from Cf specs
attrs = self.get_attrs(cf_name, loc=None, standardize=False, multi=True)

Expand Down Expand Up @@ -2914,7 +2904,6 @@ def get_dim_type(self, dim, obj=None, lower=True):

# Check if a coordinate have the same name and an axis type
if obj is not None:

# Check dim validity
if dim_loc not in obj.dims:
raise XoaCFError(f"dimension '{dim}' does not belong to obj")
Expand Down Expand Up @@ -3018,7 +3007,6 @@ def search_dim(self, obj, cf_arg=None, loc=None, single=True, errors="ignore"):
# Loop on dims
found = []
for dim in obj.dims:

# Filter-out by loc
pname, ploc = self.sglocator.parse_attr('name', dim)
ploc = self.sglocator.parse_loc_arg(ploc)
Expand Down Expand Up @@ -3117,7 +3105,6 @@ def get_ndim(o):
return len(o.dims)

if dim_type is not None:

# Look for a coordinate with this dim_type
# starting from coordinates with a higher number of dimensions
# like depth that have more dims than level
Expand Down Expand Up @@ -3246,7 +3233,6 @@ def get_rename_dims_args(self, obj, locations=None, specialize=False):
# Loop on dims
rename_args = {}
for dim in obj.dims:

# Skip effective coordinate dims
if dim in obj.coords:
continue
Expand Down Expand Up @@ -3585,7 +3571,6 @@ def get_default_cf_specs(cache="rw"):

# Compute it from scratch
if cfspecs is None:

# Setup
cfspecs = CFSpecs()

Expand Down Expand Up @@ -3641,7 +3626,6 @@ def get_cf_specs(name=None, cache="rw"):
if name is None:
name = "current"
if not isinstance(name, str) or name not in ("current", "default"):

# Registered name
if isinstance(name, str):
return get_cf_specs_from_name(name, errors="raise")
Expand Down

0 comments on commit 31965e2

Please sign in to comment.