├── .travis.yml ├── CMakeLists.txt ├── LICENSE ├── OptionParser.lua ├── Profiler.lua ├── README.md ├── init.lua ├── xlua-1.0-0.rockspec └── xlua-1.1-0.rockspec /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | compiler: 3 | - gcc 4 | - clang 5 | cache: 6 | directories: 7 | - $HOME/OpenBlasInstall 8 | sudo: false 9 | addons: 10 | apt: 11 | packages: 12 | - cmake 13 | - gfortran 14 | - gcc-multilib 15 | - gfortran-multilib 16 | - liblapack-dev 17 | - build-essential 18 | - gcc 19 | - g++ 20 | - curl 21 | - cmake 22 | - libreadline-dev 23 | - git-core 24 | - libqt4-core 25 | - libqt4-gui 26 | - libqt4-dev 27 | - libjpeg-dev 28 | - libpng-dev 29 | - ncurses-dev 30 | - imagemagick 31 | - libzmq3-dev 32 | - gfortran 33 | - unzip 34 | - gnuplot 35 | - gnuplot-x11 36 | before_script: 37 | - export ROOT_TRAVIS_DIR=$(pwd) 38 | - export INSTALL_PREFIX=~/torch/install 39 | - ls $HOME/OpenBlasInstall/lib || (cd /tmp/ && git clone https://github.com/xianyi/OpenBLAS.git -b master && cd OpenBLAS && (make NO_AFFINITY=1 -j$(getconf _NPROCESSORS_ONLN) 2>/dev/null >/dev/null) && make PREFIX=$HOME/OpenBlasInstall install) 40 | - git clone https://github.com/torch/distro.git ~/torch --recursive 41 | - cd ~/torch && git submodule update --init --recursive 42 | - mkdir build && cd build 43 | - export CMAKE_LIBRARY_PATH=$HOME/OpenBlasInstall/include:$HOME/OpenBlasInstall/lib:$CMAKE_LIBRARY_PATH 44 | - cmake .. -DCMAKE_INSTALL_PREFIX="${INSTALL_PREFIX}" -DCMAKE_BUILD_TYPE=Release -DWITH_LUAJIT21=ON 45 | - make && make install 46 | - cd $ROOT_TRAVIS_DIR 47 | - export LD_LIBRARY_PATH=${INSTALL_PREFIX}/lib:$LD_LIBRARY_PATH 48 | script: 49 | - ${INSTALL_PREFIX}/bin/luarocks make xlua-1.1-0.rockspec 50 | - ${INSTALL_PREFIX}/bin/luajit -lxlua -e "print('xlua loaded succesfully')" 51 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 2.6 FATAL_ERROR) 2 | CMAKE_POLICY(VERSION 2.6) 3 | IF(LUAROCKS_PREFIX) 4 | MESSAGE(STATUS "Installing Torch through Luarocks") 5 | STRING(REGEX REPLACE "(.*)lib/luarocks/rocks.*" "\\1" CMAKE_INSTALL_PREFIX "${LUAROCKS_PREFIX}") 6 | MESSAGE(STATUS "Prefix inferred from Luarocks: ${CMAKE_INSTALL_PREFIX}") 7 | ENDIF() 8 | FIND_PACKAGE(Torch REQUIRED) 9 | 10 | SET(src) 11 | SET(luasrc init.lua OptionParser.lua Profiler.lua) 12 | 13 | ADD_TORCH_PACKAGE(xlua "${src}" "${luasrc}" "System") 14 | 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011-2014 Idiap Research Institute (Ronan Collobert) 2 | Copyright (c) 2011-2012 NEC Laboratories America (Koray Kavukcuoglu) 3 | Copyright (c) 2011-2013 NYU (Clement Farabet) 4 | 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | 10 | 1. Redistributions of source code must retain the above copyright 11 | notice, this list of conditions and the following disclaimer. 12 | 13 | 2. Redistributions in binary form must reproduce the above copyright 14 | notice, this list of conditions and the following disclaimer in the 15 | documentation and/or other materials provided with the distribution. 16 | 17 | 3. Neither the names of NEC Laboratories American and IDIAP Research 18 | Institute nor the names of its contributors may be used to endorse or 19 | promote products derived from this software without specific prior 20 | written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 26 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | POSSIBILITY OF SUCH DAMAGE. 33 | -------------------------------------------------------------------------------- /OptionParser.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -- Lua command line option parser. 3 | -- Interface based on Pythons optparse. 4 | -- http://docs.python.org/lib/module-optparse.html 5 | -- (c) 2008 David Manura, Licensed under the same terms as Lua (MIT license) 6 | -- 7 | -- To be used like this: 8 | -- t={usage="", version=""} 9 | -- op = xlua.OptionParser(t) 10 | -- op:option{"", action=, dest=, help=""} 11 | -- 12 | -- with : 13 | -- the option string to be used (can be anything, if one letter opt, then should be -x val, more letters: -xy=val ) 14 | -- one of 15 | -- - store: store in options as key, val 16 | -- - store_true: stores key, true 17 | -- - store_false: stores key, false 18 | -- is the key under which the option is saved 19 | -- 20 | -- options,args = op.parse_args() 21 | -- 22 | -- now options is the table of options (key, val) and args is the table with non-option arguments. 23 | -- You can use op.fail(message) for failing and op.help() for printing the usage as you like. 24 | -- 25 | -- modifed by Benoit Corda, Clement Farabet 26 | -- 27 | 28 | local OptionParser = {} 29 | 30 | function xlua.OptionParser(usage) 31 | local self = {} 32 | self.usage = usage 33 | self.option_descriptions = {} 34 | self.option_of = {} 35 | for k,v in pairs(OptionParser) do 36 | self[k] = v 37 | end 38 | self:option{"-h", "--help", action="store_true", dest="help", 39 | help="show this help message and exit"} 40 | return self 41 | end 42 | 43 | function OptionParser:fail(s) -- extension 44 | io.stderr:write(s .. '\n') 45 | self:help() 46 | os.exit(1) 47 | end 48 | 49 | function OptionParser:option(optdesc) 50 | self.option_descriptions[#self.option_descriptions+1] = optdesc 51 | for _,v in ipairs(optdesc) do 52 | self.option_of[v] = optdesc 53 | end 54 | end 55 | 56 | function OptionParser:parse(options) 57 | local options = options or {} 58 | local args = {} 59 | 60 | -- set the default 61 | for _,v in ipairs(self.option_descriptions) do 62 | if v.default ~= nil and options[v.dest]==nil then 63 | options[v.dest] = v.default 64 | end 65 | end 66 | 67 | if not arg then 68 | options.__main__ = false -- python like main 69 | self.options = options 70 | return options, args 71 | end 72 | options.__main__ = true -- python like main 73 | 74 | -- expand options (e.g. "--input=file" -> "--input", "file") 75 | local unpack = unpack or table.unpack 76 | local arg = {unpack(arg)} 77 | for i=#arg,1,-1 do local v = arg[i] 78 | local flag, val = v:match('^(%-%-%w+)=(.*)') 79 | if flag then 80 | arg[i] = flag 81 | table.insert(arg, i+1, val) 82 | end 83 | end 84 | 85 | local i = 1 86 | while i <= #arg do 87 | local v = arg[i] 88 | local optdesc = self.option_of[v] 89 | if optdesc then 90 | local default = optdesc.default 91 | local action = optdesc.action 92 | local val = default 93 | if action == 'store' or action == nil then 94 | i = i + 1 95 | val = arg[i] or default 96 | if not val then self:fail('option requires an argument ' .. v) end 97 | elseif action == 'store_true' then 98 | val = true 99 | elseif action == 'store_false' then 100 | val = false 101 | end 102 | options[optdesc.dest] = val 103 | else 104 | if v:match('^%-') then self:fail('invalid option ' .. v) end 105 | args[#args+1] = v 106 | end 107 | i = i + 1 108 | end 109 | for k,opt in pairs(self.option_of) do 110 | if opt.req and not options[opt.dest] then 111 | self:fail('option '.. k .. ' requires an argument ') 112 | end 113 | end 114 | if options.help then 115 | self:help() 116 | os.exit() 117 | end 118 | -- set the default if nil 119 | self.options = options 120 | return options, args 121 | end 122 | 123 | function OptionParser:flags(optdesc) 124 | local sflags = {} 125 | local action = optdesc and optdesc.action 126 | for _,flag in ipairs(optdesc) do 127 | local sflagend 128 | if action == nil or action == 'store' then 129 | local metavar = optdesc.metavar or optdesc.dest:upper() 130 | sflagend = #flag == 2 and ' ' .. metavar 131 | or '=' .. metavar 132 | else 133 | sflagend = '' 134 | end 135 | sflags[#sflags+1] = flag .. sflagend 136 | end 137 | return table.concat(sflags, ', ') 138 | end 139 | 140 | function OptionParser:help() 141 | if arg[-1] then 142 | io.stdout:write("Usage: " .. self.usage:gsub('%%prog', (arg[-1] .. ' ' .. arg[0])) .. "\n") 143 | elseif arg[0] then 144 | io.stdout:write("Usage: " .. self.usage:gsub('%%prog', arg[0]) .. "\n") 145 | else 146 | io.stdout:write("Usage: " .. self.usage:gsub('%%prog', 'THISPROG') .. "\n") 147 | end 148 | io.stdout:write("\n") 149 | io.stdout:write("Options:\n") 150 | pad = 0 151 | for _,optdesc in ipairs(self.option_descriptions) do 152 | pad = math.max(pad, #self:flags(optdesc)) 153 | end 154 | for _,optdesc in ipairs(self.option_descriptions) do 155 | local defstr = '' 156 | if optdesc.req then 157 | defstr = ' [REQUIRED]' 158 | elseif optdesc.default then 159 | defstr = ' [default = ' .. tostring(optdesc.default) .. ']' 160 | end 161 | io.stdout:write(" " .. self:flags(optdesc) .. 162 | string.rep(' ', pad - #self:flags(optdesc)) .. 163 | " " .. optdesc.help .. defstr .. "\n") 164 | end 165 | end 166 | 167 | function OptionParser:tostring(generatefilename, params) 168 | local str = '' 169 | if not generatefilename then 170 | str = '<'.. ((arg and arg[0]) or 'interpreted.lua'):gsub('.lua','') .. "> configuration:\n" 171 | for k,v in pairs(self.options) do 172 | str = str .. ' + ' .. k .. ' = ' .. tostring(v) .. '\n' 173 | end 174 | else 175 | local first = true 176 | for i,entry in ipairs(self.option_descriptions) do 177 | local key = entry[1] 178 | local match = true 179 | if #params > 0 then 180 | match = false 181 | for i,param in ipairs(params) do 182 | if key == param then match = true; break end 183 | end 184 | end 185 | local val = self.options[entry.dest] 186 | if val and match then 187 | if first then 188 | str = str .. key .. '=' .. tostring(val) 189 | else 190 | str = str .. ',' .. key .. '=' .. tostring(val) 191 | end 192 | first = false 193 | end 194 | end 195 | str = str:gsub('/','|'):gsub(' ','_') 196 | end 197 | return str 198 | end 199 | 200 | function OptionParser:summarize(compact) 201 | io.write(self:tostring(compact)) 202 | end 203 | -------------------------------------------------------------------------------- /Profiler.lua: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- 2 | -- Profiler: a simple class to help profiling code 3 | -------------------------------------------------------------------------------- 4 | local Profiler = {} 5 | 6 | function xlua.Profiler(mode,verbose) 7 | local self = {} 8 | self.events = {} 9 | self.list = {} 10 | self.off = (mode == 'off') or false 11 | self.verbose = verbose or false 12 | for k,v in pairs(Profiler) do 13 | self[k] = v 14 | end 15 | return self 16 | end 17 | 18 | function Profiler:start(name, fps) 19 | if self.events[name] then 20 | -- update 21 | self.events[name].cpu = os.clock() 22 | self.events[name].real = sys.clock() 23 | else 24 | -- create 25 | self.events[name] = {cpu=os.clock(), real=sys.clock(), name=name} 26 | self.list[#self.list+1] = self.events[name] 27 | end 28 | if fps and fps == 'fps' then 29 | self.events[name].fps = true 30 | end 31 | if self.verbose then io.write('<' .. name .. '>') io.flush() end 32 | end 33 | 34 | function Profiler:setColor(name, color) 35 | if self.events[name] then 36 | -- update 37 | self.events[name].color = color 38 | else 39 | error('# ERROR: There is no such profiler - '.. name..', create it first') 40 | end 41 | end 42 | 43 | 44 | function Profiler:cpu(name,divider) 45 | local delta = os.clock() - self.events[name].cpu 46 | if divider then delta = delta / divider end 47 | self.events[name].cpud = delta 48 | return delta 49 | end 50 | 51 | function Profiler:real(name,divider) 52 | local delta = sys.clock() - self.events[name].real 53 | if divider then delta = delta / divider end 54 | self.events[name].reald = delta 55 | return delta 56 | end 57 | 58 | function Profiler:lap(name,divider) 59 | local r = self:real(name,divider) 60 | local c = self:cpu(name,divider) 61 | if self.verbose then io.write('\r') self:print(name) end 62 | return r,c 63 | end 64 | 65 | function Profiler:format(name) 66 | return string.format('$ real | cpu: %f | %f <%s>', 67 | self.events[name].reald or -1, self.events[name].cpud or -1, name) 68 | end 69 | 70 | function Profiler:print(name) 71 | if not self.off then 72 | print(self:format(name)) 73 | end 74 | end 75 | 76 | function Profiler:formatAll() 77 | local str = '$ profiler report:' 78 | for i = 1,#self.list do 79 | if self.list[i].fps then 80 | str = str .. '\n' .. string.format('$ real %f | cpu %f <%s> = %f fps', 81 | self.list[i].reald or -1, 82 | self.list[i].cpud or -1, 83 | self.list[i].name, 84 | 1/self.list[i].reald) 85 | else 86 | str = str .. '\n' .. string.format('$ real %f | cpu %f <%s>', 87 | self.list[i].reald or -1, 88 | self.list[i].cpud or -1, 89 | self.list[i].name) 90 | end 91 | end 92 | return str 93 | end 94 | 95 | function Profiler:printAll() 96 | if not self.off then 97 | print(self:formatAll()) 98 | end 99 | end 100 | 101 | function Profiler:displayAll(args) 102 | -- args 103 | local x = args.x or 0 104 | local y = args.y or 0 105 | local zoom = args.zoom or 1 106 | local painter = args.painter or args.win 107 | local font = args.font or 24*zoom 108 | if not painter then error('# ERROR: Profiler.displayAll() needs a painter') end 109 | 110 | painter:setfont(qt.QFont{serif=false,italic=false,size=font}) 111 | if not self.off then 112 | for i = 1,#self.list do 113 | painter:setcolor(self.list[i].color or "black") 114 | local str 115 | if self.list[i].fps then 116 | str = string.format('$ real %f | cpu %f <%s> = %f fps', 117 | self.list[i].reald or -1, 118 | self.list[i].cpud or -1, 119 | self.list[i].name, 120 | 1/self.list[i].reald) 121 | else 122 | str = string.format('$ real %f | cpu %f <%s>', 123 | self.list[i].reald or -1, 124 | self.list[i].cpud or -1, 125 | self.list[i].name) 126 | end 127 | -- disp line: 128 | painter:moveto(x,y); y = y + font*1.5 129 | painter:show(str) 130 | end 131 | end 132 | end 133 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # A set of useful extensions to Lua 2 | 3 | [![Build Status](https://travis-ci.org/torch/xlua.svg)](https://travis-ci.org/torch/xlua) 4 | 5 | ## Dependencies: 6 | Torch7 (www.torch.ch) 7 | 8 | ## Install: 9 | ``` 10 | $ torch-rocks install xlua 11 | ``` 12 | 13 | ## Use 14 | ``` 15 | $ torch -lxlua 16 | xLua > a = 5 17 | xLua > b = 'test' 18 | xLua > xlua.who() 19 | 20 | Global Libs: 21 | {[1] = string, 22 | [2] = package, 23 | [3] = os, 24 | [4] = io, 25 | [5] = xlua, 26 | [6] = sys, 27 | [7] = math, 28 | [8] = debug, 29 | [9] = table, 30 | [10] = coroutine} 31 | 32 | Global Vars: 33 | {[a] = 5, 34 | [b] = test} 35 | 36 | xLua > xlua.clearall() -- also calls the garbage collector ! 37 | xLua > xlua.who() 38 | 39 | Global Libs: 40 | {[1] = string, 41 | [2] = package, 42 | [3] = os, 43 | [4] = io, 44 | [5] = xlua, 45 | [6] = sys, 46 | [7] = math, 47 | [8] = debug, 48 | [9] = table, 49 | [10] = coroutine} 50 | 51 | Global Vars: 52 | {} 53 | 54 | xLua > print(xlua) 55 | {[clear] = function: 0x10020cd10, 56 | [clearall] = function: 0x10020ca70, 57 | [_PACKAGE] = , 58 | [progress] = function: 0x10020cda0, 59 | [print] = function: 0x10020c9d0, 60 | [_NAME] = xlua, 61 | [who] = function: 0x10020cd50, 62 | [_M] = table: 0x10020c990, 63 | [lua_print] = function: 0x100201900} 64 | 65 | xLua > test = {a = 14, b = "test"} 66 | xLua > =test 67 | {[a] = 14, 68 | [b] = test} 69 | xLua > 70 | ``` 71 | -------------------------------------------------------------------------------- /init.lua: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------- 2 | -- 3 | -- Copyright (c) 2011 Clement Farabet 4 | -- (c) 2008 David Manura (for the OptionParser) 5 | -- 6 | -- Permission is hereby granted, free of charge, to any person obtaining 7 | -- a copy of this software and associated documentation files (the 8 | -- "Software"), to deal in the Software without restriction, including 9 | -- without limitation the rights to use, copy, modify, merge, publish, 10 | -- distribute, sublicense, and/or sell copies of the Software, and to 11 | -- permit persons to whom the Software is furnished to do so, subject to 12 | -- the following conditions: 13 | -- 14 | -- The above copyright notice and this permission notice shall be 15 | -- included in all copies or substantial portions of the Software. 16 | -- 17 | -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | -- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | -- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | -- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 21 | -- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | -- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 | -- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | -- 25 | ---------------------------------------------------------------------- 26 | -- description: 27 | -- xlua - a package that provides a better Lua prompt, and a few 28 | -- methods to deal with the namespace, argument unpacking 29 | -- and so on... 30 | -- 31 | -- history: 32 | -- July 7, 2011, 12:49AM - added OptionParser from D. Manura 33 | -- June 30, 2011, 4:54PM - creation - Clement Farabet 34 | ---------------------------------------------------------------------- 35 | 36 | local os = require 'os' 37 | local sys = require 'sys' 38 | local io = require 'io' 39 | local math = require 'math' 40 | local torch = require 'torch' 41 | 42 | xlua = {} 43 | local _protect_ = {} 44 | for k,v in pairs(_G) do 45 | table.insert(_protect_, k) 46 | end 47 | 48 | -- extra files 49 | require 'xlua.OptionParser' 50 | require 'xlua.Profiler' 51 | 52 | 53 | ---------------------------------------------------------------------- 54 | -- better print function 55 | ---------------------------------------------------------------------- 56 | function xlua.print(obj,...) 57 | if type(obj) == 'table' then 58 | local mt = getmetatable(obj) 59 | if mt and mt.__tostring__ then 60 | io.write(mt.__tostring__(obj)) 61 | else 62 | local tos = tostring(obj) 63 | local obj_w_usage = false 64 | if tos and not string.find(tos,'table: ') then 65 | if obj.usage and type(obj.usage) == 'string' then 66 | io.write(obj.usage) 67 | io.write('\n\nFIELDS:\n') 68 | obj_w_usage = true 69 | else 70 | io.write(tos .. ':\n') 71 | end 72 | end 73 | io.write('{') 74 | local tab = '' 75 | local idx = 1 76 | for k,v in pairs(obj) do 77 | if idx > 1 then io.write(',\n') end 78 | if type(v) == 'userdata' then 79 | io.write(tab .. '[' .. k .. ']' .. ' = ') 80 | else 81 | local tostr = tostring(v):gsub('\n','\\n') 82 | if #tostr>40 then 83 | local tostrshort = tostr:sub(1,40) .. sys.COLORS.none 84 | io.write(tab .. '[' .. tostring(k) .. ']' .. ' = ' .. tostrshort .. ' ... ') 85 | else 86 | io.write(tab .. '[' .. tostring(k) .. ']' .. ' = ' .. tostr) 87 | end 88 | end 89 | tab = ' ' 90 | idx = idx + 1 91 | end 92 | io.write('}') 93 | if obj_w_usage then 94 | io.write('') 95 | end 96 | end 97 | else 98 | io.write(tostring(obj)) 99 | end 100 | if select('#',...) > 0 then 101 | io.write(' ') 102 | print(...) 103 | else 104 | io.write('\n') 105 | end 106 | end 107 | rawset(_G, 'xprint', xlua.print) 108 | 109 | ---------------------------------------------------------------------- 110 | -- log all session, by replicating stdout to a file 111 | ---------------------------------------------------------------------- 112 | function xlua.log(file, append) 113 | os.execute('mkdir ' .. (sys.uname() ~= 'windows' and '-p ' or '') .. ' "' .. sys.dirname(file) .. '"') 114 | local mode = 'w' 115 | if append then mode = 'a' end 116 | local f = assert(io.open(file,mode)) 117 | io._write = io.write 118 | _G._print = _G.print 119 | _G.print = xlua.print 120 | io.write = function(...) 121 | io._write(...) 122 | local arg = {...} 123 | for i = 1,select('#',...) do 124 | f:write(arg[i]) 125 | end 126 | f:flush() 127 | end 128 | end 129 | 130 | ---------------------------------------------------------------------- 131 | -- clear all globals 132 | ---------------------------------------------------------------------- 133 | function xlua.clearall() 134 | for k,v in pairs(_G) do 135 | local protected = false 136 | local lib = false 137 | for i,p in ipairs(_protect_) do 138 | if k == p then protected = true end 139 | end 140 | for p in pairs(package.loaded) do 141 | if k == p then lib = true end 142 | end 143 | if not protected then 144 | _G[k] = nil 145 | if lib then package.loaded[k] = nil end 146 | end 147 | end 148 | collectgarbage() 149 | end 150 | 151 | ---------------------------------------------------------------------- 152 | -- clear one variable 153 | ---------------------------------------------------------------------- 154 | function xlua.clear(var) 155 | _G[var] = nil 156 | collectgarbage() 157 | end 158 | 159 | ---------------------------------------------------------------------- 160 | -- prints globals 161 | ---------------------------------------------------------------------- 162 | function xlua.who() 163 | local user = {} 164 | local libs = {} 165 | for k,v in pairs(_G) do 166 | local protected = false 167 | local lib = false 168 | for i,p in ipairs(_protect_) do 169 | if k == p then protected = true end 170 | end 171 | for p in pairs(package.loaded) do 172 | if k == p and p ~= '_G' then lib = true end 173 | end 174 | if lib then 175 | table.insert(libs, k) 176 | elseif not protected then 177 | user[k] = _G[k] 178 | end 179 | end 180 | xlua.print('') 181 | xlua.print('Global Libs:') 182 | xlua.print(libs) 183 | xlua.print('') 184 | xlua.print('Global Vars:') 185 | xlua.print(user) 186 | xlua.print('') 187 | end 188 | 189 | ---------------------------------------------------------------------- 190 | -- time 191 | ---------------------------------------------------------------------- 192 | function xlua.formatTime(seconds) 193 | -- decompose: 194 | local floor = math.floor 195 | local days = floor(seconds / 3600/24) 196 | seconds = seconds - days*3600*24 197 | local hours = floor(seconds / 3600) 198 | seconds = seconds - hours*3600 199 | local minutes = floor(seconds / 60) 200 | seconds = seconds - minutes*60 201 | local secondsf = floor(seconds) 202 | seconds = seconds - secondsf 203 | local millis = floor(seconds*1000) 204 | 205 | -- string 206 | local f = '' 207 | local i = 1 208 | if days > 0 then f = f .. days .. 'D' i=i+1 end 209 | if hours > 0 and i <= 2 then f = f .. hours .. 'h' i=i+1 end 210 | if minutes > 0 and i <= 2 then f = f .. minutes .. 'm' i=i+1 end 211 | if secondsf > 0 and i <= 2 then f = f .. secondsf .. 's' i=i+1 end 212 | if millis > 0 and i <= 2 then f = f .. millis .. 'ms' i=i+1 end 213 | if f == '' then f = '0ms' end 214 | 215 | -- return formatted time 216 | return f 217 | end 218 | local formatTime = xlua.formatTime 219 | 220 | ---------------------------------------------------------------------- 221 | -- progress bar 222 | ---------------------------------------------------------------------- 223 | do 224 | local function getTermLength() 225 | if sys.uname() == 'windows' then return 80 end 226 | local tputf = io.popen('tput cols', 'r') 227 | local w = tonumber(tputf:read('*a')) 228 | local rc = {tputf:close()} 229 | if rc[3] == 0 then return w 230 | else return 80 end 231 | end 232 | 233 | local barDone = true 234 | local previous = -1 235 | local tm = '' 236 | local timer 237 | local times 238 | local indices 239 | local termLength = math.min(getTermLength(), 120) 240 | function xlua.progress(current, goal) 241 | -- defaults: 242 | local barLength = termLength - 34 243 | local smoothing = 100 244 | local maxfps = 10 245 | 246 | -- Compute percentage 247 | local percent = math.floor(((current) * barLength) / goal) 248 | 249 | -- start new bar 250 | if (barDone and ((previous == -1) or (percent < previous))) then 251 | barDone = false 252 | previous = -1 253 | tm = '' 254 | timer = torch.Timer() 255 | times = {timer:time().real} 256 | indices = {current} 257 | else 258 | io.write('\r') 259 | end 260 | 261 | --if (percent ~= previous and not barDone) then 262 | if (not barDone) then 263 | previous = percent 264 | -- print bar 265 | io.write(' [') 266 | for i=1,barLength do 267 | if (i < percent) then io.write('=') 268 | elseif (i == percent) then io.write('>') 269 | else io.write('.') end 270 | end 271 | io.write('] ') 272 | for i=1,termLength-barLength-4 do io.write(' ') end 273 | for i=1,termLength-barLength-4 do io.write('\b') end 274 | -- time stats 275 | local elapsed = timer:time().real 276 | local step = (elapsed-times[1]) / (current-indices[1]) 277 | if current==indices[1] then step = 0 end 278 | local remaining = math.max(0,(goal - current)*step) 279 | table.insert(indices, current) 280 | table.insert(times, elapsed) 281 | if #indices > smoothing then 282 | indices = table.splice(indices) 283 | times = table.splice(times) 284 | end 285 | -- Print remaining time when running or total time when done. 286 | if (percent < barLength) then 287 | tm = ' ETA: ' .. formatTime(remaining) 288 | else 289 | tm = ' Tot: ' .. formatTime(elapsed) 290 | end 291 | tm = tm .. ' | Step: ' .. formatTime(step) 292 | io.write(tm) 293 | -- go back to center of bar, and print progress 294 | for i=1,5+#tm+barLength/2 do io.write('\b') end 295 | io.write(' ', current, '/', goal, ' ') 296 | -- reset for next bar 297 | if (percent == barLength) then 298 | barDone = true 299 | io.write('\n') 300 | end 301 | -- flush 302 | io.write('\r') 303 | io.flush() 304 | end 305 | end 306 | end 307 | 308 | -------------------------------------------------------------------------------- 309 | -- prints an error with nice formatting. If domain is provided, it is used as 310 | -- following: msg 311 | -------------------------------------------------------------------------------- 312 | function xlua.error(message, domain, usage) 313 | local c = sys.COLORS 314 | if domain then 315 | message = '<' .. domain .. '> ' .. message 316 | end 317 | local col_msg = c.Red .. tostring(message) .. c.none 318 | if usage then 319 | col_msg = col_msg .. '\n' .. usage 320 | end 321 | error(col_msg) 322 | end 323 | rawset(_G, 'xerror', xlua.error) 324 | 325 | -------------------------------------------------------------------------------- 326 | -- provides standard try/catch functions 327 | -------------------------------------------------------------------------------- 328 | function xlua.trycatch(try,catch) 329 | local ok,err = pcall(try) 330 | if not ok then catch(err) end 331 | end 332 | 333 | -------------------------------------------------------------------------------- 334 | -- returns true if package is installed, rather than crashing stupidly :-) 335 | -------------------------------------------------------------------------------- 336 | function xlua.installed(package) 337 | local found = false 338 | local p = package.path .. ';' .. package.cpath 339 | for path in p:gfind('.-;') do 340 | path = path:gsub(';',''):gsub('?',package) 341 | if sys.filep(path) then 342 | found = true 343 | p = path 344 | break 345 | end 346 | end 347 | return found,p 348 | end 349 | 350 | -------------------------------------------------------------------------------- 351 | -- try to load a package, and doesn't crash if not found ! 352 | -- optionally try to install it from luarocks, and then load it. 353 | -- 354 | -- @param package package to load 355 | -- @param luarocks if true, then try to install missing package with luarocks 356 | -- @param server specify a luarocks server 357 | -------------------------------------------------------------------------------- 358 | function xlua.require(package,luarocks,server) 359 | local loaded 360 | local load = function() loaded = require(package) end 361 | local ok,err = pcall(load) 362 | if not ok then 363 | print(err) 364 | print('warning: <' .. package .. '> could not be loaded (is it installed?)') 365 | return false 366 | end 367 | return loaded 368 | end 369 | rawset(_G, 'xrequire', xlua.require) 370 | 371 | 372 | 373 | --http://lua-users.org/wiki/TableUtils 374 | local function table_val_to_str ( v ) 375 | if "string" == type( v ) then 376 | v = string.gsub( v, "\n", "\\n" ) 377 | if string.match( string.gsub(v,"[^'\"]",""), '^"+$' ) then 378 | return "'" .. v .. "'" 379 | end 380 | return '"' .. string.gsub(v,'"', '\\"' ) .. '"' 381 | else 382 | return "table" == type( v ) and xlua.table2string( v ) or tostring( v ) 383 | end 384 | end 385 | 386 | local function table_key_to_str ( k ) 387 | if "string" == type( k ) and string.match( k, "^[_%a][_%a%d]*$" ) then 388 | return k 389 | else 390 | return "[" .. table_val_to_str( k ) .. "]" 391 | end 392 | end 393 | 394 | function xlua.table2string(tbl, newline) 395 | local result, done = {}, {} 396 | for k, v in ipairs( tbl ) do 397 | table.insert( result, table_val_to_str( v ) ) 398 | done[ k ] = true 399 | end 400 | local s = "=" 401 | if newline then 402 | s = " : " 403 | end 404 | for k, v in pairs( tbl ) do 405 | if not done[ k ] then 406 | local line = table_key_to_str( k ) .. s .. table_val_to_str( v ) 407 | table.insert(result, line) 408 | end 409 | end 410 | local res 411 | if newline then 412 | res = "{\n " .. table.concat( result, "\n " ) .. "\n}" 413 | else 414 | res = "{" .. table.concat( result, "," ) .. "}" 415 | end 416 | return res 417 | end 418 | 419 | 420 | -------------------------------------------------------------------------------- 421 | -- standard usage function: used to display automated help for functions 422 | -- 423 | -- @param funcname function name 424 | -- @param description description of the function 425 | -- @param example usage example 426 | -- @param ... [optional] arguments 427 | -------------------------------------------------------------------------------- 428 | function xlua.usage(funcname, description, example, ...) 429 | local c = sys.COLORS 430 | 431 | local style = { 432 | banner = '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++', 433 | list = c.blue .. '> ' .. c.none, 434 | title = c.Magenta, 435 | pre = c.cyan, 436 | em = c.Black, 437 | img = c.red, 438 | link = c.red, 439 | code = c.green, 440 | none = c.none 441 | } 442 | 443 | local str = style.banner .. '\n' 444 | 445 | str = str .. style.title .. funcname .. style.none .. '\n' 446 | if description then 447 | str = str .. '\n' .. description .. '\n' 448 | end 449 | 450 | str = str .. '\n' .. style.list .. 'usage:\n' .. style.pre 451 | 452 | -- named arguments: 453 | local args = {...} 454 | if args[1].tabled then 455 | args = args[1].tabled 456 | end 457 | if args[1].arg then 458 | str = str .. funcname .. '{\n' 459 | for i,param in ipairs(args) do 460 | local key 461 | if param.req then 462 | key = ' ' .. param.arg .. ' = ' .. param.type 463 | else 464 | key = ' [' .. param.arg .. ' = ' .. param.type .. ']' 465 | end 466 | -- align: 467 | while key:len() < 40 do 468 | key = key .. ' ' 469 | end 470 | str = str .. key .. '-- ' .. param.help 471 | if type(param.default) == 'table' then 472 | str = str .. ' [default = ' .. xlua.table2string(param.default) .. ']' 473 | elseif param.default or param.default == false then 474 | str = str .. ' [default = ' .. tostring(param.default) .. ']' 475 | elseif param.defaulta then 476 | str = str .. ' [default == ' .. param.defaulta .. ']' 477 | end 478 | str = str.. '\n' 479 | end 480 | str = str .. '}\n' 481 | 482 | -- unnamed args: 483 | else 484 | local idx = 1 485 | while true do 486 | local param 487 | str = str .. funcname .. '(\n' 488 | while true do 489 | param = args[idx] 490 | idx = idx + 1 491 | if not param or param == '' then break end 492 | local key 493 | if param.req then 494 | key = ' ' .. param.type 495 | else 496 | key = ' [' .. param.type .. ']' 497 | end 498 | -- align: 499 | while key:len() < 40 do 500 | key = key .. ' ' 501 | end 502 | str = str .. key .. '-- ' .. param.help .. '\n' 503 | end 504 | str = str .. ')\n' 505 | if not param then break end 506 | end 507 | end 508 | str = str .. style.none 509 | 510 | if example then 511 | str = str .. '\n' .. style.pre .. example .. style.none .. '\n' 512 | end 513 | 514 | str = str .. style.banner 515 | return str 516 | end 517 | 518 | -------------------------------------------------------------------------------- 519 | -- standard argument function: used to handle named arguments, and 520 | -- display automated help for functions 521 | -------------------------------------------------------------------------------- 522 | function xlua.unpack(args, funcname, description, ...) 523 | -- put args in table 524 | local defs = {...} 525 | 526 | -- generate usage string as a closure: 527 | -- this way the function only gets called when an error occurs 528 | local fusage = function() 529 | local example 530 | if #defs > 1 then 531 | example = funcname .. '{' .. defs[2].arg .. '=' .. defs[2].type .. ', ' 532 | .. defs[1].arg .. '=' .. defs[1].type .. '}\n' 533 | example = example .. funcname .. '(' .. defs[1].type .. ',' .. ' ...)' 534 | end 535 | return xlua.usage(funcname, description, example, {tabled=defs}) 536 | end 537 | local usage = {} 538 | setmetatable(usage, {__tostring=fusage}) 539 | 540 | -- get args 541 | local iargs = {} 542 | if #args == 0 then 543 | print(usage) 544 | xlua.error('error') 545 | elseif #args == 1 and type(args[1]) == 'table' and #args[1] == 0 546 | and not (torch and torch.typename(args[1]) ~= nil) then 547 | -- named args 548 | iargs = args[1] 549 | else 550 | -- ordered args 551 | for i = 1,select('#',...) do 552 | iargs[defs[i].arg] = args[i] 553 | end 554 | end 555 | 556 | -- check/set arguments 557 | local dargs = {} 558 | for i = 1,#defs do 559 | local def = defs[i] 560 | -- is value requested ? 561 | if def.req and iargs[def.arg] == nil then 562 | local c = sys.COLORS 563 | print(c.Red .. 'missing argument: ' .. def.arg .. c.none) 564 | print(usage) 565 | xlua.error('error') 566 | end 567 | -- get value or default 568 | dargs[def.arg] = iargs[def.arg] 569 | if dargs[def.arg] == nil then 570 | dargs[def.arg] = def.default 571 | end 572 | if dargs[def.arg] == nil and def.defaulta then 573 | dargs[def.arg] = dargs[def.defaulta] 574 | end 575 | dargs[i] = dargs[def.arg] 576 | end 577 | 578 | -- return usage too 579 | dargs.usage = usage 580 | 581 | -- stupid lua bug: we return all args by hand 582 | if dargs[65] then 583 | xlua.error(' oups, cant deal with more than 64 arguments :-)') 584 | end 585 | 586 | -- return modified args 587 | return dargs, 588 | dargs[1], dargs[2], dargs[3], dargs[4], dargs[5], dargs[6], dargs[7], dargs[8], 589 | dargs[9], dargs[10], dargs[11], dargs[12], dargs[13], dargs[14], dargs[15], dargs[16], 590 | dargs[17], dargs[18], dargs[19], dargs[20], dargs[21], dargs[22], dargs[23], dargs[24], 591 | dargs[25], dargs[26], dargs[27], dargs[28], dargs[29], dargs[30], dargs[31], dargs[32], 592 | dargs[33], dargs[34], dargs[35], dargs[36], dargs[37], dargs[38], dargs[39], dargs[40], 593 | dargs[41], dargs[42], dargs[43], dargs[44], dargs[45], dargs[46], dargs[47], dargs[48], 594 | dargs[49], dargs[50], dargs[51], dargs[52], dargs[53], dargs[54], dargs[55], dargs[56], 595 | dargs[57], dargs[58], dargs[59], dargs[60], dargs[61], dargs[62], dargs[63], dargs[64] 596 | end 597 | 598 | -------------------------------------------------------------------------------- 599 | -- standard argument function for classes: used to handle named arguments, and 600 | -- display automated help for functions 601 | -- auto inits the self with usage 602 | -------------------------------------------------------------------------------- 603 | function xlua.unpack_class(object, args, funcname, description, ...) 604 | local dargs = xlua.unpack(args, funcname, description, ...) 605 | for k,v in pairs(dargs) do 606 | if type(k) ~= 'number' then 607 | object[k] = v 608 | end 609 | end 610 | end 611 | 612 | -------------------------------------------------------------------------------- 613 | -- module help function 614 | -- 615 | -- @param module module 616 | -- @param name module name 617 | -- @param description description of the module 618 | -------------------------------------------------------------------------------- 619 | function xlua.usage_module(module, name, description) 620 | local c = sys.COLORS 621 | local hasglobals = false 622 | local str = c.magenta 623 | local str = str .. '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n' 624 | str = str .. 'PACKAGE:\n' .. name .. '\n' 625 | if description then 626 | str = str .. '\nDESC:\n' .. description .. '\n' 627 | end 628 | str = str .. '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++' 629 | str = str .. c.none 630 | -- register help 631 | local mt = getmetatable(module) or {} 632 | setmetatable(module,mt) 633 | mt.__tostring = function() return str end 634 | return str 635 | end 636 | 637 | -------------------------------------------------------------------------------- 638 | -- splicing: remove elements from a table 639 | -------------------------------------------------------------------------------- 640 | function table.splice(tbl, start, length) 641 | length = length or 1 642 | start = start or 1 643 | local endd = start + length 644 | local spliced = {} 645 | local remainder = {} 646 | for i,elt in ipairs(tbl) do 647 | if i < start or i >= endd then 648 | table.insert(spliced, elt) 649 | else 650 | table.insert(remainder, elt) 651 | end 652 | end 653 | return spliced, remainder 654 | end 655 | 656 | -------------------------------------------------------------------------------- 657 | -- prune: remove duplicates from a table 658 | -- if a hash function is provided, it is used to produce a unique hash for each 659 | -- element in the input table. 660 | -- if a merge function is provided, it defines how duplicate entries are merged, 661 | -- otherwise, a random entry is picked. 662 | -------------------------------------------------------------------------------- 663 | function table.prune(tbl, hashfunc, merge) 664 | local hashes = {} 665 | local hash = hashfunc or function(a) return a end 666 | if merge then 667 | for i,v in ipairs(tbl) do 668 | if not hashes[hash(v)] then 669 | hashes[hash(v)] = v 670 | else 671 | hashes[hash(v)] = merge(v, hashes[hash(v)]) 672 | end 673 | end 674 | else 675 | for i,v in ipairs(tbl) do 676 | hashes[hash(v)] = v 677 | end 678 | end 679 | local ntbl = {} 680 | for _,v in pairs(hashes) do 681 | table.insert(ntbl, v) 682 | end 683 | return ntbl 684 | end 685 | 686 | -------------------------------------------------------------------------------- 687 | -- split a string using a pattern 688 | -------------------------------------------------------------------------------- 689 | function string.split(str, pat) 690 | local t = {} -- NOTE: use {n = 0} in Lua-5.0 691 | local fpat = "(.-)" .. pat 692 | local last_end = 1 693 | local s, e, cap = str:find(fpat, 1) 694 | while s do 695 | if s ~= 1 or cap ~= "" then 696 | table.insert(t,cap) 697 | end 698 | last_end = e+1 699 | s, e, cap = str:find(fpat, last_end) 700 | end 701 | if last_end <= #str then 702 | cap = str:sub(last_end) 703 | table.insert(t, cap) 704 | end 705 | return t 706 | end 707 | 708 | -------------------------------------------------------------------------------- 709 | -- eval: just a shortcut to parse strings into symbols 710 | -- example: 711 | -- assert( string.tosymbol('madgraph.Image.File') == madgraph.Image.File ) 712 | -------------------------------------------------------------------------------- 713 | function string.tosymbol(str) 714 | local ok,result = pcall(loadstring('return ' .. str)) 715 | if not ok then 716 | error(result) 717 | elseif not result then 718 | error('symbol "' .. str .. '" does not exist') 719 | else 720 | return result 721 | end 722 | end 723 | 724 | 725 | -------------------------------------------------------------------------------- 726 | -- parses arguments passed as ENV variables 727 | -- example: 728 | -- learningRate=1e-3 nesterov=false th train.lua 729 | -- opt = xlua.envparams{learningRate=1e-2, nesterov=true} 730 | -------------------------------------------------------------------------------- 731 | function xlua.envparams(default) 732 | local params = {} 733 | for k, v in pairs(default) do 734 | params[k] = v 735 | if os.getenv(k) ~= nil then 736 | local v_new = os.getenv(k) 737 | if type(v) == "number" then 738 | v_new = tonumber(v_new) 739 | end 740 | if type(v) == "boolean" then 741 | if v_new == "false" or v_new == "False" then 742 | v_new = false 743 | elseif v_new == "true" or v_new == "True" then 744 | v_new = true 745 | end 746 | end 747 | assert(v_new ~= nil) 748 | params[k] = v_new 749 | end 750 | end 751 | return params 752 | end 753 | 754 | return xlua 755 | -------------------------------------------------------------------------------- /xlua-1.0-0.rockspec: -------------------------------------------------------------------------------- 1 | package = "xlua" 2 | version = "1.0-0" 3 | 4 | source = { 5 | url = "git://github.com/torch/xlua", 6 | dir = 'xlua', 7 | tag = '1.0-0' 8 | } 9 | 10 | description = { 11 | summary = "Extra Lua functions.", 12 | detailed = [[ 13 | Lua is pretty compact in terms of built-in functionalities: 14 | this package extends the table and string libraries, 15 | and provide other general purpose tools (progress bar, ...). 16 | ]], 17 | homepage = "https://github.com/torch/xlua", 18 | license = "BSD" 19 | } 20 | 21 | dependencies = { 22 | "torch >= 7.0", 23 | "sys >= 1.0" 24 | } 25 | 26 | build = { 27 | type = "builtin", 28 | modules = { 29 | ['xlua.init'] = 'init.lua', 30 | ['xlua.OptionParser'] = 'OptionParser.lua', 31 | ['xlua.Profiler'] = 'Profiler.lua' 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /xlua-1.1-0.rockspec: -------------------------------------------------------------------------------- 1 | package = "xlua" 2 | version = "1.1-0" 3 | 4 | source = { 5 | url = "git://github.com/torch/xlua", 6 | } 7 | 8 | description = { 9 | summary = "Extra Lua functions.", 10 | detailed = [[ 11 | Lua is pretty compact in terms of built-in functionalities: 12 | this package extends the table and string libraries, 13 | and provide other general purpose tools (progress bar, ...). 14 | ]], 15 | homepage = "https://github.com/torch/xlua", 16 | license = "BSD" 17 | } 18 | 19 | dependencies = { 20 | "torch >= 7.0", 21 | "sys >= 1.0" 22 | } 23 | 24 | build = { 25 | type = "builtin", 26 | modules = { 27 | ['xlua.init'] = 'init.lua', 28 | ['xlua.OptionParser'] = 'OptionParser.lua', 29 | ['xlua.Profiler'] = 'Profiler.lua' 30 | } 31 | } 32 | --------------------------------------------------------------------------------