我们学校的 HPC 没有调度程序。所以没有什么比作业队列更好的了。因此,我无法通过qsub
或自动化并行作业提交sbatch
。
我一直用来“提交”作业的方法是使用 screen: type screen
,然后按Enter,然后键入./runMyJob.sh
,然后按CTRL+ ,a然后按d分离。
现在我希望自动化/脚本化启动多个并行屏幕会话的过程,然后在每个会话中运行一个作业,最后分离所有屏幕会话。
正如您所看到的,在手动操作期间,我按下了Enter和CTRL+ a,然后按下了d。如何编写这些按键操作的脚本?
PS:非常欢迎任何有助于在没有调度程序的 HPC 中实现并行作业提交的建议!
答案1
不要将其视为按键,而是将其视为完成任务。按键是一种交互方式。自动完成任务的方法是编写脚本。
要在屏幕中启动作业并立即将其分离,请运行
screen -md ./runMyJob.sh
如果您想让您的工作更容易找到,您可以通过-S
设置会话名称的选项。
例如,您可以编写以下脚本,该脚本使用作业可执行文件的名称作为会话名称:
#!/bin/sh
screen -md -S "${1##*/}" "$@"
将其命名为类似submit
,将其放在 PATH 上的目录中(单用户二进制安装位置?和如何添加 Unix 哪个命令发现的主目录路径?可能有帮助),使其可执行(chmod +x ~/bin/submit
)。要开始工作,请运行
submit ./runMyJob.sh
对于并行执行,您可能需要调查GNU并行。
请注意,作业提交框架的作用不仅仅是启动作业。它还安排它们在有可用 CPU 时间和内存的地方运行,并将日志发送给提交者。您应该要求您的管理员建立适当的作业提交框架。
答案2
Enter, Ctrl-a并d生成正常的 ASCII 代码。
pipe()
因此,一个可能的解决方案可能是创建一个未命名管道( )的程序,然后fork()
创建一个子进程,该子进程首先将管道的读取端绑定到其标准输入,然后screen
在子进程(execve()
或类似进程)中执行。如果该程序已启动,您可以将启动进程所需的命令行写入所创建管道的写入端。
如何将任务放入该程序中是另一个主题。例如,您可以自己编写一个小型调度程序(类似于作业队列和一些并行启动最多 N 个进程的代码)。
==编辑==
对于 Linux(或者也可能是一些 UN*X),程序可能如下所示:
#include <sys/types.h>
#include <sys/linux.h>
#include <unistd.h>
int main(void) {
int fds[2] = {0};
pid_t pid = 0;
pipe(fds); /* Creates an unnamed pipe */
pid = fork(); /* Forks a new process */
if (pid == 0) {
static char const *argv[] = {"/usr/bin/screen", NULL};
/* Note: The array might need to be changed,
* depending on your requirements
* (eg. command-line arguments)
*/
dup2(fds[0], stdin); /* Binds the read end of the pipe to stdin */
execve(argv[0], argv, NULL);
/* If you reach this point, your execve() failed */
}
sleep(1); /* Waits for the child process to execute
* screen */
char const data[] = "./MyJob.sh\n\x00d";
/* Note: You must replace the '\x00' by the
* ASCII code of C-a!
*/
write(fds[1], data, sizeof(data));
/* Writes the name of the job along with the
* control codes to the child process
*/
int retcode = 0;
waitpid(pid, &retcode, 0);
/* Waits for the child process to terminate */
/* Note: WEXITSTATUS(retcode) gets the exit
* status of the child process */
return 0;
}
这个程序应该说明这个想法,它缺乏必要的错误处理。