jamesstringerparsec / Easy-GPU-PV

A Project dedicated to making GPU Partitioning on Windows easier!
4.01k stars 407 forks source link

Problem upgrading to new GPU: RTX 2080 to RTX 3060 Ti #316

Closed brando148 closed 10 months ago

brando148 commented 10 months ago

Hello all, I've been a consistent user of Easy-GPU-PV for about a year and have pretty consistently solved any issues that have popped up on my own, but this one is getting the best of me. I am running 3 VMs under my host machine. 2 VMs using an RTX 2070 Super (Primary PCIe Slot) 1 VM using an RTX 2080 (Secondary PCIe Slot) The VMs using the 2070 have been rock solid and have given me no issues. However the 3D design application I am using the 2080 for is giving me pretty consistently low frame rates and I found a really great priced 3060 Ti and verified that VIP3D (the app I use) will offer better performance than the prior card. After swapping cards, and updating host/VM GPU drivers to 536.99 using the "Update-VMGpuPartitionDriver.ps1", I started the VMs using the 2070 to verify these are still working properly. Once these started without issue, I started the "BrandonWin" VM which previous used the 2080. This created the following error:

Start-VM : 'BrandonWin' failed to start.
GPU Partition (Instance ID 8689E9CA-B1DB-4C72-8C36-47F5D549808A): Error 'Insufficient system resources exist to complete the requested service.'.
'BrandonWin' failed to start. (Virtual machine ID 8FCE3318-AA0F-4DE3-8664-278533573CD2)
'BrandonWin' GPU Partition: Failed to finish reserving resources with Error 'Insufficient system resources exist to complete the requested service.' (0x800705AA). (Virtual machine ID 8FCE3318-AA0F-4DE3-8664-278533573CD2)
At \\SALT-SVR1\User Files$\banderson\Documents\Partitionable GPU Setup\Easy-GPU-PV-main\Update-VMGpuPartitionDriver.ps1:49 char:5
+     Start-VM $VMName
+     ~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Start-VM], VirtualizationException
    + FullyQualifiedErrorId : Unspecified,Microsoft.HyperV.PowerShell.Commands.StartVM

I shut down all VMs and the host to swap back to the 2080 to make sure there was no issue there, and it started right up. I am back to the 3060 Ti and continue to get the same error. Any help diagnosing, or working around this issue is appreciated.

remmina_GPU VM Host_192 168 1 120_20230810-203903

brando148 commented 10 months ago

Update: I was looking through some old issues and came across #65 I used the following script that was put together there as follows to a new VM using the same VHD as my previous VM:

Param (
[string]$VMName = "BrandonWinTest",
[string]$GPUName = "NVIDIA GeForce RTX 3060 Ti",
[string]$Hostname = $ENV:Computername,
[decimal]$GPUResourceAllocationPercentage = 100
)

Function Add-VMGpuPartitionAdapterFiles {
param(
[string]$hostname = $ENV:COMPUTERNAME,
[string]$DriveLetter,
[string]$GPUName
)

If (!($DriveLetter -like "*:*")) {
    $DriveLetter = $Driveletter + ":"
    }

If ($GPUName -eq "AUTO") {
    $PartitionableGPUList = Get-WmiObject -Class "Msvm_PartitionableGpu" -ComputerName $env:COMPUTERNAME -Namespace "ROOT\virtualization\v2"
    $DevicePathName = $PartitionableGPUList.Name | Select-Object -First 1
    $GPU = Get-PnpDevice | Where-Object {($_.DeviceID -like "*$($DevicePathName.Substring(8,16))*") -and ($_.Status -eq "OK")} | Select-Object -First 1
    $GPUName = $GPU.Friendlyname
    $GPUServiceName = $GPU.Service 
    }
Else {
    $GPU = Get-PnpDevice | Where-Object {($_.Name -eq "$GPUName") -and ($_.Status -eq "OK")} | Select-Object -First 1
    $GPUServiceName = $GPU.Service
    }
# Get Third Party drivers used, that are not provided by Microsoft and presumably included in the OS

Write-Host "INFO   : Finding and copying driver files for $GPUName to VM. This could take a while..."

$Drivers = Get-WmiObject Win32_PNPSignedDriver | where {$_.DeviceName -eq "$GPUName"}

New-Item -ItemType Directory -Path "$DriveLetter\windows\system32\HostDriverStore" -Force | Out-Null

#copy directory associated with sys file 
$servicePath = (Get-WmiObject Win32_SystemDriver | Where-Object {$_.Name -eq "$GPUServiceName"}).Pathname
                $ServiceDriverDir = $servicepath.split('\')[0..5] -join('\')
                $ServicedriverDest = ("$driveletter" + "\" + $($servicepath.split('\')[1..5] -join('\'))).Replace("DriverStore","HostDriverStore")
                if (!(Test-Path $ServicedriverDest)) {
                Copy-item -path "$ServiceDriverDir" -Destination "$ServicedriverDest" -Recurse
                }

# Initialize the list of detected driver packages as an array
$DriverFolders = @()
foreach ($d in $drivers) {

    $DriverFiles = @()
    $ModifiedDeviceID = $d.DeviceID -replace "\\", "\\"
    $Antecedent = "\\" + $hostname + "\ROOT\cimv2:Win32_PNPSignedDriver.DeviceID=""$ModifiedDeviceID"""
    $DriverFiles += Get-WmiObject Win32_PNPSignedDriverCIMDataFile | where {$_.Antecedent -eq $Antecedent}
    $DriverName = $d.DeviceName
    $DriverID = $d.DeviceID
    if ($DriverName -like "NVIDIA*") {
        New-Item -ItemType Directory -Path "$driveletter\Windows\System32\drivers\Nvidia Corporation\" -Force | Out-Null
        }
    foreach ($i in $DriverFiles) {
            $path = $i.Dependent.Split("=")[1] -replace '\\\\', '\'
            $path2 = $path.Substring(1,$path.Length-2)
            $InfItem = Get-Item -Path $path2
            $Version = $InfItem.VersionInfo.FileVersion
            If ($path2 -like "c:\windows\system32\driverstore\*") {
                $DriverDir = $path2.split('\')[0..5] -join('\')
                $driverDest = ("$driveletter" + "\" + $($path2.split('\')[1..5] -join('\'))).Replace("driverstore","HostDriverStore")
                if (!(Test-Path $driverDest)) {
                Copy-item -path "$DriverDir" -Destination "$driverDest" -Recurse
                }
            }
            Else {
                $ParseDestination = $path2.Replace("c:", "$driveletter")
                $Destination = $ParseDestination.Substring(0, $ParseDestination.LastIndexOf('\'))
                if (!$(Test-Path -Path $Destination)) {
                    New-Item -ItemType Directory -Path $Destination -Force | Out-Null
                    }
                Copy-Item $path2 -Destination $Destination -Force

            }

    }
    }

}

$VM = Get-VM -VMName $VMName
$VHD = Get-VHD -VMId $VM.VMId

If ($VM.state -eq "Running") {
    [bool]$state_was_running = $true
    }

if ($VM.state -ne "Off"){
    "Attemping to shutdown VM..."
    Stop-VM -Name $VMName -Force
    } 

While ($VM.State -ne "Off") {
    Start-Sleep -s 3
    "Waiting for VM to shutdown - make sure there are no unsaved documents..."
    }

"Mounting Drive..."
$DriveLetter = (Mount-VHD -Path $VHD.Path -PassThru | Get-Disk | Get-Partition | Get-Volume | Where-Object {$_.DriveLetter} | ForEach-Object DriveLetter)

"Copying GPU Files - this could take a while..."
Add-VMGPUPartitionAdapterFiles -hostname $Hostname -DriveLetter $DriveLetter -GPUName $GPUName

"Dismounting Drive..."
Dismount-VHD -Path $VHD.Path

function Assign-VMGPUPartitionAdapter 
{  
    $PartitionableGPUList = Get-WmiObject -Class "Msvm_PartitionableGpu" -ComputerName $env:COMPUTERNAME -Namespace "ROOT\virtualization\v2" 
    if ($GPUName -eq "AUTO") {
        $DevicePathName = $PartitionableGPUList.Name[0]
        Add-VMGpuPartitionAdapter -VMName $VMName
        }
    else {
        $DeviceID = ((Get-WmiObject Win32_PNPSignedDriver | where {($_.Devicename -eq "$GPUNAME")}).hardwareid).split('\')[1]
        $DevicePathName = ($PartitionableGPUList | Where-Object name -like "*$deviceid*").Name
        Add-VMGpuPartitionAdapter -VMName $VMName -InstancePath $DevicePathName
        }

    [float]$devider = [math]::round($(100 / $GPUResourceAllocationPercentage),2)

    Set-VMGpuPartitionAdapter -VMName $VMName -MinPartitionVRAM ([math]::round($(1000000000 / $devider))) -MaxPartitionVRAM ([math]::round($(1000000000 / $devider))) -OptimalPartitionVRAM ([math]::round($(1000000000 / $devider)))
    Set-VMGPUPartitionAdapter -VMName $VMName -MinPartitionEncode ([math]::round($(18446744073709551615 / $devider))) -MaxPartitionEncode ([math]::round($(18446744073709551615 / $devider))) -OptimalPartitionEncode ([math]::round($(18446744073709551615 / $devider)))
    Set-VMGpuPartitionAdapter -VMName $VMName -MinPartitionDecode ([math]::round($(1000000000 / $devider))) -MaxPartitionDecode ([math]::round($(1000000000 / $devider))) -OptimalPartitionDecode ([math]::round($(1000000000 / $devider)))
    Set-VMGpuPartitionAdapter -VMName $VMName -MinPartitionCompute ([math]::round($(1000000000 / $devider))) -MaxPartitionCompute ([math]::round($(1000000000 / $devider))) -OptimalPartitionCompute ([math]::round($(1000000000 / $devider)))

}

"Assigning GPU-P Adapter"
Assign-VMGPUPartitionAdapter

If ($state_was_running){
    "Previous State was running so starting VM..."
    Start-VM $VMName
    }

"Done..."

This has put the new card into my device manager but with the infamous error 43

mitchellurgero commented 10 months ago

put in the 2080, remove the gpu-partition from the VMs then swap to the 3080 and add them back. You'll need the following script to do it too, I think:

https://github.com/jamesstringerparsec/Easy-GPU-PV/issues/280#issuecomment-1530466531

brando148 commented 10 months ago

put in the 2080, remove the gpu-partition from the VMs then swap to the 3080 and add them back. You'll need the following script to do it too, I think:

#280 (comment)

I assume I should set GPUResourceAllocationPercentage = 0 in this instance, in order to remove it?

mitchellurgero commented 10 months ago

No, you would use the cmdlet to remove the gpuadapter completely: Get-VMGpuPartitionAdapter -VMName "VM Name" | Remove-VMGpuPartitionAdapter

brando148 commented 10 months ago

This worked just fine! Thank you for your help.

mitchellurgero commented 10 months ago

I'm glad it worked!