PSChiaPlotter.psm1
enum KSize{ K32 = 32 K33 = 33 K34 = 34 K35 = 35 } class MaximizedKSize { [KSize]$KSize [int]$MaxPlots [Decimal]$RemainingBytes [Decimal]$KSizeBytes [int64]$TotalBytes static [Decimal]$K35 = 884.1 * 1gb static [Decimal]$K34 = 429.8 * 1gb static [Decimal]$K33 = 208.8 * 1gb static [Decimal]$K32 = 101.4 * 1gb MaximizedKSize( [KSize]$KSize, [int64]$TotalBytes ){ $this.KSize = $Ksize $this.TotalBytes = $TotalBytes $this.KSizeBytes = switch ($this.KSize){ "K35" {[MaximizedKSize]::K35} "K34" {[MaximizedKSize]::K34} "K33" {[MaximizedKSize]::K33} "K32" {[MaximizedKSize]::K32} } $this.MaxPlots = [math]::Floor([decimal]($this.TotalBytes / $this.KSizeBytes)) $this.RemainingBytes = $Totalbytes - (([math]::Floor([decimal]($this.TotalBytes / $this.KSizeBytes))) * $this.KSizeBytes) } } class OptimizedKPlots { [int]$K35 [int]$K34 [int]$K33 [int]$K32 [decimal]$RemainingBytes [double]$RemainingGB OptimizedKPlots ( [int]$K35, [int]$K34, [int]$K33, [int64]$Totalbytes ){ $sizeremaining = $TotalBytes - (($K35 * [MaximizedKSize]::K35) + ($K34 * [MaximizedKSize]::K34) + ($K33 * [MaximizedKSize]::K33)) $k32max = Get-MaxKSize -Totalbytes $sizeremaining -KSize "K32" $this.K35 = $K35 $this.K34 = $K34 $this.K33 = $K33 $this.K32 = $k32max.MaxPlots $this.RemainingBytes = $k32max.RemainingBytes $this.RemainingGB = [math]::Round($k32max.RemainingBytes / 1gb,2) } } function ConvertTo-FriendlyTimeSpan { [CmdletBinding()] param( [int32]$Seconds ) $TimeSpan = New-TimeSpan -Seconds $Seconds switch ($TimeSpan){ {$_.Days -ge 1} {return "$([math]::Round($TimeSpan.TotalDays,2)) days";break} {$_.Hours -ge 1} {return "$([math]::Round($TimeSpan.TotalHours,2)) hrs";break} {$_.Minutes -ge 1} {return "$([math]::Round($TimeSpan.TotalMinutes,2)) mins";break} {$_.seconds -ge 1} {return "$([math]::Round($TimeSpan.TotalSeconds,2)) sec";break} } } function Get-ChiaKPlotCombination{ [CmdletBinding(DefaultParameterSetName = "DriveLetter")] param( [Parameter(ParameterSetName="FreeSpace")] [int64[]]$FreeSpace, [Parameter(ParameterSetName="DriveLetter")] [string[]]$DriveLetter = (Get-Volume).DriveLetter ) if ($PSCmdlet.ParameterSetName -eq "FreeSpace"){ foreach ($space in $FreeSpace){ $Max = Get-MaxKSize -TotalBytes $space $AllCombos = Get-OptimizedKSizePlotNumbers $Max | sort RemainingBytes $AllCombos | Add-Member -MemberType NoteProperty -Name "StartingFreeSpace" -Value $space $AllCombos } } elseif ($PSCmdlet.ParameterSetName -eq "DriveLetter"){ foreach ($letter in $DriveLetter){ $Drive = Get-Volume -DriveLetter $letter $Max = Get-MaxKSize -TotalBytes $Drive.SizeRemaining $AllCombos = Get-OptimizedKSizePlotNumbers $Max | sort RemainingBytes $AllCombos | Add-Member -NotePropertyMembers @{ DriveLetter = $letter FriendlyName = $Drive.FileSystemLabel } $AllCombos | foreach {$_.psobject.TypeNames.Insert(0,"PSChiaPlotter.KSizeCombination")} $AllCombos } } } function Get-ChiaMaxParallelCount { [CmdletBinding()] param( [Parameter()] [ValidateRange(1,128)] [int]$ThreadCount = 2, [Parameter()] [ValidateRange(1, [int]::MaxValue)] [int]$BufferMiB = 3390 ) if (!$PSBoundParameters.ContainsKey("ThreadCount") -and !$PSBoundParameters.ContainsKey("BufferMiB")){ Write-Warning "All calculations based on plotting k32 plot size only. SSD TB suggestion rounded up to the nearest TB." } else{ Write-Warning "SSD TB suggestion rounded up to the nearest TB." } $Processor = Get-CimInstance -ClassName Win32_Processor $Threads = ($Processor | measure -Property ThreadCount -Sum).Sum $MaxParallelCountCPU = [math]::Floor($Threads / $ThreadCount) #1mb = 1048576 bytes $RAM = (Get-CimInstance -ClassName Win32_PhysicalMemory | measure -Property Capacity -Sum).Sum / 1mb $MaxParallelCountRAM = [Math]::Floor([decimal]($RAM / $BufferMiB)) $SystemDisk = Get-CimInstance -Namespace ROOT/Microsoft/Windows/Storage -ClassName MSFT_Disk -Filter "IsSystem=True" $SSDs = Get-CimInstance -Namespace root/microsoft/windows/storage -ClassName MSFT_PhysicalDisk -Filter "MediaType=4" #4 -eq SSD $SSDs = $SSDs | where UniqueId -ne $SystemDisk.UniqueId | select $One_TB = 1000000000000 $One_GB = 1000000000 $TotalSSDspace = ($SSDs | measure -Property Size -Sum).Sum $SSD_Count = ($SSDs | Measure-Object).Count if ($SSD_Count -eq 0){ Write-Warning "No non-system SSD found, therefore Current_MaxParallelPlots will be 0. (Ignore if using mutiple HDDs)" } if ($Threads -gt ($Processor.NumberOfCores * 2)){ Write-Warning "Threads may actually only be half what is reported and therefore all calculations are off." } $SSD_MAX = [math]::Floor([decimal]($TotalSSDspace / (256.6 * $One_GB))) if ($MaxParallelCountCPU -le $MaxParallelCountRAM){ $MAXCount = $MaxParallelCountCPU $BottleNeck = "CPU" } else{ $MAXCount = $MaxParallelCountRAM $BottleNeck = "RAM" } $Suggested_SSD_TB = [math]::Ceiling([decimal](256.6 * $MAXCount) / 1000) if ($SSD_MAX -le $MAXCount){ $CurrentMax = $SSD_MAX $BottleNeck = "SSD" } else{ $CurrentMax = $MAXCount } $Suggested_SSD_TB = [math]::Ceiling([decimal](256.6 * $MAXCount) / 1000) [PSCustomObject]@{ ThreadCount = $ThreadCount Buffer = $BufferMiB CPUTotalThreads = $Threads CPUCores = ($Processor | Measure -Property NumberOfCores -Sum).Sum NumberOfProcessors = ($Processor | measure).Count TotalRAM_MiB = $RAM BottleNeck = $BottleNeck Current_SSD_SPACE_TB = [math]::Round(($TotalSSDspace / $One_TB),2) Current_SSD_Count = $SSD_Count Suggested_SSD_SPACE_TB = $Suggested_SSD_TB Current_MaxParallelPlots = $CurrentMax Potential_MAXParallelPlots = $MAXCount } } function Get-ChiaPlottingStatistic { [CmdletBinding()] param( [Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)] [string[]]$Path = (Get-ChildItem -Path $env:USERPROFILE\.chia\mainnet\plotter\ | sort CreationTime -Descending).FullName ) Process{ foreach ($log in $path){ if (Test-Path $log){ $Content = Get-Content -Path $log | Select-String "Time for phase","Total time","Plot size","Buffer size","threads of stripe","Copy time","Copied final file from","Starting plotting progress into temporary dirs" | foreach {$_.ToString()} foreach ($line in $Content){ switch -Wildcard ($line){ "Plot size*" {$PlotSize = $line.split(' ') | select -Skip 3} #using select for these since indexing will error if empty "Buffer Size*" {$BufferSize = ($line.Split(' ') | select -Skip 3).split("M") | select -First 1} "*threads*" {$ThreadCount = $line.split(' ') | select -First 1 -Skip 1} "*phase 1*" {$Phase_1 = $line.Split(' ') | select -First 1 -Skip 5} "*phase 2*" {$Phase_2 = $line.Split(' ') | select -First 1 -Skip 5} "*phase 3*" {$Phase_3 = $line.Split(' ') | select -First 1 -Skip 5} "*phase 4*" {$phase_4 = $line.Split(' ') | select -First 1 -Skip 5} "Total time*" {$TotalTime = $line.Split(' ') | select -First 1 -Skip 3} "Copy time*" {$CopyTime = $line.Split(' ') | select -First 1 -Skip 3} "Starting plotting progress into temporary dirs*" {$TempDrive = ($line.Split(' ') | select -First 1 -Skip 6).Split('\') | select -First 1 } "Copied final file from*" {$FinalDrive = ($line.Split(' ') | select -First 1 -Skip 6).Split('\').Replace('"', '') | select -First 1} default {Write-Information "Could not match line: $line"} } } [PSCustomObject]@{ PSTypeName = "PSChiaPlotter.ChiaPlottingStatistic" KSize = $PlotSize "RAM(MiB)" = $BufferSize Threads = $ThreadCount "Phase_1_sec" = [int]$Phase_1 "Phase_2_sec" = [int]$Phase_2 "Phase_3_sec" = [int]$Phase_3 "Phase_4_sec" = [int]$phase_4 "TotalTime_sec" = [int]$TotalTime "CopyTime_sec" = [int]$CopyTime "PlotAndCopyTime_sec" = ([int]$CopyTime + [int]$TotalTime) "Time_Started" = (Get-Item -Path $log).CreationTime "Temp_drive" = $TempDrive "Final_drive" = $FinalDrive } Clear-Variable -Name "Phase_1","Phase_2","Phase_3","Phase_4","TotalTime","CopyTime" -ErrorAction SilentlyContinue } } } } function Get-ChiaRAMInfo { [CmdletBinding()] param( ) Begin{ } #Begin Process{ $Array = Get-CimInstance -Class Win32_PhysicalMemoryArray $CurrentRAM = Get-CimInstance -Class Win32_PhysicalMemory [PSCustomObject]@{ PSTypeName = "PSChiaPlotter.RAMInfo" ComputerName = $ENV:COMPUTERNAME SlotsInUse = ($CurrentRAM | Measure).Count SlotsFree = $Array.MemoryDevices - ($CurrentRAM | Measure).Count CurrentSize_GB = (($CurrentRAM).Capacity | Measure -Sum).Sum / 1gb MaxSize_GB = $Array.MaxCapacityEx / 1mb PartNumber = ($CurrentRAM.PartNumber | Select -Unique | foreach {$_.Trim()}) Manufacturer = ($CurrentRAM.Manufacturer | Select -Unique | foreach {$_.Trim()}) TotalSlots = $Array.MemoryDevices RAMDevices = $CurrentRAM } } #Process } function Get-MaxKSize { [CmdletBinding()] param( [ValidateSet("K32","K33","K34","K35")] [string[]]$KSize = ("K32","K33","K34","K35"), [Parameter(Mandatory)] [int64]$TotalBytes ) foreach ($size in $KSize){ [MaximizedKSize]::new($size,$TotalBytes) } #foreach } function Get-OptimizedKSizePlotNumbers { [CmdletBinding()] param( [MaximizedKSize[]]$MaximizedKSize ) foreach ($size in $MaximizedKSize){ switch ($size.KSize){ "K32" { [OptimizedKPlots]::new(0,0,0,$Size.TotalBytes) } "K33" { for ($K33Count = 1; $K33Count -le $size.MaxPlots; $K33Count++){ [OptimizedKPlots]::new(0,0,$K33Count,$Size.TotalBytes) } #for } "K34" { for ($K34Count = 1; $K34Count -le $size.maxplots; $K34Count++){ [OptimizedKPlots]::new(0,$K34Count,0,$Size.TotalBytes) $k34sizeremaining = $Size.TotalBytes - ($K34Count * $size.KSizeBytes) $K33Max = Get-MaxKSize -TotalBytes $k34sizeremaining -KSize "K33" for ($k33 = 1; $k33 -le $k33max.MaxPlots; $k33++){ [OptimizedKPlots]::new(0,$K34Count,$k33,$Size.TotalBytes) } #for 33 } #for 34 } #34 "K35" { for ($k35count = 1; $k35count -le $size.maxplots; $k35count++){ [OptimizedKPlots]::new($k35count,0,0,$Size.TotalBytes) $k35sizeremaining = $Size.TotalBytes - ($k35count * $size.KSizeBytes) $k33max = Get-MaxKSize -Totalbytes $k35sizeremaining -KSize "K33" for ($k33 = 1; $k33 -le $k33max.MaxPlots; $k33++){ [OptimizedKPlots]::new($k35count,0,$k33,$Size.TotalBytes) } #for 33 $k34max = Get-MaxKSize -Totalbytes $k35sizeremaining -KSize "K34" for ($k34 = 1; $k34 -le $k34max.maxplots; $k34++){ [OptimizedKPlots]::new($k35count,$k34,0,$Size.TotalBytes) $sizeremaining = $Size.TotalBytes - (($k35count * $size.KSizeBytes) + ($k34 * $k34max.KSizeBytes)) $K33max = Get-MaxKSize -TotalBytes $sizeremaining -KSize "K33" for ($k33 = 1;$k33 -le $k33max.maxplots; $k33++){ [OptimizedKPlots]::new($k35count,$k34,$k33,$Size.TotalBytes) } } } } } #switch } #foreach } Export-ModuleMember -function ConvertTo-FriendlyTimeSpan, Get-ChiaKPlotCombination, Get-ChiaMaxParallelCount, Get-ChiaPlottingStatistic, Get-ChiaRAMInfo |