HydraGNN_Predictive_GFM_2024 / inference_example_with_dummy_data_object.py
mlupopa's picture
Upload inference_example_with_dummy_data_object.py
039c51a verified
##############################################################################
# Copyright (c) 2024, Oak Ridge National Laboratory #
# All rights reserved. #
# #
# This file is part of HydraGNN and is distributed under a BSD 3-clause #
# license. For the licensing terms see the LICENSE file in the top-level #
# directory. #
# #
# SPDX-License-Identifier: BSD-3-Clause #
##############################################################################
##############################################################################
######################## INSTRUCTIONS TO RUN THE CODE #######################
##############################################################################
"""
1. Follow run instructions on HydraGNN Wiki page: https://github.com/ORNL/HydraGNN/wiki/Run
2. Copy the "Ensemble_of_models" folder with the models into "examples/ensemble_learning"
3. Copy the script "inference_example_with_dummy_data_object.py" into "examples/ensemble_learning"
"""
import json, os
from mpi4py import MPI
import argparse
import torch
from torch_geometric.data import Data
from torch_geometric.transforms import Distance
import hydragnn
try:
from hydragnn.utils.adiosdataset import AdiosWriter, AdiosDataset
except ImportError:
pass
from hydragnn.preprocess.utils import (
RadiusGraph,
)
radius_graph = RadiusGraph(5.0, loop=False, max_num_neighbors=50)
transform_coordinates = Distance(norm=False, cat=False)
from ensemble_utils import model_ensemble
######################################################
###### PYTORCH GEOMETRIC DATA OBJECT DEFINITION ######
######################################################
# Define the dummy inputs
lattice_mat = torch.tensor([[10.0, 0.0, 0.0], [0.0, 10.0, 0.0], [0.0, 0.0, 10.0]], dtype=torch.float32) # 3x3 supercell size matrix
positions = torch.tensor([[0.5, 0.5, 0.5], [1.5, 1.5, 1.5]], dtype=torch.float32) # Nx3 positions matrix
atomic_numbers = torch.tensor([1, 6], dtype=torch.int64).unsqueeze(1) # Atomic numbers as a 1D tensor
x = torch.cat([atomic_numbers, positions], dim=1)
# Creating the Data object
data = Data(
supercell_size=lattice_mat,
pos=positions,
atomic_numbers=atomic_numbers.view(-1, 1), # Reshape atomic_numbers to Nx1 tensor
x=x,
)
data = radius_graph(data)
data = transform_coordinates(data)
######################################################
###### LOAD MODELS AND USE THEM FOR PREDICTIONS ######
######################################################
if __name__ == "__main__":
##################################################################################################################
parser = argparse.ArgumentParser()
print("gfm starting")
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter
)
parser.add_argument("--models_dir_folder", help="folder of trained models", type=str, default="./Ensemble_of_models")
args = parser.parse_args()
args.parameters = vars(args)
##################################################################################################################
modeldirlists = args.models_dir_folder.split(",")
assert len(modeldirlists) == 1 or len(modeldirlists) == 2
if len(modeldirlists) == 1:
modeldirlist = [os.path.join(args.models_dir_folder, name) for name in os.listdir(args.models_dir_folder) if
os.path.isdir(os.path.join(args.models_dir_folder, name))]
else:
modeldirlist = []
for models_dir_folder in modeldirlists:
modeldirlist.extend([os.path.join(models_dir_folder, name) for name in os.listdir(models_dir_folder) if
os.path.isdir(os.path.join(models_dir_folder, name))])
var_config = None
for modeldir in modeldirlist:
input_filename = os.path.join(modeldir, "config.json")
with open(input_filename, "r") as f:
config = json.load(f)
if var_config is not None:
assert var_config == config["NeuralNetwork"][
"Variables_of_interest"], "Inconsistent variable config in %s" % input_filename
else:
var_config = config["NeuralNetwork"]["Variables_of_interest"]
verbosity = config["Verbosity"]["level"]
##################################################################################################################
# Always initialize for multi-rank training.
comm_size, rank = hydragnn.utils.setup_ddp()
##################################################################################################################
comm = MPI.COMM_WORLD
##################################################################################################################
model_ens = model_ensemble(modeldirlist)
model_ens = hydragnn.utils.get_distributed_model(model_ens, verbosity)
model_ens.eval()
##################################################################################################################
nheads = len(config["NeuralNetwork"]["Variables_of_interest"]["output_names"])
pred_ens = model_ens(data)
for model_id in range(len(modeldirlist)):
print(f"Model {modeldirlist[model_id]} - Prediction of energy: \n", pred_ens[model_id][0])
print(f"Model {modeldirlist[model_id]} - Prediction of forces: \n", pred_ens[model_id][1])