use index assignment instead of torch.where to improve memory ussage in simulated annealing and greedy
Laouen opened this issue · 1 comments
The current simulated annealing and greedy algorith uses torch.where to assign the new values to the current solutions. This creates an intermediate new tensor that consumes memory. Instead the new simulated annealing uses index assignment which updates in place the values of the current solution tensors and consumes less memory as explained in the following example:
To understand the memory consumption differences between the two PyTorch operations, let's break down what each operation does:
1. Using torch.where
best_solution = torch.where(
new_global_maxima.unsqueeze(1).expand((-1, order)), # match correct shape
new_solution,
best_solution
)
torch.where
:- This function returns a tensor composed of elements from
new_solution
where the condition (i.e.,new_global_maxima.unsqueeze(1).expand((-1, order))
) isTrue
and frombest_solution
where it isFalse
. - Memory Consumption:
- The
torch.where
operation generally creates a new tensor to hold the result. This new tensor will have the same shape asbest_solution
andnew_solution
. - The intermediate tensor created by
new_global_maxima.unsqueeze(1).expand((-1, order))
also consumes memory temporarily, which is shaped according to the expanded size. - Thus, memory is required for the output tensor and the temporary expanded tensor.
- The
- This function returns a tensor composed of elements from
2. Index assignment
best_solution[new_global_maxima] = current_solution[new_global_maxima]
- Index-based Assignment:
- This operation directly updates the
best_solution
tensor at the indices specified bynew_global_maxima
with values fromcurrent_solution
at the same indices. - Memory Consumption:
- There is no new tensor creation here; instead,
best_solution
is updated in place. - Memory is used only for the subset of elements accessed and copied from
current_solution
tobest_solution
, not for creating a new tensor. - This operation is generally more memory-efficient since it avoids the overhead of creating a new tensor.
- There is no new tensor creation here; instead,
- This operation directly updates the
Summary of Memory Consumption
torch.where
: Consumes more memory due to the creation of a new tensor and potentially larger intermediate tensors (e.g., from expanding).- Index Assignment: More memory-efficient as it updates tensors in place without needing to allocate memory for a new tensor.
When to Use Which
- Use
torch.where
when you need a new tensor and cannot modify the originalbest_solution
. - Use index assignment when you want to update an existing tensor in place and save memory.
In general, if you are concerned about memory usage, prefer the index assignment method as it avoids the overhead of allocating new memory for the result.
The idea is to always use index assignment given that we are overriding the value of the current tensors and not creating new ones.