22import warnings
33from typing import Dict , List , Literal , Optional , Union
44
5- import metatensor .torch as mts
65import torch
7- from metatensor .torch import Labels , TensorBlock , TensorMap
6+ from metatensor .torch import Labels , TensorMap
87from metatomic .torch import (
98 AtomisticModel ,
109 ModelCapabilities ,
2827from ._base_composition import (
2928 BaseCompositionModel ,
3029 FixedCompositionWeights ,
31- _include_key ,
3230)
3331from .documentation import ModelHypers
3432
@@ -46,7 +44,7 @@ class CompositionModel(ModelInterface[ModelHypers]):
4644 model.
4745 """
4846
49- __checkpoint_version__ = 1
47+ __checkpoint_version__ = 2
5048 __supported_devices__ = ["cuda" , "cpu" ]
5149 __supported_dtypes__ = [torch .float64 ]
5250 __default_metadata__ = ModelMetadata (
@@ -266,9 +264,8 @@ def restart(self, dataset_info: DatasetInfo) -> "CompositionModel":
266264 self .dataset_info = merged_info
267265
268266 self ._new_outputs = []
269- buffer_names = [n for n , _ in self .named_buffers ()]
270267 for target_name , target_info in self .target_infos .items ():
271- if target_name + "_composition_buffer" in buffer_names :
268+ if target_name in self . model . weights :
272269 continue
273270 self ._new_outputs .append (target_name )
274271 self .model .add_output (target_name , target_info .layout )
@@ -298,11 +295,6 @@ def forward(
298295 :return: A dictionary mapping each requested output name to the
299296 corresponding ``TensorMap`` containing the computed values.
300297 """
301- dtype = systems [0 ].positions .dtype
302- device = systems [0 ].positions .device
303-
304- self .weights_to (device , dtype )
305-
306298 for output_name in outputs .keys ():
307299 if output_name not in self .outputs :
308300 raise ValueError (
@@ -349,43 +341,6 @@ def _add_output(self, target_name: str, target_info: TargetInfo) -> None:
349341 description = target_info .description ,
350342 )
351343
352- layout = mts .filter_blocks (
353- target_info .layout ,
354- Labels (
355- target_info .layout .keys .names ,
356- torch .vstack (
357- [key .values for key in target_info .layout .keys if _include_key (key )]
358- ),
359- assume_unique = True ,
360- ),
361- )
362-
363- fake_weights = TensorMap (
364- keys = layout .keys ,
365- blocks = [
366- TensorBlock (
367- values = torch .zeros (
368- (len (self .atomic_types ),) + b .values .shape [1 :],
369- dtype = torch .float64 ,
370- ),
371- samples = Labels (
372- names = ["center_type" ],
373- values = torch .tensor (self .atomic_types , dtype = torch .int ).reshape (
374- - 1 , 1
375- ),
376- assume_unique = True ,
377- ),
378- components = b .components ,
379- properties = b .properties ,
380- )
381- for b in layout .blocks ()
382- ],
383- )
384- self .register_buffer (
385- target_name + "_composition_buffer" ,
386- mts .save_buffer (mts .make_contiguous (fake_weights )),
387- )
388-
389344 def remove_output (self , target_name : str ) -> None :
390345 """
391346 Remove a previously registered output target, mirroring ``_add_output``.
@@ -395,32 +350,6 @@ def remove_output(self, target_name: str) -> None:
395350 self .outputs .pop (target_name , None )
396351 self .dataset_info .targets .pop (target_name , None )
397352 self .model .remove_output (target_name )
398- buffer_name = target_name + "_composition_buffer"
399- if hasattr (self , buffer_name ):
400- delattr (self , buffer_name )
401-
402- def weights_to (self , device : torch .device , dtype : torch .dtype ) -> None :
403- """
404- Move the fitted weights and the accumulated quantities to the given
405- device and dtype.
406-
407- Needed because they are stored as ``TensorMap`` attributes, which
408- ``torch.nn.Module.to`` does not move.
409-
410- :param device: Device to move the weights to.
411- :param dtype: Dtype to convert the weights to.
412- """
413- if len (self .model .weights ) != 0 :
414- if self .model .weights [list (self .model .weights .keys ())[0 ]].device != device :
415- self .model .weights = {
416- k : v .to (device ) for k , v in self .model .weights .items ()
417- }
418- if self .model .weights [list (self .model .weights .keys ())[0 ]].dtype != dtype :
419- self .model .weights = {
420- k : v .to (dtype ) for k , v in self .model .weights .items ()
421- }
422-
423- self .model ._sync_device_dtype (device , dtype )
424353
425354 @staticmethod
426355 def is_valid_target (target_name : str , target_info : TargetInfo ) -> bool :
@@ -472,21 +401,6 @@ def is_valid_target(target_name: str, target_info: TargetInfo) -> bool:
472401
473402 return True
474403
475- def sync_tensor_maps (self ) -> None :
476- """
477- Reload the weight ``TensorMap`` objects from the registered buffers.
478-
479- Must be called after the buffers change through means that bypass the
480- model, e.g. ``load_state_dict``.
481- """
482- for k in self .dataset_info .targets :
483- buffer = self .__getattr__ (k + "_composition_buffer" )
484- # ``mts.load_buffer`` dereferences the buffer on the host, so it
485- # segfaults on a GPU buffer: deserialize on the CPU and move the
486- # weights back to the buffer's device.
487- weights = mts .load_buffer (buffer .to (device = "cpu" ))
488- self .model .weights [k ] = weights .to (device = buffer .device )
489-
490404 def get_checkpoint (self ) -> Dict :
491405 """
492406 Get the checkpoint of the model.
@@ -543,7 +457,6 @@ def load_checkpoint(
543457 )
544458
545459 model .load_state_dict (model_state_dict )
546- model .sync_tensor_maps ()
547460
548461 model .metadata = merge_metadata (model .metadata , checkpoint .get ("metadata" ))
549462
@@ -587,14 +500,11 @@ def export(self, metadata: Optional[ModelMetadata] = None) -> AtomisticModel:
587500 raise ValueError (f"unsupported dtype { dtype } for composition model" )
588501
589502 self .to (dtype )
590- self .weights_to (torch .device ("cpu" ), torch .float64 )
591-
592- interaction_range = 0.0
593503
594504 capabilities = ModelCapabilities (
595505 outputs = self .outputs ,
596506 atomic_types = self .atomic_types ,
597- interaction_range = interaction_range ,
507+ interaction_range = 0.0 ,
598508 length_unit = self .dataset_info .length_unit ,
599509 supported_devices = self .__supported_devices__ ,
600510 dtype = dtype_to_str (dtype ),
0 commit comments