diff --git a/THNN.lua b/THNN.lua index 757c424ce..2e745c85c 100644 --- a/THNN.lua +++ b/THNN.lua @@ -1,719 +1,50 @@ +------------------------------------------------ +-- Preamble +------------------------------------------------ +--[[ +* API management file for Torch7 'nn' package. +--]] + +---------------- External Dependencies local ffi = require 'ffi' +require('torchAPI') -local THNN = {} +------------------------------------------------ +-- THNN +------------------------------------------------ +---- Load header file +local header = paths.dofile('THNN_h.lua') -local generic_THNN_h = [[ -TH_API void THNN_(Abs_updateOutput)( - THNNState *state, - THTensor *input, - THTensor *output); -TH_API void THNN_(Abs_updateGradInput)( - THNNState *state, - THTensor *input, - THTensor *gradOutput, - THTensor *gradInput); - -TH_API void THNN_(AbsCriterion_updateOutput)( - THNNState *state, - THTensor *input, - THTensor *target, - THTensor *output, - bool sizeAverage); -TH_API void THNN_(AbsCriterion_updateGradInput)( - THNNState *state, - THTensor *input, - THTensor *target, - THTensor *gradInput, - bool sizeAverage); - -TH_API void THNN_(ClassNLLCriterion_updateOutput)( - THNNState *state, - THTensor *input, - THIndexTensor *target, - THTensor *output, - bool sizeAverage, - THTensor *weights, - THTensor *total_weight); -TH_API void THNN_(ClassNLLCriterion_updateGradInput)( - THNNState *state, - THTensor *input, - THIndexTensor *target, - THTensor *gradInput, - bool sizeAverage, - THTensor *weights, - THTensor *total_weight); - -TH_API void THNN_(ELU_updateOutput)( - THNNState *state, - THTensor *input, - THTensor *output, - real alpha); -TH_API void THNN_(ELU_updateGradInput)( - THNNState *state, - THTensor *input, - THTensor *gradOutput, - THTensor *gradInput, - THTensor *output, - real alpha); - -TH_API void THNN_(DistKLDivCriterion_updateOutput)( - THNNState *state, - THTensor *input, - THTensor *target, - THTensor *output, - bool sizeAverage); -TH_API void THNN_(DistKLDivCriterion_updateGradInput)( - THNNState *state, - THTensor *input, - THTensor *target, - THTensor *gradInput, - bool sizeAverage); - -TH_API void THNN_(HardShrink_updateOutput)( - THNNState *state, - THTensor *input, - THTensor *output, - real lambda); -TH_API void THNN_(HardShrink_updateGradInput)( - THNNState *state, - THTensor *input, - THTensor *gradOutput, - THTensor *gradInput, - real lambda); - -TH_API void THNN_(HardTanh_updateOutput)( - THNNState *state, - THTensor *input, - THTensor *output, - real min_val, - real max_val); -TH_API void THNN_(HardTanh_updateGradInput)( - THNNState *state, - THTensor *input, - THTensor *gradOutput, - THTensor *gradInput, - real min_val, - real max_val); - -TH_API void THNN_(L1Cost_updateOutput)( - THNNState *state, - THTensor *input, - THTensor *output); -TH_API void THNN_(L1Cost_updateGradInput)( - THNNState *state, - THTensor *input, - THTensor *gradOutput, - THTensor *gradInput); - -TH_API void THNN_(LeakyReLU_updateOutput)( - THNNState *state, - THTensor *input, - THTensor *output, - real negval, - bool inplace); -TH_API void THNN_(LeakyReLU_updateGradInput)( - THNNState *state, - THTensor *input, - THTensor *gradOutput, - THTensor *gradInput, - real negval, - bool inplace); - -TH_API void THNN_(LogSigmoid_updateOutput)( - THNNState *state, - THTensor *input, - THTensor *output, - THTensor *buffer); -TH_API void THNN_(LogSigmoid_updateGradInput)( - THNNState *state, - THTensor *input, - THTensor *gradOutput, - THTensor *gradInput, - THTensor *buffer); - -TH_API void THNN_(LogSoftMax_updateOutput)( - THNNState *state, - THTensor *input, - THTensor *output); -TH_API void THNN_(LogSoftMax_updateGradInput)( - THNNState *state, - THTensor *input, - THTensor *gradOutput, - THTensor *gradInput, - THTensor *output); - -TH_API void THNN_(LookupTable_accGradParameters)( - THNNState *state, - THIndexTensor *input, - THTensor *gradOutput, - THTensor *gradWeight, - THIntegerTensor *count, - THTensor *sorted, - THTensor *indices, - bool scaleGradByFreq, - real scale); - -TH_API void THNN_(MarginCriterion_updateOutput)( - THNNState *state, - THTensor *input, - THTensor *target, - THTensor *output, - bool sizeAverage, - real margin); -TH_API void THNN_(MarginCriterion_updateGradInput)( - THNNState *state, - THTensor *input, - THTensor *target, - THTensor *gradInput, - bool sizeAverage, - real margin); - -TH_API void THNN_(MSECriterion_updateOutput)( - THNNState *state, - THTensor *input, - THTensor *target, - THTensor *output, - bool sizeAverage); -TH_API void THNN_(MSECriterion_updateGradInput)( - THNNState *state, - THTensor *input, - THTensor *target, - THTensor *gradInput, - bool sizeAverage); - -TH_API void THNN_(MultiLabelMarginCriterion_updateOutput)( - THNNState *state, - THTensor *input, - THTensor *target, - THTensor *output, - bool sizeAverage); -TH_API void THNN_(MultiLabelMarginCriterion_updateGradInput)( - THNNState *state, - THTensor *input, - THTensor *target, - THTensor *gradInput, - bool sizeAverage); - -TH_API void THNN_(MultiMarginCriterion_updateOutput)( - THNNState *state, - THTensor *input, - THTensor *target, - THTensor *output, - bool sizeAverage, - int p); -TH_API void THNN_(MultiMarginCriterion_updateGradInput)( - THNNState *state, - THTensor *input, - THTensor *target, - THTensor *gradInput, - bool sizeAverage, - int p); - -TH_API void THNN_(PReLU_updateOutput)( - THNNState *state, - THTensor *input, - THTensor *output, - THTensor *weight, - THIndex_t nOutputPlane); -TH_API void THNN_(PReLU_updateGradInput)( - THNNState *state, - THTensor *input, - THTensor *gradOutput, - THTensor *gradInput, - THTensor *weight, - THIndex_t nOutputPlane); -TH_API void THNN_(PReLU_accGradParameters)( - THNNState *state, - THTensor *input, - THTensor *gradOutput, - THTensor *gradInput, - THTensor *weight, - THTensor *gradWeight, - THTensor *gradWeightBuf, - THTensor *gradWeightBuf2, - THIndex_t nOutputPlane, - real scale); - -TH_API void THNN_(RReLU_updateOutput)( - THNNState *state, - THTensor *input, - THTensor *output, - THTensor *noise, - real lower, - real upper, - bool train, - bool inplace, - THGenerator *generator); -TH_API void THNN_(RReLU_updateGradInput)( - THNNState *state, - THTensor *input, - THTensor *gradOutput, - THTensor *gradInput, - THTensor *noise, - real lower, - real upper, - bool train, - bool inplace); - -TH_API void THNN_(Sigmoid_updateOutput)( - THNNState *state, - THTensor *input, - THTensor *output); -TH_API void THNN_(Sigmoid_updateGradInput)( - THNNState *state, - THTensor *input, - THTensor *gradOutput, - THTensor *gradInput, - THTensor *output); - -TH_API void THNN_(SmoothL1Criterion_updateOutput)( - THNNState *state, - THTensor *input, - THTensor *target, - THTensor *output, - bool sizeAverage); -TH_API void THNN_(SmoothL1Criterion_updateGradInput)( - THNNState *state, - THTensor *input, - THTensor *target, - THTensor *gradInput, - bool sizeAverage); - -TH_API void THNN_(SoftMax_updateOutput)( - THNNState *state, - THTensor *input, - THTensor *output); -TH_API void THNN_(SoftMax_updateGradInput)( - THNNState *state, - THTensor *input, - THTensor *gradOutput, - THTensor *gradInput, - THTensor *output); - -TH_API void THNN_(SoftPlus_updateOutput)( - THNNState *state, - THTensor *input, - THTensor *output, - real beta, - real threshold); -TH_API void THNN_(SoftPlus_updateGradInput)( - THNNState *state, - THTensor *input, - THTensor *gradOutput, - THTensor *gradInput, - THTensor *output, - real beta, - real threshold); - -TH_API void THNN_(SoftShrink_updateOutput)( - THNNState *state, - THTensor *input, - THTensor *output, - real lambda); -TH_API void THNN_(SoftShrink_updateGradInput)( - THNNState *state, - THTensor *input, - THTensor *gradOutput, - THTensor *gradInput, - real lambda); - -TH_API void THNN_(Sqrt_updateOutput)( - THNNState *state, - THTensor *input, - THTensor *output, - real eps); -TH_API void THNN_(Sqrt_updateGradInput)( - THNNState *state, - THTensor *input, - THTensor *gradOutput, - THTensor *gradInput, - THTensor *output); - -TH_API void THNN_(Square_updateOutput)( - THNNState *state, - THTensor *input, - THTensor *output); -TH_API void THNN_(Square_updateGradInput)( - THNNState *state, - THTensor *input, - THTensor *gradOutput, - THTensor *gradInput); - -TH_API void THNN_(Tanh_updateOutput)( - THNNState *state, - THTensor *input, - THTensor *output); -TH_API void THNN_(Tanh_updateGradInput)( - THNNState *state, - THTensor *input, - THTensor *gradOutput, - THTensor *gradInput, - THTensor *output); - -TH_API void THNN_(Threshold_updateOutput)( - THNNState *state, - THTensor *input, - THTensor *output, - real threshold, - real val, - bool inplace); -TH_API void THNN_(Threshold_updateGradInput)( - THNNState *state, - THTensor *input, - THTensor *gradOutput, - THTensor *gradInput, - real threshold, - bool inplace); - -TH_API void THNN_(SpatialConvolutionMM_updateOutput)( - THNNState *state, - THTensor *input, - THTensor *output, - THTensor *weight, - THTensor *bias, - THTensor *finput, - THTensor *fgradInput, - int kW, int kH, - int dW, int dH, - int padW, int padH); -TH_API void THNN_(SpatialConvolutionMM_updateGradInput)( - THNNState *state, - THTensor *input, - THTensor *gradOutput, - THTensor *gradInput, - THTensor *weight, - THTensor *bias, - THTensor *finput, - THTensor *fgradInput, - int kW, int kH, - int dW, int dH, - int padW, int padH); -TH_API void THNN_(SpatialConvolutionMM_accGradParameters)( - THNNState *state, - THTensor *input, - THTensor *gradOutput, - THTensor *gradWeight, - THTensor *gradBias, - THTensor *finput, - THTensor *fgradInput, - int kW, int kH, - int dW, int dH, - int padW, int padH, - real scale); - -TH_API void THNN_(SpatialAdaptiveMaxPooling_updateOutput)( - THNNState *state, - THTensor *input, - THTensor *output, - THTensor *indices, - int owidth, int oheight); -TH_API void THNN_(SpatialAdaptiveMaxPooling_updateGradInput)( - THNNState *state, - THTensor *input, - THTensor *gradOutput, - THTensor *gradInput, - THTensor *indices); - -TH_API void THNN_(SpatialAveragePooling_updateOutput)( - THNNState *state, - THTensor *input, - THTensor *output, - int kW, int kH, - int dW, int dH, - int padW, int padH, - bool ceil_mode, - bool count_include_pad); -TH_API void THNN_(SpatialAveragePooling_updateGradInput)( - THNNState *state, - THTensor *input, - THTensor *gradOutput, - THTensor *gradInput, - int kW, int kH, - int dW, int dH, - int padW, int padH, - bool ceil_mode, - bool count_include_pad); - -TH_API void THNN_(SpatialMaxPooling_updateOutput)( - THNNState *state, - THTensor *input, - THTensor *output, - THTensor *indices, - int kW, int kH, - int dW, int dH, - int padW, int padH, - bool ceil_mode); -TH_API void THNN_(SpatialMaxPooling_updateGradInput)( - THNNState *state, - THTensor *input, - THTensor *gradOutput, - THTensor *gradInput, - THTensor *indices, - int kW, int kH, - int dW, int dH, - int padW, int padH, - bool ceil_mode); - -TH_API void THNN_(VolumetricAveragePooling_updateOutput)( - THNNState *state, - THTensor *input, - THTensor *output, - int kT, int kW, int kH, - int dT, int dW, int dH); -TH_API void THNN_(VolumetricAveragePooling_updateGradInput)( - THNNState *state, - THTensor *input, - THTensor *gradOutput, - THTensor *gradInput, - int kT, int kW, int kH, - int dT, int dW, int dH); - -TH_API void THNN_(VolumetricConvolution_updateOutput)( - THNNState *state, - THTensor *input, - THTensor *output, - THTensor *weight, - THTensor *bias, - THTensor *finput, - THTensor *fgradInput, - int dT, int dW, int dH, - int pT, int pW, int pH); -TH_API void THNN_(VolumetricConvolution_updateGradInput)( - THNNState *state, - THTensor *input, - THTensor *gradOutput, - THTensor *gradInput, - THTensor *weight, - THTensor *finput, - int dT, int dW, int dH, - int pT, int pW, int pH); -TH_API void THNN_(VolumetricConvolution_accGradParameters)( - THNNState *state, - THTensor *input, - THTensor *gradOutput, - THTensor *gradWeight, - THTensor *gradBias, - THTensor *finput, - THTensor *fgradInput, - int dT, int dW, int dH, - int pT, int pW, int pH, - real scale); - -TH_API void THNN_(VolumetricConvolutionMM_updateOutput)( - THNNState *state, - THTensor *input, - THTensor *output, - THTensor *weight, - THTensor *bias, - THTensor *finput, - int kT, int kW, int kH, - int dT, int dW, int dH, - int pT, int pW, int pH); -TH_API void THNN_(VolumetricConvolutionMM_updateGradInput)( - THNNState *state, - THTensor *input, - THTensor *gradOutput, - THTensor *gradInput, - THTensor *weight, - THTensor *finput, - THTensor *fgradInput, - int kT, int kW, int kH, - int dT, int dW, int dH, - int pT, int pW, int pH); -TH_API void THNN_(VolumetricConvolutionMM_accGradParameters)( - THNNState *state, - THTensor *input, - THTensor *gradOutput, - THTensor *gradWeight, - THTensor *gradBias, - THTensor *finput, - real scale); - -TH_API void THNN_(VolumetricFullConvolution_updateOutput)( - THNNState *state, - THTensor *input, - THTensor *output, - THTensor *weight, - THTensor *bias, - THTensor *finput, - THTensor *fgradInput, - int dT, int dW, int dH, - int pT, int pW, int pH); -TH_API void THNN_(VolumetricFullConvolution_updateGradInput)( - THNNState *state, - THTensor *input, - THTensor *gradOutput, - THTensor *gradInput, - THTensor *weight, - THTensor *finput, - THTensor *fgradInput, - int dT, int dW, int dH, - int pT, int pW, int pH); -TH_API void THNN_(VolumetricFullConvolution_accGradParameters)( - THNNState *state, - THTensor *input, - THTensor *gradOutput, - THTensor *gradWeight, - THTensor *gradBias, - THTensor *finput, - THTensor *fgradInput, - int dT, int dW, int dH, - int pT, int pW, int pH, - real scale); - -TH_API void THNN_(VolumetricMaxPooling_updateOutput)( - THNNState *state, - THTensor *input, - THTensor *output, - THTensor *indices, - int kT, int kW, int kH, - int dT, int dW, int dH, - int pT, int pW, int pH, - bool ceilMode); -TH_API void THNN_(VolumetricMaxPooling_updateGradInput)( - THNNState *state, - THTensor *input, - THTensor *gradOutput, - THTensor *gradInput, - THTensor *indices, - int dT, int dW, int dH, - int pT, int pW, int pH); - -TH_API void THNN_(VolumetricMaxUnpooling_updateOutput)( - THNNState *state, - THTensor *input, - THTensor *output, - THTensor *indices, - int oT, int oW, int oH, - int dT, int dW, int dH, - int pT, int pW, int pH); -TH_API void THNN_(VolumetricMaxUnpooling_updateGradInput)( - THNNState *state, - THTensor *input, - THTensor *gradOutput, - THTensor *gradInput, - THTensor *indices, - int oT, int oW, int oH, - int dT, int dW, int dH, - int pT, int pW, int pH); - -]] - --- THGenerator struct declaration copied from torch7/lib/TH/THRandom.h -local base_declarations = [[ -typedef void THNNState; - -typedef struct { - unsigned long the_initial_seed; - int left; - int seeded; - unsigned long next; - unsigned long state[624]; /* the array for the state vector 624 = _MERSENNE_STATE_N */ - double normal_x; - double normal_y; - double normal_rho; - int normal_is_valid; -} THGenerator; -]] - --- polyfill for LUA 5.1 -if not package.searchpath then - local sep = package.config:sub(1,1) - function package.searchpath(mod, path) - mod = mod:gsub('%.', sep) - for m in path:gmatch('[^;]+') do - local nm = m:gsub('?', mod) - local f = io.open(nm, 'r') - if f then - f:close() - return nm - end - end - end -end - --- load libTHNN -THNN.C = ffi.load(package.searchpath('libTHNN', package.cpath)) - -ffi.cdef(base_declarations) - --- expand macros, allow to use original lines from lib/THNN/generic/THNN.h -local preprocessed = string.gsub(generic_THNN_h, 'TH_API void THNN_%(([%a%d_]+)%)', 'void THNN_TYPE%1') - -local replacements = +---- Initialize API for THNN +local config = { - { - ['TYPE'] = 'Double', - ['real'] = 'double', - ['THTensor'] = 'THDoubleTensor', - ['THIndexTensor'] = 'THLongTensor', - ['THIntegerTensor'] = 'THIntTensor', - ['THIndex_t'] = 'long', - ['THInteger_t'] = 'int' - }, - { - ['TYPE'] = 'Float', - ['real'] = 'float', - ['THTensor'] = 'THFloatTensor', - ['THIndexTensor'] = 'THLongTensor', - ['THIntegerTensor'] = 'THIntTensor', - ['THIndex_t'] = 'long', - ['THInteger_t'] = 'int' - } + library = 'THNN', tag = 'TH_API', + pattern = '%(([%a%d_]+)%)', rtype = 'void', } +local THNN = torchAPI(config, header) -for i=1,#replacements do - local r = replacements[i] - local s = preprocessed - for k,v in pairs(r) do - s = string.gsub(s, k, v) - end - ffi.cdef(s) -end +---- Bind C-functions to Lua library +local cstuct = 'libTHNN' +THNN.kernels = {} +THNN.kernels['torch.FloatTensor'] = THNN:bind(cstuct, header['forward'], 'Float') +THNN.kernels['torch.DoubleTensor'] = THNN:bind(cstuct, header['forward'], 'Double') + +---- Make duplicate assignment (makes dynamic dispatching easy) +torch.getmetatable('torch.FloatTensor').THNN = THNN.kernels['torch.FloatTensor'] +torch.getmetatable('torch.DoubleTensor').THNN = THNN.kernels['torch.DoubleTensor'] +---- Additional methods THNN.NULL = ffi.NULL or nil + function THNN.getState() - return ffi.NULL or nil + return ffi.NULL or nil end function THNN.optionalTensor(t) return t and t:cdata() or THNN.NULL end -local function extract_function_names(s) - local t = {} - for n in string.gmatch(s, 'TH_API void THNN_%(([%a%d_]+)%)') do - t[#t+1] = n - end - return t -end - -function THNN.bind(lib, base_names, type_name, state_getter) - local ftable = {} - local prefix = 'THNN_' .. type_name - for i,n in ipairs(base_names) do - -- use pcall since some libs might not support all functions (e.g. cunn) - local ok,v = pcall(function() return lib[prefix .. n] end) - if ok then - ftable[n] = function(...) v(state_getter(), ...) end -- implicitely add state - else - print('not found: ' .. prefix .. n .. v) - end - end - return ftable -end - --- build function table -local function_names = extract_function_names(generic_THNN_h) - -THNN.kernels = {} -THNN.kernels['torch.FloatTensor'] = THNN.bind(THNN.C, function_names, 'Float', THNN.getState) -THNN.kernels['torch.DoubleTensor'] = THNN.bind(THNN.C, function_names, 'Double', THNN.getState) - -torch.getmetatable('torch.FloatTensor').THNN = THNN.kernels['torch.FloatTensor'] -torch.getmetatable('torch.DoubleTensor').THNN = THNN.kernels['torch.DoubleTensor'] - function THNN.runKernel(f, type, ...) local ftable = THNN.kernels[type] if not ftable then @@ -726,4 +57,4 @@ function THNN.runKernel(f, type, ...) f(...) end -return THNN +return THNN \ No newline at end of file diff --git a/THNN_h.lua b/THNN_h.lua new file mode 100644 index 000000000..3fd26c5c6 --- /dev/null +++ b/THNN_h.lua @@ -0,0 +1,665 @@ +------------------------------------------------ +-- Preamble +------------------------------------------------ +--[[ +C-code header file for THNN package. Table +'header' gets passed to an instance of the API +class during a call to API:c_init(). + +If passed as a second argument to API:__init__, +API instance will pass the header object to +API:c_init(). + + +Authored: 2016-01-06 +Modified: 2016-02-04 +--]] + +------------------------------------------------ +-- THNN_h +------------------------------------------------ +local header = {} + +-------------------------------- +-- C Preamble +-------------------------------- +--[[ +* Preamble for C code; gets defined +first. +--]] +header['preamble'] = +[[ + typedef void THNNState; + typedef struct { + unsigned long the_initial_seed; + int left; + int seeded; + unsigned long next; + unsigned long state[624]; /* the array for the state vector 624 = _MERSENNE_STATE_N */ + double normal_x; + double normal_y; + double normal_rho; + int normal_is_valid; + } THGenerator; +]] + + +-------------------------------- +-- Template +-------------------------------- +--[[ +* Pattern for re-expressing function signatures +prior to application of macros + +* , and are special patterns +denoting references to config elements of the API +instance itself. + +* The convention '$k' denotes retention of the k-th +capture group in the combined prefix-pattern +regular expression (see Forward Declaration). +--]] +header['template'] = ' _TYPE$1' + + +-------------------------------- +-- Macros +-------------------------------- +--[[ +* Macro conventions: + - Universal: 'old' = 'new' + - Grouped: = {'old':'new', ...} + - Alternatives: 'old' = {group_k:'new_k', ...} +--]] + +header['macros'] = +{ + ['TYPE'] = {d='Double', f='Float'}, + ['real'] = {d='double', f='float'}, + ['THTensor'] = {d='THDoubleTensor', f='THFloatTensor'}, + ['THIndexTensor'] = 'THLongTensor', + ['THIntegerTensor'] = 'THIntTensor', + ['THIndex_t'] = 'long', + ['THInteger_t'] = 'int', +} + + +-------------------------------- +-- Forward Declaration +-------------------------------- +--[[ +* Forward declaration of C function + +* Default Format: + _(...) + |_______ _______| + prefix + +* Example: pattern := '%(([%a%d_]+)%)' + + _ + TH_API void THNN_(Abs_updateOutput) +--]] + +header['forward'] = +[[ + TH_API void THNN_(Abs_updateOutput)( + THNNState *state, + THTensor *input, + THTensor *output); + TH_API void THNN_(Abs_updateGradInput)( + THNNState *state, + THTensor *input, + THTensor *gradOutput, + THTensor *gradInput); + TH_API void THNN_(AbsCriterion_updateOutput)( + THNNState *state, + THTensor *input, + THTensor *target, + THTensor *output, + bool sizeAverage); + TH_API void THNN_(AbsCriterion_updateGradInput)( + THNNState *state, + THTensor *input, + THTensor *target, + THTensor *gradInput, + bool sizeAverage); + TH_API void THNN_(ClassNLLCriterion_updateOutput)( + THNNState *state, + THTensor *input, + THIndexTensor *target, + THTensor *output, + bool sizeAverage, + THTensor *weights, + THTensor *total_weight); + TH_API void THNN_(ClassNLLCriterion_updateGradInput)( + THNNState *state, + THTensor *input, + THIndexTensor *target, + THTensor *gradInput, + bool sizeAverage, + THTensor *weights, + THTensor *total_weight); + TH_API void THNN_(ELU_updateOutput)( + THNNState *state, + THTensor *input, + THTensor *output, + real alpha); + TH_API void THNN_(ELU_updateGradInput)( + THNNState *state, + THTensor *input, + THTensor *gradOutput, + THTensor *gradInput, + THTensor *output, + real alpha); + TH_API void THNN_(DistKLDivCriterion_updateOutput)( + THNNState *state, + THTensor *input, + THTensor *target, + THTensor *output, + bool sizeAverage); + TH_API void THNN_(DistKLDivCriterion_updateGradInput)( + THNNState *state, + THTensor *input, + THTensor *target, + THTensor *gradInput, + bool sizeAverage); + TH_API void THNN_(HardShrink_updateOutput)( + THNNState *state, + THTensor *input, + THTensor *output, + real lambda); + TH_API void THNN_(HardShrink_updateGradInput)( + THNNState *state, + THTensor *input, + THTensor *gradOutput, + THTensor *gradInput, + real lambda); + TH_API void THNN_(HardTanh_updateOutput)( + THNNState *state, + THTensor *input, + THTensor *output, + real min_val, + real max_val); + TH_API void THNN_(HardTanh_updateGradInput)( + THNNState *state, + THTensor *input, + THTensor *gradOutput, + THTensor *gradInput, + real min_val, + real max_val); + TH_API void THNN_(L1Cost_updateOutput)( + THNNState *state, + THTensor *input, + THTensor *output); + TH_API void THNN_(L1Cost_updateGradInput)( + THNNState *state, + THTensor *input, + THTensor *gradOutput, + THTensor *gradInput); + TH_API void THNN_(LeakyReLU_updateOutput)( + THNNState *state, + THTensor *input, + THTensor *output, + real negval, + bool inplace); + TH_API void THNN_(LeakyReLU_updateGradInput)( + THNNState *state, + THTensor *input, + THTensor *gradOutput, + THTensor *gradInput, + real negval, + bool inplace); + TH_API void THNN_(LogSigmoid_updateOutput)( + THNNState *state, + THTensor *input, + THTensor *output, + THTensor *buffer); + TH_API void THNN_(LogSigmoid_updateGradInput)( + THNNState *state, + THTensor *input, + THTensor *gradOutput, + THTensor *gradInput, + THTensor *buffer); + TH_API void THNN_(LogSoftMax_updateOutput)( + THNNState *state, + THTensor *input, + THTensor *output); + TH_API void THNN_(LogSoftMax_updateGradInput)( + THNNState *state, + THTensor *input, + THTensor *gradOutput, + THTensor *gradInput, + THTensor *output); + TH_API void THNN_(LookupTable_accGradParameters)( + THNNState *state, + THIndexTensor *input, + THTensor *gradOutput, + THTensor *gradWeight, + THIntegerTensor *count, + THTensor *sorted, + THTensor *indices, + bool scaleGradByFreq, + real scale); + TH_API void THNN_(MarginCriterion_updateOutput)( + THNNState *state, + THTensor *input, + THTensor *target, + THTensor *output, + bool sizeAverage, + real margin); + TH_API void THNN_(MarginCriterion_updateGradInput)( + THNNState *state, + THTensor *input, + THTensor *target, + THTensor *gradInput, + bool sizeAverage, + real margin); + TH_API void THNN_(MSECriterion_updateOutput)( + THNNState *state, + THTensor *input, + THTensor *target, + THTensor *output, + bool sizeAverage); + TH_API void THNN_(MSECriterion_updateGradInput)( + THNNState *state, + THTensor *input, + THTensor *target, + THTensor *gradInput, + bool sizeAverage); + TH_API void THNN_(MultiLabelMarginCriterion_updateOutput)( + THNNState *state, + THTensor *input, + THTensor *target, + THTensor *output, + bool sizeAverage); + TH_API void THNN_(MultiLabelMarginCriterion_updateGradInput)( + THNNState *state, + THTensor *input, + THTensor *target, + THTensor *gradInput, + bool sizeAverage); + TH_API void THNN_(MultiMarginCriterion_updateOutput)( + THNNState *state, + THTensor *input, + THTensor *target, + THTensor *output, + bool sizeAverage, + int p); + TH_API void THNN_(MultiMarginCriterion_updateGradInput)( + THNNState *state, + THTensor *input, + THTensor *target, + THTensor *gradInput, + bool sizeAverage, + int p); + TH_API void THNN_(PReLU_updateOutput)( + THNNState *state, + THTensor *input, + THTensor *output, + THTensor *weight, + THIndex_t nOutputPlane); + TH_API void THNN_(PReLU_updateGradInput)( + THNNState *state, + THTensor *input, + THTensor *gradOutput, + THTensor *gradInput, + THTensor *weight, + THIndex_t nOutputPlane); + TH_API void THNN_(PReLU_accGradParameters)( + THNNState *state, + THTensor *input, + THTensor *gradOutput, + THTensor *gradInput, + THTensor *weight, + THTensor *gradWeight, + THTensor *gradWeightBuf, + THTensor *gradWeightBuf2, + THIndex_t nOutputPlane, + real scale); + TH_API void THNN_(RReLU_updateOutput)( + THNNState *state, + THTensor *input, + THTensor *output, + THTensor *noise, + real lower, + real upper, + bool train, + bool inplace, + THGenerator *generator); + TH_API void THNN_(RReLU_updateGradInput)( + THNNState *state, + THTensor *input, + THTensor *gradOutput, + THTensor *gradInput, + THTensor *noise, + real lower, + real upper, + bool train, + bool inplace); + TH_API void THNN_(Sigmoid_updateOutput)( + THNNState *state, + THTensor *input, + THTensor *output); + TH_API void THNN_(Sigmoid_updateGradInput)( + THNNState *state, + THTensor *input, + THTensor *gradOutput, + THTensor *gradInput, + THTensor *output); + TH_API void THNN_(SmoothL1Criterion_updateOutput)( + THNNState *state, + THTensor *input, + THTensor *target, + THTensor *output, + bool sizeAverage); + TH_API void THNN_(SmoothL1Criterion_updateGradInput)( + THNNState *state, + THTensor *input, + THTensor *target, + THTensor *gradInput, + bool sizeAverage); + TH_API void THNN_(SoftMax_updateOutput)( + THNNState *state, + THTensor *input, + THTensor *output); + TH_API void THNN_(SoftMax_updateGradInput)( + THNNState *state, + THTensor *input, + THTensor *gradOutput, + THTensor *gradInput, + THTensor *output); + TH_API void THNN_(SoftPlus_updateOutput)( + THNNState *state, + THTensor *input, + THTensor *output, + real beta, + real threshold); + TH_API void THNN_(SoftPlus_updateGradInput)( + THNNState *state, + THTensor *input, + THTensor *gradOutput, + THTensor *gradInput, + THTensor *output, + real beta, + real threshold); + TH_API void THNN_(SoftShrink_updateOutput)( + THNNState *state, + THTensor *input, + THTensor *output, + real lambda); + TH_API void THNN_(SoftShrink_updateGradInput)( + THNNState *state, + THTensor *input, + THTensor *gradOutput, + THTensor *gradInput, + real lambda); + TH_API void THNN_(Sqrt_updateOutput)( + THNNState *state, + THTensor *input, + THTensor *output, + real eps); + TH_API void THNN_(Sqrt_updateGradInput)( + THNNState *state, + THTensor *input, + THTensor *gradOutput, + THTensor *gradInput, + THTensor *output); + TH_API void THNN_(Square_updateOutput)( + THNNState *state, + THTensor *input, + THTensor *output); + TH_API void THNN_(Square_updateGradInput)( + THNNState *state, + THTensor *input, + THTensor *gradOutput, + THTensor *gradInput); + TH_API void THNN_(Tanh_updateOutput)( + THNNState *state, + THTensor *input, + THTensor *output); + TH_API void THNN_(Tanh_updateGradInput)( + THNNState *state, + THTensor *input, + THTensor *gradOutput, + THTensor *gradInput, + THTensor *output); + TH_API void THNN_(Threshold_updateOutput)( + THNNState *state, + THTensor *input, + THTensor *output, + real threshold, + real val, + bool inplace); + TH_API void THNN_(Threshold_updateGradInput)( + THNNState *state, + THTensor *input, + THTensor *gradOutput, + THTensor *gradInput, + real threshold, + bool inplace); + TH_API void THNN_(SpatialConvolutionMM_updateOutput)( + THNNState *state, + THTensor *input, + THTensor *output, + THTensor *weight, + THTensor *bias, + THTensor *finput, + THTensor *fgradInput, + int kW, int kH, + int dW, int dH, + int padW, int padH); + TH_API void THNN_(SpatialConvolutionMM_updateGradInput)( + THNNState *state, + THTensor *input, + THTensor *gradOutput, + THTensor *gradInput, + THTensor *weight, + THTensor *bias, + THTensor *finput, + THTensor *fgradInput, + int kW, int kH, + int dW, int dH, + int padW, int padH); + TH_API void THNN_(SpatialConvolutionMM_accGradParameters)( + THNNState *state, + THTensor *input, + THTensor *gradOutput, + THTensor *gradWeight, + THTensor *gradBias, + THTensor *finput, + THTensor *fgradInput, + int kW, int kH, + int dW, int dH, + int padW, int padH, + real scale); + TH_API void THNN_(SpatialAdaptiveMaxPooling_updateOutput)( + THNNState *state, + THTensor *input, + THTensor *output, + THTensor *indices, + int owidth, int oheight); + TH_API void THNN_(SpatialAdaptiveMaxPooling_updateGradInput)( + THNNState *state, + THTensor *input, + THTensor *gradOutput, + THTensor *gradInput, + THTensor *indices); + TH_API void THNN_(SpatialAveragePooling_updateOutput)( + THNNState *state, + THTensor *input, + THTensor *output, + int kW, int kH, + int dW, int dH, + int padW, int padH, + bool ceil_mode, + bool count_include_pad); + TH_API void THNN_(SpatialAveragePooling_updateGradInput)( + THNNState *state, + THTensor *input, + THTensor *gradOutput, + THTensor *gradInput, + int kW, int kH, + int dW, int dH, + int padW, int padH, + bool ceil_mode, + bool count_include_pad); + TH_API void THNN_(SpatialMaxPooling_updateOutput)( + THNNState *state, + THTensor *input, + THTensor *output, + THTensor *indices, + int kW, int kH, + int dW, int dH, + int padW, int padH, + bool ceil_mode); + TH_API void THNN_(SpatialMaxPooling_updateGradInput)( + THNNState *state, + THTensor *input, + THTensor *gradOutput, + THTensor *gradInput, + THTensor *indices, + int kW, int kH, + int dW, int dH, + int padW, int padH, + bool ceil_mode); + TH_API void THNN_(VolumetricAveragePooling_updateOutput)( + THNNState *state, + THTensor *input, + THTensor *output, + int kT, int kW, int kH, + int dT, int dW, int dH); + TH_API void THNN_(VolumetricAveragePooling_updateGradInput)( + THNNState *state, + THTensor *input, + THTensor *gradOutput, + THTensor *gradInput, + int kT, int kW, int kH, + int dT, int dW, int dH); + TH_API void THNN_(VolumetricConvolution_updateOutput)( + THNNState *state, + THTensor *input, + THTensor *output, + THTensor *weight, + THTensor *bias, + THTensor *finput, + THTensor *fgradInput, + int dT, int dW, int dH, + int pT, int pW, int pH); + TH_API void THNN_(VolumetricConvolution_updateGradInput)( + THNNState *state, + THTensor *input, + THTensor *gradOutput, + THTensor *gradInput, + THTensor *weight, + THTensor *finput, + int dT, int dW, int dH, + int pT, int pW, int pH); + TH_API void THNN_(VolumetricConvolution_accGradParameters)( + THNNState *state, + THTensor *input, + THTensor *gradOutput, + THTensor *gradWeight, + THTensor *gradBias, + THTensor *finput, + THTensor *fgradInput, + int dT, int dW, int dH, + int pT, int pW, int pH, + real scale); + TH_API void THNN_(VolumetricConvolutionMM_updateOutput)( + THNNState *state, + THTensor *input, + THTensor *output, + THTensor *weight, + THTensor *bias, + THTensor *finput, + int kT, int kW, int kH, + int dT, int dW, int dH, + int pT, int pW, int pH); + TH_API void THNN_(VolumetricConvolutionMM_updateGradInput)( + THNNState *state, + THTensor *input, + THTensor *gradOutput, + THTensor *gradInput, + THTensor *weight, + THTensor *finput, + THTensor *fgradInput, + int kT, int kW, int kH, + int dT, int dW, int dH, + int pT, int pW, int pH); + TH_API void THNN_(VolumetricConvolutionMM_accGradParameters)( + THNNState *state, + THTensor *input, + THTensor *gradOutput, + THTensor *gradWeight, + THTensor *gradBias, + THTensor *finput, + real scale); + TH_API void THNN_(VolumetricFullConvolution_updateOutput)( + THNNState *state, + THTensor *input, + THTensor *output, + THTensor *weight, + THTensor *bias, + THTensor *finput, + THTensor *fgradInput, + int dT, int dW, int dH, + int pT, int pW, int pH); + TH_API void THNN_(VolumetricFullConvolution_updateGradInput)( + THNNState *state, + THTensor *input, + THTensor *gradOutput, + THTensor *gradInput, + THTensor *weight, + THTensor *finput, + THTensor *fgradInput, + int dT, int dW, int dH, + int pT, int pW, int pH); + TH_API void THNN_(VolumetricFullConvolution_accGradParameters)( + THNNState *state, + THTensor *input, + THTensor *gradOutput, + THTensor *gradWeight, + THTensor *gradBias, + THTensor *finput, + THTensor *fgradInput, + int dT, int dW, int dH, + int pT, int pW, int pH, + real scale); + TH_API void THNN_(VolumetricMaxPooling_updateOutput)( + THNNState *state, + THTensor *input, + THTensor *output, + THTensor *indices, + int kT, int kW, int kH, + int dT, int dW, int dH, + int pT, int pW, int pH, + bool ceilMode); + TH_API void THNN_(VolumetricMaxPooling_updateGradInput)( + THNNState *state, + THTensor *input, + THTensor *gradOutput, + THTensor *gradInput, + THTensor *indices, + int dT, int dW, int dH, + int pT, int pW, int pH); + TH_API void THNN_(VolumetricMaxUnpooling_updateOutput)( + THNNState *state, + THTensor *input, + THTensor *output, + THTensor *indices, + int oT, int oW, int oH, + int dT, int dW, int dH, + int pT, int pW, int pH); + TH_API void THNN_(VolumetricMaxUnpooling_updateGradInput)( + THNNState *state, + THTensor *input, + THTensor *gradOutput, + THTensor *gradInput, + THTensor *indices, + int oT, int oW, int oH, + int dT, int dW, int dH, + int pT, int pW, int pH); +]] + +return header \ No newline at end of file diff --git a/torchAPI.lua b/torchAPI.lua new file mode 100644 index 000000000..b8ab37ad0 --- /dev/null +++ b/torchAPI.lua @@ -0,0 +1,215 @@ +------------------------------------------------ +-- Preamble +------------------------------------------------ +--[[ +Generic application program interface (API) for +convenient linkage of C and Lua code libraries. + +Glossary: + ------------------------------------------ + | Term | Description | + ------------------------------------------ + | library | Name of overarching library | + | pattern | Regex for function handles | + | tag | API-FFI method identifier | + | rtype | Return type for FFI methods | + | prefix | Function signature prefix | + ------------------------------------------ + +Default Format: + _(...) + |_______ ________| + prefix + +By way of example, using the default +pattern := '([%a%d_]+)': + + _ + TH_API void THNN_Abs_updateOutput + +Equivalently, if we initialize an API with +pattern := '%(([%a%d_]+)%)': + + _ + TH_API void THNN_(Abs_updateOutput) + + +Authored: 2016-01-05 (jwilson) +Modified: 2016-02-04 +--]] + +---------------- External Dependencies +local ffi = require 'ffi' + +------------------------------------------------ +-- API +------------------------------------------------ +local API = torch.class('torchAPI') + +function API:__init(config, header) + local L = config or {} + assert(type(L.library) == 'string') + L.pattern = L.pattern or '([%a%d_]+)' + L.rtype = L.rtype or 'void' + L.tag = L.tag or '' + L.prefix = L.prefix or string.format('%s %s %s_', L.tag, L.rtype, L.library):gsub("^%s+", "") + self.config = L + + if header then + self:c_init(header) + end +end + +function API:getState(ttype) + if ttype == 'Cuda' then + if not self.cuda_ptr then + self.cuda_ptr = ffi.typeof('THCState*') + end + return self.cuda_ptr(cutorch.getState()) + else + return ffi.NULL or nil + end +end + +function API:extract_handles(forward, pattern, handles) + local handles = handles or {} + local pattern = pattern or self.config.prefix ..self.config.pattern + for handle in string.gmatch(forward, pattern) do + handles[#handles+1] = handle + end + return handles +end + +function API:c_init(header) + + ---- Define C Preamble + if header['preamble'] then + ffi.cdef(header['preamble']) + end + + ---- Check for forward declaration + forward = header['forward'] + if not forward then return end -- terminate if no forward + + ---- Swap in template Prepare forward for declaration / expansion of macros + local templates = header['template'] + if templates then + if type(templates) == 'string' then + templates = {templates} + end + + for idx = 1, #templates do + template = templates[idx] + + ---- Check for special patterns + if template:match('') then + template = template:gsub('', self.config.tag) + end + + if template:match('') then + template = template:gsub('', self.config.rtype) + end + + if template:match('') then + template = template:gsub('', self.config.library) + end + + if template:match('$([0-9]+)') then + template = template:gsub('$([0-9]+)', '%%%1') + end + + forward = forward:gsub(self.config.prefix..self.config.pattern, template) + end + end + + ---- Expand macros + local macros = header['macro'] or header['macros'] + if macros then + local macros = self:_interp_macros(macros) + local flag = false + + -- Apply macros with same interpretation everywhere + for old, new in pairs(macros) do + if type(new) == 'string' then + forward = forward:gsub(old, new) + else + flag = true -- Are there additional macros to process? + end + end + + -- Apply macros with alternative interpretations + if flag then + for id, group in pairs(macros) do + if type(group) == 'table' then + local forward = forward + for old, new in pairs(group) do + forward = forward:gsub(old, new) + end + ffi.cdef(forward) + end + end + else + -- No alternatives case + ffi.cdef(forward) + end + else + -- No macros case + ffi.cdef(forward) + end +end + +function API:_interp_macros(macros, interp) + local interp = interp or {} + for key, macro in pairs(macros) do + if type(macro) == 'string' then -- Macros without same + assert(type(key) == 'string') -- interpretation everywhere + interp[key] = macro -- must have string keys + else + assert(type(macro) == 'table') -- Non-global macros must be tables + if type(key) == 'number' then -- Pre-sorted group, i.e. all terms + interp[key] = macros -- in interpetation are already together + else + assert(type(key) == 'string') -- Single term with multiple interps + for k, v in pairs(macro) do + assert(type(k) == 'string') -- To avoid confusion with pre-sorted + interp[k] = interp[k] or {} -- groups; strings must be used to denote + interp[k][key] = v -- membership. + end + end + end + end + return interp +end + +function API:bind(cstruct, forward, ttype, getter, library, pattern, handles, prefix) + local library = library or {} + local handles = self:extract_handles(forward, pattern, handles) + local prefix = prefix or string.format('%s_%s', self.config.library, ttype) + local getter = getter or self.getState + + if type(cstruct) == 'string' then + ---- Polyfill for LUA 5.1 + if not package.searchpath then + local sep = package.config:sub(1,1) + function package.searchpath(mod, path) + local mod, nm, f = mod:gsub('%.', sep) + for m in path:gmatch('[^;]+') do + nm = m:gsub('?', mod) + f = io.open(nm, 'r') + if f then f:close() return nm end + end + end + end + cstruct = ffi.load(package.searchpath(cstruct, package.cpath)) + end + + for idx, h in ipairs(handles) do + if cstruct[prefix .. h] then -- implicitly add state + library[h] = function(...) cstruct[prefix .. h](getter(), ...) end + else + print('> Warning:::Unable to locate method ' .. prefix .. h) + end + end + + return library +end \ No newline at end of file