Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 使用Torch.serialize两次时,Torch线程内存不足_Multithreading_Lua_Torch_Luajit - Fatal编程技术网

Multithreading 使用Torch.serialize两次时,Torch线程内存不足

Multithreading 使用Torch.serialize两次时,Torch线程内存不足,multithreading,lua,torch,luajit,Multithreading,Lua,Torch,Luajit,我正在尝试向添加一个并行数据加载器,以便添加。我使用了和,因此: 在线程外部加载基本批处理 批处理被序列化并发送到线程 在线程中,批处理被反序列化,并将批处理数据转换为张量 张量在具有输入和目标键的表中返回,以匹配设置 第二次调用enque时出现错误:../torch\u distro/install/bin/luajit:内存不足。我目前只和一个改编过的人一起工作。enque循环现在看起来像这样(带有调试内存输出): 循环enque的函数是一个非有序的函数,它非常简单(内存错误在第二个enqu

我正在尝试向添加一个并行数据加载器,以便添加。我使用了和,因此:

  • 在线程外部加载基本批处理
  • 批处理被序列化并发送到线程
  • 在线程中,批处理被反序列化,并将批处理数据转换为张量
  • 张量在具有
    输入
    目标
    键的表中返回,以匹配设置
  • 第二次调用
    enque
    时出现错误:
    ../torch\u distro/install/bin/luajit:内存不足
    。我目前只和一个改编过的人一起工作。
    enque
    循环现在看起来像这样(带有调试内存输出):

    循环
    enque
    的函数是一个非有序的函数,它非常简单(内存错误在第二个
    enque
    和第二个
    enque时抛出):


    因此问题在于
    torch.serialize
    ,其中设置中的函数将整个数据集耦合到函数。添加时:

    serialized_batch = nil
    collectgarbage()
    collectgarbage()
    
    问题解决了。我还想知道是什么占用了这么多空间,而罪魁祸首是我在一个环境中定义了这个函数,这个环境中有一个大数据集,这个数据集与函数交织在一起,大大增加了函数的大小。这里是本地数据的原始定义

    mnist = require 'mnist'
    local dataset = mnist[mode .. 'dataset']()
    
    -- PROBLEMATIC LINE BELOW --
    local ext_resource = dataset.data:reshape(dataset.data:size(1),
      dataset.data:size(2) * dataset.data:size(3)):double()
    
    -- Create a Dataframe with the label. The actual images will be loaded
    --  as an external resource
    local df = Dataframe(
      Df_Dict{
        label = dataset.label:totable(),
        row_id = torch.range(1, dataset.data:size(1)):totable()
      })
    
    -- Since the mnist package already has taken care of the data
    --  splitting we create a single subsetter
    df:create_subsets{
      subsets = Df_Dict{core = 1},
      class_args = Df_Tbl({
        batch_args = Df_Tbl({
          label = Df_Array("label"),
          data = function(row)
            return ext_resource[row.row_id]
          end
        })
      })
    }
    
    事实证明,删除我突出显示的行可以将内存使用量从358MB降低到0.0008MB!我用于测试性能的代码是:

    local mem = {}
    table.insert(mem, collectgarbage("count"))
    
    local ser_data = torch.serialize(batch.dataset)
    table.insert(mem, collectgarbage("count"))
    
    local ser_retriever = torch.serialize(batch.batchframe_defaults.data)
    table.insert(mem, collectgarbage("count"))
    
    local ser_raw_retriever = torch.serialize(function(row)
      return ext_resource[row.row_id]
    end)
    table.insert(mem, collectgarbage("count"))
    
    local serialized_batch = torch.serialize(batch)
    table.insert(mem, collectgarbage("count"))
    
    for i=2,#mem do
      print(i-1, (mem[i] - mem[i-1])/1024)
    end
    
    它最初产生了输出:

    1   0.0082607269287109  
    2   358.23344707489 
    3   0.0017471313476562  
    4   358.90182781219 
    
    修复后:

    1   0.0094480514526367  
    2   0.00080204010009766 
    3   0.00090408325195312 
    4   0.010146141052246
    
    我尝试使用函数的
    setfenv
    ,但没有解决问题。将序列化数据发送到线程仍然会带来性能损失,但主要问题已经解决,如果没有昂贵的数据检索器,函数将大大减小

    local mem = {}
    table.insert(mem, collectgarbage("count"))
    
    local ser_data = torch.serialize(batch.dataset)
    table.insert(mem, collectgarbage("count"))
    
    local ser_retriever = torch.serialize(batch.batchframe_defaults.data)
    table.insert(mem, collectgarbage("count"))
    
    local ser_raw_retriever = torch.serialize(function(row)
      return ext_resource[row.row_id]
    end)
    table.insert(mem, collectgarbage("count"))
    
    local serialized_batch = torch.serialize(batch)
    table.insert(mem, collectgarbage("count"))
    
    for i=2,#mem do
      print(i-1, (mem[i] - mem[i-1])/1024)
    end
    
    1   0.0082607269287109  
    2   358.23344707489 
    3   0.0017471313476562  
    4   358.90182781219 
    
    1   0.0094480514526367  
    2   0.00080204010009766 
    3   0.00090408325195312 
    4   0.010146141052246