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);