Выполнение кода Python с MPI (SLURM) занимает больше времени, чем в виде отдельного процесса

#python #mpi #slurm #mpi4py

#python #mpi #slurm #mpi4py

Вопрос:

У меня есть некоторый код на python, для запуска которого на моем ноутбуке (macOS 16GB 2133 MHz LPDDR3) требуется около 12 часов. Код повторяется в течение нескольких тысяч итераций и выполняет некоторую интенсивную обработку на каждом шаге, поэтому имеет смысл распараллелить проблему с обработкой MPI. У меня есть доступ к кластеру slurm, где я построил mpi4py (для python 2.7) против их реализации OpenMPI с помощью mpicc. Затем я отправляю следующий сценарий отправки с sbatch --exclusive mysub.sbatch :

 #!/bin/bash
#SBATCH -p par-multi
#SBATCH -n 50
#SBATCH --mem-per-cpu=8000
#SBATCH -t 48:00:00
#SBATCH -o %j.log
#SBATCH -e %j.err

module add eb/OpenMPI/gcc/3.1.1

mpirun python ./myscript.py
  

который должен разделить задачи на 50 процессоров, каждому из которых выделено 8 ГБ памяти.
Мой код выполняет что-то вроде следующего:

 import numpy as np
import pickle
import mpi4py

COMM = MPI.COMM_WORLD

def split(container, count):
    return [container[_i::count] for _i in range(count)]
    
def read():
    #function which reads a series of pickle files from my home directory
    return data
    
def function1():
    #some process 1
    return f1

def function2():
    #some process 2
    return f2

def main_function(inputs):
    #some process which also calls function1 and function2
    f1 = function1(inputs)
    f2 = function2(f1)
    result = #some more processing
    return result
    
### define global variables and read data ###
data = read()
N = 5000
#etc...

selected_variables = range(N)

if COMM.rank == 0:
    splitted_jobs = split(selected_variables, COMM.size)
else:
    splitted_jobs = None

scattered_jobs = COMM.scatter(splitted_jobs, root=0)

results = []
for index in scattered_jobs:
    outputs = main_function(data[index])
    results.append(outputs)
results = COMM.gather(results, root=0)
        
if COMM.rank == 0:
    all_results = []
    for r in results:
        all_results.append(r)
        
    f = open('result.pkl','wb')
    pickle.dump(np.array(all_results),f,protocol=2)
    f.close()
  

Максимальное время выполнения, которое я могу выделить для своей работы, составляет 48 часов, и в этот момент работа даже не завершена. Кто-нибудь может сказать мне, есть ли что-то в моем сценарии отправки или в моем коде, что, вероятно, приводит к тому, что это происходит очень медленно?

Спасибо

Комментарии:

1. Вы выполняли одно и то же (однопроцессорное) задание в кластере? Сначала убедитесь, что выполнение 50 задач MPI (на одном узле?) Не вызывает подкачки памяти. Затем начните с печати каждого ранга COMM.rank и COMM.size . Если это то, что вы ожидаете, то пусть каждый ранг распечатает его scattered_jobs , чтобы убедиться splitamp;scatter , что он сделал то, что вы ожидаете. Имейте в виду, что если ваша работа связана с памятью, выполнение многих задач на одном узле будет плохо масштабироваться..

2. Спасибо за ваш ответ, Жиль. Я попытался запустить одно и то же задание одного процесса в кластере, и оно также страдает от очень длительного времени выполнения. Я не уверен, как проверить обмен памятью, но я провел некоторое расследование, которое показало, что мне на самом деле не нужно 8 ГБ на процессор, поэтому я попытался запустить его снова с меньшим объемом памяти (безуспешно). Для 50 процессоров задание по умолчанию назначается для выполнения на 3 узлах. Я также попытался увеличить это до 5 узлов, но все равно безуспешно. Печать COMM.rank COMM.size и scattered_jobs возвращает то, что я ожидаю, поэтому я не уверен, куда идти дальше.

3. Вы выполняли в кластере одну задачу MPI?

4. ах, нет, это было как последовательное задание. Я буду работать с одной задачей MPI и отчитываться

5. Если одно и то же последовательное задание выполняется в кластере намного медленнее, тогда вы можете исключить MPI. Является ли ваша работа интенсивным вводом-выводом? Вы один на данном узле кластера? Как насчет поколений процессоров, тактовых частот и турбо-режима, если это применимо?