int pupc_control(int on) { return gasp_control(__gasp_ctx, on); }
This page is meant to provide a guide to GASP implementors on the steps necessary to add GASP support to their GAS model implementation. If you have any questions, feel free to email leko AT hcs DOT ufl DOT edu (email address mangled to protect against SPAM) for further clarification.
The simplest and most effective strategy to add GASP support to your GAS language/model implementation is to first begin by adding a “vacuous” implementation that provides the minimum possible support for GASP compliance. Then, add events defined in the GASP spec (eg, section 5.4) into the compiler or runtime starting with the most important events for your platform as your development schedule permits. Finally, add any relevant implementation-specific events.
To add the minimum amount necessary to be able to claim basic GASP support, you'll need to do the following:
Add the gasp.h, gasp_upc.h, and pupc.h headers to your compiler system and make sure they are put in the compiler's search path when your implementation is installed. To aid here, we have provided versions of gasp.h and pupc.h that you can simply drop into your implementation after adding any necessary legalese to the header files. We also have a skeleton version of gasp_upc.h that you can use as a starting point to define your supported GASP system events. Be sure to adjust GASP_UPC_VERSION in gasp_upc.h to something appropriate, and remember to bump that number on subsequent revisions of your GASP implementation.
Predefine the __UPC_PUPC__ macro in your compiler, or make a note that GASP wrapper scripts should define it on the command line (eg, pass -D__UPC_PUPC__=1 as a compilation argument).
Modify your compiler frontend / driver to accept the --inst, --inst-local, and --inst-functions flags. Note that in your vacuous implementation your compiler can actually ignore these flags, but for a useful implementation you'll eventually want these flags to do something. If the flags do not fit with your compiler's existing scheme, feel free to choose something else appropriate, but be sure to document the names somewhere (gasp.h or gasp_upc.h would be appropriate). If adding compiler flags is difficult, an alternate mechanism is to define some environment variables that the tool's compiler wrapper script can set to enable the instrumentation features of the compiler (eg UPC_INST=1, UPC_INST_LOCAL=1, etc.). Just be sure to document (for tool developers) the mechanism they need to use to enable instrumentation.
Modify your compiler to accept or ignore any #pragma pupc directives without spitting out an annoying error message.
Modify your compiler or runtime library to call gasp_init after your language system has been bootstrapped. A vacuous implementation should also consider firing the UPC_COLLECTIVE_EXIT event, but since the spec says all events are optional this isn't strictly necessary (just useful for testing).
Modify your compiler to translate calls to the pupc functions into the corresponding gasp calls, or provide function definitions that do the same. As an example, if you store your GASP context pointer in a thread-local data structure/macro named __gasp_ctx and source information is available in the THESRC, THELINE, and THECOL macros, you could add the following to your standard library:
int pupc_control(int on) { return gasp_control(__gasp_ctx, on); }
unsigned int pupc_create_event(const char *name, const char *desc) { return gasp_create_event(__gasp_ctx, name, desc); }
void pupc_event_start(unsigned int evttag, ...) { va_list argptr; va_start(argptr, evttag); gasp_event_notifyVA(__gasp_ctx, evttag, GASP_START, THESRC, THELINE, THECOL, argptr); va_end(argptr); }
void pupc_event_end(unsigned int evttag, ...) { va_list argptr; va_start(argptr, evttag); gasp_event_notifyVA(__gasp_ctx, evttag, GASP_END, THESRC, THELINE, THECOL, argptr); va_end(argptr); }
void pupc_event_atomic(unsigned int evttag, ...) { va_list argptr; va_start(argptr, evttag); gasp_event_notifyVA(__gasp_ctx, evttag, GASP_ATOMIC, THESRC, THELINE, THECOL, argptr); va_end(argptr); }
Note that although the vacuous implementation strategy outlined above is strictly sufficient to claim GASP compliance (because all events are officially optional), in practice a GASP implementation is only useful to end-users once you add instrumentation to report performance events of likely interest to the measurement tool and end-user. At the minimum, adding the instrumentation events described in GASP Spec section 5.4 for UPC puts and gets, upc_mem{put,get,cpy} and upc_{notify,wait,barrier} is highly recommended in order to actually generate useful performance results about communication in many UPC applications.
As another aid to GASP implementors, we are making a simple testing tool called “gasp-dump” available. This tool was written by Dan Bonachea to test out GASP support in Berkeley UPC during its implementation. The tool dumps out all known GASP events to one log file per thread, and is useful for checking your GASP implementation out against real UPC programs. A simple UPC program (also written by Dan) is included in the tarball that exercises most of the interface.
You can download the tool here.
While adding GASP support into GCC UPC, we kept a detailed implementation log which might be useful or insightful for other GASP language implementors.