Многопроцессорность в Python и обработка отдельных сеансов Linux для каждого процесса с использованием экрана.Linux

Ответить
Anonymous
 Многопроцессорность в Python и обработка отдельных сеансов Linux для каждого процесса с использованием экрана.

Сообщение Anonymous »

Я работаю над программой моделирования, для которой хочу распараллелить свою машину. Для каждой симуляции мне нужно настроить выделенные исходные файлы, и поэтому я подумал, что лучше всего использовать экран GNU/Linux для каждого подпроцесса bash, чтобы я мог выполнять специальные операции для запуска симуляции. Ниже run_queue содержит последнюю команду моделирования, которая будет вызываться в каждом подпроцессе screen.

Код: Выделить всё

    def exec_sim(self) -> None:
"""
Execute the simulation for all entries in the simulation dictionary,
ensuring recompilation and sourcing of the detector environment in each subprocess.
"""

# prepare the run queue
run_queue = [
# sim_cmd has according pixel ip6 XML file
(sim_cmd, paths['sim_shell_path'], paths['sim_det_path'])
for px_key, paths in self.sim_dict.items()
for sim_cmd in paths['px_ddsim_cmds']
]

with ProcessPoolExecutor(max_workers=os.cpu_count()) as executor:
future_to_cmd = {executor.submit(self.run_cmd, cmd): cmd for cmd in run_queue}
for future in concurrent.futures.as_completed(future_to_cmd):
cmd = future_to_cmd[future]
try:
future.result()  # handle success
self.printlog(f"Simulation completed for command: {cmd[0]}")
except Exception as e:
self.printlog(f"Simulation failed for command {cmd[0]}: {e}", level="error")

Код: Выделить всё

    def run_cmd(self, curr_cmd: Tuple[str, str, str]) -> None:
sim_cmd, shell_file_path, det_path = curr_cmd

# determine the pixel folder for logging
logger = self.subprocess_log(os.path.join(os.path.dirname(det_path), "..", "subprocess.log"))

try:
# define the name for the screen session
screen_name = f"sim_{det_path}"

# enter shell, recompile, and source the detector
enter_eic_shell = self.eic_shell_cmd()
recompile = self.recompile_det_cmd(det_path, "recompile")
source = self.source_det_cmd(shell_file_path)

# combine all steps into a single command sequence
commands = [
"set -e",  # exit on error
*enter_eic_shell,
*recompile,
*source,
f"echo 'Running simulation command: {sim_cmd}'",
sim_cmd  # execute simulation command
]

# form the command to run in a screen
full_cmd = " && ".join(commands)
screen_cmd = f"screen -dmS {screen_name} bash -c '{full_cmd}; screen -X -S {screen_name} quit'"

logger.info(f"Starting subprocess in screen session: {screen_name}")

# execute the screen command
result = subprocess.run(
["bash", "-c", screen_cmd],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
check=True
)

if result.returncode == 0:
logger.info(f"Screen session {screen_name} started successfully.")
else:
logger.error(f"Failed to start screen session {screen_name}.\nError: {result.stderr}")

except subprocess.CalledProcessError as e:
logger.error(f"Error during execution: {e.stderr}")
raise RuntimeError(f"Execution failed.  Error: {e.stderr}")
except Exception as e:
logger.error(f"Unexpected error: {str(e)}")
raise
Настройка моделирования, которую я хочу запустить в подпроцессе экрана, следующая:

Код: Выделить всё

    def recompile_det_cmd(self, det_path, compile_method: str) -> str:

# define the build directory
build_path = os.path.join(det_path, "build")

# determine the compile operation
if compile_method == "clean":
compile_method = [
f"cd {build_path}",
"make clean"
]
elif compile_method == "recompile":
compile_method = [
f"rm -rf {build_path}",
f"mkdir -p {build_path} && cd {build_path}"
]
else:
raise ValueError(f"Invalid compile method: {compile_method}. Choose between 'clean' (make clean) and 'recompile' (rm -rf build).")

# define recompile commands
recompile_cmd = [
f"echo 'Starting build process for detector at {det_path}'",
*compile_method,
"cmake ..",
"make -j$(nproc)",
f"echo 'Build process completed for {det_path}'"
]

return recompile_cmd

Код: Выделить всё

    def source_det_cmd(self, shell_file_path) -> None:
source_cmd = [
f"source '{shell_file_path}'",
f"echo 'Sourced shell script: {shell_file_path}'"
]

return source_cmd

def eic_shell_cmd(self) -> None:
eic_shell_cmd = [
"PREV_DIR=$(pwd)", # store the current directory
f"cd {self.eic_shell_path}",
"./eic-shell",
"cd $PREV_DIR" # return to the original directory
]

return eic_shell_cmd
Это так; для каждого подпроцесса sceeen я вхожу в среду сингулярности, перекомпилирую файл make, создаю файл оболочки и только затем запускаю команду из run_queue для моделирования.
Когда я пытаюсь вызвать приведенный выше файл Python, находясь в сингулярности моего основного сеанса Ubuntu, я получаю

Код: Выделить всё

2024-12-14 00:49:53,619 - INFO - Starting subprocess in screen session: sim_/data/tomble/Analysis_epic_new/simulations/simEvents/0.1x0.1px/epic
2024-12-14 00:49:53,629 - ERROR - Error during execution: bash: line 1: screen: command not found

Simulation failed for command ddsim --inputFiles /data/tomble/Analysis_epic_new/simulations/genEvents/results/results/beamEffectsElectrons_20.hepmc --outputFile /data/tomble/Analysis_epic_new/simulations/simEvents/0.1x0.1px/output_20edm4hep.root --compactFile /data/tomble/Analysis_epic_new/simulations/simEvents/0.1x0.1px/epic/install/share/epic/epic_ip6_extended.xml -N 5: Execution failed. Error: bash: line 1: screen: command not found
Это потому, что у меня нет экрана внутри сингулярности, поэтому в вызовах подпроцесса я сначала использую экран перед входом в сингулярность.
Тем не менее, вызов файла Python извне сингулярности все равно не помогает:

Код: Выделить всё

2024-12-14 00:26:22,668 - ERROR - Error during execution:
2024-12-14 00:26:22,676 - ERROR - Simulation failed for command ddsim --inputFiles /data/tomble/Analysis_epic_new/simulations/genEvents/results/results/beamEffectsElectrons_20.hepmc --outputFile /data/tomble/Analysis_epic_new/simulations/simEvents/0.1x0.1px/output_20edm4hep.root --compactFile /data/tomble/Analysis_epic_new/simulations/simEvents/0.1x0.1px/epic/install/share/epic/epic_ip6_extended.xml -N 5: Execution failed. Error:
Simulation failed for command ddsim --inputFiles /data/tomble/Analysis_epic_new/simulations/genEvents/results/results/beamEffectsElectrons_20.hepmc --outputFile /data/tomble/Analysis_epic_new/simulations/simEvents/0.1x0.1px/output_20edm4hep.root --compactFile /data/tomble/Analysis_epic_new/simulations/simEvents/0.1x0.1px/epic/install/share/epic/epic_ip6_extended.xml -N 5: Execution failed. Error:
Что я делаю не так? Как я могу правильно выполнить многопроцессорную обработку с помощью экрана для описанного мной случая? Есть ли лучший способ открыть подпроцессы Linux из Python, кроме экрана?


Подробнее здесь: https://stackoverflow.com/questions/792 ... ry-process
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Linux»