mirror of
https://github.com/Const-me/Whisper.git
synced 2026-10-18 13:10:52 +08:00
207 lines
4.7 KiB
C#
207 lines
4.7 KiB
C#
using System.Globalization;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace PerfSummary
|
|
{
|
|
enum eInputClip: byte
|
|
{
|
|
jfk,
|
|
columbia,
|
|
}
|
|
enum eWhisperModel: byte
|
|
{
|
|
medium,
|
|
large
|
|
}
|
|
|
|
struct LogName
|
|
{
|
|
public readonly eInputClip clip;
|
|
public readonly eWhisperModel model;
|
|
public readonly string gpu;
|
|
|
|
public override string ToString() => $"{clip}-{model}-{gpu}";
|
|
|
|
public static LogName? tryParse( string path )
|
|
{
|
|
string? ext = Path.GetExtension( path );
|
|
if( ext == null || !ext.Equals( ".txt", StringComparison.InvariantCultureIgnoreCase ) )
|
|
return null;
|
|
|
|
string name = Path.GetFileNameWithoutExtension( path );
|
|
string[] fields = name.Split( '-' );
|
|
if( fields.Length != 3 )
|
|
return null;
|
|
|
|
return new LogName( fields );
|
|
}
|
|
|
|
LogName( string[] fields )
|
|
{
|
|
clip = Enum.Parse<eInputClip>( fields[ 0 ] );
|
|
model = Enum.Parse<eWhisperModel>( fields[ 1 ] );
|
|
gpu = fields[ 2 ];
|
|
}
|
|
}
|
|
|
|
record class LogData
|
|
{
|
|
public LogName name { get; init; }
|
|
// The numbers are seconds
|
|
public double runComplete { get; init; }
|
|
public double encode { get; init; }
|
|
public double decode { get; init; }
|
|
// The numbers are megabytes
|
|
public double ram { get; init; }
|
|
public double vram { get; init; }
|
|
}
|
|
|
|
static class LogParser
|
|
{
|
|
public static IEnumerable<LogData> parse( string folder )
|
|
{
|
|
foreach( string path in Directory.EnumerateFiles( folder, "*.txt" ) )
|
|
{
|
|
LogName? name = LogName.tryParse( path );
|
|
if( name == null )
|
|
continue;
|
|
yield return parseFile( name.Value, path );
|
|
}
|
|
}
|
|
|
|
enum eSection: byte
|
|
{
|
|
CPU, GPU, Shaders, Memory
|
|
}
|
|
static readonly (string, eSection)[] sectionMarkers = new (string, eSection)[]
|
|
{
|
|
("CPU Tasks", eSection.CPU),
|
|
("GPU Tasks", eSection.GPU),
|
|
("Compute Shaders", eSection.Shaders),
|
|
("Memory Usage", eSection.Memory),
|
|
};
|
|
|
|
static bool tryParseSection( ref eSection? section, string line )
|
|
{
|
|
foreach( (string marker, eSection s) in sectionMarkers )
|
|
{
|
|
if( line.Contains( marker ) )
|
|
{
|
|
section = s;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
static bool tryParseTime( ref double? val, string key, string line )
|
|
{
|
|
if( !line.StartsWith( key ) )
|
|
return false;
|
|
if( !char.IsWhiteSpace( line[ key.Length ] ) )
|
|
return false;
|
|
|
|
line = line.Substring( key.Length ).TrimStart();
|
|
int comma = line.IndexOf( ',' );
|
|
if( comma > 0 )
|
|
line = line.Substring( 0, comma );
|
|
string[] fields = line.Split( ' ', StringSplitOptions.RemoveEmptyEntries );
|
|
if( fields.Length != 2 )
|
|
throw new ArgumentException();
|
|
|
|
double v = double.Parse( fields[ 0 ], CultureInfo.InvariantCulture );
|
|
switch( fields[ 1 ] )
|
|
{
|
|
case "seconds":
|
|
val = v;
|
|
return true;
|
|
case "milliseconds":
|
|
val = v / 1E3;
|
|
return true;
|
|
case "microseconds":
|
|
val = v / 1E6;
|
|
return true;
|
|
}
|
|
throw new ArgumentException();
|
|
}
|
|
|
|
static readonly Regex reMemory = new Regex( @"^Total\s+([0-9\.]+)\s+(\S+)\s+RAM, ([0-9\.]+)\s+(\S+)\s+VRAM$" );
|
|
|
|
static double parseMemory( Match m, int iv )
|
|
{
|
|
double v = double.Parse( m.Groups[ iv ].Value, CultureInfo.InvariantCulture );
|
|
string u = m.Groups[ iv + 1 ].Value;
|
|
switch( u )
|
|
{
|
|
case "bytes":
|
|
return v / ( 1 << 20 );
|
|
case "KB":
|
|
return v / ( 1 << 10 );
|
|
case "MB":
|
|
return v;
|
|
case "GB":
|
|
return v * ( 1 << 10 );
|
|
}
|
|
throw new ArgumentException();
|
|
}
|
|
|
|
static bool tryParseMemory( ref double? ram, ref double? vram, string line )
|
|
{
|
|
Match m = reMemory.Match( line );
|
|
if( !m.Success )
|
|
return false;
|
|
ram = parseMemory( m, 1 );
|
|
vram = parseMemory( m, 3 );
|
|
return true;
|
|
}
|
|
|
|
static LogData parseFile( in LogName name, string path )
|
|
{
|
|
using var reader = File.OpenText( path );
|
|
double? runComplete = null;
|
|
double? encode = null;
|
|
double? decode = null;
|
|
double? ram = null;
|
|
double? vram = null;
|
|
eSection? section = null;
|
|
|
|
while( true )
|
|
{
|
|
string? line = reader.ReadLine();
|
|
if( line == null )
|
|
break;
|
|
if( string.IsNullOrEmpty( line ) )
|
|
continue;
|
|
if( tryParseSection( ref section, line ) )
|
|
continue;
|
|
|
|
switch( section )
|
|
{
|
|
case eSection.CPU:
|
|
tryParseTime( ref runComplete, "RunComplete", line );
|
|
break;
|
|
case eSection.GPU:
|
|
tryParseTime( ref encode, "Encode", line );
|
|
tryParseTime( ref decode, "Decode", line );
|
|
break;
|
|
case eSection.Memory:
|
|
tryParseMemory( ref ram, ref vram, line );
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( null == runComplete || null == encode || null == decode || null == ram || null == vram )
|
|
throw new ArgumentException();
|
|
|
|
return new LogData()
|
|
{
|
|
name = name,
|
|
runComplete = runComplete.Value,
|
|
encode = encode.Value,
|
|
decode = decode.Value,
|
|
ram = ram.Value,
|
|
vram = vram.Value,
|
|
};
|
|
}
|
|
}
|
|
} |