[Pooma Logo]


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 arguments types i.e., a string comprising of its return type and the type of its arguments.

Adding Instrumentation

Within the application, use the Profiling API for all the functions that need to be profiled.

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 which can be selectively enabled for profiling at runtime. This is discussed at length in the selective profiling section . 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, while 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 over using sprintf to generate strings because it adds no runtime overhead when profiling is disabled. In addition, TAU_TYPE_STRING is executed only once for each function while the strings generated can be of any arbitrary length.

Compiling and Running the Profiled Application

Compile the library, pprof and the application.

% cd $(POOMA_ROOT)/lib/$(POOMA_ARCH)
% make

% cd $(POOMA_ROOT)/src/Profile/utils
% make

Settings for pprof and racy

Add to your .cshrc file
# in .cshrc file
        set path=($path $POOMA_ROOT/src/Profile/utils)
# For racy to see the Profile data on ACL SGI machines
        set path=($path /usr/local/packages/tau/bin/sgi8k)
# setenv PROFILEDIR ./data

PROFILEDIR environment variable specifies the location where profile files are stored (default is the current directory).

Make the application
% cd $(POOMA_ROOT)/test/particle
% make PIC2d

And Run the application
% mpirun -np 8 PIC2d  --commlib mpi

This generates files named profile.[node].[context].[thread] e.g., profile.7.0.0 .
[PREV] [Back to tutorial] [NEXT]