code: def _AddDynamicMemoryOptimization(model, blobs_to_keep, devices):
      blobs_to_keep_all_devices = set()
      if blobs_to_keep is not None:
          for device in devices:
              for blob_name in blobs_to_keep:
                  blobs_to_keep_all_devices.add(
                      "{}_{}/{}".format(
                          model._device_prefix, device, blob_name
                      )
                  )
  
      if model._rendezvous is not None:
          # GLOO operators expect the tensor addresses to remain same over
          # iterations so we need to remove param grads from the dynamic memory
          # management.
          blobs_to_keep_all_devices.update(
              [str(b) for b in model.param_to_grad.values()]
          )
  
      model.net._net = memonger.release_blobs_when_used(
          model.net.Proto(), blobs_to_keep_all_devices
      )
  
imports: from collections import OrderedDict
  import logging
  import copy
  from multiprocessing import cpu_count
  from caffe2.python import model_helper, dyndep, scope, workspace, core, memonger, utils
  from caffe2.proto import caffe2_pb2
  import numpy
  import warnings
label_desc: Use image node_id 47 for calling a global function with example usage: _AddDynamicMemoryOptimization(model, blobs_to_keep, devices) without return types