Optimizing an n-body simulation using Numpy and Glumpy
I am making the process of moving from MatLab to Python, and am attempting a real time N-body simulation as a way of getting to grips with the language. I have completed a script that uses glumpy for the visualisation, and vectorised numpy code for the numerical integration, but it slows waaaaaay down for more than about 150 points. Essentially, I am looking for tips on how to optimize the code so that it can run in real time with at least an order of magnitude more points. Particularly, is there any way of implementing the integration within the shader code using the GPU??
I am aware of the limitations with the Euler method that I have used (and the scaling of the acceleration), and am looking for input on optimization of the software implementation, as opposed to the numerical method itself.
import numpy as np
from glumpy import app, gloo, gl
#VERTEX SHADER CODE
vertex = """
attribute vec2 position;
void main() {
gl_PointSize = 5.0;
gl_Position = vec4(position, 0.0, 1.0);
} """
#FRAGMENT SHADER CODE
fragment = """
void main() {
gl_FragColor = vec4(vec3(0.5), 1.0);
} """
#CREATE ARRAY OF POSITIONS
n_points = int(300) #number of points
p = np.random.uniform(-1,1,(n_points,2)) #array of positions (x,y)
v = np.zeros((n_points,2)) #array of velocities (xdot,ydot)
m = np.ones((n_points,1)) #array of masses
a = np.zeros((n_points,2)) #array of accelerations
index = np.linspace(0,n_points-1,n_points)
#OPEN WINDOW AND CREATE SHADER PROGRAM
window = app.Window(512,512, color = (1,1,1,1))
points = gloo.Program(vertex,fragment,count = n_points)
points["position"] = p
@window.event
def on_draw(dt):
global v, p, a, m, theta
for i in range(n_points): #for each point
delta_x = p[index != i, 0] - p[i, 0] #distance in x to each other point
delta_y = p[index != i, 1] - p[i, 1] #distance in y to each other point
mass = m[index != i,:] #mass of other points
theta = np.arctan2(delta_y, delta_x) #angle to other points
r = (delta_x**2 + delta_y**2)*0.5 + 0.01 #distance to other points
a[i,0] = np.sum(mass * np.cos(theta) / r**2) #acceleration in x
a[i,1] = np.sum(mass * np.sin(theta) / r**2) #acceleration in y
print(dt)
a = a*0.00000001
v = v + a*dt
p = p + v*dt
window.clear()
points["position"] = p
points.draw(gl.GL_POINTS)
app.run()
python numpy glumpy
add a comment |
I am making the process of moving from MatLab to Python, and am attempting a real time N-body simulation as a way of getting to grips with the language. I have completed a script that uses glumpy for the visualisation, and vectorised numpy code for the numerical integration, but it slows waaaaaay down for more than about 150 points. Essentially, I am looking for tips on how to optimize the code so that it can run in real time with at least an order of magnitude more points. Particularly, is there any way of implementing the integration within the shader code using the GPU??
I am aware of the limitations with the Euler method that I have used (and the scaling of the acceleration), and am looking for input on optimization of the software implementation, as opposed to the numerical method itself.
import numpy as np
from glumpy import app, gloo, gl
#VERTEX SHADER CODE
vertex = """
attribute vec2 position;
void main() {
gl_PointSize = 5.0;
gl_Position = vec4(position, 0.0, 1.0);
} """
#FRAGMENT SHADER CODE
fragment = """
void main() {
gl_FragColor = vec4(vec3(0.5), 1.0);
} """
#CREATE ARRAY OF POSITIONS
n_points = int(300) #number of points
p = np.random.uniform(-1,1,(n_points,2)) #array of positions (x,y)
v = np.zeros((n_points,2)) #array of velocities (xdot,ydot)
m = np.ones((n_points,1)) #array of masses
a = np.zeros((n_points,2)) #array of accelerations
index = np.linspace(0,n_points-1,n_points)
#OPEN WINDOW AND CREATE SHADER PROGRAM
window = app.Window(512,512, color = (1,1,1,1))
points = gloo.Program(vertex,fragment,count = n_points)
points["position"] = p
@window.event
def on_draw(dt):
global v, p, a, m, theta
for i in range(n_points): #for each point
delta_x = p[index != i, 0] - p[i, 0] #distance in x to each other point
delta_y = p[index != i, 1] - p[i, 1] #distance in y to each other point
mass = m[index != i,:] #mass of other points
theta = np.arctan2(delta_y, delta_x) #angle to other points
r = (delta_x**2 + delta_y**2)*0.5 + 0.01 #distance to other points
a[i,0] = np.sum(mass * np.cos(theta) / r**2) #acceleration in x
a[i,1] = np.sum(mass * np.sin(theta) / r**2) #acceleration in y
print(dt)
a = a*0.00000001
v = v + a*dt
p = p + v*dt
window.clear()
points["position"] = p
points.draw(gl.GL_POINTS)
app.run()
python numpy glumpy
add a comment |
I am making the process of moving from MatLab to Python, and am attempting a real time N-body simulation as a way of getting to grips with the language. I have completed a script that uses glumpy for the visualisation, and vectorised numpy code for the numerical integration, but it slows waaaaaay down for more than about 150 points. Essentially, I am looking for tips on how to optimize the code so that it can run in real time with at least an order of magnitude more points. Particularly, is there any way of implementing the integration within the shader code using the GPU??
I am aware of the limitations with the Euler method that I have used (and the scaling of the acceleration), and am looking for input on optimization of the software implementation, as opposed to the numerical method itself.
import numpy as np
from glumpy import app, gloo, gl
#VERTEX SHADER CODE
vertex = """
attribute vec2 position;
void main() {
gl_PointSize = 5.0;
gl_Position = vec4(position, 0.0, 1.0);
} """
#FRAGMENT SHADER CODE
fragment = """
void main() {
gl_FragColor = vec4(vec3(0.5), 1.0);
} """
#CREATE ARRAY OF POSITIONS
n_points = int(300) #number of points
p = np.random.uniform(-1,1,(n_points,2)) #array of positions (x,y)
v = np.zeros((n_points,2)) #array of velocities (xdot,ydot)
m = np.ones((n_points,1)) #array of masses
a = np.zeros((n_points,2)) #array of accelerations
index = np.linspace(0,n_points-1,n_points)
#OPEN WINDOW AND CREATE SHADER PROGRAM
window = app.Window(512,512, color = (1,1,1,1))
points = gloo.Program(vertex,fragment,count = n_points)
points["position"] = p
@window.event
def on_draw(dt):
global v, p, a, m, theta
for i in range(n_points): #for each point
delta_x = p[index != i, 0] - p[i, 0] #distance in x to each other point
delta_y = p[index != i, 1] - p[i, 1] #distance in y to each other point
mass = m[index != i,:] #mass of other points
theta = np.arctan2(delta_y, delta_x) #angle to other points
r = (delta_x**2 + delta_y**2)*0.5 + 0.01 #distance to other points
a[i,0] = np.sum(mass * np.cos(theta) / r**2) #acceleration in x
a[i,1] = np.sum(mass * np.sin(theta) / r**2) #acceleration in y
print(dt)
a = a*0.00000001
v = v + a*dt
p = p + v*dt
window.clear()
points["position"] = p
points.draw(gl.GL_POINTS)
app.run()
python numpy glumpy
I am making the process of moving from MatLab to Python, and am attempting a real time N-body simulation as a way of getting to grips with the language. I have completed a script that uses glumpy for the visualisation, and vectorised numpy code for the numerical integration, but it slows waaaaaay down for more than about 150 points. Essentially, I am looking for tips on how to optimize the code so that it can run in real time with at least an order of magnitude more points. Particularly, is there any way of implementing the integration within the shader code using the GPU??
I am aware of the limitations with the Euler method that I have used (and the scaling of the acceleration), and am looking for input on optimization of the software implementation, as opposed to the numerical method itself.
import numpy as np
from glumpy import app, gloo, gl
#VERTEX SHADER CODE
vertex = """
attribute vec2 position;
void main() {
gl_PointSize = 5.0;
gl_Position = vec4(position, 0.0, 1.0);
} """
#FRAGMENT SHADER CODE
fragment = """
void main() {
gl_FragColor = vec4(vec3(0.5), 1.0);
} """
#CREATE ARRAY OF POSITIONS
n_points = int(300) #number of points
p = np.random.uniform(-1,1,(n_points,2)) #array of positions (x,y)
v = np.zeros((n_points,2)) #array of velocities (xdot,ydot)
m = np.ones((n_points,1)) #array of masses
a = np.zeros((n_points,2)) #array of accelerations
index = np.linspace(0,n_points-1,n_points)
#OPEN WINDOW AND CREATE SHADER PROGRAM
window = app.Window(512,512, color = (1,1,1,1))
points = gloo.Program(vertex,fragment,count = n_points)
points["position"] = p
@window.event
def on_draw(dt):
global v, p, a, m, theta
for i in range(n_points): #for each point
delta_x = p[index != i, 0] - p[i, 0] #distance in x to each other point
delta_y = p[index != i, 1] - p[i, 1] #distance in y to each other point
mass = m[index != i,:] #mass of other points
theta = np.arctan2(delta_y, delta_x) #angle to other points
r = (delta_x**2 + delta_y**2)*0.5 + 0.01 #distance to other points
a[i,0] = np.sum(mass * np.cos(theta) / r**2) #acceleration in x
a[i,1] = np.sum(mass * np.sin(theta) / r**2) #acceleration in y
print(dt)
a = a*0.00000001
v = v + a*dt
p = p + v*dt
window.clear()
points["position"] = p
points.draw(gl.GL_POINTS)
app.run()
python numpy glumpy
python numpy glumpy
asked Nov 20 '18 at 23:47
SeBeastSeBeast
104
104
add a comment |
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53403315%2foptimizing-an-n-body-simulation-using-numpy-and-glumpy%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53403315%2foptimizing-an-n-body-simulation-using-numpy-and-glumpy%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown