【发布时间】:2016-11-20 03:42:54
【问题描述】:
我正在尝试将并行数据加载器添加到 torch-dataframe 以添加 torchnet compatibility。我使用了tnt.ParallelDatasetIterator 和changed it 以便:
- 在线程外加载一个基本批处理
- 批处理被序列化并发送到线程
- 在线程中,批处理被反序列化并将批处理数据转换为张量
- 张量返回到具有
input和target键的表中,以匹配tnt.Engine 设置。
问题在第二次调用 enque 时出现错误:.../torch_distro/install/bin/luajit: not enough memory。我目前只使用mnist 和改编的mnist-example。 enque 循环现在看起来像这样(带有调试内存输出):
-- `samplePlaceholder` stands in for samples which have been
-- filtered out by the `filter` function
local samplePlaceholder = {}
-- The enque does the main loop
local idx = 1
local function enqueue()
while idx <= size and threads:acceptsjob() do
local batch, reset = self.dataset:get_batch(batch_size)
if (reset) then
idx = size + 1
else
idx = idx + 1
end
if (batch) then
local serialized_batch = torch.serialize(batch)
-- In the parallel section only the to_tensor is run in parallel
-- this should though be the computationally expensive operation
threads:addjob(
function(argList)
io.stderr:write("\n Start");
io.stderr:write("\n 1: " ..tostring(collectgarbage("count")))
local origIdx, serialized_batch, samplePlaceholder = unpack(argList)
io.stderr:write("\n 2: " ..tostring(collectgarbage("count")))
local batch = torch.deserialize(serialized_batch)
serialized_batch = nil
collectgarbage()
collectgarbage()
io.stderr:write("\n 3: " .. tostring(collectgarbage("count")))
batch = transform(batch)
io.stderr:write("\n 4: " .. tostring(collectgarbage("count")))
local sample = samplePlaceholder
if (filter(batch)) then
sample = {}
sample.input, sample.target = batch:to_tensor()
end
io.stderr:write("\n 5: " ..tostring(collectgarbage("count")))
collectgarbage()
collectgarbage()
io.stderr:write("\n 6: " ..tostring(collectgarbage("count")))
io.stderr:write("\n End \n");
return {
sample,
origIdx
}
end,
function(argList)
sample, sampleOrigIdx = unpack(argList)
end,
{idx, serialized_batch, samplePlaceholder}
)
end
end
end
我已经洒了collectgarbage 并尝试移除任何不需要的对象。内存输出相当直接:
Start
1: 374840.87695312
2: 374840.94433594
3: 372023.79101562
4: 372023.85839844
5: 372075.41308594
6: 372023.73632812
End
循环enque的函数是微不足道的无序函数(内存错误抛出第二个enque和):
iterFunction = function()
while threads:hasjob() do
enqueue()
threads:dojob()
if threads:haserror() then
threads:synchronize()
end
enqueue()
if table.exact_length(sample) > 0 then
return sample
end
end
end
【问题讨论】:
标签: multithreading lua torch luajit