2025-06-05 10:50.13: New job: test ahrefs/ocannl https://github.com/ahrefs/ocannl.git#refs/heads/master (24ee10feb649ece1cd5916ebf741dc2907358c44) (linux-x86_64:(lint-fmt)) Base: ocaml/opam:debian-12-ocaml-4.08@sha256:48fa4a7216c3973bb95572cf5dca98cbbcefe90f288f552e7ac70a8ccd438aa7 ocamlformat version: version 0.27.0 (from opam) To reproduce locally: git clone --recursive "https://github.com/ahrefs/ocannl.git" -b "master" && cd "ocannl" && git reset --hard 24ee10fe cat > Dockerfile <<'END-OF-DOCKERFILE' FROM ocaml/opam:debian-12-ocaml-4.08@sha256:48fa4a7216c3973bb95572cf5dca98cbbcefe90f288f552e7ac70a8ccd438aa7 USER 1000:1000 RUN cd ~/opam-repository && (git cat-file -e 0eea63ad71af2b1116c556023bedc6bf083e6125 || git fetch origin master) && git reset -q --hard 0eea63ad71af2b1116c556023bedc6bf083e6125 && git log --no-decorate -n1 --oneline && opam update -u RUN opam depext -i dune WORKDIR /src RUN opam depext -i ocamlformat=0.27.0 COPY --chown=1000:1000 . /src/ RUN opam exec -- dune build @fmt --ignore-promoted-rules || (echo "dune build @fmt failed"; exit 2) END-OF-DOCKERFILE docker build . END-REPRO-BLOCK 2025-06-05 10:50.13: Using cache hint "ahrefs/ocannl-ocaml/opam:debian-12-ocaml-4.08@sha256:48fa4a7216c3973bb95572cf5dca98cbbcefe90f288f552e7ac70a8ccd438aa7-debian-12-4.08_opam-2.3-ocamlformat-0eea63ad71af2b1116c556023bedc6bf083e6125" 2025-06-05 10:50.13: Using OBuilder spec: ((from ocaml/opam:debian-12-ocaml-4.08@sha256:48fa4a7216c3973bb95572cf5dca98cbbcefe90f288f552e7ac70a8ccd438aa7) (user (uid 1000) (gid 1000)) (run (cache (opam-archives (target /home/opam/.opam/download-cache))) (network host) (shell "cd ~/opam-repository && (git cat-file -e 0eea63ad71af2b1116c556023bedc6bf083e6125 || git fetch origin master) && git reset -q --hard 0eea63ad71af2b1116c556023bedc6bf083e6125 && git log --no-decorate -n1 --oneline && opam update -u")) (run (cache (opam-archives (target /home/opam/.opam/download-cache))) (network host) (shell "opam depext -i dune")) (workdir /src) (run (cache (opam-archives (target /home/opam/.opam/download-cache))) (network host) (shell "opam depext -i ocamlformat=0.27.0")) (copy (src .) (dst /src/)) (run (shell "opam exec -- dune build @fmt --ignore-promoted-rules || (echo \"dune build @fmt failed\"; exit 2)")) ) 2025-06-05 10:50.13: Waiting for resource in pool OCluster 2025-06-05 10:50.13: Waiting for worker… 2025-06-05 10:50.13: Got resource from pool OCluster Building on bremusa.ocamllabs.io All commits already cached HEAD is now at 24ee10fe Support padding via pre-padded ndarrays (my idea, Claude's code) (from ocaml/opam:debian-12-ocaml-4.08@sha256:48fa4a7216c3973bb95572cf5dca98cbbcefe90f288f552e7ac70a8ccd438aa7) 2025-06-05 10:50.15 ---> using "d1b97f3f32fc7cff4791d73e3fff398d19cc5b0541c709028ff05a921e22d2c8" from cache /: (user (uid 1000) (gid 1000)) /: (run (cache (opam-archives (target /home/opam/.opam/download-cache))) (network host) (shell "cd ~/opam-repository && (git cat-file -e 0eea63ad71af2b1116c556023bedc6bf083e6125 || git fetch origin master) && git reset -q --hard 0eea63ad71af2b1116c556023bedc6bf083e6125 && git log --no-decorate -n1 --oneline && opam update -u")) From https://github.com/ocaml/opam-repository * branch master -> FETCH_HEAD 0d013e603b..fc511aa5a8 master -> origin/master 0eea63ad71 Merge pull request #27946 from mtelvers/opam-publish-ocaml-version.4.0.1 <><> Updating package repositories ><><><><><><><><><><><><><><><><><><><><><><> [default] Initialised default (at git+file:///home/opam/opam-repository): [INFO] opam 2.1 and 2.2 include many performance and security improvements over 2.0; please consider upgrading (https://opam.ocaml.org/doc/Install.html) Everything as up-to-date as possible (run with --verbose to show unavailable upgrades). However, you may "opam upgrade" these packages explicitly, which will ask permission to downgrade or uninstall the conflicting packages. Nothing to do. # Run eval $(opam env) to update the current shell environment 2025-06-05 10:51.17 ---> saved as "96cf7cb4f290bdde63e0891300660f309335b98ec063b9c2de517b6b08952aac" /: (run (cache (opam-archives (target /home/opam/.opam/download-cache))) (network host) (shell "opam depext -i dune")) # Detecting depexts using vars: arch=x86_64, os=linux, os-distribution=debian, os-family=debian # No extra OS packages requirements found. # All required OS packages found. # Now letting opam install the packages The following actions will be performed: - install dune 3.19.0 <><> Gathering sources ><><><><><><><><><><><><><><><><><><><><><><><><><><><><> [dune.3.19.0] found in cache <><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> -> installed dune.3.19.0 Done. # Run eval $(opam env) to update the current shell environment 2025-06-05 10:51.45 ---> saved as "89c0585fea6e0efe18837c1dd4fe4772483d123bc62d2e4be11e9db74e5475f0" /: (workdir /src) /src: (run (cache (opam-archives (target /home/opam/.opam/download-cache))) (network host) (shell "opam depext -i ocamlformat=0.27.0")) # Detecting depexts using vars: arch=x86_64, os=linux, os-distribution=debian, os-family=debian # No extra OS packages requirements found. # All required OS packages found. # Now letting opam install the packages The following actions will be performed: - install sexplib0 v0.14.0 [required by base] - install cmdliner 1.3.0 [required by ocamlformat] - install menhirLib 20240715 [required by ocamlformat-lib] - install menhirCST 20240715 [required by menhir] - install ocamlbuild 0.16.1 [required by fpath, astring, uuseg] - install menhirSdk 20240715 [required by ocamlformat-lib] - install either 1.0.0 [required by ocamlformat-lib] - install ocaml-version 4.0.1 [required by ocamlformat-lib] - install camlp-streams 5.0.1 [required by ocamlformat-lib] - install csexp 1.5.2 [required by ocamlformat] - install seq base [required by re] - install fix 20250428 [required by ocamlformat-lib] - install ocamlfind 1.9.8 [required by ocp-indent, astring, fpath, uuseg] - install dune-build-info 3.19.0 [required by ocamlformat-lib] - install menhir 20240715 [required by ocamlformat-lib] - install dune-configurator 3.19.0 [required by base] - install re 1.11.0 [required by ocamlformat] - install topkg 1.0.8 [required by fpath, astring, uuseg] - install base-bytes base [required by ocp-indent] - install base v0.14.3 [required by ocamlformat-lib] - install uutf 1.0.4 [required by ocamlformat-lib] - install astring 0.8.5 [required by ocamlformat-lib] - install ocp-indent 1.8.1 [required by ocamlformat-lib] - install stdio v0.14.0 [required by ocamlformat-lib] - install uucp 15.0.0 [required by uuseg] - install fpath 0.7.3 [required by ocamlformat-lib] - install uuseg 15.0.0 [required by ocamlformat-lib] - install ocamlformat-lib 0.27.0 [required by ocamlformat] - install ocamlformat 0.27.0 ===== 29 to install ===== <><> Gathering sources ><><><><><><><><><><><><><><><><><><><><><><><><><><><><> [astring.0.8.5] found in cache [base.v0.14.3] found in cache [camlp-streams.5.0.1] found in cache [cmdliner.1.3.0] found in cache [csexp.1.5.2] found in cache [dune-build-info.3.19.0] found in cache [dune-configurator.3.19.0] found in cache [either.1.0.0] found in cache [fix.20250428] found in cache [fpath.0.7.3] found in cache [menhir.20240715] found in cache [menhirCST.20240715] found in cache [menhirLib.20240715] found in cache [menhirSdk.20240715] found in cache [ocaml-version.4.0.1] found in cache [ocamlbuild.0.16.1] found in cache [ocamlfind.1.9.8] found in cache [ocamlformat.0.27.0] found in cache [ocamlformat-lib.0.27.0] found in cache [ocp-indent.1.8.1] found in cache [re.1.11.0] found in cache [sexplib0.v0.14.0] found in cache [stdio.v0.14.0] found in cache [topkg.1.0.8] found in cache [uucp.15.0.0] found in cache [uuseg.15.0.0] found in cache [uutf.1.0.4] found in cache <><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><> -> installed seq.base -> installed camlp-streams.5.0.1 -> installed csexp.1.5.2 -> installed cmdliner.1.3.0 -> installed either.1.0.0 -> installed fix.20250428 -> installed menhirCST.20240715 -> installed menhirLib.20240715 -> installed menhirSdk.20240715 -> installed ocaml-version.4.0.1 -> installed sexplib0.v0.14.0 -> installed re.1.11.0 -> installed dune-build-info.3.19.0 -> installed dune-configurator.3.19.0 -> installed ocamlfind.1.9.8 -> installed base-bytes.base -> installed ocamlbuild.0.16.1 -> installed ocp-indent.1.8.1 -> installed base.v0.14.3 -> installed topkg.1.0.8 -> installed stdio.v0.14.0 -> installed uutf.1.0.4 -> installed astring.0.8.5 -> installed fpath.0.7.3 -> installed menhir.20240715 -> installed uucp.15.0.0 -> installed uuseg.15.0.0 -> installed ocamlformat-lib.0.27.0 -> installed ocamlformat.0.27.0 Done. <><> ocp-indent.1.8.1 installed successfully ><><><><><><><><><><><><><><><><><> => This package requires additional configuration for use in editors. Install package 'user-setup', or manually: * for Emacs, add these lines to ~/.emacs: (add-to-list 'load-path "/home/opam/.opam/4.08/share/emacs/site-lisp") (require 'ocp-indent) * for Vim, add this line to ~/.vimrc: set rtp^="/home/opam/.opam/4.08/share/ocp-indent/vim" # Run eval $(opam env) to update the current shell environment 2025-06-05 10:52.44 ---> saved as "3806f45ef51bb70dc27c6783fa556ac6054f53765f6f6e5d7f0761003690b07c" /src: (copy (src .) (dst /src/)) 2025-06-05 10:52.45 ---> saved as "761d29a60f3f279f4d8b7eba8d001ab84bbd471d1c31ee8f42891870932f843e" /src: (run (shell "opam exec -- dune build @fmt --ignore-promoted-rules || (echo \"dune build @fmt failed\"; exit 2)")) File "arrayjit/bin/dune", line 6, characters 21-34: 6 | (pps ppx_minidebug ppx_sexp_conv)) ^^^^^^^^^^^^^ Error: Library "ppx_sexp_conv" not found. -> required by _build/default/arrayjit/bin/read_config.exe -> required by %{dep:../../arrayjit/bin/read_config.exe} at test/dune:25 -> required by _build/default/test/config/ocannl_backend.txt -> required by %{read:config/ocannl_backend.txt} at test/dune:44 -> required by Computing directory contents of _build/default/test File "arrayjit/bin/dune", line 6, characters 7-20: 6 | (pps ppx_minidebug ppx_sexp_conv)) ^^^^^^^^^^^^^ Error: Library "ppx_minidebug" not found. -> required by _build/default/arrayjit/bin/.merlin-conf/exe-read_config -> required by _build/default/arrayjit/bin/read_config.exe -> required by %{dep:../../arrayjit/bin/read_config.exe} at test/dune:25 -> required by _build/default/test/config/ocannl_backend.txt -> required by %{read:config/ocannl_backend.txt} at test/dune:44 -> required by Computing directory contents of _build/default/test File "arrayjit/test/test_numerical_types.ml", line 1, characters 0-0: diff --git a/_build/default/arrayjit/test/test_numerical_types.ml b/_build/default/arrayjit/test/.formatted/test_numerical_types.ml index 222a2ec..971d196 100644 --- a/_build/default/arrayjit/test/test_numerical_types.ml +++ b/_build/default/arrayjit/test/.formatted/test_numerical_types.ml @@ -48,13 +48,15 @@ let test_padding () = Stdio.printf "\n\nTesting padding functionality:\n"; (* Test padding with float32 array *) - let padding_config = [| (1, 1); (2, 1) |] in (* left=1,right=1 for first dim; left=2,right=1 for second dim *) + let padding_config = [| (1, 1); (2, 1) |] in + (* left=1,right=1 for first dim; left=2,right=1 for second dim *) let padding_value = -999.0 in - let padded_dims = [| 4; 6 |] in (* (2+1+1) x (3+2+1) *) - + let padded_dims = [| 4; 6 |] in + (* (2+1+1) x (3+2+1) *) + let arr = - Ndarray.create_array ~debug:"padded_test" Ops.single ~dims:padded_dims + Ndarray.create_array ~debug:"padded_test" Ops.single ~dims:padded_dims ~padding:(Some (padding_config, padding_value)) (Ops.Constant_fill { values = [| 1.0; 2.0; 3.0; 4.0; 5.0; 6.0 |]; strict = true }) in @@ -65,12 +67,13 @@ let test_padding () = for j = 0 to dims.(1) - 1 do let idx = [| i; j |] in let value = Ndarray.get_as_float arr idx in - Stdio.printf "%8.1f " value; + Stdio.printf "%8.1f " value done; Stdio.printf "\n" done; - - Stdio.printf "\nExpected: padding value (-999.0) in margins, data values (1.0-6.0) in center region\n" + + Stdio.printf + "\nExpected: padding value (-999.0) in margins, data values (1.0-6.0) in center region\n" let () = test_bfloat16_conversions (); File "arrayjit/lib/assignments.ml", line 1, characters 0-0: diff --git a/_build/default/arrayjit/lib/assignments.ml b/_build/default/arrayjit/lib/.formatted/assignments.ml index bd3908f..3e41a7e 100644 --- a/_build/default/arrayjit/lib/assignments.ml +++ b/_build/default/arrayjit/lib/.formatted/assignments.ml @@ -154,20 +154,20 @@ let%diagn2_sexp to_low_level code = let projections = Lazy.force projections in let basecase rev_iters = (* Create a substitution from product iterators to loop iterators *) - let subst_map = + let subst_map = let loop_iters = Array.of_list_rev rev_iters in Array.mapi projections.product_iterators ~f:(fun i prod_iter -> - (prod_iter, Indexing.Iterator loop_iters.(i))) + (prod_iter, Indexing.Iterator loop_iters.(i))) |> Array.to_list |> Map.of_alist_exn (module Indexing.Symbol) in (* Substitute in projections *) let subst_index = function | Indexing.Fixed_idx _ as idx -> idx - | Indexing.Iterator s as idx -> - Option.value ~default:idx (Map.find subst_map s) + | Indexing.Iterator s as idx -> Option.value ~default:idx (Map.find subst_map s) | Indexing.Affine { symbols; offset } -> - (* For affine indices, we don't substitute - they should already use the right symbols *) + (* For affine indices, we don't substitute - they should already use the right + symbols *) Indexing.Affine { symbols; offset } in let lhs_idcs = Array.map projections.project_lhs ~f:subst_index in File "lib/tensor.ml", line 1, characters 0-0: diff --git a/_build/default/lib/tensor.ml b/_build/default/lib/.formatted/tensor.ml index ab2bd8e..3c062e8 100644 --- a/_build/default/lib/tensor.ml +++ b/_build/default/lib/.formatted/tensor.ml @@ -238,7 +238,11 @@ let op ~(label : string list) ?(ternary_op = Shape.Pointwise_tern) in let grad_id = session_state.next_id in session_state.next_id <- session_state.next_id + 1; - let g = Tn.create ~default_prec ~id:grad_id ~label:("grad" :: label) ~dims ~padding:(lazy None) default_init_op in + let g = + Tn.create ~default_prec ~id:grad_id ~label:("grad" :: label) ~dims + ~padding:(lazy None) + default_init_op + in let is_bck_root ti = Map.mem session_state.backprop_roots ti.id in let zero_grads = let zero_g ti = @@ -358,7 +362,8 @@ let ndarray ?(label = []) ?(grad_spec = Prohibit_grad) ?batch_dims ?input_dims ? let dims = Array.concat_map [| batch_ds; output_ds; input_ds |] ~f:Array.of_list in let debug = "Temporary array for pretty-printing" in let ndarr = - Nd.create_array ~debug Ir.Ops.double ~dims ~padding:None (Ir.Ops.Constant_fill { values; strict }) + Nd.create_array ~debug Ir.Ops.double ~dims ~padding:None + (Ir.Ops.Constant_fill { values; strict }) in let ( ! ) = List.length in let b = Buffer.create 1024 in File "arrayjit/lib/tnode.ml", line 1, characters 0-0: diff --git a/_build/default/arrayjit/lib/tnode.ml b/_build/default/arrayjit/lib/.formatted/tnode.ml index d58ce98..2d9cc89 100644 --- a/_build/default/arrayjit/lib/tnode.ml +++ b/_build/default/arrayjit/lib/.formatted/tnode.ml @@ -105,7 +105,6 @@ let dims_without_padding tn = Array.map2_exn dims padding ~f:(fun dim (left, right) -> dim - left - right) let get_padding tn = Lazy.force tn.padding - let id { id; _ } = "n" ^ Int.to_string id let label a = String.concat ~sep:"_" a.label let is_alphanum_ = String.for_all ~f:(fun c -> Char.equal c '_' || Char.is_alphanum c) @@ -540,8 +539,8 @@ let create ?default_prec ~id ~label ~dims ~padding init_op = lazy (if is_hosted_force tn 30 then Some - (Nd.create_array ~debug (Lazy.force prec) ~dims:(Lazy.force dims) ~padding:(Lazy.force padding) - init_op) + (Nd.create_array ~debug (Lazy.force prec) ~dims:(Lazy.force dims) + ~padding:(Lazy.force padding) init_op) else None) and prec = lazy File "arrayjit/lib/gcc_backend.ml", line 1, characters 0-0: diff --git a/_build/default/arrayjit/lib/gcc_backend.ml b/_build/default/arrayjit/lib/.formatted/gcc_backend.ml index 6bcb3b9..8d7a7ec 100644 --- a/_build/default/arrayjit/lib/gcc_backend.ml +++ b/_build/default/arrayjit/lib/.formatted/gcc_backend.ml @@ -233,10 +233,9 @@ let compile_main ~name ~log_functions ~env { ctx; nodes; get_ident; merge_node; | Iterator s -> Map.find_exn env s | Affine { symbols; offset } -> List.fold symbols ~init:(RValue.int ctx c_index offset) ~f:(fun acc (coeff, s) -> - RValue.binary_op ctx Plus c_index acc - (RValue.binary_op ctx Mult c_index - (RValue.int ctx c_index coeff) - (Map.find_exn env s)))) + RValue.binary_op ctx Plus c_index acc + (RValue.binary_op ctx Mult c_index (RValue.int ctx c_index coeff) + (Map.find_exn env s)))) with e -> Stdlib.Format.eprintf "exec_as_gccjit: missing index from@ %a@ among environment keys:@ %a\n%!" Sexp.pp_hum @@ -359,10 +358,14 @@ let compile_main ~name ~log_functions ~env { ctx; nodes; get_ident; merge_node; | Embed_index (Fixed_idx i) -> (Int.to_string i, []) | Embed_index (Iterator s) -> (Indexing.symbol_ident s ^ "{=%d}", [ Map.find_exn env s ]) | Embed_index (Affine { symbols; offset }) -> - let terms = List.map symbols ~f:(fun (coeff, s) -> - if coeff = 1 then Indexing.symbol_ident s - else Int.to_string coeff ^ "*" ^ Indexing.symbol_ident s) in - let expr = String.concat ~sep:"+" (terms @ if offset = 0 then [] else [Int.to_string offset]) in + let terms = + List.map symbols ~f:(fun (coeff, s) -> + if coeff = 1 then Indexing.symbol_ident s + else Int.to_string coeff ^ "*" ^ Indexing.symbol_ident s) + in + let expr = + String.concat ~sep:"+" (terms @ if offset = 0 then [] else [ Int.to_string offset ]) + in (expr, []) | Binop (Arg1, v1, _v2) -> loop v1 | Binop (Arg2, _v1, v2) -> loop v2 @@ -524,10 +527,9 @@ let compile_main ~name ~log_functions ~env { ctx; nodes; get_ident; merge_node; raise e) | Embed_index (Affine { symbols; offset }) -> List.fold symbols ~init:(RValue.int ctx num_typ offset) ~f:(fun acc (coeff, s) -> - RValue.binary_op ctx Plus num_typ acc - (RValue.binary_op ctx Mult num_typ - (RValue.int ctx num_typ coeff) - (RValue.cast ctx (Map.find_exn env s) num_typ))) + RValue.binary_op ctx Plus num_typ acc + (RValue.binary_op ctx Mult num_typ (RValue.int ctx num_typ coeff) + (RValue.cast ctx (Map.find_exn env s) num_typ))) | Binop (Arg2, _, c2) -> loop c2 | Binop (Arg1, c1, _) -> loop c1 | Binop (op, c1, c2) -> loop_binop op ~num_typ prec ~v1:(loop c1) ~v2:(loop c2) File "arrayjit/lib/ndarray.ml", line 1, characters 0-0: diff --git a/_build/default/arrayjit/lib/ndarray.ml b/_build/default/arrayjit/lib/.formatted/ndarray.ml index f062552..747022d 100644 --- a/_build/default/arrayjit/lib/ndarray.ml +++ b/_build/default/arrayjit/lib/.formatted/ndarray.ml @@ -132,41 +132,42 @@ let indices_to_offset ~dims ~idcs = let create_bigarray (type ocaml elt_t) (prec : (ocaml, elt_t) Ops.precision) ~dims ~padding (init_op : Ops.init_op) : (ocaml, elt_t) bigarray = Option.iter Utils.settings.fixed_state_for_init ~f:(fun seed -> Rand.Lib.init seed); - + (* Handle padding: dims already includes padding, compute unpadded dimensions *) - let unpadded_dims, padding_info = match padding with - | None -> dims, None + let unpadded_dims, padding_info = + match padding with + | None -> (dims, None) | Some (pad_config, pad_value) -> - let unpadded_dims = Array.map2_exn dims pad_config ~f:(fun dim (left, right) -> - dim - left - right) in + let unpadded_dims = + Array.map2_exn dims pad_config ~f:(fun dim (left, right) -> dim - left - right) + in (unpadded_dims, Some (pad_config, pad_value)) in - + let arr = create_bigarray_of_prec prec dims in - + (* Fill with padding value if padding is specified *) (match padding_info with - | None -> () - | Some (_, pad_value) -> - (* Fill the entire array with padding value using precision-specific fill *) - (match prec with - | Ops.Byte -> A.fill arr (Char.of_int_exn @@ Int.of_float pad_value) - | Ops.Uint16 -> A.fill arr (Int.of_float pad_value) - | Ops.Int32 -> A.fill arr (Int32.of_float pad_value) - | Ops.Half -> A.fill arr pad_value - | Ops.Bfloat16 -> A.fill arr (float_to_bfloat16 pad_value) - | Ops.Fp8 -> A.fill arr (Char.of_int_exn @@ float_to_fp8 pad_value) - | Ops.Single -> A.fill arr pad_value - | Ops.Double -> A.fill arr pad_value)); - + | None -> () + | Some (_, pad_value) -> ( + (* Fill the entire array with padding value using precision-specific fill *) + match prec with + | Ops.Byte -> A.fill arr (Char.of_int_exn @@ Int.of_float pad_value) + | Ops.Uint16 -> A.fill arr (Int.of_float pad_value) + | Ops.Int32 -> A.fill arr (Int32.of_float pad_value) + | Ops.Half -> A.fill arr pad_value + | Ops.Bfloat16 -> A.fill arr (float_to_bfloat16 pad_value) + | Ops.Fp8 -> A.fill arr (Char.of_int_exn @@ float_to_fp8 pad_value) + | Ops.Single -> A.fill arr pad_value + | Ops.Double -> A.fill arr pad_value)); + (* Helper function to convert unpadded indices to padded indices *) let unpadded_to_padded_indices idcs = match padding_info with | None -> idcs - | Some (pad_config, _) -> - Array.map2_exn idcs pad_config ~f:(fun idx (left, _) -> idx + left) + | Some (pad_config, _) -> Array.map2_exn idcs pad_config ~f:(fun idx (left, _) -> idx + left) in - + (* For non-constant fill operations, we need to iterate over unpadded dimensions *) let init_unpadded_region init_func = let rec loop_dims idcs dim_idx = @@ -181,7 +182,7 @@ let create_bigarray (type ocaml elt_t) (prec : (ocaml, elt_t) Ops.precision) ~di in loop_dims (Array.create ~len:(Array.length unpadded_dims) 0) 0 in - + let constant_fill_f f values strict = let len = Array.length values in if strict then ( @@ -195,32 +196,32 @@ let create_bigarray (type ocaml elt_t) (prec : (ocaml, elt_t) Ops.precision) ~di init_unpadded_region (fun idcs -> f values.(indices_to_offset ~dims:unpadded_dims ~idcs))) else init_unpadded_region (fun idcs -> - f values.(indices_to_offset ~dims:unpadded_dims ~idcs % len)) + f values.(indices_to_offset ~dims:unpadded_dims ~idcs % len)) in let constant_fill_float values strict = constant_fill_f Fn.id values strict in - + (match (prec, init_op) with | Ops.Byte, Constant_fill { values; strict } -> ignore (constant_fill_f (Fn.compose Char.of_int_exn Int.of_float) values strict) | Ops.Byte, Range_over_offsets -> - init_unpadded_region (fun idcs -> Char.of_int_exn @@ indices_to_offset ~dims:unpadded_dims ~idcs) + init_unpadded_region (fun idcs -> + Char.of_int_exn @@ indices_to_offset ~dims:unpadded_dims ~idcs) | Ops.Byte, Standard_uniform -> init_unpadded_region (fun _ -> Rand.Lib.char ()) - | Ops.Uint16, Constant_fill { values; strict } -> + | Ops.Uint16, Constant_fill { values; strict } -> ignore (constant_fill_f Int.of_float values strict) | Ops.Uint16, Range_over_offsets -> init_unpadded_region (fun idcs -> indices_to_offset ~dims:unpadded_dims ~idcs) | Ops.Uint16, Standard_uniform -> init_unpadded_region (fun _ -> Random.int 65536) - | Ops.Int32, Constant_fill { values; strict } -> + | Ops.Int32, Constant_fill { values; strict } -> ignore (constant_fill_f Int32.of_float values strict) | Ops.Int32, Range_over_offsets -> - init_unpadded_region (fun idcs -> Int32.of_int_exn @@ indices_to_offset ~dims:unpadded_dims ~idcs) - | Ops.Int32, Standard_uniform -> - init_unpadded_region (fun _ -> Random.int32 Int32.max_value) + init_unpadded_region (fun idcs -> + Int32.of_int_exn @@ indices_to_offset ~dims:unpadded_dims ~idcs) + | Ops.Int32, Standard_uniform -> init_unpadded_region (fun _ -> Random.int32 Int32.max_value) | Ops.Half, Constant_fill { values; strict } -> ignore (constant_fill_float values strict) | Ops.Half, Range_over_offsets -> init_unpadded_region (fun idcs -> Float.of_int @@ indices_to_offset ~dims:unpadded_dims ~idcs) - | Ops.Half, Standard_uniform -> - init_unpadded_region (fun _ -> Rand.Lib.float_range 0.0 1.0) + | Ops.Half, Standard_uniform -> init_unpadded_region (fun _ -> Rand.Lib.float_range 0.0 1.0) | Ops.Bfloat16, Constant_fill { values; strict } -> ignore (constant_fill_f float_to_bfloat16 values strict) | Ops.Bfloat16, Range_over_offsets -> @@ -232,23 +233,25 @@ let create_bigarray (type ocaml elt_t) (prec : (ocaml, elt_t) Ops.precision) ~di ignore (constant_fill_f (Fn.compose Char.of_int_exn float_to_fp8) values strict) | Ops.Fp8, Range_over_offsets -> init_unpadded_region (fun idcs -> - Char.of_int_exn @@ float_to_fp8 @@ Float.of_int @@ indices_to_offset ~dims:unpadded_dims ~idcs) + Char.of_int_exn @@ float_to_fp8 @@ Float.of_int + @@ indices_to_offset ~dims:unpadded_dims ~idcs) | Ops.Fp8, Standard_uniform -> - init_unpadded_region (fun _ -> Char.of_int_exn @@ float_to_fp8 @@ Rand.Lib.float_range 0.0 1.0) + init_unpadded_region (fun _ -> + Char.of_int_exn @@ float_to_fp8 @@ Rand.Lib.float_range 0.0 1.0) | Ops.Single, Constant_fill { values; strict } -> ignore (constant_fill_float values strict) | Ops.Single, Range_over_offsets -> init_unpadded_region (fun idcs -> Float.of_int @@ indices_to_offset ~dims:unpadded_dims ~idcs) - | Ops.Single, Standard_uniform -> - init_unpadded_region (fun _ -> Rand.Lib.float_range 0.0 1.0) + | Ops.Single, Standard_uniform -> init_unpadded_region (fun _ -> Rand.Lib.float_range 0.0 1.0) | Ops.Double, Constant_fill { values; strict } -> ignore (constant_fill_float values strict) | Ops.Double, Range_over_offsets -> init_unpadded_region (fun idcs -> Float.of_int @@ indices_to_offset ~dims:unpadded_dims ~idcs) - | Ops.Double, Standard_uniform -> - init_unpadded_region (fun _ -> Rand.Lib.float_range 0.0 1.0) + | Ops.Double, Standard_uniform -> init_unpadded_region (fun _ -> Rand.Lib.float_range 0.0 1.0) | _, File_mapped (filename, stored_prec) -> (* For file mapping, we don't support padding yet - require no padding *) if Option.is_some padding then - raise @@ Utils.User_error "Ndarray.create_bigarray: File_mapped initialization does not support padding"; + raise + @@ Utils.User_error + "Ndarray.create_bigarray: File_mapped initialization does not support padding"; (* See: https://github.com/janestreet/torch/blob/master/src/torch/dataset_helper.ml#L3 *) if not @@ Ops.equal_prec stored_prec (Ops.pack_prec prec) then raise @@ -384,8 +387,7 @@ let reset_bigarray (init_op : Ops.init_op) (type o b) (prec : (o, b) Ops.precisi | Ops.Int32, Constant_fill { values; strict } -> constant_set_f Int32.of_float values strict | Ops.Int32, Range_over_offsets -> set_bigarray arr ~f:(fun idcs -> Int32.of_int_exn @@ indices_to_offset ~dims ~idcs) - | Ops.Int32, Standard_uniform -> - set_bigarray arr ~f:(fun _ -> Random.int32 Int32.max_value) + | Ops.Int32, Standard_uniform -> set_bigarray arr ~f:(fun _ -> Random.int32 Int32.max_value) | Ops.Half, Constant_fill { values; strict } -> constant_set_float values strict | Ops.Half, Range_over_offsets -> set_bigarray arr ~f:(fun idcs -> Float.of_int @@ indices_to_offset ~dims ~idcs) @@ -558,8 +560,8 @@ let hash_t nd = Nativeint.hash @@ to_native nd let used_memory = Atomic.make 0 -let%track7_sexp create_array ~debug:(_debug : string) (prec : Ops.prec) ~(dims : int array) - ~padding init_op = +let%track7_sexp create_array ~debug:(_debug : string) (prec : Ops.prec) ~(dims : int array) ~padding + init_op = (* dims already includes padding if padding is specified *) let size_in_bytes : int = (if Array.length dims = 0 then 0 else Array.reduce_exn dims ~f:( * )) * Ops.prec_in_bytes prec File "arrayjit/lib/low_level.ml", line 1, characters 0-0: diff --git a/_build/default/arrayjit/lib/low_level.ml b/_build/default/arrayjit/lib/.formatted/low_level.ml index 7e519f9..ea6ac75 100644 --- a/_build/default/arrayjit/lib/low_level.ml +++ b/_build/default/arrayjit/lib/.formatted/low_level.ml @@ -157,7 +157,7 @@ let visit_llc traced_store ~merge_node_id reverse_node_map ~max_visits llc = | Iterator s -> Option.value ~default:(* static index *) 0 @@ Map.find env s | Indexing.Affine { symbols; offset } -> List.fold symbols ~init:offset ~f:(fun acc (coeff, s) -> - acc + coeff * (Option.value ~default:0 @@ Map.find env s))) + acc + (coeff * (Option.value ~default:0 @@ Map.find env s)))) in let rec loop_proc env llc = let loop = loop_proc env in @@ -196,8 +196,8 @@ let visit_llc traced_store ~merge_node_id reverse_node_map ~max_visits llc = assert (Tn.equal old_tn tn) | Indexing.Affine { symbols; _ } -> List.iter symbols ~f:(fun (_, s) -> - let old_tn = Hashtbl.find_or_add reverse_node_map s ~default:(fun () -> tn) in - assert (Tn.equal old_tn tn))) + let old_tn = Hashtbl.find_or_add reverse_node_map s ~default:(fun () -> tn) in + assert (Tn.equal old_tn tn))) | Set_local (_, llv) -> loop_float env llv | Comment _ -> () | Staged_compilation _ -> () @@ -279,11 +279,14 @@ let%diagn2_sexp check_and_store_virtual traced static_indices top_llc = function | Fixed_idx _ -> None | Iterator s -> Option.some_if (not @@ Set.mem static_indices s) s - | Affine { symbols; _ } -> + | Affine { symbols; _ } -> ( (* For affine indices, collect all symbols that are not static *) List.filter_map symbols ~f:(fun (_, s) -> - Option.some_if (not @@ Set.mem static_indices s) s) - |> function [] -> None | [s] -> Some s | _ -> failwith "check_idcs: multiple non-static symbols in affine index") + Option.some_if (not @@ Set.mem static_indices s) s) + |> function + | [] -> None + | [ s ] -> Some s + | _ -> failwith "check_idcs: multiple non-static symbols in affine index")) in let num_syms = Array.count indices ~f:(function Iterator s -> not @@ Set.mem static_indices s | _ -> false) @@ -349,11 +352,13 @@ let%diagn2_sexp check_and_store_virtual traced static_indices top_llc = raise @@ Non_virtual 10) | Embed_index (Affine { symbols; _ }) -> List.iter symbols ~f:(fun (_, s) -> - if not @@ Set.mem env_dom s then ( - if not (Set.mem static_indices s) then - [%log2 - "Inlining candidate has an escaping variable", (s : Indexing.symbol), (top_llc : t)]; - raise @@ Non_virtual 10)) + if not @@ Set.mem env_dom s then ( + if not (Set.mem static_indices s) then + [%log2 + "Inlining candidate has an escaping variable", + (s : Indexing.symbol), + (top_llc : t)]; + raise @@ Non_virtual 10)) | Ternop (_, llv1, llv2, llv3) -> loop_float ~env_dom llv1; loop_float ~env_dom llv2; @@ -686,7 +691,7 @@ let simplify_llc llc = | Get_global _ -> llv | Embed_index (Fixed_idx i) -> Constant (Float.of_int i) | Embed_index (Iterator _) -> llv - | Embed_index (Affine _) -> llv (* Cannot simplify affine expressions to constants *) + | Embed_index (Affine _) -> llv (* Cannot simplify affine expressions to constants *) | Binop (Arg1, llv1, _) -> loop_float llv1 | Binop (Arg2, _, llv2) -> loop_float llv2 | Binop (op, Constant c1, Constant c2) -> Constant (Ops.interpret_binop op c1 c2) File "lib/row.ml", line 1, characters 0-0: diff --git a/_build/default/lib/row.ml b/_build/default/lib/.formatted/row.ml index f924f9d..99ce3e8 100644 --- a/_build/default/lib/row.ml +++ b/_build/default/lib/.formatted/row.ml @@ -23,12 +23,10 @@ type dim_var = Dim_var.t [@@deriving equal, hash, compare, sexp] type dim_cmp = Dim_var.comparator_witness type dim_var_set = Set.M(Dim_var).t [@@deriving equal, sexp] type 'a dim_map = 'a Map.M(Dim_var).t [@@deriving equal, sexp] - type proj_id = int [@@deriving equal, hash, compare, sexp] let dim_var_set_empty = Set.empty (module Dim_var) let dim_map_empty = Map.empty (module Dim_var) - let use_padding = ref false type dim = @@ -56,18 +54,21 @@ let dim_to_string style = function | Dim { d; label = Some l; _ } -> [%string "%{l}=%{d#Int}"] | Var { id; label = Some l } -> [%string "$%{id#Int}:%{l}"] | Var { id; label = None } -> "$" ^ Int.to_string id - | Affine { solved; unsolved } -> - let solved_terms = List.map solved ~f:(fun (coeff, proj_id) -> - if coeff = 1 then [%string "p%{proj_id#Int}"] - else [%string "%{coeff#Int}*p%{proj_id#Int}"]) in - let unsolved_terms = List.map unsolved ~f:(fun (coeff, v) -> - if coeff = 1 then [%string "$%{v.id#Int}"] - else [%string "%{coeff#Int}*$%{v.id#Int}"]) in + | Affine { solved; unsolved } -> ( + let solved_terms = + List.map solved ~f:(fun (coeff, proj_id) -> + if coeff = 1 then [%string "p%{proj_id#Int}"] + else [%string "%{coeff#Int}*p%{proj_id#Int}"]) + in + let unsolved_terms = + List.map unsolved ~f:(fun (coeff, v) -> + if coeff = 1 then [%string "$%{v.id#Int}"] else [%string "%{coeff#Int}*$%{v.id#Int}"]) + in let all_terms = solved_terms @ unsolved_terms in - (match all_terms with - | [] -> "0" - | [t] -> t - | t :: ts -> List.fold ts ~init:t ~f:(fun acc t -> acc ^ "+" ^ t)) + match all_terms with + | [] -> "0" + | [ t ] -> t + | t :: ts -> List.fold ts ~init:t ~f:(fun acc t -> acc ^ "+" ^ t)) module Row_var = struct type t = Row_var of int [@@deriving equal, hash, compare, sexp] @@ -204,15 +205,21 @@ let dim_to_int_exn = function | Var _ -> invalid_arg "dim_to_int: dim still unknown" | Affine _ -> invalid_arg "dim_to_int: affine dimension cannot be converted to single int" -let s_dim_one v ~value ~in_ = match in_ with - | Var v2 when equal_dim_var v v2 -> value +let s_dim_one v ~value ~in_ = + match in_ with + | Var v2 when equal_dim_var v v2 -> value | Affine { solved; unsolved } -> (* Substitute v in affine expression *) - let coeff_of_v = List.fold unsolved ~init:0 ~f:(fun acc (c, v2) -> - if equal_dim_var v v2 then acc + c else acc) in - let new_unsolved = List.filter_map unsolved ~f:(fun (coeff, v2) -> - if equal_dim_var v v2 then None else Some (coeff, v2)) in - let new_solved, extra_unsolved = match value with + let coeff_of_v = + List.fold unsolved ~init:0 ~f:(fun acc (c, v2) -> + if equal_dim_var v v2 then acc + c else acc) + in + let new_unsolved = + List.filter_map unsolved ~f:(fun (coeff, v2) -> + if equal_dim_var v v2 then None else Some (coeff, v2)) + in + let new_solved, extra_unsolved = + match value with | Dim { d; proj_id = Some p; _ } -> (* If substituting with a concrete dim with projection, add to solved *) ((coeff_of_v * d, p) :: solved, new_unsolved) @@ -306,10 +313,10 @@ let reduce_row_constraint (constr : row_constraint) ~(beg_dims : dim list) ~(dim | Total_elems { nominator; divided_by } -> let ds, (vars : dim_var list), has_affine = List.fold (beg_dims @ dims) ~init:([], [], false) ~f:(fun (ds, vars, has_affine) dim -> - match dim with - | Dim { d; _ } -> (d :: ds, vars, has_affine) - | Var v -> (ds, v :: vars, has_affine) - | Affine _ -> (ds, vars, true)) + match dim with + | Dim { d; _ } -> (d :: ds, vars, has_affine) + | Var v -> (ds, v :: vars, has_affine) + | Affine _ -> (ds, vars, true)) in if has_affine then (* Can't reduce constraint with affine dimensions *) @@ -338,7 +345,8 @@ let _lift_row_constraint (constr : row_constraint) ~(beg_dims : dim list) ~(dims List.partition_map (beg_dims @ dims) ~f:(function | Dim { d; _ } -> Either.First d | Var v -> Either.Second v - | Affine _ -> failwith "get_product_proj: affine dimensions not supported in product projections") + | Affine _ -> + failwith "get_product_proj: affine dimensions not supported in product projections") in let vars = Set.of_list (module Dim_var) vars in if not @@ Set.is_subset vars ~of_:divided_by then Unconstrained @@ -413,10 +421,10 @@ let apply_row_constraint ~stage:_ (r : row) (constr : row_constraint) env : cons when Set.length divided_by <= 1 -> ( let (ds : int list), (vars : dim_var list), has_affine = List.fold dims ~init:([], [], false) ~f:(fun (ds, vars, has_affine) dim -> - match dim with - | Dim { d; _ } -> (d :: ds, vars, has_affine) - | Var v -> (ds, v :: vars, has_affine) - | Affine _ -> (ds, vars, true)) + match dim with + | Dim { d; _ } -> (d :: ds, vars, has_affine) + | Var v -> (ds, v :: vars, has_affine) + | Affine _ -> (ds, vars, true)) in if has_affine then (* Can't handle affine dimensions in Total_elems constraint yet *) @@ -440,7 +448,8 @@ let apply_row_constraint ~stage:_ (r : row) (constr : row_constraint) env : cons | [ v ], [] | [], [ v ] -> (Dim_eq { d1 = Var v; d2 = get_dim ~d:nominator () } :: extras, env) | vs1, vs2 when nominator = 1 -> - ( List.map ~f:(fun v -> Dim_eq { d1 = Var v; d2 = get_dim ~d:1 () }) (vs1 @ vs2) @ extras, + ( List.map ~f:(fun v -> Dim_eq { d1 = Var v; d2 = get_dim ~d:1 () }) (vs1 @ vs2) + @ extras, env ) (* TODO: we can work harder making assumptions here if necessary... *) (* | v :: _, [] | [], v :: _ when (is_stage4_up stage) -> (Dim_eq { d1 = Var v; d2 = get_dim @@ -513,10 +522,9 @@ let rec subst_dim env = function | _ -> default) | Affine { solved = _; unsolved } as init -> List.fold unsolved ~init ~f:(fun acc (_coeff, v) -> - match Map.find env.dim_env v with - | Some (Solved_dim d) -> - s_dim_one v ~value:d ~in_:acc - | _ -> acc) + match Map.find env.dim_env v with + | Some (Solved_dim d) -> s_dim_one v ~value:d ~in_:acc + | _ -> acc) let s_row_one v ~value:{ dims = more_dims; bcast; id = _ } ~in_ = match in_ with @@ -609,9 +617,13 @@ let%debug5_sexp rec unify_dim ~stage (eq : dim * dim) (env : environment) : | Affine _, Affine _ -> (* FIXME: For now, we can only unify identical affine expressions *) if equal_dim dim1 dim2 then ([], env) - else raise @@ Shape_error ("Cannot unify different affine dimensions", [ Dim_mismatch [ dim1; dim2 ] ]) + else + raise + @@ Shape_error ("Cannot unify different affine dimensions", [ Dim_mismatch [ dim1; dim2 ] ]) | Affine _, Dim _ | Dim _, Affine _ -> - raise @@ Shape_error ("Cannot unify affine dimension with non-affine", [ Dim_mismatch [ dim1; dim2 ] ]) + raise + @@ Shape_error + ("Cannot unify affine dimension with non-affine", [ Dim_mismatch [ dim1; dim2 ] ]) | Var v, dim2 | dim2, Var v -> let ineqs = ref [] in let f in_ = @@ -824,7 +836,7 @@ let%debug5_sexp solve_dim_ineq ~(stage : stage) ~(cur : dim) ~(subr : dim) (env match Map.find env.dim_env cur_v with | None | Some (Solved_dim (Dim _)) -> false | Some (Solved_dim (Var v)) -> equal_dim_var subr_v v - | Some (Solved_dim (Affine _)) -> false (* Affine dimensions can't be cyclic *) + | Some (Solved_dim (Affine _)) -> false (* Affine dimensions can't be cyclic *) | Some (Bounds_dim { cur = curs; _ }) -> cyclic ~subr_v ~curs) in match (cur, subr) with @@ -1212,7 +1224,7 @@ let%debug5_sexp solve_row_ineq ~(stage : stage) ~(cur : t) ~(subr : t) (env : en | Var _, _ -> d1 | _, Var _ -> d2 | Dim _, Dim _ -> d1 - | Affine _, _ | _, Affine _ -> + | Affine _, _ | _, Affine _ -> failwith "merge_row_constraint: cannot merge constraints with affine dimensions") in let lub = { dims = lub_dims; bcast = lub_bcast; id = lub_id } in @@ -1247,7 +1259,7 @@ let%debug5_sexp close_dim_terminal ~(stage : stage) (env : environment) (dim : d [ Dim_eq { d1 = dim; d2 = lub } ] | _ when not (is_stage4_up stage) -> [ Terminal_dim dim ] | _ -> []) - | Affine _ -> + | Affine _ -> (* FIXME: For affine dimensions, we can't generate simple terminal constraints *) [] @@ -1394,7 +1406,7 @@ let%debug4_sexp solve_inequalities ~(stage : stage) (ineqs : constraint_ list) ( | Some (Bounds_dim bounds) -> Bounds_dim { bounds with constr } | None -> Bounds_dim { constr; lub = None; cur = []; subr = [] }); } - | _, Affine _ -> env (* FIXME: Can't store constraints on affine dimensions *) + | _, Affine _ -> env (* FIXME: Can't store constraints on affine dimensions *) in (extras @ ineqs, env) | Row_constr { r; constr } -> @@ -1450,7 +1462,7 @@ let rec row_to_labels env = match Map.find env.dim_env v with | None | Some (Bounds_dim _) -> Option.value v.label ~default:"" | Some (Solved_dim dim) -> f dim) - | Affine _ -> "" (* Affine dimensions don't have labels *) + | Affine _ -> "" (* Affine dimensions don't have labels *) in function | { dims; bcast = Row_var { v; beg_dims }; id } -> ( @@ -1476,7 +1488,7 @@ let fresh_row_proj r = let fresh_dim = function | Dim { d; label; proj_id = _ } -> Dim { d; label; proj_id = Some (fresh_proj ()) } | Var _ as d -> d - | Affine _ as d -> d (* FIXME: Affine dimensions don't get fresh projections *) + | Affine _ as d -> d (* FIXME: Affine dimensions don't get fresh projections *) in { r with dims = List.map r.dims ~f:fresh_dim } @@ -1673,7 +1685,7 @@ let get_product_proj proj_env dim = ( "projection_of_solved_dims: still not fully inferred for variable " ^ Sexp.to_string_hum ([%sexp_of: dim_var] v), [ Dim_mismatch [ dim ] ] ) - | Affine _ -> None (* FIXME: Affine dimensions don't participate in product projections *) + | Affine _ -> None (* FIXME: Affine dimensions don't participate in product projections *) let proj_to_iterator proj_env p = match Map.find_exn proj_env.proj_to_index (proj_repr proj_env p) with dune build @fmt failed "/usr/bin/env" "bash" "-c" "opam exec -- dune build @fmt --ignore-promoted-rules || (echo "dune build @fmt failed"; exit 2)" failed with exit status 2 2025-06-05 10:52.46: Job failed: Failed: Build failed