-
Notifications
You must be signed in to change notification settings - Fork 387
Open
Description
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
Labels
No labels