1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
use std::ptr;

use crate::generated::binding::*;

pub(crate) fn new_device_utilization(raw: FuriosaSmiDeviceUtilization) -> DeviceUtilization {
    DeviceUtilization { raw }
}

/// A struct for a utilization information of the device
pub struct DeviceUtilization {
    raw: FuriosaSmiDeviceUtilization,
}

impl DeviceUtilization {
    /// Returns a utilization of PE cores of the device.
    pub fn pe_utilization(&self) -> Vec<PeUtilization> {
        let mut result = Vec::with_capacity(self.raw.pe_count as usize);
        for i in 0..self.raw.pe_count {
            result.push(new_pe_utilization(self.raw.pe[i as usize]));
        }

        result
    }

    /// Returns a memory utilization of the device.
    pub fn memory_utilization(&self) -> MemoryUtilization {
        new_memory_utilization(self.raw.memory)
    }
}

fn new_pe_utilization(raw: FuriosaSmiPeUtilization) -> PeUtilization {
    PeUtilization { raw }
}

/// A struct for PE utilization
pub struct PeUtilization {
    raw: FuriosaSmiPeUtilization,
}

impl PeUtilization {
    /// Returns PE core index.
    pub fn core(&self) -> u32 {
        self.raw.core
    }

    /// Returns time window for utilization.
    pub fn time_window_mill(&self) -> u32 {
        self.raw.time_window_mil
    }
    /// Returns PE usage percentage.
    pub fn pe_usage_percentage(&self) -> f64 {
        self.raw.pe_usage_percentage
    }
}

fn new_memory_utilization(raw: FuriosaSmiMemoryUtilization) -> MemoryUtilization {
    MemoryUtilization { raw }
}

/// A struct for memory utilization
pub struct MemoryUtilization {
    raw: FuriosaSmiMemoryUtilization,
}

impl MemoryUtilization {
    /// Returns the total bytes of memory.
    pub fn total_bytes(&self) -> u64 {
        self.raw.total_bytes
    }

    /// Returns the memory bytes currently in use.
    pub fn in_use_bytes(&self) -> u64 {
        self.raw.in_use_bytes
    }
}

pub(crate) fn new_device_temperature(raw: FuriosaSmiDeviceTemperature) -> DeviceTemperature {
    DeviceTemperature { raw }
}

/// A struct for a temperature information of the device
pub struct DeviceTemperature {
    raw: FuriosaSmiDeviceTemperature,
}

impl DeviceTemperature {
    /// Returns the highest temperature observed from SoC sensors.
    pub fn soc_peak(&self) -> f64 {
        self.raw.soc_peak
    }

    /// Returns the temperature observed from sensors attached to the board
    pub fn ambient(&self) -> f64 {
        self.raw.ambient
    }
}

pub(crate) fn new_observer_instance(raw: FuriosaSmiObserverInstance) -> DeviceObserverInstance {
    DeviceObserverInstance { raw }
}

pub(crate) struct DeviceObserverInstance {
    raw: FuriosaSmiObserverInstance,
}

impl DeviceObserverInstance {
    pub(crate) fn raw(&self) -> FuriosaSmiObserverInstance {
        self.raw
    }
}

impl Drop for DeviceObserverInstance {
    fn drop(&mut self) {
        unsafe {
            furiosa_smi_destroy_observer(&mut self.raw as *mut FuriosaSmiObserverInstance);
        }
    }
}

fn default_pe_utilization() -> FuriosaSmiPeUtilization {
    FuriosaSmiPeUtilization {
        core: 0,
        time_window_mil: 0,
        pe_usage_percentage: 0.0,
    }
}

fn default_memory_utilization() -> FuriosaSmiMemoryUtilization {
    FuriosaSmiMemoryUtilization {
        total_bytes: 0,
        in_use_bytes: 0,
    }
}

pub(crate) fn default_device_utilization() -> FuriosaSmiDeviceUtilization {
    FuriosaSmiDeviceUtilization {
        pe_count: 0,
        pe: [default_pe_utilization(); FURIOSA_SMI_MAX_PE_SIZE as usize],
        memory: default_memory_utilization(),
    }
}

pub(crate) fn default_power_consumption() -> FuriosaSmiDevicePowerConsumption {
    FuriosaSmiDevicePowerConsumption { rms_total: 0.0 }
}

pub(crate) fn default_temperature() -> FuriosaSmiDeviceTemperature {
    FuriosaSmiDeviceTemperature {
        soc_peak: 0.0,
        ambient: 0.0,
    }
}

pub(crate) fn default_observer_instance() -> FuriosaSmiObserverInstance {
    ptr::null_mut()
}