Caffe2 - Python API
A deep learning, cross platform ML framework
workspace.py
1 ## @package onnx
2 # Module caffe2.python.onnx.workspace
3 
4 from __future__ import absolute_import
5 from __future__ import division
6 from __future__ import print_function
7 from __future__ import unicode_literals
8 
9 import uuid
10 
11 from caffe2.python import workspace
12 
13 
14 class Workspace(object):
15  """
16  An object representing a Caffe2 workspace. It is a context manager,
17  so you can say 'with workspace:' to use the represented workspace
18  as your global workspace. It also supports every method supported
19  by caffe2.python.workspace, but instead of running these operations
20  in the global workspace, it runs them in the workspace represented
21  by this object. When this object goes dead, the workspace (and all
22  nets and blobs within it) are freed.
23 
24  Why do we need this class? Caffe2's workspace model is very "global state"
25  oriented, in that there is always some ambient global workspace you are
26  working in which holds on to all of your networks and blobs. This class
27  makes it possible to work with workspaces more locally, and without
28  forgetting to deallocate everything in the end.
29  """
30  def __init__(self):
31  # Caffe2 (apparently) doesn't provide any native method of generating
32  # a fresh, unused workspace, so we have to fake it by generating
33  # a unique ID and hoping it's not used already / will not be used
34  # directly in the future.
35  self.workspace_id = str(uuid.uuid4())
36  # A stack, so that the context manager is reentrant.
37  self.workspace_stack = []
38 
39  def __getattr__(self, attr):
40  def f(*args, **kwargs):
41  with self:
42  return getattr(workspace, attr)(*args, **kwargs)
43  return f
44 
45  def __enter__(self):
46  self.workspace_stack.append(workspace.CurrentWorkspace())
47  workspace.SwitchWorkspace(self.workspace_id, create_if_missing=True)
48 
49  def __exit__(self, exc_type, exc_value, traceback):
50  w = self.workspace_stack.pop()
51  # Strictly speaking, create_if_missing here is unnecessary, since a user
52  # is not supposed to be allowed to destruct a workspace while we're in
53  # it. However, empirically, it has been observed that during abnormal
54  # shutdown, Caffe2 deletes its default workspace fairly early in the
55  # final calls to destructors. In this case, we may attempt to exit
56  # to a default workspace which no longer exists. create_if_missing=True
57  # will (harmlessly) recreate the workspace before we finally quit.)
58  workspace.SwitchWorkspace(w, create_if_missing=True)
59 
60  def __del__(self):
61  # NB: This is a 'self' call because we need to switch into the workspace
62  # we want to reset before we actually reset it. A direct call to
63  # workspace.ResetWorkspace() will reset the ambient workspace, which
64  # is not want we want.
65  self.ResetWorkspace()