使用 OpenMP 将循环划分为独特的任务
Partitioning a loop into unique tasks using OpenMP
如果这个问题之前已经回答过,请原谅,我不知道哪些是正确的关键字。
我想 运行 使用 openmp 并行调用 linux 命令。我需要以某种方式保证每个工作人员等到命令完成并且命令可能需要不同的时间才能完成。为了简化问题,我试图生成命令将 运行 对其执行的文件的名称,但每个文件名都生成了不止一次,但文件名是唯一的。我如何修改以下代码行以使用 OpenMP 通过文件名实现唯一调用(因此对命令进行唯一调用)?
omp_set_num_threads(8);
#pragma omp parallel for private(command, dirname) shared(i_traj) schedule(dynamic)
for(i_traj=0; i_traj<G.size(); i_traj++)
{
//command will contain the comand line.
snprintf(dirname1,sizeof(dirname1), "ID%i_Trajectory_%i",ID,G[i_traj].ID);
dirname = string(dirname1);
/*Initializing the trajectories*/
cout<<"Going to: "<<G[i_traj].folder_addr<<endl;
}
这部分代码将在函数中执行,而不是在主程序中执行。可以使用 MPICH2 做同样的事情吗?
更新:
问题与我的计算机有关,而不是与代码有关,因为代码可以在另一台机器上正常工作。有什么建议吗?
升级:
为了遵循 Gilles 的建议,我将代码升级如下:
#include <iostream>
#include <string>
using namespace std;
#define LARGE_NUMBER 100
double item[LARGE_NUMBER];
void process(int ID, nucleus &tr)
{
char dirname1[40];
string command;
string script_folder;
snprintf(dirname1,sizeof(dirname1), "ID%i_Trajectory_%i",ID,tr.ID);
string dirname;
dirname = string(dirname1);
/*Initializing the trajectories*/
cout<<"Running: "<<dirname<<endl;
script_folder = "./"+ dirname;
chdir(script_folder.c_str());
//command = "qsub " + dirname+"_PBS" + ".sh";
command = "gamess-2013 " + dirname + ".inp 01 1 ";
printf ("Checking if processor is available...");
if (system(NULL)) puts ("Ok");
else exit (EXIT_FAILURE);
if(!tr.runned)
{
int fail= system(command.c_str());
tr.runned=true;
}
chdir("../");
return;
}
int main() {
#pragma omp parallel
{
#pragma omp single
{
int i;
for (i=0; i<LARGE_NUMBER; i++)
#pragma omp task
// i is firstprivate, item is shared
process(i);
}
}
return 0;
}
但是保证每个文件只处理一次的问题依然存在。我如何确保每个任务都在一个唯一的文件上工作,等待命令执行完成?
抱歉,我真的不明白你问的问题,也不明白它的上下文。这句话尤其让我百思不得其解:
To simplify the issue, I am trying to generate the names of the files on which the command will run but each file name is been generated more than once, but the names of the file are unique.
总之,说了这么多我的回答很可能没有抓住要点。但是,我仍然可以报告您的代码片段存在一个主要问题:您明确声明 shared
您尝试并行化的循环的索引 i_traj
。这没有任何意义,因为如果您希望在 OpenMP 并行循环中有一个变量 private
,那么这就是循环索引。此外,OpenMP 标准明确禁止它 section 2.14.1.1。 (重点是我的)
The loop iteration variable(s) in the associated for-loop(s) of a for
or parallel for construct is (are) private.
[...]
Variables with predetermined data-sharing attributes may not be listed
in data-sharing attribute clauses, except for the cases listed below.
For these exceptions only, listing a predetermined variable in a
data-sharing attribute clause is allowed and overrides the variable’s
predetermined data-sharing attributes.
遵循例外列表,其中未提及 shared
"loop iteration variable(s)"。
再说一次,我的回答可能完全没有抓住要点,但你肯定有问题,你最好在尝试更深入之前解决这个问题。
如果这个问题之前已经回答过,请原谅,我不知道哪些是正确的关键字。
我想 运行 使用 openmp 并行调用 linux 命令。我需要以某种方式保证每个工作人员等到命令完成并且命令可能需要不同的时间才能完成。为了简化问题,我试图生成命令将 运行 对其执行的文件的名称,但每个文件名都生成了不止一次,但文件名是唯一的。我如何修改以下代码行以使用 OpenMP 通过文件名实现唯一调用(因此对命令进行唯一调用)?
omp_set_num_threads(8);
#pragma omp parallel for private(command, dirname) shared(i_traj) schedule(dynamic)
for(i_traj=0; i_traj<G.size(); i_traj++)
{
//command will contain the comand line.
snprintf(dirname1,sizeof(dirname1), "ID%i_Trajectory_%i",ID,G[i_traj].ID);
dirname = string(dirname1);
/*Initializing the trajectories*/
cout<<"Going to: "<<G[i_traj].folder_addr<<endl;
}
这部分代码将在函数中执行,而不是在主程序中执行。可以使用 MPICH2 做同样的事情吗?
更新: 问题与我的计算机有关,而不是与代码有关,因为代码可以在另一台机器上正常工作。有什么建议吗?
升级:
为了遵循 Gilles 的建议,我将代码升级如下:
#include <iostream>
#include <string>
using namespace std;
#define LARGE_NUMBER 100
double item[LARGE_NUMBER];
void process(int ID, nucleus &tr)
{
char dirname1[40];
string command;
string script_folder;
snprintf(dirname1,sizeof(dirname1), "ID%i_Trajectory_%i",ID,tr.ID);
string dirname;
dirname = string(dirname1);
/*Initializing the trajectories*/
cout<<"Running: "<<dirname<<endl;
script_folder = "./"+ dirname;
chdir(script_folder.c_str());
//command = "qsub " + dirname+"_PBS" + ".sh";
command = "gamess-2013 " + dirname + ".inp 01 1 ";
printf ("Checking if processor is available...");
if (system(NULL)) puts ("Ok");
else exit (EXIT_FAILURE);
if(!tr.runned)
{
int fail= system(command.c_str());
tr.runned=true;
}
chdir("../");
return;
}
int main() {
#pragma omp parallel
{
#pragma omp single
{
int i;
for (i=0; i<LARGE_NUMBER; i++)
#pragma omp task
// i is firstprivate, item is shared
process(i);
}
}
return 0;
}
但是保证每个文件只处理一次的问题依然存在。我如何确保每个任务都在一个唯一的文件上工作,等待命令执行完成?
抱歉,我真的不明白你问的问题,也不明白它的上下文。这句话尤其让我百思不得其解:
To simplify the issue, I am trying to generate the names of the files on which the command will run but each file name is been generated more than once, but the names of the file are unique.
总之,说了这么多我的回答很可能没有抓住要点。但是,我仍然可以报告您的代码片段存在一个主要问题:您明确声明 shared
您尝试并行化的循环的索引 i_traj
。这没有任何意义,因为如果您希望在 OpenMP 并行循环中有一个变量 private
,那么这就是循环索引。此外,OpenMP 标准明确禁止它 section 2.14.1.1。 (重点是我的)
The loop iteration variable(s) in the associated for-loop(s) of a for or parallel for construct is (are) private.
[...]
Variables with predetermined data-sharing attributes may not be listed in data-sharing attribute clauses, except for the cases listed below. For these exceptions only, listing a predetermined variable in a data-sharing attribute clause is allowed and overrides the variable’s predetermined data-sharing attributes.
遵循例外列表,其中未提及 shared
"loop iteration variable(s)"。
再说一次,我的回答可能完全没有抓住要点,但你肯定有问题,你最好在尝试更深入之前解决这个问题。