Metadata.lua 1.99 KB
Newer Older
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
-- Copyright 2016-present, Facebook, Inc.
-- All rights reserved.
--
-- This source code is licensed under the license found in the
-- LICENSE file in the root directory of this source tree.

--[[
Store Metadata relating to which spatial locations are active at each scale.
Convolutions and 'convolution reversing' deconvolutions
all coexist within the same MetaData object as long as each spatial size
only occurs once. Valid convolutions do not change the spatial structure.

Serialization is emulated by storing the pointer as an integer.
This is sufficient for mutithreaded batch preparation: each 'serialized'
object must be de-serialized exactly once.
]]

return function(sparseconvnet)
  local ffi=require 'ffi'
  local C = sparseconvnet.C
  local Metadata = torch.class('sparseconvnet.Metadata', sparseconvnet)
  function Metadata:__init(dimension)
    self.ffi=ffi.new('void *[1]')
    self.dimension=dimension
    --[[ffi.gc to delete Metadata that need to be garbage collected.]]
    ffi.gc(self.ffi, C.dimensionFn(self.dimension, 'freeMetadata'))
  end
  function Metadata:deactivateGC()
    --[[FFI pointers cannot be serialized for passing from batch-creation
    worker threads to the main learner thread. So we convert it to something
    that can, ...]]
    if self.ffi then
      self.p = torch.LongStorage(1)
      C.copyFfiPtrToLong(self.p,self.ffi)
      ffi.gc(self.ffi,nil)
      self.ffi=nil
    end
  end
  function Metadata:reactivateGC()
    --[[... and then convert them back as soon as possible after the thread
    to thread transfer, and hope no-one notices.]]
    if self.p then
      self.ffi=ffi.new('void *[1]')
      ffi.gc(self.ffi, C.dimensionFn(self.dimension, 'freeMetadata'))
      C.copyLongToFfiPtr(self.ffi,self.p)
      self.p=nil
    end
  end
  function Metadata:write(file)
    self:deactivateGC()
    file:writeObject({self.dimension,self.p})
  end
  function Metadata:read(file)
    local r = file:readObject()
    self.dimension=r[1]
    self.p=r[2]
    self:reactivateGC()
  end
end