subprocess.run() 在第二次迭代时失败

我想进行统计模型的在线(主动)学习。

这意味着在编译时我有一个已知的初始训练数据集(x-y对)。

然而,由于其在线(主动)的性质,更多的数据会在运行时从第三方程序(一个C++仿真程序)中获取。

我在Python中使用GPytorch进行这项工作,并通过subprocess Python模块调用第三方程序。

我的问题属于编程类型,而不是GPytorch或统计类型,因此我在这里提问。

工作流程是:Python决定以哪些输入参数运行.cpp,创建一个基于这些参数命名的新文件夹,进入该文件夹,运行.cpp,收集文件夹中出现的数据,更新统计模型,Python决定以哪些输入参数运行.cpp,创建一个基于这些参数命名的新文件夹,进入该文件夹,运行.cpp,收集文件夹中出现的数据,更新统计模型…(例如,重复100次)。

在WSL1终端中,我通常使用以下命令运行.cpp代码:$ mpirun -n 1 smilei namelist.py,这个命令在包含可执行文件smilei和.py文件namelist.py的文件夹中运行。

Python工作流程在主动学习循环的第一次迭代时返回退出码0(和必要的数据),但在第二次迭代时失败并返回退出码1。基本上,它在第一次迭代时完成了工作,但在第二次迭代时失败了。

我尝试使用subprocess.run()os.system()(见下面的代码,所有的尝试都以注释开头),在括号内我输入了通常在BASH WindowsSubsytemForLinux1终端中运行第三方C++程序的命令。

我无法调试为什么第二次会失败。

我尝试打印出子进程的stdoutstderr,在第二次迭代的主动学习循环中查询时,它们都返回空行,似乎没有这些(没有stdout和stderr)。

我知道下面的代码可能看起来很复杂,但其实不然。它只是遵循了我上面提到的工作流程。

def SMILEI(I):    os.chdir(top_folder_path)# 创建一个新文件夹,命名为a0_942.782348987103(示例值)    a0 = "%.13f" % a0_from_IntensityWcm2(I)    dirname = "a0_%.13f" % a0_from_IntensityWcm2(I)    os.mkdir(dirname)# 进入创建的文件夹    os.chdir(top_folder_path + "/" + dirname)    print("我们已更改目录并进入了新创建的文件夹!")# 将通用namelist复制到这个新创建的文件夹中    shutil.copy(top_folder_path + "/" + general_namelist_name, ".")    print("我们已复制了通用namelist!")# 在通用namelist中添加a0值,即在第8行(空行)添加一行a0 = 942.782348987103。    with open(general_namelist_name, 'r+') as fd:        contents = fd.readlines()        contents.insert(8, "a0 = {}".format(a0))  # 新字符串应该以换行符结束        fd.seek(0)  # readlines消耗了迭代器,因此我们需要重新开始        fd.writelines(contents)  # 不需要截断,因为我们正在增加文件大小    print("我们已修改通用namelist以包含第8行的a0 = ...")# 重命名修改后的namelist    os.rename(general_namelist_name, particular_namelist_name)    print("我们已将通用namelist重命名为namelist_Xe_GPtrial_noOAM_a0included.py")# 运行仿真    print("我们现在将在文件夹内运行SMILEI命令:")    print(os.getcwd())    print("根据os指示的smilei可执行文件的绝对路径是:")    print(os.path.abspath("../smilei"))    cp = subprocess.run(["mpirun", "-n", "1", os.path.abspath("../smilei"), particular_namelist_name],                                 # stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.PIPE)                            #stdout=subprocess.PIPE, stderr=subprocess.PIPE)                            #capture_output=True)                        )    print("返回代码是:")    print(cp.returncode)    #os.system("mpirun -n 1 ../smilei {}".format(particular_namelist_name))             #subprocess.run("mpirun -n 1 ../smilei {}".format(particular_namelist_name), shell=True)            #print(cp.stdout) # Y    #print(cp.stderr)    #print(cp.returncode) # 获取仿真结果    # os.chdir(top_folder_path + "/" + dirname)    # print("我们再次更改了目录并再次进入了新创建的文件夹!")    S = happi.Open(".")    pbb = S.ParticleBinning(0).get()    results_dict = dict()    for z in range(len(pbb['data'][-1])):        results_dict['c_%d' % z] = pbb['data'][-1][z]    return np.asarray(list(results_dict.values()))if __name__ == '__main__':    # 初始训练数据集:    x_train = torch.from_numpy(np.array([0.1, 0.3, 0.5, 0.6, 0.8]))    y_train = torch.from_numpy(np.array([0.1, 0.2, 0.3, 0.4, 0.5]))    # 初始化似然和模型    likelihood = gpytorch.likelihoods.GaussianLikelihood()    model = ExactGPModel(x_train, y_train, likelihood)    model.train()    likelihood.train()    # GPs的"损失" - 边际对数似然    mll = gpytorch.mlls.ExactMarginalLogLikelihood(likelihood, model)    optimizer = torch.optim.Adam(model.parameters(), lr=0.1)      training_iters = 10    for i in range(training_iters):        optimizer.zero_grad()        output = model(x_train)        loss   = - mll(output, y_train)        loss.backward()        print('迭代 %d/%d' % (i+1, training_iters))        optimizer.step()    Xn = x_train    Yn = y_train    ######################################################################################    # 主动学习(AL)循环:    budget_value = 100    for i in range(budget_value):        OldValues = lhs(1, samples=100)        Xref = range_transform(OldValues, 10.0**20, 10.0**25)        x_nplus1 = xnp1search(model, Xn, Xref) # x_nplus1是下一次运行SMILEI进行主动学习GP拟合的强度(W/cm2)        y_nplus1 = SMILEI(x_nplus1.detach().numpy())[53] # SMILEI(x_nplus1.detach().numpy())返回一个形状为(55,)的ndarray        Xn = torch.cat(   ( Xn, torch.reshape(x_nplus1, (1,)) )   )        Yn = torch.cat(   ( Yn, torch.reshape(torch.from_numpy(np.reshape(y_nplus1, (1,))), (1,)) )   )        model.set_train_data(Xn, Yn, strict=False)        for j in range(training_iters):            optimizer.zero_grad()            output = model(Xn)            loss = -mll(output, Yn)            loss.backward()            print('迭代 %d/%d' % (j+1, training_iters) + '在AL步骤号 %d/%d' % (i+1, budget_value))            optimizer.step()

为什么第二次会失败?

我实在看不出来。我也无法调试它,我没有得到任何错误消息或任何东西,它只是在第二个创建的文件夹中不运行仿真,该文件夹在Python脚本结束时只包含namelist_Xe_GPtrial_noOAM_a0included.py,其中包含了a0值(正如它应该的那样)。

谢谢!


回答:

我自己使用plumbum模块解决了这个问题。

我的代码保持不变,它们都很好。

然而,我修改了subprocess.run()命令,或者我尝试过的许多变体,改为smi = local.cmd.mpirun,然后smi("-n", "1", "../smilei", particular_namelist_name),我可以在循环的每次迭代中运行它!

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注