Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/torch/nn.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'generic/TemporalConvolution.c')
-rw-r--r--generic/TemporalConvolution.c194
1 files changed, 194 insertions, 0 deletions
diff --git a/generic/TemporalConvolution.c b/generic/TemporalConvolution.c
new file mode 100644
index 0000000..fa14a22
--- /dev/null
+++ b/generic/TemporalConvolution.c
@@ -0,0 +1,194 @@
+#ifndef TH_GENERIC_FILE
+#define TH_GENERIC_FILE "generic/TemporalConvolution.c"
+#else
+
+static int nn_(TemporalConvolution_updateOutput)(lua_State *L)
+{
+ THTensor *input = luaT_checkudata(L, 2, torch_(Tensor_id));
+ int kW = luaT_getfieldcheckint(L, 1, "kW");
+ int dW = luaT_getfieldcheckint(L, 1, "dW");
+ int inputFrameSize = luaT_getfieldcheckint(L, 1, "inputFrameSize");
+ int outputFrameSize = luaT_getfieldcheckint(L, 1, "outputFrameSize");
+
+ THTensor *weight = luaT_getfieldcheckudata(L, 1, "weight", torch_(Tensor_id));
+ THTensor *bias = luaT_getfieldcheckudata(L, 1, "bias", torch_(Tensor_id));
+ THTensor *output = luaT_getfieldcheckudata(L, 1, "output", torch_(Tensor_id));
+
+ THTensor *outputWindow, *inputWindow;
+ int nInputFrame, nOutputFrame;
+ long k;
+
+ luaL_argcheck(L, input->nDimension == 2, 2, "2D tensor expected");
+ luaL_argcheck(L, input->size[1] == inputFrameSize, 2, "invalid input frame size");
+ luaL_argcheck(L, input->size[0] >= kW, 2, "input sequence smaller than kernel size");
+
+ input = THTensor_(newContiguous)(input);
+ outputWindow = THTensor_(new)();
+ inputWindow = THTensor_(new)();
+
+ nInputFrame = input->size[0];
+ nOutputFrame = (nInputFrame - kW) / dW + 1;
+
+ THTensor_(resize2d)(output,
+ nOutputFrame,
+ outputFrameSize);
+
+ /* bias first */
+ for(k = 0; k < nOutputFrame; k++)
+ {
+ THTensor_(select)(outputWindow, output, 0, k);
+ THTensor_(copy)(outputWindow, bias);
+ }
+
+ /* ouch */
+ for(k = 0; nOutputFrame > 0; k++)
+ {
+ long outputFrameStride = (kW-1)/dW+1;
+ long inputFrameStride = outputFrameStride*dW;
+ long nFrame = (nInputFrame-k*dW-kW)/inputFrameStride + 1;
+ nOutputFrame -= nFrame;
+
+ THTensor_(setStorage2d)(inputWindow, input->storage,
+ input->storageOffset+k*dW*input->size[1],
+ nFrame, inputFrameStride*input->size[1],
+ kW*input->size[1], 1);
+
+ THTensor_(setStorage2d)(outputWindow, output->storage,
+ output->storageOffset + k*output->size[1],
+ nFrame, outputFrameStride*output->size[1],
+ output->size[1], 1);
+
+ THTensor_(transpose)(weight, NULL, 0, 1);
+ THTensor_(addmm)(outputWindow, 1, outputWindow, 1, inputWindow, weight);
+ THTensor_(transpose)(weight, NULL, 0, 1);
+ }
+
+ THTensor_(free)(outputWindow);
+ THTensor_(free)(inputWindow);
+ THTensor_(free)(input);
+
+ return 1;
+}
+
+static int nn_(TemporalConvolution_updateGradInput)(lua_State *L)
+{
+ THTensor *input = luaT_checkudata(L, 2, torch_(Tensor_id));
+ THTensor *gradOutput = luaT_checkudata(L, 3, torch_(Tensor_id));
+ int kW = luaT_getfieldcheckint(L, 1, "kW");
+ int dW = luaT_getfieldcheckint(L, 1, "dW");
+ long nInputFrame = input->size[0];
+ long nOutputFrame = gradOutput->size[0];
+
+ THTensor *weight = luaT_getfieldcheckudata(L, 1, "weight", torch_(Tensor_id));
+ THTensor *gradInput = luaT_getfieldcheckudata(L, 1, "gradInput", torch_(Tensor_id));
+
+ THTensor *gradOutputWindow;
+ THTensor *gradInputWindow;
+ long k;
+
+ gradOutputWindow = THTensor_(new)();
+ gradInputWindow = THTensor_(new)();
+
+ THTensor_(resizeAs)(gradInput, input);
+ THTensor_(zero)(gradInput);
+
+ /* ouch */
+ for(k = 0; nOutputFrame > 0; k++)
+ {
+ long outputFrameStride = (kW-1)/dW+1;
+ long inputFrameStride = outputFrameStride*dW;
+ long nFrame = (nInputFrame-k*dW-kW)/inputFrameStride + 1;
+ nOutputFrame -= nFrame;
+
+ THTensor_(setStorage2d)(gradOutputWindow, gradOutput->storage,
+ gradOutput->storageOffset + k*gradOutput->size[1],
+ nFrame, outputFrameStride*gradOutput->size[1],
+ gradOutput->size[1], 1);
+
+ THTensor_(setStorage2d)(gradInputWindow, gradInput->storage,
+ gradInput->storageOffset+k*dW*gradInput->size[1],
+ nFrame, inputFrameStride*gradInput->size[1],
+ kW*gradInput->size[1], 1);
+
+ THTensor_(addmm)(gradInputWindow, 1, gradInputWindow, 1, gradOutputWindow, weight);
+ }
+
+ THTensor_(free)(gradOutputWindow);
+ THTensor_(free)(gradInputWindow);
+
+ return 1;
+}
+
+static int nn_(TemporalConvolution_accGradParameters)(lua_State *L)
+{
+ THTensor *input = luaT_checkudata(L, 2, torch_(Tensor_id));
+ THTensor *gradOutput = luaT_checkudata(L, 3, torch_(Tensor_id));
+ real scale = luaL_optnumber(L, 4, 1);
+ int kW = luaT_getfieldcheckint(L, 1, "kW");
+ int dW = luaT_getfieldcheckint(L, 1, "dW");
+ long nInputFrame = input->size[0];
+ long nOutputFrame = gradOutput->size[0];
+
+ THTensor *gradWeight = luaT_getfieldcheckudata(L, 1, "gradWeight", torch_(Tensor_id));
+ THTensor *gradBias = luaT_getfieldcheckudata(L, 1, "gradBias", torch_(Tensor_id));
+
+ THTensor *gradOutputWindow;
+ THTensor *inputWindow;
+ long k;
+
+ input = THTensor_(newContiguous)(input);
+ gradOutputWindow = THTensor_(new)();
+ inputWindow = THTensor_(new)();
+
+ /* bias first */
+ for(k = 0; k < nOutputFrame; k++)
+ {
+ THTensor_(select)(gradOutputWindow, gradOutput, 0, k);
+ THTensor_(cadd)(gradBias, gradBias, scale, gradOutputWindow);
+ }
+
+ /* ouch */
+ for(k = 0; nOutputFrame > 0; k++)
+ {
+ long outputFrameStride = (kW-1)/dW+1;
+ long inputFrameStride = outputFrameStride*dW;
+ long nFrame = (nInputFrame-k*dW-kW)/inputFrameStride + 1;
+ nOutputFrame -= nFrame;
+
+ THTensor_(setStorage2d)(inputWindow, input->storage,
+ input->storageOffset+k*dW*input->size[1],
+ nFrame, inputFrameStride*input->size[1],
+ kW*input->size[1], 1);
+
+ THTensor_(setStorage2d)(gradOutputWindow, gradOutput->storage,
+ gradOutput->storageOffset + k*gradOutput->size[1],
+ nFrame, outputFrameStride*gradOutput->size[1],
+ gradOutput->size[1], 1);
+
+ THTensor_(transpose)(gradOutputWindow, NULL, 0, 1);
+ THTensor_(addmm)(gradWeight, 1, gradWeight, scale, gradOutputWindow, inputWindow);
+ THTensor_(transpose)(gradOutputWindow, NULL, 0, 1);
+ }
+
+ THTensor_(free)(gradOutputWindow);
+ THTensor_(free)(inputWindow);
+ THTensor_(free)(input);
+
+ return 0;
+}
+
+static const struct luaL_Reg nn_(TemporalConvolution__) [] = {
+ {"TemporalConvolution_updateOutput", nn_(TemporalConvolution_updateOutput)},
+ {"TemporalConvolution_updateGradInput", nn_(TemporalConvolution_updateGradInput)},
+ {"TemporalConvolution_accGradParameters", nn_(TemporalConvolution_accGradParameters)},
+ {NULL, NULL}
+};
+
+static void nn_(TemporalConvolution_init)(lua_State *L)
+{
+ luaT_pushmetaclass(L, torch_(Tensor_id));
+ luaT_registeratname(L, nn_(TemporalConvolution__), "nn");
+ lua_pop(L,1);
+}
+
+#endif