Skip to content

新增crun -u, --unbuffered #553

@haofangTu-bot

Description

@haofangTu-bot

1、功能描述
当你使用srun启动一个任务时,Slurm的slurmstepd守护进程会在计算节点上启动你的程序。它会创建一个管道 (pipe) 来捕获程序的stdout和stderr,然后将这些输出转发回调用srun的终端。因为程序的stdout现在是连接到一个管道,而不是一个交互式终端,glibc会自动将其设置为全缓冲。如果你的程序是逐步产生输出的(例如,每完成一步计算就打印一行日志),你将无法实时看到这些输出。所有的输出都会被暂存在缓冲区里,直到程序结束或者缓冲区被填满时,你才会一次性地看到所有结果。这对于调试和实时监控作业进度非常不便。

--unbuffered 的作用:
--unbuffered 或 -u 参数告诉srun改变其I/O处理方式。它不再使用标准的管道,而是为你的任务分配一个伪终端 (Pseudo Terminal, PTY)。当你的程序在PTY中运行时,它会“认为”自己正在与一个交互式终端对话。因此,glibc会自动将stdout的缓冲模式切换为行缓冲。

总结:

  • 默认 (srun my_app): stdout -> pipe -> 全缓冲 -> 输出延迟,最后集中显示。
  • 使用 (srun -u my_app): stdout -> PTY -> 行缓冲 -> 输出实时,每行(遇到\n)都会显示。

2、输出交错

  • 这是使用-u时最常见的问题。当你有多个任务(srun -n > 1)并且它们都实时输出时,来自不同任务的输出行会严重混合交错在一起,导致输出难以阅读。
  • 解决方法:
    • 添加任务号前缀: 修改你的程序,让每一行输出都以任务ID(如Slurm_PROCID环境变量)作为前缀。Slurm提供了--label选项来自动完成这件事,它会在每一行输出前加上任务号:。

参考文档:https://slurm.schedmd.com/srun.html
调研文档:https://e26ruh1viz.feishu.cn/wiki/XVfowM0tjii6GNk8RNHcVKWQn3g

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions