From c18d99b69934a87e3e0d75fe8a06c22ff6cb3a99 Mon Sep 17 00:00:00 2001 From: Nicholas Gates Date: Fri, 1 Mar 2024 10:17:19 +0000 Subject: [PATCH 1/6] C Library --- build.zig | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/build.zig b/build.zig index 2f1ffcb..ec189f2 100644 --- a/build.zig +++ b/build.zig @@ -30,6 +30,18 @@ pub fn build(b: *std.Build) void { }, }); + // Static Library + const lib = b.addStaticLibrary(.{ + .name = "fastlanez", + .target = target, + .optimize = optimize, + .root_source_file = .{ .path = "src/lib.zig" }, + }); + b.installArtifact(lib); + // Ideally we would use dlib.getEmittedH(), but https://github.com/ziglang/zig/issues/18497 + const lib_header = b.addInstallFile(.{ .path = "zig-cache/fastlanez.h" }, "include/fastlanez.h"); + b.getInstallStep().dependOn(&lib_header.step); + // Unit Tests const unit_tests = b.addTest(.{ .root_source_file = .{ .path = "src/fastlanez.zig" }, From 4966989e9a8ef55b56a6b0d085a27b8ed6d9bc07 Mon Sep 17 00:00:00 2001 From: Nicholas Gates Date: Fri, 1 Mar 2024 10:17:23 +0000 Subject: [PATCH 2/6] C Library --- src/lib.zig | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 src/lib.zig diff --git a/src/lib.zig b/src/lib.zig new file mode 100644 index 0000000..63ec570 --- /dev/null +++ b/src/lib.zig @@ -0,0 +1,31 @@ +//! The C library for FastLanez. +const fl = @import("./fastlanez.zig"); +const std = @import("std"); + +// BitPacking +comptime { + const BitPacking = @import("./bitpacking.zig").BitPacking; + for (.{u8}) |E| { + const FL = fl.FastLanez(E); + + for (1..@bitSizeOf(E)) |W| { + // TODO(ngates): configure this in build.zig + const dbg = @import("builtin").mode == .Debug; + if (dbg and !std.math.isPowerOfTwo(W)) { + // Avoid too much code-gen in debug mode. + continue; + } + + const Wrapper = struct { + fn encode(in: *const FL.Vector, out: *FL.PackedBytes(W)) callconv(.C) void { + @call(.always_inline, BitPacking(FL).encode, .{ W, in, out }); + } + }; + + @export(Wrapper.encode, .{ + .name = "bitpack_" ++ @typeName(E) ++ "_" ++ @typeName(std.meta.Int(.unsigned, W)), + .linkage = .Strong, + }); + } + } +} From c45e8223d514bb087da1e2f4e19f42c38db1ffb1 Mon Sep 17 00:00:00 2001 From: Nicholas Gates Date: Fri, 1 Mar 2024 15:04:24 +0000 Subject: [PATCH 3/6] C Library --- build.zig | 4 ++++ src/lib.zig | 16 ++++++++-------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/build.zig b/build.zig index ec189f2..158cb2f 100644 --- a/build.zig +++ b/build.zig @@ -39,9 +39,13 @@ pub fn build(b: *std.Build) void { }); b.installArtifact(lib); // Ideally we would use dlib.getEmittedH(), but https://github.com/ziglang/zig/issues/18497 + _ = lib.getEmittedH(); // Needed to trigger generation const lib_header = b.addInstallFile(.{ .path = "zig-cache/fastlanez.h" }, "include/fastlanez.h"); + lib_header.step.dependOn(&lib.step); b.getInstallStep().dependOn(&lib_header.step); + // const lib_header_file = .{ .step = &lib.step, .path = "/Users/ngates/git/fastlanez/zig-cache/fastlanez.h" }; + // Unit Tests const unit_tests = b.addTest(.{ .root_source_file = .{ .path = "src/fastlanez.zig" }, diff --git a/src/lib.zig b/src/lib.zig index 63ec570..03d3835 100644 --- a/src/lib.zig +++ b/src/lib.zig @@ -8,14 +8,15 @@ comptime { for (.{u8}) |E| { const FL = fl.FastLanez(E); - for (1..@bitSizeOf(E)) |W| { - // TODO(ngates): configure this in build.zig - const dbg = @import("builtin").mode == .Debug; - if (dbg and !std.math.isPowerOfTwo(W)) { - // Avoid too much code-gen in debug mode. - continue; + const bit_packing_widths = blk: { + var widths_: [FL.T]u8 = undefined; + for (0..FL.T) |i| { + widths_[i] = @intCast(i); } + break :blk widths_; + }; + for (bit_packing_widths) |W| { const Wrapper = struct { fn encode(in: *const FL.Vector, out: *FL.PackedBytes(W)) callconv(.C) void { @call(.always_inline, BitPacking(FL).encode, .{ W, in, out }); @@ -23,8 +24,7 @@ comptime { }; @export(Wrapper.encode, .{ - .name = "bitpack_" ++ @typeName(E) ++ "_" ++ @typeName(std.meta.Int(.unsigned, W)), - .linkage = .Strong, + .name = "fl_bitpack_" ++ @typeName(E) ++ "_" ++ @typeName(std.meta.Int(.unsigned, W)), }); } } From 04a5473c009197d04d144cffb7457faeadc13a66 Mon Sep 17 00:00:00 2001 From: Nicholas Gates Date: Fri, 1 Mar 2024 15:07:16 +0000 Subject: [PATCH 4/6] C Library --- src/lib.zig | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/lib.zig b/src/lib.zig index 03d3835..37631c8 100644 --- a/src/lib.zig +++ b/src/lib.zig @@ -5,18 +5,10 @@ const std = @import("std"); // BitPacking comptime { const BitPacking = @import("./bitpacking.zig").BitPacking; - for (.{u8}) |E| { + for (.{ u8, u16, u32, u64 }) |E| { const FL = fl.FastLanez(E); - const bit_packing_widths = blk: { - var widths_: [FL.T]u8 = undefined; - for (0..FL.T) |i| { - widths_[i] = @intCast(i); - } - break :blk widths_; - }; - - for (bit_packing_widths) |W| { + for (1..FL.T) |W| { const Wrapper = struct { fn encode(in: *const FL.Vector, out: *FL.PackedBytes(W)) callconv(.C) void { @call(.always_inline, BitPacking(FL).encode, .{ W, in, out }); From ec6f5ba568fbd672c8fd54fca4cd7d3137444577 Mon Sep 17 00:00:00 2001 From: Nicholas Gates Date: Fri, 1 Mar 2024 15:09:08 +0000 Subject: [PATCH 5/6] C Library --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7762ba4..3a57155 100644 --- a/README.md +++ b/README.md @@ -159,10 +159,12 @@ of this library. Another possible advantage to the FastLanes loop ordering is that we can avoid unrolling the outer SIMD word loop, resulting in potentially much smaller code size for minimal impact on performance. - ## C Library -TODO: this library will be made available as a C library. +Running `zig build` will generate a static C library in `zig-out/lib` and a header file in `zig-out/include`. +The header file requires `zig.h` which is located in the `lib_dir` output by running `zig env`. + +This process should improve as https://github.com/ziglang/zig/issues/13528 is resolved. ## Python Library From 429648b56150eb9f6dcf717ec327e8e9048c5ec7 Mon Sep 17 00:00:00 2001 From: Nicholas Gates Date: Fri, 1 Mar 2024 15:14:18 +0000 Subject: [PATCH 6/6] Separate lib into its own build step --- README.md | 2 +- build.zig | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 3a57155..4d8452a 100644 --- a/README.md +++ b/README.md @@ -161,7 +161,7 @@ resulting in potentially much smaller code size for minimal impact on performanc ## C Library -Running `zig build` will generate a static C library in `zig-out/lib` and a header file in `zig-out/include`. +Running `zig build lib` will generate a static C library in `zig-out/lib` and a header file in `zig-out/include`. The header file requires `zig.h` which is located in the `lib_dir` output by running `zig env`. This process should improve as https://github.com/ziglang/zig/issues/13528 is resolved. diff --git a/build.zig b/build.zig index 158cb2f..3565f0a 100644 --- a/build.zig +++ b/build.zig @@ -37,14 +37,16 @@ pub fn build(b: *std.Build) void { .optimize = optimize, .root_source_file = .{ .path = "src/lib.zig" }, }); - b.installArtifact(lib); + const lib_install = b.addInstallArtifact(lib, .{}); + // Ideally we would use dlib.getEmittedH(), but https://github.com/ziglang/zig/issues/18497 - _ = lib.getEmittedH(); // Needed to trigger generation + _ = lib.getEmittedH(); // Needed to trigger header generation const lib_header = b.addInstallFile(.{ .path = "zig-cache/fastlanez.h" }, "include/fastlanez.h"); - lib_header.step.dependOn(&lib.step); - b.getInstallStep().dependOn(&lib_header.step); + lib_header.step.dependOn(&lib_install.step); - // const lib_header_file = .{ .step = &lib.step, .path = "/Users/ngates/git/fastlanez/zig-cache/fastlanez.h" }; + const lib_step = b.step("lib", "Build static C library"); + lib_step.dependOn(&lib_header.step); + lib_step.dependOn(&lib_install.step); // Unit Tests const unit_tests = b.addTest(.{