Параллельные вычисления в Julia с большими данными

первый мой вопрос:

  • можно ли запретить Julia копировать переменные каждый раз в параллельном цикле for ?
  • если нет, как реализовать параллельные операции сокращения в Julia ?

теперь подробнее:

у меня есть эта программа:

data = DataFrames.readtable("...") # a big baby (~100MB)
filter_functions = [ fct1, fct2, fct3 ... ] # (x::DataFrame) -> y::DataFrame
filtered_data = @parallel vcat for fct in filter_functions
  fct(data)::DataFrame
end

он работает с хорошей функциональностью, но каждый параллельный вызов fct (data) на другом работнике копирует весь фрейм данных, делая все болезненно медленный.

В идеале я хотел бы загрузить данные один раз и всегда использовать каждый на каждом работнике предварительно загруженные данные. Я придумал этот код:

@everywhere data = DataFrames.readtable("...") # a big baby (~100MB)
@everywhere filter_functions = [ fct1, fct2, fct3 ... ] # (x::DataFrame) -> y::DataFrame
@everywhere for i in 1:length(filter_functions)
  if (myid()-1) % nworkers()
    fct = filter_functions[i]
    filtered_data_temp = fct(data)
  end
  # How to vcat all the filtered_data_temp ?
end

но теперь у меня другая проблема: я не могу понять, как vcat() все filtered_data_temp на переменную в работнике с myid()==1.

Я был бы очень признателен за любое понимание.

Примечание: я в курсе работающ параллельно на большой постоянн datastructure внутри Юлия!--24-->. Тем не менее, я не считаю, что это относится к моей проблеме, потому что все мои filter_functions работают с массивом в целом.

2 ответов


вы можете посмотреть/загрузить свои данные в Распределенные Массивы

EDIT: вероятно, что-то вроде этого:

data = DataFrames.readtable("...")
dfiltered_data = distribute(data) #distributes data among processes automagically
filter_functions = [ fct1, fct2, fct3 ... ] 
for fct in filter_functions
  dfiltered_data = fct(dfiltered_data)::DataFrame
end

вы также можете проверить тесты дополнительные примеры


В конце концов, я нашел там решение моего вопроса:Julia: как скопировать данные на другой процессор в Julia.

в частности, он вводит следующий примитив для извлечения переменной из другого процесса:

getfrom(p::Int, nm::Symbol; mod=Main) = fetch(@spawnat(p, getfield(mod, nm)))

ниже, как я его использую:

@everywhere data = DataFrames.readtable("...") # a big baby (~100MB)
@everywhere filter_functions = [ fct1, fct2, fct3 ... ] # (x::DataFrame) -> y::DataFrame
# Executes the filter functions
@everywhere for i in 1:length(filter_functions)
  local_results = ... # some type
  if (myid()-1) % nworkers()
    fct = filter_functions[i]
    filtered_data_temp = fct(data)
    local_results = vcat(local_results, filtered_data_temp)
  end
  # How to vcat all the filtered_data_temp ?
end
# Concatenate all the local results
all_results = ... # some type
for wid in 1:workers()
  worker_local_results = getfrom(wid, :local_results)
  all_results = vcat(all_results,worker_local_results)
end