X-Git-Url: https://fleuret.org/cgi-bin/gitweb/gitweb.cgi?a=blobdiff_plain;f=dagnn.lua;h=65a30e212126532f8796f6c1e35208a018f421fe;hb=682b76200f755f5f16477e086056a86cafdea1cd;hp=52913ad9992f404277a9b695be590baaa9cdedea;hpb=be03a73e411d18082a2dd99bff5df45c085017ca;p=dagnn.git diff --git a/dagnn.lua b/dagnn.lua index 52913ad..65a30e2 100755 --- a/dagnn.lua +++ b/dagnn.lua @@ -11,6 +11,7 @@ function DAG:__init() end function DAG:addEdge(a, b) + self.sorted = nil local pred, succ = self.pred, self.succ if not pred[a] and not succ[a] then self:add(a) @@ -24,38 +25,36 @@ function DAG:addEdge(a, b) succ[a][#succ[a] + 1] = b end -function DAG:setInput(i) - if torch.type(i) == 'table' then - self.inputModules = i - for _, m in ipairs(i) do - if not self.pred[m] and not self.succ[m] then - self:add(m) - end +function DAG:applyOnModules(f, t1, t2) + if torch.type(t1) == 'table' then + local result = {} + for k, s in pairs(t1) do + result[k] = self:applyOnModules(f, s, t2 and t2[k]) end + return result else - self:setInput({ i }) + return f(t1, t2) end end +function DAG:setInput(i) + self.sorted = nil + self.inputModules = i +end + function DAG:setOutput(o) - if torch.type(o) == 'table' then - self.outputModules = o - for _, m in ipairs(o) do - if not self.pred[m] and not self.succ[m] then - self:add(m) - end - end - else - self:setOutput({ o }) - end + self.sorted = nil + self.outputModules = o end -function DAG:order() +function DAG:sort() + if self.sorted then + return + end + local distance = {} - for _, a in pairs(self.inputModules) do - distance[a] = 1 - end + self:applyOnModules(function(m) distance[m] = 1 end, self.inputModules) local nc @@ -81,19 +80,17 @@ function DAG:order() end function DAG:print() + self:sort() + for i, d in ipairs(self.sorted) do print('#' .. i .. ' -> ' .. torch.type(d)) end end function DAG:updateOutput(input) - if #self.inputModules == 1 then - self.inputModules[1]:updateOutput(input) - else - for i, d in ipairs(self.inputModules) do - d:updateOutput(input[i]) - end - end + self:sort() + + self:applyOnModules(function(m, i) m:updateOutput(i) end, self.inputModules, input) for _, d in ipairs(self.sorted) do if self.pred[d] then @@ -109,14 +106,13 @@ function DAG:updateOutput(input) end end - if #self.outputModules == 1 then - self.output = self.outputModules[1].output - else - self.output = { } - for i, d in ipairs(self.outputModules) do - self.output[i] = d.output - end - end + self.output = self:applyOnModules(function(m) return m.output end, self.outputModules) return self.output end + +function DAG:updateGradInput(input, gradOutput) + self:sort() +end + +return DAG