criterion_papi/
lib.rs

1use std::ffi::CString;
2
3use criterion::measurement::{Measurement, ValueFormatter};
4use libpapi_sys::*;
5
6mod formatter;
7use formatter::InsFormatter;
8
9pub struct PapiMeasurement {
10    event_set: std::os::raw::c_int,
11}
12
13impl PapiMeasurement {
14    pub fn new(event: &str) -> PapiMeasurement {
15        let mut event_set = PAPI_NULL;
16        let mut papi_tot_ins: std::os::raw::c_int = 0;
17
18        let event_name = CString::new(event).expect("CString::new failed");
19
20        unsafe {
21            let retval = PAPI_library_init(PAPI_VER_CURRENT);
22            if retval != PAPI_VER_CURRENT {
23                panic!("PAPI_library_init failed {}", retval)
24            }
25
26            let retval = PAPI_event_name_to_code(event_name.into_raw(), &mut papi_tot_ins);
27            if retval != PAPI_OK as i32 {
28                panic!("PAPI_event_name_to_code failed {}", retval)
29            }
30
31            let retval = PAPI_create_eventset(&mut event_set);
32            if retval != PAPI_OK as i32 {
33                panic!("PAPI_create_eventset error {}", retval)
34            }
35
36            let retval = PAPI_add_event(event_set.clone(), papi_tot_ins as i32);
37            if retval != PAPI_OK as i32 {
38                panic!("PAPI_add_event failed {}", retval)
39            }
40        }
41
42        return PapiMeasurement {
43            event_set,
44        }
45    }
46}
47
48impl Measurement for PapiMeasurement {
49    type Intermediate = i64;
50    type Value = i64;
51
52    fn start(&self) -> Self::Intermediate {
53        let mut values = [0i64];
54
55        unsafe {
56            let retval = PAPI_start(self.event_set.clone());
57            if retval != PAPI_OK as i32 {
58                panic!("PAPI_start failed {}", retval)
59            }
60
61            let retval = PAPI_read(self.event_set.clone(), values.as_mut_ptr());
62            if retval != PAPI_OK as i32 {
63                panic!("PAPI_read failed")
64            }
65        }
66
67        values[0]
68    }
69
70    fn end(&self, i: Self::Intermediate) -> Self::Value {
71        let mut values = [0i64];
72
73        unsafe {
74            let retval = PAPI_stop(self.event_set.clone(), values.as_mut_ptr());
75            if retval != PAPI_OK as i32 {
76                panic!("PAPI_read failed")
77            }
78        }
79
80        values[0] - i
81    }
82
83    fn add(&self, v1: &Self::Value, v2: &Self::Value) -> Self::Value {
84        v1 + v2
85    }
86
87    fn zero(&self) -> Self::Value {
88        0
89    }
90
91    fn to_f64(&self, value: &Self::Value) -> f64 {
92        *value as f64
93    }
94
95    fn formatter(&self) -> &dyn ValueFormatter {
96        &InsFormatter
97    }
98}