Taking Ownership of Your Package’s Python Interface 2005 Trilinos Users Group Meeting 31 Oct 2005 1:15-2:15 Bill Spotz.

Slides:



Advertisements
Similar presentations
Chapter Modules CSC1310 Fall Modules Modules Modules are the highest level program organization unit, usually correspond to source files and.
Advertisements

Module R2 CS450. Next Week R1 is due next Friday ▫Bring manuals in a binder - make sure to have a cover page with group number, module, and date. You.
A Crash Course Python. Python? Isn’t that a snake? Yes, but it is also a...
API Design CPSC 315 – Programming Studio Fall 2008 Follows Kernighan and Pike, The Practice of Programming and Joshua Bloch’s Library-Centric Software.
George Blank University Lecturer. CS 602 Java and the Web Object Oriented Software Development Using Java Chapter 4.
Copyright © 2008 Pearson Addison-Wesley. All rights reserved. Chapter 12 Separate Compilation Namespaces Simple Make Files (Ignore all class references.
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved. Chapter 13 - The Preprocessor Outline 13.1Introduction.
Guide To UNIX Using Linux Third Edition
 2000 Prentice Hall, Inc. All rights reserved. Chapter 13 - The Preprocessor Outline 13.1Introduction 13.2The #include Preprocessor Directive 13.3The.
 2007 Pearson Education, Inc. All rights reserved C++ as a Better C; Introducing Object Technology.
1 Outline 7.1 Introduction 7.2 Implementing a Time Abstract Data Type with a Class 7.3 Special Attributes 7.4Controlling Access to Attributes 7.4.1Get.
C++ fundamentals.
Unit Testing Using PyUnit Monther Suboh Yazan Hamam Saddam Al-Mahasneh Miran Ahmad
1 Introduction to Tool chains. 2 Tool chain for the Sitara Family (but it is true for other ARM based devices as well) A tool chain is a collection of.
 2003 Prentice Hall, Inc. All rights reserved. 1 Chapter 19 - The Preprocessor Outline 19.1 Introduction 19.2 The #include Preprocessor Directive 19.3.
Dataface API Essentials Steve Hannah Web Lite Solutions Corp.
1 Chapter One A First Program Using C#. 2 Objectives Learn about programming tasks Learn object-oriented programming concepts Learn about the C# programming.
REFACTORING Lecture 4. Definition Refactoring is a process of changing the internal structure of the program, not affecting its external behavior and.
Java Programming, 3e Concepts and Techniques Chapter 2 - Part 2 Creating a Java Application and Applet.
C++ Code Analysis: an Open Architecture for the Verification of Coding Rules Paolo Tonella ITC-irst, Centro per la Ricerca Scientifica e Tecnologica
Software Tools and Processes Training and Discussion October 16, :00-4:30 p.m. Jim Willenbring.
Trilinos 101: Getting Started with Trilinos November 7, :30-9:30 a.m. Mike Heroux Jim Willenbring.
COSC 1P03 Data Structures and Abstraction 4.1 Abstract Data Types The advantage of a bad memory is that one enjoys several times the same good things for.
Builtins, namespaces, functions. There are objects that are predefined in Python Python built-ins When you use something without defining it, it means.
Using PyTrilinos 2005 Trilinos Users Group Meeting 1 Nov :30-4:30 Bill Spotz.
PyTrilinos: A Python Interface to Trilinos Bill Spotz Sandia National Laboratories Reproducible Research in Computational Geophysics August 31, 2006.
Python Modules An Introduction. Introduction A module is a file containing Python definitions and statements. The file name is the module name with the.
Parallel Interactive Computing with PyTrilinos and IPython Bill Spotz, SNL (Brian Granger, Tech-X Corporation) November 8, 2007 Trilinos Users Group Meeting.
H3D API Training  Part 3.1: Python – Quick overview.
Scons Writing Solid Code Overview What is scons? scons Basics Other cools scons stuff Resources.
How to configure, build and install Trilinos November 2, :30-9:30 a.m. Jim Willenbring Mike Phenow.
Sandia is a multiprogram laboratory operated by Sandia Corporation, a Lockheed Martin Company, for the United States Department of Energy’s National Nuclear.
Copyright © 2010 Certification Partners, LLC -- All Rights Reserved Perl Specialist.
By James Braunsberg. What are Modules? Modules are files containing Python definitions and statements (ex. name.py) A module’s definitions can be imported.
PyTrilinos: a Python Interface to Selected Trilinos Packages Bill Spotz Trilinos Users Group Meeting November 2, 2004.
ADTs and C++ Classes Classes and Members Constructors The header file and the implementation file Classes and Parameters Operator Overloading.
Built-in Data Structures in Python An Introduction.
Overview Intro to functions What are functions? Why use functions? Defining functions Calling functions Documenting functions Top-down design Variable.
Unit Testing with JUnit and Clover Based on material from: Daniel Amyot JUnit Web site.
Python Functions.
1 Chapter 2 C++ Syntax and Semantics, and the Program Development Process.
Test Specifications A Specification System for Multi-Platform Test Suite Configuration, Build, and Execution Greg Cooksey.
CS105 Computer Programming PYTHON (based on CS 11 Python track: lecture 1, CALTECH)
Copyright © 2003 ProsoftTraining. All rights reserved. Perl Fundamentals.
 2003 Prentice Hall, Inc. All rights reserved. 1 IS 0020 Program Design and Software Tools Preprocessor Midterm Review Lecture 7 Feb 17, 2004.
Getting Started with Trilinos October 14, :30-10:30 a.m. Jim Willenbring.
Python Let’s get started!.
The Preprocessor Directives Introduction Preprocessing – Occurs before program compiled Inclusion of external files Definition of symbolic constants.
Creating FunctionstMyn1 Creating Functions Function can be divided into two groups: –Internal (built in) functions –User-defined functions.
Chapter – 8 Software Tools.
How to configure, build and install Trilinos November 2, :30-9:30 a.m. Jim Willenbring.
12. MODULES Rocky K. C. Chang November 6, 2015 (Based on from Charles Dierbach. Introduction to Computer Science Using Python and William F. Punch and.
Today… Modularity, or Writing Functions. Winter 2016CISC101 - Prof. McLeod1.
FUNCTIONS (C) KHAERONI, M.SI. OBJECTIVE After this topic, students will be able to understand basic concept of user defined function in C++ to declare.
FILES AND EXCEPTIONS Topics Introduction to File Input and Output Using Loops to Process Files Processing Records Exceptions.
Python C API overview References:
DOE/Office of Science/ASCR (Sandia National Laboratories)
Python’s Modules Noah Black.
Introduction to C++ Systems Programming.
Java Primer 1: Types, Classes and Operators
Chapter 13 - The Preprocessor
Topics Introduction to File Input and Output
Java Programming Language
C Preprocessor(CPP).
Rocky K. C. Chang 15 November 2018 (Based on Dierbach)
CISC101 Reminders Assignment 3 due next Friday. Winter 2019
Python Modules.
Topics Introduction to File Input and Output
 A function is a named sequence of statement(s) that performs a computation. It contains  line of code(s) that are executed sequentially from top.
Python Modules.
Presentation transcript:

Taking Ownership of Your Package’s Python Interface 2005 Trilinos Users Group Meeting 31 Oct :15-2:15 Bill Spotz

Limited Capabilities Marzio Sala Trilinos Packages with Python Interfaces Amesos Anasazi AztecOO Epetra EpetraExt Galeri IFPACK LOCA ML New_Package NOX Triutils

Creating a Python Wrapper.h Header Files setup.py Build ScriptLibrary.a.so Shared Object $ python setup.py build.i SWIG Interface File _wrap.cpp Wrapper Code.py Python Module SWIG distutils.py DistUtils Module

Outline A brief discussion of python modules Trilinos python directories structure –Overview –Automatic generation SWIG interface files: New_Package.i The setup.py script Testing PyTrilinos modules: testNew_Package.py Issues –“Pythonification” –The PyTrilinos package –Bugzilla –Test harness

A Brief Discussion of Python Modules Python import statements –import MyModule –import MyModule, YourModule –import MyModule as MM –from MyModule import myFunc –from MyModule import myFunc as mf –from MyModule import * When import is used, it does the following: –Creates a new namespace –Puts defined objects in the namespace –Executes code contained in the module

A Brief Discussion of Python Modules import will load and execute only once Module search path: >>> import sys >>> print sys.path ['', '/Users/wfspotz', '/sw/lib/python24.zip', '/sw/lib/python2.4', '/sw/lib/python2.4/plat-darwin', '/sw/lib/python2.4/plat-mac', '/sw/lib/python2.4/plat-mac/lib-scriptpackages', '/sw/lib/python2.4/lib-tk', '/sw/lib/python2.4/lib-dynload', '/sw/lib/python2.4/site-packages', '/sw/lib/python2.4/site- packages/Numeric', … ]

A Brief Discussion of Python Modules When looking for a module example, the python interpreter searches each of the directories in sys.path for the following, in search order: –A directory example defining a package (i.e., it contains a file named __init__.py) –example.so or examplemodule.{so,sl,dll} –example.pyo (optimized byte code) –example.pyc (byte code) –example.py (pure python)

A Brief Discussion of Python Modules Packages allow a collection of modules to be grouped under a common package name: PyTrilinos/ __init__.py Amesos.py AztecOO.py Epetra.py EpetraExt.py IFPACK.py ML.py NOX/ __init__.py Abstract.py Epetra.py LAPACK.py Parameter.py Solver.py StatusTest.py TopLevel.py _Abstract.so _Epetra.so _LAPACK.so _Parameter.so _Solver.so _StatusTest.so _TopLevel.py New_Package.py Triutils.py _Amesos.py _AztecOO.py _Epetra.py _EpetraExt.o _IFPACK.so _ML.so _New_Package.so _Triutils.so

A Brief Discussion of Python Modules The __init__.py file can contain anything, but should usually define list __all__ For NOX, __init__.py is: from TopLevel import * from TopLevel import __version__ import Abstract, Parameter, Solver, StatusTest __all__ = [“Abstract”, “Parameter”, “Solver”, “StatusTest”] try: import Epetra __all__.append(“Epetra”) except ImportError: pass try: import LAPACK __all__.append(“LAPACK”) except ImportError: pass

Trilinos python Directories Structure Trilinos packages new_package configdocexamplepythonsrctest

The python Directory Structure pythonMakefile.am Makefile.in example src test Makefile.am Makefile.in.deps New_Package.i TRILINOS_HOME_DIR.in __init__.py.in setup.py dummy.in Makefile.am Makefile.in setpath.py testNew_Package.py

The python Build Directory Structure pythonMakefile example src test Makefile setpath.py testNew_Package.py Makefile.deps New_Package.py TRILINOS_HOME_DIR __init__.py build dummy New_Package_wrap.cpp

Automatic Directory Generation Updated directions for adding python wrappers to your package in –Trilinos/packages/new_package/python/Instructions.txt Don’t copy new_package/python directory; use –Trilinos/packages/new_package/CreatePythonDir.py Examples: –CreatePythonDir.py Anasazi New_Package  Anasazi new_package  anasazi NEW_PACKAGE  ANASAZI –CreatePythonDir.py --capital=ML –CreatePythonDir.py --help Move generated directory to your package –mv anasazi_python../anasazi/python

SWIG Interface Files: New_Package.i %define DOCSTRING "The New_Package module allows access to The Trilinos package New_Package. Use the python help() facility for local documentation on classes and methods, or see the on-line documentation for more in-depth information." %enddef %module(package="PyTrilinos", docstring=DOCSTRING) New_Package Define the module name, its package, and its documentation string Python file name (New_Package.py) and wrapper file name (New_Package_wrap.cpp) are derived from module name, not interface file name

SWIG Interface Files: New_Package.i %{ #include #include "New_Package_Version.h" #include "Newp_Hello.h" #ifdef NEWP_SWAHILI #include "Newp_Jambo.h" #endif %} Percent-brackets enclose code that will be passed to the wrapper code verbatim

SWIG Interface Files: New_Package.i %ignore Newp_Hello::Print(ostream &) const; #ifdef NEWP_SWAHILI %ignore Newp_Jambo::Print(ostream &) const; #endif %ignore directives tell SWIG not to generate particular wrappers (in this case because there are no python ostreams) Issued prior to %includes Can accept wildcard * Modifiers are respected Often used to suppress warnings (e.g., operator=)

SWIG Interface Files: New_Package.i %include "std_string.i" using namespace std; %include "New_Package_Version.h" %include "Newp_Hello.h" #ifdef NEWP_SWAHILI %include "Newp_Jambo.h" #endif %include is used to tell SWIG which header files to wrap std_string.i is one of many SWIG interface libraries for handling common situations %import may be used to tell SWIG about needed code without generating a wrapper

SWIG Interface Files: New_Package.i %extend Newp_Hello { string __str__() { stringstream os; self->Print(os); string s = os.str(); return s.substr(0,s.length()-1); } #ifdef NEWP_SWAHILI %extend Newp_Jambo { string __str__() { stringstream os; self->Print(os); string s = os.str(); return s.substr(0,s.length()-1); } #endif The %extend directive can be used to add methods to the python version of the class Here we add a __str__() method, which is the python string-conversion method This allows use to use Newp_Hello or Newp_Jambo objects with the python print statement

SWIG Interface Files: New_Package.i %feature("autodoc", "1"); %pythoncode %{ __version__ = New_Package_Version().split()[2] %} Autodoc feature adds minimal documentation strings to each method indicating input arguments and output…work with python help() function %pythoncode directive puts python code directly in New_Package.py. Here we obtain the New_Package version string, split it using “ ” as a delimiter, and accept index 2 of that list as the version

The setup.py Script If your package uses only one namespace that is the package name, required modifications are minimal (and essentially cosmetic) –Get rid of NEWP_SWAHILI stuff –Change author name and If you use more than one namespace, you’ll need more familiarity with setup.py and the distutils module If you ever have to debug a make problem, you’ll need more familiarity...

The setup.py Script The setup.py script has three main sections: Variable definitions –Extracting macro definitions from Makefiles Extension definition(s) –A python “extension module” refers to any compiled python module –Extension is a distutils class for defining a python extension The setup call –Defines the entire package –Pure python module(s), extension module(s)

Variable Definitions TRILINOS_HOME_DIR = os.path.normpath( open("TRILINOS_HOME_DIR").read()[:-1]) sys.path.insert(0,os.path.join(TRILINOS_HOME_DIR,"commonTools", "buildTools")) from MakefileVariables import * makeVars = { } makeVars.update(processMakefile("Makefile")) globals().update(makeVars) Get the top source directory Prepend commonTools/buildTools to python search path Import the MakefileVariables module Extract make variables; put in python dictionary Push make variables into the global namespace

Variable Definitions define_macros = [("HAVE_CONFIG_H", "1")] include_dirs = [srcdir] library_dirs = [ ] libraries = [ ] extra_link_args = [ ] extra_compile_args = CPPFLAGS.split() + CXXFLAGS.split() uniquifyList(extra_compile_args) options = NEW_PACKAGE_INCLUDES.split() + \ NEW_PACKAGE_LIBS.split() + \ PYTRILINOS_INCLUDES.split() + \ PYTRILINOS_LIBS.split() uniquifyList(options) These lists will be passed to Extension constructor(s) String split() method: string  list of strings Addition operator concatenates lists

Variable Definitions for option in options: if option[:2] == "-I": include_dirs.append(option[2:]) elif option[:2] == "-L": library_dirs.append(option[2:]) elif option[:2] == "-l": libraries.append(option[2:]) else: extra_link_args.append(option) Put the export Makefile values in their proper places

Extension Definitions new_packageWrap = "New_Package_wrap.cpp" _New_Package = Extension("PyTrilinos._New_Package", [new_packageWrap], define_macros = define_macros, include_dirs = include_dirs, library_dirs = library_dirs, libraries = libraries, extra_compile_args = extra_compile_args, extra_link_args = extra_link_args ) This defines an Extension object, which will be passed to setup()

The setup() Call setup(name = "PyTrilinos.New_Package", version = version, description = "Python Interface to New_Package", author = "Bill Spotz", author_ = package_dir = {"PyTrilinos" : "."}, packages = ["PyTrilinos"], ext_modules = [ _New_Package ] ) The setup() function will check the command-line arguments for a command (build, install, clean, etc.) and execute appropriately

Testing: the setpath Module myDir,myName = os.path.split(__file__) libDir = "lib.%s-%s" % (get_platform(), sys.version[0:3]) fullPath = os.path.normpath(os.path.join(myDir, "..", "src", "build", libDir, "PyTrilinos")) epetraPath = os.path.normpath(os.path.join(myDir, "..", "..", "..", "epetra","python","src","build",libDir,"PyTrilinos")) sys.path.insert(0,fullPath) sys.path.insert(1,epetraPath) Build the paths for the location of the New_Package module and the Epetra module Prepend the python search path

Testing: testNew_Package.py import sys try: import setpath import Epetra, New_Package except ImportError: from PyTrilinos import Epetra, New_Package print >>sys.stderr, "Using system-installed Epetra, New_Package" import unittest Tries to import locally built modules On ImportError exception, tries to import from system- installed PyTrilinos

Testing: testNew_Package.py class New_PackageTestCase(unittest.TestCase): "TestCase class for New_Package module" def setUp(self): self.comm = Epetra.PyComm() self.comm.Barrier() def tearDown(self): # This will help tame the printing self.comm.Barrier() Inherit from unittest.TestCase base class setUp() method called before every test tearDown() method called after every test Epetra.PyComm() returns SerialComm or MpiComm depending on configuration

Testing: testNew_Package.py def testVersion(self): "Test New_Package New_Package_Version function" front = "New_Package Version " version = New_Package.New_Package_Version() self.assertEquals(version[:len(front)], front) def testHelloConstructor(self): "Test New_Package Hello constructor" hello = New_Package.Newp_Hello(self.comm) # No assert here; executing w/o an exception is enough More New_PackageTestCase methods Framework looks for methods that begin with “test” Framework provides several “assert” methods

Testing: testNew_Package.py def testHelloPrint(self): "Test New_Package Hello print operator" hello = New_Package.Newp_Hello(self.comm) if self.comm.MyPID() == 0: result="This will print out one line for each of the "+\ str(self.comm.NumProc()) + " processes \n\n" else: result = "" result += "Hello. I am process %d" % self.comm.MyPID() string = hello.__str__() self.assertEquals(string, result) Comparison depends on processor Special __str__() method used by python to convert objects to strings; we have defined it in New_Package.i

Testing: testNew_Package.py if __name__ == "__main__": suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(New_PackageTestCase)) comm = Epetra.PyComm() iAmRoot = comm.MyPID() == 0 if iAmRoot: print >>sys.stderr, \ "\n*******************\nTesting New_Package\n*******************\n" verbosity = 2 * int(iAmRoot) result = unittest.TextTestRunner(verbosity=verbosity).run(suite) errsPlusFails = comm.SumAll(len(result.errors) + \ len(result.failures))[0] if errsPlusFails==0 and iAmRoot: print "End Result: TEST PASSED" sys.exit(errsPlusFails) Create test suite, run and get the results

Testing: Results $ mpirun -np 2 testNew_Package.py ******************* Testing New_Package ******************* Test New_Package Hello constructor... ok Test New_Package Hello print operator... ok Test New_Package New_Package_Version function... ok Ran 3 tests in 0.049s OK Ran 3 tests in 0.029s OK End Result: TEST PASSED

“Pythonification” of Your Package SWIG does not know if a pointer is a simple reference or an array –Creates compilable code and importable module, but not particularly useful –Package should be designed so that python users can use a reasonable container whenever C arrays are expected in the underlying code –Numeric has an array constructor that takes a generic PyObject... use %typemap or %extend Python can and does return multiple values via tuples: –(a,b,c) = f(x) –SWIG provides %typemap for doing this Integer return codes? –Python has always supported exception handling –I have changed some methods to raise exceptions if non-zero return codes are detected Look at other packages or talk to me

“Pythonification” of Your Package Trilinos parameter lists and python dictionaries are functionally equivalent Python dictionaries have very clean syntax Goal: anywhere a parameter list is expected, accept a python dictionary in its place Current status: –Some packages have been extended –Data type support is limited –Input only Caveat: SWIG cannot wrap Teuchos::Parameter:: List because it cannot handle nested classes RefCountPtrs should be transparent to users…

The PyTrilinos Package Formerly, all python interfaces were in the PyTrilinos package Currently a compiled C++ library –Callback(cross-language polymorphism) –FileStream(python/C files and streams) –NumPyArray(interface for Numeric and C++) –NumPyWrapper Plan to move these classes to Teuchos PyTrilinos will then become a “cleanup” package that generates a valid __init__.py file for the entire package –from PyTrilinos import *

Bugzilla Those packages that have python wrappers now have a component in bugzilla called “Python wrappers” I am the default assignee for these bugs… Bugs for the PyTrilinos package should be rare Not perfect: build errors for python interfaces should be filed under…what?

Test Harness Python test scripts are run nightly –beowulf (serial, mpi) –s (serial, mpi) –Plans to expand Python (and Thyra) have their own Special Test Sets MPI exit status is robust for test directories (not example) Plans for separate python (and thyra) builds (minimize impact) I am working to expand test coverage and eliminate test duplication…

The “To Do” List Handling C arrays –SWIG library numeric.i –Package by package, class by class, method by method Parameter lists –(Teuchos::Parameter::List/PyObject) class –Implement Handling Teuchos::RefCountPtrs Test and example scripts PyTrilinos refactor –Move PyTrilinos classes to Teuchos –Change PyTrilinos to be a “clean up” package Robustness –Portability, parallelism, advanced features Documentation New Packages…

References Python – distutils documentation unittest documentation SWIG – Online documentation PyTrilinos – –CVS: Trilinos/packages/PyTrilinos/doc