Tutorial

Instrumenting the sources for Profiling

Adding Profiling calls to the functions ensures the profiling data is generated for that function. A function is uniquely identified by its name and its type arguments i.e., a string comprising of its return type and the type of its arguments.

Adding Instrumentation

In the application, for all the functions that need to be profiled use the Profiling API:

TAU_PROFILE(char *func_name, char *type_info, uint profile_group);
TAU_TYPE_STRING(string_varname, cstring& str);
TAU_PROFILE_TIMER(var, name, type, group);
TAU_PROFILE_START(var);
TAU_PROFILE_STOP(var);
TAU_PROFILE_STMT(stmt);
TAU_PROFILE_INIT(argc, argv);
TAU_PROFILE_SET_NODE(myNode);
TAU_PROFILE_EXIT(const char *message);

In the application, several related functions can be grouped together to form a profile group that can be selectively enabled for profiling at runtime. This is discussed at length later . In the TAU_TYPE_STRING macro, the type string generated can be retrieved using string_varname for use in the second argument of TAU_PROFILE . TAU_PROFILE_STMT is used typically to declare a variable that is used only while profiling. TAU_PROFILE_INIT macro is used to set profile groups and TAU_PROFILE_SET_NODE is used to set the current node id (both are called by framework). TAU_PROFILE_EXIT is called by any thread prior to calling exit(), if it wants to dump the profiling data to disk before exiting.

For e.g.,

        int main(int argc, char **argv)
        {
          TAU_PROFILE("main", "int (int, char **)", TAU_DEFAULT);
          TAU_PROFILE_TIMER(timer1,"main-loop1", "int (int, char **)", TAU_USER);
          TAU_PROFILE_TIMER(timer2,"main-loop2", "int (int, char **)", TAU_USER);


	  TAU_PROFILE_START(timer1);
	  for(i=0; i < N; i++)  { // loop1 profiled using timer1 var 
		}
	  TAU_PROFILE_STOP(timer1);

	  ...
	  TAU_PROFILE_START(timer2);
	  for(j=0; j < N; j++) { //loop2 profiled using timer2 var 
		}
	  TAU_PROFILE_STOP(timer2);

        ...
        }

        template <class T>
        class MyClass {
          public :
  	  T Data;
          int MyFunc(T * x) {
            TAU_PROFILE("MyClass::Myfunc", typeid(MyFunc).name(), TAU_USER1);
            // Or use typeid(*this).name() in to get type info of class
           ... }

	// member template of a class template
	template <class Dim>
	T SetDataTemplMem (Dim dimen, T dat) {

	  TAU_TYPE_STRING(p1, CT(Data) + " (" + CT(dimen) + ", " + CT(dat) + ")");

  	  // produces a string like "int (int, double)" at runtime
	  TAU_PROFILE("TemplClass::SetDataTemplMem()", p1, TAU_USER2);

	  Data = dat * dimen;
	  return Data;
 	}

        };

This example is covered in greater detail in the examples section later.
Note: The use of TAU_TYPE_STRING macro is highly recommended as opposed to using sprintf to generate strings, as it adds no runtime overhead when profiling is disabled. Also, this call gets executed only once for each function and the strings generated can be of any arbitrary length.

Compiling and Running the Profiled Application

TAU configuration generates a Makefile stub as well as a library. The Makefile name has the form Makefile.tau-<options> the library name the form libtau-<options>a. For example,
%./configure -TRACE -c++=KCC -arch=sgin32
generates Makefile.tau-trace-kcc libtau-trace-kcc.a in tau-2.x/sgin32/lib Using different configuration options, several modular libraries can be built and co-exist even in the same architecture. To choose a particular version of the library, the corresponding Makefile stub must be included in the application Makefile. The stub Makefile defines the following variables:

TAU_CXX           for the C++ compiler
TAU_CC            for the C compiler 
TAU_INCLUDE       for the include directories 
TAU_DEFS          for the defines on the command-line 
TAU_LIBS          for the TAU library
TAU_MPI_INCLUDE   for the directory where MPI header files reside
TAU_MPI_LIBS      for the TAU MPI library with the mpi libraries for C/C++
TAU_MPI_FLIBS     for the TAU MPI library with mpi libraries for Fortran
TAU_FORTRANLIBS   for additional fortran libraries for linking with C++
TAU_DISABLE       for the default TAU stub library for Fortran, and 
USER_OPT          for any user defined options specified during configuration
A typical makefile that uses these Makefile variables is shown below:
TAUROOTDIR      = /usr/local/packages/tau-2.x
include $(TAUROOTDIR)/sgin32/lib/Makefile.tau-trace-kcc 
CXX             = $(TAU_CXX) 
CC              = $(TAU_CC) 
CFLAGS          = $(TAU_INCLUDE) $(TAU_DEFS) 
LIBS            = $(TAU_LIBS) -lmpi
LDFLAGS         = $(USER_OPT) 
MAKEFILE        = Makefile
PRINT           = pr
RM              = /bin/rm -f
TARGET          = matrix
EXTRAOBJS       = 
##############################################
all:            $(TARGET)
install:        $(TARGET)
$(TARGET):      $(TARGET).o
        $(CXX) $(LDFLAGS) $(TARGET).o -o $@ $(LIBS)
$(TARGET).o : $(TARGET).cpp
        $(CXX) $(CFLAGS) -c $(TARGET).cpp
clean:
        $(RM) $(TARGET).o $(TARGET)
##############################################
To use a different configuration, simply change the included makefile to some other. For example, for
% ./configure -pthread -arch=sgi64 
substitute
include $(TAUROOTDIR)/sgi64/lib/Makefile.tau-pthread
in the makefile above. Also,
$(TAUROOTDIR)/include/Makefile
points to the most recently configured version of the library.

Settings for pprof/racy

Add to your .cshrc file
# in .cshrc file
        set path=($path /usr/local/packages/tau-2.x/<arch>/bin)
# setenv PROFILEDIR ./data

PROFILEDIR environment variable specifies the location where profile files are stored (default is the current directory).
Executing the instrumented program generates files named profile.[node].[context].[thread] e.g., profile.7.0.0 in the directory specified by the environment variable PROFILEDIR, if profiling is enabled.