What is Pyre?

From DANSE

The Pyre application framework puts various components together at run time to form, well, an application. The framework assumes responsibility for managing the components. It provides a uniform set of steps for constructing and initializing components; this allows the framework to provide guarantees about when components will be ready to use.

Historically, Pyre was created to bring a degree of order to the complex task of staging large (massively) parallel scientific simulations. Applications support a command-line, serial execution model; the framework includes another class that supports command-line parallel execution. Most of what works for serial applications follows for parallel applications, so learning about serial apps is a good way to get started. Moving forward with the DANSE project (and relatives!), the framework will still have much to offer (to jump ahead for a moment, components will be unchanged, but the things that manage and juxtapose components, currently instances of class Application or mpi.Application, will have to evolve).


  • Components...

Here's a simple example component:

#!/usr/bin/env python
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# 9/14/2004 version 0.0.1b
# mmckerns@caltech.edu
# (C) 2004 All Rights Reserved
#
# <LicenseText>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
__author__ = 'Mike McKerns'

from pyre.inventory.Component import Component
import os

class Template(Component):
    '''pyre component template
Inventory:
  foo -- string (default=None)
  bar -- string (default=None)
Methods:
  shuffle() --> shuffles foo and bar
  printall() --> prints foo and bar'''
    class Inventory(Component.Inventory):
        '''Inventory declares and stores user modifiable variables'''
        import pyre.inventory    #for pythia0.6
        foo = pyre.inventory.str('foo', default=None)
        bar = pyre.inventory.str('bar', default=None)
#       return

    def config(self, **kwds):
        '''configure the inventory'''
        for key,value in kwds.items():
            if key in ['foo','bar']:
                if value.__class__() == '':
                    exec 'self.inventory.'+key+' = "'+value+'"'
                else:
                    exec 'self.inventory.'+key+' = '+str(value)
        return

    def shuffle(self):
        '''shuffles foo and bar; a example method'''
        #pass inventory into local variables
        foo = self.inventory.foo
        bar = self.inventory.bar
        #main code
        self.inventory.foo = bar
        self.inventory.bar = foo
        return

    def printall(self):
        '''prints foo and bar; a example method'''
        #pass inventory into local variables
        foo = self.inventory.foo
        bar = self.inventory.bar
        #main code
        print foo, bar
        return

    def __init__(self, name='Template', **kwds):
        '''instantiate the application, and pass any keywords to config'''
        Component.__init__(self, name, 'DummyTemplate')
        self.config(**kwds)
        return

    def help(self):
        print self.__doc__
        return

# End of file


  • Application...

A Pyre application is a Component with a run() method, and can have a "__main__" code block.

To make a Pyre application from a given component:

  1. substitute "pyre.inventory.Component" with "pyre.applications.Application"
  2. substitute all instances of "Component" with "Application"
  3. add a run() method (i.e. a code block for "def run(self):"
  4. delete the 'facility' name in __init__: "Component.__init__(self, name, facility)"
  5. add a "if __name__ == '__main__':" code block
  6. add a help() method (if one does not already exist)

We can convert our simple component to an application:

#!/usr/bin/env python
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# 9/14/2004 version 0.0.1b
# mmckerns@caltech.edu
# (C) 2004 All Rights Reserved
#
# <LicenseText>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
__author__ = 'Mike McKerns'

from pyre.applications.Application import Application
import os

class Template(Application):
    '''pyre application template
Inventory:
  foo -- string (default=None)
  bar -- string (default=None)
  mix -- boolean (default=False)
Methods:
  shuffle() --> shuffles foo and bar
  printall() --> prints foo and bar'''
    class Inventory(Application.Inventory):
        '''Inventory declares and stores user modifiable variables'''
        import pyre.inventory    #for pythia0.6
        foo = pyre.inventory.str('foo', default=None)
        bar = pyre.inventory.str('bar', default=None)
        mix = pyre.inventory.bool('mix', default=False)
#       return

    def config(self, **kwds):
        '''configure the inventory'''
        for key,value in kwds.items():
            if key in ['foo','bar','mix']:
                if value.__class__() == '':
                    exec 'self.inventory.'+key+' = "'+value+'"'
                else:
                    exec 'self.inventory.'+key+' = '+str(value)
        return

    def shuffle(self):
        '''shuffles foo and bar; a example method'''
        #pass inventory into local variables
        foo = self.inventory.foo
        bar = self.inventory.bar
        #main code
        self.inventory.foo = bar
        self.inventory.bar = foo
        return

    def printall(self):
        '''prints foo and bar; a example method'''
        #pass inventory into local variables
        foo = self.inventory.foo
        bar = self.inventory.bar
        #main code
        print foo, bar
        return

    def run(self):
        '''shuffle if required; the main method'''
        self.printall()
        if self.inventory.mix:
            self.shuffle()
            self.printall()
        return

    def __init__(self, name='Template', **kwds):
        '''instantiate the application, and pass any keywords to config'''
        Application.__init__(self, name)
        self.config(**kwds)
        return

    def help(self):
        print self.__doc__
        return

# main
if __name__ == '__main__':
    '''begin journaling services, and then run the main code block'''
    import journal
    mp = Template('test')  #instance of class Template (named 'test')
    journal.debug('test').activate()  #activate journal for 'test'
    mp.main()  #launch the main code block ('Template.run')

# End of file

Notice that an additional inventory item, "mix", was added ("mix" only is used by the 'run' method).


  • Inventory...
  • Facility...
Document Uploads/Links