libmsr_write_test

This test demonstrates the ability of PAPI to use libmsr to read and
write RAPL MSRs to gather energy information and apply power
constraints.

See the instructions in the libmsr directory to build the component.

It works by using PAPI to read RAPL information from libmsr and write
it to a file.  The code repeatedly runs an OpenMP multithreaded
routine (primes) to stress the CPU.  The routine is called 100 times,
and at each call the power measurements are read using
PAPI_read(EventSet, values) and printed to a file.  At every 10th call
the power caps for the power packages are adjusted using
PAPI_write(EventSet, values ).

Build and run the test as follows
   cd components/libmsr/utils/ 
   make clean && make 
   ./libmsr_write_test
Generate a figure from the output file (libmsr_write_test_output.txt) using gnuplot.  
   sh ./libmsr_write_test.sh

In the output file, you can see the power values that are SET and the
power values that are READ.  By comparing them you can confirm that
the component is performing as expected.

Note: To set the power limit for PKG_POWER_LIMIT_{1,2}:PACKAGE_{NN}
requires a value for PKG_TIME_WINDOW_POWER_LIMIT_{1,2}:PACKAGE_{NN}.
This is because the power caps need to be set to average over some
given time window.

Note: For some CPUs, only setting/writing PKG_POWER_LIMIT_1 will have
effect.  Setting PKG_POWER_LIMIT_2 will not have any effect.

Note: For some CPUs, the power constraint written for one package
applies to all packages/sockets.  So the last power constraint written
will be the one that is used for all the packages.

The following is not executable code, but should give an idea of how
to use PAPI to write event values.

   PAPI_create_eventset( &EventSet );
   PAPI_add_named_event( EventSet, "libmsr:::PKG_WATTS:PACKAGE1" );
   PAPI_add_named_event( EventSet, "libmsr:::PKG_POWER_LIMIT_1:PACKAGE1" );
   PAPI_add_named_event( EventSet, "libmsr:::PKG_TIME_WINDOW_POWER_LIMIT_1:PACKAGE1" );
   
   PAPI_start( EventSet );
   PAPI_read( EventSet, values );
   
   // Note: the libmsr RAPL values are double precision and PAPI expects long long integers.
   // You can use a union to handle the type conversion 
   // union { long long ll; double dbl; } tmp_ll_dbl;
   
   values[0]=PAPI_NULL;  // PKG_WATTS is not writable; value is ignored; or use PAPI_NULL
   tmp_ll_dbl.dbl = 45.0  // use a union to transfer data between PAPI and libmsr
   values[1]=tmp_ll_dbl.ll;    // PKG_POWER_LIMIT_1 average Watts to be written 
   values[2]=put_double_in_long_long_storage(1.0); // PKG_TIME_WINDOW_POWER_LIMIT_1 averaged over 1 second 
   PAPI_write( EventSet, values );

   PAPI_read( EventSet, values);
   // print some output remembering to convert between PAPI long long ints and the double values
   printf( "Power %lf\n", get_double_from_long_long_storage(values[0]);

   retval = PAPI_stop( EventSet, values);
