]> git.djapps.eu Git - pkg/ggml/sources/ggml/commitdiff
zig : fix build (#840)
authorEmmanuel Durand <redacted>
Wed, 5 Jun 2024 08:41:51 +0000 (04:41 -0400)
committerGitHub <redacted>
Wed, 5 Jun 2024 08:41:51 +0000 (11:41 +0300)
build.zig
tests/test0.zig
tests/test1.zig
tests/test2.zig
tests/test3.zig

index 5aa379dc1558ef5fa8a0dc6865ef47b955961428..ffe471f202f8f25c8fec36b73ea089dbba12e1d0 100644 (file)
--- a/build.zig
+++ b/build.zig
@@ -4,14 +4,9 @@ const builtin = @import("builtin");
 // Zig Version: 0.11.0
 // Zig Build Command: zig build
 // Zig Run Command: zig build -h
-//     zig build run_dolly-v2
-//     zig build run_gpt-2
 //     zig build run_gpt-j
-//     zig build run_gpt-neox
 //     zig build run_mnist
-//     zig build run_mpt
-//     zig build run_replit
-//     zig build run_starcoder
+//     zig build run_magika
 //     zig build run_test-grad0
 //     zig build run_test-mul-mat0
 //     zig build run_test-mul-mat2
@@ -25,7 +20,7 @@ const builtin = @import("builtin");
 //     zig build run_zig_test1
 //     zig build run_zig_test2
 //     zig build run_zig_test3
-pub fn build(b: *std.build.Builder) void {
+pub fn build(b: *std.Build) void {
     const target = b.standardTargetOptions(.{});
     const optimize = b.standardOptimizeOption(.{});
     const lib = b.addStaticLibrary(.{
@@ -33,25 +28,27 @@ pub fn build(b: *std.build.Builder) void {
         .target = target,
         .optimize = optimize,
     });
-    lib.addIncludePath(.{ .path = "./include" });
-    lib.addIncludePath(.{ .path = "./include/ggml" });
-    lib.addCSourceFiles(&.{
+    lib.addIncludePath(b.path("./include"));
+    lib.addIncludePath(b.path("./include/ggml"));
+    lib.addCSourceFiles(.{ .files = &.{
         "src/ggml.c",
-    }, &.{"-std=c11"});
+        "src/ggml-alloc.c",
+        "src/ggml-backend.c",
+        "src/ggml-quants.c",
+    }, .flags = &.{
+        "-std=c11",
+        "-D_GNU_SOURCE",
+        "-D_XOPEN_SOURCE=600",
+    } });
     lib.linkLibC();
     lib.linkLibCpp();
     b.installArtifact(lib);
 
     // examples
     const examples = .{
-        "dolly-v2",
-        "gpt-2",
         "gpt-j",
-        "gpt-neox",
+        "magika",
         "mnist",
-        "mpt",
-        "replit",
-        "starcoder",
         // "whisper",
     };
     inline for (examples) |name| {
@@ -60,16 +57,19 @@ pub fn build(b: *std.build.Builder) void {
             .target = target,
             .optimize = optimize,
         });
-        exe.addIncludePath(.{ .path = "./include" });
-        exe.addIncludePath(.{ .path = "./include/ggml" });
-        exe.addIncludePath(.{ .path = "./examples" });
+        exe.addIncludePath(b.path("./include"));
+        exe.addIncludePath(b.path("./include/ggml"));
+        exe.addIncludePath(b.path("./examples"));
         // exe.addIncludePath("./examples/whisper");
-        exe.addCSourceFiles(&.{
-            std.fmt.comptimePrint("examples/{s}/main.cpp", .{name}),
-            "examples/common.cpp",
-            "examples/common-ggml.cpp",
-            // "examples/whisper/whisper.cpp",
-        }, &.{"-std=c++11"});
+        exe.addCSourceFiles(.{
+            .files = &.{
+                std.fmt.comptimePrint("examples/{s}/main.cpp", .{name}),
+                "examples/common.cpp",
+                "examples/common-ggml.cpp",
+                // "examples/whisper/whisper.cpp",
+            },
+            .flags = &.{"-std=c++11"},
+        });
         exe.linkLibrary(lib);
         b.installArtifact(exe);
         const run_cmd = b.addRunArtifact(exe);
@@ -88,7 +88,7 @@ pub fn build(b: *std.build.Builder) void {
         "test-mul-mat2",
         // "test-opt",
         // "test-svd0",
-        // "test-vec0",
+        "test-vec0",
         "test-vec1",
         // "test-vec2",
         "test0",
@@ -117,11 +117,13 @@ pub fn build(b: *std.build.Builder) void {
             .target = target,
             .optimize = optimize,
         });
-        exe.addIncludePath(.{ .path = "./include" });
-        exe.addIncludePath(.{ .path = "./include/ggml" });
-        exe.addCSourceFiles(&.{
+        exe.addIncludePath(b.path("./include"));
+        exe.addIncludePath(b.path("./include/ggml"));
+        exe.addCSourceFiles(.{ .files = &.{
             std.fmt.comptimePrint("tests/{s}.c", .{name}),
-        }, &.{"-std=c11"});
+        }, .flags = &.{
+            "-std=c11",
+        } });
         exe.linkLibrary(lib);
         b.installArtifact(exe);
         const run_cmd = b.addRunArtifact(exe);
@@ -141,12 +143,12 @@ pub fn build(b: *std.build.Builder) void {
     inline for (zig_tests) |name| {
         const exe = b.addExecutable(.{
             .name = name,
-            .root_source_file = .{ .path = std.fmt.comptimePrint("tests/{s}.zig", .{name}) },
+            .root_source_file = b.path(std.fmt.comptimePrint("tests/{s}.zig", .{name})),
             .target = target,
             .optimize = optimize,
         });
-        exe.addIncludePath(.{ .path = "./include" });
-        exe.addIncludePath(.{ .path = "./include/ggml" });
+        exe.addIncludePath(b.path("./include"));
+        exe.addIncludePath(b.path("./include/ggml"));
         exe.linkLibrary(lib);
         b.installArtifact(exe);
         const run_cmd = b.addRunArtifact(exe);
index e47bf36528d1d98935569020d7bd298a5ac61e59..26994d8952df3bd49527717a5daf2443d5b18dd4 100644 (file)
@@ -5,9 +5,9 @@ const c = @cImport({
 \r
 pub fn main() !void {\r
     const params = .{\r
-        .mem_size   = 128*1024*1024,\r
+        .mem_size = 128 * 1024 * 1024,\r
         .mem_buffer = null,\r
-        .no_alloc   = false,\r
+        .no_alloc = false,\r
     };\r
 \r
     const ctx0 = c.ggml_init(params);\r
@@ -17,23 +17,23 @@ pub fn main() !void {
     const t2 = c.ggml_new_tensor_2d(ctx0, c.GGML_TYPE_I16, 10, 20);\r
     const t3 = c.ggml_new_tensor_3d(ctx0, c.GGML_TYPE_I32, 10, 20, 30);\r
 \r
-    try std.testing.expect(t1.*.n_dims == 1);\r
-    try std.testing.expect(t1.*.ne[0]  == 10);\r
-    try std.testing.expect(t1.*.nb[1]  == 10*@sizeOf(f32));\r
-\r
-    try std.testing.expect(t2.*.n_dims == 2);\r
-    try std.testing.expect(t2.*.ne[0]  == 10);\r
-    try std.testing.expect(t2.*.ne[1]  == 20);\r
-    try std.testing.expect(t2.*.nb[1]  == 10*@sizeOf(i16));\r
-    try std.testing.expect(t2.*.nb[2]  == 10*20*@sizeOf(i16));\r
-\r
-    try std.testing.expect(t3.*.n_dims == 3);\r
-    try std.testing.expect(t3.*.ne[0]  == 10);\r
-    try std.testing.expect(t3.*.ne[1]  == 20);\r
-    try std.testing.expect(t3.*.ne[2]  == 30);\r
-    try std.testing.expect(t3.*.nb[1]  == 10*@sizeOf(i32));\r
-    try std.testing.expect(t3.*.nb[2]  == 10*20*@sizeOf(i32));\r
-    try std.testing.expect(t3.*.nb[3]  == 10*20*30*@sizeOf(i32));\r
+    try std.testing.expect(c.ggml_n_dims(t1) == 1);\r
+    try std.testing.expect(t1.*.ne[0] == 10);\r
+    try std.testing.expect(t1.*.nb[1] == 10 * @sizeOf(f32));\r
+\r
+    try std.testing.expect(c.ggml_n_dims(t2) == 2);\r
+    try std.testing.expect(t2.*.ne[0] == 10);\r
+    try std.testing.expect(t2.*.ne[1] == 20);\r
+    try std.testing.expect(t2.*.nb[1] == 10 * @sizeOf(i16));\r
+    try std.testing.expect(t2.*.nb[2] == 10 * 20 * @sizeOf(i16));\r
+\r
+    try std.testing.expect(c.ggml_n_dims(t3) == 3);\r
+    try std.testing.expect(t3.*.ne[0] == 10);\r
+    try std.testing.expect(t3.*.ne[1] == 20);\r
+    try std.testing.expect(t3.*.ne[2] == 30);\r
+    try std.testing.expect(t3.*.nb[1] == 10 * @sizeOf(i32));\r
+    try std.testing.expect(t3.*.nb[2] == 10 * 20 * @sizeOf(i32));\r
+    try std.testing.expect(t3.*.nb[3] == 10 * 20 * 30 * @sizeOf(i32));\r
 \r
     c.ggml_print_objects(ctx0);\r
 \r
index f331acbd81b61d3babad7b0cccb45e795f2b3d9b..507562c4196d377957c392b60b44a5aa69cccf23 100644 (file)
@@ -7,9 +7,9 @@ pub fn main() !void {
     const n_threads = 2;\r
 \r
     const params = .{\r
-        .mem_size   = 128*1024*1024,\r
+        .mem_size = 128 * 1024 * 1024,\r
         .mem_buffer = null,\r
-        .no_alloc   = false,\r
+        .no_alloc = false,\r
     };\r
 \r
     const ctx0 = c.ggml_init(params);\r
@@ -29,38 +29,40 @@ pub fn main() !void {
 \r
         c.ggml_print_objects(ctx0);\r
 \r
-        const gf = c.ggml_build_forward(f);\r
-        const gb = c.ggml_build_backward(ctx0, @constCast(&gf), false);\r
+        const gf = c.ggml_new_graph_custom(ctx0, c.GGML_DEFAULT_GRAPH_SIZE, true);\r
+        c.ggml_build_forward_expand(gf, f);\r
+        const gb = c.ggml_graph_dup(ctx0, @constCast(gf));\r
+        c.ggml_build_backward_expand(ctx0, @constCast(gf), @constCast(gb), false);\r
 \r
         _ = c.ggml_set_f32(x, 2.0);\r
         _ = c.ggml_set_f32(a, 3.0);\r
 \r
-        c.ggml_graph_reset(@constCast(&gf));\r
+        c.ggml_graph_reset(@constCast(gf));\r
         _ = c.ggml_set_f32(f.*.grad, 1.0);\r
 \r
-        c.ggml_graph_compute_with_ctx(ctx0, @constCast(&gb), n_threads);\r
+        _ = c.ggml_graph_compute_with_ctx(ctx0, @constCast(gb), n_threads);\r
 \r
         std.debug.print("f     = {d:.6}\n", .{c.ggml_get_f32_1d(f, 0)});\r
         std.debug.print("df/dx = {d:.6}\n", .{c.ggml_get_f32_1d(x.*.grad, 0)});\r
 \r
-        try std.testing.expect(c.ggml_get_f32_1d(f, 0)          ==  12.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x.*.grad, 0)   ==  12.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(f, 0) == 12.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x.*.grad, 0) == 12.0);\r
 \r
         _ = c.ggml_set_f32(x, 3.0);\r
 \r
-        c.ggml_graph_reset(@constCast(&gf));\r
+        c.ggml_graph_reset(@constCast(gf));\r
         _ = c.ggml_set_f32(f.*.grad, 1.0);\r
 \r
-        c.ggml_graph_compute_with_ctx(ctx0, @constCast(&gb), n_threads);\r
+        _ = c.ggml_graph_compute_with_ctx(ctx0, @constCast(gb), n_threads);\r
 \r
         std.debug.print("f     = {d:.6}\n", .{c.ggml_get_f32_1d(f, 0)});\r
         std.debug.print("df/dx = {d:.6}\n", .{c.ggml_get_f32_1d(x.*.grad, 0)});\r
 \r
-        try std.testing.expect(c.ggml_get_f32_1d(f, 0)          ==  27.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x.*.grad, 0)   ==  18.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(f, 0) == 27.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x.*.grad, 0) == 18.0);\r
 \r
-        c.ggml_graph_dump_dot(&gf, null, "test1-1-forward.dot");\r
-        c.ggml_graph_dump_dot(&gb, &gf,  "test1-1-backward.dot");\r
+        c.ggml_graph_dump_dot(gf, null, "test1-1-forward.dot");\r
+        c.ggml_graph_dump_dot(gb, gf, "test1-1-backward.dot");\r
     }\r
 \r
     /////////////////////////////////////////////////////////////\r
@@ -79,40 +81,44 @@ pub fn main() !void {
 \r
         const y = c.ggml_add(ctx0, c.ggml_mul(ctx0, x1, x1), c.ggml_mul(ctx0, x1, x2));\r
 \r
-        const gf = c.ggml_build_forward(y);\r
-        const gb = c.ggml_build_backward(ctx0, @constCast(&gf), false);\r
+        const gf = c.ggml_new_graph_custom(ctx0, c.GGML_DEFAULT_GRAPH_SIZE, true);\r
+        c.ggml_build_forward_expand(gf, y);\r
+        const gb = c.ggml_graph_dup(ctx0, @constCast(gf));\r
+        c.ggml_build_backward_expand(ctx0, @constCast(gf), @constCast(gb), false);\r
 \r
-        c.ggml_graph_reset(@constCast(&gf));\r
+        c.ggml_graph_reset(@constCast(gf));\r
         _ = c.ggml_set_f32(y.*.grad, 1.0);\r
 \r
-        c.ggml_graph_compute_with_ctx(ctx0, @constCast(&gb), n_threads);\r
+        _ = c.ggml_graph_compute_with_ctx(ctx0, @constCast(gb), n_threads);\r
 \r
         std.debug.print("y      = {d:.6}\n", .{c.ggml_get_f32_1d(y, 0)});\r
         std.debug.print("df/dx1 = {d:.6}\n", .{c.ggml_get_f32_1d(x1.*.grad, 0)});\r
         std.debug.print("df/dx2 = {d:.6}\n", .{c.ggml_get_f32_1d(x2.*.grad, 0)});\r
 \r
-        try std.testing.expect(c.ggml_get_f32_1d(y, 0)          ==  12.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 0)  ==  7.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 0)  ==  3.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(y, 0) == 12.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 0) == 7.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 0) == 3.0);\r
 \r
         const g1 = x1.*.grad;\r
         const g2 = x2.*.grad;\r
 \r
-        const gbb = c.ggml_build_backward(ctx0, @constCast(&gb), true);\r
+        const gbb = c.ggml_graph_dup(ctx0, @constCast(gb));\r
 \r
-        c.ggml_graph_reset(@constCast(&gb));\r
+        c.ggml_build_backward_expand(ctx0, @constCast(gb), @constCast(gbb), true);\r
+\r
+        c.ggml_graph_reset(@constCast(gb));\r
         _ = c.ggml_set_f32(g1.*.grad, 1.0);\r
         _ = c.ggml_set_f32(g2.*.grad, 1.0);\r
 \r
-        c.ggml_graph_compute_with_ctx(ctx0, @constCast(&gbb), n_threads);\r
+        _ = c.ggml_graph_compute_with_ctx(ctx0, @constCast(gbb), n_threads);\r
 \r
-        std.debug.print("H * [1, 1] = [ {d:.6} {d:.6} ]\n", .{c.ggml_get_f32_1d(x1.*.grad, 0), c.ggml_get_f32_1d(x2.*.grad, 0)});\r
+        std.debug.print("H * [1, 1] = [ {d:.6} {d:.6} ]\n", .{ c.ggml_get_f32_1d(x1.*.grad, 0), c.ggml_get_f32_1d(x2.*.grad, 0) });\r
 \r
-        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 0)  ==  3.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 0)  ==  1.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 0) == 3.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 0) == 1.0);\r
 \r
-        c.ggml_graph_dump_dot(&gf, null, "test1-2-forward.dot");\r
-        c.ggml_graph_dump_dot(&gb, &gf,  "test1-2-backward.dot");\r
+        c.ggml_graph_dump_dot(gf, null, "test1-2-forward.dot");\r
+        c.ggml_graph_dump_dot(gb, gf, "test1-2-backward.dot");\r
     }\r
 \r
     ///////////////////////////////////////////////////////////////\r
@@ -126,27 +132,29 @@ pub fn main() !void {
 \r
         const y = c.ggml_mul(ctx0, c.ggml_add(ctx0, c.ggml_mul(ctx0, x1, x1), c.ggml_mul(ctx0, x1, x2)), x1);\r
 \r
-        const gf = c.ggml_build_forward(y);\r
-        const gb = c.ggml_build_backward(ctx0, @constCast(&gf), false);\r
+        const gf = c.ggml_new_graph_custom(ctx0, c.GGML_DEFAULT_GRAPH_SIZE, true);\r
+        c.ggml_build_forward_expand(gf, y);\r
+        const gb = c.ggml_graph_dup(ctx0, @constCast(gf));\r
+        c.ggml_build_backward_expand(ctx0, @constCast(gf), @constCast(gb), false);\r
 \r
         _ = c.ggml_set_f32(x1, 3.0);\r
         _ = c.ggml_set_f32(x2, 4.0);\r
 \r
-        c.ggml_graph_reset(@constCast(&gf));\r
+        c.ggml_graph_reset(@constCast(gf));\r
         _ = c.ggml_set_f32(y.*.grad, 1.0);\r
 \r
-        c.ggml_graph_compute_with_ctx(ctx0, @constCast(&gb), n_threads);\r
+        _ = c.ggml_graph_compute_with_ctx(ctx0, @constCast(gb), n_threads);\r
 \r
         std.debug.print("y      = {d:.6}\n", .{c.ggml_get_f32_1d(y, 0)});\r
         std.debug.print("df/dx1 = {d:.6}\n", .{c.ggml_get_f32_1d(x1.*.grad, 0)});\r
         std.debug.print("df/dx2 = {d:.6}\n", .{c.ggml_get_f32_1d(x2.*.grad, 0)});\r
 \r
-        try std.testing.expect(c.ggml_get_f32_1d(y, 0)          ==  63.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 0)  ==  51.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 0)  ==  9.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(y, 0) == 63.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 0) == 51.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 0) == 9.0);\r
 \r
-        c.ggml_graph_dump_dot(&gf, null, "test1-3-forward.dot");\r
-        c.ggml_graph_dump_dot(&gb, &gf,  "test1-3-backward.dot");\r
+        c.ggml_graph_dump_dot(gf, null, "test1-3-forward.dot");\r
+        c.ggml_graph_dump_dot(gb, gf, "test1-3-backward.dot");\r
     }\r
 \r
     ///////////////////////////////////////////////////////////////\r
@@ -162,54 +170,57 @@ pub fn main() !void {
 \r
         const y = c.ggml_mul(ctx0, c.ggml_mul(ctx0, c.ggml_mul(ctx0, x1, x1), c.ggml_mul(ctx0, x2, x2)), x3);\r
 \r
-        const gf = c.ggml_build_forward(y);\r
-        const gb = c.ggml_build_backward(ctx0, @constCast(&gf), false);\r
+        const gf = c.ggml_new_graph_custom(ctx0, c.GGML_DEFAULT_GRAPH_SIZE, true);\r
+        c.ggml_build_forward_expand(gf, y);\r
+        const gb = c.ggml_graph_dup(ctx0, @constCast(gf));\r
+        c.ggml_build_backward_expand(ctx0, @constCast(gf), @constCast(gb), false);\r
 \r
         _ = c.ggml_set_f32(x1, 1.0);\r
         _ = c.ggml_set_f32(x2, 2.0);\r
         _ = c.ggml_set_f32(x3, 3.0);\r
 \r
-        c.ggml_graph_reset(@constCast(&gf));\r
+        c.ggml_graph_reset(@constCast(gf));\r
         _ = c.ggml_set_f32(y.*.grad, 1.0);\r
 \r
-        c.ggml_graph_compute_with_ctx(ctx0, @constCast(&gb), n_threads);\r
+        _ = c.ggml_graph_compute_with_ctx(ctx0, @constCast(gb), n_threads);\r
 \r
         std.debug.print("y      = {d:.6}\n", .{c.ggml_get_f32_1d(y, 0)});\r
         std.debug.print("df/dx1 = {d:.6}\n", .{c.ggml_get_f32_1d(x1.*.grad, 0)});\r
         std.debug.print("df/dx2 = {d:.6}\n", .{c.ggml_get_f32_1d(x2.*.grad, 0)});\r
         std.debug.print("df/dx3 = {d:.6}\n", .{c.ggml_get_f32_1d(x3.*.grad, 0)});\r
 \r
-        try std.testing.expect(c.ggml_get_f32_1d(y, 0)          ==  12.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 0)  ==  24.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 0)  ==  12.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x3.*.grad, 0)  ==  4.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(y, 0) == 12.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 0) == 24.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 0) == 12.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x3.*.grad, 0) == 4.0);\r
 \r
         const g1 = x1.*.grad;\r
         const g2 = x2.*.grad;\r
         const g3 = x3.*.grad;\r
 \r
-        const gbb = c.ggml_build_backward(ctx0, @constCast(&gb), true);\r
+        const gbb = c.ggml_graph_dup(ctx0, @constCast(gb));\r
+\r
+        c.ggml_build_backward_expand(ctx0, @constCast(gb), @constCast(gbb), true);\r
 \r
-        c.ggml_graph_reset(@constCast(&gb));\r
+        c.ggml_graph_reset(@constCast(gb));\r
         _ = c.ggml_set_f32(g1.*.grad, 1.0);\r
         _ = c.ggml_set_f32(g2.*.grad, 1.0);\r
         _ = c.ggml_set_f32(g3.*.grad, 1.0);\r
 \r
-        c.ggml_graph_compute_with_ctx(ctx0, @constCast(&gbb), n_threads);\r
+        _ = c.ggml_graph_compute_with_ctx(ctx0, @constCast(gbb), n_threads);\r
 \r
-        std.debug.print("H * [1, 1, 1] = [ {d:.6} {d:.6} {d:.6}]\n",\r
-            .{\r
-                c.ggml_get_f32_1d(x1.*.grad, 0),\r
-                c.ggml_get_f32_1d(x2.*.grad, 0),\r
-                c.ggml_get_f32_1d(x3.*.grad, 0),\r
-            });\r
+        std.debug.print("H * [1, 1, 1] = [ {d:.6} {d:.6} {d:.6}]\n", .{\r
+            c.ggml_get_f32_1d(x1.*.grad, 0),\r
+            c.ggml_get_f32_1d(x2.*.grad, 0),\r
+            c.ggml_get_f32_1d(x3.*.grad, 0),\r
+        });\r
 \r
-        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 0)  ==  56.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 0)  ==  34.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x3.*.grad, 0)  ==  12.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 0) == 56.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 0) == 34.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x3.*.grad, 0) == 12.0);\r
 \r
-        c.ggml_graph_dump_dot(&gf, null, "test1-4-forward.dot");\r
-        c.ggml_graph_dump_dot(&gb, &gf,  "test1-4-backward.dot");\r
+        c.ggml_graph_dump_dot(gf, null, "test1-4-forward.dot");\r
+        c.ggml_graph_dump_dot(gb, gf, "test1-4-backward.dot");\r
     }\r
 \r
     ///////////////////////////////////////////////////////////////\r
@@ -223,41 +234,41 @@ pub fn main() !void {
 \r
         const y = c.ggml_sum(ctx0, c.ggml_mul(ctx0, x1, x2));\r
 \r
-        const gf = c.ggml_build_forward(y);\r
-        const gb = c.ggml_build_backward(ctx0, @constCast(&gf), false);\r
+        const gf = c.ggml_new_graph_custom(ctx0, c.GGML_DEFAULT_GRAPH_SIZE, true);\r
+        c.ggml_build_forward_expand(gf, y);\r
+        const gb = c.ggml_graph_dup(ctx0, @constCast(gf));\r
+        c.ggml_build_backward_expand(ctx0, @constCast(gf), @constCast(gb), false);\r
 \r
         _ = c.ggml_set_f32(x1, 3.0);\r
         _ = c.ggml_set_f32(x2, 5.0);\r
 \r
-        c.ggml_graph_reset(@constCast(&gf));\r
+        c.ggml_graph_reset(@constCast(gf));\r
         _ = c.ggml_set_f32(y.*.grad, 1.0);\r
 \r
-        c.ggml_graph_compute_with_ctx(ctx0, @constCast(&gb), n_threads);\r
+        _ = c.ggml_graph_compute_with_ctx(ctx0, @constCast(gb), n_threads);\r
 \r
         std.debug.print("y      = {d:.6}\n", .{c.ggml_get_f32_1d(y, 0)});\r
-        std.debug.print("df/dx1 = {d:.6} {d:.6} {d:.6}\n",\r
-            .{\r
-                c.ggml_get_f32_1d(x1.*.grad, 0),\r
-                c.ggml_get_f32_1d(x1.*.grad, 1),\r
-                c.ggml_get_f32_1d(x1.*.grad, 2),\r
-            });\r
-        std.debug.print("df/dx2 = {d:.6} {d:.6} {d:.6}\n",\r
-            .{\r
-                c.ggml_get_f32_1d(x2.*.grad, 0),\r
-                c.ggml_get_f32_1d(x2.*.grad, 1),\r
-                c.ggml_get_f32_1d(x2.*.grad, 2),\r
-            });\r
-\r
-        try std.testing.expect(c.ggml_get_f32_1d(y, 0)          ==  45.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 0)  ==  5.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 0)  ==  3.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 1)  ==  5.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 1)  ==  3.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 2)  ==  5.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 2)  ==  3.0);\r
-\r
-        c.ggml_graph_dump_dot(&gf, null, "test1-5-forward.dot");\r
-        c.ggml_graph_dump_dot(&gb, &gf,  "test1-5-backward.dot");\r
+        std.debug.print("df/dx1 = {d:.6} {d:.6} {d:.6}\n", .{\r
+            c.ggml_get_f32_1d(x1.*.grad, 0),\r
+            c.ggml_get_f32_1d(x1.*.grad, 1),\r
+            c.ggml_get_f32_1d(x1.*.grad, 2),\r
+        });\r
+        std.debug.print("df/dx2 = {d:.6} {d:.6} {d:.6}\n", .{\r
+            c.ggml_get_f32_1d(x2.*.grad, 0),\r
+            c.ggml_get_f32_1d(x2.*.grad, 1),\r
+            c.ggml_get_f32_1d(x2.*.grad, 2),\r
+        });\r
+\r
+        try std.testing.expect(c.ggml_get_f32_1d(y, 0) == 45.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 0) == 5.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 0) == 3.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 1) == 5.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 1) == 3.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 2) == 5.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 2) == 3.0);\r
+\r
+        c.ggml_graph_dump_dot(gf, null, "test1-5-forward.dot");\r
+        c.ggml_graph_dump_dot(gb, gf, "test1-5-backward.dot");\r
     }\r
 \r
     ///////////////////////////////////////////////////////////////\r
@@ -270,51 +281,43 @@ pub fn main() !void {
         c.ggml_set_param(ctx0, x2);\r
 \r
         const y =\r
-            c.ggml_sum(ctx0,\r
-                    c.ggml_add(ctx0,\r
-                        c.ggml_mul(ctx0, x1, x2),\r
-                        c.ggml_mul(ctx0,\r
-                            c.ggml_repeat(ctx0, c.ggml_new_f32(ctx0, -2.0), x1),\r
-                            c.ggml_mul(ctx0, x1, x1)\r
-                            )\r
-                        )\r
-                    );\r
-\r
-        const gf = c.ggml_build_forward(y);\r
-        const gb = c.ggml_build_backward(ctx0, @constCast(&gf), false);\r
+            c.ggml_sum(ctx0, c.ggml_add(ctx0, c.ggml_mul(ctx0, x1, x2), c.ggml_mul(ctx0, c.ggml_repeat(ctx0, c.ggml_new_f32(ctx0, -2.0), x1), c.ggml_mul(ctx0, x1, x1))));\r
+\r
+        const gf = c.ggml_new_graph_custom(ctx0, c.GGML_DEFAULT_GRAPH_SIZE, true);\r
+        c.ggml_build_forward_expand(gf, y);\r
+        const gb = c.ggml_graph_dup(ctx0, @constCast(gf));\r
+        c.ggml_build_backward_expand(ctx0, @constCast(gf), @constCast(gb), false);\r
 \r
         _ = c.ggml_set_f32(x1, 3.0);\r
         _ = c.ggml_set_f32(x2, 5.0);\r
 \r
-        c.ggml_graph_reset(@constCast(&gf));\r
+        c.ggml_graph_reset(@constCast(gf));\r
         _ = c.ggml_set_f32(y.*.grad, 1.0);\r
 \r
-        c.ggml_graph_compute_with_ctx(ctx0, @constCast(&gb), n_threads);\r
+        _ = c.ggml_graph_compute_with_ctx(ctx0, @constCast(gb), n_threads);\r
 \r
         std.debug.print("y      = {d:.6}\n", .{c.ggml_get_f32_1d(y, 0)});\r
-        std.debug.print("df/dx1 = {d:.6} {d:.6} {d:.6}\n",\r
-            .{\r
-                c.ggml_get_f32_1d(x1.*.grad, 0),\r
-                c.ggml_get_f32_1d(x1.*.grad, 1),\r
-                c.ggml_get_f32_1d(x1.*.grad, 2),\r
-            });\r
-        std.debug.print("df/dx2 = {d:.6} {d:.6} {d:.6}\n",\r
-            .{\r
-                c.ggml_get_f32_1d(x2.*.grad, 0),\r
-                c.ggml_get_f32_1d(x2.*.grad, 1),\r
-                c.ggml_get_f32_1d(x2.*.grad, 2),\r
-            });\r
-\r
-        try std.testing.expect(c.ggml_get_f32_1d(y, 0)          ==  -9.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 0)  ==  -7.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 1)  ==  -7.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 2)  ==  -7.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 0)  ==  3.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 1)  ==  3.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 2)  ==  3.0);\r
-\r
-        c.ggml_graph_dump_dot(&gf, null, "test1-6-forward.dot");\r
-        c.ggml_graph_dump_dot(&gb, &gf,  "test1-6-backward.dot");\r
+        std.debug.print("df/dx1 = {d:.6} {d:.6} {d:.6}\n", .{\r
+            c.ggml_get_f32_1d(x1.*.grad, 0),\r
+            c.ggml_get_f32_1d(x1.*.grad, 1),\r
+            c.ggml_get_f32_1d(x1.*.grad, 2),\r
+        });\r
+        std.debug.print("df/dx2 = {d:.6} {d:.6} {d:.6}\n", .{\r
+            c.ggml_get_f32_1d(x2.*.grad, 0),\r
+            c.ggml_get_f32_1d(x2.*.grad, 1),\r
+            c.ggml_get_f32_1d(x2.*.grad, 2),\r
+        });\r
+\r
+        try std.testing.expect(c.ggml_get_f32_1d(y, 0) == -9.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 0) == -7.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 1) == -7.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 2) == -7.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 0) == 3.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 1) == 3.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 2) == 3.0);\r
+\r
+        c.ggml_graph_dump_dot(gf, null, "test1-6-forward.dot");\r
+        c.ggml_graph_dump_dot(gb, gf, "test1-6-backward.dot");\r
     }\r
 \r
     ///////////////////////////////////////////////////////////////\r
@@ -327,51 +330,43 @@ pub fn main() !void {
         c.ggml_set_param(ctx0, x2);\r
 \r
         const y =\r
-            c.ggml_sum(ctx0,\r
-                    c.ggml_sub(ctx0,\r
-                        c.ggml_mul(ctx0, x1, x2),\r
-                        c.ggml_mul(ctx0,\r
-                            c.ggml_mul(ctx0, x1, x1),\r
-                            c.ggml_repeat(ctx0, c.ggml_new_f32(ctx0, -2.0), x1)\r
-                            )\r
-                        )\r
-                    );\r
-\r
-        const gf = c.ggml_build_forward(y);\r
-        const gb = c.ggml_build_backward(ctx0, @constCast(&gf), false);\r
+            c.ggml_sum(ctx0, c.ggml_sub(ctx0, c.ggml_mul(ctx0, x1, x2), c.ggml_mul(ctx0, c.ggml_mul(ctx0, x1, x1), c.ggml_repeat(ctx0, c.ggml_new_f32(ctx0, -2.0), x1))));\r
+\r
+        const gf = c.ggml_new_graph_custom(ctx0, c.GGML_DEFAULT_GRAPH_SIZE, true);\r
+        c.ggml_build_forward_expand(gf, y);\r
+        const gb = c.ggml_graph_dup(ctx0, @constCast(gf));\r
+        c.ggml_build_backward_expand(ctx0, @constCast(gf), @constCast(gb), false);\r
 \r
         _ = c.ggml_set_f32(x1, 3.0);\r
         _ = c.ggml_set_f32(x2, 5.0);\r
 \r
-        c.ggml_graph_reset(@constCast(&gf));\r
+        c.ggml_graph_reset(@constCast(gf));\r
         _ = c.ggml_set_f32(y.*.grad, 1.0);\r
 \r
-        c.ggml_graph_compute_with_ctx(ctx0, @constCast(&gb), n_threads);\r
+        _ = c.ggml_graph_compute_with_ctx(ctx0, @constCast(gb), n_threads);\r
 \r
         std.debug.print("y      = {d:.6}\n", .{c.ggml_get_f32_1d(y, 0)});\r
-        std.debug.print("df/dx1 = {d:.6} {d:.6} {d:.6}\n",\r
-            .{\r
-                c.ggml_get_f32_1d(x1.*.grad, 0),\r
-                c.ggml_get_f32_1d(x1.*.grad, 1),\r
-                c.ggml_get_f32_1d(x1.*.grad, 2),\r
-            });\r
-        std.debug.print("df/dx2 = {d:.6} {d:.6} {d:.6}\n",\r
-            .{\r
-                c.ggml_get_f32_1d(x2.*.grad, 0),\r
-                c.ggml_get_f32_1d(x2.*.grad, 1),\r
-                c.ggml_get_f32_1d(x2.*.grad, 2),\r
-            });\r
-\r
-        try std.testing.expect(c.ggml_get_f32_1d(y, 0)          ==  99.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 0)  ==  17.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 1)  ==  17.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 2)  ==  17.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 0)  ==  3.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 1)  ==  3.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 2)  ==  3.0);\r
-\r
-        c.ggml_graph_dump_dot(&gf, null, "test1-7-forward.dot");\r
-        c.ggml_graph_dump_dot(&gb, &gf,  "test1-7-backward.dot");\r
+        std.debug.print("df/dx1 = {d:.6} {d:.6} {d:.6}\n", .{\r
+            c.ggml_get_f32_1d(x1.*.grad, 0),\r
+            c.ggml_get_f32_1d(x1.*.grad, 1),\r
+            c.ggml_get_f32_1d(x1.*.grad, 2),\r
+        });\r
+        std.debug.print("df/dx2 = {d:.6} {d:.6} {d:.6}\n", .{\r
+            c.ggml_get_f32_1d(x2.*.grad, 0),\r
+            c.ggml_get_f32_1d(x2.*.grad, 1),\r
+            c.ggml_get_f32_1d(x2.*.grad, 2),\r
+        });\r
+\r
+        try std.testing.expect(c.ggml_get_f32_1d(y, 0) == 99.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 0) == 17.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 1) == 17.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 2) == 17.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 0) == 3.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 1) == 3.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 2) == 3.0);\r
+\r
+        c.ggml_graph_dump_dot(gf, null, "test1-7-forward.dot");\r
+        c.ggml_graph_dump_dot(gb, gf, "test1-7-backward.dot");\r
     }\r
 \r
     ///////////////////////////////////////////////////////////////\r
@@ -384,75 +379,71 @@ pub fn main() !void {
         c.ggml_set_param(ctx0, x2);\r
 \r
         const y =\r
-            c.ggml_abs(ctx0,\r
-                    c.ggml_sub(ctx0, x1, x2)\r
-                    );\r
+            c.ggml_abs(ctx0, c.ggml_sub(ctx0, x1, x2));\r
 \r
-        const gf = c.ggml_build_forward(y);\r
-        const gb = c.ggml_build_backward(ctx0, @constCast(&gf), false);\r
+        const gf = c.ggml_new_graph_custom(ctx0, c.GGML_DEFAULT_GRAPH_SIZE, true);\r
+        c.ggml_build_forward_expand(gf, y);\r
+        const gb = c.ggml_graph_dup(ctx0, @constCast(gf));\r
+        c.ggml_build_backward_expand(ctx0, @constCast(gf), @constCast(gb), false);\r
 \r
         _ = c.ggml_set_f32(x1, 3.0);\r
         _ = c.ggml_set_f32(x2, 5.0);\r
 \r
-        c.ggml_graph_reset(@constCast(&gf));\r
+        c.ggml_graph_reset(@constCast(gf));\r
         _ = c.ggml_set_f32(y.*.grad, 1.0);\r
 \r
-        c.ggml_graph_compute_with_ctx(ctx0, @constCast(&gb), n_threads);\r
+        _ = c.ggml_graph_compute_with_ctx(ctx0, @constCast(gb), n_threads);\r
 \r
         std.debug.print("y      = {d:.6}\n", .{c.ggml_get_f32_1d(y, 0)});\r
-        std.debug.print("df/dx1 = {d:.6} {d:.6} {d:.6}\n",\r
-            .{\r
-                c.ggml_get_f32_1d(x1.*.grad, 0),\r
-                c.ggml_get_f32_1d(x1.*.grad, 1),\r
-                c.ggml_get_f32_1d(x1.*.grad, 2),\r
-            });\r
-        std.debug.print("df/dx2 = {d:.6} {d:.6} {d:.6}\n",\r
-            .{\r
-                c.ggml_get_f32_1d(x2.*.grad, 0),\r
-                c.ggml_get_f32_1d(x2.*.grad, 1),\r
-                c.ggml_get_f32_1d(x2.*.grad, 2),\r
-            });\r
-\r
-        try std.testing.expect(c.ggml_get_f32_1d(y, 0)          ==  2.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 0)  ==  -1.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 1)  ==  -1.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 2)  ==  -1.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 0)  ==  1.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 1)  ==  1.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 2)  ==  1.0);\r
+        std.debug.print("df/dx1 = {d:.6} {d:.6} {d:.6}\n", .{\r
+            c.ggml_get_f32_1d(x1.*.grad, 0),\r
+            c.ggml_get_f32_1d(x1.*.grad, 1),\r
+            c.ggml_get_f32_1d(x1.*.grad, 2),\r
+        });\r
+        std.debug.print("df/dx2 = {d:.6} {d:.6} {d:.6}\n", .{\r
+            c.ggml_get_f32_1d(x2.*.grad, 0),\r
+            c.ggml_get_f32_1d(x2.*.grad, 1),\r
+            c.ggml_get_f32_1d(x2.*.grad, 2),\r
+        });\r
+\r
+        try std.testing.expect(c.ggml_get_f32_1d(y, 0) == 2.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 0) == -1.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 1) == -1.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 2) == -1.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 0) == 1.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 1) == 1.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 2) == 1.0);\r
 \r
         _ = c.ggml_set_f32(x1, 7.0);\r
         _ = c.ggml_set_f32(x2, 5.0);\r
 \r
-        c.ggml_graph_reset(@constCast(&gf));\r
+        c.ggml_graph_reset(@constCast(gf));\r
         _ = c.ggml_set_f32(y.*.grad, 1.0);\r
 \r
-        c.ggml_graph_compute_with_ctx(ctx0, @constCast(&gb), n_threads);\r
+        _ = c.ggml_graph_compute_with_ctx(ctx0, @constCast(gb), n_threads);\r
 \r
         std.debug.print("y      = {d:.6}\n", .{c.ggml_get_f32_1d(y, 0)});\r
-        std.debug.print("df/dx1 = {d:.6} {d:.6} {d:.6}\n",\r
-            .{\r
-                c.ggml_get_f32_1d(x1.*.grad, 0),\r
-                c.ggml_get_f32_1d(x1.*.grad, 1),\r
-                c.ggml_get_f32_1d(x1.*.grad, 2),\r
-            });\r
-        std.debug.print("df/dx2 = {d:.6} {d:.6} {d:.6}\n",\r
-            .{\r
-                c.ggml_get_f32_1d(x2.*.grad, 0),\r
-                c.ggml_get_f32_1d(x2.*.grad, 1),\r
-                c.ggml_get_f32_1d(x2.*.grad, 2),\r
-            });\r
-\r
-        try std.testing.expect(c.ggml_get_f32_1d(y, 0)          ==  2.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 0)  ==  1.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 1)  ==  1.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 2)  ==  1.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 0)  ==  -1.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 1)  ==  -1.0);\r
-        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 2)  ==  -1.0);\r
-\r
-        c.ggml_graph_dump_dot(&gf, null, "test1-8-forward.dot");\r
-        c.ggml_graph_dump_dot(&gb, &gf,  "test1-8-backward.dot");\r
+        std.debug.print("df/dx1 = {d:.6} {d:.6} {d:.6}\n", .{\r
+            c.ggml_get_f32_1d(x1.*.grad, 0),\r
+            c.ggml_get_f32_1d(x1.*.grad, 1),\r
+            c.ggml_get_f32_1d(x1.*.grad, 2),\r
+        });\r
+        std.debug.print("df/dx2 = {d:.6} {d:.6} {d:.6}\n", .{\r
+            c.ggml_get_f32_1d(x2.*.grad, 0),\r
+            c.ggml_get_f32_1d(x2.*.grad, 1),\r
+            c.ggml_get_f32_1d(x2.*.grad, 2),\r
+        });\r
+\r
+        try std.testing.expect(c.ggml_get_f32_1d(y, 0) == 2.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 0) == 1.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 1) == 1.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x1.*.grad, 2) == 1.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 0) == -1.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 1) == -1.0);\r
+        try std.testing.expect(c.ggml_get_f32_1d(x2.*.grad, 2) == -1.0);\r
+\r
+        c.ggml_graph_dump_dot(gf, null, "test1-8-forward.dot");\r
+        c.ggml_graph_dump_dot(gb, gf, "test1-8-backward.dot");\r
     }\r
 \r
     _ = try std.io.getStdIn().reader().readByte();\r
index 667de967fbd622d6b92ec3778cd6ef26c3450c90..7c68d6d1591801577dcc4eb5cd7851aca073b50d 100644 (file)
@@ -5,23 +5,23 @@ const c = @cImport({
 });\r
 \r
 fn is_close(a: f32, b: f32, epsilon: f32) bool {\r
-    return std.math.fabs(a - b) < epsilon;\r
+    return @abs(a - b) < epsilon;\r
 }\r
 \r
 pub fn main() !void {\r
     const params = .{\r
-        .mem_size   = 128*1024*1024,\r
+        .mem_size = 128 * 1024 * 1024,\r
         .mem_buffer = null,\r
-        .no_alloc   = false,\r
+        .no_alloc = false,\r
     };\r
 \r
-    var opt_params = c.ggml_opt_default_params(c.GGML_OPT_LBFGS);\r
-    \r
+    var opt_params = c.ggml_opt_default_params(c.GGML_OPT_TYPE_LBFGS);\r
+\r
     const nthreads = try Thread.getCpuCount();\r
     opt_params.n_threads = @intCast(nthreads);\r
     std.debug.print("test2: n_threads:{}\n", .{opt_params.n_threads});\r
 \r
-    const xi = [_]f32{  1.0,  2.0,  3.0,  4.0,  5.0,  6.0,  7.0,  8.0,  9.0,  10.0 };\r
+    const xi = [_]f32{ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0 };\r
     const yi = [_]f32{ 15.0, 25.0, 35.0, 45.0, 55.0, 65.0, 75.0, 85.0, 95.0, 105.0 };\r
 \r
     const n = xi.len;\r
@@ -49,60 +49,38 @@ pub fn main() !void {
 \r
         // f = sum_i[(t0 + t1*x_i - y_i)^2]/(2n)\r
         const f =\r
-            c.ggml_div(ctx0,\r
-                    c.ggml_sum(ctx0,\r
-                        c.ggml_sqr(ctx0,\r
-                            c.ggml_sub(ctx0,\r
-                                c.ggml_add(ctx0,\r
-                                    c.ggml_mul(ctx0, x, c.ggml_repeat(ctx0, t1, x)),\r
-                                    c.ggml_repeat(ctx0, t0, x)),\r
-                                y)\r
-                            )\r
-                        ),\r
-                    c.ggml_new_f32(ctx0, @as(f32, 2.0)*n));\r
+            c.ggml_div(ctx0, c.ggml_sum(ctx0, c.ggml_sqr(ctx0, c.ggml_sub(ctx0, c.ggml_add(ctx0, c.ggml_mul(ctx0, x, c.ggml_repeat(ctx0, t1, x)), c.ggml_repeat(ctx0, t0, x)), y))), c.ggml_new_f32(ctx0, @as(f32, 2.0) * n));\r
 \r
         const res = c.ggml_opt(null, opt_params, f);\r
 \r
         std.debug.print("t0 = {d:.6}\n", .{c.ggml_get_f32_1d(t0, 0)});\r
         std.debug.print("t1 = {d:.6}\n", .{c.ggml_get_f32_1d(t1, 0)});\r
 \r
-        try std.testing.expect(res == c.GGML_OPT_OK);\r
-        try std.testing.expect(is_close(c.ggml_get_f32_1d(t0, 0),  5.0, 1e-3));\r
+        try std.testing.expect(res == c.GGML_OPT_RESULT_OK);\r
+        try std.testing.expect(is_close(c.ggml_get_f32_1d(t0, 0), 5.0, 1e-3));\r
         try std.testing.expect(is_close(c.ggml_get_f32_1d(t1, 0), 10.0, 1e-3));\r
     }\r
 \r
     {\r
         const t0 = c.ggml_new_f32(ctx0, -1.0);\r
-        const t1 = c.ggml_new_f32(ctx0,  9.0);\r
+        const t1 = c.ggml_new_f32(ctx0, 9.0);\r
 \r
         _ = c.ggml_set_param(ctx0, t0);\r
         _ = c.ggml_set_param(ctx0, t1);\r
 \r
         // f = 0.5*sum_i[abs(t0 + t1*x_i - y_i)]/n\r
         const f =\r
-            c.ggml_mul(ctx0,\r
-                    c.ggml_new_f32(ctx0, @as(f32, 1.0)/(2*n)),\r
-                    c.ggml_sum(ctx0,\r
-                        c.ggml_abs(ctx0,\r
-                            c.ggml_sub(ctx0,\r
-                                c.ggml_add(ctx0,\r
-                                    c.ggml_mul(ctx0, x, c.ggml_repeat(ctx0, t1, x)),\r
-                                    c.ggml_repeat(ctx0, t0, x)),\r
-                                y)\r
-                            )\r
-                        )\r
-                    );\r
-\r
+            c.ggml_mul(ctx0, c.ggml_new_f32(ctx0, @as(f32, 1.0) / (2 * n)), c.ggml_sum(ctx0, c.ggml_abs(ctx0, c.ggml_sub(ctx0, c.ggml_add(ctx0, c.ggml_mul(ctx0, x, c.ggml_repeat(ctx0, t1, x)), c.ggml_repeat(ctx0, t0, x)), y))));\r
 \r
         const res = c.ggml_opt(null, opt_params, f);\r
 \r
-        try std.testing.expect(res == c.GGML_OPT_OK);\r
-        try std.testing.expect(is_close(c.ggml_get_f32_1d(t0, 0),  5.0, 1e-2));\r
+        try std.testing.expect(res == c.GGML_OPT_RESULT_OK);\r
+        try std.testing.expect(is_close(c.ggml_get_f32_1d(t0, 0), 5.0, 1e-2));\r
         try std.testing.expect(is_close(c.ggml_get_f32_1d(t1, 0), 10.0, 1e-2));\r
     }\r
 \r
     {\r
-        const t0 = c.ggml_new_f32(ctx0,  5.0);\r
+        const t0 = c.ggml_new_f32(ctx0, 5.0);\r
         const t1 = c.ggml_new_f32(ctx0, -4.0);\r
 \r
         _ = c.ggml_set_param(ctx0, t0);\r
@@ -110,15 +88,12 @@ pub fn main() !void {
 \r
         // f = t0^2 + t1^2\r
         const f =\r
-            c.ggml_add(ctx0,\r
-                    c.ggml_sqr(ctx0, t0),\r
-                    c.ggml_sqr(ctx0, t1)\r
-                    );\r
+            c.ggml_add(ctx0, c.ggml_sqr(ctx0, t0), c.ggml_sqr(ctx0, t1));\r
 \r
         const res = c.ggml_opt(null, opt_params, f);\r
 \r
-        try std.testing.expect(res == c.GGML_OPT_OK);\r
-        try std.testing.expect(is_close(c.ggml_get_f32_1d(f,  0), 0.0, 1e-3));\r
+        try std.testing.expect(res == c.GGML_OPT_RESULT_OK);\r
+        try std.testing.expect(is_close(c.ggml_get_f32_1d(f, 0), 0.0, 1e-3));\r
         try std.testing.expect(is_close(c.ggml_get_f32_1d(t0, 0), 0.0, 1e-3));\r
         try std.testing.expect(is_close(c.ggml_get_f32_1d(t1, 0), 0.0, 1e-3));\r
     }\r
@@ -127,36 +102,19 @@ pub fn main() !void {
 \r
     {\r
         const t0 = c.ggml_new_f32(ctx0, -7.0);\r
-        const t1 = c.ggml_new_f32(ctx0,  8.0);\r
+        const t1 = c.ggml_new_f32(ctx0, 8.0);\r
 \r
         _ = c.ggml_set_param(ctx0, t0);\r
         _ = c.ggml_set_param(ctx0, t1);\r
 \r
         // f = (t0 + 2*t1 - 7)^2 + (2*t0 + t1 - 5)^2\r
         const f =\r
-            c.ggml_add(ctx0,\r
-                    c.ggml_sqr(ctx0,\r
-                        c.ggml_sub(ctx0,\r
-                            c.ggml_add(ctx0,\r
-                                t0,\r
-                                c.ggml_mul(ctx0, t1, c.ggml_new_f32(ctx0, 2.0))),\r
-                            c.ggml_new_f32(ctx0, 7.0)\r
-                            )\r
-                        ),\r
-                    c.ggml_sqr(ctx0,\r
-                        c.ggml_sub(ctx0,\r
-                            c.ggml_add(ctx0,\r
-                                c.ggml_mul(ctx0, t0, c.ggml_new_f32(ctx0, 2.0)),\r
-                                t1),\r
-                            c.ggml_new_f32(ctx0, 5.0)\r
-                            )\r
-                        )\r
-                    );\r
+            c.ggml_add(ctx0, c.ggml_sqr(ctx0, c.ggml_sub(ctx0, c.ggml_add(ctx0, t0, c.ggml_mul(ctx0, t1, c.ggml_new_f32(ctx0, 2.0))), c.ggml_new_f32(ctx0, 7.0))), c.ggml_sqr(ctx0, c.ggml_sub(ctx0, c.ggml_add(ctx0, c.ggml_mul(ctx0, t0, c.ggml_new_f32(ctx0, 2.0)), t1), c.ggml_new_f32(ctx0, 5.0))));\r
 \r
         const res = c.ggml_opt(null, opt_params, f);\r
 \r
-        try std.testing.expect(res == c.GGML_OPT_OK);\r
-        try std.testing.expect(is_close(c.ggml_get_f32_1d(f,  0), 0.0, 1e-3));\r
+        try std.testing.expect(res == c.GGML_OPT_RESULT_OK);\r
+        try std.testing.expect(is_close(c.ggml_get_f32_1d(f, 0), 0.0, 1e-3));\r
         try std.testing.expect(is_close(c.ggml_get_f32_1d(t0, 0), 1.0, 1e-3));\r
         try std.testing.expect(is_close(c.ggml_get_f32_1d(t1, 0), 3.0, 1e-3));\r
     }\r
index d676961fc69758235488913a5babb66f6f43c154..fe87df80c78a59259c20e4d2ae4d90a586550712 100644 (file)
@@ -6,18 +6,18 @@ const c = @cImport({
 });\r
 \r
 fn is_close(a: f32, b: f32, epsilon: f32) bool {\r
-    return std.math.fabs(a - b) < epsilon;\r
+    return @abs(a - b) < epsilon;\r
 }\r
 \r
 pub fn main() !void {\r
     const params = .{\r
-        .mem_size   = 128*1024*1024,\r
+        .mem_size = 128 * 1024 * 1024,\r
         .mem_buffer = null,\r
-        .no_alloc   = false,\r
+        .no_alloc = false,\r
     };\r
 \r
-    var opt_params = c.ggml_opt_default_params(c.GGML_OPT_LBFGS);\r
-    \r
+    var opt_params = c.ggml_opt_default_params(c.GGML_OPT_TYPE_LBFGS);\r
+\r
     const nthreads = try Thread.getCpuCount();\r
     opt_params.n_threads = @intCast(nthreads);\r
 \r
@@ -38,15 +38,14 @@ pub fn main() !void {
     const l_data_pointer: [*]f32 = @ptrCast(@alignCast(l.*.data));\r
     const f_data_pointer: [*]f32 = @ptrCast(@alignCast(F.*.data));\r
     for (0..NP) |j| {\r
-        const ll = if (j < NP/2) @as(f32, 1.0) else @as(f32, -1.0);\r
+        const ll = if (j < NP / 2) @as(f32, 1.0) else @as(f32, -1.0);\r
         l_data_pointer[j] = ll;\r
-        \r
+\r
         for (0..NF) |i| {\r
             const c_rand: f32 = @floatFromInt(c.rand());\r
-            f_data_pointer[j*NF + i] = \r
-                ((if (ll > 0 and i < NF/2) @as(f32, 1.0) else \r
-                    if (ll < 0 and i >= NF/2) @as(f32, 1.0) else @as(f32, 0.0)) + \r
-                        (c_rand/c.RAND_MAX - 0.5) * 0.1) / (0.5 * NF);\r
+            f_data_pointer[j * NF + i] =\r
+                ((if (ll > 0 and i < NF / 2) @as(f32, 1.0) else if (ll < 0 and i >= NF / 2) @as(f32, 1.0) else @as(f32, 0.0)) +\r
+                (c_rand / c.RAND_MAX - 0.5) * 0.1) / (0.5 * NF);\r
         }\r
     }\r
 \r
@@ -58,39 +57,25 @@ pub fn main() !void {
 \r
         // f = sum[(fj*x - l)^2]/n + lambda*|x^2|\r
         const f =\r
-            c.ggml_add(ctx0,\r
-                    c.ggml_div(ctx0,\r
-                        c.ggml_sum(ctx0,\r
-                            c.ggml_sqr(ctx0,\r
-                                c.ggml_sub(ctx0,\r
-                                    c.ggml_mul_mat(ctx0, F, x),\r
-                                    l)\r
-                                )\r
-                            ),\r
-                        c.ggml_new_f32(ctx0, @as(f32, NP))\r
-                        ),\r
-                    c.ggml_mul(ctx0,\r
-                        c.ggml_sum(ctx0, c.ggml_sqr(ctx0, x)),\r
-                        lambda)\r
-                    );\r
+            c.ggml_add(ctx0, c.ggml_div(ctx0, c.ggml_sum(ctx0, c.ggml_sqr(ctx0, c.ggml_sub(ctx0, c.ggml_mul_mat(ctx0, F, x), l))), c.ggml_new_f32(ctx0, @as(f32, NP))), c.ggml_mul(ctx0, c.ggml_sum(ctx0, c.ggml_sqr(ctx0, x)), lambda));\r
 \r
         const res = c.ggml_opt(null, opt_params, f);\r
 \r
-        try std.testing.expect(res == c.GGML_OPT_OK);\r
+        try std.testing.expect(res == c.GGML_OPT_RESULT_OK);\r
 \r
         const x_data_pointer: [*]f32 = @ptrCast(@alignCast(x.*.data));\r
         // print results\r
         for (0..16) |i| {\r
-            std.debug.print("x[{d:3}] = {d:.6}\n", .{i, x_data_pointer[i]});\r
+            std.debug.print("x[{d:3}] = {d:.6}\n", .{ i, x_data_pointer[i] });\r
         }\r
         std.debug.print("...\n", .{});\r
         for (NF - 16..NF) |i| {\r
-            std.debug.print("x[{d:3}] = {d:.6}\n", .{i, x_data_pointer[i]});\r
+            std.debug.print("x[{d:3}] = {d:.6}\n", .{ i, x_data_pointer[i] });\r
         }\r
         std.debug.print("\n", .{});\r
 \r
         for (0..NF) |i| {\r
-            if (i < NF/2) {\r
+            if (i < NF / 2) {\r
                 try std.testing.expect(is_close(x_data_pointer[i], 1.0, 1e-2));\r
             } else {\r
                 try std.testing.expect(is_close(x_data_pointer[i], -1.0, 1e-2));\r