From 50d745c11710b5256b82039293feac92155b2006 Mon Sep 17 00:00:00 2001 From: Terence Date: Fri, 23 May 2025 14:51:55 +0200 Subject: [PATCH 1/2] =?UTF-8?q?modification=20:=20=20ajout=20de=20fonction?= =?UTF-8?q?=20pour=20calculer=20la=20consommation=20d'un=20processus=20via?= =?UTF-8?q?=20la=20corr=C3=A9lation=20avec=20la=20charge=20SM?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/gpu_power_by_process.adb | 116 +++++++++++++++++++++++++++++++++++ src/gpu_power_by_process.ads | 24 ++++++++ 2 files changed, 140 insertions(+) create mode 100644 src/gpu_power_by_process.adb create mode 100644 src/gpu_power_by_process.ads diff --git a/src/gpu_power_by_process.adb b/src/gpu_power_by_process.adb new file mode 100644 index 0000000..e0c7855 --- /dev/null +++ b/src/gpu_power_by_process.adb @@ -0,0 +1,116 @@ +with Ada.Text_IO; use Ada.Text_IO; +with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; +with GNAT.OS_Lib; use GNAT.OS_Lib; +with Ada.Containers.Vectors; +with Ada.Strings.Fixed; +with Ada.Command_Line; + +with Nvidia_SMI; use Nvidia_SMI; + +procedure Gpu_Power_By_Process is + + type PID_Type is new Integer; + + type SM_Usage is record + PID : PID_Type; + SM : Float; + end record; + + package SM_Vector is new + Ada.Containers.Vectors (Index_Type => Natural, Element_Type => SM_Usage); + use SM_Vector; + + -- Helper to execute a shell command and return the output as string + function Execute_Command (Command : String) return String is + Output : String (1 .. 10_000); + Len : Integer; + begin + Len := GNAT.OS_Lib.Shell (Command, Output'Address, Output'Length); + return Output (1 .. Len); + end Execute_Command; + + -- Get the SM usage per PID from nvidia-smi pmon + function Get_SM_By_PID return SM_Vector.Vector is + Raw_Output : constant String := Execute_Command ("nvidia-smi pmon -s u"); -- run nvidia-smi pmon -s um pour plus d'info mémoire. + Lines : SM_Vector.Vector; + Line_Start : Positive := 1; + Line_End : Natural; + begin + declare + Output_Lines : constant String := Raw_Output; + use Ada.Strings.Fixed; + Line : String; + Count : Natural := 0; + begin + for L of Output_Lines'Range loop + exit when Count > 1000; + Line_End := + Index (Output_Lines (Line_Start .. Output_Lines'Last), ASCII.LF); + exit when Line_End = 0; + Line := Output_Lines (Line_Start .. Line_Start + Line_End - 2); + Line_Start := Line_Start + Line_End; + + if Line'Length > 0 and then Line (1) /= '#' then + declare + Tokens : constant String := Line; + PID_Val : PID_Type := + Integer'Value (Trim (Tokens (1 .. 5), Ada.Strings.Left)); + SM_Val : Float := + Float'Value (Trim (Tokens (27 .. 30), Ada.Strings.Left)); + begin + Lines.Append ((PID => PID_Val, SM => SM_Val)); + exception + when others => + null; + end; + end if; + Count := Count + 1; + end loop; + + return Lines; + end; + end Get_SM_By_PID; + + -- Compute GPU consumption for a specific PID + function Estimate_PID_Consumption (Target_PID : PID_Type) return Float is + SM_Data : SM_Vector.Vector := Get_SM_By_PID; + Total_SM : Float := 0.0; + PID_SM : Float := 0.0; + Total_Power : Float := Float(Get_Nvidia_SMI_Power); + begin + for Usage of SM_Data loop + Total_SM := Total_SM + Usage.SM; + if Usage.PID = Target_PID then + PID_SM := PID_SM + Usage.SM; + end if; + end loop; + + if Total_SM = 0.0 then + return 0.0; + end if; + + -- return (PID_SM / Total_SM) * Total_Power; + return (PID_SM * Total_Power) / Total_SM; + end Estimate_PID_Consumption; + +begin + if Ada.Command_Line.Argument_Count < 1 then + Put_Line ("Usage: gpu_power_by_process "); + return; + end if; + + declare + PID : PID_Type := + Integer'Value (Ada.Command_Line.Argument (1)); + Estimated_Conso : Float := Estimate_PID_Consumption (PID); + begin + Put_Line + ("Estimated GPU Power Consumption for PID " + & PID'Image + & ": " + & Estimated_Conso'Image + & " W"); + end; +end Gpu_Power_By_Process; + + diff --git a/src/gpu_power_by_process.ads b/src/gpu_power_by_process.ads new file mode 100644 index 0000000..f0ab614 --- /dev/null +++ b/src/gpu_power_by_process.ads @@ -0,0 +1,24 @@ +with Ada.Containers.Vectors; + +package Gpu_Power_By_Process is + + type PID_Type is new Integer; + + type SM_Usage is record + PID : PID_Type; + SM : Float; + end record; + + package SM_Vector is new Ada.Containers.Vectors (Index_Type => Natural, Element_Type => SM_Usage); + + -- Exécute une commande shell et retourne la sortie sous forme de chaîne + -- revoir ? + function Execute_Command (Command : String) return String; + + -- Récupère l'utilisation SM par PID à partir de nvidia-smi pmon + function Get_SM_By_PID return SM_Vector.Vector; + + -- Estime la consommation GPU d'un processus donné (PID) + function Estimate_PID_Consumption (Target_PID : PID_Type) return Float; + +end Gpu_Power_By_Process; \ No newline at end of file From 0196e1756f6b4372c87a19ce4a314affcace68aa Mon Sep 17 00:00:00 2001 From: Terence Date: Fri, 23 May 2025 14:56:59 +0200 Subject: [PATCH 2/2] modification : ajout de la nouvelle fonction dans le fichier principal lors de l'argument -p: --- src/powerjoular.adb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/powerjoular.adb b/src/powerjoular.adb index 5b01fd3..b77214f 100755 --- a/src/powerjoular.adb +++ b/src/powerjoular.adb @@ -31,6 +31,8 @@ with Raspberry_Pi_CPU_Formula; use Raspberry_Pi_CPU_Formula; with CPU_STAT_App; use CPU_STAT_App; with Virtual_Machine; use Virtual_Machine; +with Gpu_Power_By_Process; use Gpu_Power_By_Process; + procedure Powerjoular is -- Power variables -- @@ -133,6 +135,7 @@ procedure Powerjoular is -- PID_Number := Integer'Value (Parameter); CPU_PID_Monitor.PID_Number := Integer'Value (Parameter); Monitor_PID := True; + Estimate_PID_Consumption (CPU_PID_Monitor.PID_Number); when 'a' => -- Monitor a particular application by its name CPU_App_Monitor.App_Name := To_Unbounded_String (Parameter);