parent
fb66acb6c8
commit
f8715f39e7
55 changed files with 2385 additions and 397 deletions
@ -1,2 +1,43 @@ |
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include <opencv2/core.hpp> |
||||
#include <opencv2/dnn.hpp> |
||||
|
@ -1,348 +0,0 @@ |
||||
local File = torch.getmetatable('torch.File') |
||||
|
||||
function File:writeBool(value) |
||||
if value then |
||||
self:writeInt(1) |
||||
else |
||||
self:writeInt(0) |
||||
end |
||||
end |
||||
|
||||
function File:readBool() |
||||
return (self:readInt() == 1) |
||||
end |
||||
|
||||
local TYPE_NIL = 0 |
||||
local TYPE_NUMBER = 1 |
||||
local TYPE_STRING = 2 |
||||
local TYPE_TABLE = 3 |
||||
local TYPE_TORCH = 4 |
||||
local TYPE_BOOLEAN = 5 |
||||
local TYPE_FUNCTION = 6 |
||||
local TYPE_RECUR_FUNCTION = 8 |
||||
local LEGACY_TYPE_RECUR_FUNCTION = 7 |
||||
|
||||
-- Lua 5.2 compatibility |
||||
local loadstring = loadstring or load |
||||
|
||||
function File:isWritableObject(object) |
||||
local typename = type(object) |
||||
local typeidx |
||||
if type(object) ~= 'boolean' and not object then |
||||
typeidx = TYPE_NIL |
||||
elseif torch.typename(object) and torch.factory(torch.typename(object)) then |
||||
typeidx = TYPE_TORCH |
||||
elseif typename == 'table' then |
||||
typeidx = TYPE_TABLE |
||||
elseif typename == 'number' then |
||||
typeidx = TYPE_NUMBER |
||||
elseif typename == 'string' then |
||||
typeidx = TYPE_STRING |
||||
elseif typename == 'boolean' then |
||||
typeidx = TYPE_BOOLEAN |
||||
elseif typename == 'function' and pcall(string.dump, object) then |
||||
typeidx = TYPE_RECUR_FUNCTION |
||||
end |
||||
return typeidx |
||||
end |
||||
|
||||
function File:referenced(ref) |
||||
-- we use an environment to keep a record of written objects |
||||
if not torch.getenv(self).writeObjects then |
||||
torch.setenv(self, {writeObjects={}, writeObjectsRef={}, readObjects={}}) |
||||
end |
||||
local env = torch.getenv(self) |
||||
env.force = not ref |
||||
torch.setenv(self,env) |
||||
return self |
||||
end |
||||
|
||||
function File:isReferenced() |
||||
-- if no environment, then no forcing setup yet |
||||
if not torch.getenv(self).writeObjects then |
||||
return true |
||||
end |
||||
local env = torch.getenv(self) |
||||
return not env.force |
||||
end |
||||
|
||||
local function getmetamethod(obj, name) |
||||
local func |
||||
local status |
||||
|
||||
-- check getmetatable(obj).__name or |
||||
-- check getmetatable(obj).name |
||||
status, func = pcall( |
||||
function() |
||||
-- note that sometimes the metatable is hidden |
||||
-- we get it for sure through the torch type system |
||||
local mt = torch.getmetatable(torch.typename(obj)) |
||||
if mt then |
||||
return mt['__' .. name] or mt[name] |
||||
end |
||||
end |
||||
) |
||||
if status and type(func) == 'function' then |
||||
return func |
||||
end |
||||
end |
||||
|
||||
function File:writeObject(object) |
||||
-- we use an environment to keep a record of written objects |
||||
if not torch.getenv(self).writeObjects then |
||||
torch.setenv(self, {writeObjects={}, writeObjectsRef={}, readObjects={}}) |
||||
end |
||||
|
||||
local force = torch.getenv(self).force |
||||
|
||||
-- if nil object, only write the type and return |
||||
if type(object) ~= 'boolean' and not object then |
||||
self:writeInt(TYPE_NIL) |
||||
return |
||||
end |
||||
|
||||
-- check the type we are dealing with |
||||
local typeidx = self:isWritableObject(object) |
||||
if not typeidx then |
||||
error(string.format('Unwritable object <%s>', type(object))) |
||||
end |
||||
self:writeInt(typeidx) |
||||
|
||||
if typeidx == TYPE_NUMBER then |
||||
self:writeDouble(object) |
||||
elseif typeidx == TYPE_BOOLEAN then |
||||
self:writeBool(object) |
||||
elseif typeidx == TYPE_STRING then |
||||
local stringStorage = torch.CharStorage():string(object) |
||||
self:writeInt(#stringStorage) |
||||
self:writeChar(stringStorage) |
||||
elseif typeidx == TYPE_TORCH or typeidx == TYPE_TABLE or typeidx == TYPE_RECUR_FUNCTION then |
||||
-- check it exists already (we look at the pointer!) |
||||
local objects = torch.getenv(self).writeObjects |
||||
local objectsRef = torch.getenv(self).writeObjectsRef |
||||
local index = objects[torch.pointer(object)] |
||||
|
||||
if index and (not force) then |
||||
-- if already exists, write only its index |
||||
self:writeInt(index) |
||||
else |
||||
-- else write the object itself |
||||
index = objects.nWriteObject or 0 |
||||
index = index + 1 |
||||
objects[torch.pointer(object)] = index |
||||
if not force then |
||||
objectsRef[object] = index -- we make sure the object is not going to disappear |
||||
end |
||||
self:writeInt(index) |
||||
objects.nWriteObject = index |
||||
if typeidx == TYPE_RECUR_FUNCTION then |
||||
local upvalues = {} |
||||
local counter = 0 |
||||
while true do |
||||
counter = counter + 1 |
||||
local name,value = debug.getupvalue(object, counter) |
||||
if not name then break end |
||||
if name == '_ENV' then value = nil end |
||||
table.insert(upvalues, {name=name, value=value}) |
||||
end |
||||
local dumped = string.dump(object) |
||||
local stringStorage = torch.CharStorage():string(dumped) |
||||
self:writeInt(#stringStorage) |
||||
self:writeChar(stringStorage) |
||||
self:writeObject(upvalues) |
||||
elseif typeidx == TYPE_TORCH then |
||||
local version = torch.CharStorage():string('V ' .. torch.version(object)) |
||||
local className = torch.CharStorage():string(torch.typename(object)) |
||||
self:writeInt(#version) |
||||
self:writeChar(version) |
||||
self:writeInt(#className) |
||||
self:writeChar(className) |
||||
local write = getmetamethod(object, 'write') |
||||
if write then |
||||
write(object, self) |
||||
elseif type(object) == 'table' then |
||||
local var = {} |
||||
for k,v in pairs(object) do |
||||
if self:isWritableObject(v) then |
||||
var[k] = v |
||||
else |
||||
print(string.format('$ Warning: cannot write object field <%s>', k)) |
||||
end |
||||
end |
||||
self:writeObject(var) |
||||
else |
||||
error(string.format('<%s> is a non-serializable Torch object', torch.typename(object))) |
||||
end |
||||
else -- it is a table |
||||
local size = 0; for k,v in pairs(object) do size = size + 1 end |
||||
self:writeInt(size) |
||||
for k,v in pairs(object) do |
||||
self:writeObject(k) |
||||
self:writeObject(v) |
||||
end |
||||
end |
||||
end |
||||
else |
||||
error('Unwritable object') |
||||
end |
||||
end |
||||
|
||||
function File:readObject() |
||||
-- we use an environment to keep a record of read objects |
||||
if not torch.getenv(self).writeObjects then |
||||
torch.setenv(self, {writeObjects={}, writeObjectsRef={}, readObjects={}}) |
||||
end |
||||
|
||||
local force = torch.getenv(self).force |
||||
|
||||
-- read the typeidx |
||||
local typeidx = self:readInt() |
||||
|
||||
-- is it nil? |
||||
if typeidx == TYPE_NIL then |
||||
return nil |
||||
end |
||||
|
||||
if typeidx == TYPE_NUMBER then |
||||
return self:readDouble() |
||||
elseif typeidx == TYPE_BOOLEAN then |
||||
return self:readBool() |
||||
elseif typeidx == TYPE_STRING then |
||||
local size = self:readInt() |
||||
return self:readChar(size):string() |
||||
elseif typeidx == TYPE_FUNCTION then |
||||
local size = self:readInt() |
||||
local dumped = self:readChar(size):string() |
||||
local func = loadstring(dumped) |
||||
local upvalues = self:readObject() |
||||
for index,upvalue in ipairs(upvalues) do |
||||
debug.setupvalue(func, index, upvalue) |
||||
end |
||||
return func |
||||
elseif typeidx == TYPE_TABLE or typeidx == TYPE_TORCH or typeidx == TYPE_RECUR_FUNCTION or typeidx == LEGACY_TYPE_RECUR_FUNCTION then |
||||
-- read the index |
||||
local index = self:readInt() |
||||
|
||||
-- check it is loaded already |
||||
local objects = torch.getenv(self).readObjects |
||||
if objects[index] and not force then |
||||
return objects[index] |
||||
end |
||||
|
||||
-- otherwise read it |
||||
if typeidx == TYPE_RECUR_FUNCTION or typeidx == LEGACY_TYPE_RECUR_FUNCTION then |
||||
local size = self:readInt() |
||||
local dumped = self:readChar(size):string() |
||||
local func = loadstring(dumped) |
||||
objects[index] = func |
||||
local upvalues = self:readObject() |
||||
for index,upvalue in ipairs(upvalues) do |
||||
if typeidx == LEGACY_TYPE_RECUR_FUNCTION then |
||||
debug.setupvalue(func, index, upvalue) |
||||
elseif upvalue.name == '_ENV' then |
||||
debug.setupvalue(func, index, _ENV) |
||||
else |
||||
debug.setupvalue(func, index, upvalue.value) |
||||
end |
||||
end |
||||
return func |
||||
elseif typeidx == TYPE_TORCH then |
||||
local version, className, versionNumber |
||||
version = self:readChar(self:readInt()):string() |
||||
versionNumber = tonumber(string.match(version, '^V (.*)$')) |
||||
if not versionNumber then |
||||
className = version |
||||
versionNumber = 0 -- file created before existence of versioning system |
||||
else |
||||
className = self:readChar(self:readInt()):string() |
||||
end |
||||
if not torch.factory(className) then |
||||
error(string.format('unknown Torch class <%s>', tostring(className))) |
||||
end |
||||
local object = torch.factory(className)(self) |
||||
objects[index] = object |
||||
local read = getmetamethod(object, 'read') |
||||
if read then |
||||
read(object, self, versionNumber) |
||||
elseif type(object) == 'table' then |
||||
local var = self:readObject() |
||||
for k,v in pairs(var) do |
||||
object[k] = v |
||||
end |
||||
else |
||||
error(string.format('Cannot load object class <%s>', tostring(className))) |
||||
end |
||||
return object |
||||
else -- it is a table |
||||
local size = self:readInt() |
||||
local object = {} |
||||
objects[index] = object |
||||
for i = 1,size do |
||||
local k = self:readObject() |
||||
local v = self:readObject() |
||||
object[k] = v |
||||
end |
||||
return object |
||||
end |
||||
else |
||||
error('unknown object') |
||||
end |
||||
end |
||||
|
||||
-- simple helpers to save/load arbitrary objects/tables |
||||
function torch.save(filename, object, mode) |
||||
mode = mode or 'binary' |
||||
local file = torch.DiskFile(filename, 'w') |
||||
file[mode](file) |
||||
file:writeObject(object) |
||||
file:close() |
||||
end |
||||
|
||||
function torch.load(filename, mode) |
||||
mode = mode or 'binary' |
||||
local file = torch.DiskFile(filename, 'r') |
||||
file[mode](file) |
||||
local object = file:readObject() |
||||
file:close() |
||||
return object |
||||
end |
||||
|
||||
-- simple helpers to serialize/deserialize arbitrary objects/tables |
||||
function torch.serialize(object, mode) |
||||
local storage = torch.serializeToStorage(object, mode) |
||||
return storage:string() |
||||
end |
||||
|
||||
-- Serialize to a CharStorage, not a lua string. This avoids |
||||
function torch.serializeToStorage(object, mode) |
||||
mode = mode or 'binary' |
||||
local f = torch.MemoryFile() |
||||
f = f[mode](f) |
||||
f:writeObject(object) |
||||
local storage = f:storage() |
||||
f:close() |
||||
return storage |
||||
end |
||||
|
||||
function torch.deserializeFromStorage(storage, mode) |
||||
mode = mode or 'binary' |
||||
local tx = torch.CharTensor(storage) |
||||
local xp = torch.CharStorage(tx:size(1)+1) |
||||
local txp = torch.CharTensor(xp) |
||||
txp:narrow(1,1,tx:size(1)):copy(tx) |
||||
txp[tx:size(1)+1] = 0 |
||||
local f = torch.MemoryFile(xp) |
||||
f = f[mode](f) |
||||
local object = f:readObject() |
||||
f:close() |
||||
return object |
||||
end |
||||
|
||||
function torch.deserialize(str, mode) |
||||
local storage = torch.CharStorage():string(str) |
||||
return torch.deserializeFromStorage(storage, mode) |
||||
end |
||||
|
||||
-- public API (saveobj/loadobj are safe for global import) |
||||
torch.saveobj = torch.save |
||||
torch.loadobj = torch.load |
Loading…
Reference in new issue