Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

negative memory increment #396

Open
aidenhammond opened this issue Nov 1, 2023 · 0 comments
Open

negative memory increment #396

aidenhammond opened this issue Nov 1, 2023 · 0 comments

Comments

@aidenhammond
Copy link

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant