Skip to content

Drivers

Driver

oqd_heisenberg_ion.common.driver

base

Driver

Driver base class

Calls the required simulator engine after preprocessing

Source code in src/oqd_heisenberg_ion/common/driver/base.py
class Driver:
    """Driver base class

    Calls the required simulator engine after preprocessing

    """

    def __init__(self, simulation_folder):
        """Driver base class constructor

        Args:
            simulation_folder (str): root directory for storing simulator outputs

        Raises:
                Exception: if the root simulation folder does not exist
        """

        self.simulation_folder = simulation_folder
        if not os.path.exists(self.simulation_folder):
            raise Exception("Unable to find the root simulation folder\n")

    def simulate(self):
        """Driver should always have a simulate method implemented by subclasses"""

        pass
__init__

Driver base class constructor

Parameters:

  • simulation_folder (str) –

    root directory for storing simulator outputs

Raises:

  • Exception

    if the root simulation folder does not exist

Source code in src/oqd_heisenberg_ion/common/driver/base.py
def __init__(self, simulation_folder):
    """Driver base class constructor

    Args:
        simulation_folder (str): root directory for storing simulator outputs

    Raises:
            Exception: if the root simulation folder does not exist
    """

    self.simulation_folder = simulation_folder
    if not os.path.exists(self.simulation_folder):
        raise Exception("Unable to find the root simulation folder\n")
simulate

Driver should always have a simulate method implemented by subclasses

Source code in src/oqd_heisenberg_ion/common/driver/base.py
def simulate(self):
    """Driver should always have a simulate method implemented by subclasses"""

    pass

factory

DriverFactory

Generates a Driver object based on input specifications

Carries a registry of recognized Driver subclasses, the constructors of which are called to build the Driver objects

Raises:

  • ValueError

    if the requested driver implementation is not found

Source code in src/oqd_heisenberg_ion/common/driver/factory.py
class DriverFactory:
    """
     Generates a Driver object based on input specifications

     Carries a registry of recognized Driver subclasses, the constructors of which are called to build the Driver objects

    Raises:
        ValueError: if the requested driver implementation is not found

    """

    registry = {}

    def register(cls, name, subclass):
        """
        adds a Driver subclass to the registry

        Args:
            name (str): defines the name of the subclass to be registered
            subclass (Type[Driver]): specifies the subclass to be registered
        """

        cls.registry[name] = subclass

    def create(cls, name, root_folder, simulator_inputs):
        """
        generates an instance of the requested subclass of Driver

        Args:
            name (str): specifies the name of the requested subclass
            root_folder (str): root directory for simulation outputs
            simulator_inputs (dict): contains the key word arguments to instantiate the Driver subclass requested

        Raises:
            Exception: if requested driver not found in registry

        Returns:
            (Driver): instance of requested driver subclass
        """

        if name not in cls.registry:
            raise Exception(f"Driver implementation not found for name: {name}")
        else:
            return cls.registry[name](root_folder, simulator_inputs)
register

adds a Driver subclass to the registry

Parameters:

  • name (str) –

    defines the name of the subclass to be registered

  • subclass (Type[Driver]) –

    specifies the subclass to be registered

Source code in src/oqd_heisenberg_ion/common/driver/factory.py
def register(cls, name, subclass):
    """
    adds a Driver subclass to the registry

    Args:
        name (str): defines the name of the subclass to be registered
        subclass (Type[Driver]): specifies the subclass to be registered
    """

    cls.registry[name] = subclass
create

generates an instance of the requested subclass of Driver

Parameters:

  • name (str) –

    specifies the name of the requested subclass

  • root_folder (str) –

    root directory for simulation outputs

  • simulator_inputs (dict) –

    contains the key word arguments to instantiate the Driver subclass requested

Raises:

  • Exception

    if requested driver not found in registry

Returns:

  • Driver

    instance of requested driver subclass

Source code in src/oqd_heisenberg_ion/common/driver/factory.py
def create(cls, name, root_folder, simulator_inputs):
    """
    generates an instance of the requested subclass of Driver

    Args:
        name (str): specifies the name of the requested subclass
        root_folder (str): root directory for simulation outputs
        simulator_inputs (dict): contains the key word arguments to instantiate the Driver subclass requested

    Raises:
        Exception: if requested driver not found in registry

    Returns:
        (Driver): instance of requested driver subclass
    """

    if name not in cls.registry:
        raise Exception(f"Driver implementation not found for name: {name}")
    else:
        return cls.registry[name](root_folder, simulator_inputs)

Long Range Quantum Monte Carlo

oqd_heisenberg_ion.simulators.qmc.long_range.driver

LongRangeQMC

Bases: Driver

Driver subclass for long range QMC

Source code in src/oqd_heisenberg_ion/simulators/qmc/long_range/driver.py
class LongRangeQMC(Driver):
    """
    Driver subclass for long range QMC
    """

    def __init__(self, simulation_folder, simulator_inputs):
        """
        builds and compiles the C++ engine if needed after extracting the build directory and input file for the QMC engine

        Args:
            simulation_folder (str): simulation output folder
            simulator_inputs (dict): specifies either the binaries or the cpp source directory
        """

        super().__init__(simulation_folder)

        self.input_file = os.path.join(os.path.abspath(simulation_folder), "inputs.txt")
        self.build_dir = os.path.join(os.path.abspath(simulation_folder), "build")
        os.mkdir(self.build_dir)

        self.bin_dir = simulator_inputs["bin_folder"]
        self.source_dir = simulator_inputs["cpp_source_folder"]

        if self.bin_dir is None:
            self.build_from_cmake(self.source_dir)
            self.compile_source()

    def build_from_cmake(self, cpp_source):
        """
        method for calling cmake via Python subprocess

        Args:
            cpp_source (str): path pointing to the C++ source code
        """

        configure_command = ["cmake", cpp_source, "-DCMAKE_BUILD_TYPE=Release"]
        try:
            subprocess.run(configure_command, cwd=self.build_dir, check=True, capture_output=True, text=True)
        except subprocess.CalledProcessError as error:
            print("Build from cmake failed with exit code: {}\n".format(error.returncode))
            print("STDOUT: {}".format(error.stdout))
            print("STDERR:{}".format(error.stderr))
            raise

    def compile_source(self):
        """
        method for compiling the C++ source code
        """

        compile_command = ["cmake", "--build", ".", "-j"]
        try:
            subprocess.run(compile_command, cwd=self.build_dir, check=True, capture_output=True, text=True)
        except subprocess.CalledProcessError as error:
            print("Compile failed with exit code: {}\n".format(error.returncode))
            print("STDOUT: {}".format(error.stdout))
            print("STDERR:{}".format(error.stderr))
            raise

    def simulate(self):
        """
        method for calling the C++ engine for simulating the system, via a Python subprocess call

        Returns:
            (int): exit code, 0 if the simulation terminates gracefully
        """

        if self.bin_dir is not None:
            copy_command = ["cp", "-r", self.bin_dir, self.build_dir]
            try:
                subprocess.run(copy_command, check=True, capture_output=True, text=True)
            except subprocess.CalledProcessError as error:
                print("Copying binaries run failed with exit code: {}\n".format(error.returncode))
                print("STDOUT: {}".format(error.stdout))
                print("STDERR:{}".format(error.stderr))
                raise

        try:
            subprocess.run(
                ["./cpp_qmc", self.input_file], cwd=self.build_dir, check=True, capture_output=True, text=True
            )
        except subprocess.CalledProcessError as error:
            print("Cpp run failed with exit code: {}\n".format(error.returncode))
            print("STDOUT: {}".format(error.stdout))
            print("STDERR:{}".format(error.stderr))
            raise

        return 0

__init__

builds and compiles the C++ engine if needed after extracting the build directory and input file for the QMC engine

Parameters:

  • simulation_folder (str) –

    simulation output folder

  • simulator_inputs (dict) –

    specifies either the binaries or the cpp source directory

Source code in src/oqd_heisenberg_ion/simulators/qmc/long_range/driver.py
def __init__(self, simulation_folder, simulator_inputs):
    """
    builds and compiles the C++ engine if needed after extracting the build directory and input file for the QMC engine

    Args:
        simulation_folder (str): simulation output folder
        simulator_inputs (dict): specifies either the binaries or the cpp source directory
    """

    super().__init__(simulation_folder)

    self.input_file = os.path.join(os.path.abspath(simulation_folder), "inputs.txt")
    self.build_dir = os.path.join(os.path.abspath(simulation_folder), "build")
    os.mkdir(self.build_dir)

    self.bin_dir = simulator_inputs["bin_folder"]
    self.source_dir = simulator_inputs["cpp_source_folder"]

    if self.bin_dir is None:
        self.build_from_cmake(self.source_dir)
        self.compile_source()

build_from_cmake

method for calling cmake via Python subprocess

Parameters:

  • cpp_source (str) –

    path pointing to the C++ source code

Source code in src/oqd_heisenberg_ion/simulators/qmc/long_range/driver.py
def build_from_cmake(self, cpp_source):
    """
    method for calling cmake via Python subprocess

    Args:
        cpp_source (str): path pointing to the C++ source code
    """

    configure_command = ["cmake", cpp_source, "-DCMAKE_BUILD_TYPE=Release"]
    try:
        subprocess.run(configure_command, cwd=self.build_dir, check=True, capture_output=True, text=True)
    except subprocess.CalledProcessError as error:
        print("Build from cmake failed with exit code: {}\n".format(error.returncode))
        print("STDOUT: {}".format(error.stdout))
        print("STDERR:{}".format(error.stderr))
        raise

compile_source

method for compiling the C++ source code

Source code in src/oqd_heisenberg_ion/simulators/qmc/long_range/driver.py
def compile_source(self):
    """
    method for compiling the C++ source code
    """

    compile_command = ["cmake", "--build", ".", "-j"]
    try:
        subprocess.run(compile_command, cwd=self.build_dir, check=True, capture_output=True, text=True)
    except subprocess.CalledProcessError as error:
        print("Compile failed with exit code: {}\n".format(error.returncode))
        print("STDOUT: {}".format(error.stdout))
        print("STDERR:{}".format(error.stderr))
        raise

simulate

method for calling the C++ engine for simulating the system, via a Python subprocess call

Returns:

  • int

    exit code, 0 if the simulation terminates gracefully

Source code in src/oqd_heisenberg_ion/simulators/qmc/long_range/driver.py
def simulate(self):
    """
    method for calling the C++ engine for simulating the system, via a Python subprocess call

    Returns:
        (int): exit code, 0 if the simulation terminates gracefully
    """

    if self.bin_dir is not None:
        copy_command = ["cp", "-r", self.bin_dir, self.build_dir]
        try:
            subprocess.run(copy_command, check=True, capture_output=True, text=True)
        except subprocess.CalledProcessError as error:
            print("Copying binaries run failed with exit code: {}\n".format(error.returncode))
            print("STDOUT: {}".format(error.stdout))
            print("STDERR:{}".format(error.stderr))
            raise

    try:
        subprocess.run(
            ["./cpp_qmc", self.input_file], cwd=self.build_dir, check=True, capture_output=True, text=True
        )
    except subprocess.CalledProcessError as error:
        print("Cpp run failed with exit code: {}\n".format(error.returncode))
        print("STDOUT: {}".format(error.stdout))
        print("STDERR:{}".format(error.stderr))
        raise

    return 0

Nearest Neighbor Quantum Monte Carlo

oqd_heisenberg_ion.simulators.qmc.nearest_neighbor.driver

NearestNeighborQMC

Bases: Driver

Driver subclass for nearest neighbor qmc

Source code in src/oqd_heisenberg_ion/simulators/qmc/nearest_neighbor/driver.py
class NearestNeighborQMC(Driver):
    """
    Driver subclass for nearest neighbor qmc
    """

    def __init__(self, simulation_folder, simulator_inputs):
        """
        initializes the nearest neighbor qmc driver and counts the number of parameter sets

        Args:
            simulation_folder (str): path to the simulation output folder
            simulator_inputs (list[dict]): list of nearest neighbor qmc parameter sets to be simulated
        """

        super().__init__(simulation_folder)

        self.sse_inputs = simulator_inputs

        self.num_parameter_sets = len(simulator_inputs)

    def simulate(self):
        """
        calls the Python ConfigurationGenerator class, the nearest neighbor qmc engine

        Returns:
            (int): exit code, 0 if the simulation terminates gracefully
        """

        for i in range(self.num_parameter_sets):
            run_folder = self.sse_inputs[i].run_folder
            system = self.sse_inputs[i].system
            sampling_args = self.sse_inputs[i].sampling_parameters

            config_generator = ConfigurationGenerator(system, sampling_args, run_folder)
            config_generator.simulate()
            config_generator.write_outputs()

        return 0

__init__

initializes the nearest neighbor qmc driver and counts the number of parameter sets

Parameters:

  • simulation_folder (str) –

    path to the simulation output folder

  • simulator_inputs (list[dict]) –

    list of nearest neighbor qmc parameter sets to be simulated

Source code in src/oqd_heisenberg_ion/simulators/qmc/nearest_neighbor/driver.py
def __init__(self, simulation_folder, simulator_inputs):
    """
    initializes the nearest neighbor qmc driver and counts the number of parameter sets

    Args:
        simulation_folder (str): path to the simulation output folder
        simulator_inputs (list[dict]): list of nearest neighbor qmc parameter sets to be simulated
    """

    super().__init__(simulation_folder)

    self.sse_inputs = simulator_inputs

    self.num_parameter_sets = len(simulator_inputs)

simulate

calls the Python ConfigurationGenerator class, the nearest neighbor qmc engine

Returns:

  • int

    exit code, 0 if the simulation terminates gracefully

Source code in src/oqd_heisenberg_ion/simulators/qmc/nearest_neighbor/driver.py
def simulate(self):
    """
    calls the Python ConfigurationGenerator class, the nearest neighbor qmc engine

    Returns:
        (int): exit code, 0 if the simulation terminates gracefully
    """

    for i in range(self.num_parameter_sets):
        run_folder = self.sse_inputs[i].run_folder
        system = self.sse_inputs[i].system
        sampling_args = self.sse_inputs[i].sampling_parameters

        config_generator = ConfigurationGenerator(system, sampling_args, run_folder)
        config_generator.simulate()
        config_generator.write_outputs()

    return 0

Exact Diagonalization

oqd_heisenberg_ion.simulators.ed.driver

ExactDiagonalization

Bases: Driver

Driver subclass for Exact Diagonalization. Calls the Julia ED engine via a python subprocess which uses the input file generated by the preprocessor to specify the simulation parameters

Source code in src/oqd_heisenberg_ion/simulators/ed/driver.py
class ExactDiagonalization(Driver):
    """
    Driver subclass for Exact Diagonalization.
    Calls the Julia ED engine via a python subprocess which uses the input file generated by the preprocessor to specify the simulation parameters
    """

    def __init__(self, simulation_folder, simulator_inputs):
        """
        constructor for the ED Driver subclass. Specifies the ED engine path, the ED engine input file path and the Julia path

        Args:
            simulation_folder (str): the parameter set simulation folder
            simulator_inputs (dict): contains the Julia path as a key value pair
        """

        super().__init__(simulation_folder)

        self.input_file = os.path.join(simulation_folder, "inputs.txt")
        self.julia_path = simulator_inputs["julia_path"]
        self.ed_engine = os.path.dirname(os.path.abspath(__file__)) + "/engine.jl"

    def simulate(self):
        """
        calls the Julia engine for the ED calculation

        Returns:
            (int): exit code, 0 if the program executes to completion
        """

        try:
            subprocess.run(
                [self.julia_path, self.ed_engine, self.input_file], check=True, capture_output=True, text=True
            )
        except subprocess.CalledProcessError as error:
            print(f"Julia execution failed with exit code: {error.returncode}\n")
            print(f"STDOUT: {error.stdout}")
            print(f"STDERR:{error.stderr}")
            raise

        return 0

__init__

constructor for the ED Driver subclass. Specifies the ED engine path, the ED engine input file path and the Julia path

Parameters:

  • simulation_folder (str) –

    the parameter set simulation folder

  • simulator_inputs (dict) –

    contains the Julia path as a key value pair

Source code in src/oqd_heisenberg_ion/simulators/ed/driver.py
def __init__(self, simulation_folder, simulator_inputs):
    """
    constructor for the ED Driver subclass. Specifies the ED engine path, the ED engine input file path and the Julia path

    Args:
        simulation_folder (str): the parameter set simulation folder
        simulator_inputs (dict): contains the Julia path as a key value pair
    """

    super().__init__(simulation_folder)

    self.input_file = os.path.join(simulation_folder, "inputs.txt")
    self.julia_path = simulator_inputs["julia_path"]
    self.ed_engine = os.path.dirname(os.path.abspath(__file__)) + "/engine.jl"

simulate

calls the Julia engine for the ED calculation

Returns:

  • int

    exit code, 0 if the program executes to completion

Source code in src/oqd_heisenberg_ion/simulators/ed/driver.py
def simulate(self):
    """
    calls the Julia engine for the ED calculation

    Returns:
        (int): exit code, 0 if the program executes to completion
    """

    try:
        subprocess.run(
            [self.julia_path, self.ed_engine, self.input_file], check=True, capture_output=True, text=True
        )
    except subprocess.CalledProcessError as error:
        print(f"Julia execution failed with exit code: {error.returncode}\n")
        print(f"STDOUT: {error.stdout}")
        print(f"STDERR:{error.stderr}")
        raise

    return 0