diff --git a/libs/lib_criteria.py b/libs/lib_criteria.py index 5385028..43d02aa 100644 --- a/libs/lib_criteria.py +++ b/libs/lib_criteria.py @@ -395,6 +395,9 @@ def uncert_strconvter(value): """ if value == '---- ': return value + if isinstance(value, np.float32): + value = float(value) + return '{:.5e}'.format(Decimal(value)) diff --git a/libs/lib_input.py b/libs/lib_input.py index 0256788..2b8d08c 100644 --- a/libs/lib_input.py +++ b/libs/lib_input.py @@ -49,6 +49,9 @@ def __init__(self, input_file='input.in'): self.output_format = 'trajectory.son' ##[Active learning setting] + + self.MLIP = 'nequip' + # nstep: int # The number of subsampling sets self.nstep = 1 @@ -184,6 +187,41 @@ def __init__(self, input_file='input.in'): # Recommend to use the ground state total energy. self.E_gs = 0.0 + ##[so3krates setting] + self.r_cut = 5.0 + self.l = 3 + self.f = 132 + self.l_min = 1 + self.l_max = 3 + self.max_body_order = 2 + self.f_body_order = 1 + self.we = 0.01 # weight-energy + self.wf = 1.00 # weight-forces + self.ws = 'None' # weight-stress + self.loss_variance_scaling = '--no-loss-variance-scaling' + self.epochs = 2000 + self.eval_energy_t = 'None' + self.mic = '--mic' + self.float64 = '--no-float64' + self.lr = 0.001 + self.lr_stop = 0.00001 + self.lr_decay_exp_transition_steps = 100000 + self.lr_decay_exp_decay_factor = 0.7 + self.clip_by_global_norm = 'None' + self.shift_mean = '--shift-mean' + self.size_batch = 'None' + self.size_batch_training = 'None' + self.size_batch_validation = 'None' + # self.seed_model = 0 + self.seed_data = 0 + self.seed_training = 0 + self.wandb_name = 'None' + self.wandb_group = 'None' + self.wandb_project = 'None' + # self.outfile_inputs = 'inputs.json' + self.overwrite_module = '--no-overwrite-module' + self.ace = '--no-ace' + ##[Constants] # kB: float # Boltzmann constant in units of eV/K @@ -214,6 +252,8 @@ def __init__(self, input_file='input.in'): # ntotal: Total number of added training and valdiation data for all subsamplings for each iteractive step self.ntotal = (self.ntrain + self.nval) * self.nstep + self.train_split = self.ntrain/(self.ntrain + self.nval) + ### Initization of parameters # index: int # The index of AL interactive steps diff --git a/libs/lib_load_model.py b/libs/lib_load_model.py index 65b5ee0..4326794 100644 --- a/libs/lib_load_model.py +++ b/libs/lib_load_model.py @@ -3,6 +3,8 @@ from nequip.ase import nequip_calculator from libs.lib_util import mpi_print +from glp import instantiate +from glp.ase import Calculator import torch torch.set_default_dtype(torch.float64) @@ -22,17 +24,23 @@ def load_model(inputs): for index_nmodel in range(inputs.nmodel): for index_nstep in range(inputs.nstep): if (index_nmodel * inputs.nstep + index_nstep) % inputs.size == inputs.rank: - dply_model = f'deployed-model_{index_nmodel}_{index_nstep}.pth' - if os.path.exists(f'{workpath}/{dply_model}'): - mpi_print(f'\t\tFound the deployed model: {dply_model}', rank=0) - inputs.calc_MLIP.append( - nequip_calculator.NequIPCalculator.from_deployed_model(f'{workpath}/{dply_model}', device=inputs.device) - ) - else: - # If there is no model, turn on the termination signal - mpi_print(f'\t\tCannot find the model: {dply_model}', rank=0) - signal = 1 - signal = inputs.comm.bcast(signal, root=inputs.rank) + + if inputs.MLIP == 'nequip': + dply_model = f'deployed-model_{index_nmodel}_{index_nstep}.pth' + if os.path.exists(f'{workpath}/{dply_model}'): + mpi_print(f'\t\tFound the deployed model: {dply_model}', rank=0) + inputs.calc_MLIP.append( + nequip_calculator.NequIPCalculator.from_deployed_model(f'{workpath}/{dply_model}', device=inputs.device) + ) + else: + # If there is no model, turn on the termination signal + mpi_print(f'\t\tCannot find the model: {dply_model}', rank=0) + signal = 1 + signal = inputs.comm.bcast(signal, root=inputs.rank) + elif inputs.MLIP == 'so3krates': + potential_dict = {"mlff": {"folder": f"{workpath}/deployed-model_{index_nmodel}_{index_nstep}"}} + get_calculator = instantiate.get_calculator(potential_dict, {"atom_pair": {"skin": 0.1}}) + inputs.calc_MLIP.append(Calculator(get_calculator)) # Check the termination signal if signal == 1: diff --git a/libs/lib_mainloop.py b/libs/lib_mainloop.py index ba877b7..e6da0ee 100644 --- a/libs/lib_mainloop.py +++ b/libs/lib_mainloop.py @@ -2,7 +2,7 @@ from ase.io.trajectory import TrajectoryWriter import os -import son +from vibes import son import copy import random import numpy as np diff --git a/libs/lib_mainloop_new.py b/libs/lib_mainloop_new.py index aa3268b..2cb56e7 100644 --- a/libs/lib_mainloop_new.py +++ b/libs/lib_mainloop_new.py @@ -3,7 +3,7 @@ from ase.io.bundletrajectory import BundleTrajectory import os -import son +from vibes import son import copy import random import numpy as np diff --git a/libs/lib_npz.py b/libs/lib_npz.py index d6c7af3..e41a0e5 100644 --- a/libs/lib_npz.py +++ b/libs/lib_npz.py @@ -103,11 +103,19 @@ def generate_npz_DFT_init(inputs, traj, workpath): 'F': np.array(F_train_store), 'R': np.array(R_train_store), 'z': np.array(z_train_store), - 'CELL': np.array(CELL_train_store), - 'PBC': np.array(PBC_train_store), 'sigma': np.array(sigma_train_store) } + if inputs.MLIP == 'nequip': + arrays_to_save['CELL'] = np.array(CELL_train_store) + arrays_to_save['PBC'] = np.array(PBC_train_store) + elif inputs.MLIP == 'so3krates': + arrays_to_save['unit_cell'] = np.array(CELL_train_store) + arrays_to_save['pbc'] = np.array(PBC_train_store) + else: + arrays_to_save['CELL'] = np.array(CELL_train_store) + arrays_to_save['PBC'] = np.array(PBC_train_store) + if inputs.ensemble == 'NPTisoiso' or inputs.train_stress: arrays_to_save['stress'] = np.array(stress_train_store) @@ -346,11 +354,19 @@ def generate_npz_DFT(inputs, workpath): 'F': np.array(F_train_store), 'R': np.array(R_train_store), 'z': np.array(z_train_store), - 'CELL': np.array(CELL_train_store), - 'PBC': np.array(PBC_train_store), 'sigma': np.array(sigma_train_store), } + if inputs.MLIP == 'nequip': + arrays_to_save['CELL'] = np.array(CELL_train_store) + arrays_to_save['PBC'] = np.array(PBC_train_store) + elif inputs.MLIP == 'so3krates': + arrays_to_save['unit_cell'] = np.array(CELL_train_store) + arrays_to_save['pbc'] = np.array(PBC_train_store) + else: + arrays_to_save['CELL'] = np.array(CELL_train_store) + arrays_to_save['PBC'] = np.array(PBC_train_store) + if inputs.ensemble == 'NPTisoiso' or inputs.train_stress: arrays_to_save['stress'] = np.array(stress_train_store) @@ -468,11 +484,19 @@ def generate_npz_DFT_rand_init(inputs, traj, ntrain, nval, workpath): 'F': np.array(F_train_store), 'R': np.array(R_train_store), 'z': np.array(z_train_store), - 'CELL': np.array(CELL_train_store), - 'PBC': np.array(PBC_train_store), 'sigma': np.array(sigma_train_store) } + if inputs.MLIP == 'nequip': + arrays_to_save['CELL'] = np.array(CELL_train_store) + arrays_to_save['PBC'] = np.array(PBC_train_store) + elif inputs.MLIP == 'so3krates': + arrays_to_save['unit_cell'] = np.array(CELL_train_store) + arrays_to_save['pbc'] = np.array(PBC_train_store) + else: + arrays_to_save['CELL'] = np.array(CELL_train_store) + arrays_to_save['PBC'] = np.array(PBC_train_store) + if inputs.ensemble == 'NPTisoiso' or inputs.train_stress: arrays_to_save['stress'] = np.array(stress_train_store) @@ -626,11 +650,19 @@ def generate_npz_DFT_rand( 'F': np.array(F_train_store), 'R': np.array(R_train_store), 'z': np.array(z_train_store), - 'CELL': np.array(CELL_train_store), - 'PBC': np.array(PBC_train_store), 'sigma': np.array(sigma_train_store) } + if inputs.MLIP == 'nequip': + arrays_to_save['CELL'] = np.array(CELL_train_store) + arrays_to_save['PBC'] = np.array(PBC_train_store) + elif inputs.MLIP == 'so3krates': + arrays_to_save['unit_cell'] = np.array(CELL_train_store) + arrays_to_save['pbc'] = np.array(PBC_train_store) + else: + arrays_to_save['CELL'] = np.array(CELL_train_store) + arrays_to_save['PBC'] = np.array(PBC_train_store) + if inputs.ensemble == 'NPTisoiso' or inputs.train_stress: arrays_to_save['stress'] = np.array(stress_train_store) diff --git a/libs/lib_progress.py b/libs/lib_progress.py index e345661..65a88a9 100644 --- a/libs/lib_progress.py +++ b/libs/lib_progress.py @@ -6,7 +6,6 @@ from libs.lib_util import check_mkdir, mpi_print, single_print, generate_msg from libs.lib_criteria import get_result -from libs.lib_train import get_train_job from libs.lib_termination import get_testerror diff --git a/libs/lib_train.py b/libs/lib_train.py index 3093dc0..da6e977 100644 --- a/libs/lib_train.py +++ b/libs/lib_train.py @@ -13,114 +13,114 @@ torch.set_default_dtype(torch.float64) -def get_train_job( - inputs, struc_relaxed, ntrain, nval, workpath -): - """Function [get_train_job] - Get calculators from previously trained MLIP and - its total energy of ground state structure. - If there are unfinished trained models, - resubmit the corresponding job script. - - Parameters: - - struc_relaxed: ASE atoms - A structral configuration of a starting point - ntrain: int - The number of added training data for each iterative step - nval: int - The number of added validating data for each iterative step - rmax: float - The rmax input for NequIP - lmax: int - The lmax input for NequIP - nfeatures: int - The nfeatures input for NequIP - workpath: str - Path to the working directory - nstep: int - The number of subsampling sets - nmodel: int - The number of ensemble model sets with different initialization - - Returns: - - E_ref: float - Predicted ground state energy - calc_MLIP: - Collected calculators from trained models - """ - - # Initialization of signal - signal = 0 - # Get a current path - currentpath = os.getcwd() - - calc_MLIP = [] - for index_nmodel in range(inputs.nmodel): - job_script_input = '' - - for index_nstep in range(inputs.nstep): - dply_model = f'deployed-model_{index_nmodel}_{index_nstep}.pth' - if (index_nmodel*inputs.nstep + index_nstep) % inputs.size == inputs.rank: - # Check the existence of trained models - # If yes, collect trained models - if os.path.exists(f'{workpath}/{dply_model}'): - mpi_print(f'\t\tFound the deployed model: {dply_model}', rank=0) - calc_MLIP.append( - nequip_calculator.NequIPCalculator.\ - from_deployed_model(f'{workpath}/{dply_model}', device=inputs.device) - ) - else: # If not, prepare the training job - rm_mkdir(f'{workpath}/train_{index_nmodel}_{index_nstep}') - job_script_input += nequip_train_job( - inputs, ntrain, nval, workpath, index_nstep, index_nmodel, dply_model - ) - mpi_print(f'\t\tDeploying the model: {dply_model}', rank=0) - # Activate the termination signal - signal = 1 - signal = inputs.comm.bcast(signal, root=inputs.rank) - - job_script_input = inputs.comm.gather(job_script_input, root=0) - if inputs.rank == 0: - if job_script_input != ['' for i in range(inputs.size)]: - # Prepare ingredients for the job script - with open('./job-nequip-gpu.slurm', 'r') as job_script_initial: - job_script_default = job_script_initial.read() - - os.chdir(workpath) - # Write an input for NequIP - job_script = f'./job-nequip-gpu_{index_nmodel}.slurm' - - with open(job_script, 'w') as writing_input: - writing_input.write(job_script_default) - for job_item in job_script_input: - writing_input.write(job_item) - - # Submit the job scripts - subprocess.run([inputs.job_command, job_script]) - os.chdir(currentpath) - - # Temination check - if signal == 1: - sys.exit() - - # Get ground state energies predicted by trained models - E_inter = [] - zndex = 0 - for index_nmodel in range(inputs.nmodel): - for index_nstep in range(inputs.nstep): - if (index_nmodel*inputs.nstep + index_nstep) % inputs.size == inputs.rank: - struc_relaxed.calc = calc_MLIP[zndex] - E_inter.append(struc_relaxed.get_potential_energy()) - zndex += 1 - E_inter = inputs.comm.allgather(E_inter) +# def get_train_job( +# inputs, struc_relaxed, ntrain, nval, workpath +# ): +# """Function [get_train_job] +# Get calculators from previously trained MLIP and +# its total energy of ground state structure. +# If there are unfinished trained models, +# resubmit the corresponding job script. + +# Parameters: + +# struc_relaxed: ASE atoms +# A structral configuration of a starting point +# ntrain: int +# The number of added training data for each iterative step +# nval: int +# The number of added validating data for each iterative step +# rmax: float +# The rmax input for NequIP +# lmax: int +# The lmax input for NequIP +# nfeatures: int +# The nfeatures input for NequIP +# workpath: str +# Path to the working directory +# nstep: int +# The number of subsampling sets +# nmodel: int +# The number of ensemble model sets with different initialization + +# Returns: + +# E_ref: float +# Predicted ground state energy +# calc_MLIP: +# Collected calculators from trained models +# """ + +# # Initialization of signal +# signal = 0 +# # Get a current path +# currentpath = os.getcwd() + +# calc_MLIP = [] +# for index_nmodel in range(inputs.nmodel): +# job_script_input = '' + +# for index_nstep in range(inputs.nstep): +# dply_model = f'deployed-model_{index_nmodel}_{index_nstep}.pth' +# if (index_nmodel*inputs.nstep + index_nstep) % inputs.size == inputs.rank: +# # Check the existence of trained models +# # If yes, collect trained models +# if os.path.exists(f'{workpath}/{dply_model}'): +# mpi_print(f'\t\tFound the deployed model: {dply_model}', rank=0) +# calc_MLIP.append( +# nequip_calculator.NequIPCalculator.\ +# from_deployed_model(f'{workpath}/{dply_model}', device=inputs.device) +# ) +# else: # If not, prepare the training job +# rm_mkdir(f'{workpath}/train_{index_nmodel}_{index_nstep}') +# job_script_input += nequip_train_job( +# inputs, ntrain, nval, workpath, index_nstep, index_nmodel, dply_model +# ) +# mpi_print(f'\t\tDeploying the model: {dply_model}', rank=0) +# # Activate the termination signal +# signal = 1 +# signal = inputs.comm.bcast(signal, root=inputs.rank) + +# job_script_input = inputs.comm.gather(job_script_input, root=0) +# if inputs.rank == 0: +# if job_script_input != ['' for i in range(inputs.size)]: +# # Prepare ingredients for the job script +# with open('./job-nequip-gpu.slurm', 'r') as job_script_initial: +# job_script_default = job_script_initial.read() + +# os.chdir(workpath) +# # Write an input for NequIP +# job_script = f'./job-nequip-gpu_{index_nmodel}.slurm' + +# with open(job_script, 'w') as writing_input: +# writing_input.write(job_script_default) +# for job_item in job_script_input: +# writing_input.write(job_item) + +# # Submit the job scripts +# subprocess.run([inputs.job_command, job_script]) +# os.chdir(currentpath) + +# # Temination check +# if signal == 1: +# sys.exit() + +# # Get ground state energies predicted by trained models +# E_inter = [] +# zndex = 0 +# for index_nmodel in range(inputs.nmodel): +# for index_nstep in range(inputs.nstep): +# if (index_nmodel*inputs.nstep + index_nstep) % inputs.size == inputs.rank: +# struc_relaxed.calc = calc_MLIP[zndex] +# E_inter.append(struc_relaxed.get_potential_energy()) +# zndex += 1 +# E_inter = inputs.comm.allgather(E_inter) - # Calculate the average of ground state energies - E_ref = np.average(np.array([i for items in E_inter for i in items]), axis=0); - del E_inter; +# # Calculate the average of ground state energies +# E_ref = np.average(np.array([i for items in E_inter for i in items]), axis=0); +# del E_inter; - return E_ref, calc_MLIP +# return E_ref, calc_MLIP @@ -198,7 +198,73 @@ def nequip_train_job( # Move back to the original path os.chdir(currentpath) - return f'{job_script_extra} {nequip_input}\n{job_script_deploy} {modelpath} {deploy_model}\n' + return f'{job_script_extra} {nequip_input} --warn-unused\n{job_script_deploy} {modelpath} {deploy_model}\n' + + + +def so3krates_train_job( + inputs, ntrain, nval, workpath, index_nstep, index_nmodel, dply_model +): + so3krates_input_extra = ( + f'--ckpt-dir {dply_model} ' + + f'--r-cut {inputs.r_cut} ' + + f'--l {inputs.l} ' + + f'--f {inputs.f} ' + + f'--l-min {inputs.l_min} ' + + f'--l-max {inputs.l_max} ' + + f'--max-body-order {inputs.max_body_order} ' + + f'--f-body-order {inputs.f_body_order} ' + + f'-we {inputs.we} ' + + f'-wf {inputs.wf} ' + + f'{inputs.loss_variance_scaling} ' + + f'--epochs {inputs.epochs} ' + + f'--train-split {inputs.train_split} ' + + f'{inputs.mic} ' + + f'{inputs.float64} ' + + f'--lr {inputs.lr} ' + + f'--lr-stop {inputs.lr_stop} ' + + f'--lr-decay-exp-transition-steps {inputs.lr_decay_exp_transition_steps} ' + + f'--lr-decay-exp-decay-factor {inputs.lr_decay_exp_decay_factor} ' + + f'{inputs.shift_mean} ' + + f'--seed-model {index_nmodel} ' + + f'--seed-data {inputs.seed_data} ' + + f'--seed-training {inputs.seed_training} ' + + f'--outfile-inputs inputs_{index_nmodel}_{index_nstep}.json ' + + f'{inputs.overwrite_module} ' + + f'{inputs.ace} ' + ) + + if inputs.ws != 'None': + so3krates_input_extra += f'-ws {inputs.ws} ' + + if inputs.eval_energy_t != 'None': + so3krates_input_extra += f'--eval-every-t {inputs.eval_energy_t} ' + + if inputs.clip_by_global_norm != 'None': + so3krates_input_extra += f'--clip-by-global-norm {inputs.clip_by_global_norm} ' + + if inputs.size_batch != 'None': + so3krates_input_extra += f'--size-batch {inputs.size_batch} ' + + if inputs.size_batch_training != 'None': + so3krates_input_extra += f'--size-batch-training {inputs.size_batch_training} ' + + if inputs.size_batch_validation != 'None': + so3krates_input_extra += f'--size-batch-validation {inputs.size_batch_validation} ' + + if inputs.wandb_name != 'None': + so3krates_input_extra += f'--wandb-name {inputs.wandb_name} ' + + if inputs.wandb_group != 'None': + so3krates_input_extra += f'--wandb-group {inputs.wandb_group} ' + + if inputs.wandb_project != 'None': + so3krates_input_extra += f'--wandb-project {inputs.wandb_project} ' + + job_script_extra = 'srun sokrates_train' + so3krates_input = f'data-train_{index_nstep}.npz' + + return f'{job_script_extra} {so3krates_input_extra}{so3krates_input}\n' def execute_train_job( @@ -229,37 +295,93 @@ def execute_train_job( # Get a current path currentpath = os.getcwd() - - job_script_input = [] - for index_nmodel in range(inputs.nmodel): - for index_nstep in range(inputs.nstep): - dply_model = f'deployed-model_{index_nmodel}_{index_nstep}.pth' - if os.path.exists(f'{workpath}/{dply_model}'): - mpi_print(f'\t\tFound the deployed model: {dply_model}', inputs.rank) - else: # If not, prepare the training job - rm_mkdir(f'{workpath}/train_{index_nmodel}_{index_nstep}') - job_script_input.append(nequip_train_job( - inputs, ntrain, nval, workpath, index_nstep, index_nmodel, dply_model - )) - mpi_print(f'\t\tPrepare a command line for traing a model: {dply_model}', inputs.rank) - - if inputs.rank == 0: - for index_num_mdl in range(inputs.num_mdl_calc): - - # Prepare ingredients for the job script - with open(f'./{inputs.job_MLIP_name}', 'r') as job_script_initial: - job_script_default = job_script_initial.read() - - os.chdir(workpath) - # Write an input for NequIP - job_script = f'./{inputs.job_MLIP_name.split(".")[0]}_{index_num_mdl}.{inputs.job_MLIP_name.split(".")[1]}' - - with open(job_script, 'w') as writing_input: - writing_input.write(job_script_default) - for index_item, job_item in enumerate(job_script_input): - if index_item % inputs.num_mdl_calc == index_num_mdl: - writing_input.write(job_item) - - # Submit the job scripts - # subprocess.run([inputs.job_command, job_script]); - os.chdir(currentpath) + + if inputs.MLIP == 'nequip': + job_script_input = [] + for index_nmodel in range(inputs.nmodel): + for index_nstep in range(inputs.nstep): + dply_model = f'deployed-model_{index_nmodel}_{index_nstep}.pth' + if os.path.exists(f'{workpath}/{dply_model}'): + mpi_print(f'\t\tFound the deployed model: {dply_model}', inputs.rank) + else: # If not, prepare the training job + rm_mkdir(f'{workpath}/train_{index_nmodel}_{index_nstep}') + job_script_input.append(nequip_train_job( + inputs, ntrain, nval, workpath, index_nstep, index_nmodel, dply_model + )) + mpi_print(f'\t\tPrepare a command line for traing a model: {dply_model}', inputs.rank) + + if inputs.rank == 0: + for index_num_mdl in range(inputs.num_mdl_calc): + + # Prepare ingredients for the job script + with open(f'./{inputs.job_MLIP_name}', 'r') as job_script_initial: + job_script_default = job_script_initial.read() + + os.chdir(workpath) + # Write an input for NequIP + job_script = f'./{inputs.job_MLIP_name.split(".")[0]}_{index_num_mdl}.{inputs.job_MLIP_name.split(".")[1]}' + + with open(job_script, 'w') as writing_input: + writing_input.write(job_script_default) + for index_item, job_item in enumerate(job_script_input): + if index_item % inputs.num_mdl_calc == index_num_mdl: + writing_input.write(job_item) + + # Submit the job scripts + # subprocess.run([inputs.job_command, job_script]); + os.chdir(currentpath) + + elif inputs.MLIP == 'so3krates': + job_script_input = [] + for index_nmodel in range(inputs.nmodel): + for index_nstep in range(inputs.nstep): + dply_model = f'deployed-model_{index_nmodel}_{index_nstep}' + if os.path.exists(f'{workpath}/{dply_model}'): + mpi_print(f'\t\tFound the deployed model: {dply_model}', inputs.rank) + else: # If not, prepare the training job + rm_mkdir(f'{workpath}/inputs_{index_nmodel}_{index_nstep}.json') + job_script_input.append(so3krates_train_job( + inputs, ntrain, nval, workpath, index_nstep, index_nmodel, dply_model + )) + mpi_print(f'\t\tPrepare a command line for traing a model: {dply_model}', inputs.rank) + + if inputs.rank == 0: + for index_num_mdl in range(inputs.num_mdl_calc): + inputs.job_MLIP_name = 'job-so3krates.slurm' + # Prepare ingredients for the job script + with open(f'./{inputs.job_MLIP_name}', 'r') as job_script_initial: + job_script_default = job_script_initial.read() + + os.chdir(workpath) + # Write an input for NequIP + job_script = f'./{inputs.job_MLIP_name.split(".")[0]}_{index_num_mdl}.{inputs.job_MLIP_name.split(".")[1]}' + + with open(job_script, 'w') as writing_input: + writing_input.write(job_script_default) + for index_item, job_item in enumerate(job_script_input): + if index_item % inputs.num_mdl_calc == index_num_mdl: + writing_input.write(job_item) + + # Submit the job scripts + # subprocess.run([inputs.job_command, job_script]); + os.chdir(currentpath) + + + + + + + + + + + + + + + + + + + + diff --git a/libs/lib_util.py b/libs/lib_util.py index b030ab0..67a5816 100644 --- a/libs/lib_util.py +++ b/libs/lib_util.py @@ -365,15 +365,25 @@ def read_input_file(file_path): value = value.strip() # Perform type conversions for specific variables - if name in ['supercell', 'supercell_init', 'mask', 'harmonic_F', 'anharmoic_F', 'meta_restart', 'signal_uncert', 'criteria_energy', 'train_stress']: + if name in [ + 'supercell', 'supercell_init', 'mask', 'harmonic_F', 'anharmoic_F', 'meta_restart', + 'signal_uncert', 'criteria_energy', 'train_stress' + ]: value = eval(value) - elif name in ['crtria_cnvg', 'friction', 'compressibility', 'kB', 'E_gs', 'uncert_shift', 'uncert_grad', 'meta_Ediff', 'meta_r_crtria', 'ttime', 'pfactor', 'timestep', 'cell_factor', 'bias_A', 'bias_B', 'temp_factor']: + elif name in [ + 'crtria_cnvg', 'friction', 'compressibility', 'kB', 'E_gs', 'uncert_shift', 'uncert_grad', + 'meta_Ediff', 'meta_r_crtria', 'ttime', 'pfactor', 'timestep', 'cell_factor', 'bias_A', + 'bias_B', 'temp_factor', 'r_cut', 'we', 'wf', 'ws', 'eval_energy_t', 'lr', 'lr_stop', + 'lr_decay_exp_decay_factor', 'clip_by_global_norm' + ]: value = float(value) elif name in [ - 'ntrain_init', 'ntrain', 'nstep', 'nmodel', 'nperiod', 'temperature', 'taut', - 'pressure', 'taup', 'steps_ther', 'steps_init', 'steps_random', - 'cutoff_ther', 'lmax', 'nfeatures', 'random_index', - 'wndex', 'steps', 'loginterval', 'num_calc', 'test_index', 'num_mdl_calc', 'printinterval', 'idx_atom' + 'ntrain_init', 'ntrain', 'nstep', 'nmodel', 'nperiod', 'temperature', 'taut', 'pressure', + 'taup', 'steps_ther', 'steps_init', 'steps_random', 'cutoff_ther', 'lmax', 'nfeatures', + 'random_index', 'wndex', 'steps', 'loginterval', 'num_calc', 'test_index', 'num_mdl_calc', + 'printinterval', 'idx_atom', 'l', 'f', 'l_min', 'l_max', 'max_body_order', 'f_body_order', + 'epochs', 'lr_decay_exp_transition_steps', 'size_batch', 'size_batch_training', + 'size_batch_validation', 'seed_data', 'seed_training' ]: value = int(value) else: diff --git a/scripts/lib_run_dft_cont.py b/scripts/lib_run_dft_cont.py index 8dc2494..b8029e4 100644 --- a/scripts/lib_run_dft_cont.py +++ b/scripts/lib_run_dft_cont.py @@ -4,7 +4,6 @@ from libs.lib_dft import run_DFT from libs.lib_util import output_init, mpi_print, check_mkdir -from libs.lib_train import get_train_job from libs.lib_load_model import load_model from libs.lib_criteria import get_result from libs.lib_mainloop_new import MLMD_main, MLMD_random diff --git a/scripts/lib_run_dft_runmd.py b/scripts/lib_run_dft_runmd.py index 3501a08..0d7e635 100644 --- a/scripts/lib_run_dft_runmd.py +++ b/scripts/lib_run_dft_runmd.py @@ -1,5 +1,5 @@ import os -import son +from vibes import son import sys import numpy as np diff --git a/setup.py b/setup.py index d137702..102fe39 100644 --- a/setup.py +++ b/setup.py @@ -7,15 +7,16 @@ description='Active-learning machine-operated molecular dynamics (ALmoMD) is a Python code package designed for the effective training of machine learned interatomic potential (MLIP) through active learning based on uncertainty evaluation. It also facilitates the implementation of molecular dynamics (MD) using trained MLIPs with uncertainty evaluation.', packages=find_packages(), install_requires=[ - 'numpy>=1.25.0', - 'scipy>=1.10.1', + 'numpy>=1.23.0', + 'scipy==1.8.0', 'son>=0.4.2', 'ase>=3.22.1', 'pandas>=1.5.3', 'matplotlib>=3.7.0', 'scikit-learn>=1.2.2', 'wandb>=0.13.10', - 'nequip>=0.5.6' + 'nequip>=0.5.6', + 'numba' ], entry_points={ 'console_scripts': [