restarting
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#*.png
|
||||||
|
*.mkv
|
||||||
|
*.mp4
|
1
README
Normal file
@ -0,0 +1 @@
|
|||||||
|
I will organize and collect this code all into one project some time!
|
BIN
animation/asdf.png
Normal file
After Width: | Height: | Size: 1.0 MiB |
146
animation/gpu_migration.py
Executable file
@ -0,0 +1,146 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import matplotlib.animation as animation
|
||||||
|
import pyopencl as cl
|
||||||
|
from alive_progress import alive_bar
|
||||||
|
from matplotlib.backend_bases import MouseButton
|
||||||
|
|
||||||
|
img_res_x = 1000
|
||||||
|
img_res_y = 1000
|
||||||
|
total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time
|
||||||
|
|
||||||
|
periods = 1
|
||||||
|
square_x = 0
|
||||||
|
square_y = 0
|
||||||
|
|
||||||
|
x_min = (-periods * np.pi) + (square_x * np.pi)
|
||||||
|
x_max = (periods * np.pi) + (square_x * np.pi)
|
||||||
|
y_min = (-periods * np.pi) + (square_y * np.pi)
|
||||||
|
y_max = (periods * np.pi) + (square_y * np.pi)
|
||||||
|
|
||||||
|
escape = 10000
|
||||||
|
iterations = 255*3
|
||||||
|
c_x = 2 * np.pi
|
||||||
|
c_y = 2 * np.pi
|
||||||
|
|
||||||
|
animation_progres_save = "ani1_less.mp4"
|
||||||
|
single_frame_save = "asdf.png"
|
||||||
|
|
||||||
|
opencl_context = cl.create_some_context(interactive=False)
|
||||||
|
opencl_queue = cl.CommandQueue(opencl_context)
|
||||||
|
|
||||||
|
kernel_src_path = "./kernel.c"
|
||||||
|
|
||||||
|
frames = 200
|
||||||
|
rendered_frames = []
|
||||||
|
|
||||||
|
image = np.empty([img_res_x, img_res_y], np.uint32)
|
||||||
|
image_buffer = cl.Buffer(opencl_context, cl.mem_flags.WRITE_ONLY, image.nbytes)
|
||||||
|
|
||||||
|
plt.style.use('dark_background')
|
||||||
|
# fuck this shit
|
||||||
|
fig = plt.figure(frameon=False)
|
||||||
|
fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi)
|
||||||
|
#fig.set_size_inches(width/height, 1, forward=False)
|
||||||
|
|
||||||
|
|
||||||
|
ax = plt.Axes(fig, [0., 0., 1., 1.])
|
||||||
|
#ax.set_axis_off()
|
||||||
|
fig.add_axes(ax)
|
||||||
|
|
||||||
|
cmap = plt.cm.viridis
|
||||||
|
cmap.set_bad((0,0,0))
|
||||||
|
cmap.set_over((0,0,0))
|
||||||
|
cmap.set_under((0,0,0))
|
||||||
|
|
||||||
|
bruh = None
|
||||||
|
|
||||||
|
def on_click(event):
|
||||||
|
global bruh
|
||||||
|
split_ratio = 1
|
||||||
|
if (event.button is MouseButton.MIDDLE) and (event.inaxes):
|
||||||
|
# there's probably a way to set global coordinates;
|
||||||
|
# I don't expect this to go anywhere so I don't really care
|
||||||
|
on_x = ((event.xdata / img_res_x) * abs(x_max - x_min)) + x_min
|
||||||
|
on_y = ((event.ydata / img_res_y) * abs(y_max - y_min)) + y_min
|
||||||
|
|
||||||
|
#I, uh, also don't know the best way to replicate the openCL code automaticly in python
|
||||||
|
#so ajust if nessesary
|
||||||
|
x_hops = []
|
||||||
|
y_hops = []
|
||||||
|
for i in range(iterations):
|
||||||
|
x_hops.append(((on_x - x_min) / abs(x_max - x_min)) * img_res_x)
|
||||||
|
y_hops.append(((on_y - y_min) / abs(y_max - y_min)) * img_res_y)
|
||||||
|
next_x = on_x/np.tan(on_y)
|
||||||
|
on_y = on_y/np.tan(on_x)
|
||||||
|
on_x = next_x
|
||||||
|
if on_x**2 + on_y**2 > escape:
|
||||||
|
break
|
||||||
|
print(y_hops[0])
|
||||||
|
print(on_y)
|
||||||
|
print("{} hops".format(len(x_hops)))
|
||||||
|
if bruh:
|
||||||
|
bruh.pop(0).remove()
|
||||||
|
bruh = ax.plot(x_hops, y_hops)
|
||||||
|
plt.draw()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
print(on_x, on_y)
|
||||||
|
|
||||||
|
|
||||||
|
print("compiling openCL kernel...")
|
||||||
|
with open(kernel_src_path, 'r') as kernel_src:
|
||||||
|
compiled_kernel = cl.Program(opencl_context, kernel_src.read()).build()
|
||||||
|
|
||||||
|
encoding_progress = alive_bar(frames, bar = 'filling', spinner = 'waves')
|
||||||
|
|
||||||
|
def display_encoder_progress(current_frame: int, total_frames: int):
|
||||||
|
print("Encoding: frame {}/{}".format(current_frame, frames))
|
||||||
|
|
||||||
|
|
||||||
|
mp_image = None
|
||||||
|
|
||||||
|
print("Rendering {} frames...".format(frames))
|
||||||
|
plt.show(block=False)
|
||||||
|
if frames > 1:
|
||||||
|
with alive_bar(frames, bar = 'filling', spinner = 'waves') as bar_total:
|
||||||
|
for frame_i in range(0, frames):
|
||||||
|
compiled_kernel.render_frame(opencl_queue, image.shape, None, image_buffer,
|
||||||
|
np.double(abs(x_max - x_min) / img_res_x),
|
||||||
|
np.double(abs(y_max - y_min) / img_res_y),
|
||||||
|
np.double(x_min), np.double(y_min),
|
||||||
|
np.uint32(iterations), np.uint32(escape),
|
||||||
|
np.double(frame_i / frames))
|
||||||
|
|
||||||
|
|
||||||
|
cl.enqueue_copy(opencl_queue, image, image_buffer).wait()
|
||||||
|
rendered_frame = ax.imshow(image, norm="log", aspect="auto", cmap=cmap, animated="True", interpolation='none')
|
||||||
|
if frame_i == 0:
|
||||||
|
mp_image = rendered_frame
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
#mp_image.set_array(image)
|
||||||
|
rendered_frames.append([rendered_frame])
|
||||||
|
bar_total()
|
||||||
|
#fig.canvas.draw()
|
||||||
|
#fig.canvas.flush_events()
|
||||||
|
print("Encoding/Saving...")
|
||||||
|
ani = animation.ArtistAnimation(fig, rendered_frames, interval=30, blit=True)
|
||||||
|
ani.save(animation_progres_save, extra_args=['-preset', 'lossless'], progress_callback=display_encoder_progress, codec="h264_nvenc")
|
||||||
|
else:
|
||||||
|
compiled_kernel.render_frame(opencl_queue, image.shape, None, image_buffer,
|
||||||
|
np.double(abs(x_max - x_min) / img_res_x),
|
||||||
|
np.double(abs(y_max - y_min) / img_res_y),
|
||||||
|
np.double(x_min), np.double(y_min),
|
||||||
|
np.uint32(iterations), np.uint32(escape),
|
||||||
|
np.double(1))
|
||||||
|
cl.enqueue_copy(opencl_queue, image, image_buffer).wait()
|
||||||
|
ax.imshow(image, norm="log", aspect="auto", cmap=cmap)
|
||||||
|
fig.savefig(single_frame_save)
|
||||||
|
plt.autoscale(False)
|
||||||
|
plt.connect('motion_notify_event', on_click)
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
|
30
animation/kernel.c
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
__kernel void basic_test() {
|
||||||
|
printf("this cores ID: (%lu, %lu)\n", get_global_id(0), get_global_id(1));
|
||||||
|
}
|
||||||
|
double cosecant_single(double a, double b) { return a / tan(b); }
|
||||||
|
double secant_single(double a, double b) { return a / sin(b); }
|
||||||
|
|
||||||
|
__kernel void render_frame(__global unsigned int *frame_output,
|
||||||
|
double x_step, double y_step,
|
||||||
|
double x_start, double y_start,
|
||||||
|
unsigned int iterations, unsigned int escape, double r) {
|
||||||
|
unsigned int iter;
|
||||||
|
|
||||||
|
double x_cart = (get_global_id(0) * x_step) + x_start;
|
||||||
|
double y_cart = (get_global_id(1) * y_step) + y_start;
|
||||||
|
size_t img_index = (get_global_id(1) * get_global_size(1)) + get_global_id(0);
|
||||||
|
|
||||||
|
|
||||||
|
double x = sqrt(pow(x_cart, 2) + pow(y_cart, 2));
|
||||||
|
double y = atan(y_cart / x_cart);
|
||||||
|
double next_x;
|
||||||
|
|
||||||
|
for(iter = 0; iter < iterations; iter++) {
|
||||||
|
next_x = (r * cosecant_single(x, y)) + ((1 - r) * secant_single(x, y));
|
||||||
|
y = (r * cosecant_single(y, x)) + ((1 - r) * secant_single(y, x));
|
||||||
|
x = next_x;
|
||||||
|
if((pow(x, 2) + pow(y, 2)) >= escape) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
frame_output[img_index] = iter;
|
||||||
|
}
|
79
animation/notes
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import matplotlib.animation as animation
|
||||||
|
import pyopencl as cl
|
||||||
|
from alive_progress import alive_bar
|
||||||
|
|
||||||
|
img_res_x = 2000
|
||||||
|
img_res_y = 2000
|
||||||
|
total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time
|
||||||
|
|
||||||
|
periods = 1
|
||||||
|
square_x = 0
|
||||||
|
square_y = 0
|
||||||
|
|
||||||
|
xmin = (-periods * np.pi) + (square_x * np.pi)
|
||||||
|
xmax = (periods * np.pi) + (square_x * np.pi)
|
||||||
|
ymin = (-periods * np.pi) + (square_y * np.pi)
|
||||||
|
ymax = (periods * np.pi) + (square_y * np.pi)
|
||||||
|
|
||||||
|
escape = 10000
|
||||||
|
iterations = 255*3
|
||||||
|
c_x = 2 * np.pi
|
||||||
|
c_y = 2 * np.pi
|
||||||
|
|
||||||
|
animation_progres_save = "./animations"
|
||||||
|
frames = 120
|
||||||
|
|
||||||
|
rendered_frames = []
|
||||||
|
|
||||||
|
|
||||||
|
plt.style.use('dark_background')
|
||||||
|
# fuck this shit
|
||||||
|
fig = plt.figure(frameon=False)
|
||||||
|
fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi)
|
||||||
|
#fig.set_size_inches(width/height, 1, forward=False)
|
||||||
|
|
||||||
|
ax = plt.Axes(fig, [0., 0., 1., 1.])
|
||||||
|
ax.set_axis_off()
|
||||||
|
fig.add_axes(ax)
|
||||||
|
|
||||||
|
cmap = plt.cm.viridis
|
||||||
|
cmap.set_bad((0,0,0))
|
||||||
|
cmap.set_over((0,0,0))
|
||||||
|
cmap.set_under((0,0,0))
|
||||||
|
|
||||||
|
opencl_context = cl.create_some_context()
|
||||||
|
opencl_queue = cl.CommandQueue(opencl_context)
|
||||||
|
|
||||||
|
|
||||||
|
#def render():
|
||||||
|
# image = np.empty([img_res_y, img_res_x])
|
||||||
|
# print("Rendering frames")
|
||||||
|
# with alive_bar(frames, bar = 'filling', spinner = 'waves') as bar_total:
|
||||||
|
# for frame in range(frames):
|
||||||
|
# split_ratio = frame / frames
|
||||||
|
# for pix_y, y in enumerate(np.linspace(ymin, ymax, img_res_y)):
|
||||||
|
# for pix_x, x in enumerate(np.linspace(xmin, xmax, img_res_x)):
|
||||||
|
# on_x = x
|
||||||
|
# on_y = y
|
||||||
|
# for i in range(iterations):
|
||||||
|
# next_x = (split_ratio * (on_x/np.sin(on_y))) + ((1 - split_ratio) * on_x/np.tan(on_y))
|
||||||
|
# on_y = (split_ratio * (on_y/np.sin(on_x))) + ((1 - split_ratio) * on_y/np.tan(on_x))
|
||||||
|
# on_x = next_x
|
||||||
|
# if on_x**2 + on_y**2 > escape:
|
||||||
|
# break
|
||||||
|
# image[pix_y][pix_x] = i
|
||||||
|
# rendered_frame = ax.imshow(image, norm="log", aspect="auto", cmap=cmap, animated=False)
|
||||||
|
# rendered_frames.append([rendered_frame])
|
||||||
|
# bar_total()
|
||||||
|
|
||||||
|
def display():
|
||||||
|
print(rendered_frames)
|
||||||
|
ani = animation.ArtistAnimation(fig, rendered_frames, interval=30, blit=True)
|
||||||
|
ani.save("test.mp4")
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
render()
|
||||||
|
display()
|
62
backup
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
from alive_progress import alive_bar
|
||||||
|
|
||||||
|
img_res_x = 1000
|
||||||
|
img_res_y = 1000
|
||||||
|
total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time
|
||||||
|
|
||||||
|
periods = .25
|
||||||
|
square_x = 1
|
||||||
|
square_y = 1
|
||||||
|
|
||||||
|
xmin = (-periods * np.pi) + (square_x * np.pi)
|
||||||
|
xmax = (periods * np.pi) + (square_x * np.pi)
|
||||||
|
ymin = (-periods * np.pi) + (square_y * np.pi)
|
||||||
|
ymax = (periods * np.pi) + (square_y * np.pi)
|
||||||
|
|
||||||
|
escape = 10000
|
||||||
|
iterations = 255*3
|
||||||
|
c_x = 2 * np.pi
|
||||||
|
c_y = 2 * np.pi
|
||||||
|
|
||||||
|
|
||||||
|
image = np.empty([img_res_y, img_res_x])
|
||||||
|
|
||||||
|
with alive_bar(img_res_y, bar = 'filling', spinner = 'waves') as bar:
|
||||||
|
for pix_y, y in enumerate(np.linspace(ymin, ymax, img_res_y)):
|
||||||
|
for pix_x, x in enumerate(np.linspace(xmin, xmax, img_res_x)):
|
||||||
|
on_x = x
|
||||||
|
on_y = y
|
||||||
|
for i in range(iterations):
|
||||||
|
completed_ratio = (((pix_x * pix_y * 1)) / total_pixels)
|
||||||
|
next_x = (completed_ratio * (on_x/np.sin(on_y))) + ((1 - completed_ratio) * on_x/np.tan(on_y))
|
||||||
|
on_y = (completed_ratio * (on_y/np.sin(on_x))) + ((1 - completed_ratio) * on_y/np.tan(on_x))
|
||||||
|
on_x = next_x
|
||||||
|
if on_x**2 + on_y**2 > escape:
|
||||||
|
break
|
||||||
|
image[pix_y][pix_x] = i
|
||||||
|
bar()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
plt.style.use('dark_background')
|
||||||
|
# fuck this shit
|
||||||
|
fig = plt.figure(frameon=False)
|
||||||
|
fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi)
|
||||||
|
#fig.set_size_inches(width/height, 1, forward=False)
|
||||||
|
|
||||||
|
ax = plt.Axes(fig, [0., 0., 1., 1.])
|
||||||
|
ax.set_axis_off()
|
||||||
|
fig.add_axes(ax)
|
||||||
|
|
||||||
|
cmap = plt.cm.viridis
|
||||||
|
cmap.set_bad((0,0,0))
|
||||||
|
cmap.set_over((0,0,0))
|
||||||
|
cmap.set_under((0,0,0))
|
||||||
|
|
||||||
|
ax.imshow(image, norm="log", aspect="auto", cmap=cmap)
|
||||||
|
fig.savefig("linear_transform_sin_tan_arnolds_tongue_hotspot.png")
|
||||||
|
plt.show()
|
BIN
collective/.gpu_migration.py.swo
Normal file
BIN
collective/.gpu_migration.py.swp
Normal file
BIN
collective/.kernel.c.swp
Normal file
165
collective/gpu_migration.py
Executable file
@ -0,0 +1,165 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import matplotlib.animation as animation
|
||||||
|
import matplotlib.style as mplstyle
|
||||||
|
import pyopencl as cl
|
||||||
|
from alive_progress import alive_bar
|
||||||
|
from matplotlib.backend_bases import MouseButton
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
|
# HELLO READER ------------------------------------------------------------------------
|
||||||
|
# yes, I know this script is horrid, but it's more of a scratchpad to quickly test ideas
|
||||||
|
# and not anything I'm ever going to show anyone else.
|
||||||
|
|
||||||
|
img_res_x = 1000
|
||||||
|
img_res_y = 1000
|
||||||
|
total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time
|
||||||
|
|
||||||
|
periods = 1
|
||||||
|
square_x = 0
|
||||||
|
square_y = -2
|
||||||
|
|
||||||
|
escape = 10000
|
||||||
|
iterations = (255*3)
|
||||||
|
c_x = 2 * np.pi
|
||||||
|
c_y = 2 * np.pi
|
||||||
|
|
||||||
|
animation_progres_save = "ani1_less.mp4"
|
||||||
|
single_frame_save = "asdf.png"
|
||||||
|
|
||||||
|
opencl_context = cl.create_some_context(interactive=False)
|
||||||
|
opencl_queue = cl.CommandQueue(opencl_context)
|
||||||
|
|
||||||
|
kernel_src_path = "./kernel.c"
|
||||||
|
|
||||||
|
frames = 1
|
||||||
|
rendered_frames = []
|
||||||
|
|
||||||
|
image = np.empty([img_res_x, img_res_y], np.double)
|
||||||
|
|
||||||
|
plt.style.use('dark_background')
|
||||||
|
# fuck this shit
|
||||||
|
fig = plt.figure(frameon=False)
|
||||||
|
fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi)
|
||||||
|
#fig.set_size_inches(width/height, 1, forward=False)
|
||||||
|
|
||||||
|
|
||||||
|
ax = plt.Axes(fig, [0., 0., 1., 1.])
|
||||||
|
|
||||||
|
manual_limits = [15.832664460420503,
|
||||||
|
16.161782579162786,
|
||||||
|
0.21263776938088172,
|
||||||
|
0.2668613889327035]
|
||||||
|
|
||||||
|
|
||||||
|
#ax.invert_yaxis()
|
||||||
|
ax.set_xlim((-periods * np.pi) + (square_x * np.pi), (periods * np.pi) + (square_x * np.pi))
|
||||||
|
ax.set_ylim((-periods * np.pi) + (square_y * np.pi), (periods * np.pi) + (square_y * np.pi))
|
||||||
|
#ax.set_xlim(manual_limits[0], manual_limits[1])
|
||||||
|
#ax.set_ylim(manual_limits[2], manual_limits[3])
|
||||||
|
|
||||||
|
#ax.set_axis_off()
|
||||||
|
fig.add_axes(ax)
|
||||||
|
mplstyle.use('fast')
|
||||||
|
|
||||||
|
cmap = plt.cm.viridis
|
||||||
|
cmap.set_bad((0,0,0))
|
||||||
|
cmap.set_over((0,0,0))
|
||||||
|
cmap.set_under((0,0,0))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
print("compiling openCL kernel...")
|
||||||
|
with open(kernel_src_path, 'r') as kernel_src:
|
||||||
|
compiled_kernel = cl.Program(opencl_context, kernel_src.read()).build()
|
||||||
|
|
||||||
|
encoding_progress = alive_bar(frames, bar = 'filling', spinner = 'waves')
|
||||||
|
|
||||||
|
def display_encoder_progress(current_frame: int, total_frames: int):
|
||||||
|
print("Encoding: frame {}/{}".format(current_frame, frames))
|
||||||
|
|
||||||
|
temp_render_hook = False
|
||||||
|
mp_image = None
|
||||||
|
|
||||||
|
def render(axes):
|
||||||
|
global temp_render_hook
|
||||||
|
global mp_image
|
||||||
|
if not temp_render_hook:
|
||||||
|
temp_render_hook = True
|
||||||
|
x_min = axes.get_xlim()[0]
|
||||||
|
x_max = axes.get_xlim()[1]
|
||||||
|
y_min = axes.get_ylim()[1]
|
||||||
|
y_max = axes.get_ylim()[0]
|
||||||
|
print(axes.get_ylim())
|
||||||
|
compiled_kernel.render_frame_curvature(opencl_queue, image.shape, None, image_buffer, mask_buffer,
|
||||||
|
np.double(abs(x_max - x_min) / img_res_x),
|
||||||
|
np.double(abs(y_max - y_min) / img_res_y),
|
||||||
|
np.double(x_min), np.double(y_min),
|
||||||
|
np.uint32(iterations), np.uint32(escape),
|
||||||
|
np.double(1))
|
||||||
|
cl.enqueue_copy(opencl_queue, image, image_buffer).wait()
|
||||||
|
print("kernel")
|
||||||
|
if mp_image == None:
|
||||||
|
mp_image = ax.imshow(image, norm="linear", aspect="auto", cmap=cmap, interpolation='none', extent=(x_min, x_max, y_min, y_max)) # TODO
|
||||||
|
else:
|
||||||
|
mp_image.set(extent=(x_min, x_max, y_min, y_max))
|
||||||
|
#ax.set_aspect('equal')
|
||||||
|
#mp_image.set_data(image)
|
||||||
|
mp_image.set_array(image)
|
||||||
|
|
||||||
|
|
||||||
|
fig.canvas.draw_idle()
|
||||||
|
fig.canvas.flush_events()
|
||||||
|
temp_render_hook = False
|
||||||
|
|
||||||
|
#plt.ion()
|
||||||
|
|
||||||
|
#open image
|
||||||
|
mask_path = "mask.png"
|
||||||
|
mask = np.asarray(Image.open(mask_path).convert("L").resize((img_res_x, img_res_y)), dtype=np.double)
|
||||||
|
#mask = np.zeros((img_res_x, img_res_y), dtype=np.double)
|
||||||
|
mask.setflags(write=1)
|
||||||
|
mask /= np.max(mask) # normalize
|
||||||
|
#print(mask.shape)
|
||||||
|
#print(mask.dtype)
|
||||||
|
#print(mask)
|
||||||
|
#ax.imshow(mask, norm="linear")
|
||||||
|
#plt.show()
|
||||||
|
|
||||||
|
image_buffer = cl.Buffer(opencl_context, cl.mem_flags.WRITE_ONLY, image.nbytes)
|
||||||
|
mask_buffer = cl.Buffer(opencl_context, cl.mem_flags.READ_ONLY, mask.nbytes)
|
||||||
|
cl.enqueue_copy(opencl_queue, mask_buffer, mask).wait()
|
||||||
|
#mask_buffer = cl.array.Array(opencl_context,mask.shape, dtype=np.uint8, data=mask)
|
||||||
|
|
||||||
|
#move to render
|
||||||
|
print("Rendering {} frames...".format(frames))
|
||||||
|
if frames > 1:
|
||||||
|
x_min = ax.get_xlim()[0]
|
||||||
|
x_max = ax.get_xlim()[1]
|
||||||
|
y_min = ax.get_ylim()[1]
|
||||||
|
y_max = ax.get_ylim()[0]
|
||||||
|
with alive_bar(frames, bar = 'filling', spinner = 'waves') as bar_total:
|
||||||
|
for frame_i in range(0, frames):
|
||||||
|
compiled_kernel.render_frame_curvature(opencl_queue, image.shape, None, image_buffer, mask_buffer,
|
||||||
|
np.double(abs(x_max - x_min) / img_res_x),
|
||||||
|
np.double(abs(y_max - y_min) / img_res_y),
|
||||||
|
np.double(x_min), np.double(y_min),
|
||||||
|
np.uint32(iterations), np.uint32(escape),
|
||||||
|
np.double(frame_i/frames))
|
||||||
|
|
||||||
|
|
||||||
|
cl.enqueue_copy(opencl_queue, image, image_buffer).wait()
|
||||||
|
rendered_frame = ax.imshow(image, norm="linear", aspect="auto", cmap=cmap, animated="True")
|
||||||
|
rendered_frames.append([rendered_frame])
|
||||||
|
bar_total()
|
||||||
|
print("Encoding/Saving...")
|
||||||
|
ani = animation.ArtistAnimation(fig, rendered_frames, interval=30, blit=True)
|
||||||
|
ani.save(animation_progres_save, extra_args=['-preset', 'lossless'], progress_callback=display_encoder_progress, codec="h264_nvenc")
|
||||||
|
else:
|
||||||
|
ax.callbacks.connect('ylim_changed', render)
|
||||||
|
ax.callbacks.connect('xlim_changed', render)
|
||||||
|
render(ax)
|
||||||
|
plt.savefig("out_texture.png")
|
||||||
|
plt.show(block=True)
|
116
collective/kernel.c
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
//#include <math.h>
|
||||||
|
#define PI 3.141592653589793115997963468544185161590576171875
|
||||||
|
|
||||||
|
double cosecant_single(double a, double b) { return a / cos(b); }
|
||||||
|
double secant_single(double a, double b) { return a / cos(b); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
__kernel void render_frame_orbit_trap(__global double *frame_output, __global double *mask,
|
||||||
|
double x_step, double y_step,
|
||||||
|
double x_start, double y_start,
|
||||||
|
unsigned int iterations, unsigned int escape, double ratio) {
|
||||||
|
|
||||||
|
const vec2 point = (0, 0);
|
||||||
|
|
||||||
|
unsigned int result;
|
||||||
|
unsigned int iter;
|
||||||
|
|
||||||
|
double min_distance = DBL_MAX;
|
||||||
|
|
||||||
|
for(iter = 0; iter < iterations; iter++) {
|
||||||
|
double next_x;
|
||||||
|
double r = mask[img_index];
|
||||||
|
next_x = (r * cosecant_single(x, y)) + ((1 - r) * secant_single(x, y));
|
||||||
|
y = (r * cosecant_single(y, x)) + ((1 - r) * secant_single(y, x));
|
||||||
|
x = next_x;
|
||||||
|
if((pow(x, 2) + pow(y, 2)) >= escape) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
frame_output[img_index] = total_curve / iter;
|
||||||
|
|
||||||
|
}
|
||||||
|
**/
|
||||||
|
|
||||||
|
|
||||||
|
__kernel void render_frame_curvature(__global double *frame_output, __global double *mask,
|
||||||
|
double x_step, double y_step,
|
||||||
|
double x_start, double y_start,
|
||||||
|
unsigned int iterations, unsigned int escape, double ratio) {
|
||||||
|
unsigned int result;
|
||||||
|
unsigned int iter;
|
||||||
|
|
||||||
|
double x_cart = (get_global_id(0) * x_step) + x_start;
|
||||||
|
double y_cart = (get_global_id(1) * y_step) + y_start;
|
||||||
|
double x = sqrt(pow(x_cart, 2) + pow(y_cart, 2));
|
||||||
|
double y = atan(y_cart / x_cart);
|
||||||
|
|
||||||
|
//double x = (get_global_id(0) * x_step) + x_start;
|
||||||
|
//double y = (get_global_id(1) * y_step) + y_start;
|
||||||
|
size_t img_index = (get_global_id(1) * get_global_size(1)) + get_global_id(0);
|
||||||
|
|
||||||
|
double total_curve = 0;
|
||||||
|
|
||||||
|
//just found out vectors are a thing
|
||||||
|
double2 lp[3];
|
||||||
|
|
||||||
|
for(iter = 0; iter < iterations; iter++) {
|
||||||
|
double next_x;
|
||||||
|
double r = mask[img_index];
|
||||||
|
next_x = (r * secant_single(x, y)) + ((1 - r) * cosecant_single(x, y));
|
||||||
|
y = (r * secant_single(y, x)) + ((1 - r) * cosecant_single(y, x));
|
||||||
|
x = next_x;
|
||||||
|
|
||||||
|
if((pow(x, 2) + pow(y, 2)) >= escape) break;
|
||||||
|
lp[2] = lp[1];
|
||||||
|
lp[1] = lp[0];
|
||||||
|
lp[0] = (double2)(x, y); //why do I have to cast this? hope no accuracy lost
|
||||||
|
|
||||||
|
/**
|
||||||
|
if(img_index == 254234) {
|
||||||
|
printf("%u\n", ratio);
|
||||||
|
}
|
||||||
|
**/
|
||||||
|
if(iter >= 2) {
|
||||||
|
double curl = acos(dot((lp[0] - lp[1]), (lp[2] - lp[1])) / (distance(lp[0], lp[1]) * distance(lp[2], lp[1])));
|
||||||
|
total_curve = (total_curve + curl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
frame_output[img_index] = total_curve / iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
__kernel void render_frame(__global double *frame_output, __global double *mask,
|
||||||
|
double x_step, double y_step,
|
||||||
|
double x_start, double y_start,
|
||||||
|
unsigned int iterations, unsigned int escape, double ratio) {
|
||||||
|
unsigned int result;
|
||||||
|
double x_cart = (get_global_id(0) * x_step) + x_start;
|
||||||
|
double y_cart = (get_global_id(1) * y_step) + y_start;
|
||||||
|
size_t img_index = (get_global_id(1) * get_global_size(1)) + get_global_id(0);
|
||||||
|
|
||||||
|
double x = sqrt(pow(x_cart, 2) + pow(y_cart, 2));
|
||||||
|
double y = atan(y_cart / x_cart);
|
||||||
|
|
||||||
|
//double x = (get_global_id(0) * x_step) + x_start;
|
||||||
|
//double y = (get_global_id(1) * y_step) + y_start;
|
||||||
|
|
||||||
|
|
||||||
|
unsigned int iter;
|
||||||
|
|
||||||
|
//vec2 pos;
|
||||||
|
|
||||||
|
for(iter = 0; iter < iterations; iter++) {
|
||||||
|
double next_x;
|
||||||
|
double r = ratio;
|
||||||
|
next_x = (r * cosecant_single(x, y)) + ((1 - r) * secant_single(x, y));
|
||||||
|
y = (r * cosecant_single(y, x)) + ((1 - r) * secant_single(y, x));
|
||||||
|
x = next_x;
|
||||||
|
//if(distance(pos) >= escape) break;
|
||||||
|
if((pow(x, 2) + pow(y, 2)) >= escape) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//TODO turn back to int whenever
|
||||||
|
frame_output[img_index] = (double)iter;
|
||||||
|
//frame_output[img_index] = mask[img_index] * 255;
|
||||||
|
}
|
1
collective/mask.png
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../masks/clouds.png
|
79
collective/notes
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import matplotlib.animation as animation
|
||||||
|
import pyopencl as cl
|
||||||
|
from alive_progress import alive_bar
|
||||||
|
|
||||||
|
img_res_x = 2000
|
||||||
|
img_res_y = 2000
|
||||||
|
total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time
|
||||||
|
|
||||||
|
periods = 1
|
||||||
|
square_x = 0
|
||||||
|
square_y = 0
|
||||||
|
|
||||||
|
xmin = (-periods * np.pi) + (square_x * np.pi)
|
||||||
|
xmax = (periods * np.pi) + (square_x * np.pi)
|
||||||
|
ymin = (-periods * np.pi) + (square_y * np.pi)
|
||||||
|
ymax = (periods * np.pi) + (square_y * np.pi)
|
||||||
|
|
||||||
|
escape = 10000
|
||||||
|
iterations = 255*3
|
||||||
|
c_x = 2 * np.pi
|
||||||
|
c_y = 2 * np.pi
|
||||||
|
|
||||||
|
animation_progres_save = "./animations"
|
||||||
|
frames = 120
|
||||||
|
|
||||||
|
rendered_frames = []
|
||||||
|
|
||||||
|
|
||||||
|
plt.style.use('dark_background')
|
||||||
|
# fuck this shit
|
||||||
|
fig = plt.figure(frameon=False)
|
||||||
|
fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi)
|
||||||
|
#fig.set_size_inches(width/height, 1, forward=False)
|
||||||
|
|
||||||
|
ax = plt.Axes(fig, [0., 0., 1., 1.])
|
||||||
|
ax.set_axis_off()
|
||||||
|
fig.add_axes(ax)
|
||||||
|
|
||||||
|
cmap = plt.cm.viridis
|
||||||
|
cmap.set_bad((0,0,0))
|
||||||
|
cmap.set_over((0,0,0))
|
||||||
|
cmap.set_under((0,0,0))
|
||||||
|
|
||||||
|
opencl_context = cl.create_some_context()
|
||||||
|
opencl_queue = cl.CommandQueue(opencl_context)
|
||||||
|
|
||||||
|
|
||||||
|
#def render():
|
||||||
|
# image = np.empty([img_res_y, img_res_x])
|
||||||
|
# print("Rendering frames")
|
||||||
|
# with alive_bar(frames, bar = 'filling', spinner = 'waves') as bar_total:
|
||||||
|
# for frame in range(frames):
|
||||||
|
# split_ratio = frame / frames
|
||||||
|
# for pix_y, y in enumerate(np.linspace(ymin, ymax, img_res_y)):
|
||||||
|
# for pix_x, x in enumerate(np.linspace(xmin, xmax, img_res_x)):
|
||||||
|
# on_x = x
|
||||||
|
# on_y = y
|
||||||
|
# for i in range(iterations):
|
||||||
|
# next_x = (split_ratio * (on_x/np.sin(on_y))) + ((1 - split_ratio) * on_x/np.tan(on_y))
|
||||||
|
# on_y = (split_ratio * (on_y/np.sin(on_x))) + ((1 - split_ratio) * on_y/np.tan(on_x))
|
||||||
|
# on_x = next_x
|
||||||
|
# if on_x**2 + on_y**2 > escape:
|
||||||
|
# break
|
||||||
|
# image[pix_y][pix_x] = i
|
||||||
|
# rendered_frame = ax.imshow(image, norm="log", aspect="auto", cmap=cmap, animated=False)
|
||||||
|
# rendered_frames.append([rendered_frame])
|
||||||
|
# bar_total()
|
||||||
|
|
||||||
|
def display():
|
||||||
|
print(rendered_frames)
|
||||||
|
ani = animation.ArtistAnimation(fig, rendered_frames, interval=30, blit=True)
|
||||||
|
ani.save("test.mp4")
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
render()
|
||||||
|
display()
|
BIN
collective/out.png
Normal file
After Width: | Height: | Size: 3.8 MiB |
BIN
collective/out_grad.png
Normal file
After Width: | Height: | Size: 3.2 MiB |
BIN
collective/out_texture.png
Normal file
After Width: | Height: | Size: 1.8 MiB |
21
collective/texput.log
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
This is pdfTeX, Version 3.141592653-2.6-1.40.26 (TeX Live 2024/Arch Linux) (preloaded format=pdflatex 2024.4.22) 28 APR 2024 21:33
|
||||||
|
entering extended mode
|
||||||
|
restricted \write18 enabled.
|
||||||
|
%&-line parsing enabled.
|
||||||
|
**
|
||||||
|
|
||||||
|
! Emergency stop.
|
||||||
|
<*>
|
||||||
|
|
||||||
|
End of file on the terminal!
|
||||||
|
|
||||||
|
|
||||||
|
Here is how much of TeX's memory you used:
|
||||||
|
3 strings out of 476076
|
||||||
|
113 string characters out of 5793775
|
||||||
|
1925187 words of memory out of 5000000
|
||||||
|
22212 multiletter control sequences out of 15000+600000
|
||||||
|
558069 words of font info for 36 fonts, out of 8000000 for 9000
|
||||||
|
14 hyphenation exceptions out of 8191
|
||||||
|
0i,0n,0p,13b,6s stack positions out of 10000i,1000n,20000p,200000b,200000s
|
||||||
|
! ==> Fatal error occurred, no output PDF file produced!
|
6
cool_places
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
windows into space
|
||||||
|
15.832664460420503
|
||||||
|
16.161782579162786
|
||||||
|
|
||||||
|
0.21263776938088172
|
||||||
|
0.2668613889327035
|
62
field_tests/backup
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
from alive_progress import alive_bar
|
||||||
|
|
||||||
|
img_res_x = 1000
|
||||||
|
img_res_y = 1000
|
||||||
|
total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time
|
||||||
|
|
||||||
|
periods = .25
|
||||||
|
square_x = 1
|
||||||
|
square_y = 1
|
||||||
|
|
||||||
|
xmin = (-periods * np.pi) + (square_x * np.pi)
|
||||||
|
xmax = (periods * np.pi) + (square_x * np.pi)
|
||||||
|
ymin = (-periods * np.pi) + (square_y * np.pi)
|
||||||
|
ymax = (periods * np.pi) + (square_y * np.pi)
|
||||||
|
|
||||||
|
escape = 10000
|
||||||
|
iterations = 255*3
|
||||||
|
c_x = 2 * np.pi
|
||||||
|
c_y = 2 * np.pi
|
||||||
|
|
||||||
|
|
||||||
|
image = np.empty([img_res_y, img_res_x])
|
||||||
|
|
||||||
|
with alive_bar(img_res_y, bar = 'filling', spinner = 'waves') as bar:
|
||||||
|
for pix_y, y in enumerate(np.linspace(ymin, ymax, img_res_y)):
|
||||||
|
for pix_x, x in enumerate(np.linspace(xmin, xmax, img_res_x)):
|
||||||
|
on_x = x
|
||||||
|
on_y = y
|
||||||
|
for i in range(iterations):
|
||||||
|
completed_ratio = (((pix_x * pix_y * 1)) / total_pixels)
|
||||||
|
next_x = (completed_ratio * (on_x/np.sin(on_y))) + ((1 - completed_ratio) * on_x/np.tan(on_y))
|
||||||
|
on_y = (completed_ratio * (on_y/np.sin(on_x))) + ((1 - completed_ratio) * on_y/np.tan(on_x))
|
||||||
|
on_x = next_x
|
||||||
|
if on_x**2 + on_y**2 > escape:
|
||||||
|
break
|
||||||
|
image[pix_y][pix_x] = i
|
||||||
|
bar()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
plt.style.use('dark_background')
|
||||||
|
# fuck this shit
|
||||||
|
fig = plt.figure(frameon=False)
|
||||||
|
fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi)
|
||||||
|
#fig.set_size_inches(width/height, 1, forward=False)
|
||||||
|
|
||||||
|
ax = plt.Axes(fig, [0., 0., 1., 1.])
|
||||||
|
ax.set_axis_off()
|
||||||
|
fig.add_axes(ax)
|
||||||
|
|
||||||
|
cmap = plt.cm.viridis
|
||||||
|
cmap.set_bad((0,0,0))
|
||||||
|
cmap.set_over((0,0,0))
|
||||||
|
cmap.set_under((0,0,0))
|
||||||
|
|
||||||
|
ax.imshow(image, norm="log", aspect="auto", cmap=cmap)
|
||||||
|
fig.savefig("linear_transform_sin_tan_arnolds_tongue_hotspot.png")
|
||||||
|
plt.show()
|
168
field_tests/basic_field_test.py
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
from alive_progress import alive_bar
|
||||||
|
|
||||||
|
img_res_x = 100
|
||||||
|
img_res_y = 100
|
||||||
|
total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time
|
||||||
|
|
||||||
|
periods = 1
|
||||||
|
square_x = 0
|
||||||
|
square_y = 0
|
||||||
|
|
||||||
|
#xmin = (-periods * np.pi) + (square_x * np.pi)
|
||||||
|
#xmax = (periods * np.pi) + (square_x * np.pi)
|
||||||
|
#ymin = (-periods * np.pi) + (square_y * np.pi)
|
||||||
|
#ymax = (periods * np.pi) + (square_y * np.pi)
|
||||||
|
|
||||||
|
xmin = -10
|
||||||
|
xmax = 10
|
||||||
|
ymin = -10
|
||||||
|
ymax = 10
|
||||||
|
|
||||||
|
escape = 10000
|
||||||
|
iterations = 255*3
|
||||||
|
c_x = 2 * np.pi
|
||||||
|
c_y = 2 * np.pi
|
||||||
|
|
||||||
|
|
||||||
|
image = np.empty([img_res_y, img_res_x])
|
||||||
|
grid = np.meshgrid(np.linspace(ymin, ymax, img_res_y), np.linspace(xmin, xmax, img_res_x))
|
||||||
|
print(grid[0].dtype)
|
||||||
|
|
||||||
|
|
||||||
|
class point_charge():
|
||||||
|
def __init__(self, x, y, c, mod):
|
||||||
|
self.x = x
|
||||||
|
self.y = y
|
||||||
|
self.c = c
|
||||||
|
self.mod = mod
|
||||||
|
def get_field(self, to_x, to_y):
|
||||||
|
if(self.mod):
|
||||||
|
to_x = (to_x % self.mod)
|
||||||
|
to_y = (to_y % self.mod)
|
||||||
|
return (
|
||||||
|
((self.c * (self.x - to_x)) / ((self.x - to_x)**2 + (self.y - to_y)**2)**1.5),
|
||||||
|
((self.c * (self.y - to_y)) / ((self.x - to_x)**2 + (self.y - to_y)**2)**1.5))
|
||||||
|
|
||||||
|
#will remove all the point charge code if it turns out to be good enough to be impliemnted into openCL
|
||||||
|
#point_charges = [point_charge(-5, -5, 100), point_charge(-5, 5, -100), point_charge(5, 0, 100)]
|
||||||
|
point_charges = [point_charge(5,5, 100, 10), point_charge(0,0,-100, 0)]
|
||||||
|
|
||||||
|
|
||||||
|
plt.ion()
|
||||||
|
ax = plt.gca()
|
||||||
|
fig = plt.gcf()
|
||||||
|
ax.set_autoscale_on(False)
|
||||||
|
ax.set_xlim([xmin, xmax])
|
||||||
|
ax.set_ylim([ymin, ymax])
|
||||||
|
|
||||||
|
vector_arrows = None
|
||||||
|
|
||||||
|
def show_field():
|
||||||
|
global vector_arrows
|
||||||
|
grid_f = np.zeros_like(grid)
|
||||||
|
for p in point_charges:
|
||||||
|
grid_f += p.get_field(grid[0], grid[1])
|
||||||
|
#plt.streamplot(grid[0], grid[1], grid_f[0], grid_f[1], density=5)
|
||||||
|
vector_arrows = plt.quiver(grid[0], grid[1], grid_f[0], grid_f[1])
|
||||||
|
plt.show(block=False)
|
||||||
|
plt.pause(.1)
|
||||||
|
|
||||||
|
|
||||||
|
show_field()
|
||||||
|
|
||||||
|
timestep = .1
|
||||||
|
def test_sim():
|
||||||
|
particle_grid = np.meshgrid(np.linspace(ymin, ymax, 100), np.linspace(xmin, xmax, 100))
|
||||||
|
pos = particle_grid
|
||||||
|
acceleration = np.zeros_like(particle_grid)
|
||||||
|
velocity = np.zeros_like(particle_grid)
|
||||||
|
velocity = [np.ones_like(particle_grid[0]) * 1, np.ones_like(particle_grid[0]) * .5]
|
||||||
|
mass = 10
|
||||||
|
charge = 1
|
||||||
|
particle_plot = ax.plot(velocity[0], velocity[1], 'bo', animated=True)
|
||||||
|
#velocity += .1
|
||||||
|
|
||||||
|
background = fig.canvas.copy_from_bbox(ax.bbox)
|
||||||
|
ax.draw_artist(vector_arrows)
|
||||||
|
fig.canvas.blit(fig.bbox)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
fig.canvas.restore_region(background)
|
||||||
|
field = np.zeros_like(particle_grid)
|
||||||
|
# TODO can make this quicker by skipping initilization
|
||||||
|
for p in point_charges:
|
||||||
|
field += p.get_field(pos[0], pos[1])
|
||||||
|
acceleration = ((charge * field) / mass) * timestep
|
||||||
|
#print(acceleration)
|
||||||
|
velocity += acceleration * timestep
|
||||||
|
pos += velocity * timestep
|
||||||
|
|
||||||
|
fig.canvas.restore_region(background)
|
||||||
|
particle_plot[0].set_data(pos[0],pos[1])
|
||||||
|
ax.draw_artist(particle_plot[0])
|
||||||
|
fig.canvas.blit(fig.bbox)
|
||||||
|
fig.canvas.flush_events()
|
||||||
|
plt.pause(1/60)
|
||||||
|
|
||||||
|
#fig.canvas.draw_idle()
|
||||||
|
test_sim()
|
||||||
|
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#with alive_bar(iterations, bar = 'filling', spinner = 'waves') as bar:
|
||||||
|
# for i in range(iterations):
|
||||||
|
# next_x = xx / np.sin(yy)
|
||||||
|
# yy = yy / np.sin(xx)
|
||||||
|
# xx = next_x
|
||||||
|
# bar()
|
||||||
|
#image = np.vstack([xx.ravel(), yy.ravel()])
|
||||||
|
|
||||||
|
|
||||||
|
#meshgrid makes things slower as we can't test individual points for breaking to infinity
|
||||||
|
fractal_test = False
|
||||||
|
if fractal_test:
|
||||||
|
with alive_bar(img_res_y, bar = 'filling', spinner = 'waves') as bar:
|
||||||
|
for pix_y, y in enumerate(np.linspace(ymin, ymax, img_res_y)):
|
||||||
|
for pix_x, x in enumerate(np.linspace(xmin, xmax, img_res_x)):
|
||||||
|
on_x = x
|
||||||
|
on_y = y
|
||||||
|
for i in range(iterations):
|
||||||
|
completed_ratio = (((pix_x * pix_y * 1)) / total_pixels)
|
||||||
|
next_x = (completed_ratio * (on_x/np.sin(on_y))) + ((1 - completed_ratio) * on_x/np.tan(on_y))
|
||||||
|
on_y = (completed_ratio * (on_y/np.sin(on_x))) + ((1 - completed_ratio) * on_y/np.tan(on_x))
|
||||||
|
on_x = next_x
|
||||||
|
if on_x**2 + on_y**2 > escape:
|
||||||
|
break
|
||||||
|
image[pix_y][pix_x] = i
|
||||||
|
bar()
|
||||||
|
else:
|
||||||
|
exit()
|
||||||
|
|
||||||
|
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
plt.style.use('dark_background')
|
||||||
|
# fuck this shit
|
||||||
|
fig = plt.figure(frameon=False)
|
||||||
|
fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi)
|
||||||
|
#fig.set_size_inches(width/height, 1, forward=False)
|
||||||
|
|
||||||
|
ax = plt.Axes(fig, [0., 0., 1., 1.])
|
||||||
|
ax.set_axis_off()
|
||||||
|
fig.add_axes(ax)
|
||||||
|
|
||||||
|
cmap = plt.cm.viridis
|
||||||
|
cmap.set_bad((0,0,0))
|
||||||
|
cmap.set_over((0,0,0))
|
||||||
|
cmap.set_under((0,0,0))
|
||||||
|
|
||||||
|
ax.imshow(image, norm="log", aspect="auto", cmap=cmap)
|
||||||
|
fig.savefig("linear_transform_sin_tan_arnolds_tongue_hotspot.png")
|
||||||
|
plt.show()
|
191
field_tests/field.py
Executable file
@ -0,0 +1,191 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
from alive_progress import alive_bar
|
||||||
|
|
||||||
|
img_res_x = 250
|
||||||
|
img_res_y = 250
|
||||||
|
total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time
|
||||||
|
|
||||||
|
periods = 1
|
||||||
|
square_x = 0
|
||||||
|
square_y = 0
|
||||||
|
|
||||||
|
xmin = (-periods * np.pi) + (square_x * np.pi)
|
||||||
|
xmax = (periods * np.pi) + (square_x * np.pi)
|
||||||
|
ymin = (-periods * np.pi) + (square_y * np.pi)
|
||||||
|
ymax = (periods * np.pi) + (square_y * np.pi)
|
||||||
|
|
||||||
|
#xmin = -10
|
||||||
|
#xmax = 10
|
||||||
|
#ymin = -10
|
||||||
|
#ymax = 10
|
||||||
|
|
||||||
|
escape = 10000
|
||||||
|
iterations = 255*3
|
||||||
|
c_x = 2 * np.pi
|
||||||
|
c_y = 2 * np.pi
|
||||||
|
|
||||||
|
|
||||||
|
grid = np.meshgrid(np.linspace(ymin, ymax, 200), np.linspace(xmin, xmax, 200))
|
||||||
|
#image = np.meshgrid(np.linspace(ymin, ymax, img_res_y), np.linspace(xmin, xmax, img_res_x))
|
||||||
|
image = np.zeros([img_res_y, img_res_x], dtype=np.double)
|
||||||
|
|
||||||
|
|
||||||
|
class point_charge():
|
||||||
|
def __init__(self, x, y, c, mod):
|
||||||
|
self.x = x
|
||||||
|
self.y = y
|
||||||
|
self.c = c
|
||||||
|
self.mod = mod
|
||||||
|
def get_field(self, to_x, to_y):
|
||||||
|
if(self.mod):
|
||||||
|
to_x = (to_x % self.mod)
|
||||||
|
to_y = (to_y % self.mod)
|
||||||
|
return np.array([
|
||||||
|
((self.c * (self.x - to_x)) / ((self.x - to_x)**2 + (self.y - to_y)**2)**1.5),
|
||||||
|
((self.c * (self.y - to_y)) / ((self.x - to_x)**2 + (self.y - to_y)**2)**1.5)])
|
||||||
|
|
||||||
|
#will remove all the point charge code if it turns out to be good enough to be impliemnted into openCL
|
||||||
|
#point_charges = [point_charge(-5, -5, 100), point_charge(-5, 5, -100), point_charge(5, 0, 100)]
|
||||||
|
#point_charges = [point_charge(-1,-1, 100, 10), point_charge(1,1,-100, 0)]
|
||||||
|
point_charges = []
|
||||||
|
|
||||||
|
|
||||||
|
#plt.ion()
|
||||||
|
ax = plt.gca()
|
||||||
|
fig = plt.gcf()
|
||||||
|
#ax.set_autoscale_on(False)
|
||||||
|
#ax.set_xlim([xmin, xmax])
|
||||||
|
#ax.set_ylim([ymin, ymax])
|
||||||
|
|
||||||
|
vector_arrows = None
|
||||||
|
|
||||||
|
def show_field():
|
||||||
|
global vector_arrows
|
||||||
|
grid_f = np.zeros_like(grid)
|
||||||
|
for p in point_charges:
|
||||||
|
grid_f += p.get_field(grid[0], grid[1])
|
||||||
|
#plt.streamplot(grid[0], grid[1], grid_f[0], grid_f[1], density=5)
|
||||||
|
vector_arrows = plt.quiver(grid[0], grid[1], grid_f[0], grid_f[1])
|
||||||
|
plt.show(block=False)
|
||||||
|
plt.pause(.1)
|
||||||
|
|
||||||
|
|
||||||
|
#show_field()
|
||||||
|
|
||||||
|
timestep = .1
|
||||||
|
def test_sim():
|
||||||
|
particle_grid = np.meshgrid(np.linspace(ymin, ymax, 100), np.linspace(xmin, xmax, 100))
|
||||||
|
pos = particle_grid
|
||||||
|
acceleration = np.zeros_like(particle_grid)
|
||||||
|
velocity = np.zeros_like(particle_grid)
|
||||||
|
velocity = [np.ones_like(particle_grid[0]) * 1, np.ones_like(particle_grid[0]) * .5]
|
||||||
|
mass = 10
|
||||||
|
charge = 1
|
||||||
|
particle_plot = ax.plot(velocity[0], velocity[1], 'bo', animated=True)
|
||||||
|
#velocity += .1
|
||||||
|
|
||||||
|
background = fig.canvas.copy_from_bbox(ax.bbox)
|
||||||
|
ax.draw_artist(vector_arrows)
|
||||||
|
fig.canvas.blit(fig.bbox)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
fig.canvas.restore_region(background)
|
||||||
|
field = np.zeros_like(particle_grid)
|
||||||
|
# TODO can make this quicker by skipping initilization
|
||||||
|
for p in point_charges:
|
||||||
|
field += p.get_field(pos[0], pos[1])
|
||||||
|
acceleration = ((charge * field) / mass) * timestep
|
||||||
|
#print(acceleration)
|
||||||
|
velocity += acceleration * timestep
|
||||||
|
pos += velocity * timestep
|
||||||
|
|
||||||
|
fig.canvas.restore_region(background)
|
||||||
|
particle_plot[0].set_data(pos[0],pos[1])
|
||||||
|
ax.draw_artist(particle_plot[0])
|
||||||
|
fig.canvas.blit(fig.bbox)
|
||||||
|
fig.canvas.flush_events()
|
||||||
|
plt.pause(1/60)
|
||||||
|
|
||||||
|
#fig.canvas.draw_idle()
|
||||||
|
#test_sim()
|
||||||
|
|
||||||
|
#exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
max_timesteps = 10
|
||||||
|
|
||||||
|
def get_fractal_iter(img):
|
||||||
|
next_x = img[1][y][x] / np.sin(img[0][y][x])
|
||||||
|
img[0][y][x] = img[0][y][x] / np.sin(img[1][y][x])
|
||||||
|
img[1][y][x] = next_x
|
||||||
|
if (np.square(img[0][y][x]) + np.square(img[1][y][x])) >= escape:
|
||||||
|
z[y][x] = i
|
||||||
|
|
||||||
|
|
||||||
|
#meshgrid makes things slower as we can't test individual points for breaking to infinity;
|
||||||
|
#however, I will fix that later.
|
||||||
|
cmap = plt.cm.viridis
|
||||||
|
cmap.set_bad((0,0,0))
|
||||||
|
cmap.set_over((0,0,0))
|
||||||
|
cmap.set_under((0,0,0))
|
||||||
|
|
||||||
|
with alive_bar(img_res_y, bar = 'filling', spinner = 'waves') as bar:
|
||||||
|
for pix_y, y in enumerate(np.linspace(ymin, ymax, img_res_y)):
|
||||||
|
for pix_x, x in enumerate(np.linspace(xmin, xmax, img_res_x)):
|
||||||
|
on_x = x
|
||||||
|
on_y = y
|
||||||
|
for i in range(iterations):
|
||||||
|
completed_ratio = (((pix_x * pix_y * 1)) / total_pixels)
|
||||||
|
next_x = on_x/np.sin(on_y)
|
||||||
|
on_y = on_y/np.sin(on_x)
|
||||||
|
on_x = next_x
|
||||||
|
|
||||||
|
|
||||||
|
# do physics here - we could just use vectors but i keep rewriting things
|
||||||
|
timesteps = max_
|
||||||
|
acceleration = np.array([0, 0], dtype=np.double)
|
||||||
|
velocity = np.array([on_x, on_y], dtype=np.double) # maybe multiply by stuff
|
||||||
|
pos = np.array([0,0], dtype=np.double)
|
||||||
|
for t in range(timesteps):
|
||||||
|
for p in point_charges:
|
||||||
|
acceleration += p.get_field(on_x, on_y)
|
||||||
|
velocity += acceleration
|
||||||
|
pos += velocity * (timesteps)
|
||||||
|
on_x += pos[0]
|
||||||
|
on_y += pos[1]
|
||||||
|
|
||||||
|
if on_x**2 + on_y**2 > escape:
|
||||||
|
image[pix_x][pix_y] = i
|
||||||
|
break
|
||||||
|
bar()
|
||||||
|
|
||||||
|
ax.imshow(image, norm="log", aspect="auto", cmap=cmap)
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
|
||||||
|
# yeah, I shouldn't have switched to a meshgrid, oh well
|
||||||
|
#z = np.empty_like(image[0])
|
||||||
|
exit(0)
|
||||||
|
with alive_bar(img_res_x, bar = 'filling', spinner = 'waves') as bar:
|
||||||
|
for y in range(img_res_y):
|
||||||
|
for x in range(img_res_x):
|
||||||
|
for i in range(iterations):
|
||||||
|
if image[0][y][x] == np.NAN:
|
||||||
|
continue
|
||||||
|
next_x = image[1][y][x] / np.sin(image[0][y][x])
|
||||||
|
image[0][y][x] = image[0][y][x] / np.sin(image[1][y][x])
|
||||||
|
image[1][y][x] = next_x
|
||||||
|
if (np.square(image[0][y][x]) + np.square(image[1][y][x])) >= escape:
|
||||||
|
z[y][x] = i
|
||||||
|
image[0][y][x] = np.NAN
|
||||||
|
image[1][y][x] = np.NAN
|
||||||
|
break
|
||||||
|
# #do physics here
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bar()
|
||||||
|
#image = np.clip(image, -escape, escape)
|
||||||
|
|
137
field_tests/gpu_migration.py
Executable file
@ -0,0 +1,137 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import matplotlib.animation as animation
|
||||||
|
import pyopencl as cl
|
||||||
|
from alive_progress import alive_bar
|
||||||
|
from matplotlib.backend_bases import MouseButton
|
||||||
|
|
||||||
|
img_res_x = 1000
|
||||||
|
img_res_y = 1000
|
||||||
|
total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time
|
||||||
|
|
||||||
|
periods = 1
|
||||||
|
square_x = 0
|
||||||
|
square_y = 0
|
||||||
|
|
||||||
|
x_min = (-periods * np.pi) + (square_x * np.pi)
|
||||||
|
x_max = (periods * np.pi) + (square_x * np.pi)
|
||||||
|
y_min = (-periods * np.pi) + (square_y * np.pi)
|
||||||
|
y_max = (periods * np.pi) + (square_y * np.pi)
|
||||||
|
|
||||||
|
escape = 10000
|
||||||
|
iterations = 255*3
|
||||||
|
c_x = 2 * np.pi
|
||||||
|
c_y = 2 * np.pi
|
||||||
|
|
||||||
|
animation_progres_save = "ani1_less.mp4"
|
||||||
|
single_frame_save = "asdf.png"
|
||||||
|
|
||||||
|
opencl_context = cl.create_some_context(interactive=False)
|
||||||
|
opencl_queue = cl.CommandQueue(opencl_context)
|
||||||
|
|
||||||
|
kernel_src_path = "./kernel.c"
|
||||||
|
|
||||||
|
frames = 1
|
||||||
|
rendered_frames = []
|
||||||
|
|
||||||
|
image = np.empty([img_res_x, img_res_y], np.uint32)
|
||||||
|
image_buffer = cl.Buffer(opencl_context, cl.mem_flags.WRITE_ONLY, image.nbytes)
|
||||||
|
|
||||||
|
plt.style.use('dark_background')
|
||||||
|
# fuck this shit
|
||||||
|
fig = plt.figure(frameon=False)
|
||||||
|
fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi)
|
||||||
|
#fig.set_size_inches(width/height, 1, forward=False)
|
||||||
|
|
||||||
|
|
||||||
|
ax = plt.Axes(fig, [0., 0., 1., 1.])
|
||||||
|
#ax.set_axis_off()
|
||||||
|
fig.add_axes(ax)
|
||||||
|
|
||||||
|
cmap = plt.cm.viridis
|
||||||
|
cmap.set_bad((0,0,0))
|
||||||
|
cmap.set_over((0,0,0))
|
||||||
|
cmap.set_under((0,0,0))
|
||||||
|
|
||||||
|
bruh = None
|
||||||
|
|
||||||
|
def on_click(event):
|
||||||
|
global bruh
|
||||||
|
split_ratio = 1
|
||||||
|
if (event.button is MouseButton.MIDDLE) and (event.inaxes):
|
||||||
|
# there's probably a way to set global coordinates;
|
||||||
|
# I don't expect this to go anywhere so I don't really care
|
||||||
|
on_x = ((event.xdata / img_res_x) * abs(x_max - x_min)) + x_min
|
||||||
|
on_y = ((event.ydata / img_res_y) * abs(y_max - y_min)) + y_min
|
||||||
|
|
||||||
|
#I, uh, also don't know the best way to replicate the openCL code automaticly in python
|
||||||
|
#so ajust if nessesary
|
||||||
|
x_hops = []
|
||||||
|
y_hops = []
|
||||||
|
for i in range(iterations):
|
||||||
|
x_hops.append(((on_x - x_min) / abs(x_max - x_min)) * img_res_x)
|
||||||
|
y_hops.append(((on_y - y_min) / abs(y_max - y_min)) * img_res_y)
|
||||||
|
next_x = on_x/np.tan(on_y)
|
||||||
|
on_y = on_y/np.tan(on_x)
|
||||||
|
on_x = next_x
|
||||||
|
if on_x**2 + on_y**2 > escape:
|
||||||
|
break
|
||||||
|
print(y_hops[0])
|
||||||
|
print(on_y)
|
||||||
|
print("{} hops".format(len(x_hops)))
|
||||||
|
if bruh:
|
||||||
|
bruh.pop(0).remove()
|
||||||
|
bruh = ax.plot(x_hops, y_hops)
|
||||||
|
plt.draw()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
print(on_x, on_y)
|
||||||
|
|
||||||
|
|
||||||
|
print("compiling openCL kernel...")
|
||||||
|
with open(kernel_src_path, 'r') as kernel_src:
|
||||||
|
compiled_kernel = cl.Program(opencl_context, kernel_src.read()).build()
|
||||||
|
|
||||||
|
encoding_progress = alive_bar(frames, bar = 'filling', spinner = 'waves')
|
||||||
|
|
||||||
|
def display_encoder_progress(current_frame: int, total_frames: int):
|
||||||
|
print("Encoding: frame {}/{}".format(current_frame, frames))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
print("Rendering {} frames...".format(frames))
|
||||||
|
if frames > 1:
|
||||||
|
with alive_bar(frames, bar = 'filling', spinner = 'waves') as bar_total:
|
||||||
|
for frame_i in range(0, frames):
|
||||||
|
compiled_kernel.render_frame(opencl_queue, image.shape, None, image_buffer,
|
||||||
|
np.double(abs(x_max - x_min) / img_res_x),
|
||||||
|
np.double(abs(y_max - y_min) / img_res_y),
|
||||||
|
np.double(x_min), np.double(y_min),
|
||||||
|
np.uint32(iterations), np.uint32(escape),
|
||||||
|
np.double(frame_i / frames))
|
||||||
|
|
||||||
|
|
||||||
|
cl.enqueue_copy(opencl_queue, image, image_buffer).wait()
|
||||||
|
rendered_frame = ax.imshow(image, norm="log", aspect="auto", cmap=cmap, animated="True")
|
||||||
|
rendered_frames.append([rendered_frame])
|
||||||
|
bar_total()
|
||||||
|
print("Encoding/Saving...")
|
||||||
|
ani = animation.ArtistAnimation(fig, rendered_frames, interval=30, blit=True)
|
||||||
|
ani.save(animation_progres_save, extra_args=['-preset', 'lossless'], progress_callback=display_encoder_progress, codec="h264_nvenc")
|
||||||
|
else:
|
||||||
|
compiled_kernel.render_frame(opencl_queue, image.shape, None, image_buffer,
|
||||||
|
np.double(abs(x_max - x_min) / img_res_x),
|
||||||
|
np.double(abs(y_max - y_min) / img_res_y),
|
||||||
|
np.double(x_min), np.double(y_min),
|
||||||
|
np.uint32(iterations), np.uint32(escape),
|
||||||
|
np.double(1))
|
||||||
|
cl.enqueue_copy(opencl_queue, image, image_buffer).wait()
|
||||||
|
ax.imshow(image, norm="log", aspect="auto", cmap=cmap)
|
||||||
|
fig.savefig(single_frame_save)
|
||||||
|
plt.autoscale(False)
|
||||||
|
plt.connect('motion_notify_event', on_click)
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
|
26
field_tests/kernel.c
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
__kernel void basic_test() {
|
||||||
|
printf("this cores ID: (%lu, %lu)\n", get_global_id(0), get_global_id(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
__kernel void render_frame(__global unsigned int *frame_output,
|
||||||
|
double x_step, double y_step,
|
||||||
|
double x_start, double y_start,
|
||||||
|
unsigned int iterations, unsigned int escape, double ratio) {
|
||||||
|
unsigned int result;
|
||||||
|
double on_x = (get_global_id(0) * x_step) + x_start;
|
||||||
|
double on_y = (get_global_id(1) * y_step) + y_start;
|
||||||
|
double next_x;
|
||||||
|
unsigned int iter;
|
||||||
|
|
||||||
|
orig_x = on_x;
|
||||||
|
orig_y = on_y;
|
||||||
|
for(iter = 0; iter < iterations; iter++) {
|
||||||
|
if(orig_x == 123 && orig_y == 5) printf("%d, %d\n", orig_x,orig_y);
|
||||||
|
next_x = on_x / sin(on_y);
|
||||||
|
on_y = on_y / sin(on_x);
|
||||||
|
on_x = next_x;
|
||||||
|
if((pow(on_x, 2) + pow(on_y, 2)) >= escape) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
frame_output[(get_global_id(1) * get_global_size(1)) + get_global_id(0)] = iter;
|
||||||
|
}
|
4
field_tests/makefile
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
make:
|
||||||
|
gcc -Wall -fpic -c field.c
|
||||||
|
gcc -Wall -shared -o field.so field.o
|
||||||
|
python3 field.py
|
63
linear_transform_test.py
Executable file
@ -0,0 +1,63 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
from alive_progress import alive_bar
|
||||||
|
|
||||||
|
img_res_x = 500
|
||||||
|
img_res_y = 500
|
||||||
|
total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time
|
||||||
|
|
||||||
|
periods = .25
|
||||||
|
square_x = 1
|
||||||
|
square_y = 1
|
||||||
|
|
||||||
|
xmin = (-periods * np.pi) + (square_x * np.pi)
|
||||||
|
xmax = (periods * np.pi) + (square_x * np.pi)
|
||||||
|
ymin = (-periods * np.pi) + (square_y * np.pi)
|
||||||
|
ymax = (periods * np.pi) + (square_y * np.pi)
|
||||||
|
|
||||||
|
escape = 10000
|
||||||
|
iterations = 255*3
|
||||||
|
c_x = 2 * np.pi
|
||||||
|
c_y = 2 * np.pi
|
||||||
|
|
||||||
|
|
||||||
|
image = np.empty([img_res_y, img_res_x])
|
||||||
|
|
||||||
|
with alive_bar(img_res_y, bar = 'filling', spinner = 'waves') as bar:
|
||||||
|
for pix_y, y in enumerate(np.linspace(ymin, ymax, img_res_y)):
|
||||||
|
for pix_x, x in enumerate(np.linspace(xmin, xmax, img_res_x)):
|
||||||
|
on_x = x
|
||||||
|
on_y = y
|
||||||
|
for i in range(iterations):
|
||||||
|
completed_ratio = ((pix_y * img_res_y) + pix_x) / total_pixels
|
||||||
|
next_x = (completed_ratio * (on_x/np.sin(on_y))) + ((1 - completed_ratio) * on_x/np.tan(on_y))
|
||||||
|
on_y = (completed_ratio * (on_y/np.sin(on_x))) + ((1 - completed_ratio) * on_y/np.tan(on_x))
|
||||||
|
on_x = next_x
|
||||||
|
if on_x**2 + on_y**2 > escape:
|
||||||
|
break
|
||||||
|
print(completed_ratio)
|
||||||
|
image[pix_y][pix_x] = i
|
||||||
|
bar()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
plt.style.use('dark_background')
|
||||||
|
# fuck this shit
|
||||||
|
fig = plt.figure(frameon=False)
|
||||||
|
fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi)
|
||||||
|
#fig.set_size_inches(width/height, 1, forward=False)
|
||||||
|
|
||||||
|
ax = plt.Axes(fig, [0., 0., 1., 1.])
|
||||||
|
ax.set_axis_off()
|
||||||
|
fig.add_axes(ax)
|
||||||
|
|
||||||
|
cmap = plt.cm.viridis
|
||||||
|
cmap.set_bad((0,0,0))
|
||||||
|
cmap.set_over((0,0,0))
|
||||||
|
cmap.set_under((0,0,0))
|
||||||
|
|
||||||
|
ax.imshow(image, norm="log", aspect="auto", cmap=cmap)
|
||||||
|
fig.savefig("linear_transform_sin_tan_arnolds_tongue_hotspot.png")
|
||||||
|
plt.show()
|
BIN
live_play/.gpu_migration.py.swo
Normal file
BIN
live_play/.gpu_migration.py.swp
Normal file
BIN
live_play/.kernel.c.swp
Normal file
154
live_play/gpu_migration.py
Executable file
@ -0,0 +1,154 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import matplotlib.animation as animation
|
||||||
|
import matplotlib.style as mplstyle
|
||||||
|
import pyopencl as cl
|
||||||
|
from alive_progress import alive_bar
|
||||||
|
from matplotlib.backend_bases import MouseButton
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
|
# HELLO READER ------------------------------------------------------------------------
|
||||||
|
# yes, I know this script is horrid, but it's more of a scratchpad to quickly test ideas
|
||||||
|
# and not anything I'm ever going to show anyone else.
|
||||||
|
|
||||||
|
img_res_x = 1000
|
||||||
|
img_res_y = 1000
|
||||||
|
total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time
|
||||||
|
|
||||||
|
periods = 1
|
||||||
|
square_x = 0
|
||||||
|
square_y = -2
|
||||||
|
|
||||||
|
escape = 10000
|
||||||
|
iterations = (255*3)*2
|
||||||
|
c_x = 2 * np.pi
|
||||||
|
c_y = 2 * np.pi
|
||||||
|
|
||||||
|
animation_progres_save = "ani1_less.mp4"
|
||||||
|
single_frame_save = "asdf.png"
|
||||||
|
|
||||||
|
opencl_context = cl.create_some_context(interactive=False)
|
||||||
|
opencl_queue = cl.CommandQueue(opencl_context)
|
||||||
|
|
||||||
|
kernel_src_path = "./kernel.c"
|
||||||
|
|
||||||
|
frames = 1
|
||||||
|
rendered_frames = []
|
||||||
|
|
||||||
|
image = np.empty([img_res_x, img_res_y], np.uint32)
|
||||||
|
|
||||||
|
plt.style.use('dark_background')
|
||||||
|
# fuck this shit
|
||||||
|
fig = plt.figure(frameon=False)
|
||||||
|
fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi)
|
||||||
|
#fig.set_size_inches(width/height, 1, forward=False)
|
||||||
|
|
||||||
|
|
||||||
|
ax = plt.Axes(fig, [0., 0., 1., 1.])
|
||||||
|
|
||||||
|
#ax.invert_yaxis()
|
||||||
|
ax.set_xlim((-periods * np.pi) + (square_x * np.pi), (periods * np.pi) + (square_x * np.pi))
|
||||||
|
ax.set_ylim((-periods * np.pi) + (square_y * np.pi), (periods * np.pi) + (square_y * np.pi))
|
||||||
|
|
||||||
|
#ax.set_axis_off()
|
||||||
|
fig.add_axes(ax)
|
||||||
|
mplstyle.use('fast')
|
||||||
|
|
||||||
|
cmap = plt.cm.viridis
|
||||||
|
cmap.set_bad((0,0,0))
|
||||||
|
cmap.set_over((0,0,0))
|
||||||
|
cmap.set_under((0,0,0))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
print("compiling openCL kernel...")
|
||||||
|
with open(kernel_src_path, 'r') as kernel_src:
|
||||||
|
compiled_kernel = cl.Program(opencl_context, kernel_src.read()).build()
|
||||||
|
|
||||||
|
encoding_progress = alive_bar(frames, bar = 'filling', spinner = 'waves')
|
||||||
|
|
||||||
|
def display_encoder_progress(current_frame: int, total_frames: int):
|
||||||
|
print("Encoding: frame {}/{}".format(current_frame, frames))
|
||||||
|
|
||||||
|
temp_render_hook = False
|
||||||
|
mp_image = None
|
||||||
|
|
||||||
|
def render(axes):
|
||||||
|
global temp_render_hook
|
||||||
|
global mp_image
|
||||||
|
if not temp_render_hook:
|
||||||
|
temp_render_hook = True
|
||||||
|
x_min = axes.get_xlim()[0]
|
||||||
|
x_max = axes.get_xlim()[1]
|
||||||
|
y_min = axes.get_ylim()[1]
|
||||||
|
y_max = axes.get_ylim()[0]
|
||||||
|
print(axes.get_ylim())
|
||||||
|
compiled_kernel.render_frame(opencl_queue, image.shape, None, image_buffer, mask_buffer,
|
||||||
|
np.double(abs(x_max - x_min) / img_res_x),
|
||||||
|
np.double(abs(y_max - y_min) / img_res_y),
|
||||||
|
np.double(x_min), np.double(y_min),
|
||||||
|
np.uint32(iterations), np.uint32(escape),
|
||||||
|
np.double(1))
|
||||||
|
cl.enqueue_copy(opencl_queue, image, image_buffer).wait()
|
||||||
|
print("kernel")
|
||||||
|
if mp_image == None:
|
||||||
|
mp_image = ax.imshow(image, norm="log", aspect="auto", cmap=cmap, interpolation='none', extent=(x_min, x_max, y_min, y_max)) # TODO
|
||||||
|
else:
|
||||||
|
mp_image.set(extent=(x_min, x_max, y_min, y_max))
|
||||||
|
#ax.set_aspect('equal')
|
||||||
|
#mp_image.set_data(image)
|
||||||
|
mp_image.set_array(image)
|
||||||
|
|
||||||
|
|
||||||
|
fig.canvas.draw_idle()
|
||||||
|
fig.canvas.flush_events()
|
||||||
|
temp_render_hook = False
|
||||||
|
|
||||||
|
#plt.ion()
|
||||||
|
|
||||||
|
#open image
|
||||||
|
mask_path = "mask.png"
|
||||||
|
mask = np.asarray(Image.open(mask_path).convert("L").resize((img_res_x, img_res_y)), dtype=np.double)
|
||||||
|
#mask = np.zeros((1000, 1000), dtype=np.double)
|
||||||
|
mask.setflags(write=1)
|
||||||
|
mask /= np.max(mask) # normalize
|
||||||
|
print(mask.shape)
|
||||||
|
print(mask.dtype)
|
||||||
|
print(mask)
|
||||||
|
#ax.imshow(mask, norm="linear")
|
||||||
|
#plt.show()
|
||||||
|
|
||||||
|
image_buffer = cl.Buffer(opencl_context, cl.mem_flags.WRITE_ONLY, image.nbytes)
|
||||||
|
mask_buffer = cl.Buffer(opencl_context, cl.mem_flags.READ_ONLY, mask.nbytes)
|
||||||
|
cl.enqueue_copy(opencl_queue, mask_buffer, mask).wait()
|
||||||
|
#mask_buffer = cl.array.Array(opencl_context,mask.shape, dtype=np.uint8, data=mask)
|
||||||
|
|
||||||
|
#move to render
|
||||||
|
print("Rendering {} frames...".format(frames))
|
||||||
|
if frames > 1:
|
||||||
|
with alive_bar(frames, bar = 'filling', spinner = 'waves') as bar_total:
|
||||||
|
for frame_i in range(0, frames):
|
||||||
|
compiled_kernel.render_frame(opencl_queue, image.shape, None, image_buffer, mask,
|
||||||
|
np.double(abs(x_max - x_min) / img_res_x),
|
||||||
|
np.double(abs(y_max - y_min) / img_res_y),
|
||||||
|
np.double(x_min), np.double(y_min),
|
||||||
|
np.uint32(iterations), np.uint32(escape),
|
||||||
|
np.double(frame_i / frames))
|
||||||
|
|
||||||
|
|
||||||
|
cl.enqueue_copy(opencl_queue, image, image_buffer).wait()
|
||||||
|
rendered_frame = ax.imshow(image, norm="log", aspect="auto", cmap=cmap, animated="True")
|
||||||
|
rendered_frames.append([rendered_frame])
|
||||||
|
bar_total()
|
||||||
|
print("Encoding/Saving...")
|
||||||
|
ani = animation.ArtistAnimation(fig, rendered_frames, interval=30, blit=True)
|
||||||
|
ani.save(animation_progres_save, extra_args=['-preset', 'lossless'], progress_callback=display_encoder_progress, codec="h264_nvenc")
|
||||||
|
else:
|
||||||
|
ax.callbacks.connect('ylim_changed', render)
|
||||||
|
ax.callbacks.connect('xlim_changed', render)
|
||||||
|
render(ax)
|
||||||
|
plt.show(block=True)
|
||||||
|
|
||||||
|
|
40
live_play/kernel.c
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
//#include <math.h>
|
||||||
|
#define PI 3.141592653589793115997963468544185161590576171875
|
||||||
|
|
||||||
|
double cosecant_single(double a, double b) { return a / sin(b); }
|
||||||
|
double secant_single(double a, double b) {
|
||||||
|
//double killme = (double)floor(b / (PI / 2.0)) * (double)(PI / 2.0);
|
||||||
|
//return a / sin(killme);
|
||||||
|
//return a / sin((PI / 2.0));
|
||||||
|
//return a / sin(PI);
|
||||||
|
return a / sin(-PI);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
__kernel void render_frame(__global unsigned int *frame_output, __global double *mask,
|
||||||
|
double x_step, double y_step,
|
||||||
|
double x_start, double y_start,
|
||||||
|
unsigned int iterations, unsigned int escape, double ratio) {
|
||||||
|
unsigned int result;
|
||||||
|
double x = (get_global_id(0) * x_step) + x_start;
|
||||||
|
double y = (get_global_id(1) * y_step) + y_start;
|
||||||
|
size_t img_index = (get_global_id(1) * get_global_size(1)) + get_global_id(0);
|
||||||
|
|
||||||
|
unsigned int iter;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for(iter = 0; iter < iterations; iter++) {
|
||||||
|
double next_x;
|
||||||
|
double r = mask[img_index];
|
||||||
|
next_x = (r * cosecant_single(x, y)) + ((1 - r) * secant_single(x, y));
|
||||||
|
y = (r * cosecant_single(y, x)) + ((1 - r) * secant_single(y, x));
|
||||||
|
x = next_x;
|
||||||
|
if((pow(x, 2) + pow(y, 2)) >= escape) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
frame_output[img_index] = iter;
|
||||||
|
//frame_output[img_index] = mask[img_index] * 255;
|
||||||
|
}
|
1
live_play/mask.png
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../masks/threedots.png
|
79
live_play/notes
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import matplotlib.animation as animation
|
||||||
|
import pyopencl as cl
|
||||||
|
from alive_progress import alive_bar
|
||||||
|
|
||||||
|
img_res_x = 2000
|
||||||
|
img_res_y = 2000
|
||||||
|
total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time
|
||||||
|
|
||||||
|
periods = 1
|
||||||
|
square_x = 0
|
||||||
|
square_y = 0
|
||||||
|
|
||||||
|
xmin = (-periods * np.pi) + (square_x * np.pi)
|
||||||
|
xmax = (periods * np.pi) + (square_x * np.pi)
|
||||||
|
ymin = (-periods * np.pi) + (square_y * np.pi)
|
||||||
|
ymax = (periods * np.pi) + (square_y * np.pi)
|
||||||
|
|
||||||
|
escape = 10000
|
||||||
|
iterations = 255*3
|
||||||
|
c_x = 2 * np.pi
|
||||||
|
c_y = 2 * np.pi
|
||||||
|
|
||||||
|
animation_progres_save = "./animations"
|
||||||
|
frames = 120
|
||||||
|
|
||||||
|
rendered_frames = []
|
||||||
|
|
||||||
|
|
||||||
|
plt.style.use('dark_background')
|
||||||
|
# fuck this shit
|
||||||
|
fig = plt.figure(frameon=False)
|
||||||
|
fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi)
|
||||||
|
#fig.set_size_inches(width/height, 1, forward=False)
|
||||||
|
|
||||||
|
ax = plt.Axes(fig, [0., 0., 1., 1.])
|
||||||
|
ax.set_axis_off()
|
||||||
|
fig.add_axes(ax)
|
||||||
|
|
||||||
|
cmap = plt.cm.viridis
|
||||||
|
cmap.set_bad((0,0,0))
|
||||||
|
cmap.set_over((0,0,0))
|
||||||
|
cmap.set_under((0,0,0))
|
||||||
|
|
||||||
|
opencl_context = cl.create_some_context()
|
||||||
|
opencl_queue = cl.CommandQueue(opencl_context)
|
||||||
|
|
||||||
|
|
||||||
|
#def render():
|
||||||
|
# image = np.empty([img_res_y, img_res_x])
|
||||||
|
# print("Rendering frames")
|
||||||
|
# with alive_bar(frames, bar = 'filling', spinner = 'waves') as bar_total:
|
||||||
|
# for frame in range(frames):
|
||||||
|
# split_ratio = frame / frames
|
||||||
|
# for pix_y, y in enumerate(np.linspace(ymin, ymax, img_res_y)):
|
||||||
|
# for pix_x, x in enumerate(np.linspace(xmin, xmax, img_res_x)):
|
||||||
|
# on_x = x
|
||||||
|
# on_y = y
|
||||||
|
# for i in range(iterations):
|
||||||
|
# next_x = (split_ratio * (on_x/np.sin(on_y))) + ((1 - split_ratio) * on_x/np.tan(on_y))
|
||||||
|
# on_y = (split_ratio * (on_y/np.sin(on_x))) + ((1 - split_ratio) * on_y/np.tan(on_x))
|
||||||
|
# on_x = next_x
|
||||||
|
# if on_x**2 + on_y**2 > escape:
|
||||||
|
# break
|
||||||
|
# image[pix_y][pix_x] = i
|
||||||
|
# rendered_frame = ax.imshow(image, norm="log", aspect="auto", cmap=cmap, animated=False)
|
||||||
|
# rendered_frames.append([rendered_frame])
|
||||||
|
# bar_total()
|
||||||
|
|
||||||
|
def display():
|
||||||
|
print(rendered_frames)
|
||||||
|
ani = animation.ArtistAnimation(fig, rendered_frames, interval=30, blit=True)
|
||||||
|
ani.save("test.mp4")
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
render()
|
||||||
|
display()
|
30
mask_tests/;
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
unsigned int secant_fractal(double x, double y, unsigned int escape, unsigned int iterations) {
|
||||||
|
for(unsigned int iter = 0; iter < iterations; iter++) {
|
||||||
|
double next_x;
|
||||||
|
next_x = x / cos(y);
|
||||||
|
y = y / cos(x);
|
||||||
|
x = next_x;
|
||||||
|
if((pow(x, 2) + pow(y, 2)) >= escape) return iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unsigned int cosecant_fractal(double x, double y, unsigned int escape, unsigned int iterations) {
|
||||||
|
for(unsigned int iter = 0; iter < iterations; iter++) {
|
||||||
|
double next_x;
|
||||||
|
next_x = x / sin(y);
|
||||||
|
y = y / sin(x);
|
||||||
|
x = next_x;
|
||||||
|
if((pow(x, 2) + pow(y, 2)) >= escape) return iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__kernel void render_frame(__global unsigned int *frame_output, //uint8_t *mask, //more bit depth is possible
|
||||||
|
double x_step, double y_step,
|
||||||
|
double x_start, double y_start,
|
||||||
|
unsigned int iterations, unsigned int escape, double ratio) {
|
||||||
|
unsigned int result;
|
||||||
|
double on_x = (get_global_id(0) * x_step) + x_start;
|
||||||
|
double on_y = (get_global_id(1) * y_step) + y_start;
|
||||||
|
|
||||||
|
frame_output[(get_global_id(1) * get_global_size(1)) + get_global_id(0)] =
|
||||||
|
secant_fractal(on_x, on_y, escape, iterations);
|
||||||
|
}
|
BIN
mask_tests/asdf.png
Normal file
After Width: | Height: | Size: 1.0 MiB |
49
mask_tests/kernel.c
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
unsigned int secant_fractal(double x, double y, unsigned int escape, unsigned int iterations) {
|
||||||
|
for(unsigned int iter = 0; iter < iterations; iter++) {
|
||||||
|
double next_x;
|
||||||
|
next_x = x / cos(y);
|
||||||
|
y = y / cos(x);
|
||||||
|
x = next_x;
|
||||||
|
if((pow(x, 2) + pow(y, 2)) >= escape) return iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unsigned int cosecant_fractal(double x, double y, unsigned int escape, unsigned int iterations) {
|
||||||
|
for(unsigned int iter = 0; iter < iterations; iter++) {
|
||||||
|
double next_x;
|
||||||
|
next_x = x / sin(y);
|
||||||
|
y = y / sin(x);
|
||||||
|
x = next_x;
|
||||||
|
if((pow(x, 2) + pow(y, 2)) >= escape) return iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double cosecant_single(double a, double b) { return a / sin(b); }
|
||||||
|
double secant_single(double a, double b) { return a / tan(b); }
|
||||||
|
|
||||||
|
|
||||||
|
__kernel void render_frame(__global unsigned int *frame_output, __global double *mask,
|
||||||
|
double x_step, double y_step,
|
||||||
|
double x_start, double y_start,
|
||||||
|
unsigned int iterations, unsigned int escape, double ratio) {
|
||||||
|
unsigned int result;
|
||||||
|
double x = (get_global_id(0) * x_step) + x_start;
|
||||||
|
double y = (get_global_id(1) * y_step) + y_start;
|
||||||
|
size_t img_index = (get_global_id(1) * get_global_size(1)) + get_global_id(0);
|
||||||
|
|
||||||
|
unsigned int iter;
|
||||||
|
|
||||||
|
|
||||||
|
for(iter = 0; iter < iterations; iter++) {
|
||||||
|
double next_x;
|
||||||
|
double r = mask[img_index];
|
||||||
|
next_x = (r * cosecant_single(x, y)) + ((1 - r) * secant_single(x, y));
|
||||||
|
y = (r * cosecant_single(y, x)) + ((1 - r) * secant_single(y, x));
|
||||||
|
x = next_x;
|
||||||
|
if((pow(x, 2) + pow(y, 2)) >= escape) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
frame_output[img_index] = iter;
|
||||||
|
//frame_output[img_index] = mask[img_index] * 255;
|
||||||
|
}
|
1
mask_tests/mask.png
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../masks/threedots.png
|
153
mask_tests/mask.py
Executable file
@ -0,0 +1,153 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import matplotlib.animation as animation
|
||||||
|
import pyopencl as cl
|
||||||
|
from alive_progress import alive_bar
|
||||||
|
from matplotlib.backend_bases import MouseButton
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
|
img_res_x = 1000
|
||||||
|
img_res_y = 1000
|
||||||
|
total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time
|
||||||
|
|
||||||
|
periods = 1
|
||||||
|
square_x = 0
|
||||||
|
square_y = 0
|
||||||
|
|
||||||
|
x_min = (-periods * np.pi) + (square_x * np.pi)
|
||||||
|
x_max = (periods * np.pi) + (square_x * np.pi)
|
||||||
|
y_min = (-periods * np.pi) + (square_y * np.pi)
|
||||||
|
y_max = (periods * np.pi) + (square_y * np.pi)
|
||||||
|
|
||||||
|
escape = 10000
|
||||||
|
iterations = 255*3
|
||||||
|
c_x = 2 * np.pi
|
||||||
|
c_y = 2 * np.pi
|
||||||
|
|
||||||
|
animation_progres_save = "ani1_less.mp4"
|
||||||
|
single_frame_save = "asdf.png"
|
||||||
|
|
||||||
|
opencl_context = cl.create_some_context(interactive=False)
|
||||||
|
opencl_queue = cl.CommandQueue(opencl_context)
|
||||||
|
|
||||||
|
kernel_src_path = "./kernel.c"
|
||||||
|
|
||||||
|
frames = 1
|
||||||
|
rendered_frames = []
|
||||||
|
|
||||||
|
image = np.empty([img_res_x, img_res_y], np.uint32)
|
||||||
|
|
||||||
|
plt.style.use('dark_background')
|
||||||
|
# fuck this shit
|
||||||
|
fig = plt.figure(frameon=False)
|
||||||
|
fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi)
|
||||||
|
#fig.set_size_inches(width/height, 1, forward=False)
|
||||||
|
|
||||||
|
|
||||||
|
ax = plt.Axes(fig, [0., 0., 1., 1.])
|
||||||
|
#ax.set_axis_off()
|
||||||
|
fig.add_axes(ax)
|
||||||
|
|
||||||
|
cmap = plt.cm.viridis
|
||||||
|
cmap.set_bad((0,0,0))
|
||||||
|
cmap.set_over((0,0,0))
|
||||||
|
cmap.set_under((0,0,0))
|
||||||
|
|
||||||
|
mask_path = "mask.png"
|
||||||
|
|
||||||
|
bruh = None
|
||||||
|
|
||||||
|
def on_click(event):
|
||||||
|
global bruh
|
||||||
|
split_ratio = 1
|
||||||
|
if (event.button is MouseButton.MIDDLE) and (event.inaxes):
|
||||||
|
# there's probably a way to set global coordinates;
|
||||||
|
# I don't expect this to go anywhere so I don't really care
|
||||||
|
on_x = ((event.xdata / img_res_x) * abs(x_max - x_min)) + x_min
|
||||||
|
on_y = ((event.ydata / img_res_y) * abs(y_max - y_min)) + y_min
|
||||||
|
|
||||||
|
#I, uh, also don't know the best way to replicate the openCL code automaticly in python
|
||||||
|
#so ajust if nessesary
|
||||||
|
x_hops = []
|
||||||
|
y_hops = []
|
||||||
|
for i in range(iterations):
|
||||||
|
x_hops.append(((on_x - x_min) / abs(x_max - x_min)) * img_res_x)
|
||||||
|
y_hops.append(((on_y - y_min) / abs(y_max - y_min)) * img_res_y)
|
||||||
|
next_x = on_x/np.tan(on_y)
|
||||||
|
on_y = on_y/np.tan(on_x)
|
||||||
|
on_x = next_x
|
||||||
|
if on_x**2 + on_y**2 > escape:
|
||||||
|
break
|
||||||
|
print(y_hops[0])
|
||||||
|
print(on_y)
|
||||||
|
print("{} hops".format(len(x_hops)))
|
||||||
|
if bruh:
|
||||||
|
bruh.pop(0).remove()
|
||||||
|
bruh = ax.plot(x_hops, y_hops)
|
||||||
|
plt.draw()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
print(on_x, on_y)
|
||||||
|
|
||||||
|
|
||||||
|
print("compiling openCL kernel...")
|
||||||
|
with open(kernel_src_path, 'r') as kernel_src:
|
||||||
|
compiled_kernel = cl.Program(opencl_context, kernel_src.read()).build()
|
||||||
|
|
||||||
|
encoding_progress = alive_bar(frames, bar = 'filling', spinner = 'waves')
|
||||||
|
|
||||||
|
def display_encoder_progress(current_frame: int, total_frames: int):
|
||||||
|
print("Encoding: frame {}/{}".format(current_frame, frames))
|
||||||
|
|
||||||
|
#open image
|
||||||
|
mask = np.asarray(Image.open(mask_path).convert("L"), dtype=np.double)
|
||||||
|
mask.setflags(write=1)
|
||||||
|
mask /= np.max(mask) # normalize
|
||||||
|
print(mask.shape)
|
||||||
|
print(mask.dtype)
|
||||||
|
#ax.imshow(mask, norm="linear")
|
||||||
|
#plt.show()
|
||||||
|
|
||||||
|
image_buffer = cl.Buffer(opencl_context, cl.mem_flags.WRITE_ONLY, image.nbytes)
|
||||||
|
mask_buffer = cl.Buffer(opencl_context, cl.mem_flags.READ_ONLY, mask.nbytes)
|
||||||
|
cl.enqueue_copy(opencl_queue, mask_buffer, mask).wait()
|
||||||
|
#mask_buffer = cl.array.Array(opencl_context,mask.shape, dtype=np.uint8, data=mask)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# TODO clean this up
|
||||||
|
print("Rendering {} frames...".format(frames))
|
||||||
|
if frames > 1:
|
||||||
|
with alive_bar(frames, bar = 'filling', spinner = 'waves') as bar_total:
|
||||||
|
for frame_i in range(0, frames):
|
||||||
|
compiled_kernel.render_frame(opencl_queue, image.shape, None, image_buffer,
|
||||||
|
np.double(abs(x_max - x_min) / img_res_x),
|
||||||
|
np.double(abs(y_max - y_min) / img_res_y),
|
||||||
|
np.double(x_min), np.double(y_min),
|
||||||
|
np.uint32(iterations), np.uint32(escape),
|
||||||
|
np.double(frame_i / frames))
|
||||||
|
|
||||||
|
|
||||||
|
cl.enqueue_copy(opencl_queue, image, image_buffer).wait()
|
||||||
|
rendered_frame = ax.imshow(image, norm="log", aspect="auto", cmap=cmap, animated="True")
|
||||||
|
rendered_frames.append([rendered_frame])
|
||||||
|
bar_total()
|
||||||
|
print("Encoding/Saving...")
|
||||||
|
ani = animation.ArtistAnimation(fig, rendered_frames, interval=30, blit=True)
|
||||||
|
ani.save(animation_progres_save, extra_args=['-preset', 'lossless'], progress_callback=display_encoder_progress, codec="h264_nvenc")
|
||||||
|
else:
|
||||||
|
compiled_kernel.render_frame(opencl_queue, image.shape, None, image_buffer, mask_buffer,
|
||||||
|
np.double(abs(x_max - x_min) / img_res_x),
|
||||||
|
np.double(abs(y_max - y_min) / img_res_y),
|
||||||
|
np.double(x_min), np.double(y_min),
|
||||||
|
np.uint32(iterations), np.uint32(escape),
|
||||||
|
np.double(1))
|
||||||
|
cl.enqueue_copy(opencl_queue, image, image_buffer).wait()
|
||||||
|
ax.imshow(image, norm="log", aspect="auto", cmap=cmap)
|
||||||
|
fig.savefig(single_frame_save)
|
||||||
|
plt.autoscale(False)
|
||||||
|
plt.connect('motion_notify_event', on_click)
|
||||||
|
plt.show()
|
142
mask_tests/mask.py.bak
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import matplotlib.animation as animation
|
||||||
|
import pyopencl as cl
|
||||||
|
from alive_progress import alive_bar
|
||||||
|
from matplotlib.backend_bases import MouseButton
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
|
img_res_x = 1000
|
||||||
|
img_res_y = 1000
|
||||||
|
total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time
|
||||||
|
|
||||||
|
periods = 1
|
||||||
|
square_x = 0
|
||||||
|
square_y = 0
|
||||||
|
|
||||||
|
x_min = (-periods * np.pi) + (square_x * np.pi)
|
||||||
|
x_max = (periods * np.pi) + (square_x * np.pi)
|
||||||
|
y_min = (-periods * np.pi) + (square_y * np.pi)
|
||||||
|
y_max = (periods * np.pi) + (square_y * np.pi)
|
||||||
|
|
||||||
|
escape = 10000
|
||||||
|
iterations = 255*3
|
||||||
|
c_x = 2 * np.pi
|
||||||
|
c_y = 2 * np.pi
|
||||||
|
|
||||||
|
animation_progres_save = "ani1_less.mp4"
|
||||||
|
single_frame_save = "asdf.png"
|
||||||
|
|
||||||
|
opencl_context = cl.create_some_context(interactive=False)
|
||||||
|
opencl_queue = cl.CommandQueue(opencl_context)
|
||||||
|
|
||||||
|
kernel_src_path = "./kernel.c"
|
||||||
|
|
||||||
|
frames = 1
|
||||||
|
rendered_frames = []
|
||||||
|
|
||||||
|
image = np.empty([img_res_x, img_res_y], np.uint32)
|
||||||
|
image_buffer = cl.Buffer(opencl_context, cl.mem_flags.WRITE_ONLY, image.nbytes)
|
||||||
|
|
||||||
|
plt.style.use('dark_background')
|
||||||
|
# fuck this shit
|
||||||
|
fig = plt.figure(frameon=False)
|
||||||
|
fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi)
|
||||||
|
#fig.set_size_inches(width/height, 1, forward=False)
|
||||||
|
|
||||||
|
|
||||||
|
ax = plt.Axes(fig, [0., 0., 1., 1.])
|
||||||
|
#ax.set_axis_off()
|
||||||
|
fig.add_axes(ax)
|
||||||
|
|
||||||
|
cmap = plt.cm.viridis
|
||||||
|
cmap.set_bad((0,0,0))
|
||||||
|
cmap.set_over((0,0,0))
|
||||||
|
cmap.set_under((0,0,0))
|
||||||
|
|
||||||
|
mask_path = "mask.png"
|
||||||
|
|
||||||
|
bruh = None
|
||||||
|
|
||||||
|
def on_click(event):
|
||||||
|
global bruh
|
||||||
|
split_ratio = 1
|
||||||
|
if (event.button is MouseButton.MIDDLE) and (event.inaxes):
|
||||||
|
# there's probably a way to set global coordinates;
|
||||||
|
# I don't expect this to go anywhere so I don't really care
|
||||||
|
on_x = ((event.xdata / img_res_x) * abs(x_max - x_min)) + x_min
|
||||||
|
on_y = ((event.ydata / img_res_y) * abs(y_max - y_min)) + y_min
|
||||||
|
|
||||||
|
#I, uh, also don't know the best way to replicate the openCL code automaticly in python
|
||||||
|
#so ajust if nessesary
|
||||||
|
x_hops = []
|
||||||
|
y_hops = []
|
||||||
|
for i in range(iterations):
|
||||||
|
x_hops.append(((on_x - x_min) / abs(x_max - x_min)) * img_res_x)
|
||||||
|
y_hops.append(((on_y - y_min) / abs(y_max - y_min)) * img_res_y)
|
||||||
|
next_x = on_x/np.tan(on_y)
|
||||||
|
on_y = on_y/np.tan(on_x)
|
||||||
|
on_x = next_x
|
||||||
|
if on_x**2 + on_y**2 > escape:
|
||||||
|
break
|
||||||
|
print(y_hops[0])
|
||||||
|
print(on_y)
|
||||||
|
print("{} hops".format(len(x_hops)))
|
||||||
|
if bruh:
|
||||||
|
bruh.pop(0).remove()
|
||||||
|
bruh = ax.plot(x_hops, y_hops)
|
||||||
|
plt.draw()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
print(on_x, on_y)
|
||||||
|
|
||||||
|
|
||||||
|
print("compiling openCL kernel...")
|
||||||
|
with open(kernel_src_path, 'r') as kernel_src:
|
||||||
|
compiled_kernel = cl.Program(opencl_context, kernel_src.read()).build()
|
||||||
|
|
||||||
|
encoding_progress = alive_bar(frames, bar = 'filling', spinner = 'waves')
|
||||||
|
|
||||||
|
def display_encoder_progress(current_frame: int, total_frames: int):
|
||||||
|
print("Encoding: frame {}/{}".format(current_frame, frames))
|
||||||
|
|
||||||
|
with open G
|
||||||
|
|
||||||
|
|
||||||
|
# TODO clean this up
|
||||||
|
print("Rendering {} frames...".format(frames))
|
||||||
|
if frames > 1:
|
||||||
|
with alive_bar(frames, bar = 'filling', spinner = 'waves') as bar_total:
|
||||||
|
for frame_i in range(0, frames):
|
||||||
|
compiled_kernel.render_frame(opencl_queue, image.shape, None, image_buffer,
|
||||||
|
np.double(abs(x_max - x_min) / img_res_x),
|
||||||
|
np.double(abs(y_max - y_min) / img_res_y),
|
||||||
|
np.double(x_min), np.double(y_min),
|
||||||
|
np.uint32(iterations), np.uint32(escape),
|
||||||
|
np.double(frame_i / frames))
|
||||||
|
|
||||||
|
|
||||||
|
cl.enqueue_copy(opencl_queue, image, image_buffer).wait()
|
||||||
|
rendered_frame = ax.imshow(image, norm="log", aspect="auto", cmap=cmap, animated="True")
|
||||||
|
rendered_frames.append([rendered_frame])
|
||||||
|
bar_total()
|
||||||
|
print("Encoding/Saving...")
|
||||||
|
ani = animation.ArtistAnimation(fig, rendered_frames, interval=30, blit=True)
|
||||||
|
ani.save(animation_progres_save, extra_args=['-preset', 'lossless'], progress_callback=display_encoder_progress, codec="h264_nvenc")
|
||||||
|
else:
|
||||||
|
compiled_kernel.render_frame(opencl_queue, image.shape, None, image_buffer,
|
||||||
|
np.double(abs(x_max - x_min) / img_res_x),
|
||||||
|
np.double(abs(y_max - y_min) / img_res_y),
|
||||||
|
np.double(x_min), np.double(y_min),
|
||||||
|
np.uint32(iterations), np.uint32(escape),
|
||||||
|
np.double(1))
|
||||||
|
cl.enqueue_copy(opencl_queue, image, image_buffer).wait()
|
||||||
|
ax.imshow(image, norm="log", aspect="auto", cmap=cmap)
|
||||||
|
fig.savefig(single_frame_save)
|
||||||
|
plt.autoscale(False)
|
||||||
|
plt.connect('motion_notify_event', on_click)
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
|
79
mask_tests/notes
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import matplotlib.animation as animation
|
||||||
|
import pyopencl as cl
|
||||||
|
from alive_progress import alive_bar
|
||||||
|
|
||||||
|
img_res_x = 2000
|
||||||
|
img_res_y = 2000
|
||||||
|
total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time
|
||||||
|
|
||||||
|
periods = 1
|
||||||
|
square_x = 0
|
||||||
|
square_y = 0
|
||||||
|
|
||||||
|
xmin = (-periods * np.pi) + (square_x * np.pi)
|
||||||
|
xmax = (periods * np.pi) + (square_x * np.pi)
|
||||||
|
ymin = (-periods * np.pi) + (square_y * np.pi)
|
||||||
|
ymax = (periods * np.pi) + (square_y * np.pi)
|
||||||
|
|
||||||
|
escape = 10000
|
||||||
|
iterations = 255*3
|
||||||
|
c_x = 2 * np.pi
|
||||||
|
c_y = 2 * np.pi
|
||||||
|
|
||||||
|
animation_progres_save = "./animations"
|
||||||
|
frames = 120
|
||||||
|
|
||||||
|
rendered_frames = []
|
||||||
|
|
||||||
|
|
||||||
|
plt.style.use('dark_background')
|
||||||
|
# fuck this shit
|
||||||
|
fig = plt.figure(frameon=False)
|
||||||
|
fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi)
|
||||||
|
#fig.set_size_inches(width/height, 1, forward=False)
|
||||||
|
|
||||||
|
ax = plt.Axes(fig, [0., 0., 1., 1.])
|
||||||
|
ax.set_axis_off()
|
||||||
|
fig.add_axes(ax)
|
||||||
|
|
||||||
|
cmap = plt.cm.viridis
|
||||||
|
cmap.set_bad((0,0,0))
|
||||||
|
cmap.set_over((0,0,0))
|
||||||
|
cmap.set_under((0,0,0))
|
||||||
|
|
||||||
|
opencl_context = cl.create_some_context()
|
||||||
|
opencl_queue = cl.CommandQueue(opencl_context)
|
||||||
|
|
||||||
|
|
||||||
|
#def render():
|
||||||
|
# image = np.empty([img_res_y, img_res_x])
|
||||||
|
# print("Rendering frames")
|
||||||
|
# with alive_bar(frames, bar = 'filling', spinner = 'waves') as bar_total:
|
||||||
|
# for frame in range(frames):
|
||||||
|
# split_ratio = frame / frames
|
||||||
|
# for pix_y, y in enumerate(np.linspace(ymin, ymax, img_res_y)):
|
||||||
|
# for pix_x, x in enumerate(np.linspace(xmin, xmax, img_res_x)):
|
||||||
|
# on_x = x
|
||||||
|
# on_y = y
|
||||||
|
# for i in range(iterations):
|
||||||
|
# next_x = (split_ratio * (on_x/np.sin(on_y))) + ((1 - split_ratio) * on_x/np.tan(on_y))
|
||||||
|
# on_y = (split_ratio * (on_y/np.sin(on_x))) + ((1 - split_ratio) * on_y/np.tan(on_x))
|
||||||
|
# on_x = next_x
|
||||||
|
# if on_x**2 + on_y**2 > escape:
|
||||||
|
# break
|
||||||
|
# image[pix_y][pix_x] = i
|
||||||
|
# rendered_frame = ax.imshow(image, norm="log", aspect="auto", cmap=cmap, animated=False)
|
||||||
|
# rendered_frames.append([rendered_frame])
|
||||||
|
# bar_total()
|
||||||
|
|
||||||
|
def display():
|
||||||
|
print(rendered_frames)
|
||||||
|
ani = animation.ArtistAnimation(fig, rendered_frames, interval=30, blit=True)
|
||||||
|
ani.save("test.mp4")
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
render()
|
||||||
|
display()
|
BIN
masks/clouds.png
Normal file
After Width: | Height: | Size: 103 KiB |
BIN
masks/hi.png
Normal file
After Width: | Height: | Size: 75 KiB |
BIN
masks/test_circle.png
Normal file
After Width: | Height: | Size: 394 KiB |
BIN
masks/test_circle_linear_smooth.png
Normal file
After Width: | Height: | Size: 433 KiB |
BIN
masks/test_circle_perceptual_smooth.png
Normal file
After Width: | Height: | Size: 451 KiB |
BIN
masks/test_diagnol.png
Normal file
After Width: | Height: | Size: 326 KiB |
BIN
masks/test_diagnol_linear_smooth.png
Normal file
After Width: | Height: | Size: 573 KiB |
BIN
masks/test_diagnol_perceptual_smooth.png
Normal file
After Width: | Height: | Size: 568 KiB |
BIN
masks/threedots.png
Normal file
After Width: | Height: | Size: 178 KiB |
BIN
photos_incorrectly_named/cosine_gpu_double_2.png
Normal file
After Width: | Height: | Size: 3.8 MiB |
BIN
photos_incorrectly_named/cpu.png
Normal file
After Width: | Height: | Size: 3.8 MiB |
BIN
photos_incorrectly_named/ice_period_16.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
photos_incorrectly_named/ice_period_16_shifted_.25.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
photos_incorrectly_named/ice_period_16_shifted_.5.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
photos_incorrectly_named/ice_period_noshift_x_1.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
After Width: | Height: | Size: 281 KiB |
BIN
polar/.gpu_migration.py.swo
Normal file
BIN
polar/.gpu_migration.py.swp
Normal file
BIN
polar/.kernel.c.swp
Normal file
157
polar/gpu_migration.py
Executable file
@ -0,0 +1,157 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import matplotlib.animation as animation
|
||||||
|
import matplotlib.style as mplstyle
|
||||||
|
import pyopencl as cl
|
||||||
|
from alive_progress import alive_bar
|
||||||
|
from matplotlib.backend_bases import MouseButton
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
|
# HELLO READER ------------------------------------------------------------------------
|
||||||
|
# yes, I know this script is horrid, but it's more of a scratchpad to quickly test ideas
|
||||||
|
# and not anything I'm ever going to show anyone else.
|
||||||
|
|
||||||
|
img_res_x = 10000
|
||||||
|
img_res_y = 10000
|
||||||
|
total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time
|
||||||
|
|
||||||
|
periods = 1
|
||||||
|
square_x = 0
|
||||||
|
square_y = -2
|
||||||
|
|
||||||
|
escape = 10000
|
||||||
|
iterations = (255*3)
|
||||||
|
c_x = 2 * np.pi
|
||||||
|
c_y = 2 * np.pi
|
||||||
|
|
||||||
|
animation_progres_save = "ani1_less.mp4"
|
||||||
|
single_frame_save = "asdf.png"
|
||||||
|
|
||||||
|
opencl_context = cl.create_some_context(interactive=False)
|
||||||
|
opencl_queue = cl.CommandQueue(opencl_context)
|
||||||
|
|
||||||
|
kernel_src_path = "./kernel.c"
|
||||||
|
|
||||||
|
frames = 1
|
||||||
|
rendered_frames = []
|
||||||
|
|
||||||
|
image = np.empty([img_res_x, img_res_y], np.uint32)
|
||||||
|
|
||||||
|
plt.style.use('dark_background')
|
||||||
|
# fuck this shit
|
||||||
|
fig = plt.figure(frameon=False)
|
||||||
|
fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi)
|
||||||
|
#fig.set_size_inches(width/height, 1, forward=False)
|
||||||
|
|
||||||
|
|
||||||
|
ax = plt.Axes(fig, [0., 0., 1., 1.])
|
||||||
|
|
||||||
|
#ax.invert_yaxis()
|
||||||
|
#ax.set_xlim((-periods * np.pi) + (square_x * np.pi), (periods * np.pi) + (square_x * np.pi))
|
||||||
|
#ax.set_ylim((-periods * np.pi) + (square_y * np.pi), (periods * np.pi) + (square_y * np.pi))
|
||||||
|
ax.set_xlim(-6.678564587410841, -4.837591292407222)
|
||||||
|
ax.set_ylim(-1.0818908008385455, 0.9287284974589227)
|
||||||
|
|
||||||
|
#ax.set_axis_off()
|
||||||
|
fig.add_axes(ax)
|
||||||
|
mplstyle.use('fast')
|
||||||
|
|
||||||
|
cmap = plt.cm.viridis
|
||||||
|
cmap.set_bad((0,0,0))
|
||||||
|
cmap.set_over((0,0,0))
|
||||||
|
cmap.set_under((0,0,0))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
print("compiling openCL kernel...")
|
||||||
|
with open(kernel_src_path, 'r') as kernel_src:
|
||||||
|
compiled_kernel = cl.Program(opencl_context, kernel_src.read()).build()
|
||||||
|
|
||||||
|
encoding_progress = alive_bar(frames, bar = 'filling', spinner = 'waves')
|
||||||
|
|
||||||
|
def display_encoder_progress(current_frame: int, total_frames: int):
|
||||||
|
print("Encoding: frame {}/{}".format(current_frame, frames))
|
||||||
|
|
||||||
|
temp_render_hook = False
|
||||||
|
mp_image = None
|
||||||
|
|
||||||
|
def render(axes):
|
||||||
|
global temp_render_hook
|
||||||
|
global mp_image
|
||||||
|
if not temp_render_hook:
|
||||||
|
temp_render_hook = True
|
||||||
|
x_min = axes.get_xlim()[0]
|
||||||
|
x_max = axes.get_xlim()[1]
|
||||||
|
y_min = axes.get_ylim()[1]
|
||||||
|
y_max = axes.get_ylim()[0]
|
||||||
|
print(axes.get_ylim())
|
||||||
|
compiled_kernel.render_frame(opencl_queue, image.shape, None, image_buffer, mask_buffer,
|
||||||
|
np.double(abs(x_max - x_min) / img_res_x),
|
||||||
|
np.double(abs(y_max - y_min) / img_res_y),
|
||||||
|
np.double(x_min), np.double(y_min),
|
||||||
|
np.uint32(iterations), np.uint32(escape),
|
||||||
|
np.double(1))
|
||||||
|
cl.enqueue_copy(opencl_queue, image, image_buffer).wait()
|
||||||
|
print("kernel")
|
||||||
|
if mp_image == None:
|
||||||
|
mp_image = ax.imshow(image, norm="log", aspect="auto", cmap=cmap, interpolation='none', extent=(x_min, x_max, y_min, y_max)) # TODO
|
||||||
|
else:
|
||||||
|
mp_image.set(extent=(x_min, x_max, y_min, y_max))
|
||||||
|
#ax.set_aspect('equal')
|
||||||
|
#mp_image.set_data(image)
|
||||||
|
mp_image.set_array(image)
|
||||||
|
|
||||||
|
|
||||||
|
fig.canvas.draw_idle()
|
||||||
|
fig.canvas.flush_events()
|
||||||
|
temp_render_hook = False
|
||||||
|
|
||||||
|
#plt.ion()
|
||||||
|
|
||||||
|
#open image
|
||||||
|
mask_path = "mask.png"
|
||||||
|
mask = np.asarray(Image.open(mask_path).convert("L").resize((img_res_x, img_res_y)), dtype=np.double)
|
||||||
|
#mask = np.zeros((img_res_x, img_res_y), dtype=np.double)
|
||||||
|
mask.setflags(write=1)
|
||||||
|
mask /= np.max(mask) # normalize
|
||||||
|
print(mask.shape)
|
||||||
|
print(mask.dtype)
|
||||||
|
print(mask)
|
||||||
|
#ax.imshow(mask, norm="linear")
|
||||||
|
#plt.show()
|
||||||
|
|
||||||
|
image_buffer = cl.Buffer(opencl_context, cl.mem_flags.WRITE_ONLY, image.nbytes)
|
||||||
|
mask_buffer = cl.Buffer(opencl_context, cl.mem_flags.READ_ONLY, mask.nbytes)
|
||||||
|
cl.enqueue_copy(opencl_queue, mask_buffer, mask).wait()
|
||||||
|
#mask_buffer = cl.array.Array(opencl_context,mask.shape, dtype=np.uint8, data=mask)
|
||||||
|
|
||||||
|
#move to render
|
||||||
|
print("Rendering {} frames...".format(frames))
|
||||||
|
if frames > 1:
|
||||||
|
with alive_bar(frames, bar = 'filling', spinner = 'waves') as bar_total:
|
||||||
|
for frame_i in range(0, frames):
|
||||||
|
compiled_kernel.render_frame(opencl_queue, image.shape, None, image_buffer, mask,
|
||||||
|
np.double(abs(x_max - x_min) / img_res_x),
|
||||||
|
np.double(abs(y_max - y_min) / img_res_y),
|
||||||
|
np.double(x_min), np.double(y_min),
|
||||||
|
np.uint32(iterations), np.uint32(escape),
|
||||||
|
np.double(frame_i / frames))
|
||||||
|
|
||||||
|
|
||||||
|
cl.enqueue_copy(opencl_queue, image, image_buffer).wait()
|
||||||
|
rendered_frame = ax.imshow(image, norm="linear", aspect="auto", cmap=cmap, animated="True")
|
||||||
|
rendered_frames.append([rendered_frame])
|
||||||
|
bar_total()
|
||||||
|
print("Encoding/Saving...")
|
||||||
|
ani = animation.ArtistAnimation(fig, rendered_frames, interval=30, blit=True)
|
||||||
|
ani.save(animation_progres_save, extra_args=['-preset', 'lossless'], progress_callback=display_encoder_progress, codec="h264_nvenc")
|
||||||
|
else:
|
||||||
|
ax.callbacks.connect('ylim_changed', render)
|
||||||
|
ax.callbacks.connect('xlim_changed', render)
|
||||||
|
render(ax)
|
||||||
|
plt.savefig("out.png")
|
||||||
|
#plt.show(block=True)
|
||||||
|
|
||||||
|
|
35
polar/kernel.c
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
//#include <math.h>
|
||||||
|
#define PI 3.141592653589793115997963468544185161590576171875
|
||||||
|
|
||||||
|
double cosecant_single(double a, double b) { return a / sin(b); }
|
||||||
|
double secant_single(double a, double b) { return a / tan(b); }
|
||||||
|
|
||||||
|
|
||||||
|
__kernel void render_frame(__global unsigned int *frame_output, __global double *mask,
|
||||||
|
double x_step, double y_step,
|
||||||
|
double x_start, double y_start,
|
||||||
|
unsigned int iterations, unsigned int escape, double ratio) {
|
||||||
|
unsigned int result;
|
||||||
|
double x_cart = (get_global_id(0) * x_step) + x_start;
|
||||||
|
double y_cart = (get_global_id(1) * y_step) + y_start;
|
||||||
|
size_t img_index = (get_global_id(1) * get_global_size(1)) + get_global_id(0);
|
||||||
|
|
||||||
|
double x = sqrt(pow(x_cart, 2) + pow(y_cart, 2));
|
||||||
|
double y = atan(y_cart / x_cart);
|
||||||
|
|
||||||
|
unsigned int iter;
|
||||||
|
|
||||||
|
for(iter = 0; iter < iterations; iter++) {
|
||||||
|
double next_x;
|
||||||
|
double r = mask[img_index];
|
||||||
|
next_x = (r * cosecant_single(x, y)) + ((1 - r) * secant_single(x, y));
|
||||||
|
y = (r * cosecant_single(y, x)) + ((1 - r) * secant_single(y, x));
|
||||||
|
x = next_x;
|
||||||
|
if((pow(x, 2) + pow(y, 2)) >= escape) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
frame_output[img_index] = iter;
|
||||||
|
//frame_output[img_index] = mask[img_index] * 255;
|
||||||
|
}
|
79
polar/notes
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import matplotlib.animation as animation
|
||||||
|
import pyopencl as cl
|
||||||
|
from alive_progress import alive_bar
|
||||||
|
|
||||||
|
img_res_x = 2000
|
||||||
|
img_res_y = 2000
|
||||||
|
total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time
|
||||||
|
|
||||||
|
periods = 1
|
||||||
|
square_x = 0
|
||||||
|
square_y = 0
|
||||||
|
|
||||||
|
xmin = (-periods * np.pi) + (square_x * np.pi)
|
||||||
|
xmax = (periods * np.pi) + (square_x * np.pi)
|
||||||
|
ymin = (-periods * np.pi) + (square_y * np.pi)
|
||||||
|
ymax = (periods * np.pi) + (square_y * np.pi)
|
||||||
|
|
||||||
|
escape = 10000
|
||||||
|
iterations = 255*3
|
||||||
|
c_x = 2 * np.pi
|
||||||
|
c_y = 2 * np.pi
|
||||||
|
|
||||||
|
animation_progres_save = "./animations"
|
||||||
|
frames = 120
|
||||||
|
|
||||||
|
rendered_frames = []
|
||||||
|
|
||||||
|
|
||||||
|
plt.style.use('dark_background')
|
||||||
|
# fuck this shit
|
||||||
|
fig = plt.figure(frameon=False)
|
||||||
|
fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi)
|
||||||
|
#fig.set_size_inches(width/height, 1, forward=False)
|
||||||
|
|
||||||
|
ax = plt.Axes(fig, [0., 0., 1., 1.])
|
||||||
|
ax.set_axis_off()
|
||||||
|
fig.add_axes(ax)
|
||||||
|
|
||||||
|
cmap = plt.cm.viridis
|
||||||
|
cmap.set_bad((0,0,0))
|
||||||
|
cmap.set_over((0,0,0))
|
||||||
|
cmap.set_under((0,0,0))
|
||||||
|
|
||||||
|
opencl_context = cl.create_some_context()
|
||||||
|
opencl_queue = cl.CommandQueue(opencl_context)
|
||||||
|
|
||||||
|
|
||||||
|
#def render():
|
||||||
|
# image = np.empty([img_res_y, img_res_x])
|
||||||
|
# print("Rendering frames")
|
||||||
|
# with alive_bar(frames, bar = 'filling', spinner = 'waves') as bar_total:
|
||||||
|
# for frame in range(frames):
|
||||||
|
# split_ratio = frame / frames
|
||||||
|
# for pix_y, y in enumerate(np.linspace(ymin, ymax, img_res_y)):
|
||||||
|
# for pix_x, x in enumerate(np.linspace(xmin, xmax, img_res_x)):
|
||||||
|
# on_x = x
|
||||||
|
# on_y = y
|
||||||
|
# for i in range(iterations):
|
||||||
|
# next_x = (split_ratio * (on_x/np.sin(on_y))) + ((1 - split_ratio) * on_x/np.tan(on_y))
|
||||||
|
# on_y = (split_ratio * (on_y/np.sin(on_x))) + ((1 - split_ratio) * on_y/np.tan(on_x))
|
||||||
|
# on_x = next_x
|
||||||
|
# if on_x**2 + on_y**2 > escape:
|
||||||
|
# break
|
||||||
|
# image[pix_y][pix_x] = i
|
||||||
|
# rendered_frame = ax.imshow(image, norm="log", aspect="auto", cmap=cmap, animated=False)
|
||||||
|
# rendered_frames.append([rendered_frame])
|
||||||
|
# bar_total()
|
||||||
|
|
||||||
|
def display():
|
||||||
|
print(rendered_frames)
|
||||||
|
ani = animation.ArtistAnimation(fig, rendered_frames, interval=30, blit=True)
|
||||||
|
ani.save("test.mp4")
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
render()
|
||||||
|
display()
|
21
polar/texput.log
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
This is pdfTeX, Version 3.141592653-2.6-1.40.26 (TeX Live 2024/Arch Linux) (preloaded format=pdflatex 2024.4.22) 28 APR 2024 21:33
|
||||||
|
entering extended mode
|
||||||
|
restricted \write18 enabled.
|
||||||
|
%&-line parsing enabled.
|
||||||
|
**
|
||||||
|
|
||||||
|
! Emergency stop.
|
||||||
|
<*>
|
||||||
|
|
||||||
|
End of file on the terminal!
|
||||||
|
|
||||||
|
|
||||||
|
Here is how much of TeX's memory you used:
|
||||||
|
3 strings out of 476076
|
||||||
|
113 string characters out of 5793775
|
||||||
|
1925187 words of memory out of 5000000
|
||||||
|
22212 multiletter control sequences out of 15000+600000
|
||||||
|
558069 words of font info for 36 fonts, out of 8000000 for 9000
|
||||||
|
14 hyphenation exceptions out of 8191
|
||||||
|
0i,0n,0p,13b,6s stack positions out of 10000i,1000n,20000p,200000b,200000s
|
||||||
|
! ==> Fatal error occurred, no output PDF file produced!
|
55
thorn_fractal.py
Executable file
@ -0,0 +1,55 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
img_res_x = 2000
|
||||||
|
img_res_y = 2000
|
||||||
|
|
||||||
|
xmin = -np.pi
|
||||||
|
xmax = np.pi
|
||||||
|
ymin = -np.pi
|
||||||
|
ymax = np.pi
|
||||||
|
|
||||||
|
escape = 10000
|
||||||
|
iterations = 255
|
||||||
|
c_x = 0
|
||||||
|
c_y = 0
|
||||||
|
|
||||||
|
|
||||||
|
image = np.empty([img_res_y, img_res_x], np.float32)
|
||||||
|
|
||||||
|
for pix_y, y in enumerate(np.linspace(ymin, ymax, img_res_y)):
|
||||||
|
for pix_x, x in enumerate(np.linspace(xmin, xmax, img_res_x)):
|
||||||
|
on_x = x
|
||||||
|
on_y = y
|
||||||
|
for i in range(iterations):
|
||||||
|
next_x = (on_x/np.sin(on_y))
|
||||||
|
on_y = (on_y/np.sin(on_x))
|
||||||
|
on_x = next_x
|
||||||
|
if on_x**2 + on_y**2 > escape:
|
||||||
|
break
|
||||||
|
image[pix_y][pix_x] = i
|
||||||
|
#print(pix_y)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
plt.style.use('dark_background')
|
||||||
|
# fuck this shit
|
||||||
|
fig = plt.figure(frameon=False)
|
||||||
|
fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi)
|
||||||
|
#fig.set_size_inches(width/height, 1, forward=False)
|
||||||
|
print(fig.dpi)
|
||||||
|
|
||||||
|
ax = plt.Axes(fig, [0., 0., 1., 1.])
|
||||||
|
ax.set_axis_off()
|
||||||
|
fig.add_axes(ax)
|
||||||
|
|
||||||
|
cmap = plt.cm.viridis
|
||||||
|
cmap.set_bad((0,0,0))
|
||||||
|
cmap.set_over((0,0,0))
|
||||||
|
cmap.set_under((0,0,0))
|
||||||
|
|
||||||
|
ax.imshow(image, norm="log", aspect="auto", cmap=cmap)
|
||||||
|
fig.savefig("animation/cpu.png")
|
||||||
|
#plt.show()
|