package papi

  1. Overview
  2. Docs
Legend:
Library
Module
Module type
Parameter
Class
Class type

Performance Application Programming Interface (PAPI) bindings.

This module binds <papi.h>. PAPI provides portable access to hardware performance counters. For more information, see the homepage.

Note. All functions in this module except shutdown raise Error whenever the underlying PAPI call signals an error.

Note. All functions except init and shutdown raise Error (ENOINIT, _) before initialisation.

For examples of use, consult examples.

v0.1.0 — homepage

Errors

type error =
  1. | EINVAL
  2. | ENOMEM
  3. | ESYS
  4. | ECMP
  5. | ECLOST
  6. | EBUG
  7. | ENOEVNT
  8. | ECNFLCT
  9. | ENOTRUN
  10. | EISRUN
  11. | ENOEVST
  12. | ENOTPRESET
  13. | ENOCNTR
  14. | EMISC
  15. | EPERM
  16. | ENOINIT
  17. | ENOCMP
  18. | ENOSUPP
  19. | ENOIMPL
  20. | EBUF
  21. | EINVAL_DOM
  22. | EATTR
  23. | ECOUNT
  24. | ECOMBO
    (*

    PAPI errors.

    See the header file papi.h for descriptions of errors.

    *)
exception Error of error * string

PAPI errors are signalled by raising Error ((err, fname)), where fname is the name of the failing function.

val pp_error : Format.formatter -> error -> unit

pp_error ppf err pretty-prints err on ppf.

val pp_exn_error : Format.formatter -> (error * string) -> unit

pp_exn_error ppf arg pretty-prints the Error argument arg on ppf.

Initialisation

val init : unit -> unit

Initializes PAPI by calling PAPI_library_init. Idempotent: repeated calls are ignored.

val shutdown : unit -> unit

Releases PAPI state by calling PAPI_shutdown. Idempotent.

val hw_counters : unit -> int

hw_counters () is the number of available hardware counters.

Events

type event =
  1. | L1_DCM
  2. | L1_ICM
  3. | L2_DCM
  4. | L2_ICM
  5. | L3_DCM
  6. | L3_ICM
  7. | L1_TCM
  8. | L2_TCM
  9. | L3_TCM
  10. | CA_SNP
  11. | CA_SHR
  12. | CA_CLN
  13. | CA_INV
  14. | CA_ITV
  15. | L3_LDM
  16. | L3_STM
  17. | BRU_IDL
  18. | FXU_IDL
  19. | FPU_IDL
  20. | LSU_IDL
  21. | TLB_DM
  22. | TLB_IM
  23. | TLB_TL
  24. | L1_LDM
  25. | L1_STM
  26. | L2_LDM
  27. | L2_STM
  28. | BTAC_M
  29. | PRF_DM
  30. | L3_DCH
  31. | TLB_SD
  32. | CSR_FAL
  33. | CSR_SUC
  34. | CSR_TOT
  35. | MEM_SCY
  36. | MEM_RCY
  37. | MEM_WCY
  38. | STL_ICY
  39. | FUL_ICY
  40. | STL_CCY
  41. | FUL_CCY
  42. | HW_INT
  43. | BR_UCN
  44. | BR_CN
  45. | BR_TKN
  46. | BR_NTK
  47. | BR_MSP
  48. | BR_PRC
  49. | FMA_INS
  50. | TOT_IIS
  51. | TOT_INS
  52. | INT_INS
  53. | FP_INS
  54. | LD_INS
  55. | SR_INS
  56. | BR_INS
  57. | VEC_INS
  58. | RES_STL
  59. | FP_STAL
  60. | TOT_CYC
  61. | LST_INS
  62. | SYC_INS
  63. | L1_DCH
  64. | L2_DCH
  65. | L1_DCA
  66. | L2_DCA
  67. | L3_DCA
  68. | L1_DCR
  69. | L2_DCR
  70. | L3_DCR
  71. | L1_DCW
  72. | L2_DCW
  73. | L3_DCW
  74. | L1_ICH
  75. | L2_ICH
  76. | L3_ICH
  77. | L1_ICA
  78. | L2_ICA
  79. | L3_ICA
  80. | L1_ICR
  81. | L2_ICR
  82. | L3_ICR
  83. | L1_ICW
  84. | L2_ICW
  85. | L3_ICW
  86. | L1_TCH
  87. | L2_TCH
  88. | L3_TCH
  89. | L1_TCA
  90. | L2_TCA
  91. | L3_TCA
  92. | L1_TCR
  93. | L2_TCR
  94. | L3_TCR
  95. | L1_TCW
  96. | L2_TCW
  97. | L3_TCW
  98. | FML_INS
  99. | FAD_INS
  100. | FDV_INS
  101. | FSQ_INS
  102. | FNV_INS
  103. | FP_OPS
  104. | SP_OPS
  105. | DP_OPS
  106. | VEC_SP
  107. | VEC_DP
  108. | REF_CYC
    (*

    PAPI PRESET events.

    The header file papiStdEventDefs.h, installed by PAPI, is the authoritative description of events.

    Another way to obtain event descriptions is to call description, or pretty-print them with pp_event.

    *)
val name : event -> string

name e is a human-readable name for e.

It returns PAPI_event_info_t.name, without the prefix "PAPI_".

val description : event -> string

description e is a human-readable description of e.

It returns PAPI_event_info_t.long_descr.

val query : event -> bool

query e is true iff the hardware supports the event e.

val pp_event : Format.formatter -> event -> unit

pp_event ppf e pretty-prints a human-readable description on e on ppf.

val events : event array

events contains all defined events.

Event sets

type eventset

Sets of events.

Note. Eventsets are handles to resources held by PAPI. The handles are recycled. Calls to destroy followed by create can therefore return handles identical to previously destroyed handles, making destroyed eventsets live again.

val create : unit -> eventset

create () is a new eventset es.

Calls PAPI_create_eventset.

val cleanup : eventset -> unit

cleanup es removes counters from es.

Calls PAPI_cleanup_eventset.

val destroy : eventset -> unit

destroy es releases the resources backing es.

Calls PAPI_destroy_eventset.

val add : eventset -> event -> unit

add es e adds the event e to es.

Calls PAPI_add_event.

val num_events : eventset -> int

num_events es is the number of events currently attached to es.

val start : eventset -> unit

start es starts counting the events in es.

Calls PAPI_start.

val stop : eventset -> unit

stop es stops counting the events in es.

Calls PAPI_stop.

val reset : eventset -> unit

reset es resets the counters of events in es.

Calls PAPI_reset.

val read : eventset -> ?off:int -> float array -> unit

read es ~off values es' event counters to values.

These values are written to values.(off), ..., values.(off + n - 1) where n is num_events es. off defaults to 0.

Calls PAPI_read.

val accum : eventset -> ?off:int -> float array -> unit

accum es ~off values adds es' event counters to values and resets them.

These values are written to values.(off), ..., values.(off + n - 1) where n is num_events es. off defaults to 0.

Calls PAPI_accum.

Examples

Read the TSC and the actual number of cycles:

open Papi

let _ = init ()
let _ =
  let es = create ()
  and vs = Array.create_float 2 in
  List.iter (add es) [REF_CYC; TOT_CYC];
  start es;
  long_running_fun ();
  read es vs;
  stop es; cleanup es; destroy es;
  Fmt.pr "reference: %f, total: %f\n" vs.(0) vs.(1)

Create bracket that reads a set of events:

open Papi

let _ = init ()
let count_events ~events f =
  let es = create ()
  and vs = Array.create_float (List.length events) in
  List.iter (add es) events;
  start es;
  let res = f () in
  read es vs;
  stop es; cleanup es; destroy es;
  (res, vs)