Create a component package

This is an example creating a hello world component installable package. This is also an example of using MODULE instead of SCRIPT in the component configuration section.

The examples will be a simple hello world with one driver and one worker. The only requirement of the package is ipsframework. The ipsframework should be automatically installed from pypi when install ipsexamples but you can manually install it from pypi with

python -m pip install ipsframework

Or to install it directly from github you can do

python -m pip install git+https://github.com/HPC-SimTools/IPS-framework.git

To create this project locally, create the following file structure

helloworld
├── helloworld
│   ├── __init__.py
│   ├── hello_driver.py
│   └── hello_worker.py
└── setup.py

The file __init__.py is just empty but turns the helloworld folder into a python module.

A simple setup.py would be

#!/usr/bin/env python3
from setuptools import setup, find_packages

setup(
    name="helloworld",
    version="1.0.0",
    install_requires=["ipsframework"],
    packages=find_packages(),
)

The hello_driver.py in the most simplest form would be

from ipsframework import Component


class hello_driver(Component):
    def __init__(self, services, config):
        super().__init__(services, config)
        print('Created %s' % (self.__class__))

    def step(self, timestamp=0.0):
        print('hello_driver: beginning step call')
        worker_comp = self.services.get_port('WORKER')
        self.services.call(worker_comp, 'step', 0.0)
        print('hello_driver: finished step call')

And the hello_worker.py is

from ipsframework import Component


class hello_worker(Component):
    def __init__(self, services, config):
        super().__init__(services, config)
        print('Created %s' % (self.__class__))

    def step(self, timestamp=0.0):
        print('Hello from hello_worker')

This helloworld package can be installed with

python -m pip install .

Or to install it in editable mode with

python -m pip install -e .

With the components installed as a package you can reference them by MODULE instead of providing the full path with SCRIPT. So to use the hello_driver you do MODULE = helloworld.hello_driver, and for hello_worker you can do MODULE = helloworld.hello_worker.

A simple config to run this is, helloworld.config

SIM_NAME = helloworld
SIM_ROOT = $PWD
LOG_FILE = log
LOG_LEVEL = INFO
SIMULATION_MODE = NORMAL

[PORTS]
    NAMES = DRIVER WORKER
    [[DRIVER]]
        IMPLEMENTATION = hello_world_driver

    [[WORKER]]
        IMPLEMENTATION = hello_world

[hello_world_driver]
    CLASS = driver
    SUB_CLASS =
    NAME = hello_driver
    NPROC = 1
    BIN_PATH =
    INPUT_FILES =
    OUTPUT_FILES =
    SCRIPT =
    MODULE = helloworld.hello_driver

[hello_world]
    CLASS = workers
    SUB_CLASS =
    NAME = hello_worker
    NPROC = 1
    BIN_PATH =
    INPUT_FILES =
    OUTPUT_FILES =
    SCRIPT =
    MODULE = helloworld.hello_worker

And you need a platform file, platform.conf

MPIRUN = eval
NODE_DETECTION = manual
CORES_PER_NODE = 1
SOCKETS_PER_NODE = 1
NODE_ALLOCATION_MODE =  shared
HOST =

So after installing ipsframework and helloworld you can run it with

ips.py --config=helloworld.config --platform=platform.conf

and you should get the output

Created <class 'helloworld.hello_driver.hello_driver'>
Created <class 'helloworld.hello_worker.hello_worker'>
hello_driver: beginning step call
Hello from hello_worker
hello_driver: finished step call

Using PYTHONPATH instead of installing the package

If you don’t want to install the package, this can still work if you set your PYTHONPATH correctly. In this case you don’t need the setup.py either.

You can run the helloworld example from within the directory without installing by

PYTHONPATH=$PWD ips.py --config=helloworld.config --platform=platform.conf