Skip to content

negative memory increment #396

@aidenhammond

Description

@aidenhammond

I've seen similar tickets from 2018 on this topic, but I assume they've been fixed since. Getting a negative memory increment when running some code. Here is the code that I am running:

from torch import Tensor, linspace, meshgrid, zeros, square, div, sum, norm, sqrt, nan_to_num, nonzero, device, zeros_like, atan, cat, empty, subtract
import argparse
from torch.cuda import is_available
from torch.nn.functional import normalize
from scipy.constants import pi, epsilon_0
from math import ceil
from jaxtyping import Shaped
from matplotlib.pyplot import figure, show
from numpy import abs, min
import memory_profiler


#################################
#                               #
#             Setup             #
#                               #
#################################
# Checking for cuda-capable device (for gpu assistance)
device = device("cuda:0" if is_available() else "cpu")

# Parsing arguments
parser = argparse.ArgumentParser()
parser.add_argument('--charge', type=str, help='The name of the person.')
parser.add_argument('--side-length', type=float, help='The y-coordinate of observation.')
parser.add_argument('--x', type=float, help='The x-coordinate of observation.')
parser.add_argument('--y', type=float, help='The y-coordinate of observation.')
parser.add_argument('--z', type=float, help='The z-coordinate of observation.')
parser.add_argument('--n', type=float, help='The number of points.')

args = parser.parse_args() # get arguments


# set arguments to variables to save space
@profile
def main():
	q = float(args.charge)
	L = float(args.side_length)
	x = float(args.x)
	y = float(args.y)
	z = float(args.z)
	N = int(args.n)
	sigma = q / L**2 # useful later
	k= (q/N**2) / (4.0 * pi * epsilon_0)
	_k = sigma / (pi*epsilon_0)
	Ls = (L/2)**2

	#### Preallocating tensors
	# creating N number of points along z axis from 0 to z
	z_coords = linspace(0, z, N, device=device)
	_p = zeros(N, 1, 1, 3, device=device)
	result = empty(N, 3)
	estimated = empty(N,3)


	# setting up tensor representing the square on the xy plane centered at the origin
	# think of it like a cube of size 1*N*N where each point in that
	# cube holds 3 values
	# shape is [1,N,N,3]
	t = zeros(1,N,N,3, device=device)

	# Creating one-dim tensors of size N whose values are evenly spaced
	# between -L/2 and L/2 for both x and y coordinates of charges 
	# throughout a square plane centered at the origin
	x_coords = linspace(-L/2.0, L/2.0, N) if N > 1 else Tensor([0.0])
	y_coords = linspace(-L/2.0, L/2.0, N) if N > 1 else Tensor([0.0])

	# putting those coordinates into a 2D grid
	_x, _y = meshgrid(x_coords, y_coords)

	# putting the grid in for the x and y components along the last
	# dimension of our tensor that represents the square
	t[:,:,:,0] = _x
	t[:,:,:,1] = _y

	# point of observation
	# shape is [1,1,1,3]
	p = Tensor([[[[x,y,z]]]], device=device)

	# print to console
	point = p[0][0][0]
	p = p.subtract(t)

	# basic efield equation
	#	 1       q
	#  E = ------ * ---- *r_hat
	#      4pi*e0    r^2
	print("E-Field at ", point," is: ", nan_to_num(sum((div(k, square(p)))*normalize(p,dim=3), dim=(1,2))))

	#################################
	#                               #
	#    Finding Percent Error      #
	#                               #
	#################################


	# reshaping and adding to tensor of correct shape
	z_coords = z_coords.view(N, 1, 1)
	_p[:,:,:,2] = z_coords


	# finding estimated at the points along the z axis
	estimated = nan_to_num(sum((div(k, square(_p-t)))*normalize(_p-t,dim=3), dim=(1,2)))

	# finding actual
	#
	#       sigma            /          (L/2)^2         \
	#  E = ------- * tan^-1 ( -------------------------- )
	#       pi*e0            \ z* sqrt(z^2 + 2*(L/2)^2) /
	#

	e = (_k) * atan(div(Ls,_p * sqrt(square(_p) + 2*Ls))) * normalize(_p, dim=3)
	actual = nan_to_num(e.squeeze(1).squeeze(1))

	#################################
	#                               #
	#     Printing to console       #
	#                               #
	#################################
	z_coords = z_coords.squeeze(-1).squeeze(-1)

	a = actual[:, 2].squeeze(-1).cpu().numpy()
	e = estimated[:, 2].squeeze(-1).cpu().numpy()

	print("Plotting....")
	#
	#     Plotting
	#
	fig = figure()
	ax1 = fig.add_subplot(1,2,1)
	ax1.plot(z_coords.cpu().numpy(), a, label="Actual")
	ax1.plot(z_coords.cpu().numpy(), e, label="Estimate")

	ax2= fig.add_subplot(1,2,2)
	ax2.plot(z_coords.cpu().numpy(), abs(e-a)/a, label="Percent Error")

	show()
main()

This is how I am running it:

python -m memory_profiler efield.py --charge 0.1 --side-length 0.01 --x -1.694 --y -0.051 --z 2.345 --n 1001

This is the output I get:

E-Field at  tensor([-1.6940, -0.0510,  2.3450])  is:  tensor([[-1.8337e+08, -6.1105e+09,  1.3247e+08]])
Plotting....
efield.py:134: RuntimeWarning: invalid value encountered in divide
  ax2.plot(z_coords.cpu().numpy(), abs(e-a)/a, label="Percent Error")
Filename: efield.py

Line #    Mem usage    Increment  Occurrences   Line Contents
=============================================================
    34  207.062 MiB  207.062 MiB           1   @profile
    35                                         def main():
    36  207.062 MiB    0.000 MiB           1   	q = float(args.charge)
    37  207.062 MiB    0.000 MiB           1   	L = float(args.side_length)
    38  207.062 MiB    0.000 MiB           1   	x = float(args.x)
    39  207.062 MiB    0.000 MiB           1   	y = float(args.y)
    40  207.062 MiB    0.000 MiB           1   	z = float(args.z)
    41  207.062 MiB    0.000 MiB           1   	N = int(args.n)
    42  207.062 MiB    0.000 MiB           1   	sigma = q / L**2 # useful later
    43  207.062 MiB    0.000 MiB           1   	k= (q/N**2) / (4.0 * pi * epsilon_0)
    44  207.062 MiB    0.000 MiB           1   	_k = sigma / (pi*epsilon_0)
    45  207.062 MiB    0.000 MiB           1   	Ls = (L/2)**2
    46                                         
    47                                         	#### Preallocating tensors
    48                                         	# creating N number of points along z axis from 0 to z
    49  207.594 MiB    0.531 MiB           1   	z_coords = linspace(0, z, N, device=device)
    50  207.781 MiB    0.188 MiB           1   	_p = zeros(N, 1, 1, 3, device=device)
    51  207.797 MiB    0.016 MiB           1   	result = empty(N, 3)
    52  207.797 MiB    0.000 MiB           1   	estimated = empty(N,3)
    53                                         
    54                                         
    55                                         	# setting up tensor representing the square on the xy plane centered at the origin
    56                                         	# think of it like a cube of size 1*N*N where each point in that
    57                                         	# cube holds 3 values
    58                                         	# shape is [1,N,N,3]
    59  219.516 MiB   11.719 MiB           1   	t = zeros(1,N,N,3, device=device)
    60                                         
    61                                         	# Creating one-dim tensors of size N whose values are evenly spaced
    62                                         	# between -L/2 and L/2 for both x and y coordinates of charges 
    63                                         	# throughout a square plane centered at the origin
    64  219.516 MiB    0.000 MiB           1   	x_coords = linspace(-L/2.0, L/2.0, N) if N > 1 else Tensor([0.0])
    65  219.516 MiB    0.000 MiB           1   	y_coords = linspace(-L/2.0, L/2.0, N) if N > 1 else Tensor([0.0])
    66                                         
    67                                         	# putting those coordinates into a 2D grid
    68  220.047 MiB    0.531 MiB           1   	_x, _y = meshgrid(x_coords, y_coords)
    69                                         
    70                                         	# putting the grid in for the x and y components along the last
    71                                         	# dimension of our tensor that represents the square
    72  220.547 MiB    0.500 MiB           1   	t[:,:,:,0] = _x
    73  220.547 MiB    0.000 MiB           1   	t[:,:,:,1] = _y
    74                                         
    75                                         	# point of observation
    76                                         	# shape is [1,1,1,3]
    77  220.656 MiB    0.109 MiB           1   	p = Tensor([[[[x,y,z]]]], device=device)
    78                                         
    79                                         	# print to console
    80  220.656 MiB    0.000 MiB           1   	point = p[0][0][0]
    81  232.281 MiB   11.625 MiB           1   	p = p.subtract(t)
    82                                         
    83                                         	# basic efield equation
    84                                         	#	 1       q
    85                                         	#  E = ------ * ---- *r_hat
    86                                         	#      4pi*e0    r^2
    87  276.828 MiB   44.547 MiB           1   	print("E-Field at ", point," is: ", nan_to_num(sum((div(k, square(p)))*normalize(p,dim=3), dim=(1,2))))
    88                                         
    89                                         	#################################
    90                                         	#                               #
    91                                         	#    Finding Percent Error      #
    92                                         	#                               #
    93                                         	#################################
    94                                         
    95                                         
    96                                         	# reshaping and adding to tensor of correct shape
    97  276.844 MiB    0.016 MiB           1   	z_coords = z_coords.view(N, 1, 1)
    98  276.844 MiB    0.000 MiB           1   	_p[:,:,:,2] = z_coords
    99                                         
   100                                         
   101                                         	# finding estimated at the points along the z axis
   102   53.266 MiB -223.578 MiB           1   	estimated = nan_to_num(sum((div(k, square(_p-t)))*normalize(_p-t,dim=3), dim=(1,2)))
   103                                         
   104                                         	# finding actual
   105                                         	#
   106                                         	#       sigma            /          (L/2)^2         \
   107                                         	#  E = ------- * tan^-1 ( -------------------------- )
   108                                         	#       pi*e0            \ z* sqrt(z^2 + 2*(L/2)^2) /
   109                                         	#
   110                                         
   111   56.781 MiB    3.516 MiB           1   	e = (_k) * atan(div(Ls,_p * sqrt(square(_p) + 2*Ls))) * normalize(_p, dim=3)
   112   57.000 MiB    0.219 MiB           1   	actual = nan_to_num(e.squeeze(1).squeeze(1))
   113                                         
   114                                         	#################################
   115                                         	#                               #
   116                                         	#     Printing to console       #
   117                                         	#                               #
   118                                         	#################################
   119   57.094 MiB    0.094 MiB           1   	z_coords = z_coords.squeeze(-1).squeeze(-1)
   120                                         
   121   57.469 MiB    0.375 MiB           1   	a = actual[:, 2].squeeze(-1).cpu().numpy()
   122   57.469 MiB    0.000 MiB           1   	e = estimated[:, 2].squeeze(-1).cpu().numpy()
   123                                         
   124   57.609 MiB    0.141 MiB           1   	print("Plotting....")
   125                                         	#
   126                                         	#     Plotting
   127                                         	#
   128  100.125 MiB   42.516 MiB           1   	fig = figure()
   129  108.234 MiB    8.109 MiB           1   	ax1 = fig.add_subplot(1,2,1)
   130  108.500 MiB    0.266 MiB           1   	ax1.plot(z_coords.cpu().numpy(), a, label="Actual")
   131  108.547 MiB    0.047 MiB           1   	ax1.plot(z_coords.cpu().numpy(), e, label="Estimate")
   132                                         
   133  108.953 MiB    0.406 MiB           1   	ax2= fig.add_subplot(1,2,2)
   134  109.344 MiB    0.391 MiB           1   	ax2.plot(z_coords.cpu().numpy(), abs(e-a)/a, label="Percent Error")
   135                                         
   136  172.156 MiB   62.812 MiB           1   	show()

Line 102 has a memory increment of -223.578 MiB.

Here is an output of running uname -a on the M1 pro system:

Darwin MacBook-Pro.local 22.1.0 Darwin Kernel Version 22.1.0: Sun Oct  9 20:15:09 PDT 2022; root:xnu-8792.41.9~2/RELEASE_ARM64_T6000 arm64

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions