You can do it by using a Context object with pdqContext (or other sort functions of the *Context variant), it allows you to map the usize a and b indexes, which are passed to the lessThan and swap functions, in a way where these indexes represent the row that is currently being sorted.
const std = @import("std");
fn sort(matrix: []f32, n: usize) void {
const Context = struct {
items: []f32,
columns: usize,
pub fn lessThan(ctx: @This(), a: usize, b: usize) bool {
const c = ctx.columns;
const lhs = ctx.items[a*c..][0..c];
const rhs = ctx.items[b*c..][0..c];
return std.mem.indexOfNone(f32, lhs, &.{0}) orelse lhs.len <
std.mem.indexOfNone(f32, rhs, &.{0}) orelse rhs.len;
}
pub fn swap(ctx: @This(), a: usize, b: usize) void {
const c = ctx.columns;
const lhs = ctx.items[a*c..][0..c];
const rhs = ctx.items[b*c..][0..c];
for(lhs, rhs) |*l, *r| std.mem.swap(f32, l, r);
}
};
const rows = matrix.len / n;
std.debug.assert(rows * n == matrix.len);
std.sort.pdqContext(0, rows, Context{.items = matrix, .columns = n});
}
pub fn printMatrix(matrix:[]f32, n:usize) void {
for(0..n) |i| {
for(0..n) |j| {
std.debug.print("{} ",.{matrix[4*i+j]});
}
std.debug.print("\n",.{});
}
}
pub fn main() !void {
var test_matrix = [_]f32{
0.0, 0.0, 3.0, 0.0,
0.0, 4.0, 0.0, 0.0,
0.0, 0.0, 0.0, 2.0,
7.0, 0.0, 0.0, 0.0,
};
printMatrix(&test_matrix, 4);
std.debug.print("\n",.{});
sort(&test_matrix, 4);
std.debug.print("\n",.{});
printMatrix(&test_matrix, 4);
}