I am making a wrapper for MPI and been trying to make it "zig-like". However, due to some details of MPI this is proving to be difficult, especially since I want to maintain a clean API. Anyways, I need help deciding which of the following is better. This first snippet shows a very thin API, where the functions keep the same signature as the c ones:
pub fn main() !void {
try mpi.init();
const comm: mpi.Comm = .world;
const rank = try comm.rank();
if (rank == 0) {
const val: f64 = 3.14;
try comm.send(
&val,
1,
mpi.datatype.double,
1,
0,
);
} else if (rank == 1) {
var val: f64 = undefined;
_ = try comm.recv(
&val,
1,
mpi.datatype.double,
0,
0,
);
std.debug.print("Process {d} received from process 0 value: {d}\n", .{ rank, val });
}
try mpi.finalize();
}
The second snippet is my attempt at a more zig-like version:
pub fn main() !void {
const a: std.mem.Allocator = std.heap.page_allocator;
try mpi.init(a);
const comm: mpi.Comm = .world;
const rank = try comm.rank();
if (rank == 0) {
const val: f64 = 3.14;
try comm.send(
f64,
.{
.slice = &.{val},
.kind = .none,
},
1,
0,
);
} else if (rank == 1) {
var val: [1]f64 = .{0.0};
_ = try comm.recv(
f64,
.{
.slice = &val,
.kind = .none,
},
0,
0,
);
std.debug.print("Process {d} received from process 0 value: {d}\n", .{ rank, val[0] });
}
try mpi.finalize();
}
The second snippet is more type safe than the first (the first uses *anyopaque everywhere), but feels a lot more verbose