/** * PAPI counter library. The available counters are platform dependent. * It has been tested on the sequential and smp backend. There is a know * problem on the smp backend. When TI_PFORP is set with m/n, where m > n, * there is a race condition in the PAPI start method. This problem does * not occur when m = n */ public class PAPICounter{ private int event; private long accumulated_counter1; private int eventSet; private int state; private static final int IDLE = 0; private static final int RUNNING = 1; private static String[] errorMessage = initErrorMes(); /** * PAPI constants for preset events */ public static final int PAPI_L1_DCM = 0x80000000; public static final int PAPI_L1_ICM = 0x80000001; public static final int PAPI_L2_DCM = 0x80000002; public static final int PAPI_L2_ICM = 0x80000003; public static final int PAPI_L3_DCM = 0x80000004; public static final int PAPI_L3_ICM = 0x80000005; public static final int PAPI_L1_TCM = 0x80000006; public static final int PAPI_L2_TCM = 0x80000007; public static final int PAPI_L3_TCM = 0x80000008; public static final int PAPI_CA_SNP = 0x80000009; public static final int PAPI_CA_SHR = 0x8000000a; public static final int PAPI_CA_CLN = 0x8000000b; public static final int PAPI_CA_INV = 0x8000000c; public static final int PAPI_CA_ITV = 0x8000000d; public static final int PAPI_L3_LDM = 0x8000000e; public static final int PAPI_L3_STM = 0x8000000f; public static final int PAPI_BRU_IDL = 0x80000010; public static final int PAPI_FXU_IDL = 0x80000011; public static final int PAPI_FPU_IDL = 0x80000012; public static final int PAPI_LSU_IDL = 0x80000013; public static final int PAPI_TLB_DM = 0x80000014; public static final int PAPI_TLB_IM = 0x80000015; public static final int PAPI_TLB_TL = 0x80000016; public static final int PAPI_L1_LDM = 0x80000017; public static final int PAPI_L1_STM = 0x80000018; public static final int PAPI_L2_LDM = 0x80000019; public static final int PAPI_L2_STM = 0x8000001a; public static final int PAPI_BTAC_M = 0x8000001b; public static final int PAPI_PRF_DM = 0x8000001c; public static final int PAPI_L3_DCH = 0x8000001d; public static final int PAPI_TLB_SD = 0x8000001e; public static final int PAPI_CSR_FAL = 0x8000001f; public static final int PAPI_CSR_SUC = 0x80000020; public static final int PAPI_CSR_TOT = 0x80000021; public static final int PAPI_MEM_SCY = 0x80000022; public static final int PAPI_MEM_RCY = 0x80000023; public static final int PAPI_MEM_WCY = 0x80000024; public static final int PAPI_STL_ICY = 0x80000025; public static final int PAPI_FUL_ICY = 0x80000026; public static final int PAPI_STL_CCY = 0x80000027; public static final int PAPI_FUL_CCY = 0x80000028; public static final int PAPI_HW_INT = 0x80000029; public static final int PAPI_BR_UCN = 0x8000002a; public static final int PAPI_BR_CN = 0x8000002b; public static final int PAPI_BR_TKN = 0x8000002c; public static final int PAPI_BR_NTK = 0x8000002d; public static final int PAPI_BR_MSP = 0x8000002e; public static final int PAPI_BR_PRC = 0x8000002f; public static final int PAPI_FMA_INS = 0x80000030; public static final int PAPI_TOT_IIS = 0x80000031; public static final int PAPI_TOT_INS = 0x80000032; public static final int PAPI_INT_INS = 0x80000033; public static final int PAPI_FP_INS = 0x80000034; public static final int PAPI_LD_INS = 0x80000035; public static final int PAPI_SR_INS = 0x80000036; public static final int PAPI_BR_INS = 0x80000037; public static final int PAPI_VEC_INS = 0x80000038; public static final int PAPI_FLOPS = 0x80000039; public static final int PAPI_RES_STL = 0x8000003a; public static final int PAPI_FP_STAL = 0x8000003b; public static final int PAPI_TOT_CYC = 0x8000003c; public static final int PAPI_IPS = 0x8000003d; public static final int PAPI_LST_INS = 0x8000003e; public static final int PAPI_SYC_INS = 0x8000003f; public static final int PAPI_L1_DCH = 0x80000040; public static final int PAPI_L2_DCH = 0x80000041; public static final int PAPI_L1_DCA = 0x80000042; public static final int PAPI_L2_DCA = 0x80000043; public static final int PAPI_L3_DCA = 0x80000044; public static final int PAPI_L1_DCR = 0x80000045; public static final int PAPI_L2_DCR = 0x80000046; public static final int PAPI_L3_DCR = 0x80000047; public static final int PAPI_L1_DCW = 0x80000048; public static final int PAPI_L2_DCW = 0x80000049; public static final int PAPI_L3_DCW = 0x8000004a; public static final int PAPI_L1_ICH = 0x8000004b; public static final int PAPI_L2_ICH = 0x8000004c; public static final int PAPI_L3_ICH = 0x8000004d; public static final int PAPI_L1_ICA = 0x8000004e; public static final int PAPI_L2_ICA = 0x8000004f; public static final int PAPI_L3_ICA = 0x80000050; public static final int PAPI_L1_ICR = 0x80000051; public static final int PAPI_L2_ICR = 0x80000052; public static final int PAPI_L3_ICR = 0x80000053; public static final int PAPI_L1_ICW = 0x80000054; public static final int PAPI_L2_ICW = 0x80000055; public static final int PAPI_L3_ICW = 0x80000056; public static final int PAPI_L1_TCH = 0x80000057; public static final int PAPI_L2_TCH = 0x80000058; public static final int PAPI_L3_TCH = 0x80000059; public static final int PAPI_L1_TCA = 0x8000005a; public static final int PAPI_L2_TCA = 0x8000005b; public static final int PAPI_L3_TCA = 0x8000005c; public static final int PAPI_L1_TCR = 0x8000005d; public static final int PAPI_L2_TCR = 0x8000005e; public static final int PAPI_L3_TCR = 0x8000005f; public static final int PAPI_L1_TCW = 0x80000060; public static final int PAPI_L2_TCW = 0x80000061; public static final int PAPI_L3_TCW = 0x80000062; public static final int PAPI_FML_INS = 0x80000063; public static final int PAPI_FAD_INS = 0x80000064; public static final int PAPI_FDV_INS = 0x80000065; public static final int PAPI_FSQ_INS = 0x80000066; public static final int PAPI_FNV_INS = 0x80000067; private static native int PAPI_initSingleEvent(int event1, int tag); private static native void PAPI_init(); private static native void PAPI_shutdown(); private static native void PAPI_start(int eventSet); private static native long PAPI_stop(int eventSet, long value); private static native int PAPI_checkEvent(int event); private static native int PAPI_cleanup(int tag); /** * PAPICounter constructor * @param event a PAPI preset event constant */ public PAPICounter(int event) { PAPI_init(); if (!checkEvent(event)){ throw new EventNotAvailException(event); } this.event = event; state = IDLE; accumulated_counter1 = 0; } private static String[] initErrorMes(){ String[] tmp = new String[11]; tmp[0] = "PAPI library init"; tmp[1] = "PAPI multiplex init"; tmp[2] = "PAPI set debug"; tmp[3] = "PAPI thread init"; tmp[4] = "PAPI event not available on this platform"; tmp[5] = "PAPI create event set"; tmp[6] = "PAPI add event"; tmp[7] = "PAPI start"; tmp[8] = "PAPI stop"; tmp[9] = "PAPI clean up"; tmp[10] = "PAPI destroy event set"; return tmp; } /** * returns true if event is available, false otherwise * @param event a PAPI preset event constant */ public boolean checkEvent(int event){ if (PAPI_checkEvent(event) == 1){ return true; } else{ return false; } } private void setup(){ eventSet = 0; eventSet = PAPI_initSingleEvent(event, eventSet); } /** * Starts the PAPI counter. Can only be called when counter is idle, * otherwise an exception is thrown */ public void start() { if (!this.isLocal()){ throw new CounterNotLocalException(); } if (state == RUNNING){ throw new PAPIException("Can not call start when counter is running"); } setup(); PAPI_start(eventSet); state = RUNNING; } /** * Stops the PAPI counter. Can only be called when counter is running, * otherwise an exception is thrown */ public void stop() { long value; if (!this.isLocal()){ throw new CounterNotLocalException(); } if (state == IDLE){ throw new PAPIException("Can not call stop when counter is idle"); } value = PAPI_stop(eventSet, value); accumulated_counter1 += value; cleanup(); state = IDLE; } /** * Clears the accumulated value for the counter. Can only be called * when counter is idle, otherwise an exception is thrown */ public void clear(){ if (state == RUNNING){ throw new PAPIException("Can not clear counter when counter is running"); } accumulated_counter1 = 0; } private void cleanup(){ eventSet = PAPI_cleanup(eventSet); } /** * Returns the accumulated value for the counter. Can only be called * when counter is idle, otherwise an exception is thrown */ public long getCounterValue(){ if (state == RUNNING){ throw new PAPIException("Can not get counter value when counter is running"); } return accumulated_counter1; } private static void throwTooManyCounterException() { throw new TooManyCounterException(); } private static void throwPAPIException(int eventType, int errorCode){ throw new PAPIException(errorMessage[eventType] + " with error code " + errorCode); } } class EventNotAvailException extends RuntimeException{ public EventNotAvailException(int event){ super("Event " + event + " is not available on this platform"); } } class TooManyCounterException extends RuntimeException{ public TooManyCounterException(){ super("There are too many counters in use"); } } class CounterNotLocalException extends RuntimeException{ public CounterNotLocalException(){ super(); } } class PAPIException extends RuntimeException{ public PAPIException(String s){ super(s); } }