From 8c0166d52babb26e755c6275544dd003423b04f3 Mon Sep 17 00:00:00 2001 From: itzzdev09 Date: Fri, 11 Sep 2026 17:51:46 +0530 Subject: [PATCH] Follow the input tensor's device instead of forcing CUDA All four model files move the adjacency matrix with: self.A = self.A.cuda(x.get_device()) torch.Tensor.get_device() returns -1 for a CPU tensor, and .cuda() requests CUDA regardless of where x actually lives. On a machine without a GPU the call is therefore .cuda(-1), which raises: RuntimeError: Device index must not be negative Reproduced on torch 2.14.0+cpu: >>> x = torch.zeros(2, 3) >>> x.get_device() -1 >>> torch.zeros(3, 3).cuda(x.get_device()) RuntimeError: Device index must not be negative >>> torch.zeros(3, 3).to(x.device) tensor(..., device='cpu') Using .to(x.device) follows whichever device x is already on: the same GPU when the model runs on CUDA, and CPU otherwise. This is also what the StackOverflow answer linked from the issue recommends. Applied to all four copies of the model: DK/WeatherGCNet, DK/WeatherGCNet with gamma, NL/WeatherGCNet, NL/WeatherGCNet with gamma. Fixes #1. Co-Authored-By: Claude Opus 5 --- .../WeatherGCNet with gamma/model_dk.py | 5 ++++- DK wind speed forecasting/WeatherGCNet/model_dk.py | 5 ++++- .../WeatherGCNet with gamma/model_nl.py | 5 ++++- NL wind speed forecasting/WeatherGCNet/model_nl.py | 5 ++++- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/DK wind speed forecasting/WeatherGCNet with gamma/model_dk.py b/DK wind speed forecasting/WeatherGCNet with gamma/model_dk.py index 68b9036..96a1418 100644 --- a/DK wind speed forecasting/WeatherGCNet with gamma/model_dk.py +++ b/DK wind speed forecasting/WeatherGCNet with gamma/model_dk.py @@ -75,7 +75,10 @@ def forward(self, x): f_in = x.contiguous().view(N, C * T, V) adj_mat = None - self.A = self.A.cuda(x.get_device()) + # x.get_device() returns -1 for a CPU tensor, and .cuda() forces CUDA + # regardless, so this raised "Device index must not be negative" on any + # machine without a GPU. .to() follows whichever device x is already on. + self.A = self.A.to(x.device) adj_mat = self.B[:,:] + self.gamma * self.A[:,:] adj_mat_min = torch.min(adj_mat) adj_mat_max = torch.max(adj_mat) diff --git a/DK wind speed forecasting/WeatherGCNet/model_dk.py b/DK wind speed forecasting/WeatherGCNet/model_dk.py index 08459ac..5f10773 100644 --- a/DK wind speed forecasting/WeatherGCNet/model_dk.py +++ b/DK wind speed forecasting/WeatherGCNet/model_dk.py @@ -76,7 +76,10 @@ def forward(self, x): f_in = x.contiguous().view(N, C * T, V) adj_mat = None - self.A = self.A.cuda(x.get_device()) + # x.get_device() returns -1 for a CPU tensor, and .cuda() forces CUDA + # regardless, so this raised "Device index must not be negative" on any + # machine without a GPU. .to() follows whichever device x is already on. + self.A = self.A.to(x.device) adj_mat = self.B[:,:] + self.A[:,:] adj_mat_min = torch.min(adj_mat) adj_mat_max = torch.max(adj_mat) diff --git a/NL wind speed forecasting/WeatherGCNet with gamma/model_nl.py b/NL wind speed forecasting/WeatherGCNet with gamma/model_nl.py index 2ceb277..46146c3 100644 --- a/NL wind speed forecasting/WeatherGCNet with gamma/model_nl.py +++ b/NL wind speed forecasting/WeatherGCNet with gamma/model_nl.py @@ -77,7 +77,10 @@ def forward(self, x): f_in = x.contiguous().view(N, C * T, V) adj_mat = None - self.A = self.A.cuda(x.get_device()) + # x.get_device() returns -1 for a CPU tensor, and .cuda() forces CUDA + # regardless, so this raised "Device index must not be negative" on any + # machine without a GPU. .to() follows whichever device x is already on. + self.A = self.A.to(x.device) adj_mat = self.B[:,:] + self.gamma * self.A[:,:] adj_mat_min = torch.min(adj_mat) adj_mat_max = torch.max(adj_mat) diff --git a/NL wind speed forecasting/WeatherGCNet/model_nl.py b/NL wind speed forecasting/WeatherGCNet/model_nl.py index 89ec71b..5d11bad 100644 --- a/NL wind speed forecasting/WeatherGCNet/model_nl.py +++ b/NL wind speed forecasting/WeatherGCNet/model_nl.py @@ -74,7 +74,10 @@ def forward(self, x): f_in = x.contiguous().view(N, C * T, V) adj_mat = None - self.A = self.A.cuda(x.get_device()) + # x.get_device() returns -1 for a CPU tensor, and .cuda() forces CUDA + # regardless, so this raised "Device index must not be negative" on any + # machine without a GPU. .to() follows whichever device x is already on. + self.A = self.A.to(x.device) adj_mat = self.B[:,:] + self.A[:,:] adj_mat_min = torch.min(adj_mat) adj_mat_max = torch.max(adj_mat)