-- -- Copyright (c) 2020-2023, Adel Noureddine, Université de Pau et des Pays de l'Adour. -- All rights reserved. This program and the accompanying materials -- are made available under the terms of the -- GNU General Public License v3.0 only (GPL-3.0-only) -- which accompanies this distribution, and is available at: -- https://www.gnu.org/licenses/gpl-3.0.en.html -- -- Author : Adel Noureddine -- with Ada.Text_IO; use Ada.Text_IO; with GNAT.Expect; use GNAT.Expect; with GNAT.OS_Lib; use GNAT.OS_Lib; with GNAT.String_Split; use GNAT; with Ada.Characters.Latin_1; use Ada.Characters.Latin_1; package body Nvidia_SMI is function Get_Nvidia_SMI_Power return Float is Command : String := "nvidia-smi --format=csv,noheader,nounits --query-gpu=power.draw"; Args : Argument_List_Access; Status : aliased Integer; Subs : String_Split.Slice_Set; -- Used to slice the read data from stat file Seps : constant String := CR & LF; -- Seperator (space) for slicing string Slice_number_count : String_Split.Slice_Number; GPU_Energy : Float := 0.0; begin Args := Argument_String_To_List (Command); declare Response : String := Get_Command_Output (Command => Args (Args'First).all, Arguments => Args (Args'First + 1 .. Args'Last), Input => "", Status => Status'Access); begin Free (Args); if Response = "[N/A]" then return 0.0; else String_Split.Create (S => Subs, -- Store sliced data in Subs From => Response, -- Read data to slice Separators => Seps, -- Separator (here space) Mode => String_Split.Multiple); Slice_number_count := String_Split.Slice_Count (Subs); for I in 1 .. Slice_number_count loop GPU_Energy := GPU_Energy + Float'Value (String_Split.Slice (Subs, 1)); end loop; return GPU_Energy; end if; end; exception when others => return 0.0; end; function Check_Nvidia_Supported_System return Boolean is Command : String := "nvidia-smi --format=csv,noheader,nounits --query-gpu=power.draw"; Args : Argument_List_Access; Status : aliased Integer; begin Args := Argument_String_To_List (Command); declare Response : String := Get_Command_Output (Command => Args (Args'First).all, Arguments => Args (Args'First + 1 .. Args'Last), Input => "", Status => Status'Access); begin Free (Args); return Response /= "[N/A]"; end; exception when others => return False; end; end Nvidia_SMI;