Параллельные вычисления в 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.
Я был бы очень признателен за любое понимание.
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