2022-07-25 10:37:44 +02:00
using Flowframes.Data ;
using Flowframes.IO ;
using Flowframes.Main ;
using Flowframes.Os ;
using System ;
using System.Collections.Generic ;
using System.Diagnostics ;
using System.Drawing ;
using System.IO ;
using System.Linq ;
using System.Text ;
using System.Threading.Tasks ;
namespace Flowframes.Utilities
{
class NcnnUtils
{
/// <summary> Get amount of GPU Compute Queues (VK) for each GPU </summary>
public static async Task < Dictionary < int , int > > GetNcnnGpuComputeQueueCounts ( )
{
Dictionary < int , int > queueCounts = new Dictionary < int , int > ( ) ; // int gpuId, int queueCount
Process rifeNcnn = OsUtils . NewProcess ( true ) ;
2022-07-26 21:08:27 +02:00
rifeNcnn . StartInfo . Arguments = $"{OsUtils.GetCmdArg()} cd /D {Path.Combine(Paths.GetPkgPath(), Implementations.rifeNcnn.PkgDir)} & rife-ncnn-vulkan.exe -i dummydir -o dummydir" ;
2022-07-25 10:37:44 +02:00
string output = await Task . Run ( ( ) = > OsUtils . GetProcStdOut ( rifeNcnn , true ) ) ;
var queueLines = output . SplitIntoLines ( ) . Where ( x = > x . MatchesWildcard ( @"*queueC=*queue*" ) ) ;
foreach ( var line in queueLines )
{
int gpuId = line . Split ( ' ' ) [ 0 ] . GetInt ( ) ;
int queueCount = line . Split ( "queue" ) [ 1 ] . Split ( '[' ) [ 1 ] . Split ( ']' ) [ 0 ] . GetInt ( ) ;
Logger . Log ( $"NCNN: Found GPU {gpuId} with compute queue count {queueCount}" , true ) ;
queueCounts [ gpuId ] = queueCount ;
}
return queueCounts ;
}
public static async Task < int > GetRifeNcnnGpuThreads ( Size res , int gpuId , AI ai )
{
2023-02-17 21:54:33 +01:00
int threads = 8 ;
//if (res.Width * res.Height > 2560 * 1440) threads = 4;
// if (res.Width * res.Height > 3840 * 2160) threads = 1;
2022-07-25 10:37:44 +02:00
if ( threads ! = 1 )
{
2022-07-26 21:08:27 +02:00
var queueDict = await GetNcnnGpuComputeQueueCounts ( ) ;
int maxThreads = queueDict . ContainsKey ( gpuId ) ? queueDict [ gpuId ] : 1 ;
2022-07-25 10:37:44 +02:00
threads = threads . Clamp ( 1 , maxThreads ) ; // To avoid exceeding the max queue count
Logger . Log ( $"Using {threads}/{maxThreads} GPU threads." , true , false , ai . LogFilename ) ;
}
else
{
Logger . Log ( $"Using {threads} GPU thread." , true , false , ai . LogFilename ) ;
}
return threads ;
}
public static string GetNcnnPattern ( )
{
return $"%0{Padding.interpFrames}d{Interpolate.currentSettings.interpExt}" ;
}
public static string GetNcnnTilesize ( int tilesize )
{
int gpusAmount = Config . Get ( Config . Key . ncnnGpus ) . Split ( ',' ) . Length ;
string tilesizeStr = $"{tilesize}" ;
for ( int i = 1 ; i < gpusAmount ; i + + )
tilesizeStr + = $",{tilesize}" ;
return tilesizeStr ;
}
public static string GetNcnnThreads ( bool forceSingleThread = false )
{
int gpusAmount = Config . Get ( Config . Key . ncnnGpus ) . Split ( ',' ) . Length ;
int procThreads = Config . GetInt ( Config . Key . ncnnThreads ) ;
string progThreadsStr = $"{procThreads}" ;
for ( int i = 1 ; i < gpusAmount ; i + + )
progThreadsStr + = $",{procThreads}" ;
return $"{(forceSingleThread ? 1 : (Interpolate.currentlyUsingAutoEnc ? 2 : 4))}:{progThreadsStr}:4" ; // Read threads: 1 for singlethreaded, 2 for autoenc, 4 if order is irrelevant
}
public static async Task DeleteNcnnDupes ( string dir , float factor )
{
int dupeCount = InterpolateUtils . GetRoundedInterpFramesPerInputFrame ( factor ) ;
var files = IoUtils . GetFileInfosSorted ( dir , false ) . Reverse ( ) . Take ( dupeCount ) . ToList ( ) ;
Logger . Log ( $"DeleteNcnnDupes: Calculated dupe count from factor; deleting last {dupeCount} interp frames of {IoUtils.GetAmountOfFiles(dir, false)} ({string.Join(" , ", files.Select(x => x.Name))})" , true ) ;
int attempts = 4 ;
while ( attempts > 0 )
{
try
{
files . ForEach ( x = > x . Delete ( ) ) ;
break ;
}
catch ( Exception ex )
{
attempts - - ;
if ( attempts < 1 )
{
Logger . Log ( $"DeleteNcnnDupes Error: {ex.Message}" , true ) ;
break ;
}
else
{
await Task . Delay ( 500 ) ;
}
}
}
}
}
}