|
| 1 | +Python API to the MPI Standard |
| 2 | +############################## |
| 3 | + |
| 4 | +This tutorial is intended to teach how to use the Python API of the MPI Standard. |
| 5 | + |
| 6 | +Structure of the MPI Standard |
| 7 | +***************************** |
| 8 | + |
| 9 | +The Python usage in the MPI Standard is varied. |
| 10 | + |
| 11 | +The Python Domain Specific Language (DSL): We use the DSL to specify and encode the information in the MPI Standard through *mpi-binding* latex blocks. This facilitates that the "truth" remains within the Latex of the Standard. |
| 12 | + |
| 13 | +The Python API *pympistandard* (./pympistandard) is the package by which access to the DSL encoded information is given to tools. |
| 14 | + |
| 15 | +The tools which operate on the DSL encoded information are also written in Python (although they could be written in any language). This includes the binding_prepass (binding-tool/binding_prepass), binding_tool (tools/binding_tool), binding_linter (binding-tool/binding_linter), etc. |
| 16 | + |
| 17 | +Finally, the testing of both the binding_tool, DSL, and text of the MPI Standard are partially done in Python (test/). |
| 18 | + |
| 19 | +How to start using the Python API |
| 20 | +********************************* |
| 21 | + |
| 22 | +The goal of the Python API is to provide access to all information in the MPI Standard as easily as possible. Therefore importing the pympistandard package is done the typical python way, either by exporting the PYTHONPATH or having the pympistandard package on a standard path. The current solution is to have PYTHONPATH correctly exported. |
| 23 | + |
| 24 | +To have functioning setup do: |
| 25 | + |
| 26 | +#. change directory to the mpi-standard directory containing the version which you want to access programatically |
| 27 | +#. ``make`` (at least past the rendering such that the apis.json file exists) |
| 28 | +#. ``export PYTHONPATH=$(pwd)`` |
| 29 | + |
| 30 | +At this point the following should be possible within a python interpreter: |
| 31 | + |
| 32 | +.. sourcecode:: |
| 33 | + |
| 34 | + import pympistandard |
| 35 | + |
| 36 | +.. toctree:: |
| 37 | + :maxdepth: 2 |
| 38 | + |
| 39 | + procedure |
| 40 | + |
| 41 | +The Python API |
| 42 | +************** |
| 43 | + |
| 44 | +After importing the pympistandard package no information is yet loaded. One must first do: |
| 45 | + |
| 46 | +.. sourcecode:: |
| 47 | + |
| 48 | + pympistandard.use_api_version(1) |
| 49 | + |
| 50 | +This loads the information contained in the MPI Standard using the first API version. |
| 51 | + |
| 52 | +In future, other versions of the API will be accessible and a deprecation warning will be given. Extensions will not merit a new version, only backwards compatibility breaking changes. Once the ``use_api_version`` has been called the information is read into the global variables, at which point all information in the Standard will be accessible. |
| 53 | + |
| 54 | +.. sourcecode:: |
| 55 | + |
| 56 | + import pympistandard as std |
| 57 | + std.use_api_version(1) |
| 58 | + |
| 59 | +The top-level package contains **PROCEDURES**, **KINDS**, **CALLBACKS**, **PREDEFINED_FUNCTIONS** (the names are subject to change). |
| 60 | + |
| 61 | +* PROCEDURES are all MPI procedures such as MPI_Send, MPI_Wait, MPI_Allreduce, MPI_Init, ... |
| 62 | +* KINDS are all the different KINDS which are currently specified within the MPI Standard (these are subject to major revisions) |
| 63 | +* CALLBACKS are all callback functions which are given as Kinds, these provide access to the expressions instead of just a label like the corresponding KIND |
| 64 | +* PREDEFINED_FUNCTIONS are the predefined callback functions provided by the MPI Standard and its implementations |
| 65 | + |
| 66 | +Using the Python API |
| 67 | +******************** |
| 68 | + |
| 69 | +The global containers can be accessed using the dot notation or the dictionary access: |
| 70 | + |
| 71 | +.. sourcecode:: |
| 72 | + |
| 73 | + mpi_send = std.PROCEDURES.mpi_send |
| 74 | + |
| 75 | + mpi_send = std.PROCEDURES["mpi_send"] |
| 76 | + |
| 77 | +Capitalisation is ignored. `MPI_SEND` is the same as `mpi_send`. |
| 78 | + |
| 79 | +Checking membership of in a container can be done with: |
| 80 | + |
| 81 | +.. sourcecode:: |
| 82 | + |
| 83 | + "mpi_send" in std.PROCEDURES |
| 84 | + mpi_send in std.PROCEDURES |
| 85 | + |
| 86 | +Another method to fetch Procedure/Callback/PredefinedFunction objects is through the provided iterators. Iterators are currently available for all Procedures expressible in a given language: |
| 87 | + |
| 88 | +.. sourcecode:: |
| 89 | + |
| 90 | + count_initializing_iso_c_procedures = sum(procedure.express.iso_c.is_initializing() for procedure in std.all_iso_c_procedures()) |
| 91 | + |
| 92 | +*Currently, is_initializing does not exist.* |
| 93 | + |
| 94 | +Language Agnostic Information |
| 95 | +***************************** |
| 96 | + |
| 97 | +The above `mpi_send` object is a Procedure object which encapsulates all information which is generic to the MPI Procedure MPI\_Send. In future this will include all sorts of information such as the initialising, starting, completing, and freeing behaviour of a specific procedure. Currently the properties are `has_embiggenment` and `has_proxy_render`. |
| 98 | + |
| 99 | +Language Expressions |
| 100 | +******************** |
| 101 | + |
| 102 | +In addition to language agnostic information about the MPI Procedure the object provides access to expressions of the Procedure. An expression is a form of the Procedure in a specific language officially standardised by the MPI Forum through the MPI Standard. To access the ISO C expression of the _MPI\_Send_ procedure you would do: |
| 103 | + |
| 104 | +.. sourcecode:: |
| 105 | + |
| 106 | + c_send = std.PROCEDURES.mpi_send.express.iso_c |
| 107 | + |
| 108 | +The `c\_send` object is a ISOCProcedure. The language specific procedure objects allow access to properties which are specific to a language. For example, ISO C procedures may use uppercase indexing in the MPI Standard therefore the `has_uppercase_index` property is provided within the ISOCProcedure. |
| 109 | + |
| 110 | +In addition to language specific properties the expression in the language is enabled through this object. Access to parameters, return type/kind, and name is given: |
| 111 | + |
| 112 | +.. sourcecode:: |
| 113 | + |
| 114 | + c_send.name # 'MPI_Send' |
| 115 | + c_send.return_type # 'int' |
| 116 | + |
| 117 | +Parameters are accessed as objects themselves: |
| 118 | + |
| 119 | +.. sourcecode:: |
| 120 | + |
| 121 | + names = (parameter.name for parameter in c_send.parameters) # ('buf', 'count', 'datatype', 'dest', 'tag', 'comm') |
| 122 | + |
| 123 | +Parameters also provide all properties associated with them and can be access through the object. |
| 124 | + |
| 125 | +Not all Procedures are expressed in all languages. Therefore when an attempt is made to access an expression which does not exist a Nonetype is returned: |
| 126 | + |
| 127 | +.. sourcecode:: |
| 128 | + |
| 129 | + std.PROCEDURES.mpi_sizeof.iso_c # None |
| 130 | + |
| 131 | +Other Expressions |
| 132 | +***************** |
| 133 | + |
| 134 | +The expressions are not only related to the language in which a binding is expressed, but also the type of binding. For example, the profiling interface of MPI specifies many PMPI prefixed procedures which can be accessed through: |
| 135 | + |
| 136 | +.. sourcecode:: |
| 137 | + |
| 138 | + pmpi_send = std.PROCEDURES.mpi_send.profile.iso_c |
| 139 | + pmpi_send.name # 'PMPI_Send' |
| 140 | + |
| 141 | +Another large expression subset is the embiggened procedures: |
| 142 | + |
| 143 | +.. sourcecode:: |
| 144 | + |
| 145 | + mpi_send_c = std.PROCEDURES.mpi_send.embiggen.iso_c |
| 146 | + mpi_send_c.name # 'MPI_Send_c' |
| 147 | + |
| 148 | +These expression attributes can be combined arbitrarily: `mpi_send.profile.embiggen.iso_c`. If a valid configuration is chosen an object representing the properties and expression will be returned. If not a Nonetype will be returned. |
| 149 | + |
| 150 | +Instead of accessing the expressions through the dot notation you can also choose to have an iterable over all expressions of a language: |
| 151 | + |
| 152 | +.. sourcecode:: |
| 153 | + |
| 154 | + print(std.PROCEDURES.mpi_send.express.all_iso_c) |
| 155 | + |
| 156 | + # (<pympistandard.isoc.ISOCProcedure object at 0x10ee9ef10>, |
| 157 | + # <pympistandard.isoc.ProfilingISOCProcedure object at 0x10ee9eeb0>, |
| 158 | + # <pympistandard.isoc.EmbiggenedISOCProcedure object at 0x10ee9ed30>, |
| 159 | + # <pympistandard.isoc.EmbiggenedProfilingISOCProcedure object at 0x10ee9ed90>) |
0 commit comments