#include "mex.h" #include "matrix.h" #include "papi.h" static long long accum_error = 0; static long long start_time = 0; void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { float real_time, proc_time, rate; double *x; unsigned int mrows, ncols; int result; unsigned int flop_events[2]; long long ins = 0, flop_values[2]; long long elapsed_time; /* Check for proper number of arguments. */ if(nrhs > 1) { mexErrMsgTxt("This function expects one optional input."); } else if(nlhs > 2) { mexErrMsgTxt("This function produces 1 or 2 outputs: [ops, mflops]."); } /* The input must be a noncomplex scalar double.*/ if(nrhs == 1) { mrows = mxGetM(prhs[0]); ncols = mxGetN(prhs[0]); if(!mxIsDouble(prhs[0]) || mxIsComplex(prhs[0]) || !(mrows == 1 && ncols == 1)) { mexErrMsgTxt("Input must be a noncomplex scalar double."); } /* Assign a pointer to the input. */ x = mxGetPr(prhs[0]); /* if input is 0, reset the counters by calling PAPI_stop_counters with 0 values */ if(*x == 0) { if (start_time == 0) { PAPI_stop_counters(NULL, 0); accum_error = 0; } else { start_time = 0; PAPI_stop_counters(flop_values, 2); } } } if(result = PAPI_event_name_to_code("EMON_SSE_SSE2_COMP_INST_RETIRED_PACKED_DOUBLE", &(flop_events[0])) < PAPI_OK) { if(result = PAPI_flops( &real_time, &proc_time, &ins, &rate) 0) { plhs[0] = mxCreateScalarDouble((double)(ins - accum_error)); /* this call adds 7 fp instructions to the total */ /* but apparently not on Pentium M with Matlab 7.0.4 */ // accum_error += 7; if(nlhs == 2) { plhs[1] = mxCreateScalarDouble((double)rate); /* the second call adds 4 fp instructions to the total */ /* but apparently not on Pentium M with Matlab 7.0.4 */ // accum_error += 4; } } }