Skip to content

Instantly share code, notes, and snippets.

@dinosaure
Created April 2, 2019 13:35
Show Gist options
  • Save dinosaure/33f4177c627ecfb704dcd4024fe3a7f1 to your computer and use it in GitHub Desktop.
Save dinosaure/33f4177c627ecfb704dcd4024fe3a7f1 to your computer and use it in GitHub Desktop.
let () = Printexc.record_backtrace true
type t =
{ dims : int array
; memory : int * int } (* absolute position * absolute position *)
let ptr t = fst t.memory
let len t = snd t.memory - fst t.memory
let dims t = Array.length t.dims
let overlap a b =
let src_a = ptr a in
let src_b = ptr b in
let len_a = len a in
let len_b = len b in
let len = max 0 ((min (src_a + len_a) (src_b + len_b)) - (max src_a src_b)) in
if src_a >= src_b && src_a < src_b + len_b
then
( let off = ref (src_b + (src_a - src_b)) in
let dim0 = Array.make (dims a) 0 in
let dim1 = Array.make (dims b) 0 in
for i = (dims b) - 1 downto 0 do
dim1.(i) <- !off mod b.dims.(i);
off := !off / b.dims.(i);
done;
Some (len, dim0, dim1) )
else if src_b >= src_a && src_b < src_a + len_a
then
( let off = ref (src_a + (src_b - src_a)) in
let dim0 = Array.make (dims a) 0 in
let dim1 = Array.make (dims b) 0 in
for i = (dims a) - 1 downto 0 do
dim0.(i) <- !off mod a.dims.(i);
off := !off / a.dims.(i);
done;
Some (len, dim0, dim1) )
else None
let v ~dims v =
let len' = Array.fold_right ( * ) dims 1 in
assert (len' = (snd v - fst v)) ;
{ dims; memory= v; }
(* [caml_ba_offset] *)
let dims_to_ptr t dims =
let offset = ref 0 in
for i = 0 to Array.length t.dims - 1
do offset := !offset * t.dims.(i) + dims.(i) done;
ptr t + !offset
let o1 = assert ((overlap (v ~dims:[||] (0, 1)) (v ~dims:[||] (1, 2))) = None)
let o2 = assert ((overlap (v ~dims:[||] (0, 1)) (v ~dims:[||] (0, 1))) = Some (1, [||], [||]))
let o3 = assert ((overlap (v ~dims:[|10|] (0, 10)) (v ~dims:[|5|] (5, 10))) = Some (5, [|5|], [|0|]))
let o4 = assert ((overlap (v ~dims:[|5|] (5, 10)) (v ~dims:[|10|] (0, 10))) = Some (5, [|0|], [|5|]))
let o5 = assert ((overlap (v ~dims:[|5|] (0, 5)) (v ~dims:[|5|] (5, 10))) = None)
let o6 = assert ((overlap (v ~dims:[|5|] (0, 5)) (v ~dims:[|5|] (0, 5))) = Some (5, [|0|], [|0|]))
let o7 = assert ((overlap (v ~dims:[|10|] (0, 10)) (v ~dims:[|10|] (5, 15))) = Some (5, [|5|], [|0|]))
let o7 = assert ((overlap (v ~dims:[|10|] (5, 15)) (v ~dims:[|10|] (0, 10))) = Some (5, [|0|], [|5|]))
let o8 = assert ((overlap (v ~dims:[|10; 10|] (0, 100)) (v ~dims:[|10; 10|] (50, 150))) = Some (50, [|5; 0|], [|0; 0|]))
let o9 = assert ((overlap (v ~dims:[|10; 10|] (0, 100))) (v ~dims:[|10; 10|] (100, 200)) = None)
let o10 = assert ((overlap (v ~dims:[|10; 10|] (0, 100)) (v ~dims:[|10; 10|] (25, 125))) = Some (75, [|2; 5|], [|0; 0|]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment