Skip to content

Commit 743ac2c

Browse files
authored
Merge branch 'hanabi1224:main' into zig
2 parents a593325 + 77f6bd5 commit 743ac2c

File tree

4 files changed

+295
-0
lines changed

4 files changed

+295
-0
lines changed

bench/algorithm/fasta/6.rs

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
// Ported from 1.zig
2+
3+
use std::io::{self, BufWriter, StdoutLock, Write};
4+
5+
const MAX_LINE_LENGTH: usize = 60;
6+
const IM: u32 = 139968;
7+
const IA: u32 = 3877;
8+
const IC: u32 = 29573;
9+
10+
struct AminoAcid {
11+
l: u8,
12+
p: f64,
13+
}
14+
15+
struct Random {
16+
seed: u32,
17+
}
18+
19+
impl Random {
20+
fn new() -> Self {
21+
Self { seed: 42 }
22+
}
23+
24+
fn next(&mut self) -> f64 {
25+
self.seed = (self.seed * IA + IC) % IM;
26+
(IM as f64 * self.seed as f64) / IM as f64
27+
}
28+
}
29+
30+
impl Iterator for Random {
31+
type Item = f64;
32+
33+
fn next(&mut self) -> Option<Self::Item> {
34+
Some(self.next())
35+
}
36+
}
37+
38+
fn repeat_and_wrap(
39+
out: &mut BufWriter<StdoutLock<'static>>,
40+
sequence: &[u8],
41+
count: usize,
42+
) -> io::Result<()> {
43+
let n = sequence.len();
44+
let padded_sequence = (0..(n + MAX_LINE_LENGTH))
45+
.map(|i| sequence[i % n])
46+
.collect::<Vec<_>>();
47+
48+
let mut off = 0;
49+
let mut idx = 0;
50+
while idx < count {
51+
let rem = count - idx;
52+
let line_length = MAX_LINE_LENGTH.min(rem);
53+
out.write_all(&padded_sequence[off..off + line_length])?;
54+
out.write_all(&[b'\n'])?;
55+
56+
off += line_length;
57+
if off > n {
58+
off -= n;
59+
}
60+
idx += line_length;
61+
}
62+
Ok(())
63+
}
64+
65+
fn generate_and_wrap(
66+
random: &mut Random,
67+
out: &mut BufWriter<StdoutLock<'static>>,
68+
nucleotides: &[AminoAcid],
69+
count: usize,
70+
) -> io::Result<()> {
71+
let mut cum_prob = 0.0;
72+
let cum_prob_total = nucleotides
73+
.iter()
74+
.map(|&AminoAcid { l: _, p }| {
75+
cum_prob += p;
76+
cum_prob * IM as f64
77+
})
78+
.collect::<Vec<_>>();
79+
80+
let mut line = [0u8; MAX_LINE_LENGTH + 1];
81+
line[MAX_LINE_LENGTH] = b'\n';
82+
83+
let mut idx = 0;
84+
while idx < count {
85+
let rem = count - idx;
86+
let line_length = MAX_LINE_LENGTH.min(rem);
87+
88+
line[..line_length]
89+
.iter_mut()
90+
.zip(&mut *random)
91+
.for_each(|(col, r)| {
92+
let c = cum_prob_total
93+
.iter()
94+
.fold(0, |acc, &n| acc + (n <= r) as usize);
95+
96+
*col = nucleotides[c].l;
97+
});
98+
99+
line[line_length] = b'\n';
100+
out.write_all(&line[..line_length + 1])?;
101+
idx += line_length;
102+
}
103+
Ok(())
104+
}
105+
106+
pub fn main() -> io::Result<()> {
107+
let stdout = io::stdout();
108+
let mut stdout = io::BufWriter::new(stdout.lock());
109+
let n = std::env::args_os()
110+
.nth(1)
111+
.and_then(|s| s.as_os_str().to_str().and_then(|s| s.parse().ok()))
112+
.unwrap_or(1000);
113+
114+
let homo_sapiens_alu =
115+
b"GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTC\
116+
AGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCG\
117+
TGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGG\
118+
AGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA";
119+
120+
stdout.write_all(b">ONE Homo sapiens alu\n".as_slice())?;
121+
repeat_and_wrap(&mut stdout, &homo_sapiens_alu[..], 2 * n)?;
122+
let mut random = Random::new();
123+
124+
let iub_nucleotide_info = &[
125+
AminoAcid { l: b'a', p: 0.27 },
126+
AminoAcid { l: b'c', p: 0.12 },
127+
AminoAcid { l: b'g', p: 0.12 },
128+
AminoAcid { l: b't', p: 0.27 },
129+
AminoAcid { l: b'B', p: 0.02 },
130+
AminoAcid { l: b'D', p: 0.02 },
131+
AminoAcid { l: b'H', p: 0.02 },
132+
AminoAcid { l: b'K', p: 0.02 },
133+
AminoAcid { l: b'M', p: 0.02 },
134+
AminoAcid { l: b'N', p: 0.02 },
135+
AminoAcid { l: b'R', p: 0.02 },
136+
AminoAcid { l: b'S', p: 0.02 },
137+
AminoAcid { l: b'V', p: 0.02 },
138+
AminoAcid { l: b'W', p: 0.02 },
139+
AminoAcid { l: b'Y', p: 0.02 },
140+
];
141+
142+
stdout.write_all(b">TWO IUB ambiguity codes\n".as_slice())?;
143+
generate_and_wrap(&mut random, &mut stdout, iub_nucleotide_info, 3 * n)?;
144+
145+
let homo_sapien_nucleotide_info = &[
146+
AminoAcid {
147+
l: b'a',
148+
p: 0.3029549426680,
149+
},
150+
AminoAcid {
151+
l: b'c',
152+
p: 0.1979883004921,
153+
},
154+
AminoAcid {
155+
l: b'g',
156+
p: 0.1975473066391,
157+
},
158+
AminoAcid {
159+
l: b't',
160+
p: 0.3015094502008,
161+
},
162+
];
163+
164+
stdout.write_all(b">THREE Homo sapiens frequency\n".as_slice())?;
165+
generate_and_wrap(&mut random, &mut stdout, homo_sapien_nucleotide_info, 5 * n)?;
166+
Ok(())
167+
}

bench/algorithm/nbody/3.zig

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
const std = @import("std");
2+
const math = std.math;
3+
4+
const solar_mass = 4.0 * math.pi * math.pi;
5+
const year = 365.24;
6+
7+
const vec3 = @Vector(3, f64);
8+
9+
fn scale(v: anytype, f: f64) @TypeOf(v) {
10+
return v * @as(@TypeOf(v), @splat(f));
11+
}
12+
13+
fn lengthSq(v: vec3) f64 {
14+
return @reduce(.Add, v * v);
15+
}
16+
17+
fn length(v: vec3) f64 {
18+
return @sqrt(lengthSq(v));
19+
}
20+
21+
const Body = struct {
22+
pos: vec3,
23+
vel: vec3,
24+
mass: f64,
25+
};
26+
27+
fn offsetMomentum(bodies: []Body) void {
28+
@setFloatMode(.optimized);
29+
var pos: vec3 = @splat(0);
30+
for (bodies[1..]) |b| pos += scale(@as(vec3, b.vel), b.mass);
31+
bodies[0].vel = -scale(pos, 1.0 / solar_mass);
32+
}
33+
34+
fn allPairs(comptime n: usize) [n * (n - 1)/2][2]u32 {
35+
var res: [n * (n - 1)/2][2]u32 = undefined;
36+
var k: usize = 0;
37+
for (0..n - 1) |i| for (i + 1..n) |j| {
38+
res[k] = .{@intCast(i), @intCast(j)};
39+
k += 1;
40+
};
41+
return res;
42+
}
43+
44+
fn advance(comptime n: usize, bodies: *[n]Body, dt: f64) void {
45+
@setFloatMode(.optimized);
46+
const pairs = comptime allPairs(n);
47+
var dp: [pairs.len]vec3 = undefined;
48+
var distSq: @Vector(pairs.len, f64) = undefined;
49+
inline for (pairs, 0..) |p, i| {
50+
const d = bodies[p[0]].pos - bodies[p[1]].pos;
51+
dp[i] = d;
52+
distSq[i] = lengthSq(dp[i]);
53+
}
54+
const mag = @as(@Vector(pairs.len, f64), @splat(dt)) / (distSq * @sqrt(distSq));
55+
56+
inline for (pairs, 0..) |p, i| {
57+
bodies[p[0]].vel -= scale(dp[i], bodies[p[1]].mass * mag[i]);
58+
bodies[p[1]].vel += scale(dp[i], bodies[p[0]].mass * mag[i]);
59+
}
60+
61+
inline for (bodies) |*body| body.pos += scale(body.vel, dt);
62+
}
63+
64+
fn energy(bodies: []const Body) f64 {
65+
@setFloatMode(.optimized);
66+
var e: f64 = 0.0;
67+
for (bodies, 0..) |bi, i| {
68+
e += 0.5 * lengthSq(bi.vel) * bi.mass;
69+
for (bodies[i + 1 ..]) |bj| {
70+
e -= bi.mass * bj.mass / length(bi.pos - bj.pos);
71+
}
72+
}
73+
return e;
74+
}
75+
76+
var solar_bodies = [_]Body{
77+
// Sun
78+
Body{
79+
.pos = @splat(0),
80+
.vel = @splat(0),
81+
.mass = solar_mass,
82+
},
83+
// Jupiter
84+
Body{
85+
.pos = .{ 4.84143144246472090, -1.16032004402742839, -0.103622044471123109 },
86+
.vel = scale(vec3{ 1.66007664274403694e-03, 7.69901118419740425e-03, -6.90460016972063023e-05 }, year),
87+
.mass = 9.54791938424326609e-04 * solar_mass,
88+
},
89+
// Saturn
90+
Body{
91+
.pos = .{ 8.34336671824457987, 4.12479856412430479, -0.403523417114321381 },
92+
.vel = scale(vec3{ -2.76742510726862411e-03, 4.99852801234917238e-03, 2.30417297573763929e-05 }, year),
93+
.mass = 2.85885980666130812e-04 * solar_mass,
94+
},
95+
// Uranus
96+
Body{
97+
.pos = .{ 12.8943695621391310, -15.1111514016986312, -0.223307578892655734 },
98+
.vel = scale(vec3{ 2.96460137564761618e-03, 2.37847173959480950e-03, -2.96589568540237556e-05 }, year),
99+
.mass = 4.36624404335156298e-05 * solar_mass,
100+
},
101+
// Neptune
102+
Body{
103+
.pos = .{ 15.3796971148509165, -25.9193146099879641, 0.179258772950371181 },
104+
.vel = scale(vec3{ 2.68067772490389322e-03, 1.62824170038242295e-03, -9.51592254519715870e-05 }, year),
105+
.mass = 5.15138902046611451e-05 * solar_mass,
106+
},
107+
};
108+
109+
pub fn main() !void {
110+
const steps = try getSteps();
111+
112+
offsetMomentum(&solar_bodies);
113+
const initial_energy = energy(&solar_bodies);
114+
for (0..steps) |_| advance(solar_bodies.len, &solar_bodies, 0.01);
115+
const final_energy = energy(&solar_bodies);
116+
117+
const stdout = std.io.getStdOut().writer();
118+
try stdout.print("{d:.9}\n{d:.9}\n", .{ initial_energy, final_energy });
119+
}
120+
121+
fn getSteps() !usize {
122+
var arg_it = std.process.args();
123+
_ = arg_it.skip();
124+
const arg = arg_it.next() orelse return 1000;
125+
return try std.fmt.parseInt(usize, arg, 10);
126+
}

bench/bench_rust.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ problems:
3232
- 1c.rs
3333
- 5-m.rs
3434
- 5c-m.rs
35+
- 6.rs
3536
- name: knucleotide
3637
source:
3738
- 8.rs

bench/bench_zig.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ problems:
1313
source:
1414
- 1.zig
1515
- 2.zig
16+
- 3.zig
1617
- name: spectral-norm
1718
source:
1819
- 1.zig

0 commit comments

Comments
 (0)