-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparallel_map.zig
More file actions
189 lines (154 loc) · 6.13 KB
/
Copy pathparallel_map.zig
File metadata and controls
189 lines (154 loc) · 6.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
// Parallel Map Sample
//
// Demonstrates parallel map transformation over arrays.
// Shows forEach, forEachIndexed, map, and filter operations.
const std = @import("std");
const zigparallel = @import("loom");
const par_iter = zigparallel.par_iter;
const ThreadPool = zigparallel.ThreadPool;
pub fn main() !void {
const allocator = std.heap.page_allocator;
std.debug.print("=== Parallel Map Sample ===\n\n", .{});
// Create a thread pool
const pool = try ThreadPool.init(allocator, .{ .num_threads = 4 });
defer pool.deinit();
// ========================================================================
// forEach - In-place modification
// ========================================================================
std.debug.print("--- forEach (in-place double) ---\n", .{});
var data1 = [_]i32{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
std.debug.print("Before: ", .{});
printArray(&data1);
par_iter(&data1).withPool(pool).forEach(struct {
fn double(x: *i32) void {
x.* *= 2;
}
}.double);
std.debug.print("After: ", .{});
printArray(&data1);
// ========================================================================
// forEachIndexed - Access index during modification
// ========================================================================
std.debug.print("\n--- forEachIndexed (set to index * 10) ---\n", .{});
var data2 = [_]i32{ 0, 0, 0, 0, 0 };
std.debug.print("Before: ", .{});
printArray(&data2);
par_iter(&data2).withPool(pool).forEachIndexed(struct {
fn setFromIndex(i: usize, x: *i32) void {
x.* = @intCast(i * 10);
}
}.setFromIndex);
std.debug.print("After: ", .{});
printArray(&data2);
// ========================================================================
// map - Transform to new array
// ========================================================================
std.debug.print("\n--- map (square each element) ---\n", .{});
var data3 = [_]i32{ 1, 2, 3, 4, 5 };
std.debug.print("Input: ", .{});
printArray(&data3);
const squares = try par_iter(&data3).withPool(pool).map(i64, struct {
fn square(x: i32) i64 {
return @as(i64, x) * @as(i64, x);
}
}.square, allocator);
defer allocator.free(squares);
std.debug.print("Output: ", .{});
for (squares, 0..) |val, i| {
std.debug.print("{d}", .{val});
if (i < squares.len - 1) std.debug.print(", ", .{});
}
std.debug.print("\n", .{});
// ========================================================================
// filter - Select matching elements
// ========================================================================
std.debug.print("\n--- filter (select even numbers) ---\n", .{});
var data4 = [_]i32{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
std.debug.print("Input: ", .{});
printArray(&data4);
const evens = try par_iter(&data4).filter(struct {
fn isEven(x: i32) bool {
return @mod(x, 2) == 0;
}
}.isEven, allocator);
defer allocator.free(evens);
std.debug.print("Output: ", .{});
for (evens, 0..) |val, i| {
std.debug.print("{d}", .{val});
if (i < evens.len - 1) std.debug.print(", ", .{});
}
std.debug.print("\n", .{});
// ========================================================================
// Predicates: any, all, find, count
// ========================================================================
std.debug.print("\n--- Predicates ---\n", .{});
var data5 = [_]i32{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
const has_even = par_iter(&data5).any(struct {
fn isEven(x: i32) bool {
return @mod(x, 2) == 0;
}
}.isEven);
std.debug.print("any(isEven): {}\n", .{has_even});
const all_positive = par_iter(&data5).all(struct {
fn isPositive(x: i32) bool {
return x > 0;
}
}.isPositive);
std.debug.print("all(isPositive): {}\n", .{all_positive});
const first_gt5 = par_iter(&data5).find(struct {
fn greaterThan5(x: i32) bool {
return x > 5;
}
}.greaterThan5);
std.debug.print("find(>5): {?}\n", .{first_gt5});
const even_count = par_iter(&data5).count(struct {
fn isEven(x: i32) bool {
return @mod(x, 2) == 0;
}
}.isEven);
std.debug.print("count(isEven): {d}\n", .{even_count});
// ========================================================================
// withAlloc - Store allocator once, use for multiple operations
// ========================================================================
std.debug.print("\n--- withAlloc (set allocator once) ---\n", .{});
var data6 = [_]i32{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
std.debug.print("Input: ", .{});
printArray(&data6);
// Create iterator with stored allocator - no need to pass allocator to each operation
const iter = par_iter(&data6).withPool(pool).withAlloc(allocator);
// filter uses stored allocator (pass null)
const evens2 = try iter.filter(struct {
fn isEven(x: i32) bool {
return @mod(x, 2) == 0;
}
}.isEven, null);
defer allocator.free(evens2);
std.debug.print("Filtered evens: ", .{});
for (evens2, 0..) |val, i| {
std.debug.print("{d}", .{val});
if (i < evens2.len - 1) std.debug.print(", ", .{});
}
std.debug.print("\n", .{});
// map uses stored allocator (pass null)
const cubed = try iter.map(i64, struct {
fn cube(x: i32) i64 {
const v: i64 = @intCast(x);
return v * v * v;
}
}.cube, null);
defer allocator.free(cubed);
std.debug.print("Cubed values: ", .{});
for (cubed[0..6], 0..) |val, i| {
std.debug.print("{d}", .{val});
if (i < 5) std.debug.print(", ", .{});
}
std.debug.print("...\n", .{});
std.debug.print("\n=== Sample Complete ===\n", .{});
}
fn printArray(arr: []const i32) void {
for (arr, 0..) |val, i| {
std.debug.print("{d}", .{val});
if (i < arr.len - 1) std.debug.print(", ", .{});
}
std.debug.print("\n", .{});
}