Skip to content

Commit 9c11bd1

Browse files
HasenpfoteHasenpfote
Hasenpfote
authored and
Hasenpfote
committed
新規サンプルの追加
1 parent e7fc1f1 commit 9c11bd1

19 files changed

+1039
-0
lines changed

BitonicSort/CMakeLists.txt

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
cmake_minimum_required(VERSION 3.5)
2+
3+
project(BitonicSort)
4+
5+
include(template)
6+
make_simple_example_project(${PROJECT_NAME})

BitonicSort/README.md

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
Bitonic Sort
2+
=============================
3+
4+
5+
6+
![Preview](preview.gif)
7+
8+
9+
10+
This sample is a WORK IN PROGRESS and actually not meant as a sample.
11+
12+
On the TODO list:
13+
*
14+
15+
Run the sample for more information.
16+
17+
18+
19+
See also:
20+
21+
- [Bitonic sort](http://www.iti.fh-flensburg.de/lang/algorithmen/sortieren/bitonic/bitonicen.htm)
22+
- [Bitonic sorting network for n not a power of 2](http://www.iti.fh-flensburg.de/lang/algorithmen/sortieren/bitonic/oddn.htm)
23+
- [[GPU Gems 2](https://developer.nvidia.com/gpugems/GPUGems2/gpugems2_chapter46.html)]
24+
- [t-pot『Bitonic sort』](https://t-pot.com/program/90_BitonicSort/index.html)
25+

BitonicSort/assets/shaders/apply.fs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#version 430
2+
3+
out vec4 o_color;
4+
5+
uniform sampler2D u_tex0;
6+
uniform vec2 u_pixel_size;
7+
8+
void main(void)
9+
{
10+
vec2 tex_coord = gl_FragCoord.xy * u_pixel_size;
11+
o_color.rgb = texture(u_tex0, tex_coord).rgb;
12+
o_color.a = 1.0;
13+
}

BitonicSort/assets/shaders/apply.vs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#version 430
2+
3+
layout(location = 0) in vec3 vs_position;
4+
5+
out gl_PerVertex
6+
{
7+
vec4 gl_Position;
8+
};
9+
10+
void main(void)
11+
{
12+
gl_Position = vec4(vs_position.x, vs_position.y, 0.0, 1.0);
13+
}

BitonicSort/assets/shaders/decode.fs

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#version 430
2+
3+
out vec4 o_color;
4+
5+
uniform sampler2D u_tex0;
6+
uniform vec2 u_src_resolution;
7+
uniform vec2 u_dst_resolution;
8+
9+
float address(vec2 address2d, vec2 resolution)
10+
{
11+
vec2 temp = floor(address2d);
12+
return temp.y * resolution.x + temp.x;
13+
}
14+
15+
vec2 address(float address1d, vec2 resolution)
16+
{
17+
vec2 temp;
18+
temp.x = mod(address1d, resolution.x);
19+
temp.y = address1d / resolution.x;
20+
return floor(temp) + 0.5;
21+
}
22+
23+
void main(void)
24+
{
25+
float adr1d = address(gl_FragCoord.xy, u_dst_resolution);
26+
vec2 adr2d = address(adr1d, u_src_resolution);
27+
28+
vec3 color = texture(u_tex0, adr2d / u_src_resolution).rgb;
29+
30+
o_color = vec4(color, 1.0);
31+
}

BitonicSort/assets/shaders/decode.vs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#version 430
2+
3+
layout(location = 0) in vec3 vs_position;
4+
5+
out gl_PerVertex
6+
{
7+
vec4 gl_Position;
8+
};
9+
10+
void main(void)
11+
{
12+
gl_Position = vec4(vs_position.x, vs_position.y, 0.0, 1.0);
13+
}

BitonicSort/assets/shaders/noise.fs

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#version 430
2+
3+
out vec4 o_color;
4+
5+
uniform vec2 u_pixel_size;
6+
7+
float hash(in vec2 p)
8+
{
9+
return fract(sin(dot(p.xy, vec2(12.9898, 78.233))) * 43758.5453123);
10+
}
11+
12+
float noise(in vec2 x)
13+
{
14+
vec2 i = floor(x);
15+
vec2 f = fract(x);
16+
17+
// Four corners.
18+
float a = hash(i);
19+
float b = hash(i + vec2(1.0, 0.0));
20+
float c = hash(i + vec2(0.0, 1.0));
21+
float d = hash(i + vec2(1.0, 1.0));
22+
23+
// Cubic Hermite Curve.
24+
vec2 u = smoothstep(0.0, 1.0, f);
25+
26+
return mix(mix(a, b, u.x), mix(c, d, u.x), u.y);
27+
}
28+
29+
#define OCTAVES 6
30+
float fbm(in vec2 st)
31+
{
32+
float value = 0.0;
33+
float amplitude = .5;
34+
float frequency = 0.;
35+
36+
for(int i = 0; i < OCTAVES; i++)
37+
{
38+
value += amplitude * noise(st);
39+
st *= 2.;
40+
amplitude *= .5;
41+
}
42+
return value;
43+
}
44+
45+
void main(void)
46+
{
47+
vec2 p = gl_FragCoord.xy * u_pixel_size;
48+
49+
vec3 color = vec3(fbm(p*3.0));
50+
51+
o_color = vec4(color, 1.0);
52+
}

BitonicSort/assets/shaders/noise.vs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#version 430
2+
3+
layout(location = 0) in vec3 vs_position;
4+
5+
out gl_PerVertex
6+
{
7+
vec4 gl_Position;
8+
};
9+
10+
void main(void)
11+
{
12+
gl_Position = vec4(vs_position.x, vs_position.y, 0.0, 1.0);
13+
}

BitonicSort/assets/shaders/sort.fs

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#version 430
2+
3+
out vec4 o_color;
4+
5+
uniform sampler2D u_tex0;
6+
uniform vec2 u_resolution;
7+
uniform float u_seq_size;
8+
uniform float u_offset;
9+
uniform float u_range;
10+
11+
float address(vec2 address2d, vec2 resolution)
12+
{
13+
vec2 temp = floor(address2d);
14+
return temp.y * resolution.x + temp.x;
15+
}
16+
17+
vec2 address(float address1d, vec2 resolution)
18+
{
19+
vec2 temp;
20+
temp.x = mod(address1d, resolution.x);
21+
temp.y = address1d / resolution.x;
22+
return floor(temp) + 0.5;
23+
}
24+
25+
void main(void)
26+
{
27+
float own_adr1d = address(gl_FragCoord.xy, u_resolution);
28+
29+
float fetch_dir = (mod(own_adr1d, u_range) < u_offset)? 1 : -1;
30+
float sort_dir = (mod(floor(own_adr1d / u_seq_size), 2.0) <= 0.5)? 1 : -1;
31+
32+
float partner_adr1d = own_adr1d + fetch_dir * u_offset;
33+
vec2 partner_adr2d = address(partner_adr1d, u_resolution);
34+
35+
vec3 own_color = texture(u_tex0, gl_FragCoord.xy / u_resolution).rgb;
36+
vec3 partner_color = texture(u_tex0, partner_adr2d / u_resolution).rgb;
37+
38+
vec3 min_color = (own_color.x < partner_color.x)? own_color : partner_color;
39+
vec3 max_color = (own_color.x < partner_color.x)? partner_color : own_color;
40+
41+
vec3 color = (fetch_dir == sort_dir)? min_color : max_color;
42+
43+
o_color = vec4(color, 1.0);
44+
}

BitonicSort/assets/shaders/sort.vs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#version 430
2+
3+
layout(location = 0) in vec3 vs_position;
4+
5+
out gl_PerVertex
6+
{
7+
vec4 gl_Position;
8+
};
9+
10+
void main(void)
11+
{
12+
gl_Position = vec4(vs_position.x, vs_position.y, 0.0, 1.0);
13+
}

BitonicSort/preview.gif

6.43 MB
Loading

BitonicSort/src/bitonic_sort.cpp

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#include <iterator>
2+
#include <cstdlib>
3+
#include <cassert>
4+
#include <array>
5+
#include <cmath>
6+
#include <vector>
7+
#include <numeric>
8+
#include <random>
9+
#include <algorithm>
10+
#include "bitonic_sort.h"
11+
12+
namespace bitonic_sort
13+
{
14+
15+
static int solve_quadratic_equation(double a, double b, double c, std::array<double, 2> & roots)
16+
{
17+
double d = b * b - 4.0 * a * c;
18+
if(d < 0.0)
19+
return 0; // equation has imaginary roots.
20+
21+
double x = (std::abs(b) + std::sqrt(d)) / (2.0 * a);
22+
if(d > 0.0)
23+
{
24+
// equation has 2 roots.
25+
if(b < 0.0) // negative sign
26+
{
27+
// x1 = (- b - sqrt(D)) / 2a = (- (-|b|) - sqrt(D)) / 2a = (|b| - sqrt(D)) / 2a ... When b is larger, There is a possibility to underflow.
28+
// x2 = (- b + sqrt(D)) / 2a = (- (-|b|) + sqrt(D)) / 2a = (|b| + sqrt(D)) / 2a
29+
roots[0] = c / (a * x); // rationalize the numerator
30+
roots[1] = x;
31+
}
32+
else // positive sign
33+
{
34+
// x1 = (- b - sqrt(D)) / 2a = (- (+|b|) - sqrt(D)) / 2a = (-|b| - sqrt(D)) / 2a = -(|b| + sqrt(D)) / 2a
35+
// x2 = (- b + sqrt(D)) / 2a = (- (+|b|) + sqrt(D)) / 2a = (-|b| + sqrt(D)) / 2a = -(|b| - sqrt(D)) / 2a ... When b is larger, There is a possibility to underflow.
36+
roots[0] = -x;
37+
roots[1] = -(c / (a * x)); // rationalize the numerator
38+
}
39+
return 2;
40+
}
41+
42+
// equation has 1 root
43+
roots[0] = roots[1] = (b < 0.0) ? x : -x;
44+
return 1;
45+
}
46+
47+
static int pass_to_step(int pass)
48+
{
49+
// ax^2 + bx + c = 0
50+
double a = 1.0;
51+
double b = 1.0;
52+
double c = -2.0 * static_cast<double>(pass);
53+
std::array<double, 2> roots;
54+
auto ret = solve_quadratic_equation(a, b, c, roots);
55+
assert(ret > 0);
56+
auto root = std::max(roots[0], roots[1]);
57+
58+
return static_cast<int>(std::ceil(root));
59+
}
60+
61+
static int pass_to_stage(int pass, int step)
62+
{
63+
auto sum = step * (step + 1) / 2;
64+
return sum - pass + 1;
65+
}
66+
67+
static int stage_to_offset(int stage)
68+
{
69+
return std::pow(2.0, stage - 1);
70+
}
71+
72+
double next_lower_power_of_two(double x)
73+
{
74+
return std::pow(2.0, std::floor(std::log2(x)));
75+
}
76+
77+
double next_higher_power_of_two(double x)
78+
{
79+
return std::pow(2.0, std::ceil(std::log2(x)));
80+
}
81+
82+
int get_num_passes(int N)
83+
{
84+
auto n = static_cast<int>(std::log2(N));
85+
return n * (n + 1) / 2;
86+
}
87+
88+
params get_params(int pass)
89+
{
90+
auto step = pass_to_step(pass);
91+
auto stage = pass_to_stage(pass, step);
92+
auto seq_size = static_cast<int>(std::pow(2.0, step));
93+
auto offset = stage_to_offset(stage);
94+
auto range = offset * 2;
95+
96+
return std::make_tuple(step, stage, seq_size, offset, range);
97+
}
98+
99+
}

BitonicSort/src/bitonic_sort.h

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#pragma once
2+
3+
namespace bitonic_sort
4+
{
5+
6+
using params = std::tuple<int, int, int, int, int>;
7+
8+
double next_lower_power_of_two(double x);
9+
double next_higher_power_of_two(double x);
10+
int get_num_passes(int N);
11+
params get_params(int pass);
12+
13+
}

0 commit comments

Comments
 (0)