use crate::enums::gpm::GpmMetricId;
use crate::error::{nvml_sym, nvml_try, NvmlError};
use crate::ffi::bindings::*;
use crate::struct_wrappers::gpm::GpmMetricResult;
use crate::Nvml;
use std::mem;
#[derive(Debug)]
pub struct GpmSample<'nvml> {
sample: nvmlGpmSample_t,
nvml: &'nvml Nvml,
}
unsafe impl<'nvml> Send for GpmSample<'nvml> {}
impl<'nvml> GpmSample<'nvml> {
#[doc(alias = "nvmlGpmSampleAlloc")]
pub(crate) fn alloc(nvml: &'nvml Nvml) -> Result<Self, NvmlError> {
let sym = nvml_sym(nvml.lib.nvmlGpmSampleAlloc.as_ref())?;
unsafe {
let mut sample: nvmlGpmSample_t = mem::zeroed();
nvml_try(sym(&mut sample))?;
Ok(Self { sample, nvml })
}
}
#[doc(alias = "nvmlGpmSampleFree")]
pub fn free(self) -> Result<(), NvmlError> {
let sym = nvml_sym(self.nvml.lib.nvmlGpmSampleFree.as_ref())?;
unsafe {
nvml_try(sym(self.sample))?;
}
mem::forget(self);
Ok(())
}
pub unsafe fn handle(&self) -> nvmlGpmSample_t {
self.sample
}
pub fn nvml(&self) -> &'nvml Nvml {
self.nvml
}
}
impl<'nvml> Drop for GpmSample<'nvml> {
#[doc(alias = "nvmlGpmSampleFree")]
fn drop(&mut self) {
unsafe {
self.nvml.lib.nvmlGpmSampleFree(self.sample);
}
}
}
#[doc(alias = "nvmlGpmMetricsGet")]
pub fn gpm_metrics_get<'nvml>(
nvml: &'nvml Nvml,
sample1: &GpmSample<'nvml>,
sample2: &GpmSample<'nvml>,
metric_ids: &[GpmMetricId],
) -> Result<Vec<Result<GpmMetricResult, NvmlError>>, NvmlError> {
assert!(
metric_ids.len() <= nvmlGpmMetricId_t_NVML_GPM_METRIC_MAX as usize,
"cannot request more than {} GPM metrics at once",
nvmlGpmMetricId_t_NVML_GPM_METRIC_MAX
);
let sym = nvml_sym(nvml.lib.nvmlGpmMetricsGet.as_ref())?;
unsafe {
let mut request: nvmlGpmMetricsGet_t = mem::zeroed();
request.version = NVML_GPM_METRICS_GET_VERSION;
request.numMetrics = metric_ids.len() as u32;
request.sample1 = sample1.sample;
request.sample2 = sample2.sample;
for (i, id) in metric_ids.iter().enumerate() {
request.metrics[i].metricId = id.as_c();
}
nvml_try(sym(&mut request))?;
let results = (0..metric_ids.len())
.map(|i| GpmMetricResult::try_from_c(&request.metrics[i]))
.collect();
Ok(results)
}
}