diff --git a/bytecomp/bytegen.ml b/bytecomp/bytegen.ml index 3766aa0315d..3691b1f0515 100644 --- a/bytecomp/bytegen.ml +++ b/bytecomp/bytegen.ml @@ -685,7 +685,10 @@ let comp_primitive stack_info p sz args = "Preinterpret_unboxed_int64_as_tagged_int63 can only be used on 64-bit \ targets"; Kccall("caml_reinterpret_unboxed_int64_as_tagged_int63", 1) - | Pmakearray_dynamic(kind, locality) -> + | Pmakearray_dynamic(kind, locality, With_initializer) -> + if List.compare_length_with args 2 <> 0 then + fatal_error "Bytegen.comp_primitive: Pmakearray_dynamic takes two \ + arguments for [With_initializer]"; (* CR layouts v4.0: This is "wrong" for unboxed types. It should construct blocks that can't be marshalled. We've decided to ignore that problem in the short term, as it's unlikely to cause issues - see the internal arrays @@ -701,8 +704,8 @@ let comp_primitive stack_info p sz args = | Alloc_heap -> Kccall("caml_make_vect", 2) | Alloc_local -> Kccall("caml_make_local_vect", 2) end - | Parrayblit(kind) -> - begin match kind with + | Parrayblit { src_mutability = _; dst_array_set_kind } -> + begin match dst_array_set_kind with | Punboxedvectorarray_set _ -> fatal_error "SIMD is not supported in bytecode mode." | Pgenarray_set _ | Pintarray_set | Paddrarray_set _ @@ -710,6 +713,9 @@ let comp_primitive stack_info p sz args = | Pgcscannableproductarray_set _ | Pgcignorableproductarray_set _ -> () end; Kccall("caml_array_blit", 5) + | Pmakearray_dynamic(_, _, Uninitialized) -> + Misc.fatal_error "Pmakearray_dynamic Uninitialized should have been \ + translated to Pmakearray_dynamic Initialized earlier on" (* The cases below are handled in [comp_expr] before the [comp_primitive] call (in the order in which they appear below), so they should never be reached in this function. *) @@ -1011,6 +1017,54 @@ and comp_expr stack_info env exp sz cont = (Kreperformterm(sz + nargs) :: discard_dead_code cont) else fatal_error "Reperform used in non-tail position" + | Lprim (Pmakearray_dynamic (kind, locality, Uninitialized), [len], loc) -> + (* Use a dummy initializer to implement the "uninitialized" primitive *) + let init = + match kind with + | Pgenarray | Paddrarray | Pintarray | Pfloatarray + | Pgcscannableproductarray _ -> + Misc.fatal_errorf "Array kind %s should have been ruled out by \ + the frontend for %%makearray_dynamic_uninit" + (Printlambda.array_kind kind) + | Punboxedfloatarray Unboxed_float32 -> + Lconst (Const_base (Const_float32 "0.0")) + | Punboxedfloatarray Unboxed_float64 -> + Lconst (Const_base (Const_float "0.0")) + | Punboxedintarray Unboxed_int32 -> + Lconst (Const_base (Const_int32 0l)) + | Punboxedintarray Unboxed_int64 -> + Lconst (Const_base (Const_int64 0L)) + | Punboxedintarray Unboxed_nativeint -> + Lconst (Const_base (Const_nativeint 0n)) + | Punboxedvectorarray _ -> + fatal_error "SIMD is not supported in bytecode mode." + | Pgcignorableproductarray ignorables -> + let rec convert_ignorable + (ign : Lambda.ignorable_product_element_kind) = + match ign with + | Pint_ignorable -> Lconst (Const_base (Const_int 0)) + | Punboxedfloat_ignorable Unboxed_float32 -> + Lconst (Const_base (Const_float32 "0.0")) + | Punboxedfloat_ignorable Unboxed_float64 -> + Lconst (Const_base (Const_float "0.0")) + | Punboxedint_ignorable Unboxed_int32 -> + Lconst (Const_base (Const_int32 0l)) + | Punboxedint_ignorable Unboxed_int64 -> + Lconst (Const_base (Const_int64 0L)) + | Punboxedint_ignorable Unboxed_nativeint -> + Lconst (Const_base (Const_nativeint 0n)) + | Pproduct_ignorable ignorables -> + let fields = List.map convert_ignorable ignorables in + Lprim (Pmakeblock (0, Immutable, None, alloc_heap), fields, + loc) + in + convert_ignorable (Pproduct_ignorable ignorables) + in + comp_expr stack_info env + (Lprim (Pmakearray_dynamic (kind, locality, With_initializer), + [len; init], loc)) sz cont + | Lprim (Pmakearray_dynamic (_, _, Uninitialized), _, _loc) -> + Misc.fatal_error "Pmakearray_dynamic takes one arg when [Uninitialized]" | Lprim (Pduparray (kind, mutability), [Lprim (Pmakearray (kind',_,m),args,_)], loc) -> assert (kind = kind'); diff --git a/lambda/lambda.ml b/lambda/lambda.ml index a151ee51b1d..d5bc289e09a 100644 --- a/lambda/lambda.ml +++ b/lambda/lambda.ml @@ -43,6 +43,10 @@ type field_read_semantics = | Reads_agree | Reads_vary +type has_initializer = + | With_initializer + | Uninitialized + include (struct type locality_mode = @@ -189,9 +193,12 @@ type primitive = | Pbyteslength | Pbytesrefu | Pbytessetu | Pbytesrefs | Pbytessets (* Array operations *) | Pmakearray of array_kind * mutable_flag * locality_mode - | Pmakearray_dynamic of array_kind * locality_mode + | Pmakearray_dynamic of array_kind * locality_mode * has_initializer | Pduparray of array_kind * mutable_flag - | Parrayblit of array_set_kind (* Kind of the dest array. *) + | Parrayblit of { + src_mutability : mutable_flag; + dst_array_set_kind : array_set_kind; + } | Parraylength of array_kind | Parrayrefu of array_ref_kind * array_index_kind * mutable_flag | Parraysetu of array_set_kind * array_index_kind @@ -944,6 +951,10 @@ let lfunction ~kind ~params ~return ~body ~attr ~loc ~mode ~ret_mode ~region = let lambda_unit = Lconst const_unit +let of_bool = function + | true -> Lconst (const_int 1) + | false -> Lconst (const_int 0) + (* CR vlaviron: review the following cases *) let non_null_value raw_kind = Pvalue { raw_kind; nullable = Non_nullable } @@ -1819,7 +1830,7 @@ let primitive_may_allocate : primitive -> locality_mode option = function | Pstringlength | Pstringrefu | Pstringrefs | Pbyteslength | Pbytesrefu | Pbytessetu | Pbytesrefs | Pbytessets -> None | Pmakearray (_, _, m) -> Some m - | Pmakearray_dynamic (_, m) -> Some m + | Pmakearray_dynamic (_, m, _) -> Some m | Pduparray _ -> Some alloc_heap | Parraylength _ -> None | Parrayblit _ @@ -2388,6 +2399,21 @@ let array_set_kind mode = function | Pgcscannableproductarray kinds -> Pgcscannableproductarray_set (mode, kinds) | Pgcignorableproductarray kinds -> Pgcignorableproductarray_set kinds +let array_ref_kind_of_array_set_kind (kind : array_set_kind) mode + : array_ref_kind = + match kind with + | Pintarray_set -> Pintarray_ref + | Punboxedfloatarray_set uf -> Punboxedfloatarray_ref uf + | Punboxedintarray_set ui -> Punboxedintarray_ref ui + | Punboxedvectorarray_set uv -> Punboxedvectorarray_ref uv + | Pgcscannableproductarray_set (_, scannables) -> + Pgcscannableproductarray_ref scannables + | Pgcignorableproductarray_set ignorables -> + Pgcignorableproductarray_ref ignorables + | Pgenarray_set _ -> Pgenarray_ref mode + | Paddrarray_set _ -> Paddrarray_ref + | Pfloatarray_set -> Pfloatarray_ref mode + let may_allocate_in_region lam = (* loop_region raises, if the lambda might allocate in parent region *) let rec loop_region lam = @@ -2479,3 +2505,42 @@ let rec try_to_find_location lam = let try_to_find_debuginfo lam = Debuginfo.from_location (try_to_find_location lam) + +let rec count_initializers_scannable + (scannable : scannable_product_element_kind) = + match scannable with + | Pint_scannable | Paddr_scannable -> 1 + | Pproduct_scannable scannables -> + List.fold_left + (fun acc scannable -> acc + count_initializers_scannable scannable) + 0 scannables + +let rec count_initializers_ignorable + (ignorable : ignorable_product_element_kind) = + match ignorable with + | Pint_ignorable | Punboxedfloat_ignorable _ | Punboxedint_ignorable _ -> 1 + | Pproduct_ignorable ignorables -> + List.fold_left + (fun acc ignorable -> acc + count_initializers_ignorable ignorable) + 0 ignorables + +let count_initializers_array_kind (lambda_array_kind : array_kind) = + match lambda_array_kind with + | Pgenarray | Paddrarray | Pintarray | Pfloatarray | Punboxedfloatarray _ + | Punboxedintarray _ | Punboxedvectorarray _ -> 1 + | Pgcscannableproductarray scannables -> + List.fold_left + (fun acc scannable -> acc + count_initializers_scannable scannable) + 0 scannables + | Pgcignorableproductarray ignorables -> + List.fold_left + (fun acc ignorable -> acc + count_initializers_ignorable ignorable) + 0 ignorables + +let rec ignorable_product_element_kind_involves_int + (kind : ignorable_product_element_kind) = + match kind with + | Pint_ignorable -> true + | Punboxedfloat_ignorable _ | Punboxedint_ignorable _ -> false + | Pproduct_ignorable kinds -> + List.exists ignorable_product_element_kind_involves_int kinds diff --git a/lambda/lambda.mli b/lambda/lambda.mli index f72780dda1c..31a90c4434e 100644 --- a/lambda/lambda.mli +++ b/lambda/lambda.mli @@ -74,6 +74,10 @@ type field_read_semantics = | Reads_agree | Reads_vary +type has_initializer = + | With_initializer + | Uninitialized + (* Tail calls can close their enclosing region early *) type region_close = | Rc_normal (* do not close region, may TCO if in tail position *) @@ -178,15 +182,21 @@ type primitive = | Pbyteslength | Pbytesrefu | Pbytessetu | Pbytesrefs | Pbytessets (* Array operations *) | Pmakearray of array_kind * mutable_flag * locality_mode - | Pmakearray_dynamic of array_kind * locality_mode + | Pmakearray_dynamic of array_kind * locality_mode * has_initializer + (** For [Pmakearray_dynamic], if the array kind specifies an unboxed + product, the float array optimization will never apply. *) | Pduparray of array_kind * mutable_flag (** For [Pduparray], the argument must be an immutable array. The arguments of [Pduparray] give the kind and mutability of the array being *produced* by the duplication. *) - | Parrayblit of array_set_kind + | Parrayblit of { + src_mutability : mutable_flag; + dst_array_set_kind : array_set_kind; + } (** For [Parrayblit], we record the [array_set_kind] of the destination array. We check that the source array has the same shape, but do not - need to know anything about its locality. *) + need to know anything about its locality. We do however request the + mutability of the source array. *) | Parraylength of array_kind | Parrayrefu of array_ref_kind * array_index_kind * mutable_flag | Parraysetu of array_set_kind * array_index_kind @@ -914,6 +924,8 @@ val const_unit: structured_constant val const_int : int -> structured_constant val lambda_unit: lambda +val of_bool : bool -> lambda + val layout_unit : layout val layout_int : layout val layout_array : array_kind -> layout @@ -1158,6 +1170,11 @@ val array_ref_kind : locality_mode -> array_kind -> array_ref_kind (** The mode will be discarded if unnecessary for the given [array_kind] *) val array_set_kind : modify_mode -> array_kind -> array_set_kind +(** Any mode information in the given [array_set_kind] is ignored. Any mode + in the return value always comes from the [locality_mode] parameter. *) +val array_ref_kind_of_array_set_kind + : array_set_kind -> locality_mode -> array_ref_kind + (* Returns true if the given lambda can allocate on the local stack *) val may_allocate_in_region : lambda -> bool @@ -1173,3 +1190,7 @@ val try_to_find_location : lambda -> scoped_location val try_to_find_debuginfo : lambda -> Debuginfo.t val primitive_can_raise : primitive -> bool + +val count_initializers_array_kind : array_kind -> int +val ignorable_product_element_kind_involves_int : + ignorable_product_element_kind -> bool diff --git a/lambda/printlambda.ml b/lambda/printlambda.ml index ed0e1326695..74cd27a3e1b 100644 --- a/lambda/printlambda.ml +++ b/lambda/printlambda.ml @@ -668,14 +668,20 @@ let primitive ppf = function | Pmakearray (k, Immutable_unique, mode) -> fprintf ppf "make%sarray_unique[%s]" (locality_mode_if_local mode) (array_kind k) - | Pmakearray_dynamic (k, mode) -> - fprintf ppf "make%sarray_any[%s]" (locality_mode_if_local mode) + | Pmakearray_dynamic (k, mode, has_init) -> + fprintf ppf "make%sarray_any[%s]%s" (locality_mode_if_local mode) (array_kind k) + (match has_init with + | With_initializer -> "" + | Uninitialized -> "[uninit]") | Pduparray (k, Mutable) -> fprintf ppf "duparray[%s]" (array_kind k) | Pduparray (k, Immutable) -> fprintf ppf "duparray_imm[%s]" (array_kind k) | Pduparray (k, Immutable_unique) -> fprintf ppf "duparray_unique[%s]" (array_kind k) - | Parrayblit sk -> fprintf ppf "arrayblit[%a]" array_set_kind sk + | Parrayblit { src_mutability; dst_array_set_kind } -> + fprintf ppf "arrayblit[%s -> %a]" + (array_mut src_mutability) + array_set_kind dst_array_set_kind | Parrayrefu (rk, idx, mut) -> fprintf ppf "%s.unsafe_get[%a indexed by %a]" (array_mut mut) array_ref_kind rk diff --git a/lambda/printlambda.mli b/lambda/printlambda.mli index fc4b898a224..05bb1f49f1d 100644 --- a/lambda/printlambda.mli +++ b/lambda/printlambda.mli @@ -44,6 +44,7 @@ val print_bigarray : val zero_alloc_attribute : formatter -> zero_alloc_attribute -> unit val locality_mode : formatter -> locality_mode -> unit val array_kind : array_kind -> string +val array_set_kind : formatter -> array_set_kind -> unit val tag_and_constructor_shape : (formatter -> value_kind -> unit) -> diff --git a/lambda/translprim.ml b/lambda/translprim.ml index 109651c043c..770a4f8ecc1 100644 --- a/lambda/translprim.ml +++ b/lambda/translprim.ml @@ -30,6 +30,7 @@ type error = | Wrong_arity_builtin_primitive of string | Invalid_floatarray_glb | Product_iarrays_unsupported + | Invalid_array_kind_for_uninitialized_makearray_dynamic exception Error of Location.t * error @@ -45,6 +46,18 @@ let unboxed_product_iarray_check loc kind mut = | Punboxedintarray _ | Punboxedvectorarray _), _ -> () +let unboxed_product_uninitialized_array_check loc array_kind = + (* See comments in lambda_to_lambda_transforms.ml in Flambda 2 for more + details on this restriction. *) + match array_kind with + | Pgcignorableproductarray igns + when not (List.exists + Lambda.ignorable_product_element_kind_involves_int igns) -> () + | Punboxedfloatarray _ | Punboxedintarray _ | Punboxedvectorarray _ -> + () + | Pgenarray | Paddrarray | Pintarray | Pfloatarray + | Pgcscannableproductarray _ | Pgcignorableproductarray _ -> + raise (Error (loc, Invalid_array_kind_for_uninitialized_makearray_dynamic)) (* Insertion of debugging events *) @@ -531,11 +544,23 @@ let lookup_primitive loc ~poly_mode ~poly_sort pos p = (gen_array_set_kind (get_first_arg_mode ()), Punboxed_int_index Unboxed_nativeint)), 3) | "%makearray_dynamic" -> - Language_extension.assert_enabled ~loc Layouts Language_extension.Alpha; - Primitive (Pmakearray_dynamic (gen_array_kind, mode), 2) + Language_extension.assert_enabled ~loc Layouts Language_extension.Beta; + Primitive (Pmakearray_dynamic (gen_array_kind, mode, With_initializer), 2) + | "%makearray_dynamic_uninit" -> + Language_extension.assert_enabled ~loc Layouts Language_extension.Beta; + Primitive (Pmakearray_dynamic (gen_array_kind, mode, Uninitialized), 1) | "%arrayblit" -> - Language_extension.assert_enabled ~loc Layouts Language_extension.Alpha; - Primitive (Parrayblit (gen_array_set_kind (get_third_arg_mode ())), 5) + Language_extension.assert_enabled ~loc Layouts Language_extension.Beta; + Primitive (Parrayblit { + src_mutability = Mutable; + dst_array_set_kind = gen_array_set_kind (get_third_arg_mode ()) + }, 5); + | "%arrayblit_src_immut" -> + Language_extension.assert_enabled ~loc Layouts Language_extension.Beta; + Primitive (Parrayblit { + src_mutability = Immutable; + dst_array_set_kind = gen_array_set_kind (get_third_arg_mode ()) + }, 5); | "%obj_size" -> Primitive ((Parraylength Pgenarray), 1) | "%obj_field" -> Primitive ((Parrayrefu (Pgenarray_ref mode, Ptagged_int_index, Mutable)), 2) | "%obj_set_field" -> @@ -1229,19 +1254,40 @@ let specialize_primitive env loc ty ~has_constant_constructor prim = if st = array_set_type then None else Some (Primitive (Parraysets (array_set_type, index_kind), arity)) end - | Primitive (Pmakearray_dynamic (at, mode), arity), - _ :: p2 :: _ -> begin + | Primitive (Pmakearray_dynamic (array_kind, mode, With_initializer), 2), + _ :: p2 :: [] -> begin let loc = to_location loc in - let array_type = - glb_array_type loc at - (array_kind_of_elt ~elt_sort:None env loc p2) + let new_array_kind = + array_kind_of_elt ~elt_sort:None env loc p2 + |> glb_array_type loc array_kind in let array_mut = array_type_mut env rest_ty in - unboxed_product_iarray_check loc array_type array_mut; - if at = array_type then None - else Some (Primitive (Pmakearray_dynamic (array_type, mode), arity)) + unboxed_product_iarray_check loc new_array_kind array_mut; + if array_kind = new_array_kind then None + else + Some (Primitive (Pmakearray_dynamic ( + new_array_kind, mode, With_initializer), 2)) end - | Primitive (Parrayblit st, arity), + | Primitive (Pmakearray_dynamic (array_kind, mode, Uninitialized), 1), + _ :: [] -> begin + let loc = to_location loc in + let new_array_kind = + array_type_kind ~elt_sort:None env loc rest_ty + |> glb_array_type loc array_kind + in + let array_mut = array_type_mut env rest_ty in + unboxed_product_iarray_check loc new_array_kind array_mut; + unboxed_product_uninitialized_array_check loc new_array_kind; + if array_kind = new_array_kind then None + else + Some (Primitive (Pmakearray_dynamic ( + new_array_kind, mode, Uninitialized), 1)) + end + | Primitive (Pmakearray_dynamic _, arity), args -> + Misc.fatal_errorf + "Wrong arity for Pmakearray_dynamic (arity=%d, args length %d)" + arity (List.length args) + | Primitive (Parrayblit { src_mutability; dst_array_set_kind }, arity), _p1 :: _ :: p2 :: _ -> let loc = to_location loc in (* We only use the kind of one of two input arrays here. If you've bound the @@ -1249,11 +1295,13 @@ let specialize_primitive env loc ty ~has_constant_constructor prim = kind. If you haven't, then taking the glb of both would be just as likely to compound your error (e.g., by treating a Pgenarray as a Pfloatarray) as to help you. *) - let array_type = - glb_array_set_type loc st (array_type_kind ~elt_sort:None env loc p2) + let array_kind = array_type_kind ~elt_sort:None env loc p2 in + let new_dst_array_set_kind = + glb_array_set_type loc dst_array_set_kind array_kind in - if st = array_type then None - else Some (Primitive (Parrayblit array_type, arity)) + if dst_array_set_kind = new_dst_array_set_kind then None + else Some (Primitive (Parrayblit { + src_mutability; dst_array_set_kind = new_dst_array_set_kind }, arity)) | Primitive (Pbigarrayref(unsafe, n, kind, layout), arity), p1 :: _ -> begin let (k, l) = bigarray_specialize_kind_and_layout env ~kind ~layout p1 in match k, l with @@ -1733,7 +1781,7 @@ let lambda_primitive_needs_event_after = function | Pmulfloat (_, _) | Pdivfloat (_, _) | Pstringrefs | Pbytesrefs | Pbytessets | Pmakearray (Pgenarray, _, _) | Pduparray _ - | Pmakearray_dynamic (Pgenarray, _) + | Pmakearray_dynamic (Pgenarray, _, _) | Parrayrefu ((Pgenarray_ref _ | Pfloatarray_ref _), _, _) | Parrayrefs _ | Parraysets _ | Pbintofint _ | Pcvtbint _ | Pnegbint _ | Paddbint _ | Psubbint _ | Pmulbint _ | Pdivbint _ | Pmodbint _ | Pandbint _ @@ -1783,7 +1831,7 @@ let lambda_primitive_needs_event_after = function | Pmakearray_dynamic ((Pintarray | Paddrarray | Pfloatarray | Punboxedfloatarray _ | Punboxedintarray _ | Punboxedvectorarray _ - | Pgcscannableproductarray _ | Pgcignorableproductarray _), _) + | Pgcscannableproductarray _ | Pgcignorableproductarray _), _, _) | Parrayblit _ | Parraylength _ | Parrayrefu _ | Parraysetu _ | Pisint _ | Pisnull | Pisout | Pprobe_is_enabled _ @@ -1857,6 +1905,11 @@ let report_error ppf = function | Product_iarrays_unsupported -> fprintf ppf "Immutable arrays of unboxed products are not yet supported." + | Invalid_array_kind_for_uninitialized_makearray_dynamic -> + fprintf ppf + "%%makearray_dynamic_uninit can only be used for GC-ignorable arrays@ \ + not involving tagged immediates; and arrays of unboxed numbers.@ Use \ + %%makearray instead, providing an initializer." let () = Location.register_error_of_exn diff --git a/lambda/translprim.mli b/lambda/translprim.mli index 10916122801..2f58c381370 100644 --- a/lambda/translprim.mli +++ b/lambda/translprim.mli @@ -64,6 +64,7 @@ type error = | Wrong_arity_builtin_primitive of string | Invalid_floatarray_glb | Product_iarrays_unsupported + | Invalid_array_kind_for_uninitialized_makearray_dynamic exception Error of Location.t * error diff --git a/middle_end/flambda2/from_lambda/closure_conversion.ml b/middle_end/flambda2/from_lambda/closure_conversion.ml index 00f1f447c81..eac97e6e665 100644 --- a/middle_end/flambda2/from_lambda/closure_conversion.ml +++ b/middle_end/flambda2/from_lambda/closure_conversion.ml @@ -993,19 +993,18 @@ let close_primitive acc env ~let_bound_ids_with_kinds named | Pmakearray (array_kind, _, _mode) -> let array_kind = Empty_array_kind.of_lambda array_kind in register_const0 acc (Static_const.empty_array array_kind) "empty_array" - | Pmakearray_dynamic (_array_kind, _mode) -> - Misc.fatal_error "Closure_conversion.close_primitive: unimplemented" | Parrayblit _array_set_kind -> Misc.fatal_error "Closure_conversion.close_primitive: unimplemented" - | Pbytes_to_string | Pbytes_of_string | Parray_of_iarray - | Parray_to_iarray | Pignore | Pgetglobal _ | Psetglobal _ | Pgetpredef _ - | Pfield _ | Pfield_computed _ | Psetfield _ | Psetfield_computed _ - | Pfloatfield _ | Psetfloatfield _ | Pduprecord _ | Pccall _ | Praise _ - | Pufloatfield _ | Psetufloatfield _ | Psequand | Psequor | Pnot | Pnegint - | Pmixedfield _ | Psetmixedfield _ | Paddint | Psubint | Pmulint - | Pdivint _ | Pmodint _ | Pandint | Porint | Pxorint | Plslint | Plsrint - | Pasrint | Pintcomp _ | Pcompare_ints | Pcompare_floats _ - | Pcompare_bints _ | Poffsetint _ | Poffsetref _ | Pintoffloat _ + | Pmakearray_dynamic _ | Pbytes_to_string | Pbytes_of_string + | Parray_of_iarray | Parray_to_iarray | Pignore | Pgetglobal _ + | Psetglobal _ | Pgetpredef _ | Pfield _ | Pfield_computed _ | Psetfield _ + | Psetfield_computed _ | Pfloatfield _ | Psetfloatfield _ | Pduprecord _ + | Pccall _ | Praise _ | Pufloatfield _ | Psetufloatfield _ | Psequand + | Psequor | Pnot | Pnegint | Pmixedfield _ | Psetmixedfield _ | Paddint + | Psubint | Pmulint | Pdivint _ | Pmodint _ | Pandint | Porint | Pxorint + | Plslint | Plsrint | Pasrint | Pintcomp _ | Pcompare_ints + | Pcompare_floats _ | Pcompare_bints _ | Poffsetint _ | Poffsetref _ + | Pintoffloat _ | Pfloatofint (_, _) | Pfloatoffloat32 _ | Pfloat32offloat _ | Pnegfloat (_, _) diff --git a/middle_end/flambda2/from_lambda/lambda_to_flambda.ml b/middle_end/flambda2/from_lambda/lambda_to_flambda.ml index 3f232bb6643..80c5b51a1cd 100644 --- a/middle_end/flambda2/from_lambda/lambda_to_flambda.ml +++ b/middle_end/flambda2/from_lambda/lambda_to_flambda.ml @@ -535,7 +535,10 @@ let rec cps acc env ccenv (lam : L.lambda) (k : cps_continuation) id, Lprim (prim, args, loc), body ) -> ( - match Lambda_to_lambda_transforms.transform_primitive env prim args loc with + let env, result = + Lambda_to_lambda_transforms.transform_primitive env prim args loc + in + match result with | Primitive (prim, args, loc) -> (* This case avoids extraneous continuations. *) let exn_continuation : IR.exn_continuation option = diff --git a/middle_end/flambda2/from_lambda/lambda_to_flambda_primitives.ml b/middle_end/flambda2/from_lambda/lambda_to_flambda_primitives.ml index a7a1494fa94..a87be38e3f8 100644 --- a/middle_end/flambda2/from_lambda/lambda_to_flambda_primitives.ml +++ b/middle_end/flambda2/from_lambda/lambda_to_flambda_primitives.ml @@ -814,13 +814,48 @@ let bytes_like_set ~dbg ~unsafe (* Array bounds checks *) +(* The following function constructs bounds checks based on two things: + + 1. The array length kind, which specifies the representation of the array, + including any unboxed product types. This kind is used to establish the + starting field index in the runtime value where the access(es) is/are going + to occur, in addition to how many fields are going to be accessed at a + minimum. "How many fields" is always one except in the case where unboxed + products are involved: in such cases, more than one field may be accessed. + "At a minimum" only applies for vector reinterpret operations as described + next; in all other cases this number is exact. + + 2. The [num_consecutive_elements_being_accessed]. "Elements" here refers to + the non-unarized elements as the user sees via the array get/set primitives. + This value is always 1 except in the case where the array operation is in + fact really a reinterpret operation with a vector input or output (for + example an array of naked floats being read as a 128-bit vector of such + floats). In these latter cases the value of + [num_consecutive_elements_being_accessed] may be greater than 1. This value + may not be greater than 1 if unboxed products are involved, at present. *) + +(* CR mshinwell: When considering vectors and unboxed products, we should think + again about whether the abstractions/concepts here can be improved. *) let multiple_word_array_access_validity_condition array ~size_int - array_length_kind (index_kind : L.array_index_kind) ~width_in_scalars ~index - = + array_length_kind (index_kind : L.array_index_kind) + ~num_consecutive_elements_being_accessed ~index = + let width_in_scalars_per_access = + P.Array_kind_for_length.width_in_scalars array_length_kind + in + assert (width_in_scalars_per_access >= 1); let length_tagged = H.Prim (Unary (Array_length array_length_kind, array)) in - if width_in_scalars < 1 - then Misc.fatal_errorf "Invalid width_in_scalars value: %d" width_in_scalars - else if width_in_scalars = 1 + if num_consecutive_elements_being_accessed < 1 + then + Misc.fatal_errorf + "Invalid num_consecutive_elements_being_accessed value: %d" + num_consecutive_elements_being_accessed + else if width_in_scalars_per_access > 1 + && num_consecutive_elements_being_accessed > 1 + then + Misc.fatal_error + "Unboxed product arrays cannot involve vector accesses at present" + else if width_in_scalars_per_access = 1 + && num_consecutive_elements_being_accessed = 1 then (* Ensure good code generation in the common case. *) check_bound ~index_kind ~bound_kind:Tagged_immediate ~index @@ -828,13 +863,19 @@ let multiple_word_array_access_validity_condition array ~size_int else let length_untagged = untag_int length_tagged in let reduced_length_untagged = - H.Prim - (Binary - ( Int_arith (Naked_immediate, Sub), - length_untagged, - Simple - (Simple.untagged_const_int - (Targetint_31_63.of_int (width_in_scalars - 1))) )) + if num_consecutive_elements_being_accessed = 1 + then length_untagged + else + (* This is used for vector accesses, where no unarization is + involved. *) + H.Prim + (Binary + ( Int_arith (Naked_immediate, Sub), + length_untagged, + Simple + (Simple.untagged_const_int + (Targetint_31_63.of_int + (num_consecutive_elements_being_accessed - 1))) )) in (* We need to convert the length into a naked_nativeint because the optimised version of the max_with_zero function needs to be on @@ -847,34 +888,21 @@ let multiple_word_array_access_validity_condition array ~size_int reduced_length_untagged )) in let nativeint_bound = max_with_zero ~size_int reduced_length_nativeint in - let index : H.simple_or_prim = - (* [length_tagged] is in units of scalars. Multiply up [index] to - match. *) - let multiplier = - P.Array_kind_for_length.width_in_scalars array_length_kind - in - let arith_kind, multiplier = - match index_kind with - | Ptagged_int_index -> - ( I.Tagged_immediate, - Simple.const_int (Targetint_31_63.of_int multiplier) ) - | Punboxed_int_index bint -> ( - match bint with - | Unboxed_int32 -> - ( I.Naked_int32, - Simple.const - (Reg_width_const.naked_int32 (Int32.of_int multiplier)) ) - | Unboxed_int64 -> - ( I.Naked_int64, - Simple.const - (Reg_width_const.naked_int64 (Int64.of_int multiplier)) ) - | Unboxed_nativeint -> - ( I.Naked_nativeint, - Simple.const - (Reg_width_const.naked_nativeint - (Targetint_32_64.of_int multiplier)) )) - in - Prim (Binary (Int_arith (arith_kind, Mul), index, Simple multiplier)) + let nativeint_bound : H.simple_or_prim = + if width_in_scalars_per_access = 1 + then nativeint_bound + else + (* This is used for unboxed product accesses. [index] is in non-unarized + terms and we don't touch it, to avoid risks of overflow. Instead we + compute the non-unarized bound, then compare against that. *) + Prim + (Binary + ( Int_arith (Naked_nativeint, Div), + nativeint_bound, + Simple + (Simple.const + (Reg_width_const.naked_nativeint + (Targetint_32_64.of_int width_in_scalars_per_access))) )) in check_bound ~index_kind ~bound_kind:Naked_nativeint ~index ~bound:nativeint_bound @@ -883,25 +911,25 @@ let multiple_word_array_access_validity_condition array ~size_int (* CR mshinwell: it seems like these could be folded into the normal array load/store functions below *) -let array_vector_access_width_in_scalars (array_kind : P.Array_kind.t) = - match array_kind with - | Naked_vec128s -> 1 - | Naked_floats | Immediates | Naked_int64s | Naked_nativeints -> 2 - | Naked_int32s | Naked_float32s -> 4 - | Values -> - Misc.fatal_error - "Attempted to load/store a SIMD vector from/to a value array." - | Unboxed_product _ -> - (* CR mshinwell: support unboxed products involving vectors? *) - Misc.fatal_error - "Attempted to load/store a SIMD vector from/to an unboxed product array, \ - which is not yet supported." - let array_vector_access_validity_condition array ~size_int (array_kind : P.Array_kind.t) index = - let width_in_scalars = array_vector_access_width_in_scalars array_kind in + let num_consecutive_elements_being_accessed = + match array_kind with + | Naked_vec128s -> 1 + | Naked_floats | Immediates | Naked_int64s | Naked_nativeints -> 2 + | Naked_int32s | Naked_float32s -> 4 + | Values -> + Misc.fatal_error + "Attempted to load/store a SIMD vector from/to a value array." + | Unboxed_product _ -> + (* CR mshinwell: support unboxed products involving vectors? *) + Misc.fatal_error + "Attempted to load/store a SIMD vector from/to an unboxed product \ + array, which is not yet supported." + in multiple_word_array_access_validity_condition array ~size_int - (Array_kind array_kind) Ptagged_int_index ~width_in_scalars ~index + (Array_kind array_kind) Ptagged_int_index + ~num_consecutive_elements_being_accessed ~index let check_array_vector_access ~dbg ~size_int ~array array_kind ~index primitive : H.expr_primitive = @@ -1053,17 +1081,16 @@ let bigarray_set ~dbg ~unsafe kind layout b indexes value = (* Array accesses *) let array_access_validity_condition array array_kind index - ~(index_kind : L.array_index_kind) ~width_in_scalars ~size_int = + ~(index_kind : L.array_index_kind) ~size_int = [ multiple_word_array_access_validity_condition array ~size_int array_kind - index_kind ~width_in_scalars ~index ] + index_kind ~num_consecutive_elements_being_accessed:1 ~index ] let check_array_access ~dbg ~array array_kind ~index ~index_kind ~size_int primitive : H.expr_primitive = - let width_in_scalars = P.Array_kind_for_length.width_in_scalars array_kind in checked_access ~primitive ~conditions: (array_access_validity_condition array array_kind index ~index_kind - ~width_in_scalars ~size_int) + ~size_int) ~dbg let compute_array_indexes ~index ~num_elts = @@ -1190,7 +1217,7 @@ let rec array_set_unsafe dbg ~array ~index array_kind then Misc.fatal_errorf "Wrong arity for unboxed product array_set_unsafe:@ %a" Debuginfo.print_compact dbg; - (* XXX mshinwell: should these be set in reverse order, to match the + (* CR mshinwell: should these be set in reverse order, to match the evaluation order? *) [ H.Sequence (List.concat_map @@ -1431,10 +1458,10 @@ let convert_lprim ~big_endian (prim : L.primitive) (args : Simple.t list list) List.map unbox_float args ), Variadic (Make_array (Values, mutability, mode), args), [K.With_subkind.any_value] ) ])) - | Pmakearray_dynamic (_lambda_array_kind, _mode), _ -> - Misc.fatal_error "Lambda_to_flambda_primitives.convert_lprim: unimplemented" - | Parrayblit _array_set_kind, _ -> - Misc.fatal_error "Lambda_to_flambda_primitives.convert_lprim: unimplemented" + | Pmakearray_dynamic _, _ | Parrayblit _, _ -> + Misc.fatal_error + "Lambda_to_flambda_primitives.convert_lprim: Pmakearray_dynamic and \ + Parrayblit should have been expanded in [Lambda_to_lambda_transforms]" | Popaque layout, [arg] -> opaque layout arg ~middle_end_only:false | Pobj_magic layout, [arg] -> opaque layout arg ~middle_end_only:true | Pduprecord (repr, num_fields), [[arg]] -> @@ -1976,6 +2003,8 @@ let convert_lprim ~big_endian (prim : L.primitive) (args : Simple.t list list) [Binary (Int_arith (I.Tagged_immediate, Div), arg1, arg2)] | Pdivint Safe, [[arg1]; [arg2]] -> [checked_arith_op ~dbg None Div None arg1 arg2 ~current_region] + | Pmodint Unsafe, [[arg1]; [arg2]] -> + [H.Binary (Int_arith (I.Tagged_immediate, Mod), arg1, arg2)] | Pmodint Safe, [[arg1]; [arg2]] -> [checked_arith_op ~dbg None Mod None arg1 arg2 ~current_region] | Pdivbint { size = Boxed_int32; is_safe = Safe; mode }, [[arg1]; [arg2]] -> @@ -2345,8 +2374,7 @@ let convert_lprim ~big_endian (prim : L.primitive) (args : Simple.t list list) "Preinterpret_tagged_int63_as_unboxed_int64 can only be used on 64-bit \ targets"; [Unary (Reinterpret_64_bit_word Tagged_int63_as_unboxed_int64, i)] - | ( ( Pmodint Unsafe - | Pdivbint { is_safe = Unsafe; size = _; mode = _ } + | ( ( Pdivbint { is_safe = Unsafe; size = _; mode = _ } | Pmodbint { is_safe = Unsafe; size = _; mode = _ } | Psetglobal _ | Praise _ | Pccall _ ), _ ) -> diff --git a/middle_end/flambda2/from_lambda/lambda_to_flambda_primitives.mli b/middle_end/flambda2/from_lambda/lambda_to_flambda_primitives.mli index c678ffe5494..70cbfc63835 100644 --- a/middle_end/flambda2/from_lambda/lambda_to_flambda_primitives.mli +++ b/middle_end/flambda2/from_lambda/lambda_to_flambda_primitives.mli @@ -17,6 +17,8 @@ module Acc = Closure_conversion_aux.Acc module Expr_with_acc = Closure_conversion_aux.Expr_with_acc +val check_float_array_optimisation_enabled : string -> unit + val convert_and_bind : Acc.t -> big_endian:bool -> diff --git a/middle_end/flambda2/from_lambda/lambda_to_lambda_transforms.ml b/middle_end/flambda2/from_lambda/lambda_to_lambda_transforms.ml index 7886600e567..8545b061d90 100644 --- a/middle_end/flambda2/from_lambda/lambda_to_lambda_transforms.ml +++ b/middle_end/flambda2/from_lambda/lambda_to_lambda_transforms.ml @@ -110,7 +110,447 @@ let rec_catch_for_for_loop env loc ident start stop in env, lam -let transform_primitive env (prim : L.primitive) args loc = +type initialize_array_element_width = + | Thirty_two of { zero_init : L.lambda } + | Sixty_four_or_more + +let initialize_array0 env loc ~length array_set_kind width ~(init : L.lambda) + creation_expr = + let array = Ident.create_local "array" in + (* If the element size is 32-bit, zero-initialize the last 64-bit word, to + ensure reproducibility. *) + (* CR mshinwell: why does e.g. caml_make_unboxed_int32_vect not do this? *) + let maybe_zero_init_last_field = + match width with + | Sixty_four_or_more -> L.lambda_unit + | Thirty_two { zero_init } -> + let zero_init_last_field = + L.Lprim + ( Parraysetu (array_set_kind, Ptagged_int_index), + (* [Popaque] is used to conceal the out-of-bounds write. *) + [Lprim (Popaque L.layout_unit, [Lvar array], loc); length; zero_init], + loc ) + in + let length_is_greater_than_zero_and_is_one_mod_two = + L.Lprim + ( Psequand, + [ Lprim (Pintcomp Cgt, [Lconst (L.const_int 0); length], loc); + Lprim + ( Pintcomp Cne, + [ Lprim (Pmodint Unsafe, [length; Lconst (L.const_int 2)], loc); + Lconst (L.const_int 0) ], + loc ) ], + loc ) + in + L.Lifthenelse + ( length_is_greater_than_zero_and_is_one_mod_two, + zero_init_last_field, + L.lambda_unit, + L.layout_unit ) + in + let env, initialize = + let index = Ident.create_local "index" in + rec_catch_for_for_loop env loc index + (Lconst (L.const_int 0)) + (L.Lprim (Psubint, [length; Lconst (L.const_int 1)], loc)) + Upto + (Lprim + ( Parraysetu (array_set_kind, Ptagged_int_index), + [Lvar array; Lvar index; init], + loc )) + in + let term = + L.Llet + ( Strict, + Pvalue { raw_kind = Pgenval; nullable = Non_nullable }, + array, + creation_expr, + Lsequence + (maybe_zero_init_last_field, Lsequence (initialize, Lvar array)) ) + in + env, Transformed term + +let initialize_array env loc ~length array_set_kind width ~init creation_expr = + match init with + | None -> env, Transformed creation_expr + | Some init -> + initialize_array0 env loc ~length array_set_kind width ~init creation_expr + +let makearray_dynamic_singleton name (mode : L.locality_mode) ~length ~init loc + = + let name = + Printf.sprintf "caml_make%s_%s%svect" + (match mode with Alloc_heap -> "" | Alloc_local -> "_local") + name + (if String.length name > 0 then "_" else "") + in + let external_call_desc = + Primitive.make ~name ~alloc:true (* the C stub may raise an exception *) + ~c_builtin:false ~effects:Arbitrary_effects ~coeffects:Has_coeffects + ~native_name:name + ~native_repr_args: + ([Primitive.Prim_global, L.Same_as_ocaml_repr (Base Value)] + @ + match init with + | None -> [] + | Some (init_extern_repr, _) -> [Primitive.Prim_local, init_extern_repr] + ) + ~native_repr_res: + ( (match mode with + | Alloc_heap -> Prim_global + | Alloc_local -> Prim_local), + L.Same_as_ocaml_repr (Base Value) ) + ~is_layout_poly:false + in + L.Lprim + ( Pccall external_call_desc, + ([length] @ match init with None -> [] | Some (_, init) -> [init]), + loc ) + +let makearray_dynamic_singleton_uninitialized name (mode : L.locality_mode) + ~length loc = + makearray_dynamic_singleton name + (mode : L.locality_mode) + ~length ~init:None loc + +let makearray_dynamic_unboxed_products_only_64_bit () = + (* To keep things simple in the C stub as regards array length, we currently + restrict to 64-bit targets. *) + if not (Target_system.is_64_bit ()) + then + Misc.fatal_error + "Cannot compile Pmakearray_dynamic at unboxed product layouts for 32-bit \ + targets" + +let makearray_dynamic_unboxed_product_c_stub ~name (mode : L.locality_mode) = + Primitive.make ~name ~alloc:true (* the C stub may raise an exception *) + ~c_builtin:false ~effects:Arbitrary_effects ~coeffects:Has_coeffects + ~native_name:name + ~native_repr_args: + [ Prim_global, L.Same_as_ocaml_repr (Base Value); + Prim_local, L.Same_as_ocaml_repr (Base Value); + Prim_global, L.Same_as_ocaml_repr (Base Value) ] + ~native_repr_res: + ( (match mode with Alloc_heap -> Prim_global | Alloc_local -> Prim_local), + L.Same_as_ocaml_repr (Base Value) ) + ~is_layout_poly:false + +let makearray_dynamic_non_scannable_unboxed_product env + (lambda_array_kind : L.array_kind) (mode : L.locality_mode) ~length + ~(init : L.lambda option) loc = + makearray_dynamic_unboxed_products_only_64_bit (); + let is_local = + L.of_bool (match mode with Alloc_heap -> false | Alloc_local -> true) + in + let external_call_desc = + makearray_dynamic_unboxed_product_c_stub + ~name:"caml_makearray_dynamic_non_scannable_unboxed_product" mode + in + let num_components = L.count_initializers_array_kind lambda_array_kind in + (* Note that we don't check the number of unarized arguments against the + layout; we trust the front end. If we wanted to do this, it would have to + be done slightly later, after unarization. *) + (* CR mshinwell: two things were tried here, but one is dirty and the other + needed too much work: + + - CPS convert the primitive arguments before getting here. They may then + have to be converted a second time, in the event that the primitive is + transformed by this file. + + - For this primitive only, have a function passed in here which when + called, does the CPS conversion of the arguments and then escapes using an + exception, returning the number of arguments. This seems dirty. + + Both of these cases introduce complexity as it is necessary to go back to + using an older accumulator during CPS conversion. This is probably fine but + is a real change. *) + let term = + L.( + Lprim + ( Pccall external_call_desc, + [Lconst (L.const_int num_components); is_local; length], + loc )) + in + match init with + | None -> env, Transformed term + | Some init -> + initialize_array0 env loc ~length + (L.array_set_kind + (match mode with + | Alloc_heap -> L.modify_heap + | Alloc_local -> L.modify_maybe_stack) + lambda_array_kind) + (* There is no packing in unboxed product arrays, even if the elements are + all float32# or int32#. *) + Sixty_four_or_more ~init term + +let makearray_dynamic_scannable_unboxed_product0 + (lambda_array_kind : L.array_kind) (mode : L.locality_mode) ~length ~init + loc = + makearray_dynamic_unboxed_products_only_64_bit (); + (* Trick: use the local stack as a way of getting the variable argument list + to the C function. *) + if not Config.stack_allocation + then + Misc.fatal_error + "Cannot compile Pmakearray_dynamic at unboxed product layouts without \ + stack allocation enabled"; + let args_array = Ident.create_local "args_array" in + let array_layout = L.layout_array lambda_array_kind in + let is_local = + L.of_bool (match mode with Alloc_heap -> false | Alloc_local -> true) + in + let external_call_desc = + makearray_dynamic_unboxed_product_c_stub + ~name:"caml_makearray_dynamic_scannable_unboxed_product" mode + in + (* Note that we don't check the number of unarized arguments against the + layout; we trust the front end. If we wanted to do this, it would have to + be done slightly later, after unarization. *) + let body = + L.Llet + ( Strict, + array_layout, + args_array, + Lprim + ( Pmakearray (lambda_array_kind, Immutable, L.alloc_local), + [init] (* will be unarized when this term is CPS converted *), + loc ), + Lprim + (Pccall external_call_desc, [Lvar args_array; is_local; length], loc) + ) + in + (* We must not add a region if the C stub is going to return a local value, + otherwise we will incorrectly close the region on such live value. *) + Transformed + (match mode with + | Alloc_local -> body + | Alloc_heap -> L.Lregion (body, array_layout)) + +let makearray_dynamic_scannable_unboxed_product env + (lambda_array_kind : L.array_kind) (mode : L.locality_mode) ~length + ~(init : L.lambda) loc = + let must_be_scanned = + match lambda_array_kind with + | Pgcignorableproductarray _ -> false + | Pgcscannableproductarray kinds -> + let rec must_be_scanned (kind : L.scannable_product_element_kind) = + match kind with + | Pint_scannable -> false + | Paddr_scannable -> true + | Pproduct_scannable kinds -> List.exists must_be_scanned kinds + in + List.exists must_be_scanned kinds + | Pgenarray | Paddrarray | Pintarray | Pfloatarray | Punboxedfloatarray _ + | Punboxedintarray _ | Punboxedvectorarray _ -> + Misc.fatal_errorf + "%s: should have been sent to [makearray_dynamic_singleton]" + (Printlambda.array_kind lambda_array_kind) + in + if must_be_scanned + then + ( env, + makearray_dynamic_scannable_unboxed_product0 lambda_array_kind mode + ~length ~init loc ) + else + makearray_dynamic_non_scannable_unboxed_product env lambda_array_kind mode + ~length ~init:(Some init) loc + +let makearray_dynamic env (lambda_array_kind : L.array_kind) + (mode : L.locality_mode) (has_init : L.has_initializer) args loc : + Env.t * primitive_transform_result = + (* %makearray_dynamic is analogous to (from stdlib/array.ml): + * external create: int -> 'a -> 'a array = "caml_make_vect" + * except that it works on any layout, including unboxed products, at both + * heap and local modes. + * Additionally, if the initializer is omitted, an uninitialized array will + * be returned. Initializers must however be provided when the array kind is + * Pgenarray, Paddrarray, Pintarray, Pfloatarray or Pgcscannableproductarray; + * or when a Pgcignorablearray involves an [int]. (See comment below.) + *) + let dbg = Debuginfo.from_location loc in + let length, init = + match args, has_init with + | [length], Uninitialized -> length, None + | [length; init], With_initializer -> length, Some init + | _, (Uninitialized | With_initializer) -> + Misc.fatal_errorf + "Pmakearray_dynamic takes the (non-unarized) length and optionally an \ + initializer (the latter perhaps of unboxed product layout) according \ + to the setting of [Uninitialized] or [With_initializer]:@ %a" + Debuginfo.print_compact dbg + in + let[@inline] must_have_initializer () = + match init with + | Some init -> init + | None -> ( + match lambda_array_kind with + | Pintarray | Pgcignorableproductarray _ -> + (* If we get here for [Pgcignorableproductarray] then a tagged immediate + is involved: see main [match] below. *) + Misc.fatal_errorf + "Cannot compile Pmakearray_dynamic at layout %s without an \ + initializer; otherwise it might be possible for values of type \ + [int] having incorrect representations to be revealed, thus \ + breaking soundness:@ %a" + (Printlambda.array_kind lambda_array_kind) + Debuginfo.print_compact dbg + | Pgenarray | Paddrarray | Pfloatarray | Punboxedfloatarray _ + | Punboxedintarray _ | Punboxedvectorarray _ | Pgcscannableproductarray _ + -> + Misc.fatal_errorf + "Cannot compile Pmakearray_dynamic at layout %s without an \ + initializer:@ %a" + (Printlambda.array_kind lambda_array_kind) + Debuginfo.print_compact dbg) + in + match lambda_array_kind with + | Pgenarray | Paddrarray | Pintarray | Pfloatarray -> + let init = must_have_initializer () in + ( env, + Transformed + (makearray_dynamic_singleton "" mode ~length + ~init:(Some (Same_as_ocaml_repr (Base Value), init)) + loc) ) + | Punboxedfloatarray Unboxed_float32 -> + makearray_dynamic_singleton_uninitialized "unboxed_float32" ~length mode loc + |> initialize_array env loc ~length (Punboxedfloatarray_set Unboxed_float32) + (Thirty_two + { zero_init = Lconst (Const_base (Const_unboxed_float32 "0")) }) + ~init + | Punboxedfloatarray Unboxed_float64 -> + makearray_dynamic_singleton_uninitialized "unboxed_float64" ~length mode loc + |> initialize_array env loc ~length (Punboxedfloatarray_set Unboxed_float64) + Sixty_four_or_more ~init + | Punboxedintarray Unboxed_int32 -> + makearray_dynamic_singleton_uninitialized "unboxed_int32" ~length mode loc + |> initialize_array env loc ~length (Punboxedintarray_set Unboxed_int32) + (Thirty_two + { zero_init = Lconst (Const_base (Const_unboxed_int32 0l)) }) + ~init + | Punboxedintarray Unboxed_int64 -> + makearray_dynamic_singleton_uninitialized "unboxed_int64" ~length mode loc + |> initialize_array env loc ~length (Punboxedintarray_set Unboxed_int64) + Sixty_four_or_more ~init + | Punboxedintarray Unboxed_nativeint -> + makearray_dynamic_singleton_uninitialized "unboxed_nativeint" ~length mode + loc + |> initialize_array env loc ~length (Punboxedintarray_set Unboxed_nativeint) + Sixty_four_or_more ~init + | Punboxedvectorarray Unboxed_vec128 -> + makearray_dynamic_singleton_uninitialized "unboxed_vec128" ~length mode loc + |> initialize_array env loc ~length (Punboxedvectorarray_set Unboxed_vec128) + Sixty_four_or_more ~init + | Pgcscannableproductarray _ -> + let init = must_have_initializer () in + makearray_dynamic_scannable_unboxed_product env lambda_array_kind mode + ~length ~init loc + | Pgcignorableproductarray ignorable -> + (* Care: all (unarized) elements that are valid OCaml values, in this case + of type [int] or equivalent, must be initialized. This is to ensure + soundness in the event of a read occurring prior to initialization (e.g. + by ensuring that values without the bottom bit set cannot be returned at + type [int]). *) + let init = + if List.exists L.ignorable_product_element_kind_involves_int ignorable + then Some (must_have_initializer ()) + else init + in + makearray_dynamic_non_scannable_unboxed_product env lambda_array_kind mode + ~length ~init loc + +let arrayblit env ~(src_mutability : L.mutable_flag) + ~(dst_array_set_kind : L.array_set_kind) args loc = + let src_array_ref_kind = + (* We don't expect any allocation (e.g. occurring from the reading of a + [float array]) to persist after simplification. We use [alloc_local] just + in case that simplification doesn't happen for some reason (this seems + unlikely). *) + L.array_ref_kind_of_array_set_kind dst_array_set_kind L.alloc_local + in + match args with + | [src_expr; src_start_pos_expr; dst_expr; dst_start_pos_expr; length_expr] -> + (* Care: the [args] are arbitrary Lambda expressions, so need to be + [let]-bound *) + let id = Ident.create_local in + let bind = L.bind_with_layout in + let src = id "src" in + let src_start_pos = id "src_start_pos" in + let dst = id "dst" in + let dst_start_pos = id "dst_start_pos" in + let length = id "length" in + (* CR mshinwell: support indexing by other types apart from [int] *) + let src_end_pos_exclusive = + L.Lprim (Paddint, [Lvar src_start_pos; Lvar length], loc) + in + let src_end_pos_inclusive = + L.Lprim (Psubint, [src_end_pos_exclusive; Lconst (L.const_int 1)], loc) + in + let dst_start_pos_minus_src_start_pos = + L.Lprim (Psubint, [Lvar dst_start_pos; Lvar src_start_pos], loc) + in + let dst_start_pos_minus_src_start_pos_var = + Ident.create_local "dst_start_pos_minus_src_start_pos" + in + let must_copy_backwards = + L.Lprim (Pintcomp Cgt, [Lvar dst_start_pos; Lvar src_start_pos], loc) + in + let make_loop env (direction : Asttypes.direction_flag) = + let src_index = Ident.create_local "index" in + let start_pos, end_pos = + match direction with + | Upto -> L.Lvar src_start_pos, src_end_pos_inclusive + | Downto -> src_end_pos_inclusive, L.Lvar src_start_pos + in + rec_catch_for_for_loop env loc src_index start_pos end_pos direction + (Lprim + ( Parraysetu (dst_array_set_kind, Ptagged_int_index), + [ Lvar dst; + Lprim + ( Paddint, + [Lvar src_index; dst_start_pos_minus_src_start_pos], + loc ); + Lprim + ( Parrayrefu + ( src_array_ref_kind, + Ptagged_int_index, + match src_mutability with + | Immutable | Immutable_unique -> Immutable + | Mutable -> Mutable ), + [Lvar src; Lvar src_index], + loc ) ], + loc )) + in + let env, copy_backwards = make_loop env Downto in + let env, copy_forwards = make_loop env Upto in + let body = + (* The region is expected to be redundant (see comment above about + modes). *) + L.Lregion + ( L.Lifthenelse + (must_copy_backwards, copy_backwards, copy_forwards, L.layout_unit), + L.layout_unit ) + in + let expr = + (* Preserve right-to-left evaluation order. *) + bind Strict (length, L.layout_int) length_expr + @@ bind Strict (dst_start_pos, L.layout_int) dst_start_pos_expr + @@ bind Strict (dst, L.layout_any_value) dst_expr + @@ bind Strict (src_start_pos, L.layout_int) src_start_pos_expr + @@ bind Strict (src, L.layout_any_value) src_expr + @@ bind Strict + (dst_start_pos_minus_src_start_pos_var, L.layout_int) + dst_start_pos_minus_src_start_pos body + in + env, Transformed expr + | _ -> + Misc.fatal_errorf + "Wrong arity for Parrayblit{,_immut} (expected src, src_offset, \ + dst_offset and length):@ %a" + Debuginfo.print_compact + (Debuginfo.from_location loc) + +let transform_primitive0 env (prim : L.primitive) args loc = match prim, args with | Psequor, [arg1; arg2] -> let const_true = Ident.create_local "const_true" in @@ -251,3 +691,12 @@ let transform_primitive env (prim : L.primitive) args loc = (see translprim).") | _, _ -> Primitive (prim, args, loc) [@@ocaml.warning "-fragile-match"] + +let transform_primitive env (prim : L.primitive) args loc = + match prim with + | Pmakearray_dynamic (lambda_array_kind, mode, has_init) -> + makearray_dynamic env lambda_array_kind mode has_init args loc + | Parrayblit { src_mutability; dst_array_set_kind } -> + arrayblit env ~src_mutability ~dst_array_set_kind args loc + | _ -> env, transform_primitive0 env prim args loc + [@@ocaml.warning "-fragile-match"] diff --git a/middle_end/flambda2/from_lambda/lambda_to_lambda_transforms.mli b/middle_end/flambda2/from_lambda/lambda_to_lambda_transforms.mli index f7a0bd73d04..4ea169908bb 100644 --- a/middle_end/flambda2/from_lambda/lambda_to_lambda_transforms.mli +++ b/middle_end/flambda2/from_lambda/lambda_to_lambda_transforms.mli @@ -44,6 +44,7 @@ val switch_for_if_then_else : val transform_primitive : Lambda_to_flambda_env.t -> Lambda.primitive -> + (* CR mshinwell: consider [Ident.t list] instead for the arguments. *) Lambda.lambda list -> Lambda.scoped_location -> - primitive_transform_result + Lambda_to_flambda_env.t * primitive_transform_result diff --git a/runtime/array.c b/runtime/array.c index a58b16c1cc7..419645d85db 100644 --- a/runtime/array.c +++ b/runtime/array.c @@ -406,6 +406,18 @@ CAMLprim value caml_floatarray_create_local(value len) return caml_alloc_local (wosize, Double_array_tag); } +// Stubs with consistent naming: + +CAMLprim value caml_make_unboxed_float64_vect(value len) +{ + return caml_floatarray_create(len); +} + +CAMLprim value caml_make_local_unboxed_float64_vect(value len) +{ + return caml_floatarray_create_local(len); +} + /* [len] is a [value] representing number of words or floats */ static value make_vect_gen(value len, value init, int local) { @@ -453,7 +465,8 @@ static value make_vect_gen(value len, value init, int local) for (i = 0; i < size; i++) Field(res, i) = init; } } - /* Give the GC a chance to run, and run memprof callbacks */ + /* Give the GC a chance to run, and run memprof callbacks. + This matches the semantics of allocations directly from OCaml code. */ if (!local) caml_process_pending_actions (); CAMLreturn (res); } @@ -469,6 +482,151 @@ CAMLprim value caml_make_local_vect(value len, value init) return make_vect_gen(len, init, 1); } +CAMLprim value caml_makearray_dynamic_non_scannable_unboxed_product( + value v_num_components, value v_is_local, + value v_non_unarized_length) +{ + // Some of this is similar to [caml_make_vect], above. + // This function is only used for native code. + + CAMLparam0(); + CAMLlocal1(res); + + mlsize_t num_components = Long_val(v_num_components); + int is_local = Bool_val(v_is_local); + mlsize_t non_unarized_length = Long_val(v_non_unarized_length); + mlsize_t size; + + if (sizeof(uintnat) != sizeof(double)) { + // Just make things easy as regards maximum array lengths for now. + // This should have been caught in [Lambda_to_flambda]. + caml_invalid_argument( + "%makearray_dynamic: only supported on 64-bit targets " + "(this is a compiler bug)"); + } + + int tag = 0; + // These arrays are always mixed blocks without packing. + // This currently differs from e.g. int32# array, which is allocated as a + // custom block, and is packed. + int reserved = Reserved_mixed_block_scannable_wosize_native(0); + + size = non_unarized_length * num_components; + if (size == 0) { + res = Atom(0); + } else if (num_components < 1) { + // This could happen with void layouts. We don't rule it out in + // [Lambda_to_flambda] since it is in fact ok, if the size is zero. + caml_invalid_argument( + "%makearray_dynamic: the only array that can be initialized with " + "nothing is a zero-length array"); + } else if (size > Max_array_wosize) { + caml_invalid_argument( + "%makearray_dynamic: array size too large (> Max_array_wosize)"); + } else if (is_local) { + res = caml_alloc_local_reserved(size, tag, reserved); + } else if (size <= Max_young_wosize) { + res = caml_alloc_small_with_reserved(size, tag, reserved); + } else { + res = caml_alloc_shr_reserved(size, tag, reserved); + } + + /* Give the GC a chance to run, and run memprof callbacks. + This matches the semantics of allocations directly from OCaml code. */ + // CR mshinwell: the other functions which allocate unboxed number arrays + // should also do this + if (!is_local) caml_process_pending_actions (); + + CAMLreturn(res); +} + +CAMLprim value caml_makearray_dynamic_scannable_unboxed_product( + value v_init, value v_is_local, value v_non_unarized_length) +{ + // Some of this is similar to [caml_make_vect], above. + + CAMLparam1(v_init); + CAMLlocal1(res); + + mlsize_t num_initializers = Wosize_val(v_init); + int is_local = Bool_val(v_is_local); + mlsize_t non_unarized_length = Long_val(v_non_unarized_length); + + mlsize_t size, i; + + // N.B. [v_init] may be on the local stack! + + if (sizeof(uintnat) != sizeof(double)) { + // Just make things easy as regards maximum array lengths for now. + // This should have been caught in [Lambda_to_flambda]. + caml_invalid_argument( + "%makearray_dynamic: only supported on 64-bit targets " + "(this is a compiler bug)"); + } + + int tag = 0; + + size = non_unarized_length * num_initializers; + if (size == 0) { + res = Atom(0); + } else if (num_initializers < 1) { + // This could happen with void layouts. We don't rule it out in + // [Lambda_to_flambda] since it is in fact ok, if the size is zero. + caml_invalid_argument( + "%makearray_dynamic: the only array that can be initialized with " + "nothing is a zero-length array"); + } else if (size > Max_array_wosize) { + caml_invalid_argument( + "%makearray_dynamic: array size too large (> Max_array_wosize)"); + } else if (is_local) { + res = caml_alloc_local(size, tag); + for (i = 0; i < size; i++) { + Field(res, i) = Field(v_init, i % num_initializers); + } + } else if (size <= Max_young_wosize) { + res = caml_alloc_small(size, tag); + for (i = 0; i < size; i++) { + Field(res, i) = Field(v_init, i % num_initializers); + } + } else { + int move_init_to_major = 0; + for (mlsize_t i = 0; i < num_initializers; i++) { + if (Is_block(Field(v_init, i)) && Is_young(Field(v_init, i))) { + move_init_to_major = 1; + } + } + if (move_init_to_major) { + /* We don't want to create so many major-to-minor references, + so the contents of [v_init] are moved to the major heap by doing + a minor GC. */ + /* CR mslater/mshinwell: Why is this better than adding them to the + remembered set with caml_initialize? See discussion in a + conversation on: + https://github.com/ocaml-flambda/flambda-backend/pull/3317 + */ + CAML_EV_COUNTER (EV_C_FORCE_MINOR_MAKE_VECT, 1); + caml_minor_collection (); + } +#ifdef DEBUG + for (mlsize_t i = 0; i < num_initializers; i++) { + CAMLassert(!(Is_block(Field(v_init, i)) && Is_young(Field(v_init, i)))); + } +#endif + res = caml_alloc_shr(size, tag); + /* We now know that everything in [v_init] is not in the minor heap, so + there is no need to call [caml_initialize]. */ + for (i = 0; i < size; i++) { + Field(res, i) = Field(v_init, i % num_initializers); + } + } + + /* Give the GC a chance to run, and run memprof callbacks. + This matches the semantics of allocations directly from OCaml code. */ + if (!is_local) caml_process_pending_actions (); + + CAMLreturn(res); +} + /* [len] is a [value] representing number of floats */ /* [ int -> float array ] */ CAMLprim value caml_make_float_vect(value len) @@ -492,18 +650,34 @@ CAMLprim value caml_make_float_vect(value len) #endif } -CAMLprim value caml_make_unboxed_int32_vect(value len) +static value caml_make_unboxed_int32_vect0(value len, int local) { /* This is only used on 64-bit targets. */ mlsize_t num_elements = Long_val(len); - if (num_elements > Max_unboxed_int32_array_wosize) caml_invalid_argument("Array.make"); + if (num_elements > Max_unboxed_int32_array_wosize) + caml_invalid_argument("Array.make"); /* [num_fields] does not include the custom operations field. */ mlsize_t num_fields = num_elements / 2 + num_elements % 2; - return caml_alloc_custom(&caml_unboxed_int32_array_ops[num_elements % 2], - num_fields * sizeof(value), 0, 0); + struct custom_operations* ops = + &caml_unboxed_int32_array_ops[num_elements % 2]; + + if (local) + return caml_alloc_custom_local(ops, num_fields * sizeof(value), 0, 0); + else + return caml_alloc_custom(ops, num_fields * sizeof(value), 0, 0); +} + +CAMLprim value caml_make_unboxed_int32_vect(value len) +{ + return caml_make_unboxed_int32_vect0(len, 0); +} + +CAMLprim value caml_make_local_unboxed_int32_vect(value len) +{ + return caml_make_unboxed_int32_vect0(len, 1); } CAMLprim value caml_make_unboxed_int32_vect_bytecode(value len) @@ -511,14 +685,28 @@ CAMLprim value caml_make_unboxed_int32_vect_bytecode(value len) return caml_make_vect(len, caml_copy_int32(0)); } -CAMLprim value caml_make_unboxed_int64_vect(value len) +static value caml_make_unboxed_int64_vect0(value len, int local) { mlsize_t num_elements = Long_val(len); - if (num_elements > Max_unboxed_int64_array_wosize) caml_invalid_argument("Array.make"); + if (num_elements > Max_unboxed_int64_array_wosize) + caml_invalid_argument("Array.make"); struct custom_operations* ops = &caml_unboxed_int64_array_ops; - return caml_alloc_custom(ops, num_elements * sizeof(value), 0, 0); + if (local) + return caml_alloc_custom_local(ops, num_elements * sizeof(value), 0, 0); + else + return caml_alloc_custom(ops, num_elements * sizeof(value), 0, 0); +} + +CAMLprim value caml_make_unboxed_int64_vect(value len) +{ + return caml_make_unboxed_int64_vect0(len, 0); +} + +CAMLprim value caml_make_local_unboxed_int64_vect(value len) +{ + return caml_make_unboxed_int64_vect0(len, 1); } CAMLprim value caml_make_unboxed_int64_vect_bytecode(value len) @@ -526,16 +714,30 @@ CAMLprim value caml_make_unboxed_int64_vect_bytecode(value len) return caml_make_vect(len, caml_copy_int64(0)); } -CAMLprim value caml_make_unboxed_nativeint_vect(value len) +static value caml_make_unboxed_nativeint_vect0(value len, int local) { /* This is only used on 64-bit targets. */ mlsize_t num_elements = Long_val(len); - if (num_elements > Max_unboxed_nativeint_array_wosize) caml_invalid_argument("Array.make"); + if (num_elements > Max_unboxed_nativeint_array_wosize) + caml_invalid_argument("Array.make"); struct custom_operations* ops = &caml_unboxed_nativeint_array_ops; - return caml_alloc_custom(ops, num_elements * sizeof(value), 0, 0); + if (local) + return caml_alloc_custom_local(ops, num_elements * sizeof(value), 0, 0); + else + return caml_alloc_custom(ops, num_elements * sizeof(value), 0, 0); +} + +CAMLprim value caml_make_unboxed_nativeint_vect(value len) +{ + return caml_make_unboxed_nativeint_vect0(len, 0); +} + +CAMLprim value caml_make_local_unboxed_nativeint_vect(value len) +{ + return caml_make_unboxed_nativeint_vect0(len, 1); } CAMLprim value caml_make_unboxed_nativeint_vect_bytecode(value len) diff --git a/runtime/caml/custom.h b/runtime/caml/custom.h index 127d8247abd..509a85d2034 100644 --- a/runtime/caml/custom.h +++ b/runtime/caml/custom.h @@ -59,6 +59,13 @@ CAMLextern value caml_alloc_custom(const struct custom_operations * ops, mlsize_t mem, /*resources consumed*/ mlsize_t max /*max resources*/); +// The local version will fail if a finalizer is supplied in the [ops], +// since finalizers on locally-allocated values are not yet supported. +CAMLextern value caml_alloc_custom_local(const struct custom_operations * ops, + uintnat size, /*size in bytes*/ + mlsize_t mem, /*resources consumed*/ + mlsize_t max /*max resources*/); + /* [caml_alloc_custom_mem] allocates a custom block with dependent memory (memory outside the heap that will be reclaimed when the block is finalized). If [mem] is greater than [custom_minor_max_size] (see gc.mli) diff --git a/runtime/caml/memory.h b/runtime/caml/memory.h index 7c3359b7e86..793aed1a28b 100644 --- a/runtime/caml/memory.h +++ b/runtime/caml/memory.h @@ -37,6 +37,7 @@ CAMLextern value caml_alloc_shr (mlsize_t wosize, tag_t); CAMLextern value caml_alloc_shr_noexc(mlsize_t wosize, tag_t); CAMLextern value caml_alloc_shr_reserved (mlsize_t, tag_t, reserved_t); CAMLextern value caml_alloc_local(mlsize_t, tag_t); +CAMLextern value caml_alloc_local_reserved(mlsize_t, tag_t, reserved_t); CAMLextern void caml_adjust_gc_speed (mlsize_t, mlsize_t); CAMLextern void caml_adjust_minor_gc_speed (mlsize_t, mlsize_t); diff --git a/runtime/custom.c b/runtime/custom.c index 80f1191c08f..d277740df05 100644 --- a/runtime/custom.c +++ b/runtime/custom.c @@ -67,14 +67,20 @@ static value alloc_custom_gen (const struct custom_operations * ops, mlsize_t mem, mlsize_t max_major, mlsize_t max_minor, - int minor_ok) + int minor_ok, + int local) { mlsize_t wosize; CAMLparam0(); CAMLlocal1(result); wosize = 1 + (bsz + sizeof(value) - 1) / sizeof(value); - if (wosize <= Max_young_wosize && minor_ok) { + if (local) { + CAMLassert(ops->finalize == NULL); + result = caml_alloc_local(wosize, Custom_tag); + Custom_ops_val(result) = ops; + } + else if (wosize <= Max_young_wosize && minor_ok) { result = caml_alloc_small(wosize, Custom_tag); Custom_ops_val(result) = ops; if (ops->finalize != NULL || mem != 0) { @@ -102,14 +108,35 @@ Caml_inline mlsize_t get_max_minor (void) Bsize_wsize (Caml_state->minor_heap_wsz) / 100 * caml_custom_minor_ratio; } +static value caml_alloc_custom0(const struct custom_operations * ops, + uintnat bsz, + mlsize_t mem, + mlsize_t max, + int local) +{ + mlsize_t max_major = max; + mlsize_t max_minor = max == 0 ? get_max_minor() : max; + return alloc_custom_gen (ops, bsz, mem, max_major, max_minor, 1, local); +} + CAMLexport value caml_alloc_custom(const struct custom_operations * ops, uintnat bsz, mlsize_t mem, mlsize_t max) { - mlsize_t max_major = max; - mlsize_t max_minor = max == 0 ? get_max_minor() : max; - return alloc_custom_gen (ops, bsz, mem, max_major, max_minor, 1); + return caml_alloc_custom0(ops, bsz, mem, max, 0); +} + +CAMLexport value caml_alloc_custom_local(const struct custom_operations * ops, + uintnat bsz, + mlsize_t mem, + mlsize_t max) +{ + if (ops->finalize != NULL) + caml_invalid_argument( + "caml_alloc_custom_local: finalizers not supported"); + + return caml_alloc_custom0(ops, bsz, mem, max, 1); } CAMLexport value caml_alloc_custom_mem(const struct custom_operations * ops, @@ -124,7 +151,7 @@ CAMLexport value caml_alloc_custom_mem(const struct custom_operations * ops, max_minor_single = max_minor * caml_custom_minor_max_bsz / 100; } value v = alloc_custom_gen (ops, bsz, mem, 0, - max_minor, (mem < max_minor_single)); + max_minor, (mem < max_minor_single), 0); size_t mem_words = (mem + sizeof(value) - 1) / sizeof(value); caml_memprof_sample_block(v, mem_words, mem_words, CAML_MEMPROF_SRC_CUSTOM); return v; diff --git a/runtime/float32.c b/runtime/float32.c index ca518ecb840..6c4cce4cc7a 100644 --- a/runtime/float32.c +++ b/runtime/float32.c @@ -853,7 +853,7 @@ CAMLexport const struct custom_operations caml_unboxed_float32_array_ops[2] = { custom_fixed_length_default }, }; -CAMLprim value caml_make_unboxed_float32_vect(value len) +static value caml_make_unboxed_float32_vect0(value len, int local) { /* This is only used on 64-bit targets. */ @@ -863,8 +863,23 @@ CAMLprim value caml_make_unboxed_float32_vect(value len) /* [num_fields] does not include the custom operations field. */ mlsize_t num_fields = num_elements / 2 + num_elements % 2; - return caml_alloc_custom(&caml_unboxed_float32_array_ops[num_elements % 2], - num_fields * sizeof(value), 0, 0); + const struct custom_operations* ops = + &caml_unboxed_float32_array_ops[num_elements % 2]; + + if (local) + return caml_alloc_custom_local(ops, num_fields * sizeof(value), 0, 0); + else + return caml_alloc_custom(ops, num_fields * sizeof(value), 0, 0); +} + +CAMLprim value caml_make_unboxed_float32_vect(value len) +{ + return caml_make_unboxed_float32_vect0(len, 0); +} + +CAMLprim value caml_make_local_unboxed_float32_vect(value len) +{ + return caml_make_unboxed_float32_vect0(len, 1); } CAMLprim value caml_make_unboxed_float32_vect_bytecode(value len) diff --git a/runtime/memory.c b/runtime/memory.c index fade3ec6c55..f867a21a779 100644 --- a/runtime/memory.c +++ b/runtime/memory.c @@ -531,7 +531,8 @@ void caml_local_realloc(void) CAMLassert(Caml_state->local_limit <= Caml_state->local_sp); } -CAMLexport value caml_alloc_local(mlsize_t wosize, tag_t tag) +CAMLexport value caml_alloc_local_reserved(mlsize_t wosize, tag_t tag, + reserved_t reserved) { #if defined(NATIVE_CODE) && defined(STACK_ALLOCATION) intnat sp = Caml_state->local_sp; @@ -541,21 +542,26 @@ CAMLexport value caml_alloc_local(mlsize_t wosize, tag_t tag) if (sp < Caml_state->local_limit) caml_local_realloc(); hp = (header_t*)((char*)Caml_state->local_top + sp); - *hp = Make_header(wosize, tag, NOT_MARKABLE); + *hp = Make_header_with_reserved(wosize, tag, NOT_MARKABLE, reserved); return Val_hp(hp); #else if (wosize <= Max_young_wosize) { - return caml_alloc_small(wosize, tag); + return caml_alloc_small_with_reserved(wosize, tag, reserved); } else { /* The return value is initialised directly using Field. This is invalid if it may create major -> minor pointers. So, perform a minor GC to prevent this. (See caml_make_vect) */ caml_minor_collection(); - return caml_alloc_shr(wosize, tag); + return caml_alloc_shr_reserved(wosize, tag, reserved); } #endif } +CAMLexport value caml_alloc_local(mlsize_t wosize, tag_t tag) +{ + return caml_alloc_local_reserved(wosize, tag, 0); +} + CAMLprim value caml_local_stack_offset(value blk) { #ifdef NATIVE_CODE diff --git a/runtime/simd.c b/runtime/simd.c index 0e1e6129f26..3188184ef68 100644 --- a/runtime/simd.c +++ b/runtime/simd.c @@ -75,20 +75,37 @@ CAMLprim value caml_unboxed_vec128_vect_blit(value a1, value ofs1, value a2, return Val_unit; } -CAMLprim value caml_make_unboxed_vec128_vect(value len) { - /* This is only used on 64-bit targets. */ - - mlsize_t num_elements = Long_val(len); - if (num_elements > Max_unboxed_vec128_array_wosize) caml_invalid_argument("Array.make"); +static value caml_make_unboxed_vec128_vect0(value len, int local) +{ + /* This is only used on 64-bit targets. */ + + mlsize_t num_elements = Long_val(len); + if (num_elements > Max_unboxed_vec128_array_wosize) + caml_invalid_argument("Array.make"); + + /* [num_fields] does not include the custom operations field. */ + mlsize_t num_fields = num_elements * 2; + + if (local) + return caml_alloc_custom_local(&caml_unboxed_vec128_array_ops, + num_fields * sizeof(value), 0, 0); + else + return caml_alloc_custom(&caml_unboxed_vec128_array_ops, + num_fields * sizeof(value), 0, 0); +} - /* [num_fields] does not include the custom operations field. */ - mlsize_t num_fields = num_elements * 2; +CAMLprim value caml_make_unboxed_vec128_vect(value len) +{ + return caml_make_unboxed_vec128_vect0(len, 0); +} - return caml_alloc_custom(&caml_unboxed_vec128_array_ops, num_fields * sizeof(value), 0, 0); +CAMLprim value caml_make_local_unboxed_vec128_vect(value len) +{ + return caml_make_unboxed_vec128_vect0(len, 1); } CAMLprim value caml_make_unboxed_vec128_vect_bytecode(value len) { - caml_failwith("SIMD is not supported in bytecode mode."); + caml_failwith("SIMD is not supported on this platform."); } #else @@ -102,6 +119,10 @@ CAMLprim value caml_make_unboxed_vec128_vect(value len) { caml_failwith("SIMD is not supported on this platform."); } +CAMLprim value caml_make_local_unboxed_vec128_vect(value len) { + caml_failwith("SIMD is not supported on this platform."); +} + CAMLprim value caml_make_unboxed_vec128_vect_bytecode(value len) { caml_failwith("SIMD is not supported on this platform."); } diff --git a/runtime4/array.c b/runtime4/array.c index ae3306028f6..2d2d67e8f09 100644 --- a/runtime4/array.c +++ b/runtime4/array.c @@ -414,6 +414,18 @@ CAMLprim value caml_floatarray_create_local(value len) return caml_alloc_local (wosize, Double_array_tag); } +// Stubs with consistent naming: + +CAMLprim value caml_make_unboxed_float64_vect(value len) +{ + return caml_floatarray_create(len); +} + +CAMLprim value caml_make_local_unboxed_float64_vect(value len) +{ + return caml_floatarray_create_local(len); +} + /* [len] is a [value] representing number of words or floats */ static value make_vect_gen(value len, value init, int local) { @@ -462,12 +474,12 @@ static value make_vect_gen(value len, value init, int local) for (i = 0; i < size; i++) Field(res, i) = init; } } - // Give the GC a chance to run, and run memprof callbacks + /* Give the GC a chance to run, and run memprof callbacks. + This matches the semantics of allocations directly from OCaml code. */ if (!local) caml_process_pending_actions (); CAMLreturn (res); } - CAMLprim value caml_make_vect(value len, value init) { return make_vect_gen(len, init, 0); @@ -478,6 +490,151 @@ CAMLprim value caml_make_local_vect(value len, value init) return make_vect_gen(len, init, 1); } +CAMLprim value caml_makearray_dynamic_non_scannable_unboxed_product( + value v_num_components, value v_is_local, + value v_non_unarized_length) +{ + // Some of this is similar to [caml_make_vect], above. + // This function is only used for native code. + + CAMLparam0(); + CAMLlocal1(res); + + mlsize_t num_components = Long_val(v_num_components); + int is_local = Bool_val(v_is_local); + mlsize_t non_unarized_length = Long_val(v_non_unarized_length); + mlsize_t size; + + if (sizeof(uintnat) != sizeof(double)) { + // Just make things easy as regards maximum array lengths for now. + // This should have been caught in [Lambda_to_flambda]. + caml_invalid_argument( + "%makearray_dynamic: only supported on 64-bit targets " + "(this is a compiler bug)"); + } + + int tag = 0; + // These arrays are always mixed blocks without packing. + // This currently differs from e.g. int32# array, which is allocated as a + // custom block, and is packed. + int reserved = Reserved_mixed_block_scannable_wosize_native(0); + + size = non_unarized_length * num_components; + if (size == 0) { + res = Atom(0); + } else if (num_components < 1) { + // This could happen with void layouts. We don't rule it out in + // [Lambda_to_flambda] since it is in fact ok, if the size is zero. + caml_invalid_argument( + "%makearray_dynamic: the only array that can be initialized with " + "nothing is a zero-length array"); + } else if (size > Max_array_wosize) { + caml_invalid_argument( + "%makearray_dynamic: array size too large (> Max_array_wosize)"); + } else if (is_local) { + res = caml_alloc_local_reserved(size, tag, reserved); + } else if (size <= Max_young_wosize) { + res = caml_alloc_small_with_reserved(size, tag, reserved); + } else { + res = caml_alloc_shr_reserved(size, tag, reserved); + } + + /* Give the GC a chance to run, and run memprof callbacks. + This matches the semantics of allocations directly from OCaml code. */ + // CR mshinwell: the other functions which allocate unboxed number arrays + // should also do this + if (!is_local) caml_process_pending_actions (); + + CAMLreturn(res); +} + +CAMLprim value caml_makearray_dynamic_scannable_unboxed_product( + value v_init, value v_is_local, value v_non_unarized_length) +{ + // Some of this is similar to [caml_make_vect], above. + + CAMLparam1(v_init); + CAMLlocal1(res); + + mlsize_t num_initializers = Wosize_val(v_init); + int is_local = Bool_val(v_is_local); + mlsize_t non_unarized_length = Long_val(v_non_unarized_length); + + mlsize_t size, i; + + // N.B. [v_init] may be on the local stack! + + if (sizeof(uintnat) != sizeof(double)) { + // Just make things easy as regards maximum array lengths for now. + // This should have been caught in [Lambda_to_flambda]. + caml_invalid_argument( + "%makearray_dynamic: only supported on 64-bit targets " + "(this is a compiler bug)"); + } + + int tag = 0; + + size = non_unarized_length * num_initializers; + if (size == 0) { + res = Atom(0); + } else if (num_initializers < 1) { + // This could happen with void layouts. We don't rule it out in + // [Lambda_to_flambda] since it is in fact ok, if the size is zero. + caml_invalid_argument( + "%makearray_dynamic: the only array that can be initialized with " + "nothing is a zero-length array"); + } else if (size > Max_array_wosize) { + caml_invalid_argument( + "%makearray_dynamic: array size too large (> Max_array_wosize)"); + } else if (is_local) { + res = caml_alloc_local(size, tag); + for (i = 0; i < size; i++) { + Field(res, i) = Field(v_init, i % num_initializers); + } + } else if (size <= Max_young_wosize) { + res = caml_alloc_small(size, tag); + for (i = 0; i < size; i++) { + Field(res, i) = Field(v_init, i % num_initializers); + } + } else { + int move_init_to_major = 0; + for (mlsize_t i = 0; i < num_initializers; i++) { + if (Is_block(Field(v_init, i)) && Is_young(Field(v_init, i))) { + move_init_to_major = 1; + } + } + if (move_init_to_major) { + /* We don't want to create so many major-to-minor references, + so the contents of [v_init] are moved to the major heap by doing + a minor GC. */ + /* CR mslater/mshinwell: Why is this better than adding them to the + remembered set with caml_initialize? See discussion in a + conversation on: + https://github.com/ocaml-flambda/flambda-backend/pull/3317 + */ + CAML_EV_COUNTER (EV_C_FORCE_MINOR_MAKE_VECT, 1); + caml_minor_collection (); + } +#ifdef DEBUG + for (mlsize_t i = 0; i < num_initializers; i++) { + CAMLassert(!(Is_block(Field(v_init, i)) && Is_young(Field(v_init, i)))); + } +#endif + res = caml_alloc_shr(size, tag); + /* We now know that everything in [v_init] is not in the minor heap, so + there is no need to call [caml_initialize]. */ + for (i = 0; i < size; i++) { + Field(res, i) = Field(v_init, i % num_initializers); + } + } + + /* Give the GC a chance to run, and run memprof callbacks. + This matches the semantics of allocations directly from OCaml code. */ + if (!is_local) caml_process_pending_actions (); + + CAMLreturn(res); +} + /* [len] is a [value] representing number of floats */ /* [ int -> float array ] */ CAMLprim value caml_make_float_vect(value len) @@ -494,18 +651,34 @@ CAMLprim value caml_make_float_vect(value len) #endif } -CAMLprim value caml_make_unboxed_int32_vect(value len) +static value caml_make_unboxed_int32_vect0(value len, int local) { /* This is only used on 64-bit targets. */ mlsize_t num_elements = Long_val(len); - if (num_elements > Max_unboxed_int32_array_wosize) caml_invalid_argument("Array.make"); + if (num_elements > Max_unboxed_int32_array_wosize) + caml_invalid_argument("Array.make"); /* [num_fields] does not include the custom operations field. */ mlsize_t num_fields = num_elements / 2 + num_elements % 2; - return caml_alloc_custom(&caml_unboxed_int32_array_ops[num_elements % 2], - num_fields * sizeof(value), 0, 0); + struct custom_operations* ops = + &caml_unboxed_int32_array_ops[num_elements % 2]; + + if (local) + return caml_alloc_custom_local(ops, num_fields * sizeof(value), 0, 0); + else + return caml_alloc_custom(ops, num_fields * sizeof(value), 0, 0); +} + +CAMLprim value caml_make_unboxed_int32_vect(value len) +{ + return caml_make_unboxed_int32_vect0(len, 0); +} + +CAMLprim value caml_make_local_unboxed_int32_vect(value len) +{ + return caml_make_unboxed_int32_vect0(len, 1); } CAMLprim value caml_make_unboxed_int32_vect_bytecode(value len) @@ -513,14 +686,28 @@ CAMLprim value caml_make_unboxed_int32_vect_bytecode(value len) return caml_make_vect(len, caml_copy_int32(0)); } -CAMLprim value caml_make_unboxed_int64_vect(value len) +static value caml_make_unboxed_int64_vect0(value len, int local) { mlsize_t num_elements = Long_val(len); - if (num_elements > Max_unboxed_int64_array_wosize) caml_invalid_argument("Array.make"); + if (num_elements > Max_unboxed_int64_array_wosize) + caml_invalid_argument("Array.make"); struct custom_operations* ops = &caml_unboxed_int64_array_ops; - return caml_alloc_custom(ops, num_elements * sizeof(value), 0, 0); + if (local) + return caml_alloc_custom_local(ops, num_elements * sizeof(value), 0, 0); + else + return caml_alloc_custom(ops, num_elements * sizeof(value), 0, 0); +} + +CAMLprim value caml_make_unboxed_int64_vect(value len) +{ + return caml_make_unboxed_int64_vect0(len, 0); +} + +CAMLprim value caml_make_local_unboxed_int64_vect(value len) +{ + return caml_make_unboxed_int64_vect0(len, 1); } CAMLprim value caml_make_unboxed_int64_vect_bytecode(value len) @@ -528,16 +715,30 @@ CAMLprim value caml_make_unboxed_int64_vect_bytecode(value len) return caml_make_vect(len, caml_copy_int64(0)); } -CAMLprim value caml_make_unboxed_nativeint_vect(value len) +static value caml_make_unboxed_nativeint_vect0(value len, int local) { /* This is only used on 64-bit targets. */ mlsize_t num_elements = Long_val(len); - if (num_elements > Max_unboxed_nativeint_array_wosize) caml_invalid_argument("Array.make"); + if (num_elements > Max_unboxed_nativeint_array_wosize) + caml_invalid_argument("Array.make"); struct custom_operations* ops = &caml_unboxed_nativeint_array_ops; - return caml_alloc_custom(ops, num_elements * sizeof(value), 0, 0); + if (local) + return caml_alloc_custom_local(ops, num_elements * sizeof(value), 0, 0); + else + return caml_alloc_custom(ops, num_elements * sizeof(value), 0, 0); +} + +CAMLprim value caml_make_unboxed_nativeint_vect(value len) +{ + return caml_make_unboxed_nativeint_vect0(len, 0); +} + +CAMLprim value caml_make_local_unboxed_nativeint_vect(value len) +{ + return caml_make_unboxed_nativeint_vect0(len, 1); } CAMLprim value caml_make_unboxed_nativeint_vect_bytecode(value len) @@ -963,3 +1164,6 @@ CAMLprim value caml_array_unsafe_set_indexed_by_nativeint(value, value, value); Array_access_index_by(int64, int64_t, Int64_val) Array_access_index_by(int32, int32_t, Int32_val) Array_access_index_by(nativeint, intnat, Nativeint_val) + +// XXX mshinwell: add the %makearray_dynamic prims here for runtime4 +// once the runtime5 versions have been reviewed and tested diff --git a/runtime4/caml/custom.h b/runtime4/caml/custom.h index 62dec5c6302..c319276c3f7 100644 --- a/runtime4/caml/custom.h +++ b/runtime4/caml/custom.h @@ -61,6 +61,13 @@ CAMLextern value caml_alloc_custom(struct custom_operations * ops, mlsize_t mem, /*resources consumed*/ mlsize_t max /*max resources*/); +// The local version will fail if a finalizer is supplied in the [ops], +// since finalizers on locally-allocated values are not yet supported. +CAMLextern value caml_alloc_custom_local(struct custom_operations * ops, + uintnat size, /*size in bytes*/ + mlsize_t mem, /*resources consumed*/ + mlsize_t max /*max resources*/); + CAMLextern value caml_alloc_custom_mem(struct custom_operations * ops, uintnat size, /*size in bytes*/ mlsize_t mem /*memory consumed*/); diff --git a/runtime4/caml/memory.h b/runtime4/caml/memory.h index e5204f92f96..d5c70413cbd 100644 --- a/runtime4/caml/memory.h +++ b/runtime4/caml/memory.h @@ -55,6 +55,7 @@ CAMLextern value caml_alloc_shr_no_track_noexc (mlsize_t, tag_t); CAMLextern value caml_alloc_shr_for_minor_gc (mlsize_t, tag_t, header_t); CAMLextern value caml_alloc_local(mlsize_t, tag_t); +CAMLextern value caml_alloc_local_reserved(mlsize_t, tag_t, reserved_t); CAMLextern void caml_adjust_gc_speed (mlsize_t, mlsize_t); CAMLextern void caml_alloc_dependent_memory (mlsize_t bsz); diff --git a/runtime4/custom.c b/runtime4/custom.c index 37d88f48cdc..48595a91518 100644 --- a/runtime4/custom.c +++ b/runtime4/custom.c @@ -35,7 +35,8 @@ static value alloc_custom_gen (struct custom_operations * ops, mlsize_t mem, mlsize_t max_major, mlsize_t mem_minor, - mlsize_t max_minor) + mlsize_t max_minor, + int local) { mlsize_t wosize; CAMLparam0(); @@ -46,7 +47,12 @@ static value alloc_custom_gen (struct custom_operations * ops, CAMLassert (mem_minor <= mem); wosize = 1 + (bsz + sizeof(value) - 1) / sizeof(value); - if (wosize <= Max_young_wosize) { + if (local) { + CAMLassert(ops->finalize == NULL); + result = caml_alloc_local(wosize, Custom_tag); + Custom_ops_val(result) = ops; + } + else if (wosize <= Max_young_wosize) { result = caml_alloc_small(wosize, Custom_tag); Custom_ops_val(result) = ops; if (ops->finalize != NULL || mem != 0) { @@ -81,7 +87,19 @@ CAMLexport value caml_alloc_custom(struct custom_operations * ops, mlsize_t mem, mlsize_t max) { - return alloc_custom_gen (ops, bsz, mem, max, mem, max); + return alloc_custom_gen (ops, bsz, mem, max, mem, max, 0); +} + +CAMLexport value caml_alloc_custom_local(struct custom_operations * ops, + uintnat bsz, + mlsize_t mem, + mlsize_t max) +{ + if (ops->finalize != NULL) + caml_invalid_argument( + "caml_alloc_custom_local: finalizers not supported"); + + return alloc_custom_gen (ops, bsz, mem, max, mem, max, 1); } CAMLexport value caml_alloc_custom_mem(struct custom_operations * ops, @@ -103,7 +121,8 @@ CAMLexport value caml_alloc_custom_mem(struct custom_operations * ops, Bsize_wsize (Caml_state->stat_heap_wsz) / 150 * caml_custom_major_ratio; mlsize_t max_minor = Bsize_wsize (Caml_state->minor_heap_wsz) / 100 * caml_custom_minor_ratio; - value v = alloc_custom_gen (ops, bsz, mem, max_major, mem_minor, max_minor); + value v = + alloc_custom_gen (ops, bsz, mem, max_major, mem_minor, max_minor, 0); caml_memprof_track_custom(v, mem); return v; } diff --git a/runtime4/float32.c b/runtime4/float32.c index aa046e9e865..5261e191efe 100644 --- a/runtime4/float32.c +++ b/runtime4/float32.c @@ -852,7 +852,7 @@ CAMLexport struct custom_operations caml_unboxed_float32_array_ops[2] = { custom_fixed_length_default }, }; -CAMLprim value caml_make_unboxed_float32_vect(value len) +static value caml_make_unboxed_float32_vect0(value len, int local) { /* This is only used on 64-bit targets. */ @@ -862,8 +862,23 @@ CAMLprim value caml_make_unboxed_float32_vect(value len) /* [num_fields] does not include the custom operations field. */ mlsize_t num_fields = num_elements / 2 + num_elements % 2; - return caml_alloc_custom(&caml_unboxed_float32_array_ops[num_elements % 2], - num_fields * sizeof(value), 0, 0); + struct custom_operations* ops = + &caml_unboxed_float32_array_ops[num_elements % 2]; + + if (local) + return caml_alloc_custom_local(ops, num_fields * sizeof(value), 0, 0); + else + return caml_alloc_custom(ops, num_fields * sizeof(value), 0, 0); +} + +CAMLprim value caml_make_unboxed_float32_vect(value len) +{ + return caml_make_unboxed_float32_vect0(len, 0); +} + +CAMLprim value caml_make_local_unboxed_float32_vect(value len) +{ + return caml_make_unboxed_float32_vect0(len, 1); } CAMLprim value caml_make_unboxed_float32_vect_bytecode(value len) diff --git a/runtime4/memory.c b/runtime4/memory.c index 1d2081d0bfb..195e98c7877 100644 --- a/runtime4/memory.c +++ b/runtime4/memory.c @@ -798,7 +798,8 @@ void caml_local_realloc(void) CAMLassert(Caml_state->local_limit <= Caml_state->local_sp); } -CAMLexport value caml_alloc_local(mlsize_t wosize, tag_t tag) +CAMLexport value caml_alloc_local_reserved(mlsize_t wosize, tag_t tag, + reserved_t reserved) { #if defined(NATIVE_CODE) && defined(STACK_ALLOCATION) intnat sp = Caml_state->local_sp; @@ -808,21 +809,26 @@ CAMLexport value caml_alloc_local(mlsize_t wosize, tag_t tag) if (sp < Caml_state->local_limit) caml_local_realloc(); hp = (header_t*)((char*)Caml_state->local_top + sp); - *hp = Make_header(wosize, tag, Local_unmarked); + *hp = Make_header_with_profinfo(wosize, tag, Local_unmarked, reserved); return Val_hp(hp); #else if (wosize <= Max_young_wosize) { - return caml_alloc_small(wosize, tag); + return caml_alloc_small_with_reserved(wosize, tag, reserved); } else { /* The return value is initialised directly using Field. This is invalid if it may create major -> minor pointers. So, perform a minor GC to prevent this. (See caml_make_vect) */ caml_minor_collection(); - return caml_alloc_shr(wosize, tag); + return caml_alloc_shr_reserved(wosize, tag, reserved); } #endif } +CAMLexport value caml_alloc_local(mlsize_t wosize, tag_t tag) +{ + return caml_alloc_local_reserved(wosize, tag, 0); +} + CAMLprim value caml_local_stack_offset(value blk) { #ifdef NATIVE_CODE diff --git a/runtime4/simd.c b/runtime4/simd.c index a9ae173772b..48986e06b2b 100644 --- a/runtime4/simd.c +++ b/runtime4/simd.c @@ -73,20 +73,37 @@ CAMLprim value caml_unboxed_vec128_vect_blit(value a1, value ofs1, value a2, return Val_unit; } -CAMLprim value caml_make_unboxed_vec128_vect(value len) { - /* This is only used on 64-bit targets. */ - - mlsize_t num_elements = Long_val(len); - if (num_elements > Max_unboxed_vec128_array_wosize) caml_invalid_argument("Array.make"); +static value caml_make_unboxed_vec128_vect0(value len, int local) +{ + /* This is only used on 64-bit targets. */ + + mlsize_t num_elements = Long_val(len); + if (num_elements > Max_unboxed_vec128_array_wosize) + caml_invalid_argument("Array.make"); + + /* [num_fields] does not include the custom operations field. */ + mlsize_t num_fields = num_elements * 2; + + if (local) + return caml_alloc_custom_local(&caml_unboxed_vec128_array_ops, + num_fields * sizeof(value), 0, 0); + else + return caml_alloc_custom(&caml_unboxed_vec128_array_ops, + num_fields * sizeof(value), 0, 0); +} - /* [num_fields] does not include the custom operations field. */ - mlsize_t num_fields = num_elements * 2; +CAMLprim value caml_make_unboxed_vec128_vect(value len) +{ + return caml_make_unboxed_vec128_vect0(len, 0); +} - return caml_alloc_custom(&caml_unboxed_vec128_array_ops, num_fields * sizeof(value), 0, 0); +CAMLprim value caml_make_local_unboxed_vec128_vect(value len) +{ + return caml_make_unboxed_vec128_vect0(len, 1); } CAMLprim value caml_make_unboxed_vec128_vect_bytecode(value len) { - caml_failwith("SIMD is not supported in bytecode mode."); + caml_failwith("SIMD is not supported on this platform."); } #else @@ -100,6 +117,10 @@ CAMLprim value caml_make_unboxed_vec128_vect(value len) { caml_failwith("SIMD is not supported on this platform."); } +CAMLprim value caml_make_local_unboxed_vec128_vect(value len) { + caml_failwith("SIMD is not supported on this platform."); +} + CAMLprim value caml_make_unboxed_vec128_vect_bytecode(value len) { caml_failwith("SIMD is not supported on this platform."); } diff --git a/testsuite/tests/typing-layouts-arrays/README.md b/testsuite/tests/typing-layouts-arrays/README.md new file mode 100644 index 00000000000..14c5a717d58 --- /dev/null +++ b/testsuite/tests/typing-layouts-arrays/README.md @@ -0,0 +1,34 @@ +This directory has tests for arrays of unboxed types. The tests assume the array +contains something that is like a number. + +Using the test framework here still involves a fair amount of copy and paste to +build your new test. This is mainly because we don't have layout polymorphism, +so it's not really possible to build it as one nice big functor. Hopefully we +can improve it in the future. + +## Basic use + +The files `gen_u_array.ml` and `test_gen_u_array.ml` contain the basic +framework. Rather than reading them, you are probably better off looking at an +example. E.g., see `test_int64_u_array.ml`. + +## Errors + +The testing framework is not very helpful in the event of errors - you'll get an +assertion failure with an uninformative backtrace. One way to debug is to +copy the framework and your test file elsewhere, compile and run it as a normal +ocaml program, then comment out parts of the big test functor from +`test_gen_u_array.ml` until you locate the line causing the error. This should +be improved. + +## Unboxed products + +The file `gen_product_array_helpers.ml` has additional infrastructure for +testing arrays of unboxed products. To add a new test, copy one of the existing +ones (e.g., `test_ignorable_product_array_1.ml`) and follow the instructions +in its comments about which parts you need to edit. + +Note that tests whose filename contains `with_uninit` use +`%makearray_dynamic_uninit` to create arrays, while other tests using this +infrastructure use `%makearray_dynamic`. + diff --git a/testsuite/tests/typing-layouts-arrays/basics_alpha.ml b/testsuite/tests/typing-layouts-arrays/basics_alpha.ml index 4b6074016e1..b52edd91f95 100644 --- a/testsuite/tests/typing-layouts-arrays/basics_alpha.ml +++ b/testsuite/tests/typing-layouts-arrays/basics_alpha.ml @@ -362,3 +362,302 @@ Error: This expression has type "float32#" because it's the type of an array element, chosen to have layout value. |}] + +(* Test 8: makearraydynamic_uninit *) + +external[@layout_poly] makearray_dynamic_uninit_local + : ('a : any_non_null) . int -> 'a array @ local = "%makearray_dynamic_uninit" + +external[@layout_poly] makearray_dynamic_uninit + : ('a : any_non_null) . int -> 'a array = "%makearray_dynamic_uninit" +[%%expect{| +external makearray_dynamic_uninit_local : + ('a : any_non_null). int -> local_ 'a array = "%makearray_dynamic_uninit" + [@@layout_poly] +external makearray_dynamic_uninit : ('a : any_non_null). int -> 'a array + = "%makearray_dynamic_uninit" [@@layout_poly] +|}] + +type ('a : any) with_i64s = #( int64# * 'a * int64# ) + +type ok_1 = #(int64# * int32#) +type ok_2 = float# with_i64s + +type bad_1 = #(int * int32#) +type bad_2 = int +type bad_3 = A | B | C +type bad_4 = #{ a: int64# ; enum : bad_3 } +type bad_5 = bad_3 with_i64s +type bad_6 = #(float * #(float * float) * #(float * #(float * float * float))) +type bad_7 = #{ i : int64# ; bad_4 : bad_4 ; j : int64# } +[%%expect{| +type ('a : any) with_i64s = #(int64# * 'a * int64#) +type ok_1 = #(int64# * int32#) +type ok_2 = float# with_i64s +type bad_1 = #(int * int32#) +type bad_2 = int +type bad_3 = A | B | C +type bad_4 = #{ a : int64#; enum : bad_3; } +type bad_5 = bad_3 with_i64s +type bad_6 = + #(float * #(float * float) * #(float * #(float * float * float))) +type bad_7 = #{ i : int64#; bad_4 : bad_4; j : int64#; } +|}] + +(* Allowed usages *) + +let _ = + (makearray_dynamic_uninit 0 : float# array) +[%%expect{| +- : float# array = [||] +|}] + +let _ = + (makearray_dynamic_uninit 0 : ok_1 array) +[%%expect{| +- : ok_1 array = [||] +|}] + +let _ = + (makearray_dynamic_uninit 0 : ok_2 array) +[%%expect{| +- : ok_2 array = [||] +|}] + +(* Disallowed usages *) + +let _ = + (makearray_dynamic_uninit 0 : int array) +[%%expect{| +Line 2, characters 2-28: +2 | (makearray_dynamic_uninit 0 : int array) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: %makearray_dynamic_uninit can only be used for GC-ignorable arrays + not involving tagged immediates; and arrays of unboxed numbers. + Use %makearray instead, providing an initializer. +|}] + +let _ = + (makearray_dynamic_uninit 0 : float array) +[%%expect{| +Line 2, characters 2-28: +2 | (makearray_dynamic_uninit 0 : float array) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: %makearray_dynamic_uninit can only be used for GC-ignorable arrays + not involving tagged immediates; and arrays of unboxed numbers. + Use %makearray instead, providing an initializer. +|}] + +let _ = + (makearray_dynamic_uninit 0 : #(int64# * int) array) +[%%expect{| +Line 2, characters 2-28: +2 | (makearray_dynamic_uninit 0 : #(int64# * int) array) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: %makearray_dynamic_uninit can only be used for GC-ignorable arrays + not involving tagged immediates; and arrays of unboxed numbers. + Use %makearray instead, providing an initializer. +|}] + +let _ = + (makearray_dynamic_uninit 0 : bad_1 array) +[%%expect{| +Line 2, characters 2-28: +2 | (makearray_dynamic_uninit 0 : bad_1 array) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: %makearray_dynamic_uninit can only be used for GC-ignorable arrays + not involving tagged immediates; and arrays of unboxed numbers. + Use %makearray instead, providing an initializer. +|}] + +let _ = + (makearray_dynamic_uninit 0 : bad_2 array) +[%%expect{| +Line 2, characters 2-28: +2 | (makearray_dynamic_uninit 0 : bad_2 array) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: %makearray_dynamic_uninit can only be used for GC-ignorable arrays + not involving tagged immediates; and arrays of unboxed numbers. + Use %makearray instead, providing an initializer. +|}] + +let _ = + (makearray_dynamic_uninit 0 : bad_3 array) +[%%expect{| +Line 2, characters 2-28: +2 | (makearray_dynamic_uninit 0 : bad_3 array) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: %makearray_dynamic_uninit can only be used for GC-ignorable arrays + not involving tagged immediates; and arrays of unboxed numbers. + Use %makearray instead, providing an initializer. +|}] + +let _ = + (makearray_dynamic_uninit 0 : bad_4 array) +[%%expect{| +Line 2, characters 2-28: +2 | (makearray_dynamic_uninit 0 : bad_4 array) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: %makearray_dynamic_uninit can only be used for GC-ignorable arrays + not involving tagged immediates; and arrays of unboxed numbers. + Use %makearray instead, providing an initializer. +|}] + +let _ = + (makearray_dynamic_uninit 0 : bad_5 array) +[%%expect{| +Line 2, characters 2-28: +2 | (makearray_dynamic_uninit 0 : bad_5 array) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: %makearray_dynamic_uninit can only be used for GC-ignorable arrays + not involving tagged immediates; and arrays of unboxed numbers. + Use %makearray instead, providing an initializer. +|}] + +let _ = + (makearray_dynamic_uninit 0 : bad_6 array) +[%%expect{| +Line 2, characters 2-28: +2 | (makearray_dynamic_uninit 0 : bad_6 array) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: %makearray_dynamic_uninit can only be used for GC-ignorable arrays + not involving tagged immediates; and arrays of unboxed numbers. + Use %makearray instead, providing an initializer. +|}] + +let _ = + (makearray_dynamic_uninit 0 : bad_7 array) +[%%expect{| +Line 2, characters 3-29: +2 | (makearray_dynamic_uninit 0 : bad_7 array) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: %makearray_dynamic_uninit can only be used for GC-ignorable arrays + not involving tagged immediates; and arrays of unboxed numbers. + Use %makearray instead, providing an initializer. +|}] + +(* Allowed usages (local) *) + +let _ = + let _ = (makearray_dynamic_uninit_local 0 : ok_1 array) in + () +[%%expect{| +- : unit = () +|}] + +let _ = + let _ = (makearray_dynamic_uninit_local 0 : ok_2 array) in + () +[%%expect{| +- : unit = () +|}] + +(* Disallowed usages (local) *) + +let _ = + let _ = (makearray_dynamic_uninit_local 0 : int array) in + () +[%%expect{| +Line 2, characters 10-42: +2 | let _ = (makearray_dynamic_uninit_local 0 : int array) in + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: %makearray_dynamic_uninit can only be used for GC-ignorable arrays + not involving tagged immediates; and arrays of unboxed numbers. + Use %makearray instead, providing an initializer. +|}] + +let _ = + let _ = (makearray_dynamic_uninit_local 0 : #(int64# * int) array) in + () +[%%expect{| +Line 2, characters 10-42: +2 | let _ = (makearray_dynamic_uninit_local 0 : #(int64# * int) array) in + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: %makearray_dynamic_uninit can only be used for GC-ignorable arrays + not involving tagged immediates; and arrays of unboxed numbers. + Use %makearray instead, providing an initializer. +|}] + +let _ = + let _ = (makearray_dynamic_uninit_local 0 : bad_1 array) in + () +[%%expect{| +Line 2, characters 10-42: +2 | let _ = (makearray_dynamic_uninit_local 0 : bad_1 array) in + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: %makearray_dynamic_uninit can only be used for GC-ignorable arrays + not involving tagged immediates; and arrays of unboxed numbers. + Use %makearray instead, providing an initializer. +|}] + +let _ = + let _ = (makearray_dynamic_uninit_local 0 : bad_2 array) in + () +[%%expect{| +Line 2, characters 10-42: +2 | let _ = (makearray_dynamic_uninit_local 0 : bad_2 array) in + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: %makearray_dynamic_uninit can only be used for GC-ignorable arrays + not involving tagged immediates; and arrays of unboxed numbers. + Use %makearray instead, providing an initializer. +|}] + +let _ = + let _ = (makearray_dynamic_uninit_local 0 : bad_3 array) in + () +[%%expect{| +Line 2, characters 10-42: +2 | let _ = (makearray_dynamic_uninit_local 0 : bad_3 array) in + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: %makearray_dynamic_uninit can only be used for GC-ignorable arrays + not involving tagged immediates; and arrays of unboxed numbers. + Use %makearray instead, providing an initializer. +|}] + +let _ = + let _ = (makearray_dynamic_uninit_local 0 : bad_4 array) in + () +[%%expect{| +Line 2, characters 10-42: +2 | let _ = (makearray_dynamic_uninit_local 0 : bad_4 array) in + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: %makearray_dynamic_uninit can only be used for GC-ignorable arrays + not involving tagged immediates; and arrays of unboxed numbers. + Use %makearray instead, providing an initializer. +|}] + +let _ = + let _ = (makearray_dynamic_uninit_local 0 : bad_5 array) in + () +[%%expect{| +Line 2, characters 10-42: +2 | let _ = (makearray_dynamic_uninit_local 0 : bad_5 array) in + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: %makearray_dynamic_uninit can only be used for GC-ignorable arrays + not involving tagged immediates; and arrays of unboxed numbers. + Use %makearray instead, providing an initializer. +|}] + +let _ = + let _ = (makearray_dynamic_uninit_local 0 : bad_6 array) in + () +[%%expect{| +Line 2, characters 10-42: +2 | let _ = (makearray_dynamic_uninit_local 0 : bad_6 array) in + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: %makearray_dynamic_uninit can only be used for GC-ignorable arrays + not involving tagged immediates; and arrays of unboxed numbers. + Use %makearray instead, providing an initializer. +|}] + +let _ = + let _ = (makearray_dynamic_uninit_local 0 : bad_7 array) in + () +[%%expect{| +Line 2, characters 11-43: +2 | let _ = (makearray_dynamic_uninit_local 0 : bad_7 array) in + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: %makearray_dynamic_uninit can only be used for GC-ignorable arrays + not involving tagged immediates; and arrays of unboxed numbers. + Use %makearray instead, providing an initializer. +|}] diff --git a/testsuite/tests/typing-layouts-arrays/gen_product_array_helpers.ml b/testsuite/tests/typing-layouts-arrays/gen_product_array_helpers.ml new file mode 100644 index 00000000000..296563970a0 --- /dev/null +++ b/testsuite/tests/typing-layouts-arrays/gen_product_array_helpers.ml @@ -0,0 +1,353 @@ +module type Element_intf = Test_gen_u_array.Element_intf + +type 'a elem = + | Number : { ops : (module Element_intf with type t = 'a) } -> 'a elem + | Option : 'a elem -> ('a option) elem + | Tup2 : 'a1 elem * 'a2 elem -> ('a1 * 'a2) elem + | Tup3 : 'a1 elem * 'a2 elem * 'a3 elem -> ('a1 * 'a2 * 'a3) elem + | Tup4 : 'a1 elem * 'a2 elem * 'a3 elem * 'a4 elem + -> ('a1 * 'a2 * 'a3 * 'a4) elem + | Tup5 : 'a1 elem * 'a2 elem * 'a3 elem * 'a4 elem * 'a5 elem + -> ('a1 * 'a2 * 'a3 * 'a4 * 'a5) elem + | Tup6 : 'a1 elem * 'a2 elem * 'a3 elem * 'a4 elem * 'a5 elem * 'a6 elem + -> ('a1 * 'a2 * 'a3 * 'a4 * 'a5 * 'a6) elem + +module Int_elem : Element_intf with type t = int = +struct + include Int + let of_int x = x + let max_val = max_int + let min_val = min_int + let rand = Random.full_int + let print i = Printf.printf "%d" i +end + +let int_elem = Number { ops = (module Int_elem) } + +module Int32_elem : Element_intf with type t = int32 = +struct + include Int32 + let max_val = max_int + let min_val = min_int + let rand = Random.int32 + let print i = Printf.printf "%ld" i +end + +let int32_elem = Number { ops = (module Int32_elem) } + +module Int64_elem : Element_intf with type t = int64 = +struct + include Int64 + let max_val = max_int + let min_val = min_int + let rand = Random.int64 + let print i = Printf.printf "%Ld" i +end + +let int64_elem = Number { ops = (module Int64_elem) } + +module Nativeint_elem : Element_intf with type t = nativeint = +struct + include Nativeint + let max_val = max_int + let min_val = min_int + let rand = Random.nativeint + let print i = Printf.printf "%nd" i +end + +let nativeint_elem = Number { ops = (module Nativeint_elem) } + +module Float_elem : Element_intf with type t = float = +struct + include Float + let max_val = max_float + let min_val = min_float + let rand = Random.float + let print i = Printf.printf "%f" i +end + +let float_elem = Number { ops = (module Float_elem) } + +module Float32_elem : Element_intf with type t = float32 = +struct + include Stdlib_stable.Float32 + let max_val = max_float + let min_val = min_float + let rand x = of_float (Random.float (to_float x)) + let print i = Printf.printf "%f" (to_float i) +end + +let float32_elem = Number { ops = (module Float32_elem) } + +let traverse0 (f : 'a. (module Element_intf with type t = 'a) -> 'a) = + let rec go : type a . a elem -> a = + fun (elem : a elem) -> + match elem with + | Number {ops} -> f ops + | Option elem -> Some (go elem) + | Tup2 (e1, e2) -> (go e1, go e2) + | Tup3 (e1, e2, e3) -> (go e1, go e2, go e3) + | Tup4 (e1, e2, e3, e4) -> (go e1, go e2, go e3, go e4) + | Tup5 (e1, e2, e3, e4, e5) -> (go e1, go e2, go e3, go e4, go e5) + | Tup6 (e1, e2, e3, e4, e5, e6) -> + (go e1, go e2, go e3, go e4, go e5, go e6) + in + go + +let traverse1 (f : 'a. (module Element_intf with type t = 'a) -> 'a -> 'a) = + let rec go : type a . a elem -> a -> a = + fun (elem : a elem) (a : a) -> + match elem with + | Number {ops} -> f ops a + | Option elem -> Option.map (go elem) a + | Tup2 (e1, e2) -> + let a1, a2 = a in + (go e1 a1, go e2 a2) + | Tup3 (e1, e2, e3) -> + let a1, a2, a3 = a in + (go e1 a1, go e2 a2, go e3 a3) + | Tup4 (e1, e2, e3, e4) -> + let a1, a2, a3, a4 = a in + (go e1 a1, go e2 a2, go e3 a3, go e4 a4) + | Tup5 (e1, e2, e3, e4, e5) -> + let a1, a2, a3, a4, a5 = a in + (go e1 a1, go e2 a2, go e3 a3, go e4 a4, go e5 a5) + | Tup6 (e1, e2, e3, e4, e5, e6) -> + let a1, a2, a3, a4, a5, a6 = a in + (go e1 a1, go e2 a2, go e3 a3, go e4 a4, go e5 a5, go e6 a6) + in + go + +let traverse2 + (f : 'a. (module Element_intf with type t = 'a) -> 'a -> 'a -> 'a) = + let rec go : type a . a elem -> a -> a -> a = + fun (elem : a elem) (a1 : a) (a2 : a) -> + match elem with + | Number {ops} -> f ops a1 a2 + | Option elem -> + begin match a1, a2 with + | None, _ | _, None -> None + | Some a1, Some a2 -> Some (go elem a1 a2) + end + | Tup2 (e1, e2) -> + let a11, a12 = a1 in + let a21, a22 = a2 in + (go e1 a11 a21, go e2 a12 a22) + | Tup3 (e1, e2, e3) -> + let a11, a12, a13 = a1 in + let a21, a22, a23 = a2 in + (go e1 a11 a21, go e2 a12 a22, go e3 a13 a23) + | Tup4 (e1, e2, e3, e4) -> + let a11, a12, a13, a14 = a1 in + let a21, a22, a23, a24 = a2 in + (go e1 a11 a21, go e2 a12 a22, go e3 a13 a23, go e4 a14 a24) + | Tup5 (e1, e2, e3, e4, e5) -> + let a11, a12, a13, a14, a15 = a1 in + let a21, a22, a23, a24, a25 = a2 in + (go e1 a11 a21, go e2 a12 a22, go e3 a13 a23, go e4 a14 a24, + go e5 a15 a25) + | Tup6 (e1, e2, e3, e4, e5, e6) -> + let a11, a12, a13, a14, a15, a16 = a1 in + let a21, a22, a23, a24, a25, a26 = a2 in + (go e1 a11 a21, go e2 a12 a22, go e3 a13 a23, go e4 a14 a24, + go e5 a15 a25, go e6 a16 a26) + in + go + +let rec of_int : type a . a elem -> int -> a = + fun elem i -> + match elem with + | Number {ops} -> + let module O = (val ops) in + O.of_int i + | Option elem -> Some (of_int elem i) + | Tup2 (e1, e2) -> (of_int e1 i, of_int e2 i) + | Tup3 (e1, e2, e3) -> (of_int e1 i, of_int e2 i, of_int e3 i) + | Tup4 (e1, e2, e3, e4) -> + (of_int e1 i, of_int e2 i, of_int e3 i, of_int e4 i) + | Tup5 (e1, e2, e3, e4, e5) -> + (of_int e1 i, of_int e2 i, of_int e3 i, of_int e4 i, of_int e5 i) + | Tup6 (e1, e2, e3, e4, e5, e6) -> + (of_int e1 i, of_int e2 i, of_int e3 i, of_int e4 i, of_int e5 i, + of_int e6 i) + +let add elem a1 a2 = + let f (type a) (module E : Element_intf with type t = a) (a1 : a) (a2 : a) = + E.add a1 a2 + in + traverse2 f elem a1 a2 + +let sub elem a1 a2 = + let f (type a) (module E : Element_intf with type t = a) (a1 : a) (a2 : a) = + E.sub a1 a2 + in + traverse2 f elem a1 a2 + +let mul elem a1 a2 = + let f (type a) (module E : Element_intf with type t = a) (a1 : a) (a2 : a) = + E.mul a1 a2 + in + traverse2 f elem a1 a2 + +let neg elem a = + let f (type a) (module E : Element_intf with type t = a) (a : a) = + E.neg a + in + traverse1 f elem a + +let max_val elem = + let f (type a) (module E : Element_intf with type t = a) = + E.max_val + in + traverse0 f elem + +let min_val elem = + let rec go : type a . a elem -> a = + fun (elem : a elem) -> + match elem with + | Number {ops} -> + let module E = (val ops) in + E.min_val + | Option elem -> None + | Tup2 (e1, e2) -> (go e1, go e2) + | Tup3 (e1, e2, e3) -> (go e1, go e2, go e3) + | Tup4 (e1, e2, e3, e4) -> (go e1, go e2, go e3, go e4) + | Tup5 (e1, e2, e3, e4, e5) -> (go e1, go e2, go e3, go e4, go e5) + | Tup6 (e1, e2, e3, e4, e5, e6) -> + (go e1, go e2, go e3, go e4, go e5, go e6) + in + go elem + +let rand elem a = + let f (type a) (module E : Element_intf with type t = a) (a : a) = + E.rand a + in + traverse1 f elem a + +let rec compare : type a . a elem -> a -> a -> int = + fun elem a1 a2 -> + match elem with + | Number {ops} -> + let module E = (val ops) in + E.compare a1 a2 + | Option elem -> Option.compare (compare elem) a1 a2 + | Tup2 (e1, e2) -> + let a11, a12 = a1 in + let a21, a22 = a2 in + let x = compare e1 a11 a21 in + if x <> 0 then x + else compare e2 a12 a22 + | Tup3 (e1, e2, e3) -> + let a11, a12, a13 = a1 in + let a21, a22, a23 = a2 in + let x = compare e1 a11 a21 in + if x <> 0 then x + else + let x = compare e2 a12 a22 in + if x <> 0 then x else compare e3 a13 a23 + | Tup4 (e1, e2, e3, e4) -> + let a11, a12, a13, a14 = a1 in + let a21, a22, a23, a24 = a2 in + let x = compare e1 a11 a21 in + if x <> 0 then x + else + let x = compare e2 a12 a22 in + if x <> 0 then x else + let x = compare e3 a13 a23 in + if x <> 0 then x else compare e4 a14 a24 + | Tup5 (e1, e2, e3, e4, e5) -> + let a11, a12, a13, a14, a15 = a1 in + let a21, a22, a23, a24, a25 = a2 in + let x = compare e1 a11 a21 in + if x <> 0 then x + else + let x = compare e2 a12 a22 in + if x <> 0 then x else + let x = compare e3 a13 a23 in + if x <> 0 then x else + let x = compare e4 a14 a24 in + if x <> 0 then x else compare e5 a15 a25 + | Tup6 (e1, e2, e3, e4, e5, e6) -> + let a11, a12, a13, a14, a15, a16 = a1 in + let a21, a22, a23, a24, a25, a26 = a2 in + let x = compare e1 a11 a21 in + if x <> 0 then x + else + let x = compare e2 a12 a22 in + if x <> 0 then x else + let x = compare e3 a13 a23 in + if x <> 0 then x else + let x = compare e4 a14 a24 in + if x <> 0 then x else + let x = compare e5 a15 a25 in + if x <> 0 then x else + compare e6 a16 a26 + +let rec print : type a . a elem -> a -> unit = + let open struct + type packed = P : 'a elem * 'a -> packed + + let print_comma_sep l = + Printf.printf "("; + let rec go l = + match l with + | [] -> assert false + | [P (e,a)] -> + print e a; + Printf.printf ")" + | (P (e,a)) :: l -> + print e a; + Printf.printf ", "; + go l + in + go l + end + in + fun elem a -> + match elem with + | Number {ops} -> + let module E = (val ops) in + E.print a + | Option elem -> + begin match a with + | None -> Printf.printf "None" + | Some a -> begin + Printf.printf "Some "; + print elem a + end + end + | Tup2 (e1, e2) -> + let a1, a2 = a in + print_comma_sep [P (e1, a1); P (e2, a2)] + | Tup3 (e1, e2, e3) -> + let a1, a2, a3 = a in + print_comma_sep [P (e1, a1); P (e2, a2); P (e3, a3)] + | Tup4 (e1, e2, e3, e4) -> + let a1, a2, a3, a4 = a in + print_comma_sep [P (e1, a1); P (e2, a2); P (e3, a3); P (e4, a4)] + | Tup5 (e1, e2, e3, e4, e5) -> + let a1, a2, a3, a4, a5 = a in + print_comma_sep + [P (e1, a1); P (e2, a2); P (e3, a3); P (e4, a4); P (e5, a5)] + | Tup6 (e1, e2, e3, e4, e5, e6) -> + let a1, a2, a3, a4, a5, a6 = a in + print_comma_sep + [P (e1, a1); P (e2, a2); P (e3, a3); P (e4, a4); P (e5, a5); + P (e6, a6)] + +let make_element_ops (type a) (elem : a elem) + : (module Element_intf with type t = a) = + (module struct + type t = a + + let of_int i = of_int elem i + let add t1 t2 = add elem t1 t2 + let sub t1 t2 = sub elem t1 t2 + let mul t1 t2 = mul elem t1 t2 + let neg t = neg elem t + let max_val = max_val elem + let min_val = min_val elem + let rand t = rand elem t + let compare t1 t2 = compare elem t1 t2 + let print t = print elem t + end) diff --git a/testsuite/tests/typing-layouts-arrays/gen_product_array_helpers.mli b/testsuite/tests/typing-layouts-arrays/gen_product_array_helpers.mli new file mode 100644 index 00000000000..2ba44fb0ad1 --- /dev/null +++ b/testsuite/tests/typing-layouts-arrays/gen_product_array_helpers.mli @@ -0,0 +1,26 @@ +(* This module defines some helpers for writing tests on arays of unboxed + products. See [README.md] in this directory. *) + +module type Element_intf = Test_gen_u_array.Element_intf + +type 'a elem = + | Number : { ops : (module Element_intf with type t = 'a) } -> 'a elem + | Option : 'a elem -> ('a option) elem + | Tup2 : 'a1 elem * 'a2 elem -> ('a1 * 'a2) elem + | Tup3 : 'a1 elem * 'a2 elem * 'a3 elem -> ('a1 * 'a2 * 'a3) elem + | Tup4 : 'a1 elem * 'a2 elem * 'a3 elem * 'a4 elem + -> ('a1 * 'a2 * 'a3 * 'a4) elem + | Tup5 : 'a1 elem * 'a2 elem * 'a3 elem * 'a4 elem * 'a5 elem + -> ('a1 * 'a2 * 'a3 * 'a4 * 'a5) elem + | Tup6 : 'a1 elem * 'a2 elem * 'a3 elem * 'a4 elem * 'a5 elem * 'a6 elem + -> ('a1 * 'a2 * 'a3 * 'a4 * 'a5 * 'a6) elem + +val int_elem : int elem +val int32_elem : int32 elem +val int64_elem : int64 elem +val nativeint_elem : nativeint elem + +val float_elem : float elem +val float32_elem : float32 elem + +val make_element_ops : 'a elem -> (module Element_intf with type t = 'a) diff --git a/testsuite/tests/typing-layouts-arrays/generate_makearray_dynamic_tests.ml b/testsuite/tests/typing-layouts-arrays/generate_makearray_dynamic_tests.ml new file mode 100644 index 00000000000..2fb1aaa1827 --- /dev/null +++ b/testsuite/tests/typing-layouts-arrays/generate_makearray_dynamic_tests.ml @@ -0,0 +1,682 @@ +(* This file is used in [run_makearray_dynamic_tests.ml]. *) +open Stdlib_upstream_compatible +open Stdlib_stable +module List = ListLabels +module String = StringLabels + +let failwithf fmt = Printf.ksprintf failwith fmt +let sprintf = Printf.sprintf + +(* See [test_makearray_dynamic] for the main testing steps! *) + +module Ty : sig + (* A type in the generated code *) + type t = { + ty_code : string; + (* Code for this type expression (e.g. "int option * float") *) + value_code : int -> string; + (* Given some integer seed, generate code for a value of this type. + E.g. passing 3 gives "(Some 3, 3.)" for [int option * float]. *) + mk_value_code : string; + (* Code that dynamically implements [value_code], creating a value from an + integer seed bound to "i". + We should be able to generate this code: + "let mk_value (i : int) : $ty_code = $mk_value_code" *) + eq : string; + (* A function that implements equality in the generated code. + We should be able generate this code: + "let eq : $ty_code @ local -> $ty_code @ local -> bool = $eq" *) + is_gc_ignorable : bool; + (* Whether type only contains non-values/immediates (this used to gate + blit tests, but now that blits work for all types, this field is + unused). *) + } + + (* Generate typedecls for user-defined nominal types that have been created *) + val decls_code : unit -> string list + + (* Takes the record name and (label_name, label_type) pairs *) + val unboxed_record : string -> (string * t) list -> t + + (* [enum 3] represents [type enum3 = A3_0 | A3_1 | A3_2]. *) + val enum : int -> t + + (* Structural and built-in types *) + + val option : t -> t + val tuple : t list -> t + val unboxed_tuple : t list -> t + + val int : t + val float : t + val float_u : t + val float32 : t + val float32_u : t + val int32 : t + val int32_u : t + val int64 : t + val int64_u : t + val nativeint : t + val nativeint_u : t +end = struct + type t = { + ty_code : string; + value_code : int -> string; + mk_value_code : string; + eq : string; + is_gc_ignorable : bool; + } + + let ty_code t = t.ty_code + let value_code t = t.value_code + let mk_value_code t = t.mk_value_code + let is_gc_ignorable t = t.is_gc_ignorable + + let map_value_code ts i = List.map ts ~f:(fun t -> t.value_code i) + + (* If (name, decl) is in this list, we'll generate "type $name = $decl" *) + let decls : (string * string) list ref = ref [] + + let decls_code () = + (* [!decls] is only reversed for aesthetic reasons. *) + List.mapi (List.rev !decls) ~f:(fun i (name, def) -> + (if i == 0 then "type " else "and ") ^ name ^ " = " ^ def + ) + + let add_decl ~name ~def = + match List.assoc_opt name !decls with + | Some def' -> + if not (String.equal def def') then + failwithf + "%s has conflicting definitions:\n %s\nand\n %s" name def' def + | None -> decls := (name, def) :: !decls + + let unboxed_record name labeled_ts = + let lbls, ts = List.split labeled_ts in + let assemble colon_or_eq fields = + let labeled_fields = + List.map2 lbls fields ~f:(fun s x -> s ^ " " ^ colon_or_eq ^ " " ^ x) + in + "#{ " ^ String.concat ~sep:"; " labeled_fields ^ " }" + in + let assemble_expr fields = "(" ^ assemble "=" fields ^ " : " ^ name ^ ")" in + let value_code i = assemble_expr (map_value_code ts i) in + let mk_value_code = assemble_expr (List.map ts ~f:mk_value_code) in + let pat i = + assemble_expr (List.map lbls ~f:(fun s -> s ^ Int.to_string i)) + in + let eq = + let body = + List.map labeled_ts ~f:(fun (s, t) -> sprintf "%s %s1 %s2" t.eq s s) + |> String.concat ~sep:" && " + in + sprintf "(fun %s %s -> %s)" (pat 1) (pat 2) body + in + add_decl ~name ~def:(assemble ":" (List.map ts ~f:ty_code)); + { + ty_code = name; + value_code; + mk_value_code; + eq; + is_gc_ignorable = List.for_all ~f:is_gc_ignorable ts; + } + + let enum size = + let ith_ctor i = sprintf "A%d_%d" size i in + let def = List.init ~len:size ~f:ith_ctor |> String.concat ~sep:" | " in + let eq = + let eq_pat = + List.init ~len:size ~f:(fun i -> ith_ctor i ^ ", " ^ ith_ctor i) + |> String.concat ~sep:" | " + in + sprintf "(fun a b -> match a, b with %s -> true | _ -> false)" eq_pat + in + let mk_value_code = + let brs = + List.init ~len:size ~f:(fun i -> sprintf "%d -> %s" i (ith_ctor i)) + @ ["_ -> assert false"] + in + sprintf "(match Int.rem i %d with %s)" size (String.concat ~sep:" | " brs) + in + let name = sprintf "enum%d" size in + add_decl ~name ~def; + { + ty_code = name; + value_code = (fun i -> ith_ctor (Int.rem i size)); + mk_value_code; + eq; + is_gc_ignorable = true; + } + + let option t = { + ty_code = t.ty_code ^ " option"; + value_code = + (fun i -> if i == 0 then "None" else "Some " ^ t.value_code i); + mk_value_code = + "(if i == 0 then None else Some (" ^ t.mk_value_code ^ "))"; + eq = "(fun a b -> match a, b with None,None -> true | Some a,Some b -> " + ^ t.eq ^ " a b|_->false)"; + is_gc_ignorable = false; + } + + let gen_tuple ~unboxed ts = + let hash = if unboxed then "#" else "" in + let assemble ~sep xs = sprintf "%s(%s)" hash (String.concat ~sep xs) in + let value_code i = assemble ~sep:", " (map_value_code ts i) in + let mk_value_code = assemble ~sep:", " (List.map ts ~f:mk_value_code) in + let eq = + let pat s = + assemble ~sep:", " (List.mapi ts ~f:(fun i _ -> s ^ Int.to_string i)) + in + let body = + List.mapi ts ~f:(fun i t -> sprintf "%s a%d b%d" t.eq i i) + |> String.concat ~sep:" && " + in + sprintf "(fun %s %s -> %s)" (pat "a") (pat "b") body + in + { + ty_code = assemble ~sep:" * " (List.map ts ~f:ty_code); + value_code; + mk_value_code; + eq; + is_gc_ignorable = unboxed && List.for_all ~f:is_gc_ignorable ts; + } + + let tuple = gen_tuple ~unboxed:false + + let unboxed_tuple = gen_tuple ~unboxed:true + + let int = { + ty_code = "int"; + value_code = Int.to_string; + mk_value_code = "i"; + eq = "(fun a b -> Int.equal a b)"; + is_gc_ignorable = true; + } + + let float = { + ty_code = "float"; + value_code = (fun i -> Int.to_string i ^ "."); + mk_value_code = "Float.of_int i"; + eq = "(fun a b -> Float.equal (globalize a) (globalize b))"; + is_gc_ignorable = false; + } + + let float_u = { + ty_code = "float#"; + value_code = (fun i -> "#" ^ Int.to_string i ^ "."); + mk_value_code = "Float_u.of_int i"; + eq = "(fun a b -> Float_u.(equal (add #0. a) (add #0. b)))"; + is_gc_ignorable = true; + } + + let float32 = { + ty_code = "float32"; + value_code = (fun i -> Int.to_string i ^ ".s"); + mk_value_code = "Float32.of_int i"; + eq = "(fun a b -> Float.equal (Float32.to_float a) (Float32.to_float b))"; + is_gc_ignorable = false; + } + + let float32_u = { + ty_code = "float32#"; + value_code = (fun i -> "#" ^ Int.to_string i ^ ".s"); + mk_value_code = "Float32_u.of_int i"; + eq = "(fun a b -> Float32_u.(equal (add #0.s a) (add #0.s b)))"; + is_gc_ignorable = true; + } + + let int32 = { + ty_code = "int32"; + value_code = (fun i -> Int.to_string i ^ "l"); + mk_value_code = "Int32.of_int i"; + eq = "(fun a b -> Int32.equal (globalize a) (globalize b))"; + is_gc_ignorable = false; + } + + let int32_u = { + ty_code = "int32#"; + value_code = (fun i -> "#" ^ Int.to_string i ^ "l"); + mk_value_code = "Int32_u.of_int i"; + eq = "(fun a b -> Int32_u.(equal (add #0l a) (add #0l b)))"; + is_gc_ignorable = true; + } + + let int64 = { + ty_code = "int64"; + value_code = (fun i -> Int.to_string i ^ "L"); + mk_value_code = "Int64.of_int i"; + eq = "(fun a b -> Int64.equal (globalize a) (globalize b))"; + is_gc_ignorable = false; + } + + let int64_u = { + ty_code = "int64#"; + value_code = (fun i -> "#" ^ Int.to_string i ^ "L"); + mk_value_code = "Int64_u.of_int i"; + eq = "(fun a b -> Int64_u.(equal (add #0L a) (add #0L b)))"; + is_gc_ignorable = true; + } + + let nativeint = { + ty_code = "nativeint"; + value_code = (fun i -> (Int.to_string i) ^ "n"); + mk_value_code = "Nativeint.of_int i"; + eq = "(fun a b -> Nativeint.equal (globalize a) (globalize b))"; + is_gc_ignorable = false; + } + + let nativeint_u = { + ty_code = "nativeint#"; + value_code = (fun i -> "#" ^ Int.to_string i ^ "n"); + mk_value_code = "Nativeint_u.of_int i"; + eq = "(fun a b -> Nativeint_u.(equal (add #0n a) (add #0n b)))"; + is_gc_ignorable = true; + } +end + +let ty_ur1 = Ty.(unboxed_record "ur1" ["a", int64_u; "b", float_u]) +let ty_ur2 = Ty.(unboxed_record "ur2" ["a", int64_u; "b", int]) +let ty_ur3 = Ty.(unboxed_record "ur3" ["a", int64_u]) +let ty_ur4 = Ty.(unboxed_record "ur4" ["a", ty_ur1; "b", ty_ur3]) + +(* Types the GC always ignores, which can be used with %makearray_dynamic_uninit *) +let always_ignored_types = Ty.([ + float32_u; float_u; int32_u; int64_u; nativeint_u; ty_ur1; ty_ur3; ty_ur4; + unboxed_tuple [float_u; int32_u; int64_u]; + unboxed_tuple [ + float_u; + unboxed_tuple [int64_u; int64_u]; + float32_u; + unboxed_tuple [int32_u; unboxed_tuple [float32_u; float_u]]; + int64_u; + ]; + unboxed_tuple [int64_u; ty_ur1]; +]) + +let types = always_ignored_types @ Ty.([ + float32; float; int32; int64; nativeint; int; enum 3; ty_ur2; + unboxed_tuple [int; int64]; + unboxed_tuple [ + option int64; + unboxed_tuple [int; int32; float]; + float; + unboxed_tuple [float32; option (tuple [nativeint; nativeint])]; + int32 + ]; + unboxed_tuple [float; float; float]; + unboxed_tuple [ + float; + unboxed_tuple [float; float]; + unboxed_tuple [float; unboxed_tuple [float; float; float]] + ]; + unboxed_tuple [float_u; int; int64_u]; + unboxed_tuple [ + float_u; + unboxed_tuple [int; int64_u]; + float32_u; + unboxed_tuple [int32_u; unboxed_tuple [float32_u; float_u]]; + int; + ]; + unboxed_tuple [ty_ur2; ty_ur1]; +]) + +let preamble = {| +open Stdlib_upstream_compatible +open Stdlib_stable +module List = ListLabels +module String = StringLabels + +external[@layout_poly] makearray_dynamic_uninit_local : + ('a : any_non_null) . int -> 'a array @ local = + "%makearray_dynamic_uninit" + +external[@layout_poly] makearray_dynamic_uninit : + ('a : any_non_null) . int -> 'a array = + "%makearray_dynamic_uninit" + +external[@layout_poly] makearray_dynamic_local : + ('a : any_non_null) . int -> 'a -> 'a array @ local = + "%makearray_dynamic" + +external[@layout_poly] makearray_dynamic : + ('a : any_non_null) . int -> 'a -> 'a array = + "%makearray_dynamic" + +external[@layout_poly] get : + ('a : any_non_null) . ('a array[@local_opt]) -> (int[@local_opt]) -> 'a = + "%array_safe_get" + +external[@layout_poly] set : + ('a : any_non_null) . ('a array[@local_opt]) -> (int[@local_opt]) -> 'a -> unit = + "%array_safe_set" + +external[@layout_poly] unsafe_blit : + ('a : any_non_null) . ('a array[@local_opt]) -> (int[@local_opt]) -> ('a array[@local_opt]) -> (int[@local_opt]) -> (int[@local_opt]) -> unit = + "%arrayblit" + +let failwithf fmt = Printf.ksprintf failwith fmt + +external globalize : local_ 'a -> 'a = "%obj_dup";; + +(* Redefine iter to infer locality *) +let rec iter ~f = function + [] -> () + | a::l -> f a; iter ~f l + +let tests_run = ref [] + +let mark_test_run test_id = + if not (List.mem ~set:!tests_run test_id) then + tests_run := test_id :: !tests_run + +(* Various interesting values *) + +let sizes = [ 0; 1; 2; 30; 31; 32 ] + +let bad_indices size = + [ -100; -2; -1; size; size + 1; size + 100; Int.min_int; Int.max_int ] + +let blit_offsets size = + let candidates = [ 0; 1; size / 3; size / 2; size - 1; size ] in + List.filter candidates ~f:(fun ofs -> ofs > 0 && ofs < size) + |> List.sort_uniq ~cmp:Int.compare + +let blit_lens ~ofs1 ~ofs2 ~size1 ~size2 = + let len_until_end = Int.min (size1 - ofs1) (size2 - ofs2) in + let candidates = [ 0; 1; size1 / 2; len_until_end - 1; len_until_end ] in + List.filter candidates ~f:(fun len -> ofs1 + len <= size1 && ofs2 + len <= size2) + |> List.sort_uniq ~cmp:Int.compare +|} + +let indent = ref 0 + +let with_indent f = incr indent; f (); decr indent + +let line fmt = + Printf.ksprintf + (fun s -> + let indent = Seq.init (!indent * 2) (fun _ -> ' ') |> String.of_seq in + print_endline (indent ^ s); + flush stdout) + fmt + +let print_in_test s = + line {|let () = Printf.printf "%s%%!\n";;|} (String.escaped s) + +let seq_print_in_test s = + line {|print_endline "%s%!";|} (String.escaped s) + +let makearray_dynamic_fn ~uninit ~local = + let uninit_s = if uninit then "_uninit" else "" in + let local_s = if local then "_local" else "" in + "makearray_dynamic" ^ uninit_s ^ local_s + +type debug_expr = { expr : string ; format_s : string } + +let concat_with_leading_spaces l = + List.map l ~f:(fun s -> " " ^ s) + |> String.concat ~sep:"" + +let combine_debug_exprs (l : debug_expr list) : debug_expr = + let debug_expr_to_tuple { expr ; format_s } = expr, format_s in + let exprs, format_ss = List.split (List.rev_map ~f:debug_expr_to_tuple l) in + let expr = concat_with_leading_spaces exprs in + let format_s = concat_with_leading_spaces format_ss in + { expr; format_s } + +let seq_print_debug_exprs ~debug_exprs = + let { expr ; format_s } = combine_debug_exprs debug_exprs in + line {|Printf.printf "%s: %s\n%%!"%s;|} expr format_s expr + +let test_id = ref 0 + +let seq_assert ~debug_exprs s = + incr test_id; + let { expr ; format_s } = combine_debug_exprs debug_exprs in + line "mark_test_run %d;" !test_id; + line "let test = %s in" s; + line {|if not test then failwithf "test %d failed%s"%s;|} + !test_id format_s expr + +let for_ var ~from ~to_ ~debug_exprs f = + line "for %s = %s to %s do" var from to_; + with_indent (fun () -> + let debug_exprs = { expr = var; format_s = "%d" } :: debug_exprs in + f ~debug_exprs + ); + line "done;" + +let for_i_below_size = for_ "i" ~from:"0" ~to_:"size - 1" + +(* Iterate through a list of ints *) +let iter l var ~debug_exprs f = + line "iter (%s) ~f:(fun %s ->" l var; + with_indent (fun () -> + let debug_exprs = { expr = var; format_s = "%d" } :: debug_exprs in + f ~debug_exprs + ); + line ") [@nontail];" + +let section s = + let s_as_stars = String.init (String.length s) ~f:(fun _ -> '*') in + line "(**%s**)" s_as_stars; + line "(* %s *)" s; + line "(**%s**)" s_as_stars + +(* Test steps: + 1. Create an array, possibly local, possibly uninitialized + 2. For initialized arrays, check all elements have the correct value + 3. Fill array with distinct values and read back those values + 4. Check that getting bad indices errors + 5. Check that setting bad indices errors + 6. Check that array contents were unaffected by setting bad indices + 7. Overlapping blits + 8. Blits to heap arrays + 9. Blits to local arrays +*) +let test_makearray_dynamic ~uninit ~local ty = + let makearray_dynamic = makearray_dynamic_fn ~uninit ~local in + let debug_exprs = [{ expr = "size"; format_s = "%d"}] in + let ty_array_s = ty.Ty.ty_code ^ " array" in + (* seq_print_in_test ty.Ty.ty_code; *) + section (" " ^ ty.Ty.ty_code ^ " "); + line "let eq = %s in" ty.Ty.eq; + line "let mk_value i = %s in" ty.Ty.mk_value_code; + line "(* 1. Create an array of size [size] *)"; + (if uninit then ( + line "let a : %s = %s size in" ty_array_s makearray_dynamic; + line "(* 2. For uninitialized arrays, element values are unspecified *)" + ) else + line "let a : %s = %s size %s in" ty_array_s makearray_dynamic (ty.Ty.value_code 0); + line "(* 2. For initialized arrays, check all elements have the correct value *)"; + for_i_below_size ~debug_exprs (fun ~debug_exprs -> + line "let el = get a i in"; + if uninit then + line "let _ = el in ()" + else ( + let test = sprintf "eq el %s" (ty.Ty.value_code 0) in + seq_assert ~debug_exprs test; + ) + )); + line "(* 3. Fill [a] with distinct values and read back those values *)"; + for_i_below_size ~debug_exprs (fun ~debug_exprs -> + line "set a i (mk_value i);" + ); + line "Gc.compact ();"; + for_i_below_size ~debug_exprs (fun ~debug_exprs -> + seq_assert ~debug_exprs "eq (get a i) (mk_value i)" + ); + iter "bad_indices size" "i" ~debug_exprs (fun ~debug_exprs -> + line "(* 4. Getting bad indices errors *)"; + line "let raises ="; + with_indent (fun () -> + line "match get a i with"; + line "| exception Invalid_argument _ -> true"; + line "| _ -> false" + ); + line "in"; + seq_assert ~debug_exprs "raises"; + line "(* 5. Setting bad indices errors *)"; + line "let raises ="; + with_indent (fun () -> + line "match set a i %s with" (ty.Ty.value_code 0); + line "| exception Invalid_argument _ -> true"; + line "| _ -> false" + ); + line "in"; + seq_assert ~debug_exprs "raises" + ); + line "Gc.compact ();"; + line "(* 6. Array contents were unaffacted by setting bad indices *)"; + for_i_below_size ~debug_exprs (fun ~debug_exprs -> + seq_assert ~debug_exprs "eq (get a i) (mk_value i)" + ); + (* Blits currently only work for GC ignorable values *) + line "(* 7. Overlapping blits *)"; + iter "blit_offsets size" "ofs1" ~debug_exprs (fun ~debug_exprs -> + iter "blit_offsets size" "ofs2" ~debug_exprs (fun ~debug_exprs -> + let lens = "blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size" in + iter lens "len" ~debug_exprs (fun ~debug_exprs -> + line "unsafe_blit a ofs1 a ofs2 len;"; + for_i_below_size ~debug_exprs (fun ~debug_exprs -> + line "let expected_src_i ="; + with_indent (fun () -> + line "if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i" + ); + line "in"; + seq_assert ~debug_exprs "eq (get a i) (mk_value expected_src_i)" + ); + line "(* Reset array *)"; + for_i_below_size ~debug_exprs (fun ~debug_exprs -> + line "set a i (mk_value i);" + ) + ); + ); + ); + line "Gc.compact ();"; + let test_blit_to ~to_local = + iter "sizes" "size2" ~debug_exprs (fun ~debug_exprs -> + iter "blit_offsets size" "ofs1" ~debug_exprs (fun ~debug_exprs -> + iter "blit_offsets size2" "ofs2" ~debug_exprs (fun ~debug_exprs -> + let lens = "blit_lens ~ofs1 ~ofs2 ~size1:size ~size2" in + iter lens "len" ~debug_exprs (fun ~debug_exprs -> + (if to_local then + line "let local_ a2 = makearray_dynamic_local size2 %s in" (ty.Ty.value_code 0) + else + line "let a2 = makearray_dynamic size2 %s in" (ty.Ty.value_code 0)); + line "unsafe_blit a ofs1 a2 ofs2 len;"; + for_ "i" ~from:"0" ~to_:"size2 - 1" ~debug_exprs (fun ~debug_exprs -> + line "let expected_src_i ="; + with_indent (fun () -> + line "if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0" + ); + line "in"; + seq_assert ~debug_exprs "eq (get a2 i) (mk_value expected_src_i)" + ) + ) + ) + ) + ); + line "Gc.compact ();" + in + line "(* 8. Blits to heap arrays *)"; + test_blit_to ~to_local:false; + line "(* 9. Blits to local arrays *)"; + test_blit_to ~to_local:true; + print_endline "" + +let toplevel_unit_block f = + assert (Int.equal !indent 0); + line "let () ="; + with_indent (fun () -> + f (); line "()" + ); + line ";;"; + line "" + +let main ~bytecode = + let debug_exprs = [] in + line {|(* TEST + include stdlib_stable; + include stdlib_upstream_compatible;|}; + if bytecode then ( + line {| flags = "-extension layouts_beta";|}; + (* CR layouts: enable for arm64 once float32 is available *) + line {| arch_amd64;|}; + line {| bytecode;|}; + ) else ( + line {| modules = "stubs.c";|}; + line {| flags = "-extension layouts_beta -extension simd_beta";|}; + line {| flambda2;|}; + line {| stack-allocation;|}; + line {| arch_amd64;|}; + line {| native;|}; + ); + line {|*)|}; + line "(** This is code generated by [generate_makearray_dynamic_tests.ml]. *)"; + line ""; + line "%s" preamble; + List.iter (Ty.decls_code ()) ~f:(fun s -> line "%s" s); + line ""; + line "(* Catch metaprogramming errors early *)"; + toplevel_unit_block (fun () -> + let open Ty in + line "(* Check types and constants *)"; + List.iter types ~f:(fun ty -> + line "let _ : %s = %s in" ty.ty_code (ty.value_code 0) + ); + line "(* Check equality and mk_value functions *)"; + List.iter types ~f:(fun ty -> + line "let eq : %s @ local -> %s @ local -> bool = %s in" + ty.ty_code ty.ty_code ty.eq; + line "let mk_value i = %s in" ty.mk_value_code; + seq_assert ~debug_exprs + (sprintf "eq (mk_value 1) %s" (ty.value_code 1)); + seq_assert ~debug_exprs + (sprintf "eq %s %s" (ty.value_code 1) (ty.value_code 1)); + seq_assert ~debug_exprs + (sprintf "not (eq %s %s)" (ty.value_code 1) (ty.value_code 2)) + ); + line "(* Check always-GC-ignored types *)"; + List.iter always_ignored_types ~f:(fun ty -> + line "let _ = (makearray_dynamic_uninit 1 : %s array) in" (ty.ty_code) + ); + ); + List.iter [false; true] ~f:(fun uninit -> + List.iter [false; true] ~f:(fun local -> + line "let test_%s size =" (makearray_dynamic_fn ~uninit ~local); + with_indent (fun () -> + let tys = if uninit then always_ignored_types else types in + List.iter tys ~f:(test_makearray_dynamic ~uninit ~local); + line "()"; + ); + line ""; + ) + ); + line "(* Main tests *)"; + toplevel_unit_block (fun () -> + List.iter [false; true] ~f:(fun uninit -> + List.iter [false; true] ~f:(fun local -> + let test_fn = "test_" ^ makearray_dynamic_fn ~uninit ~local in + seq_print_in_test test_fn; + line "iter sizes ~f:%s;" test_fn + ) + ) + ); + line "for i = 1 to %d do" !test_id; + with_indent (fun () -> + line + {|if not (List.mem ~set:!tests_run i) then failwithf "test %%d not run" i|} + ); + line "done;;"; + print_in_test "All tests passed." + +let () = + let bytecode = + match Sys.argv with + | [| _; "native" |] -> false + | [| _; "byte" |] -> true + | _ -> failwith (sprintf "Usage %s " Sys.argv.(0)) + in + main ~bytecode diff --git a/testsuite/tests/typing-layouts-arrays/generated_test.ml b/testsuite/tests/typing-layouts-arrays/generated_test.ml new file mode 100644 index 00000000000..873b18854ae --- /dev/null +++ b/testsuite/tests/typing-layouts-arrays/generated_test.ml @@ -0,0 +1,8785 @@ +(* TEST + include stdlib_stable; + include stdlib_upstream_compatible; + modules = "stubs.c"; + flags = "-extension layouts_beta -extension simd_beta"; + flambda2; + stack-allocation; + arch_amd64; + native; +*) +(** This is code generated by [generate_makearray_dynamic_tests.ml]. *) + + +open Stdlib_upstream_compatible +open Stdlib_stable +module List = ListLabels +module String = StringLabels + +external[@layout_poly] makearray_dynamic_uninit_local : + ('a : any_non_null) . int -> 'a array @ local = + "%makearray_dynamic_uninit" + +external[@layout_poly] makearray_dynamic_uninit : + ('a : any_non_null) . int -> 'a array = + "%makearray_dynamic_uninit" + +external[@layout_poly] makearray_dynamic_local : + ('a : any_non_null) . int -> 'a -> 'a array @ local = + "%makearray_dynamic" + +external[@layout_poly] makearray_dynamic : + ('a : any_non_null) . int -> 'a -> 'a array = + "%makearray_dynamic" + +external[@layout_poly] get : + ('a : any_non_null) . ('a array[@local_opt]) -> (int[@local_opt]) -> 'a = + "%array_safe_get" + +external[@layout_poly] set : + ('a : any_non_null) . ('a array[@local_opt]) -> (int[@local_opt]) -> 'a -> unit = + "%array_safe_set" + +external[@layout_poly] unsafe_blit : + ('a : any_non_null) . ('a array[@local_opt]) -> (int[@local_opt]) -> ('a array[@local_opt]) -> (int[@local_opt]) -> (int[@local_opt]) -> unit = + "%arrayblit" + +let failwithf fmt = Printf.ksprintf failwith fmt + +external globalize : local_ 'a -> 'a = "%obj_dup";; + +(* Redefine iter to infer locality *) +let rec iter ~f = function + [] -> () + | a::l -> f a; iter ~f l + +let tests_run = ref [] + +let mark_test_run test_id = + if not (List.mem ~set:!tests_run test_id) then + tests_run := test_id :: !tests_run + +(* Various interesting values *) + +let sizes = [ 0; 1; 2; 30; 31; 32 ] + +let bad_indices size = + [ -100; -2; -1; size; size + 1; size + 100; Int.min_int; Int.max_int ] + +let blit_offsets size = + let candidates = [ 0; 1; size / 3; size / 2; size - 1; size ] in + List.filter candidates ~f:(fun ofs -> ofs > 0 && ofs < size) + |> List.sort_uniq ~cmp:Int.compare + +let blit_lens ~ofs1 ~ofs2 ~size1 ~size2 = + let len_until_end = Int.min (size1 - ofs1) (size2 - ofs2) in + let candidates = [ 0; 1; size1 / 2; len_until_end - 1; len_until_end ] in + List.filter candidates ~f:(fun len -> ofs1 + len <= size1 && ofs2 + len <= size2) + |> List.sort_uniq ~cmp:Int.compare + +type ur1 = #{ a : int64#; b : float# } +and ur2 = #{ a : int64#; b : int } +and ur3 = #{ a : int64# } +and ur4 = #{ a : ur1; b : ur3 } +and enum3 = A3_0 | A3_1 | A3_2 + +(* Catch metaprogramming errors early *) +let () = + (* Check types and constants *) + let _ : float32# = #0.s in + let _ : float# = #0. in + let _ : int32# = #0l in + let _ : int64# = #0L in + let _ : nativeint# = #0n in + let _ : ur1 = (#{ a = #0L; b = #0. } : ur1) in + let _ : ur3 = (#{ a = #0L } : ur3) in + let _ : ur4 = (#{ a = (#{ a = #0L; b = #0. } : ur1); b = (#{ a = #0L } : ur3) } : ur4) in + let _ : #(float# * int32# * int64#) = #(#0., #0l, #0L) in + let _ : #(float# * #(int64# * int64#) * float32# * #(int32# * #(float32# * float#)) * int64#) = #(#0., #(#0L, #0L), #0.s, #(#0l, #(#0.s, #0.)), #0L) in + let _ : #(int64# * ur1) = #(#0L, (#{ a = #0L; b = #0. } : ur1)) in + let _ : float32 = 0.s in + let _ : float = 0. in + let _ : int32 = 0l in + let _ : int64 = 0L in + let _ : nativeint = 0n in + let _ : int = 0 in + let _ : enum3 = A3_0 in + let _ : ur2 = (#{ a = #0L; b = 0 } : ur2) in + let _ : #(int * int64) = #(0, 0L) in + let _ : #(int64 option * #(int * int32 * float) * float * #(float32 * (nativeint * nativeint) option) * int32) = #(None, #(0, 0l, 0.), 0., #(0.s, None), 0l) in + let _ : #(float * float * float) = #(0., 0., 0.) in + let _ : #(float * #(float * float) * #(float * #(float * float * float))) = #(0., #(0., 0.), #(0., #(0., 0., 0.))) in + let _ : #(float# * int * int64#) = #(#0., 0, #0L) in + let _ : #(float# * #(int * int64#) * float32# * #(int32# * #(float32# * float#)) * int) = #(#0., #(0, #0L), #0.s, #(#0l, #(#0.s, #0.)), 0) in + let _ : #(ur2 * ur1) = #((#{ a = #0L; b = 0 } : ur2), (#{ a = #0L; b = #0. } : ur1)) in + (* Check equality and mk_value functions *) + let eq : float32# @ local -> float32# @ local -> bool = (fun a b -> Float32_u.(equal (add #0.s a) (add #0.s b))) in + let mk_value i = Float32_u.of_int i in + mark_test_run 1; + let test = eq (mk_value 1) #1.s in + if not test then failwithf "test 1 failed"; + mark_test_run 2; + let test = eq #1.s #1.s in + if not test then failwithf "test 2 failed"; + mark_test_run 3; + let test = not (eq #1.s #2.s) in + if not test then failwithf "test 3 failed"; + let eq : float# @ local -> float# @ local -> bool = (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) in + let mk_value i = Float_u.of_int i in + mark_test_run 4; + let test = eq (mk_value 1) #1. in + if not test then failwithf "test 4 failed"; + mark_test_run 5; + let test = eq #1. #1. in + if not test then failwithf "test 5 failed"; + mark_test_run 6; + let test = not (eq #1. #2.) in + if not test then failwithf "test 6 failed"; + let eq : int32# @ local -> int32# @ local -> bool = (fun a b -> Int32_u.(equal (add #0l a) (add #0l b))) in + let mk_value i = Int32_u.of_int i in + mark_test_run 7; + let test = eq (mk_value 1) #1l in + if not test then failwithf "test 7 failed"; + mark_test_run 8; + let test = eq #1l #1l in + if not test then failwithf "test 8 failed"; + mark_test_run 9; + let test = not (eq #1l #2l) in + if not test then failwithf "test 9 failed"; + let eq : int64# @ local -> int64# @ local -> bool = (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) in + let mk_value i = Int64_u.of_int i in + mark_test_run 10; + let test = eq (mk_value 1) #1L in + if not test then failwithf "test 10 failed"; + mark_test_run 11; + let test = eq #1L #1L in + if not test then failwithf "test 11 failed"; + mark_test_run 12; + let test = not (eq #1L #2L) in + if not test then failwithf "test 12 failed"; + let eq : nativeint# @ local -> nativeint# @ local -> bool = (fun a b -> Nativeint_u.(equal (add #0n a) (add #0n b))) in + let mk_value i = Nativeint_u.of_int i in + mark_test_run 13; + let test = eq (mk_value 1) #1n in + if not test then failwithf "test 13 failed"; + mark_test_run 14; + let test = eq #1n #1n in + if not test then failwithf "test 14 failed"; + mark_test_run 15; + let test = not (eq #1n #2n) in + if not test then failwithf "test 15 failed"; + let eq : ur1 @ local -> ur1 @ local -> bool = (fun (#{ a = a1; b = b1 } : ur1) (#{ a = a2; b = b2 } : ur1) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 a2 && (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) b1 b2) in + let mk_value i = (#{ a = Int64_u.of_int i; b = Float_u.of_int i } : ur1) in + mark_test_run 16; + let test = eq (mk_value 1) (#{ a = #1L; b = #1. } : ur1) in + if not test then failwithf "test 16 failed"; + mark_test_run 17; + let test = eq (#{ a = #1L; b = #1. } : ur1) (#{ a = #1L; b = #1. } : ur1) in + if not test then failwithf "test 17 failed"; + mark_test_run 18; + let test = not (eq (#{ a = #1L; b = #1. } : ur1) (#{ a = #2L; b = #2. } : ur1)) in + if not test then failwithf "test 18 failed"; + let eq : ur3 @ local -> ur3 @ local -> bool = (fun (#{ a = a1 } : ur3) (#{ a = a2 } : ur3) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 a2) in + let mk_value i = (#{ a = Int64_u.of_int i } : ur3) in + mark_test_run 19; + let test = eq (mk_value 1) (#{ a = #1L } : ur3) in + if not test then failwithf "test 19 failed"; + mark_test_run 20; + let test = eq (#{ a = #1L } : ur3) (#{ a = #1L } : ur3) in + if not test then failwithf "test 20 failed"; + mark_test_run 21; + let test = not (eq (#{ a = #1L } : ur3) (#{ a = #2L } : ur3)) in + if not test then failwithf "test 21 failed"; + let eq : ur4 @ local -> ur4 @ local -> bool = (fun (#{ a = a1; b = b1 } : ur4) (#{ a = a2; b = b2 } : ur4) -> (fun (#{ a = a1; b = b1 } : ur1) (#{ a = a2; b = b2 } : ur1) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 a2 && (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) b1 b2) a1 a2 && (fun (#{ a = a1 } : ur3) (#{ a = a2 } : ur3) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 a2) b1 b2) in + let mk_value i = (#{ a = (#{ a = Int64_u.of_int i; b = Float_u.of_int i } : ur1); b = (#{ a = Int64_u.of_int i } : ur3) } : ur4) in + mark_test_run 22; + let test = eq (mk_value 1) (#{ a = (#{ a = #1L; b = #1. } : ur1); b = (#{ a = #1L } : ur3) } : ur4) in + if not test then failwithf "test 22 failed"; + mark_test_run 23; + let test = eq (#{ a = (#{ a = #1L; b = #1. } : ur1); b = (#{ a = #1L } : ur3) } : ur4) (#{ a = (#{ a = #1L; b = #1. } : ur1); b = (#{ a = #1L } : ur3) } : ur4) in + if not test then failwithf "test 23 failed"; + mark_test_run 24; + let test = not (eq (#{ a = (#{ a = #1L; b = #1. } : ur1); b = (#{ a = #1L } : ur3) } : ur4) (#{ a = (#{ a = #2L; b = #2. } : ur1); b = (#{ a = #2L } : ur3) } : ur4)) in + if not test then failwithf "test 24 failed"; + let eq : #(float# * int32# * int64#) @ local -> #(float# * int32# * int64#) @ local -> bool = (fun #(a0, a1, a2) #(b0, b1, b2) -> (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) a0 b0 && (fun a b -> Int32_u.(equal (add #0l a) (add #0l b))) a1 b1 && (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a2 b2) in + let mk_value i = #(Float_u.of_int i, Int32_u.of_int i, Int64_u.of_int i) in + mark_test_run 25; + let test = eq (mk_value 1) #(#1., #1l, #1L) in + if not test then failwithf "test 25 failed"; + mark_test_run 26; + let test = eq #(#1., #1l, #1L) #(#1., #1l, #1L) in + if not test then failwithf "test 26 failed"; + mark_test_run 27; + let test = not (eq #(#1., #1l, #1L) #(#2., #2l, #2L)) in + if not test then failwithf "test 27 failed"; + let eq : #(float# * #(int64# * int64#) * float32# * #(int32# * #(float32# * float#)) * int64#) @ local -> #(float# * #(int64# * int64#) * float32# * #(int32# * #(float32# * float#)) * int64#) @ local -> bool = (fun #(a0, a1, a2, a3, a4) #(b0, b1, b2, b3, b4) -> (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) a0 b0 && (fun #(a0, a1) #(b0, b1) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a0 b0 && (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 b1) a1 b1 && (fun a b -> Float32_u.(equal (add #0.s a) (add #0.s b))) a2 b2 && (fun #(a0, a1) #(b0, b1) -> (fun a b -> Int32_u.(equal (add #0l a) (add #0l b))) a0 b0 && (fun #(a0, a1) #(b0, b1) -> (fun a b -> Float32_u.(equal (add #0.s a) (add #0.s b))) a0 b0 && (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) a1 b1) a1 b1) a3 b3 && (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a4 b4) in + let mk_value i = #(Float_u.of_int i, #(Int64_u.of_int i, Int64_u.of_int i), Float32_u.of_int i, #(Int32_u.of_int i, #(Float32_u.of_int i, Float_u.of_int i)), Int64_u.of_int i) in + mark_test_run 28; + let test = eq (mk_value 1) #(#1., #(#1L, #1L), #1.s, #(#1l, #(#1.s, #1.)), #1L) in + if not test then failwithf "test 28 failed"; + mark_test_run 29; + let test = eq #(#1., #(#1L, #1L), #1.s, #(#1l, #(#1.s, #1.)), #1L) #(#1., #(#1L, #1L), #1.s, #(#1l, #(#1.s, #1.)), #1L) in + if not test then failwithf "test 29 failed"; + mark_test_run 30; + let test = not (eq #(#1., #(#1L, #1L), #1.s, #(#1l, #(#1.s, #1.)), #1L) #(#2., #(#2L, #2L), #2.s, #(#2l, #(#2.s, #2.)), #2L)) in + if not test then failwithf "test 30 failed"; + let eq : #(int64# * ur1) @ local -> #(int64# * ur1) @ local -> bool = (fun #(a0, a1) #(b0, b1) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a0 b0 && (fun (#{ a = a1; b = b1 } : ur1) (#{ a = a2; b = b2 } : ur1) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 a2 && (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) b1 b2) a1 b1) in + let mk_value i = #(Int64_u.of_int i, (#{ a = Int64_u.of_int i; b = Float_u.of_int i } : ur1)) in + mark_test_run 31; + let test = eq (mk_value 1) #(#1L, (#{ a = #1L; b = #1. } : ur1)) in + if not test then failwithf "test 31 failed"; + mark_test_run 32; + let test = eq #(#1L, (#{ a = #1L; b = #1. } : ur1)) #(#1L, (#{ a = #1L; b = #1. } : ur1)) in + if not test then failwithf "test 32 failed"; + mark_test_run 33; + let test = not (eq #(#1L, (#{ a = #1L; b = #1. } : ur1)) #(#2L, (#{ a = #2L; b = #2. } : ur1))) in + if not test then failwithf "test 33 failed"; + let eq : float32 @ local -> float32 @ local -> bool = (fun a b -> Float.equal (Float32.to_float a) (Float32.to_float b)) in + let mk_value i = Float32.of_int i in + mark_test_run 34; + let test = eq (mk_value 1) 1.s in + if not test then failwithf "test 34 failed"; + mark_test_run 35; + let test = eq 1.s 1.s in + if not test then failwithf "test 35 failed"; + mark_test_run 36; + let test = not (eq 1.s 2.s) in + if not test then failwithf "test 36 failed"; + let eq : float @ local -> float @ local -> bool = (fun a b -> Float.equal (globalize a) (globalize b)) in + let mk_value i = Float.of_int i in + mark_test_run 37; + let test = eq (mk_value 1) 1. in + if not test then failwithf "test 37 failed"; + mark_test_run 38; + let test = eq 1. 1. in + if not test then failwithf "test 38 failed"; + mark_test_run 39; + let test = not (eq 1. 2.) in + if not test then failwithf "test 39 failed"; + let eq : int32 @ local -> int32 @ local -> bool = (fun a b -> Int32.equal (globalize a) (globalize b)) in + let mk_value i = Int32.of_int i in + mark_test_run 40; + let test = eq (mk_value 1) 1l in + if not test then failwithf "test 40 failed"; + mark_test_run 41; + let test = eq 1l 1l in + if not test then failwithf "test 41 failed"; + mark_test_run 42; + let test = not (eq 1l 2l) in + if not test then failwithf "test 42 failed"; + let eq : int64 @ local -> int64 @ local -> bool = (fun a b -> Int64.equal (globalize a) (globalize b)) in + let mk_value i = Int64.of_int i in + mark_test_run 43; + let test = eq (mk_value 1) 1L in + if not test then failwithf "test 43 failed"; + mark_test_run 44; + let test = eq 1L 1L in + if not test then failwithf "test 44 failed"; + mark_test_run 45; + let test = not (eq 1L 2L) in + if not test then failwithf "test 45 failed"; + let eq : nativeint @ local -> nativeint @ local -> bool = (fun a b -> Nativeint.equal (globalize a) (globalize b)) in + let mk_value i = Nativeint.of_int i in + mark_test_run 46; + let test = eq (mk_value 1) 1n in + if not test then failwithf "test 46 failed"; + mark_test_run 47; + let test = eq 1n 1n in + if not test then failwithf "test 47 failed"; + mark_test_run 48; + let test = not (eq 1n 2n) in + if not test then failwithf "test 48 failed"; + let eq : int @ local -> int @ local -> bool = (fun a b -> Int.equal a b) in + let mk_value i = i in + mark_test_run 49; + let test = eq (mk_value 1) 1 in + if not test then failwithf "test 49 failed"; + mark_test_run 50; + let test = eq 1 1 in + if not test then failwithf "test 50 failed"; + mark_test_run 51; + let test = not (eq 1 2) in + if not test then failwithf "test 51 failed"; + let eq : enum3 @ local -> enum3 @ local -> bool = (fun a b -> match a, b with A3_0, A3_0 | A3_1, A3_1 | A3_2, A3_2 -> true | _ -> false) in + let mk_value i = (match Int.rem i 3 with 0 -> A3_0 | 1 -> A3_1 | 2 -> A3_2 | _ -> assert false) in + mark_test_run 52; + let test = eq (mk_value 1) A3_1 in + if not test then failwithf "test 52 failed"; + mark_test_run 53; + let test = eq A3_1 A3_1 in + if not test then failwithf "test 53 failed"; + mark_test_run 54; + let test = not (eq A3_1 A3_2) in + if not test then failwithf "test 54 failed"; + let eq : ur2 @ local -> ur2 @ local -> bool = (fun (#{ a = a1; b = b1 } : ur2) (#{ a = a2; b = b2 } : ur2) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 a2 && (fun a b -> Int.equal a b) b1 b2) in + let mk_value i = (#{ a = Int64_u.of_int i; b = i } : ur2) in + mark_test_run 55; + let test = eq (mk_value 1) (#{ a = #1L; b = 1 } : ur2) in + if not test then failwithf "test 55 failed"; + mark_test_run 56; + let test = eq (#{ a = #1L; b = 1 } : ur2) (#{ a = #1L; b = 1 } : ur2) in + if not test then failwithf "test 56 failed"; + mark_test_run 57; + let test = not (eq (#{ a = #1L; b = 1 } : ur2) (#{ a = #2L; b = 2 } : ur2)) in + if not test then failwithf "test 57 failed"; + let eq : #(int * int64) @ local -> #(int * int64) @ local -> bool = (fun #(a0, a1) #(b0, b1) -> (fun a b -> Int.equal a b) a0 b0 && (fun a b -> Int64.equal (globalize a) (globalize b)) a1 b1) in + let mk_value i = #(i, Int64.of_int i) in + mark_test_run 58; + let test = eq (mk_value 1) #(1, 1L) in + if not test then failwithf "test 58 failed"; + mark_test_run 59; + let test = eq #(1, 1L) #(1, 1L) in + if not test then failwithf "test 59 failed"; + mark_test_run 60; + let test = not (eq #(1, 1L) #(2, 2L)) in + if not test then failwithf "test 60 failed"; + let eq : #(int64 option * #(int * int32 * float) * float * #(float32 * (nativeint * nativeint) option) * int32) @ local -> #(int64 option * #(int * int32 * float) * float * #(float32 * (nativeint * nativeint) option) * int32) @ local -> bool = (fun #(a0, a1, a2, a3, a4) #(b0, b1, b2, b3, b4) -> (fun a b -> match a, b with None,None -> true | Some a,Some b -> (fun a b -> Int64.equal (globalize a) (globalize b)) a b|_->false) a0 b0 && (fun #(a0, a1, a2) #(b0, b1, b2) -> (fun a b -> Int.equal a b) a0 b0 && (fun a b -> Int32.equal (globalize a) (globalize b)) a1 b1 && (fun a b -> Float.equal (globalize a) (globalize b)) a2 b2) a1 b1 && (fun a b -> Float.equal (globalize a) (globalize b)) a2 b2 && (fun #(a0, a1) #(b0, b1) -> (fun a b -> Float.equal (Float32.to_float a) (Float32.to_float b)) a0 b0 && (fun a b -> match a, b with None,None -> true | Some a,Some b -> (fun (a0, a1) (b0, b1) -> (fun a b -> Nativeint.equal (globalize a) (globalize b)) a0 b0 && (fun a b -> Nativeint.equal (globalize a) (globalize b)) a1 b1) a b|_->false) a1 b1) a3 b3 && (fun a b -> Int32.equal (globalize a) (globalize b)) a4 b4) in + let mk_value i = #((if i == 0 then None else Some (Int64.of_int i)), #(i, Int32.of_int i, Float.of_int i), Float.of_int i, #(Float32.of_int i, (if i == 0 then None else Some ((Nativeint.of_int i, Nativeint.of_int i)))), Int32.of_int i) in + mark_test_run 61; + let test = eq (mk_value 1) #(Some 1L, #(1, 1l, 1.), 1., #(1.s, Some (1n, 1n)), 1l) in + if not test then failwithf "test 61 failed"; + mark_test_run 62; + let test = eq #(Some 1L, #(1, 1l, 1.), 1., #(1.s, Some (1n, 1n)), 1l) #(Some 1L, #(1, 1l, 1.), 1., #(1.s, Some (1n, 1n)), 1l) in + if not test then failwithf "test 62 failed"; + mark_test_run 63; + let test = not (eq #(Some 1L, #(1, 1l, 1.), 1., #(1.s, Some (1n, 1n)), 1l) #(Some 2L, #(2, 2l, 2.), 2., #(2.s, Some (2n, 2n)), 2l)) in + if not test then failwithf "test 63 failed"; + let eq : #(float * float * float) @ local -> #(float * float * float) @ local -> bool = (fun #(a0, a1, a2) #(b0, b1, b2) -> (fun a b -> Float.equal (globalize a) (globalize b)) a0 b0 && (fun a b -> Float.equal (globalize a) (globalize b)) a1 b1 && (fun a b -> Float.equal (globalize a) (globalize b)) a2 b2) in + let mk_value i = #(Float.of_int i, Float.of_int i, Float.of_int i) in + mark_test_run 64; + let test = eq (mk_value 1) #(1., 1., 1.) in + if not test then failwithf "test 64 failed"; + mark_test_run 65; + let test = eq #(1., 1., 1.) #(1., 1., 1.) in + if not test then failwithf "test 65 failed"; + mark_test_run 66; + let test = not (eq #(1., 1., 1.) #(2., 2., 2.)) in + if not test then failwithf "test 66 failed"; + let eq : #(float * #(float * float) * #(float * #(float * float * float))) @ local -> #(float * #(float * float) * #(float * #(float * float * float))) @ local -> bool = (fun #(a0, a1, a2) #(b0, b1, b2) -> (fun a b -> Float.equal (globalize a) (globalize b)) a0 b0 && (fun #(a0, a1) #(b0, b1) -> (fun a b -> Float.equal (globalize a) (globalize b)) a0 b0 && (fun a b -> Float.equal (globalize a) (globalize b)) a1 b1) a1 b1 && (fun #(a0, a1) #(b0, b1) -> (fun a b -> Float.equal (globalize a) (globalize b)) a0 b0 && (fun #(a0, a1, a2) #(b0, b1, b2) -> (fun a b -> Float.equal (globalize a) (globalize b)) a0 b0 && (fun a b -> Float.equal (globalize a) (globalize b)) a1 b1 && (fun a b -> Float.equal (globalize a) (globalize b)) a2 b2) a1 b1) a2 b2) in + let mk_value i = #(Float.of_int i, #(Float.of_int i, Float.of_int i), #(Float.of_int i, #(Float.of_int i, Float.of_int i, Float.of_int i))) in + mark_test_run 67; + let test = eq (mk_value 1) #(1., #(1., 1.), #(1., #(1., 1., 1.))) in + if not test then failwithf "test 67 failed"; + mark_test_run 68; + let test = eq #(1., #(1., 1.), #(1., #(1., 1., 1.))) #(1., #(1., 1.), #(1., #(1., 1., 1.))) in + if not test then failwithf "test 68 failed"; + mark_test_run 69; + let test = not (eq #(1., #(1., 1.), #(1., #(1., 1., 1.))) #(2., #(2., 2.), #(2., #(2., 2., 2.)))) in + if not test then failwithf "test 69 failed"; + let eq : #(float# * int * int64#) @ local -> #(float# * int * int64#) @ local -> bool = (fun #(a0, a1, a2) #(b0, b1, b2) -> (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) a0 b0 && (fun a b -> Int.equal a b) a1 b1 && (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a2 b2) in + let mk_value i = #(Float_u.of_int i, i, Int64_u.of_int i) in + mark_test_run 70; + let test = eq (mk_value 1) #(#1., 1, #1L) in + if not test then failwithf "test 70 failed"; + mark_test_run 71; + let test = eq #(#1., 1, #1L) #(#1., 1, #1L) in + if not test then failwithf "test 71 failed"; + mark_test_run 72; + let test = not (eq #(#1., 1, #1L) #(#2., 2, #2L)) in + if not test then failwithf "test 72 failed"; + let eq : #(float# * #(int * int64#) * float32# * #(int32# * #(float32# * float#)) * int) @ local -> #(float# * #(int * int64#) * float32# * #(int32# * #(float32# * float#)) * int) @ local -> bool = (fun #(a0, a1, a2, a3, a4) #(b0, b1, b2, b3, b4) -> (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) a0 b0 && (fun #(a0, a1) #(b0, b1) -> (fun a b -> Int.equal a b) a0 b0 && (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 b1) a1 b1 && (fun a b -> Float32_u.(equal (add #0.s a) (add #0.s b))) a2 b2 && (fun #(a0, a1) #(b0, b1) -> (fun a b -> Int32_u.(equal (add #0l a) (add #0l b))) a0 b0 && (fun #(a0, a1) #(b0, b1) -> (fun a b -> Float32_u.(equal (add #0.s a) (add #0.s b))) a0 b0 && (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) a1 b1) a1 b1) a3 b3 && (fun a b -> Int.equal a b) a4 b4) in + let mk_value i = #(Float_u.of_int i, #(i, Int64_u.of_int i), Float32_u.of_int i, #(Int32_u.of_int i, #(Float32_u.of_int i, Float_u.of_int i)), i) in + mark_test_run 73; + let test = eq (mk_value 1) #(#1., #(1, #1L), #1.s, #(#1l, #(#1.s, #1.)), 1) in + if not test then failwithf "test 73 failed"; + mark_test_run 74; + let test = eq #(#1., #(1, #1L), #1.s, #(#1l, #(#1.s, #1.)), 1) #(#1., #(1, #1L), #1.s, #(#1l, #(#1.s, #1.)), 1) in + if not test then failwithf "test 74 failed"; + mark_test_run 75; + let test = not (eq #(#1., #(1, #1L), #1.s, #(#1l, #(#1.s, #1.)), 1) #(#2., #(2, #2L), #2.s, #(#2l, #(#2.s, #2.)), 2)) in + if not test then failwithf "test 75 failed"; + let eq : #(ur2 * ur1) @ local -> #(ur2 * ur1) @ local -> bool = (fun #(a0, a1) #(b0, b1) -> (fun (#{ a = a1; b = b1 } : ur2) (#{ a = a2; b = b2 } : ur2) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 a2 && (fun a b -> Int.equal a b) b1 b2) a0 b0 && (fun (#{ a = a1; b = b1 } : ur1) (#{ a = a2; b = b2 } : ur1) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 a2 && (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) b1 b2) a1 b1) in + let mk_value i = #((#{ a = Int64_u.of_int i; b = i } : ur2), (#{ a = Int64_u.of_int i; b = Float_u.of_int i } : ur1)) in + mark_test_run 76; + let test = eq (mk_value 1) #((#{ a = #1L; b = 1 } : ur2), (#{ a = #1L; b = #1. } : ur1)) in + if not test then failwithf "test 76 failed"; + mark_test_run 77; + let test = eq #((#{ a = #1L; b = 1 } : ur2), (#{ a = #1L; b = #1. } : ur1)) #((#{ a = #1L; b = 1 } : ur2), (#{ a = #1L; b = #1. } : ur1)) in + if not test then failwithf "test 77 failed"; + mark_test_run 78; + let test = not (eq #((#{ a = #1L; b = 1 } : ur2), (#{ a = #1L; b = #1. } : ur1)) #((#{ a = #2L; b = 2 } : ur2), (#{ a = #2L; b = #2. } : ur1))) in + if not test then failwithf "test 78 failed"; + (* Check always-GC-ignored types *) + let _ = (makearray_dynamic_uninit 1 : float32# array) in + let _ = (makearray_dynamic_uninit 1 : float# array) in + let _ = (makearray_dynamic_uninit 1 : int32# array) in + let _ = (makearray_dynamic_uninit 1 : int64# array) in + let _ = (makearray_dynamic_uninit 1 : nativeint# array) in + let _ = (makearray_dynamic_uninit 1 : ur1 array) in + let _ = (makearray_dynamic_uninit 1 : ur3 array) in + let _ = (makearray_dynamic_uninit 1 : ur4 array) in + let _ = (makearray_dynamic_uninit 1 : #(float# * int32# * int64#) array) in + let _ = (makearray_dynamic_uninit 1 : #(float# * #(int64# * int64#) * float32# * #(int32# * #(float32# * float#)) * int64#) array) in + let _ = (makearray_dynamic_uninit 1 : #(int64# * ur1) array) in + () +;; + +let test_makearray_dynamic size = + (****************) + (* float32# *) + (****************) + let eq = (fun a b -> Float32_u.(equal (add #0.s a) (add #0.s b))) in + let mk_value i = Float32_u.of_int i in + (* 1. Create an array of size [size] *) + let a : float32# array = makearray_dynamic size #0.s in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 79; + let test = eq el #0.s in + if not test then failwithf "test 79 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 80; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 80 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 81; + let test = raises in + if not test then failwithf "test 81 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #0.s with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 82; + let test = raises in + if not test then failwithf "test 82 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 83; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 83 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 84; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 84 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #0.s in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 85; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 85 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #0.s in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 86; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 86 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (**************) + (* float# *) + (**************) + let eq = (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) in + let mk_value i = Float_u.of_int i in + (* 1. Create an array of size [size] *) + let a : float# array = makearray_dynamic size #0. in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 87; + let test = eq el #0. in + if not test then failwithf "test 87 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 88; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 88 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 89; + let test = raises in + if not test then failwithf "test 89 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #0. with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 90; + let test = raises in + if not test then failwithf "test 90 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 91; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 91 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 92; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 92 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #0. in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 93; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 93 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #0. in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 94; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 94 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (**************) + (* int32# *) + (**************) + let eq = (fun a b -> Int32_u.(equal (add #0l a) (add #0l b))) in + let mk_value i = Int32_u.of_int i in + (* 1. Create an array of size [size] *) + let a : int32# array = makearray_dynamic size #0l in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 95; + let test = eq el #0l in + if not test then failwithf "test 95 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 96; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 96 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 97; + let test = raises in + if not test then failwithf "test 97 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #0l with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 98; + let test = raises in + if not test then failwithf "test 98 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 99; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 99 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 100; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 100 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #0l in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 101; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 101 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #0l in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 102; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 102 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (**************) + (* int64# *) + (**************) + let eq = (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) in + let mk_value i = Int64_u.of_int i in + (* 1. Create an array of size [size] *) + let a : int64# array = makearray_dynamic size #0L in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 103; + let test = eq el #0L in + if not test then failwithf "test 103 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 104; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 104 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 105; + let test = raises in + if not test then failwithf "test 105 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #0L with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 106; + let test = raises in + if not test then failwithf "test 106 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 107; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 107 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 108; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 108 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #0L in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 109; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 109 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #0L in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 110; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 110 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (******************) + (* nativeint# *) + (******************) + let eq = (fun a b -> Nativeint_u.(equal (add #0n a) (add #0n b))) in + let mk_value i = Nativeint_u.of_int i in + (* 1. Create an array of size [size] *) + let a : nativeint# array = makearray_dynamic size #0n in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 111; + let test = eq el #0n in + if not test then failwithf "test 111 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 112; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 112 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 113; + let test = raises in + if not test then failwithf "test 113 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #0n with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 114; + let test = raises in + if not test then failwithf "test 114 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 115; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 115 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 116; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 116 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #0n in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 117; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 117 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #0n in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 118; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 118 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (***********) + (* ur1 *) + (***********) + let eq = (fun (#{ a = a1; b = b1 } : ur1) (#{ a = a2; b = b2 } : ur1) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 a2 && (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) b1 b2) in + let mk_value i = (#{ a = Int64_u.of_int i; b = Float_u.of_int i } : ur1) in + (* 1. Create an array of size [size] *) + let a : ur1 array = makearray_dynamic size (#{ a = #0L; b = #0. } : ur1) in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 119; + let test = eq el (#{ a = #0L; b = #0. } : ur1) in + if not test then failwithf "test 119 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 120; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 120 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 121; + let test = raises in + if not test then failwithf "test 121 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i (#{ a = #0L; b = #0. } : ur1) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 122; + let test = raises in + if not test then failwithf "test 122 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 123; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 123 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 124; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 124 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 (#{ a = #0L; b = #0. } : ur1) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 125; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 125 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 (#{ a = #0L; b = #0. } : ur1) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 126; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 126 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (***********) + (* ur3 *) + (***********) + let eq = (fun (#{ a = a1 } : ur3) (#{ a = a2 } : ur3) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 a2) in + let mk_value i = (#{ a = Int64_u.of_int i } : ur3) in + (* 1. Create an array of size [size] *) + let a : ur3 array = makearray_dynamic size (#{ a = #0L } : ur3) in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 127; + let test = eq el (#{ a = #0L } : ur3) in + if not test then failwithf "test 127 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 128; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 128 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 129; + let test = raises in + if not test then failwithf "test 129 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i (#{ a = #0L } : ur3) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 130; + let test = raises in + if not test then failwithf "test 130 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 131; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 131 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 132; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 132 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 (#{ a = #0L } : ur3) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 133; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 133 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 (#{ a = #0L } : ur3) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 134; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 134 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (***********) + (* ur4 *) + (***********) + let eq = (fun (#{ a = a1; b = b1 } : ur4) (#{ a = a2; b = b2 } : ur4) -> (fun (#{ a = a1; b = b1 } : ur1) (#{ a = a2; b = b2 } : ur1) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 a2 && (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) b1 b2) a1 a2 && (fun (#{ a = a1 } : ur3) (#{ a = a2 } : ur3) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 a2) b1 b2) in + let mk_value i = (#{ a = (#{ a = Int64_u.of_int i; b = Float_u.of_int i } : ur1); b = (#{ a = Int64_u.of_int i } : ur3) } : ur4) in + (* 1. Create an array of size [size] *) + let a : ur4 array = makearray_dynamic size (#{ a = (#{ a = #0L; b = #0. } : ur1); b = (#{ a = #0L } : ur3) } : ur4) in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 135; + let test = eq el (#{ a = (#{ a = #0L; b = #0. } : ur1); b = (#{ a = #0L } : ur3) } : ur4) in + if not test then failwithf "test 135 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 136; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 136 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 137; + let test = raises in + if not test then failwithf "test 137 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i (#{ a = (#{ a = #0L; b = #0. } : ur1); b = (#{ a = #0L } : ur3) } : ur4) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 138; + let test = raises in + if not test then failwithf "test 138 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 139; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 139 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 140; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 140 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 (#{ a = (#{ a = #0L; b = #0. } : ur1); b = (#{ a = #0L } : ur3) } : ur4) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 141; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 141 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 (#{ a = (#{ a = #0L; b = #0. } : ur1); b = (#{ a = #0L } : ur3) } : ur4) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 142; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 142 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (***********************************) + (* #(float# * int32# * int64#) *) + (***********************************) + let eq = (fun #(a0, a1, a2) #(b0, b1, b2) -> (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) a0 b0 && (fun a b -> Int32_u.(equal (add #0l a) (add #0l b))) a1 b1 && (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a2 b2) in + let mk_value i = #(Float_u.of_int i, Int32_u.of_int i, Int64_u.of_int i) in + (* 1. Create an array of size [size] *) + let a : #(float# * int32# * int64#) array = makearray_dynamic size #(#0., #0l, #0L) in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 143; + let test = eq el #(#0., #0l, #0L) in + if not test then failwithf "test 143 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 144; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 144 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 145; + let test = raises in + if not test then failwithf "test 145 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #(#0., #0l, #0L) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 146; + let test = raises in + if not test then failwithf "test 146 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 147; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 147 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 148; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 148 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #(#0., #0l, #0L) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 149; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 149 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #(#0., #0l, #0L) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 150; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 150 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (*********************************************************************************************) + (* #(float# * #(int64# * int64#) * float32# * #(int32# * #(float32# * float#)) * int64#) *) + (*********************************************************************************************) + let eq = (fun #(a0, a1, a2, a3, a4) #(b0, b1, b2, b3, b4) -> (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) a0 b0 && (fun #(a0, a1) #(b0, b1) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a0 b0 && (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 b1) a1 b1 && (fun a b -> Float32_u.(equal (add #0.s a) (add #0.s b))) a2 b2 && (fun #(a0, a1) #(b0, b1) -> (fun a b -> Int32_u.(equal (add #0l a) (add #0l b))) a0 b0 && (fun #(a0, a1) #(b0, b1) -> (fun a b -> Float32_u.(equal (add #0.s a) (add #0.s b))) a0 b0 && (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) a1 b1) a1 b1) a3 b3 && (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a4 b4) in + let mk_value i = #(Float_u.of_int i, #(Int64_u.of_int i, Int64_u.of_int i), Float32_u.of_int i, #(Int32_u.of_int i, #(Float32_u.of_int i, Float_u.of_int i)), Int64_u.of_int i) in + (* 1. Create an array of size [size] *) + let a : #(float# * #(int64# * int64#) * float32# * #(int32# * #(float32# * float#)) * int64#) array = makearray_dynamic size #(#0., #(#0L, #0L), #0.s, #(#0l, #(#0.s, #0.)), #0L) in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 151; + let test = eq el #(#0., #(#0L, #0L), #0.s, #(#0l, #(#0.s, #0.)), #0L) in + if not test then failwithf "test 151 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 152; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 152 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 153; + let test = raises in + if not test then failwithf "test 153 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #(#0., #(#0L, #0L), #0.s, #(#0l, #(#0.s, #0.)), #0L) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 154; + let test = raises in + if not test then failwithf "test 154 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 155; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 155 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 156; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 156 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #(#0., #(#0L, #0L), #0.s, #(#0l, #(#0.s, #0.)), #0L) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 157; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 157 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #(#0., #(#0L, #0L), #0.s, #(#0l, #(#0.s, #0.)), #0L) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 158; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 158 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (***********************) + (* #(int64# * ur1) *) + (***********************) + let eq = (fun #(a0, a1) #(b0, b1) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a0 b0 && (fun (#{ a = a1; b = b1 } : ur1) (#{ a = a2; b = b2 } : ur1) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 a2 && (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) b1 b2) a1 b1) in + let mk_value i = #(Int64_u.of_int i, (#{ a = Int64_u.of_int i; b = Float_u.of_int i } : ur1)) in + (* 1. Create an array of size [size] *) + let a : #(int64# * ur1) array = makearray_dynamic size #(#0L, (#{ a = #0L; b = #0. } : ur1)) in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 159; + let test = eq el #(#0L, (#{ a = #0L; b = #0. } : ur1)) in + if not test then failwithf "test 159 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 160; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 160 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 161; + let test = raises in + if not test then failwithf "test 161 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #(#0L, (#{ a = #0L; b = #0. } : ur1)) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 162; + let test = raises in + if not test then failwithf "test 162 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 163; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 163 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 164; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 164 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #(#0L, (#{ a = #0L; b = #0. } : ur1)) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 165; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 165 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #(#0L, (#{ a = #0L; b = #0. } : ur1)) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 166; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 166 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (***************) + (* float32 *) + (***************) + let eq = (fun a b -> Float.equal (Float32.to_float a) (Float32.to_float b)) in + let mk_value i = Float32.of_int i in + (* 1. Create an array of size [size] *) + let a : float32 array = makearray_dynamic size 0.s in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 167; + let test = eq el 0.s in + if not test then failwithf "test 167 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 168; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 168 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 169; + let test = raises in + if not test then failwithf "test 169 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i 0.s with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 170; + let test = raises in + if not test then failwithf "test 170 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 171; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 171 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 172; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 172 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 0.s in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 173; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 173 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 0.s in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 174; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 174 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (*************) + (* float *) + (*************) + let eq = (fun a b -> Float.equal (globalize a) (globalize b)) in + let mk_value i = Float.of_int i in + (* 1. Create an array of size [size] *) + let a : float array = makearray_dynamic size 0. in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 175; + let test = eq el 0. in + if not test then failwithf "test 175 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 176; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 176 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 177; + let test = raises in + if not test then failwithf "test 177 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i 0. with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 178; + let test = raises in + if not test then failwithf "test 178 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 179; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 179 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 180; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 180 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 0. in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 181; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 181 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 0. in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 182; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 182 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (*************) + (* int32 *) + (*************) + let eq = (fun a b -> Int32.equal (globalize a) (globalize b)) in + let mk_value i = Int32.of_int i in + (* 1. Create an array of size [size] *) + let a : int32 array = makearray_dynamic size 0l in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 183; + let test = eq el 0l in + if not test then failwithf "test 183 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 184; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 184 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 185; + let test = raises in + if not test then failwithf "test 185 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i 0l with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 186; + let test = raises in + if not test then failwithf "test 186 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 187; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 187 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 188; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 188 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 0l in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 189; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 189 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 0l in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 190; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 190 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (*************) + (* int64 *) + (*************) + let eq = (fun a b -> Int64.equal (globalize a) (globalize b)) in + let mk_value i = Int64.of_int i in + (* 1. Create an array of size [size] *) + let a : int64 array = makearray_dynamic size 0L in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 191; + let test = eq el 0L in + if not test then failwithf "test 191 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 192; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 192 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 193; + let test = raises in + if not test then failwithf "test 193 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i 0L with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 194; + let test = raises in + if not test then failwithf "test 194 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 195; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 195 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 196; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 196 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 0L in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 197; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 197 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 0L in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 198; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 198 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (*****************) + (* nativeint *) + (*****************) + let eq = (fun a b -> Nativeint.equal (globalize a) (globalize b)) in + let mk_value i = Nativeint.of_int i in + (* 1. Create an array of size [size] *) + let a : nativeint array = makearray_dynamic size 0n in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 199; + let test = eq el 0n in + if not test then failwithf "test 199 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 200; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 200 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 201; + let test = raises in + if not test then failwithf "test 201 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i 0n with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 202; + let test = raises in + if not test then failwithf "test 202 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 203; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 203 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 204; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 204 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 0n in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 205; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 205 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 0n in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 206; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 206 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (***********) + (* int *) + (***********) + let eq = (fun a b -> Int.equal a b) in + let mk_value i = i in + (* 1. Create an array of size [size] *) + let a : int array = makearray_dynamic size 0 in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 207; + let test = eq el 0 in + if not test then failwithf "test 207 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 208; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 208 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 209; + let test = raises in + if not test then failwithf "test 209 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i 0 with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 210; + let test = raises in + if not test then failwithf "test 210 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 211; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 211 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 212; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 212 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 0 in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 213; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 213 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 0 in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 214; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 214 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (*************) + (* enum3 *) + (*************) + let eq = (fun a b -> match a, b with A3_0, A3_0 | A3_1, A3_1 | A3_2, A3_2 -> true | _ -> false) in + let mk_value i = (match Int.rem i 3 with 0 -> A3_0 | 1 -> A3_1 | 2 -> A3_2 | _ -> assert false) in + (* 1. Create an array of size [size] *) + let a : enum3 array = makearray_dynamic size A3_0 in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 215; + let test = eq el A3_0 in + if not test then failwithf "test 215 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 216; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 216 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 217; + let test = raises in + if not test then failwithf "test 217 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i A3_0 with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 218; + let test = raises in + if not test then failwithf "test 218 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 219; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 219 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 220; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 220 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 A3_0 in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 221; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 221 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 A3_0 in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 222; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 222 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (***********) + (* ur2 *) + (***********) + let eq = (fun (#{ a = a1; b = b1 } : ur2) (#{ a = a2; b = b2 } : ur2) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 a2 && (fun a b -> Int.equal a b) b1 b2) in + let mk_value i = (#{ a = Int64_u.of_int i; b = i } : ur2) in + (* 1. Create an array of size [size] *) + let a : ur2 array = makearray_dynamic size (#{ a = #0L; b = 0 } : ur2) in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 223; + let test = eq el (#{ a = #0L; b = 0 } : ur2) in + if not test then failwithf "test 223 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 224; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 224 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 225; + let test = raises in + if not test then failwithf "test 225 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i (#{ a = #0L; b = 0 } : ur2) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 226; + let test = raises in + if not test then failwithf "test 226 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 227; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 227 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 228; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 228 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 (#{ a = #0L; b = 0 } : ur2) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 229; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 229 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 (#{ a = #0L; b = 0 } : ur2) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 230; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 230 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (**********************) + (* #(int * int64) *) + (**********************) + let eq = (fun #(a0, a1) #(b0, b1) -> (fun a b -> Int.equal a b) a0 b0 && (fun a b -> Int64.equal (globalize a) (globalize b)) a1 b1) in + let mk_value i = #(i, Int64.of_int i) in + (* 1. Create an array of size [size] *) + let a : #(int * int64) array = makearray_dynamic size #(0, 0L) in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 231; + let test = eq el #(0, 0L) in + if not test then failwithf "test 231 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 232; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 232 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 233; + let test = raises in + if not test then failwithf "test 233 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #(0, 0L) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 234; + let test = raises in + if not test then failwithf "test 234 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 235; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 235 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 236; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 236 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #(0, 0L) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 237; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 237 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #(0, 0L) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 238; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 238 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (**************************************************************************************************************) + (* #(int64 option * #(int * int32 * float) * float * #(float32 * (nativeint * nativeint) option) * int32) *) + (**************************************************************************************************************) + let eq = (fun #(a0, a1, a2, a3, a4) #(b0, b1, b2, b3, b4) -> (fun a b -> match a, b with None,None -> true | Some a,Some b -> (fun a b -> Int64.equal (globalize a) (globalize b)) a b|_->false) a0 b0 && (fun #(a0, a1, a2) #(b0, b1, b2) -> (fun a b -> Int.equal a b) a0 b0 && (fun a b -> Int32.equal (globalize a) (globalize b)) a1 b1 && (fun a b -> Float.equal (globalize a) (globalize b)) a2 b2) a1 b1 && (fun a b -> Float.equal (globalize a) (globalize b)) a2 b2 && (fun #(a0, a1) #(b0, b1) -> (fun a b -> Float.equal (Float32.to_float a) (Float32.to_float b)) a0 b0 && (fun a b -> match a, b with None,None -> true | Some a,Some b -> (fun (a0, a1) (b0, b1) -> (fun a b -> Nativeint.equal (globalize a) (globalize b)) a0 b0 && (fun a b -> Nativeint.equal (globalize a) (globalize b)) a1 b1) a b|_->false) a1 b1) a3 b3 && (fun a b -> Int32.equal (globalize a) (globalize b)) a4 b4) in + let mk_value i = #((if i == 0 then None else Some (Int64.of_int i)), #(i, Int32.of_int i, Float.of_int i), Float.of_int i, #(Float32.of_int i, (if i == 0 then None else Some ((Nativeint.of_int i, Nativeint.of_int i)))), Int32.of_int i) in + (* 1. Create an array of size [size] *) + let a : #(int64 option * #(int * int32 * float) * float * #(float32 * (nativeint * nativeint) option) * int32) array = makearray_dynamic size #(None, #(0, 0l, 0.), 0., #(0.s, None), 0l) in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 239; + let test = eq el #(None, #(0, 0l, 0.), 0., #(0.s, None), 0l) in + if not test then failwithf "test 239 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 240; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 240 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 241; + let test = raises in + if not test then failwithf "test 241 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #(None, #(0, 0l, 0.), 0., #(0.s, None), 0l) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 242; + let test = raises in + if not test then failwithf "test 242 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 243; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 243 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 244; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 244 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #(None, #(0, 0l, 0.), 0., #(0.s, None), 0l) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 245; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 245 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #(None, #(0, 0l, 0.), 0., #(0.s, None), 0l) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 246; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 246 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (********************************) + (* #(float * float * float) *) + (********************************) + let eq = (fun #(a0, a1, a2) #(b0, b1, b2) -> (fun a b -> Float.equal (globalize a) (globalize b)) a0 b0 && (fun a b -> Float.equal (globalize a) (globalize b)) a1 b1 && (fun a b -> Float.equal (globalize a) (globalize b)) a2 b2) in + let mk_value i = #(Float.of_int i, Float.of_int i, Float.of_int i) in + (* 1. Create an array of size [size] *) + let a : #(float * float * float) array = makearray_dynamic size #(0., 0., 0.) in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 247; + let test = eq el #(0., 0., 0.) in + if not test then failwithf "test 247 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 248; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 248 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 249; + let test = raises in + if not test then failwithf "test 249 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #(0., 0., 0.) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 250; + let test = raises in + if not test then failwithf "test 250 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 251; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 251 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 252; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 252 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #(0., 0., 0.) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 253; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 253 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #(0., 0., 0.) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 254; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 254 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (*************************************************************************) + (* #(float * #(float * float) * #(float * #(float * float * float))) *) + (*************************************************************************) + let eq = (fun #(a0, a1, a2) #(b0, b1, b2) -> (fun a b -> Float.equal (globalize a) (globalize b)) a0 b0 && (fun #(a0, a1) #(b0, b1) -> (fun a b -> Float.equal (globalize a) (globalize b)) a0 b0 && (fun a b -> Float.equal (globalize a) (globalize b)) a1 b1) a1 b1 && (fun #(a0, a1) #(b0, b1) -> (fun a b -> Float.equal (globalize a) (globalize b)) a0 b0 && (fun #(a0, a1, a2) #(b0, b1, b2) -> (fun a b -> Float.equal (globalize a) (globalize b)) a0 b0 && (fun a b -> Float.equal (globalize a) (globalize b)) a1 b1 && (fun a b -> Float.equal (globalize a) (globalize b)) a2 b2) a1 b1) a2 b2) in + let mk_value i = #(Float.of_int i, #(Float.of_int i, Float.of_int i), #(Float.of_int i, #(Float.of_int i, Float.of_int i, Float.of_int i))) in + (* 1. Create an array of size [size] *) + let a : #(float * #(float * float) * #(float * #(float * float * float))) array = makearray_dynamic size #(0., #(0., 0.), #(0., #(0., 0., 0.))) in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 255; + let test = eq el #(0., #(0., 0.), #(0., #(0., 0., 0.))) in + if not test then failwithf "test 255 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 256; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 256 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 257; + let test = raises in + if not test then failwithf "test 257 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #(0., #(0., 0.), #(0., #(0., 0., 0.))) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 258; + let test = raises in + if not test then failwithf "test 258 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 259; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 259 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 260; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 260 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #(0., #(0., 0.), #(0., #(0., 0., 0.))) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 261; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 261 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #(0., #(0., 0.), #(0., #(0., 0., 0.))) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 262; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 262 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (********************************) + (* #(float# * int * int64#) *) + (********************************) + let eq = (fun #(a0, a1, a2) #(b0, b1, b2) -> (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) a0 b0 && (fun a b -> Int.equal a b) a1 b1 && (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a2 b2) in + let mk_value i = #(Float_u.of_int i, i, Int64_u.of_int i) in + (* 1. Create an array of size [size] *) + let a : #(float# * int * int64#) array = makearray_dynamic size #(#0., 0, #0L) in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 263; + let test = eq el #(#0., 0, #0L) in + if not test then failwithf "test 263 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 264; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 264 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 265; + let test = raises in + if not test then failwithf "test 265 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #(#0., 0, #0L) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 266; + let test = raises in + if not test then failwithf "test 266 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 267; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 267 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 268; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 268 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #(#0., 0, #0L) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 269; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 269 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #(#0., 0, #0L) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 270; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 270 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (***************************************************************************************) + (* #(float# * #(int * int64#) * float32# * #(int32# * #(float32# * float#)) * int) *) + (***************************************************************************************) + let eq = (fun #(a0, a1, a2, a3, a4) #(b0, b1, b2, b3, b4) -> (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) a0 b0 && (fun #(a0, a1) #(b0, b1) -> (fun a b -> Int.equal a b) a0 b0 && (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 b1) a1 b1 && (fun a b -> Float32_u.(equal (add #0.s a) (add #0.s b))) a2 b2 && (fun #(a0, a1) #(b0, b1) -> (fun a b -> Int32_u.(equal (add #0l a) (add #0l b))) a0 b0 && (fun #(a0, a1) #(b0, b1) -> (fun a b -> Float32_u.(equal (add #0.s a) (add #0.s b))) a0 b0 && (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) a1 b1) a1 b1) a3 b3 && (fun a b -> Int.equal a b) a4 b4) in + let mk_value i = #(Float_u.of_int i, #(i, Int64_u.of_int i), Float32_u.of_int i, #(Int32_u.of_int i, #(Float32_u.of_int i, Float_u.of_int i)), i) in + (* 1. Create an array of size [size] *) + let a : #(float# * #(int * int64#) * float32# * #(int32# * #(float32# * float#)) * int) array = makearray_dynamic size #(#0., #(0, #0L), #0.s, #(#0l, #(#0.s, #0.)), 0) in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 271; + let test = eq el #(#0., #(0, #0L), #0.s, #(#0l, #(#0.s, #0.)), 0) in + if not test then failwithf "test 271 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 272; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 272 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 273; + let test = raises in + if not test then failwithf "test 273 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #(#0., #(0, #0L), #0.s, #(#0l, #(#0.s, #0.)), 0) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 274; + let test = raises in + if not test then failwithf "test 274 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 275; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 275 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 276; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 276 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #(#0., #(0, #0L), #0.s, #(#0l, #(#0.s, #0.)), 0) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 277; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 277 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #(#0., #(0, #0L), #0.s, #(#0l, #(#0.s, #0.)), 0) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 278; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 278 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (********************) + (* #(ur2 * ur1) *) + (********************) + let eq = (fun #(a0, a1) #(b0, b1) -> (fun (#{ a = a1; b = b1 } : ur2) (#{ a = a2; b = b2 } : ur2) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 a2 && (fun a b -> Int.equal a b) b1 b2) a0 b0 && (fun (#{ a = a1; b = b1 } : ur1) (#{ a = a2; b = b2 } : ur1) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 a2 && (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) b1 b2) a1 b1) in + let mk_value i = #((#{ a = Int64_u.of_int i; b = i } : ur2), (#{ a = Int64_u.of_int i; b = Float_u.of_int i } : ur1)) in + (* 1. Create an array of size [size] *) + let a : #(ur2 * ur1) array = makearray_dynamic size #((#{ a = #0L; b = 0 } : ur2), (#{ a = #0L; b = #0. } : ur1)) in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 279; + let test = eq el #((#{ a = #0L; b = 0 } : ur2), (#{ a = #0L; b = #0. } : ur1)) in + if not test then failwithf "test 279 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 280; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 280 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 281; + let test = raises in + if not test then failwithf "test 281 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #((#{ a = #0L; b = 0 } : ur2), (#{ a = #0L; b = #0. } : ur1)) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 282; + let test = raises in + if not test then failwithf "test 282 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 283; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 283 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 284; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 284 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #((#{ a = #0L; b = 0 } : ur2), (#{ a = #0L; b = #0. } : ur1)) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 285; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 285 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #((#{ a = #0L; b = 0 } : ur2), (#{ a = #0L; b = #0. } : ur1)) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 286; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 286 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + () + +let test_makearray_dynamic_local size = + (****************) + (* float32# *) + (****************) + let eq = (fun a b -> Float32_u.(equal (add #0.s a) (add #0.s b))) in + let mk_value i = Float32_u.of_int i in + (* 1. Create an array of size [size] *) + let a : float32# array = makearray_dynamic_local size #0.s in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 287; + let test = eq el #0.s in + if not test then failwithf "test 287 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 288; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 288 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 289; + let test = raises in + if not test then failwithf "test 289 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #0.s with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 290; + let test = raises in + if not test then failwithf "test 290 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 291; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 291 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 292; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 292 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #0.s in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 293; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 293 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #0.s in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 294; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 294 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (**************) + (* float# *) + (**************) + let eq = (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) in + let mk_value i = Float_u.of_int i in + (* 1. Create an array of size [size] *) + let a : float# array = makearray_dynamic_local size #0. in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 295; + let test = eq el #0. in + if not test then failwithf "test 295 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 296; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 296 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 297; + let test = raises in + if not test then failwithf "test 297 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #0. with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 298; + let test = raises in + if not test then failwithf "test 298 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 299; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 299 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 300; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 300 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #0. in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 301; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 301 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #0. in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 302; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 302 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (**************) + (* int32# *) + (**************) + let eq = (fun a b -> Int32_u.(equal (add #0l a) (add #0l b))) in + let mk_value i = Int32_u.of_int i in + (* 1. Create an array of size [size] *) + let a : int32# array = makearray_dynamic_local size #0l in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 303; + let test = eq el #0l in + if not test then failwithf "test 303 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 304; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 304 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 305; + let test = raises in + if not test then failwithf "test 305 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #0l with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 306; + let test = raises in + if not test then failwithf "test 306 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 307; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 307 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 308; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 308 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #0l in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 309; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 309 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #0l in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 310; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 310 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (**************) + (* int64# *) + (**************) + let eq = (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) in + let mk_value i = Int64_u.of_int i in + (* 1. Create an array of size [size] *) + let a : int64# array = makearray_dynamic_local size #0L in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 311; + let test = eq el #0L in + if not test then failwithf "test 311 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 312; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 312 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 313; + let test = raises in + if not test then failwithf "test 313 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #0L with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 314; + let test = raises in + if not test then failwithf "test 314 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 315; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 315 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 316; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 316 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #0L in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 317; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 317 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #0L in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 318; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 318 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (******************) + (* nativeint# *) + (******************) + let eq = (fun a b -> Nativeint_u.(equal (add #0n a) (add #0n b))) in + let mk_value i = Nativeint_u.of_int i in + (* 1. Create an array of size [size] *) + let a : nativeint# array = makearray_dynamic_local size #0n in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 319; + let test = eq el #0n in + if not test then failwithf "test 319 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 320; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 320 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 321; + let test = raises in + if not test then failwithf "test 321 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #0n with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 322; + let test = raises in + if not test then failwithf "test 322 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 323; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 323 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 324; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 324 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #0n in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 325; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 325 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #0n in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 326; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 326 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (***********) + (* ur1 *) + (***********) + let eq = (fun (#{ a = a1; b = b1 } : ur1) (#{ a = a2; b = b2 } : ur1) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 a2 && (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) b1 b2) in + let mk_value i = (#{ a = Int64_u.of_int i; b = Float_u.of_int i } : ur1) in + (* 1. Create an array of size [size] *) + let a : ur1 array = makearray_dynamic_local size (#{ a = #0L; b = #0. } : ur1) in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 327; + let test = eq el (#{ a = #0L; b = #0. } : ur1) in + if not test then failwithf "test 327 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 328; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 328 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 329; + let test = raises in + if not test then failwithf "test 329 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i (#{ a = #0L; b = #0. } : ur1) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 330; + let test = raises in + if not test then failwithf "test 330 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 331; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 331 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 332; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 332 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 (#{ a = #0L; b = #0. } : ur1) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 333; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 333 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 (#{ a = #0L; b = #0. } : ur1) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 334; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 334 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (***********) + (* ur3 *) + (***********) + let eq = (fun (#{ a = a1 } : ur3) (#{ a = a2 } : ur3) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 a2) in + let mk_value i = (#{ a = Int64_u.of_int i } : ur3) in + (* 1. Create an array of size [size] *) + let a : ur3 array = makearray_dynamic_local size (#{ a = #0L } : ur3) in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 335; + let test = eq el (#{ a = #0L } : ur3) in + if not test then failwithf "test 335 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 336; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 336 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 337; + let test = raises in + if not test then failwithf "test 337 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i (#{ a = #0L } : ur3) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 338; + let test = raises in + if not test then failwithf "test 338 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 339; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 339 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 340; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 340 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 (#{ a = #0L } : ur3) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 341; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 341 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 (#{ a = #0L } : ur3) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 342; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 342 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (***********) + (* ur4 *) + (***********) + let eq = (fun (#{ a = a1; b = b1 } : ur4) (#{ a = a2; b = b2 } : ur4) -> (fun (#{ a = a1; b = b1 } : ur1) (#{ a = a2; b = b2 } : ur1) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 a2 && (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) b1 b2) a1 a2 && (fun (#{ a = a1 } : ur3) (#{ a = a2 } : ur3) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 a2) b1 b2) in + let mk_value i = (#{ a = (#{ a = Int64_u.of_int i; b = Float_u.of_int i } : ur1); b = (#{ a = Int64_u.of_int i } : ur3) } : ur4) in + (* 1. Create an array of size [size] *) + let a : ur4 array = makearray_dynamic_local size (#{ a = (#{ a = #0L; b = #0. } : ur1); b = (#{ a = #0L } : ur3) } : ur4) in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 343; + let test = eq el (#{ a = (#{ a = #0L; b = #0. } : ur1); b = (#{ a = #0L } : ur3) } : ur4) in + if not test then failwithf "test 343 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 344; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 344 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 345; + let test = raises in + if not test then failwithf "test 345 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i (#{ a = (#{ a = #0L; b = #0. } : ur1); b = (#{ a = #0L } : ur3) } : ur4) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 346; + let test = raises in + if not test then failwithf "test 346 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 347; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 347 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 348; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 348 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 (#{ a = (#{ a = #0L; b = #0. } : ur1); b = (#{ a = #0L } : ur3) } : ur4) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 349; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 349 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 (#{ a = (#{ a = #0L; b = #0. } : ur1); b = (#{ a = #0L } : ur3) } : ur4) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 350; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 350 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (***********************************) + (* #(float# * int32# * int64#) *) + (***********************************) + let eq = (fun #(a0, a1, a2) #(b0, b1, b2) -> (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) a0 b0 && (fun a b -> Int32_u.(equal (add #0l a) (add #0l b))) a1 b1 && (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a2 b2) in + let mk_value i = #(Float_u.of_int i, Int32_u.of_int i, Int64_u.of_int i) in + (* 1. Create an array of size [size] *) + let a : #(float# * int32# * int64#) array = makearray_dynamic_local size #(#0., #0l, #0L) in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 351; + let test = eq el #(#0., #0l, #0L) in + if not test then failwithf "test 351 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 352; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 352 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 353; + let test = raises in + if not test then failwithf "test 353 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #(#0., #0l, #0L) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 354; + let test = raises in + if not test then failwithf "test 354 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 355; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 355 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 356; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 356 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #(#0., #0l, #0L) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 357; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 357 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #(#0., #0l, #0L) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 358; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 358 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (*********************************************************************************************) + (* #(float# * #(int64# * int64#) * float32# * #(int32# * #(float32# * float#)) * int64#) *) + (*********************************************************************************************) + let eq = (fun #(a0, a1, a2, a3, a4) #(b0, b1, b2, b3, b4) -> (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) a0 b0 && (fun #(a0, a1) #(b0, b1) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a0 b0 && (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 b1) a1 b1 && (fun a b -> Float32_u.(equal (add #0.s a) (add #0.s b))) a2 b2 && (fun #(a0, a1) #(b0, b1) -> (fun a b -> Int32_u.(equal (add #0l a) (add #0l b))) a0 b0 && (fun #(a0, a1) #(b0, b1) -> (fun a b -> Float32_u.(equal (add #0.s a) (add #0.s b))) a0 b0 && (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) a1 b1) a1 b1) a3 b3 && (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a4 b4) in + let mk_value i = #(Float_u.of_int i, #(Int64_u.of_int i, Int64_u.of_int i), Float32_u.of_int i, #(Int32_u.of_int i, #(Float32_u.of_int i, Float_u.of_int i)), Int64_u.of_int i) in + (* 1. Create an array of size [size] *) + let a : #(float# * #(int64# * int64#) * float32# * #(int32# * #(float32# * float#)) * int64#) array = makearray_dynamic_local size #(#0., #(#0L, #0L), #0.s, #(#0l, #(#0.s, #0.)), #0L) in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 359; + let test = eq el #(#0., #(#0L, #0L), #0.s, #(#0l, #(#0.s, #0.)), #0L) in + if not test then failwithf "test 359 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 360; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 360 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 361; + let test = raises in + if not test then failwithf "test 361 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #(#0., #(#0L, #0L), #0.s, #(#0l, #(#0.s, #0.)), #0L) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 362; + let test = raises in + if not test then failwithf "test 362 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 363; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 363 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 364; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 364 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #(#0., #(#0L, #0L), #0.s, #(#0l, #(#0.s, #0.)), #0L) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 365; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 365 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #(#0., #(#0L, #0L), #0.s, #(#0l, #(#0.s, #0.)), #0L) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 366; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 366 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (***********************) + (* #(int64# * ur1) *) + (***********************) + let eq = (fun #(a0, a1) #(b0, b1) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a0 b0 && (fun (#{ a = a1; b = b1 } : ur1) (#{ a = a2; b = b2 } : ur1) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 a2 && (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) b1 b2) a1 b1) in + let mk_value i = #(Int64_u.of_int i, (#{ a = Int64_u.of_int i; b = Float_u.of_int i } : ur1)) in + (* 1. Create an array of size [size] *) + let a : #(int64# * ur1) array = makearray_dynamic_local size #(#0L, (#{ a = #0L; b = #0. } : ur1)) in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 367; + let test = eq el #(#0L, (#{ a = #0L; b = #0. } : ur1)) in + if not test then failwithf "test 367 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 368; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 368 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 369; + let test = raises in + if not test then failwithf "test 369 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #(#0L, (#{ a = #0L; b = #0. } : ur1)) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 370; + let test = raises in + if not test then failwithf "test 370 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 371; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 371 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 372; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 372 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #(#0L, (#{ a = #0L; b = #0. } : ur1)) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 373; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 373 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #(#0L, (#{ a = #0L; b = #0. } : ur1)) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 374; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 374 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (***************) + (* float32 *) + (***************) + let eq = (fun a b -> Float.equal (Float32.to_float a) (Float32.to_float b)) in + let mk_value i = Float32.of_int i in + (* 1. Create an array of size [size] *) + let a : float32 array = makearray_dynamic_local size 0.s in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 375; + let test = eq el 0.s in + if not test then failwithf "test 375 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 376; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 376 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 377; + let test = raises in + if not test then failwithf "test 377 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i 0.s with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 378; + let test = raises in + if not test then failwithf "test 378 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 379; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 379 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 380; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 380 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 0.s in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 381; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 381 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 0.s in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 382; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 382 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (*************) + (* float *) + (*************) + let eq = (fun a b -> Float.equal (globalize a) (globalize b)) in + let mk_value i = Float.of_int i in + (* 1. Create an array of size [size] *) + let a : float array = makearray_dynamic_local size 0. in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 383; + let test = eq el 0. in + if not test then failwithf "test 383 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 384; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 384 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 385; + let test = raises in + if not test then failwithf "test 385 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i 0. with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 386; + let test = raises in + if not test then failwithf "test 386 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 387; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 387 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 388; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 388 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 0. in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 389; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 389 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 0. in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 390; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 390 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (*************) + (* int32 *) + (*************) + let eq = (fun a b -> Int32.equal (globalize a) (globalize b)) in + let mk_value i = Int32.of_int i in + (* 1. Create an array of size [size] *) + let a : int32 array = makearray_dynamic_local size 0l in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 391; + let test = eq el 0l in + if not test then failwithf "test 391 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 392; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 392 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 393; + let test = raises in + if not test then failwithf "test 393 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i 0l with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 394; + let test = raises in + if not test then failwithf "test 394 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 395; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 395 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 396; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 396 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 0l in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 397; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 397 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 0l in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 398; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 398 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (*************) + (* int64 *) + (*************) + let eq = (fun a b -> Int64.equal (globalize a) (globalize b)) in + let mk_value i = Int64.of_int i in + (* 1. Create an array of size [size] *) + let a : int64 array = makearray_dynamic_local size 0L in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 399; + let test = eq el 0L in + if not test then failwithf "test 399 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 400; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 400 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 401; + let test = raises in + if not test then failwithf "test 401 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i 0L with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 402; + let test = raises in + if not test then failwithf "test 402 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 403; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 403 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 404; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 404 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 0L in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 405; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 405 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 0L in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 406; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 406 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (*****************) + (* nativeint *) + (*****************) + let eq = (fun a b -> Nativeint.equal (globalize a) (globalize b)) in + let mk_value i = Nativeint.of_int i in + (* 1. Create an array of size [size] *) + let a : nativeint array = makearray_dynamic_local size 0n in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 407; + let test = eq el 0n in + if not test then failwithf "test 407 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 408; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 408 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 409; + let test = raises in + if not test then failwithf "test 409 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i 0n with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 410; + let test = raises in + if not test then failwithf "test 410 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 411; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 411 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 412; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 412 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 0n in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 413; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 413 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 0n in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 414; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 414 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (***********) + (* int *) + (***********) + let eq = (fun a b -> Int.equal a b) in + let mk_value i = i in + (* 1. Create an array of size [size] *) + let a : int array = makearray_dynamic_local size 0 in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 415; + let test = eq el 0 in + if not test then failwithf "test 415 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 416; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 416 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 417; + let test = raises in + if not test then failwithf "test 417 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i 0 with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 418; + let test = raises in + if not test then failwithf "test 418 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 419; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 419 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 420; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 420 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 0 in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 421; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 421 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 0 in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 422; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 422 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (*************) + (* enum3 *) + (*************) + let eq = (fun a b -> match a, b with A3_0, A3_0 | A3_1, A3_1 | A3_2, A3_2 -> true | _ -> false) in + let mk_value i = (match Int.rem i 3 with 0 -> A3_0 | 1 -> A3_1 | 2 -> A3_2 | _ -> assert false) in + (* 1. Create an array of size [size] *) + let a : enum3 array = makearray_dynamic_local size A3_0 in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 423; + let test = eq el A3_0 in + if not test then failwithf "test 423 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 424; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 424 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 425; + let test = raises in + if not test then failwithf "test 425 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i A3_0 with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 426; + let test = raises in + if not test then failwithf "test 426 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 427; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 427 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 428; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 428 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 A3_0 in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 429; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 429 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 A3_0 in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 430; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 430 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (***********) + (* ur2 *) + (***********) + let eq = (fun (#{ a = a1; b = b1 } : ur2) (#{ a = a2; b = b2 } : ur2) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 a2 && (fun a b -> Int.equal a b) b1 b2) in + let mk_value i = (#{ a = Int64_u.of_int i; b = i } : ur2) in + (* 1. Create an array of size [size] *) + let a : ur2 array = makearray_dynamic_local size (#{ a = #0L; b = 0 } : ur2) in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 431; + let test = eq el (#{ a = #0L; b = 0 } : ur2) in + if not test then failwithf "test 431 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 432; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 432 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 433; + let test = raises in + if not test then failwithf "test 433 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i (#{ a = #0L; b = 0 } : ur2) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 434; + let test = raises in + if not test then failwithf "test 434 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 435; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 435 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 436; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 436 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 (#{ a = #0L; b = 0 } : ur2) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 437; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 437 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 (#{ a = #0L; b = 0 } : ur2) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 438; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 438 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (**********************) + (* #(int * int64) *) + (**********************) + let eq = (fun #(a0, a1) #(b0, b1) -> (fun a b -> Int.equal a b) a0 b0 && (fun a b -> Int64.equal (globalize a) (globalize b)) a1 b1) in + let mk_value i = #(i, Int64.of_int i) in + (* 1. Create an array of size [size] *) + let a : #(int * int64) array = makearray_dynamic_local size #(0, 0L) in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 439; + let test = eq el #(0, 0L) in + if not test then failwithf "test 439 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 440; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 440 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 441; + let test = raises in + if not test then failwithf "test 441 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #(0, 0L) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 442; + let test = raises in + if not test then failwithf "test 442 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 443; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 443 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 444; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 444 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #(0, 0L) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 445; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 445 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #(0, 0L) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 446; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 446 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (**************************************************************************************************************) + (* #(int64 option * #(int * int32 * float) * float * #(float32 * (nativeint * nativeint) option) * int32) *) + (**************************************************************************************************************) + let eq = (fun #(a0, a1, a2, a3, a4) #(b0, b1, b2, b3, b4) -> (fun a b -> match a, b with None,None -> true | Some a,Some b -> (fun a b -> Int64.equal (globalize a) (globalize b)) a b|_->false) a0 b0 && (fun #(a0, a1, a2) #(b0, b1, b2) -> (fun a b -> Int.equal a b) a0 b0 && (fun a b -> Int32.equal (globalize a) (globalize b)) a1 b1 && (fun a b -> Float.equal (globalize a) (globalize b)) a2 b2) a1 b1 && (fun a b -> Float.equal (globalize a) (globalize b)) a2 b2 && (fun #(a0, a1) #(b0, b1) -> (fun a b -> Float.equal (Float32.to_float a) (Float32.to_float b)) a0 b0 && (fun a b -> match a, b with None,None -> true | Some a,Some b -> (fun (a0, a1) (b0, b1) -> (fun a b -> Nativeint.equal (globalize a) (globalize b)) a0 b0 && (fun a b -> Nativeint.equal (globalize a) (globalize b)) a1 b1) a b|_->false) a1 b1) a3 b3 && (fun a b -> Int32.equal (globalize a) (globalize b)) a4 b4) in + let mk_value i = #((if i == 0 then None else Some (Int64.of_int i)), #(i, Int32.of_int i, Float.of_int i), Float.of_int i, #(Float32.of_int i, (if i == 0 then None else Some ((Nativeint.of_int i, Nativeint.of_int i)))), Int32.of_int i) in + (* 1. Create an array of size [size] *) + let a : #(int64 option * #(int * int32 * float) * float * #(float32 * (nativeint * nativeint) option) * int32) array = makearray_dynamic_local size #(None, #(0, 0l, 0.), 0., #(0.s, None), 0l) in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 447; + let test = eq el #(None, #(0, 0l, 0.), 0., #(0.s, None), 0l) in + if not test then failwithf "test 447 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 448; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 448 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 449; + let test = raises in + if not test then failwithf "test 449 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #(None, #(0, 0l, 0.), 0., #(0.s, None), 0l) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 450; + let test = raises in + if not test then failwithf "test 450 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 451; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 451 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 452; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 452 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #(None, #(0, 0l, 0.), 0., #(0.s, None), 0l) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 453; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 453 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #(None, #(0, 0l, 0.), 0., #(0.s, None), 0l) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 454; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 454 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (********************************) + (* #(float * float * float) *) + (********************************) + let eq = (fun #(a0, a1, a2) #(b0, b1, b2) -> (fun a b -> Float.equal (globalize a) (globalize b)) a0 b0 && (fun a b -> Float.equal (globalize a) (globalize b)) a1 b1 && (fun a b -> Float.equal (globalize a) (globalize b)) a2 b2) in + let mk_value i = #(Float.of_int i, Float.of_int i, Float.of_int i) in + (* 1. Create an array of size [size] *) + let a : #(float * float * float) array = makearray_dynamic_local size #(0., 0., 0.) in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 455; + let test = eq el #(0., 0., 0.) in + if not test then failwithf "test 455 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 456; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 456 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 457; + let test = raises in + if not test then failwithf "test 457 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #(0., 0., 0.) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 458; + let test = raises in + if not test then failwithf "test 458 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 459; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 459 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 460; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 460 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #(0., 0., 0.) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 461; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 461 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #(0., 0., 0.) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 462; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 462 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (*************************************************************************) + (* #(float * #(float * float) * #(float * #(float * float * float))) *) + (*************************************************************************) + let eq = (fun #(a0, a1, a2) #(b0, b1, b2) -> (fun a b -> Float.equal (globalize a) (globalize b)) a0 b0 && (fun #(a0, a1) #(b0, b1) -> (fun a b -> Float.equal (globalize a) (globalize b)) a0 b0 && (fun a b -> Float.equal (globalize a) (globalize b)) a1 b1) a1 b1 && (fun #(a0, a1) #(b0, b1) -> (fun a b -> Float.equal (globalize a) (globalize b)) a0 b0 && (fun #(a0, a1, a2) #(b0, b1, b2) -> (fun a b -> Float.equal (globalize a) (globalize b)) a0 b0 && (fun a b -> Float.equal (globalize a) (globalize b)) a1 b1 && (fun a b -> Float.equal (globalize a) (globalize b)) a2 b2) a1 b1) a2 b2) in + let mk_value i = #(Float.of_int i, #(Float.of_int i, Float.of_int i), #(Float.of_int i, #(Float.of_int i, Float.of_int i, Float.of_int i))) in + (* 1. Create an array of size [size] *) + let a : #(float * #(float * float) * #(float * #(float * float * float))) array = makearray_dynamic_local size #(0., #(0., 0.), #(0., #(0., 0., 0.))) in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 463; + let test = eq el #(0., #(0., 0.), #(0., #(0., 0., 0.))) in + if not test then failwithf "test 463 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 464; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 464 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 465; + let test = raises in + if not test then failwithf "test 465 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #(0., #(0., 0.), #(0., #(0., 0., 0.))) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 466; + let test = raises in + if not test then failwithf "test 466 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 467; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 467 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 468; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 468 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #(0., #(0., 0.), #(0., #(0., 0., 0.))) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 469; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 469 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #(0., #(0., 0.), #(0., #(0., 0., 0.))) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 470; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 470 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (********************************) + (* #(float# * int * int64#) *) + (********************************) + let eq = (fun #(a0, a1, a2) #(b0, b1, b2) -> (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) a0 b0 && (fun a b -> Int.equal a b) a1 b1 && (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a2 b2) in + let mk_value i = #(Float_u.of_int i, i, Int64_u.of_int i) in + (* 1. Create an array of size [size] *) + let a : #(float# * int * int64#) array = makearray_dynamic_local size #(#0., 0, #0L) in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 471; + let test = eq el #(#0., 0, #0L) in + if not test then failwithf "test 471 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 472; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 472 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 473; + let test = raises in + if not test then failwithf "test 473 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #(#0., 0, #0L) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 474; + let test = raises in + if not test then failwithf "test 474 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 475; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 475 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 476; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 476 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #(#0., 0, #0L) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 477; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 477 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #(#0., 0, #0L) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 478; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 478 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (***************************************************************************************) + (* #(float# * #(int * int64#) * float32# * #(int32# * #(float32# * float#)) * int) *) + (***************************************************************************************) + let eq = (fun #(a0, a1, a2, a3, a4) #(b0, b1, b2, b3, b4) -> (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) a0 b0 && (fun #(a0, a1) #(b0, b1) -> (fun a b -> Int.equal a b) a0 b0 && (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 b1) a1 b1 && (fun a b -> Float32_u.(equal (add #0.s a) (add #0.s b))) a2 b2 && (fun #(a0, a1) #(b0, b1) -> (fun a b -> Int32_u.(equal (add #0l a) (add #0l b))) a0 b0 && (fun #(a0, a1) #(b0, b1) -> (fun a b -> Float32_u.(equal (add #0.s a) (add #0.s b))) a0 b0 && (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) a1 b1) a1 b1) a3 b3 && (fun a b -> Int.equal a b) a4 b4) in + let mk_value i = #(Float_u.of_int i, #(i, Int64_u.of_int i), Float32_u.of_int i, #(Int32_u.of_int i, #(Float32_u.of_int i, Float_u.of_int i)), i) in + (* 1. Create an array of size [size] *) + let a : #(float# * #(int * int64#) * float32# * #(int32# * #(float32# * float#)) * int) array = makearray_dynamic_local size #(#0., #(0, #0L), #0.s, #(#0l, #(#0.s, #0.)), 0) in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 479; + let test = eq el #(#0., #(0, #0L), #0.s, #(#0l, #(#0.s, #0.)), 0) in + if not test then failwithf "test 479 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 480; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 480 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 481; + let test = raises in + if not test then failwithf "test 481 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #(#0., #(0, #0L), #0.s, #(#0l, #(#0.s, #0.)), 0) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 482; + let test = raises in + if not test then failwithf "test 482 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 483; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 483 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 484; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 484 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #(#0., #(0, #0L), #0.s, #(#0l, #(#0.s, #0.)), 0) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 485; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 485 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #(#0., #(0, #0L), #0.s, #(#0l, #(#0.s, #0.)), 0) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 486; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 486 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (********************) + (* #(ur2 * ur1) *) + (********************) + let eq = (fun #(a0, a1) #(b0, b1) -> (fun (#{ a = a1; b = b1 } : ur2) (#{ a = a2; b = b2 } : ur2) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 a2 && (fun a b -> Int.equal a b) b1 b2) a0 b0 && (fun (#{ a = a1; b = b1 } : ur1) (#{ a = a2; b = b2 } : ur1) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 a2 && (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) b1 b2) a1 b1) in + let mk_value i = #((#{ a = Int64_u.of_int i; b = i } : ur2), (#{ a = Int64_u.of_int i; b = Float_u.of_int i } : ur1)) in + (* 1. Create an array of size [size] *) + let a : #(ur2 * ur1) array = makearray_dynamic_local size #((#{ a = #0L; b = 0 } : ur2), (#{ a = #0L; b = #0. } : ur1)) in + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + mark_test_run 487; + let test = eq el #((#{ a = #0L; b = 0 } : ur2), (#{ a = #0L; b = #0. } : ur1)) in + if not test then failwithf "test 487 failed %d %d" size i; + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 488; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 488 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 489; + let test = raises in + if not test then failwithf "test 489 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #((#{ a = #0L; b = 0 } : ur2), (#{ a = #0L; b = #0. } : ur1)) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 490; + let test = raises in + if not test then failwithf "test 490 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 491; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 491 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 492; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 492 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #((#{ a = #0L; b = 0 } : ur2), (#{ a = #0L; b = #0. } : ur1)) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 493; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 493 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #((#{ a = #0L; b = 0 } : ur2), (#{ a = #0L; b = #0. } : ur1)) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 494; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 494 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + () + +let test_makearray_dynamic_uninit size = + (****************) + (* float32# *) + (****************) + let eq = (fun a b -> Float32_u.(equal (add #0.s a) (add #0.s b))) in + let mk_value i = Float32_u.of_int i in + (* 1. Create an array of size [size] *) + let a : float32# array = makearray_dynamic_uninit size in + (* 2. For uninitialized arrays, element values are unspecified *) + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + let _ = el in () + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 495; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 495 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 496; + let test = raises in + if not test then failwithf "test 496 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #0.s with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 497; + let test = raises in + if not test then failwithf "test 497 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 498; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 498 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 499; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 499 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #0.s in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 500; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 500 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #0.s in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 501; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 501 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (**************) + (* float# *) + (**************) + let eq = (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) in + let mk_value i = Float_u.of_int i in + (* 1. Create an array of size [size] *) + let a : float# array = makearray_dynamic_uninit size in + (* 2. For uninitialized arrays, element values are unspecified *) + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + let _ = el in () + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 502; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 502 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 503; + let test = raises in + if not test then failwithf "test 503 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #0. with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 504; + let test = raises in + if not test then failwithf "test 504 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 505; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 505 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 506; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 506 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #0. in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 507; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 507 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #0. in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 508; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 508 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (**************) + (* int32# *) + (**************) + let eq = (fun a b -> Int32_u.(equal (add #0l a) (add #0l b))) in + let mk_value i = Int32_u.of_int i in + (* 1. Create an array of size [size] *) + let a : int32# array = makearray_dynamic_uninit size in + (* 2. For uninitialized arrays, element values are unspecified *) + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + let _ = el in () + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 509; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 509 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 510; + let test = raises in + if not test then failwithf "test 510 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #0l with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 511; + let test = raises in + if not test then failwithf "test 511 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 512; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 512 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 513; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 513 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #0l in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 514; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 514 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #0l in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 515; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 515 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (**************) + (* int64# *) + (**************) + let eq = (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) in + let mk_value i = Int64_u.of_int i in + (* 1. Create an array of size [size] *) + let a : int64# array = makearray_dynamic_uninit size in + (* 2. For uninitialized arrays, element values are unspecified *) + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + let _ = el in () + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 516; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 516 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 517; + let test = raises in + if not test then failwithf "test 517 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #0L with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 518; + let test = raises in + if not test then failwithf "test 518 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 519; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 519 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 520; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 520 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #0L in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 521; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 521 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #0L in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 522; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 522 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (******************) + (* nativeint# *) + (******************) + let eq = (fun a b -> Nativeint_u.(equal (add #0n a) (add #0n b))) in + let mk_value i = Nativeint_u.of_int i in + (* 1. Create an array of size [size] *) + let a : nativeint# array = makearray_dynamic_uninit size in + (* 2. For uninitialized arrays, element values are unspecified *) + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + let _ = el in () + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 523; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 523 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 524; + let test = raises in + if not test then failwithf "test 524 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #0n with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 525; + let test = raises in + if not test then failwithf "test 525 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 526; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 526 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 527; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 527 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #0n in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 528; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 528 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #0n in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 529; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 529 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (***********) + (* ur1 *) + (***********) + let eq = (fun (#{ a = a1; b = b1 } : ur1) (#{ a = a2; b = b2 } : ur1) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 a2 && (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) b1 b2) in + let mk_value i = (#{ a = Int64_u.of_int i; b = Float_u.of_int i } : ur1) in + (* 1. Create an array of size [size] *) + let a : ur1 array = makearray_dynamic_uninit size in + (* 2. For uninitialized arrays, element values are unspecified *) + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + let _ = el in () + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 530; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 530 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 531; + let test = raises in + if not test then failwithf "test 531 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i (#{ a = #0L; b = #0. } : ur1) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 532; + let test = raises in + if not test then failwithf "test 532 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 533; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 533 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 534; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 534 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 (#{ a = #0L; b = #0. } : ur1) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 535; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 535 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 (#{ a = #0L; b = #0. } : ur1) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 536; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 536 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (***********) + (* ur3 *) + (***********) + let eq = (fun (#{ a = a1 } : ur3) (#{ a = a2 } : ur3) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 a2) in + let mk_value i = (#{ a = Int64_u.of_int i } : ur3) in + (* 1. Create an array of size [size] *) + let a : ur3 array = makearray_dynamic_uninit size in + (* 2. For uninitialized arrays, element values are unspecified *) + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + let _ = el in () + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 537; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 537 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 538; + let test = raises in + if not test then failwithf "test 538 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i (#{ a = #0L } : ur3) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 539; + let test = raises in + if not test then failwithf "test 539 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 540; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 540 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 541; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 541 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 (#{ a = #0L } : ur3) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 542; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 542 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 (#{ a = #0L } : ur3) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 543; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 543 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (***********) + (* ur4 *) + (***********) + let eq = (fun (#{ a = a1; b = b1 } : ur4) (#{ a = a2; b = b2 } : ur4) -> (fun (#{ a = a1; b = b1 } : ur1) (#{ a = a2; b = b2 } : ur1) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 a2 && (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) b1 b2) a1 a2 && (fun (#{ a = a1 } : ur3) (#{ a = a2 } : ur3) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 a2) b1 b2) in + let mk_value i = (#{ a = (#{ a = Int64_u.of_int i; b = Float_u.of_int i } : ur1); b = (#{ a = Int64_u.of_int i } : ur3) } : ur4) in + (* 1. Create an array of size [size] *) + let a : ur4 array = makearray_dynamic_uninit size in + (* 2. For uninitialized arrays, element values are unspecified *) + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + let _ = el in () + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 544; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 544 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 545; + let test = raises in + if not test then failwithf "test 545 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i (#{ a = (#{ a = #0L; b = #0. } : ur1); b = (#{ a = #0L } : ur3) } : ur4) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 546; + let test = raises in + if not test then failwithf "test 546 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 547; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 547 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 548; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 548 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 (#{ a = (#{ a = #0L; b = #0. } : ur1); b = (#{ a = #0L } : ur3) } : ur4) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 549; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 549 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 (#{ a = (#{ a = #0L; b = #0. } : ur1); b = (#{ a = #0L } : ur3) } : ur4) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 550; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 550 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (***********************************) + (* #(float# * int32# * int64#) *) + (***********************************) + let eq = (fun #(a0, a1, a2) #(b0, b1, b2) -> (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) a0 b0 && (fun a b -> Int32_u.(equal (add #0l a) (add #0l b))) a1 b1 && (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a2 b2) in + let mk_value i = #(Float_u.of_int i, Int32_u.of_int i, Int64_u.of_int i) in + (* 1. Create an array of size [size] *) + let a : #(float# * int32# * int64#) array = makearray_dynamic_uninit size in + (* 2. For uninitialized arrays, element values are unspecified *) + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + let _ = el in () + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 551; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 551 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 552; + let test = raises in + if not test then failwithf "test 552 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #(#0., #0l, #0L) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 553; + let test = raises in + if not test then failwithf "test 553 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 554; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 554 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 555; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 555 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #(#0., #0l, #0L) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 556; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 556 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #(#0., #0l, #0L) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 557; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 557 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (*********************************************************************************************) + (* #(float# * #(int64# * int64#) * float32# * #(int32# * #(float32# * float#)) * int64#) *) + (*********************************************************************************************) + let eq = (fun #(a0, a1, a2, a3, a4) #(b0, b1, b2, b3, b4) -> (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) a0 b0 && (fun #(a0, a1) #(b0, b1) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a0 b0 && (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 b1) a1 b1 && (fun a b -> Float32_u.(equal (add #0.s a) (add #0.s b))) a2 b2 && (fun #(a0, a1) #(b0, b1) -> (fun a b -> Int32_u.(equal (add #0l a) (add #0l b))) a0 b0 && (fun #(a0, a1) #(b0, b1) -> (fun a b -> Float32_u.(equal (add #0.s a) (add #0.s b))) a0 b0 && (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) a1 b1) a1 b1) a3 b3 && (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a4 b4) in + let mk_value i = #(Float_u.of_int i, #(Int64_u.of_int i, Int64_u.of_int i), Float32_u.of_int i, #(Int32_u.of_int i, #(Float32_u.of_int i, Float_u.of_int i)), Int64_u.of_int i) in + (* 1. Create an array of size [size] *) + let a : #(float# * #(int64# * int64#) * float32# * #(int32# * #(float32# * float#)) * int64#) array = makearray_dynamic_uninit size in + (* 2. For uninitialized arrays, element values are unspecified *) + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + let _ = el in () + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 558; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 558 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 559; + let test = raises in + if not test then failwithf "test 559 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #(#0., #(#0L, #0L), #0.s, #(#0l, #(#0.s, #0.)), #0L) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 560; + let test = raises in + if not test then failwithf "test 560 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 561; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 561 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 562; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 562 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #(#0., #(#0L, #0L), #0.s, #(#0l, #(#0.s, #0.)), #0L) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 563; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 563 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #(#0., #(#0L, #0L), #0.s, #(#0l, #(#0.s, #0.)), #0L) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 564; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 564 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (***********************) + (* #(int64# * ur1) *) + (***********************) + let eq = (fun #(a0, a1) #(b0, b1) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a0 b0 && (fun (#{ a = a1; b = b1 } : ur1) (#{ a = a2; b = b2 } : ur1) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 a2 && (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) b1 b2) a1 b1) in + let mk_value i = #(Int64_u.of_int i, (#{ a = Int64_u.of_int i; b = Float_u.of_int i } : ur1)) in + (* 1. Create an array of size [size] *) + let a : #(int64# * ur1) array = makearray_dynamic_uninit size in + (* 2. For uninitialized arrays, element values are unspecified *) + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + let _ = el in () + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 565; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 565 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 566; + let test = raises in + if not test then failwithf "test 566 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #(#0L, (#{ a = #0L; b = #0. } : ur1)) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 567; + let test = raises in + if not test then failwithf "test 567 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 568; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 568 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 569; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 569 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #(#0L, (#{ a = #0L; b = #0. } : ur1)) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 570; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 570 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #(#0L, (#{ a = #0L; b = #0. } : ur1)) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 571; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 571 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + () + +let test_makearray_dynamic_uninit_local size = + (****************) + (* float32# *) + (****************) + let eq = (fun a b -> Float32_u.(equal (add #0.s a) (add #0.s b))) in + let mk_value i = Float32_u.of_int i in + (* 1. Create an array of size [size] *) + let a : float32# array = makearray_dynamic_uninit_local size in + (* 2. For uninitialized arrays, element values are unspecified *) + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + let _ = el in () + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 572; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 572 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 573; + let test = raises in + if not test then failwithf "test 573 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #0.s with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 574; + let test = raises in + if not test then failwithf "test 574 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 575; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 575 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 576; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 576 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #0.s in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 577; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 577 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #0.s in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 578; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 578 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (**************) + (* float# *) + (**************) + let eq = (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) in + let mk_value i = Float_u.of_int i in + (* 1. Create an array of size [size] *) + let a : float# array = makearray_dynamic_uninit_local size in + (* 2. For uninitialized arrays, element values are unspecified *) + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + let _ = el in () + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 579; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 579 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 580; + let test = raises in + if not test then failwithf "test 580 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #0. with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 581; + let test = raises in + if not test then failwithf "test 581 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 582; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 582 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 583; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 583 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #0. in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 584; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 584 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #0. in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 585; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 585 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (**************) + (* int32# *) + (**************) + let eq = (fun a b -> Int32_u.(equal (add #0l a) (add #0l b))) in + let mk_value i = Int32_u.of_int i in + (* 1. Create an array of size [size] *) + let a : int32# array = makearray_dynamic_uninit_local size in + (* 2. For uninitialized arrays, element values are unspecified *) + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + let _ = el in () + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 586; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 586 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 587; + let test = raises in + if not test then failwithf "test 587 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #0l with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 588; + let test = raises in + if not test then failwithf "test 588 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 589; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 589 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 590; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 590 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #0l in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 591; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 591 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #0l in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 592; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 592 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (**************) + (* int64# *) + (**************) + let eq = (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) in + let mk_value i = Int64_u.of_int i in + (* 1. Create an array of size [size] *) + let a : int64# array = makearray_dynamic_uninit_local size in + (* 2. For uninitialized arrays, element values are unspecified *) + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + let _ = el in () + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 593; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 593 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 594; + let test = raises in + if not test then failwithf "test 594 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #0L with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 595; + let test = raises in + if not test then failwithf "test 595 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 596; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 596 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 597; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 597 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #0L in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 598; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 598 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #0L in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 599; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 599 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (******************) + (* nativeint# *) + (******************) + let eq = (fun a b -> Nativeint_u.(equal (add #0n a) (add #0n b))) in + let mk_value i = Nativeint_u.of_int i in + (* 1. Create an array of size [size] *) + let a : nativeint# array = makearray_dynamic_uninit_local size in + (* 2. For uninitialized arrays, element values are unspecified *) + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + let _ = el in () + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 600; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 600 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 601; + let test = raises in + if not test then failwithf "test 601 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #0n with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 602; + let test = raises in + if not test then failwithf "test 602 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 603; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 603 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 604; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 604 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #0n in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 605; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 605 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #0n in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 606; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 606 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (***********) + (* ur1 *) + (***********) + let eq = (fun (#{ a = a1; b = b1 } : ur1) (#{ a = a2; b = b2 } : ur1) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 a2 && (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) b1 b2) in + let mk_value i = (#{ a = Int64_u.of_int i; b = Float_u.of_int i } : ur1) in + (* 1. Create an array of size [size] *) + let a : ur1 array = makearray_dynamic_uninit_local size in + (* 2. For uninitialized arrays, element values are unspecified *) + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + let _ = el in () + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 607; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 607 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 608; + let test = raises in + if not test then failwithf "test 608 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i (#{ a = #0L; b = #0. } : ur1) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 609; + let test = raises in + if not test then failwithf "test 609 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 610; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 610 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 611; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 611 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 (#{ a = #0L; b = #0. } : ur1) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 612; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 612 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 (#{ a = #0L; b = #0. } : ur1) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 613; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 613 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (***********) + (* ur3 *) + (***********) + let eq = (fun (#{ a = a1 } : ur3) (#{ a = a2 } : ur3) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 a2) in + let mk_value i = (#{ a = Int64_u.of_int i } : ur3) in + (* 1. Create an array of size [size] *) + let a : ur3 array = makearray_dynamic_uninit_local size in + (* 2. For uninitialized arrays, element values are unspecified *) + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + let _ = el in () + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 614; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 614 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 615; + let test = raises in + if not test then failwithf "test 615 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i (#{ a = #0L } : ur3) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 616; + let test = raises in + if not test then failwithf "test 616 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 617; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 617 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 618; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 618 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 (#{ a = #0L } : ur3) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 619; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 619 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 (#{ a = #0L } : ur3) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 620; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 620 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (***********) + (* ur4 *) + (***********) + let eq = (fun (#{ a = a1; b = b1 } : ur4) (#{ a = a2; b = b2 } : ur4) -> (fun (#{ a = a1; b = b1 } : ur1) (#{ a = a2; b = b2 } : ur1) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 a2 && (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) b1 b2) a1 a2 && (fun (#{ a = a1 } : ur3) (#{ a = a2 } : ur3) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 a2) b1 b2) in + let mk_value i = (#{ a = (#{ a = Int64_u.of_int i; b = Float_u.of_int i } : ur1); b = (#{ a = Int64_u.of_int i } : ur3) } : ur4) in + (* 1. Create an array of size [size] *) + let a : ur4 array = makearray_dynamic_uninit_local size in + (* 2. For uninitialized arrays, element values are unspecified *) + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + let _ = el in () + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 621; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 621 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 622; + let test = raises in + if not test then failwithf "test 622 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i (#{ a = (#{ a = #0L; b = #0. } : ur1); b = (#{ a = #0L } : ur3) } : ur4) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 623; + let test = raises in + if not test then failwithf "test 623 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 624; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 624 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 625; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 625 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 (#{ a = (#{ a = #0L; b = #0. } : ur1); b = (#{ a = #0L } : ur3) } : ur4) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 626; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 626 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 (#{ a = (#{ a = #0L; b = #0. } : ur1); b = (#{ a = #0L } : ur3) } : ur4) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 627; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 627 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (***********************************) + (* #(float# * int32# * int64#) *) + (***********************************) + let eq = (fun #(a0, a1, a2) #(b0, b1, b2) -> (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) a0 b0 && (fun a b -> Int32_u.(equal (add #0l a) (add #0l b))) a1 b1 && (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a2 b2) in + let mk_value i = #(Float_u.of_int i, Int32_u.of_int i, Int64_u.of_int i) in + (* 1. Create an array of size [size] *) + let a : #(float# * int32# * int64#) array = makearray_dynamic_uninit_local size in + (* 2. For uninitialized arrays, element values are unspecified *) + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + let _ = el in () + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 628; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 628 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 629; + let test = raises in + if not test then failwithf "test 629 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #(#0., #0l, #0L) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 630; + let test = raises in + if not test then failwithf "test 630 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 631; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 631 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 632; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 632 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #(#0., #0l, #0L) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 633; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 633 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #(#0., #0l, #0L) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 634; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 634 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (*********************************************************************************************) + (* #(float# * #(int64# * int64#) * float32# * #(int32# * #(float32# * float#)) * int64#) *) + (*********************************************************************************************) + let eq = (fun #(a0, a1, a2, a3, a4) #(b0, b1, b2, b3, b4) -> (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) a0 b0 && (fun #(a0, a1) #(b0, b1) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a0 b0 && (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 b1) a1 b1 && (fun a b -> Float32_u.(equal (add #0.s a) (add #0.s b))) a2 b2 && (fun #(a0, a1) #(b0, b1) -> (fun a b -> Int32_u.(equal (add #0l a) (add #0l b))) a0 b0 && (fun #(a0, a1) #(b0, b1) -> (fun a b -> Float32_u.(equal (add #0.s a) (add #0.s b))) a0 b0 && (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) a1 b1) a1 b1) a3 b3 && (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a4 b4) in + let mk_value i = #(Float_u.of_int i, #(Int64_u.of_int i, Int64_u.of_int i), Float32_u.of_int i, #(Int32_u.of_int i, #(Float32_u.of_int i, Float_u.of_int i)), Int64_u.of_int i) in + (* 1. Create an array of size [size] *) + let a : #(float# * #(int64# * int64#) * float32# * #(int32# * #(float32# * float#)) * int64#) array = makearray_dynamic_uninit_local size in + (* 2. For uninitialized arrays, element values are unspecified *) + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + let _ = el in () + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 635; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 635 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 636; + let test = raises in + if not test then failwithf "test 636 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #(#0., #(#0L, #0L), #0.s, #(#0l, #(#0.s, #0.)), #0L) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 637; + let test = raises in + if not test then failwithf "test 637 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 638; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 638 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 639; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 639 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #(#0., #(#0L, #0L), #0.s, #(#0l, #(#0.s, #0.)), #0L) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 640; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 640 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #(#0., #(#0L, #0L), #0.s, #(#0l, #(#0.s, #0.)), #0L) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 641; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 641 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + (***********************) + (* #(int64# * ur1) *) + (***********************) + let eq = (fun #(a0, a1) #(b0, b1) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a0 b0 && (fun (#{ a = a1; b = b1 } : ur1) (#{ a = a2; b = b2 } : ur1) -> (fun a b -> Int64_u.(equal (add #0L a) (add #0L b))) a1 a2 && (fun a b -> Float_u.(equal (add #0. a) (add #0. b))) b1 b2) a1 b1) in + let mk_value i = #(Int64_u.of_int i, (#{ a = Int64_u.of_int i; b = Float_u.of_int i } : ur1)) in + (* 1. Create an array of size [size] *) + let a : #(int64# * ur1) array = makearray_dynamic_uninit_local size in + (* 2. For uninitialized arrays, element values are unspecified *) + (* 2. For initialized arrays, check all elements have the correct value *) + for i = 0 to size - 1 do + let el = get a i in + let _ = el in () + done; + (* 3. Fill [a] with distinct values and read back those values *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + Gc.compact (); + for i = 0 to size - 1 do + mark_test_run 642; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 642 failed %d %d" size i; + done; + iter (bad_indices size) ~f:(fun i -> + (* 4. Getting bad indices errors *) + let raises = + match get a i with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 643; + let test = raises in + if not test then failwithf "test 643 failed %d %d" size i; + (* 5. Setting bad indices errors *) + let raises = + match set a i #(#0L, (#{ a = #0L; b = #0. } : ur1)) with + | exception Invalid_argument _ -> true + | _ -> false + in + mark_test_run 644; + let test = raises in + if not test then failwithf "test 644 failed %d %d" size i; + ) [@nontail]; + Gc.compact (); + (* 6. Array contents were unaffacted by setting bad indices *) + for i = 0 to size - 1 do + mark_test_run 645; + let test = eq (get a i) (mk_value i) in + if not test then failwithf "test 645 failed %d %d" size i; + done; + (* 7. Overlapping blits *) + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2:size) ~f:(fun len -> + unsafe_blit a ofs1 a ofs2 len; + for i = 0 to size - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else i + in + mark_test_run 646; + let test = eq (get a i) (mk_value expected_src_i) in + if not test then failwithf "test 646 failed %d %d %d %d %d" size ofs1 ofs2 len i; + done; + (* Reset array *) + for i = 0 to size - 1 do + set a i (mk_value i); + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 8. Blits to heap arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let a2 = makearray_dynamic size2 #(#0L, (#{ a = #0L; b = #0. } : ur1)) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 647; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 647 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + (* 9. Blits to local arrays *) + iter (sizes) ~f:(fun size2 -> + iter (blit_offsets size) ~f:(fun ofs1 -> + iter (blit_offsets size2) ~f:(fun ofs2 -> + iter (blit_lens ~ofs1 ~ofs2 ~size1:size ~size2) ~f:(fun len -> + let local_ a2 = makearray_dynamic_local size2 #(#0L, (#{ a = #0L; b = #0. } : ur1)) in + unsafe_blit a ofs1 a2 ofs2 len; + for i = 0 to size2 - 1 do + let expected_src_i = + if i >= ofs2 && i < ofs2 + len then i - ofs2 + ofs1 else 0 + in + mark_test_run 648; + let test = eq (get a2 i) (mk_value expected_src_i) in + if not test then failwithf "test 648 failed %d %d %d %d %d %d" size size2 ofs1 ofs2 len i; + done; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + ) [@nontail]; + Gc.compact (); + + () + +(* Main tests *) +let () = + print_endline "test_makearray_dynamic"; + iter sizes ~f:test_makearray_dynamic; + print_endline "test_makearray_dynamic_local"; + iter sizes ~f:test_makearray_dynamic_local; + print_endline "test_makearray_dynamic_uninit"; + iter sizes ~f:test_makearray_dynamic_uninit; + print_endline "test_makearray_dynamic_uninit_local"; + iter sizes ~f:test_makearray_dynamic_uninit_local; + () +;; + +for i = 1 to 648 do + if not (List.mem ~set:!tests_run i) then failwithf "test %d not run" i +done;; +let () = Printf.printf "All tests passed.%!\n";; diff --git a/testsuite/tests/typing-layouts-arrays/generated_test.reference b/testsuite/tests/typing-layouts-arrays/generated_test.reference new file mode 100644 index 00000000000..c2075fa9659 --- /dev/null +++ b/testsuite/tests/typing-layouts-arrays/generated_test.reference @@ -0,0 +1,5 @@ +test_makearray_dynamic +test_makearray_dynamic_local +test_makearray_dynamic_uninit +test_makearray_dynamic_uninit_local +All tests passed. diff --git a/testsuite/tests/typing-layouts-arrays/run_makearray_dynamic_tests.ml b/testsuite/tests/typing-layouts-arrays/run_makearray_dynamic_tests.ml new file mode 100644 index 00000000000..3dd358ae67c --- /dev/null +++ b/testsuite/tests/typing-layouts-arrays/run_makearray_dynamic_tests.ml @@ -0,0 +1,24 @@ +(* TEST + readonly_files = "generate_makearray_dynamic_tests.ml"; + (* Generate the bytecode/native code versions of + [generate_makearray_dynamic_tests.ml]. This doesn't actually run the test; + it just updates the generated test program (which is separately + run by the test harness). + *) + + { + setup-ocamlopt.opt-build-env; + stack-allocation; + program = "${test_source_directory}/generate.out"; + all_modules = "generate_makearray_dynamic_tests.ml"; + include stdlib_stable; + include stdlib_upstream_compatible; + ocamlopt.opt; + arguments = "native"; + output = "${test_source_directory}/generated_test.ml.corrected"; + run; + output = "${test_source_directory}/generated_test.ml.corrected"; + reference = "${test_source_directory}/generated_test.ml"; + check-program-output; + } +*) diff --git a/testsuite/tests/typing-layouts-arrays/test_float_u_array.ml b/testsuite/tests/typing-layouts-arrays/test_float_u_array.ml new file mode 100644 index 00000000000..81dd9df04e0 --- /dev/null +++ b/testsuite/tests/typing-layouts-arrays/test_float_u_array.ml @@ -0,0 +1,93 @@ +(* TEST + include stdlib_stable; + include stdlib_upstream_compatible; + readonly_files = + "gen_u_array.ml test_gen_u_array.ml gen_product_array_helpers.ml"; + modules = "${readonly_files}"; + flambda2; + arch_amd64; + { + flags = "-extension layouts_beta"; + bytecode; + } + { + flags = "-extension layouts_beta"; + native; + } +*) + +(* CR mshinwell: enable for arm64 once float32 is available *) + +open Gen_product_array_helpers +open Stdlib_stable +open Stdlib_upstream_compatible + +(* If copying this test for a new shape, you should only have to + change the bit between here and the next comment. See README.md in this + test directory. *) +type boxed_t = float +type unboxed_t = float# + +let elem : boxed_t elem = float_elem +let words_wide : int = 1 +let zero () : unboxed_t = #0. + +let to_boxed a = Float_u.to_float a +let of_boxed a = Float_u.of_float a + +(* Below here is copy pasted due to the absence of layout polymorphism. Don't + change it. See README.md in this test directory. *) +module Element_ops = (val Gen_product_array_helpers.make_element_ops elem) + +module Float_u_array0 : + Gen_u_array.S0 with type element_t = unboxed_t + and type ('a : any) array_t = 'a array = struct + type element_t = unboxed_t + + type ('a : any) array_t = 'a array + + type element_arg = unit -> element_t + type t = element_t array + let max_length = Sys.max_array_length + external length : element_t array -> int = "%array_length" + external get: element_t array -> int -> element_t = "%array_safe_get" + let get t i = let a = get t i in fun () -> a + external set: element_t array -> int -> element_t -> unit = "%array_safe_set" + let set t i e = set t i (e ()) + external unsafe_get: element_t array -> int -> element_t = "%array_unsafe_get" + let unsafe_get t i = let a = unsafe_get t i in fun () -> a + external unsafe_set: element_t array -> int -> element_t -> unit = + "%array_unsafe_set" + let unsafe_set t i e = unsafe_set t i (e ()) + + external makearray_dynamic : int -> element_t -> element_t array = + "%makearray_dynamic" + + let unsafe_create : int -> element_t array = + (* We don't actually have an uninitialized creation function for these, yet, + so we just use [makearray_dynamic] (which is what we want to test anyway) + with the zero element. *) + fun i -> makearray_dynamic i (zero ()) + + external unsafe_blit : + element_t array -> int -> element_t array -> int -> int -> unit = + "%arrayblit" + + let empty () : unboxed_t array = [||] + let to_boxed = to_boxed + + let compare_element x y = + Element_ops.compare (to_boxed (x ())) (to_boxed (y ())) +end + +module Float_u_array = Gen_u_array.Make (Float_u_array0) + +module Float_u_array_boxed = Test_gen_u_array.Make_boxed (struct + module M = Float_u_array + module I = Element_ops + module E = struct + let to_boxed x = to_boxed (x ()) + let of_boxed x () = of_boxed x + end + end) +module _ = Test_gen_u_array.Test (Float_u_array_boxed) diff --git a/testsuite/tests/typing-layouts-arrays/test_ignorable_product_array_1.ml b/testsuite/tests/typing-layouts-arrays/test_ignorable_product_array_1.ml new file mode 100644 index 00000000000..05b59f4ee0b --- /dev/null +++ b/testsuite/tests/typing-layouts-arrays/test_ignorable_product_array_1.ml @@ -0,0 +1,93 @@ +(* TEST + include stdlib_stable; + include stdlib_upstream_compatible; + readonly_files = + "gen_u_array.ml test_gen_u_array.ml gen_product_array_helpers.ml"; + modules = "${readonly_files}"; + flambda2; + arch_amd64; + { + flags = "-extension layouts_beta"; + bytecode; + } + { + flags = "-extension layouts_beta"; + native; + } +*) + +(* CR mshinwell: enable for arm64 once float32 is available *) + +open Gen_product_array_helpers +open Stdlib_stable +open Stdlib_upstream_compatible + +(* If copying this test for a new product shape, you should only have to + change the bit between here and the next comment. See README.md in this + test directory. *) +type boxed_t = float * int * int64 +type unboxed_t = #(float# * int * int64#) + +let elem : boxed_t elem = Tup3 (float_elem, int_elem, int64_elem) +let words_wide : int = 3 +let zero () : unboxed_t = #(#0., 0, #0L) + +let to_boxed #(a, b, c) = (Float_u.to_float a, b, Int64_u.to_int64 c) +let of_boxed (a, b, c) = #(Float_u.of_float a, b, Int64_u.of_int64 c) + +(* Below here is copy pasted due to the absence of layout polymorphism. Don't + change it. See README.md in this test directory. *) +module Element_ops = (val Gen_product_array_helpers.make_element_ops elem) + +module UTuple_array0 : + Gen_u_array.S0 with type element_t = unboxed_t + and type ('a : any) array_t = 'a array = struct + type element_t = unboxed_t + + type ('a : any) array_t = 'a array + + type element_arg = unit -> element_t + type t = element_t array + let max_length = Sys.max_array_length + external length : element_t array -> int = "%array_length" + external get: element_t array -> int -> element_t = "%array_safe_get" + let get t i = let a = get t i in fun () -> a + external set: element_t array -> int -> element_t -> unit = "%array_safe_set" + let set t i e = set t i (e ()) + external unsafe_get: element_t array -> int -> element_t = "%array_unsafe_get" + let unsafe_get t i = let a = unsafe_get t i in fun () -> a + external unsafe_set: element_t array -> int -> element_t -> unit = + "%array_unsafe_set" + let unsafe_set t i e = unsafe_set t i (e ()) + + external makearray_dynamic : int -> element_t -> element_t array = + "%makearray_dynamic" + + let unsafe_create : int -> element_t array = + (* We don't actually have an uninitialized creation function for these, yet, + so we just use [makearray_dynamic] (which is what we want to test anyway) + with the zero element. *) + fun i -> makearray_dynamic i (zero ()) + + external unsafe_blit : + element_t array -> int -> element_t array -> int -> int -> unit = + "%arrayblit" + + let empty () : unboxed_t array = [||] + let to_boxed = to_boxed + + let compare_element x y = + Element_ops.compare (to_boxed (x ())) (to_boxed (y ())) +end + +module UTuple_array = Gen_u_array.Make (UTuple_array0) + +module UTuple_array_boxed = Test_gen_u_array.Make_boxed (struct + module M = UTuple_array + module I = Element_ops + module E = struct + let to_boxed x = to_boxed (x ()) + let of_boxed x () = of_boxed x + end + end) +module _ = Test_gen_u_array.Test (UTuple_array_boxed) diff --git a/testsuite/tests/typing-layouts-arrays/test_ignorable_product_array_2.ml b/testsuite/tests/typing-layouts-arrays/test_ignorable_product_array_2.ml new file mode 100644 index 00000000000..0816841ebd4 --- /dev/null +++ b/testsuite/tests/typing-layouts-arrays/test_ignorable_product_array_2.ml @@ -0,0 +1,120 @@ +(* TEST + include stdlib_stable; + include stdlib_upstream_compatible; + readonly_files = + "gen_u_array.ml test_gen_u_array.ml gen_product_array_helpers.ml"; + modules = "${readonly_files}"; + flambda2; + arch_amd64; + runtime5; + { + flags = "-extension layouts_beta"; + bytecode; + } + { + flags = "-extension layouts_beta"; + native; + } +*) + +(* This test exhibited intermittent failures with very low probability on + runtime4, and extensive investigation has not found the cause. It is + suspected it might be a problem in the runtime4 GC. So we have restricted + the test to runtime5 at least for now. *) + +(* CR mshinwell: enable for arm64 once float32 is available *) + +open Gen_product_array_helpers +open Stdlib_stable +open Stdlib_upstream_compatible + +(* If copying this test for a new product shape, you should only have to + change the bit between here and the next comment. See README.md in this + test directory. *) +type boxed_t = + float * (int * int64) * float32 * (int32 * (float32 * float)) * int +type unboxed_t = + #(float# * #(int * int64#) * float32# * #(int32# * #(float32# * float#)) + * int) + +let elem : boxed_t elem = + Tup5 (float_elem, + Tup2 (int_elem, int64_elem), + float32_elem, + Tup2 (int32_elem, (Tup2 (float32_elem, float_elem))), + int_elem) + +let words_wide : int = 8 +let zero () : unboxed_t = + #(#0., #(0, #0L), #0.s, #(#0l, #(#0.s, #0.)), 0) + +let to_boxed #(a, #(b, c), d, #(e, #(f, g)), h) = + (Float_u.to_float a, + (b, Int64_u.to_int64 c), + Float32_u.to_float32 d, + (Int32_u.to_int32 e, (Float32_u.to_float32 f, Float_u.to_float g)), + h) + +let of_boxed (a, (b, c), d, (e, (f, g)), h) = + #(Float_u.of_float a, + #(b, Int64_u.of_int64 c), + Float32_u.of_float32 d, + #(Int32_u.of_int32 e, #(Float32_u.of_float32 f, Float_u.of_float g)), + h) + +(* Below here is copy pasted due to the absence of layout polymorphism. Don't + change it. See README.md in this test directory. *) +module Element_ops = (val Gen_product_array_helpers.make_element_ops elem) + +module UTuple_array0 : + Gen_u_array.S0 with type element_t = unboxed_t + and type ('a : any) array_t = 'a array = struct + type element_t = unboxed_t + + type ('a : any) array_t = 'a array + + type element_arg = unit -> element_t + type t = element_t array + let max_length = Sys.max_array_length + external length : element_t array -> int = "%array_length" + external get: element_t array -> int -> element_t = "%array_safe_get" + let get t i = let a = get t i in fun () -> a + external set: element_t array -> int -> element_t -> unit = "%array_safe_set" + let set t i e = set t i (e ()) + external unsafe_get: element_t array -> int -> element_t = "%array_unsafe_get" + let unsafe_get t i = let a = unsafe_get t i in fun () -> a + external unsafe_set: element_t array -> int -> element_t -> unit = + "%array_unsafe_set" + let unsafe_set t i e = unsafe_set t i (e ()) + + external makearray_dynamic : int -> element_t -> element_t array = + "%makearray_dynamic" + + let unsafe_create : int -> element_t array = + (* We don't actually have an uninitialized creation function for these, yet, + so we just use [makearray_dynamic] (which is what we want to test anyway) + with the zero element. *) + fun i -> makearray_dynamic i (zero ()) + + external unsafe_blit : + element_t array -> int -> element_t array -> int -> int -> unit = + "%arrayblit" + + let empty () : unboxed_t array = [||] + let to_boxed = to_boxed + + let compare_element x y = + Element_ops.compare (to_boxed (x ())) (to_boxed (y ())) +end + +module UTuple_array = Gen_u_array.Make (UTuple_array0) + +module UTuple_array_boxed = Test_gen_u_array.Make_boxed (struct + module M = UTuple_array + module I = Element_ops + module E = struct + let to_boxed x = to_boxed (x ()) + let of_boxed x () = of_boxed x + end + end) +module _ = Test_gen_u_array.Test (UTuple_array_boxed) diff --git a/testsuite/tests/typing-layouts-arrays/test_ignorable_product_array_with_uninit_1.ml b/testsuite/tests/typing-layouts-arrays/test_ignorable_product_array_with_uninit_1.ml new file mode 100644 index 00000000000..4dc10e586f7 --- /dev/null +++ b/testsuite/tests/typing-layouts-arrays/test_ignorable_product_array_with_uninit_1.ml @@ -0,0 +1,90 @@ +(* TEST + include stdlib_stable; + include stdlib_upstream_compatible; + readonly_files = + "gen_u_array.ml test_gen_u_array.ml gen_product_array_helpers.ml"; + modules = "${readonly_files}"; + flambda2; + arch_amd64; + { + flags = "-extension layouts_beta"; + bytecode; + } + { + flags = "-extension layouts_beta"; + native; + } +*) + +(* CR mshinwell: enable for arm64 once float32 is available *) + +open Gen_product_array_helpers +open Stdlib_stable +open Stdlib_upstream_compatible + +(* If copying this test for a new product shape, you should only have to + change the bit between here and the next comment. See README.md in this + test directory. *) +type boxed_t = float * int32 * int64 +type unboxed_t = #(float# * int32# * int64#) + +let elem : boxed_t elem = Tup3 (float_elem, int32_elem, int64_elem) +let words_wide : int = 3 +let zero () : unboxed_t = #(#0., #0l, #0L) + +let to_boxed #(a, b, c) = (Float_u.to_float a, Int32_u.to_int32 b, Int64_u.to_int64 c) +let of_boxed (a, b, c) = #(Float_u.of_float a, Int32_u.of_int32 b, Int64_u.of_int64 c) + +(* Below here is copy pasted due to the absence of layout polymorphism. Don't + change it. See README.md in this test directory. *) +module Element_ops = (val Gen_product_array_helpers.make_element_ops elem) + +module UTuple_array0 : + Gen_u_array.S0 with type element_t = unboxed_t + and type ('a : any) array_t = 'a array = struct + type element_t = unboxed_t + + type ('a : any) array_t = 'a array + + type element_arg = unit -> element_t + type t = element_t array + let max_length = Sys.max_array_length + external length : element_t array -> int = "%array_length" + external get: element_t array -> int -> element_t = "%array_safe_get" + let get t i = let a = get t i in fun () -> a + external set: element_t array -> int -> element_t -> unit = "%array_safe_set" + let set t i e = set t i (e ()) + external unsafe_get: element_t array -> int -> element_t = "%array_unsafe_get" + let unsafe_get t i = let a = unsafe_get t i in fun () -> a + external unsafe_set: element_t array -> int -> element_t -> unit = + "%array_unsafe_set" + let unsafe_set t i e = unsafe_set t i (e ()) + + external makearray_dynamic_uninit : int -> element_t array = + "%makearray_dynamic_uninit" + + let unsafe_create : int -> element_t array = + fun i -> makearray_dynamic_uninit i + + external unsafe_blit : + element_t array -> int -> element_t array -> int -> int -> unit = + "%arrayblit" + + let empty () : unboxed_t array = [||] + let to_boxed = to_boxed + + let compare_element x y = + Element_ops.compare (to_boxed (x ())) (to_boxed (y ())) +end + +module UTuple_array = Gen_u_array.Make (UTuple_array0) + +module UTuple_array_boxed = Test_gen_u_array.Make_boxed (struct + module M = UTuple_array + module I = Element_ops + module E = struct + let to_boxed x = to_boxed (x ()) + let of_boxed x () = of_boxed x + end + end) +module _ = Test_gen_u_array.Test (UTuple_array_boxed) diff --git a/testsuite/tests/typing-layouts-arrays/test_ignorable_product_array_with_uninit_2.ml b/testsuite/tests/typing-layouts-arrays/test_ignorable_product_array_with_uninit_2.ml new file mode 100644 index 00000000000..542311e673d --- /dev/null +++ b/testsuite/tests/typing-layouts-arrays/test_ignorable_product_array_with_uninit_2.ml @@ -0,0 +1,117 @@ +(* TEST + include stdlib_stable; + include stdlib_upstream_compatible; + readonly_files = + "gen_u_array.ml test_gen_u_array.ml gen_product_array_helpers.ml"; + modules = "${readonly_files}"; + flambda2; + arch_amd64; + runtime5; + { + flags = "-extension layouts_beta"; + bytecode; + } + { + flags = "-extension layouts_beta"; + native; + } +*) + +(* This test exhibited intermittent failures with very low probability on + runtime4, and extensive investigation has not found the cause. It is + suspected it might be a problem in the runtime4 GC. So we have restricted + the test to runtime5 at least for now. *) + +(* CR mshinwell: enable for arm64 once float32 is available *) + +open Gen_product_array_helpers +open Stdlib_stable +open Stdlib_upstream_compatible + +(* If copying this test for a new product shape, you should only have to + change the bit between here and the next comment. See README.md in this + test directory. *) +type boxed_t = + float * (int64 * int64) * float32 * (int32 * (float32 * float)) * int64 +type unboxed_t = + #(float# * #(int64# * int64#) * float32# * #(int32# * #(float32# * float#)) + * int64#) + +let elem : boxed_t elem = + Tup5 (float_elem, + Tup2 (int64_elem, int64_elem), + float32_elem, + Tup2 (int32_elem, (Tup2 (float32_elem, float_elem))), + int64_elem) + +let words_wide : int = 8 +let zero () : unboxed_t = + #(#0., #(#0L, #0L), #0.s, #(#0l, #(#0.s, #0.)), #0L) + +let to_boxed #(a, #(b, c), d, #(e, #(f, g)), h) = + (Float_u.to_float a, + (Int64_u.to_int64 b, Int64_u.to_int64 c), + Float32_u.to_float32 d, + (Int32_u.to_int32 e, (Float32_u.to_float32 f, Float_u.to_float g)), + Int64_u.to_int64 h) + +let of_boxed (a, (b, c), d, (e, (f, g)), h) = + #(Float_u.of_float a, + #(Int64_u.of_int64 b, Int64_u.of_int64 c), + Float32_u.of_float32 d, + #(Int32_u.of_int32 e, #(Float32_u.of_float32 f, Float_u.of_float g)), + Int64_u.of_int64 h) + +(* Below here is copy pasted due to the absence of layout polymorphism. Don't + change it. See README.md in this test directory. *) +module Element_ops = (val Gen_product_array_helpers.make_element_ops elem) + +module UTuple_array0 : + Gen_u_array.S0 with type element_t = unboxed_t + and type ('a : any) array_t = 'a array = struct + type element_t = unboxed_t + + type ('a : any) array_t = 'a array + + type element_arg = unit -> element_t + type t = element_t array + let max_length = Sys.max_array_length + external length : element_t array -> int = "%array_length" + external get: element_t array -> int -> element_t = "%array_safe_get" + let get t i = let a = get t i in fun () -> a + external set: element_t array -> int -> element_t -> unit = "%array_safe_set" + let set t i e = set t i (e ()) + external unsafe_get: element_t array -> int -> element_t = "%array_unsafe_get" + let unsafe_get t i = let a = unsafe_get t i in fun () -> a + external unsafe_set: element_t array -> int -> element_t -> unit = + "%array_unsafe_set" + let unsafe_set t i e = unsafe_set t i (e ()) + + external makearray_dynamic_uninit : int -> element_t array = + "%makearray_dynamic_uninit" + + let unsafe_create : int -> element_t array = + fun i -> makearray_dynamic_uninit i + + external unsafe_blit : + element_t array -> int -> element_t array -> int -> int -> unit = + "%arrayblit" + + let empty () : unboxed_t array = [||] + let to_boxed = to_boxed + + let compare_element x y = + Element_ops.compare (to_boxed (x ())) (to_boxed (y ())) +end + +module UTuple_array = Gen_u_array.Make (UTuple_array0) + +module UTuple_array_boxed = Test_gen_u_array.Make_boxed (struct + module M = UTuple_array + module I = Element_ops + module E = struct + let to_boxed x = to_boxed (x ()) + let of_boxed x () = of_boxed x + end + end) +module _ = Test_gen_u_array.Test (UTuple_array_boxed) diff --git a/testsuite/tests/typing-layouts-arrays/test_scannable_product_array_1.ml b/testsuite/tests/typing-layouts-arrays/test_scannable_product_array_1.ml new file mode 100644 index 00000000000..33daf2c9485 --- /dev/null +++ b/testsuite/tests/typing-layouts-arrays/test_scannable_product_array_1.ml @@ -0,0 +1,94 @@ +(* TEST + include stdlib_stable; + include stdlib_upstream_compatible; + readonly_files = + "gen_u_array.ml test_gen_u_array.ml gen_product_array_helpers.ml"; + modules = "${readonly_files}"; + flambda2; + stack-allocation; + arch_amd64; + { + flags = "-extension layouts_beta"; + bytecode; + } + { + flags = "-extension layouts_beta"; + native; + } +*) + +(* CR mshinwell: enable for arm64 once float32 is available *) + +open Gen_product_array_helpers +open Stdlib_stable +open Stdlib_upstream_compatible + +(* If copying this test for a new product shape, you should only have to + change the bit between here and the next comment. See README.md in this + test directory. *) +type boxed_t = int * int64 +type unboxed_t = #(int * int64) + +let elem : boxed_t elem = Tup2 (int_elem, int64_elem) +let words_wide : int = 2 +let zero () : unboxed_t = #(0, 0L) + +let to_boxed #(i, i64) = (i, i64) +let of_boxed (i, i64) = #(i, i64) + +(* Below here is copy pasted due to the absence of layout polymorphism. Don't + change it. See README.md in this test directory. *) +module Element_ops = (val Gen_product_array_helpers.make_element_ops elem) + +module UTuple_array0 : + Gen_u_array.S0 with type element_t = unboxed_t + and type ('a : any) array_t = 'a array = struct + type element_t = unboxed_t + + type ('a : any) array_t = 'a array + + type element_arg = unit -> element_t + type t = element_t array + let max_length = Sys.max_array_length + external length : element_t array -> int = "%array_length" + external get: element_t array -> int -> element_t = "%array_safe_get" + let get t i = let a = get t i in fun () -> a + external set: element_t array -> int -> element_t -> unit = "%array_safe_set" + let set t i e = set t i (e ()) + external unsafe_get: element_t array -> int -> element_t = "%array_unsafe_get" + let unsafe_get t i = let a = unsafe_get t i in fun () -> a + external unsafe_set: element_t array -> int -> element_t -> unit = + "%array_unsafe_set" + let unsafe_set t i e = unsafe_set t i (e ()) + + external makearray_dynamic : int -> element_t -> element_t array = + "%makearray_dynamic" + + let unsafe_create : int -> element_t array = + (* We don't actually have an uninitialized creation function for these, yet, + so we just use [makearray_dynamic] (which is what we want to test anyway) + with the zero element. *) + fun i -> makearray_dynamic i (zero ()) + + external unsafe_blit : + element_t array -> int -> element_t array -> int -> int -> unit = + "%arrayblit" + + let empty () : unboxed_t array = [||] + let to_boxed = to_boxed + + let compare_element x y = + Element_ops.compare (to_boxed (x ())) (to_boxed (y ())) +end + +module UTuple_array = Gen_u_array.Make (UTuple_array0) + +module UTuple_array_boxed = Test_gen_u_array.Make_boxed (struct + module M = UTuple_array + module I = Element_ops + module E = struct + let to_boxed x = to_boxed (x ()) + let of_boxed x () = of_boxed x + end + end) +module _ = Test_gen_u_array.Test (UTuple_array_boxed) diff --git a/testsuite/tests/typing-layouts-arrays/test_scannable_product_array_2.ml b/testsuite/tests/typing-layouts-arrays/test_scannable_product_array_2.ml new file mode 100644 index 00000000000..1d64378a6ba --- /dev/null +++ b/testsuite/tests/typing-layouts-arrays/test_scannable_product_array_2.ml @@ -0,0 +1,116 @@ +(* TEST + include stdlib_stable; + include stdlib_upstream_compatible; + readonly_files = + "gen_u_array.ml test_gen_u_array.ml gen_product_array_helpers.ml"; + modules = "${readonly_files}"; + flambda2; + stack-allocation; + arch_amd64; + { + flags = "-extension layouts_beta"; + bytecode; + } + { + flags = "-extension layouts_beta"; + native; + } +*) + +(* CR mshinwell: enable for arm64 once float32 is available *) + +open Gen_product_array_helpers +open Stdlib_stable +open Stdlib_upstream_compatible + +(* If copying this test for a new product shape, you should only have to + change the bit between here and the next comment. See README.md in this + test directory. *) +type boxed_t = + int64 option + * (int * int32 * float) + * float + * (float32 * (nativeint * nativeint) option) + * int32 + +type unboxed_t = + #(int64 option + * #(int * int32 * float) + * float + * #(float32 * (nativeint * nativeint) option) + * int32) + +let elem : boxed_t elem = + Tup5 (Option int64_elem, + Tup3 (int_elem, int32_elem, float_elem), + float_elem, + Tup2 (float32_elem, Option (Tup2 (nativeint_elem, nativeint_elem))), + int32_elem) + +let words_wide : int = 8 +let zero () : unboxed_t = + #(Some 0L, + #(0, 0l, 0.), + 0., + #(0.s, Some (0n, 0n)), + 0l) + +let to_boxed #(a, #(b, c, d), e, #(f, g), h) = (a, (b, c, d), e, (f, g), h) +let of_boxed (a, (b, c, d), e, (f, g), h) = #(a, #(b, c, d), e, #(f, g), h) + +(* Below here is copy pasted due to the absence of layout polymorphism. Don't + change it. See README.md in this test directory. *) +module Element_ops = (val Gen_product_array_helpers.make_element_ops elem) + +module UTuple_array0 : + Gen_u_array.S0 with type element_t = unboxed_t + and type ('a : any) array_t = 'a array = struct + type element_t = unboxed_t + + type ('a : any) array_t = 'a array + + type element_arg = unit -> element_t + type t = element_t array + let max_length = Sys.max_array_length + external length : element_t array -> int = "%array_length" + external get: element_t array -> int -> element_t = "%array_safe_get" + let get t i = let a = get t i in fun () -> a + external set: element_t array -> int -> element_t -> unit = "%array_safe_set" + let set t i e = set t i (e ()) + external unsafe_get: element_t array -> int -> element_t = "%array_unsafe_get" + let unsafe_get t i = let a = unsafe_get t i in fun () -> a + external unsafe_set: element_t array -> int -> element_t -> unit = + "%array_unsafe_set" + let unsafe_set t i e = unsafe_set t i (e ()) + + external makearray_dynamic : int -> element_t -> element_t array = + "%makearray_dynamic" + + let unsafe_create : int -> element_t array = + (* We don't actually have an uninitialized creation function for these, yet, + so we just use [makearray_dynamic] (which is what we want to test anyway) + with the zero element. *) + fun i -> makearray_dynamic i (zero ()) + + external unsafe_blit : + element_t array -> int -> element_t array -> int -> int -> unit = + "%arrayblit" + + let empty () : unboxed_t array = [||] + let to_boxed = to_boxed + + let compare_element x y = + Element_ops.compare (to_boxed (x ())) (to_boxed (y ())) +end + +module UTuple_array = Gen_u_array.Make (UTuple_array0) + +module UTuple_array_boxed = Test_gen_u_array.Make_boxed (struct + module M = UTuple_array + module I = Element_ops + module E = struct + let to_boxed x = to_boxed (x ()) + let of_boxed x () = of_boxed x + end + end) +module _ = Test_gen_u_array.Test (UTuple_array_boxed) diff --git a/testsuite/tests/typing-layouts-arrays/test_scannable_product_array_3.ml b/testsuite/tests/typing-layouts-arrays/test_scannable_product_array_3.ml new file mode 100644 index 00000000000..b18e167c7aa --- /dev/null +++ b/testsuite/tests/typing-layouts-arrays/test_scannable_product_array_3.ml @@ -0,0 +1,96 @@ +(* TEST + include stdlib_stable; + include stdlib_upstream_compatible; + readonly_files = + "gen_u_array.ml test_gen_u_array.ml gen_product_array_helpers.ml"; + modules = "${readonly_files}"; + flambda2; + stack-allocation; + arch_amd64; + { + flags = "-extension layouts_beta"; + bytecode; + } + { + flags = "-extension layouts_beta"; + native; + } +*) + +(* CR mshinwell: enable for arm64 once float32 is available *) + +open Gen_product_array_helpers +open Stdlib_stable +open Stdlib_upstream_compatible + +(* If copying this test for a new product shape, you should only have to + change the bit between here and the next comment. See README.md in this + test directory. *) +type boxed_t = float * float * float + +type unboxed_t = #(float * float * float) + +let elem : boxed_t elem = Tup3 (float_elem, float_elem, float_elem) + +let words_wide : int = 3 +let zero () : unboxed_t = #(0., 0., 0.) + +let to_boxed #(a, b, c) = a, b, c +let of_boxed (a, b, c) = #(a, b, c) + +(* Below here is copy pasted due to the absence of layout polymorphism. Don't + change it. See README.md in this test directory. *) +module Element_ops = (val Gen_product_array_helpers.make_element_ops elem) + +module UTuple_array0 : + Gen_u_array.S0 with type element_t = unboxed_t + and type ('a : any) array_t = 'a array = struct + type element_t = unboxed_t + + type ('a : any) array_t = 'a array + + type element_arg = unit -> element_t + type t = element_t array + let max_length = Sys.max_array_length + external length : element_t array -> int = "%array_length" + external get: element_t array -> int -> element_t = "%array_safe_get" + let get t i = let a = get t i in fun () -> a + external set: element_t array -> int -> element_t -> unit = "%array_safe_set" + let set t i e = set t i (e ()) + external unsafe_get: element_t array -> int -> element_t = "%array_unsafe_get" + let unsafe_get t i = let a = unsafe_get t i in fun () -> a + external unsafe_set: element_t array -> int -> element_t -> unit = + "%array_unsafe_set" + let unsafe_set t i e = unsafe_set t i (e ()) + + external makearray_dynamic : int -> element_t -> element_t array = + "%makearray_dynamic" + + let unsafe_create : int -> element_t array = + (* We don't actually have an uninitialized creation function for these, yet, + so we just use [makearray_dynamic] (which is what we want to test anyway) + with the zero element. *) + fun i -> makearray_dynamic i (zero ()) + + external unsafe_blit : + element_t array -> int -> element_t array -> int -> int -> unit = + "%arrayblit" + + let empty () : unboxed_t array = [||] + let to_boxed = to_boxed + + let compare_element x y = + Element_ops.compare (to_boxed (x ())) (to_boxed (y ())) +end + +module UTuple_array = Gen_u_array.Make (UTuple_array0) + +module UTuple_array_boxed = Test_gen_u_array.Make_boxed (struct + module M = UTuple_array + module I = Element_ops + module E = struct + let to_boxed x = to_boxed (x ()) + let of_boxed x () = of_boxed x + end + end) +module _ = Test_gen_u_array.Test (UTuple_array_boxed) diff --git a/testsuite/tests/typing-layouts-arrays/test_scannable_product_array_4.ml b/testsuite/tests/typing-layouts-arrays/test_scannable_product_array_4.ml new file mode 100644 index 00000000000..19aa03f400a --- /dev/null +++ b/testsuite/tests/typing-layouts-arrays/test_scannable_product_array_4.ml @@ -0,0 +1,100 @@ +(* TEST + include stdlib_stable; + include stdlib_upstream_compatible; + readonly_files = + "gen_u_array.ml test_gen_u_array.ml gen_product_array_helpers.ml"; + modules = "${readonly_files}"; + flambda2; + stack-allocation; + arch_amd64; + { + flags = "-extension layouts_beta"; + bytecode; + } + { + flags = "-extension layouts_beta"; + native; + } +*) + +(* CR mshinwell: enable for arm64 once float32 is available *) + +open Gen_product_array_helpers +open Stdlib_stable +open Stdlib_upstream_compatible + +(* If copying this test for a new product shape, you should only have to + change the bit between here and the next comment. See README.md in this + test directory. *) +type boxed_t = float * (float * float) * (float * (float * float * float)) + +type unboxed_t = + #(float * #(float * float) * #(float * #(float * float * float))) + +let elem : boxed_t elem = + Tup3 (float_elem, + Tup2 (float_elem, float_elem), + Tup2 (float_elem, Tup3 (float_elem, float_elem, float_elem))) + +let words_wide : int = 7 +let zero () : unboxed_t = #(0., #(0., 0.), #(0., #(0., 0., 0.))) + +let to_boxed #(a, #(b, c), #(d, #(e, f, g))) = a, (b, c), (d, (e, f, g)) +let of_boxed (a, (b, c), (d, (e, f, g))) = #(a, #(b, c), #(d, #(e, g, f))) + +(* Below here is copy pasted due to the absence of layout polymorphism. Don't + change it. See README.md in this test directory. *) +module Element_ops = (val Gen_product_array_helpers.make_element_ops elem) + +module UTuple_array0 : + Gen_u_array.S0 with type element_t = unboxed_t + and type ('a : any) array_t = 'a array = struct + type element_t = unboxed_t + + type ('a : any) array_t = 'a array + + type element_arg = unit -> element_t + type t = element_t array + let max_length = Sys.max_array_length + external length : element_t array -> int = "%array_length" + external get: element_t array -> int -> element_t = "%array_safe_get" + let get t i = let a = get t i in fun () -> a + external set: element_t array -> int -> element_t -> unit = "%array_safe_set" + let set t i e = set t i (e ()) + external unsafe_get: element_t array -> int -> element_t = "%array_unsafe_get" + let unsafe_get t i = let a = unsafe_get t i in fun () -> a + external unsafe_set: element_t array -> int -> element_t -> unit = + "%array_unsafe_set" + let unsafe_set t i e = unsafe_set t i (e ()) + + external makearray_dynamic : int -> element_t -> element_t array = + "%makearray_dynamic" + + let unsafe_create : int -> element_t array = + (* We don't actually have an uninitialized creation function for these, yet, + so we just use [makearray_dynamic] (which is what we want to test anyway) + with the zero element. *) + fun i -> makearray_dynamic i (zero ()) + + external unsafe_blit : + element_t array -> int -> element_t array -> int -> int -> unit = + "%arrayblit" + + let empty () : unboxed_t array = [||] + let to_boxed = to_boxed + + let compare_element x y = + Element_ops.compare (to_boxed (x ())) (to_boxed (y ())) +end + +module UTuple_array = Gen_u_array.Make (UTuple_array0) + +module UTuple_array_boxed = Test_gen_u_array.Make_boxed (struct + module M = UTuple_array + module I = Element_ops + module E = struct + let to_boxed x = to_boxed (x ()) + let of_boxed x () = of_boxed x + end + end) +module _ = Test_gen_u_array.Test (UTuple_array_boxed) diff --git a/testsuite/tests/typing-layouts-products/basics.ml b/testsuite/tests/typing-layouts-products/basics.ml index 88df08c5294..4520f1bd9ba 100644 --- a/testsuite/tests/typing-layouts-products/basics.ml +++ b/testsuite/tests/typing-layouts-products/basics.ml @@ -1,9 +1,6 @@ (* TEST flambda2; include stdlib_upstream_compatible; - { - expect; - } { flags = "-extension layouts_beta"; expect; @@ -1519,13 +1516,7 @@ type t4 = #(string * #(float# * bool option)) array arrays to beta. *) let _ = [| #(1,2) |] [%%expect{| -Line 1, characters 8-20: -1 | let _ = [| #(1,2) |] - ^^^^^^^^^^^^ -Error: Non-value layout value & value detected as sort for type #(int * int), - but this requires extension layouts_alpha, which is not enabled. - If you intended to use this layout, please add this flag to your build file. - Otherwise, please report this error to the Jane Street compilers team. +- : #(int * int) array = [|#(1, 2)|] |}] let _ = Array.init 3 (fun _ -> #(1,2)) @@ -1569,13 +1560,7 @@ let f x : #(int * int) = array_get x 3 [%%expect{| external array_get : ('a : any_non_null). 'a array -> int -> 'a = "%array_safe_get" [@@layout_poly] -Line 3, characters 25-38: -3 | let f x : #(int * int) = array_get x 3 - ^^^^^^^^^^^^^ -Error: Non-value layout value & value detected as sort for type #(int * int), - but this requires extension layouts_alpha, which is not enabled. - If you intended to use this layout, please add this flag to your build file. - Otherwise, please report this error to the Jane Street compilers team. +val f : #(int * int) array -> #(int * int) = |}] external[@layout_poly] array_set : ('a : any_non_null) . 'a array -> int -> 'a -> unit = @@ -1584,17 +1569,10 @@ let f x = array_set x 3 #(1,2) [%%expect{| external array_set : ('a : any_non_null). 'a array -> int -> 'a -> unit = "%array_safe_set" [@@layout_poly] -Line 3, characters 10-30: -3 | let f x = array_set x 3 #(1,2) - ^^^^^^^^^^^^^^^^^^^^ -Error: Non-value layout value & value detected as sort for type #(int * int), - but this requires extension layouts_alpha, which is not enabled. - If you intended to use this layout, please add this flag to your build file. - Otherwise, please report this error to the Jane Street compilers team. +val f : #(int * int) array -> unit = |}] -(* You can write the type of an array of unboxed records, but not create - one. Soon, you can do both. *) +(* You can write the type of an array of unboxed records and create one. *) type ('a : value & value) t1 = 'a array type ('a : bits64 & (value & float64)) t2 = 'a array @@ -1618,15 +1596,10 @@ type array_record = #{ i1 : int; i2 : int } let _ = [| #{ i1 = 1; i2 = 2 } |] [%%expect{| type array_record = #{ i1 : int; i2 : int; } -Line 2, characters 8-33: -2 | let _ = [| #{ i1 = 1; i2 = 2 } |] - ^^^^^^^^^^^^^^^^^^^^^^^^^ -Error: Non-value layout value & value detected as sort for type array_record, - but this requires extension layouts_alpha, which is not enabled. - If you intended to use this layout, please add this flag to your build file. - Otherwise, please report this error to the Jane Street compilers team. +- : array_record array = [|#{i1 = 1; i2 = 2}|] |}] +(* However, such records can't be passed to [Array.init]. *) type array_init_record = #{ i1 : int; i2 : int } let _ = Array.init 3 (fun _ -> #{ i1 = 1; i2 = 2 }) [%%expect{| @@ -1641,7 +1614,7 @@ Error: This expression has type "array_init_record" But the layout of array_init_record must be a sublayout of value. |}] -(* Arrays of unboxed records of kind value *are* allowed *) +(* Arrays of unboxed records of kind value *are* allowed in all cases *) type array_record = #{ i : int } let _ = [| #{ i = 1 } |] [%%expect{| diff --git a/testsuite/tests/typing-layouts-products/product_arrays.ml b/testsuite/tests/typing-layouts-products/product_arrays.ml index 2aaeeeec00e..a8765e1c10b 100644 --- a/testsuite/tests/typing-layouts-products/product_arrays.ml +++ b/testsuite/tests/typing-layouts-products/product_arrays.ml @@ -1,7 +1,7 @@ (* TEST flambda2; include stdlib_upstream_compatible; - flags = "-extension layouts_alpha"; + flags = "-extension layouts_beta"; { expect; } @@ -13,7 +13,7 @@ (* CR layouts v7.1: The PR with middle-end support for product arrays can move this test to beta. *) -(* CR layouts v7.1: Everywhere this file says "any_non_null" it should instead +(* CR layouts v7.1: Everywhere this file says "any" it should instead say any. This is caused by [any] meaning different things alpha and beta - we can fix it when we move this test to beta. *) @@ -1864,10 +1864,8 @@ external blit_scannable : #(int * float * string) array -> int -> #(int * float * string) array -> int -> int -> unit = "%arrayblit" val blit_scannable_app : - ('a : value_or_null). - #(int * float * string) array -> - 'a -> #(int * float * string) array -> int -> int -> unit = - + #(int * float * string) array -> + 'a -> #(int * float * string) array -> int -> int -> unit = external blit_ignorable : #(float# * int * int64# * bool) array -> int -> #(float# * int * int64# * bool) array -> int -> int -> unit diff --git a/testsuite/tests/typing-layouts-products/product_iarrays.ml b/testsuite/tests/typing-layouts-products/product_iarrays.ml index 82773c9e516..261b8950263 100644 --- a/testsuite/tests/typing-layouts-products/product_iarrays.ml +++ b/testsuite/tests/typing-layouts-products/product_iarrays.ml @@ -1,7 +1,7 @@ (* TEST flambda2; include stdlib_upstream_compatible; - flags = "-extension layouts_alpha"; + flags = "-extension layouts_beta"; { expect; } diff --git a/testsuite/tests/typing-layouts/layout_poly.ml b/testsuite/tests/typing-layouts/layout_poly.ml index acbd1dd0d0c..8037325d149 100644 --- a/testsuite/tests/typing-layouts/layout_poly.ml +++ b/testsuite/tests/typing-layouts/layout_poly.ml @@ -1,10 +1,6 @@ (* TEST include stdlib_upstream_compatible; { - flags = "-extension layouts"; - expect; - }{ - flags = "-extension layouts_beta"; expect; } *) @@ -715,8 +711,8 @@ Error: "[@layout_poly]" on this external declaration has no variable for it to operate on. |}] -(***********************************************) -(* New untested array prims are gated to alpha *) +(********************************************************) +(* Newer prims are gated to appropriate maturity levels *) external[@layout_poly] makearray_dynamic : ('a : any_non_null). int -> 'a -> 'a array = "%makearray_dynamic" @@ -724,7 +720,7 @@ external[@layout_poly] makearray_dynamic : ('a : any_non_null). int -> 'a -> 'a Lines 1-2, characters 0-22: 1 | external[@layout_poly] makearray_dynamic : ('a : any_non_null). int -> 'a -> 'a array = 2 | "%makearray_dynamic" -Error: This construct requires the alpha version of the extension "layouts", which is disabled and cannot be used +Error: This construct requires the beta version of the extension "layouts", which is disabled and cannot be used |}] external[@layout_poly] arrayblit : @@ -735,5 +731,14 @@ Lines 1-3, characters 0-14: 1 | external[@layout_poly] arrayblit : 2 | ('a : any_non_null). 'a array -> int -> 'a array -> int -> int -> unit = 3 | "%arrayblit" -Error: This construct requires the alpha version of the extension "layouts", which is disabled and cannot be used +Error: This construct requires the beta version of the extension "layouts", which is disabled and cannot be used +|}] + +external[@layout_poly] makearray_dynamic : ('a : any_non_null). int -> 'a -> 'a array = + "%makearray_dynamic_uninit" +[%%expect{| +Lines 1-2, characters 0-29: +1 | external[@layout_poly] makearray_dynamic : ('a : any_non_null). int -> 'a -> 'a array = +2 | "%makearray_dynamic_uninit" +Error: This construct requires the beta version of the extension "layouts", which is disabled and cannot be used |}] diff --git a/typing/primitive.ml b/typing/primitive.ml index d2cc075844f..272b58674af 100644 --- a/typing/primitive.ml +++ b/typing/primitive.ml @@ -674,6 +674,12 @@ let prim_has_valid_reprs ~loc prim = any; is (Same_as_ocaml_repr C.value); ] + | "%makearray_dynamic_uninit" -> + (* Restrictions on this primitive are checked in [Translprim] *) + check [ + is (Same_as_ocaml_repr C.value); + is (Same_as_ocaml_repr C.value); + ] | "%box_float" -> exactly [Same_as_ocaml_repr C.float64; Same_as_ocaml_repr C.value] diff --git a/typing/typeopt.ml b/typing/typeopt.ml index f76557ed36e..75389569b84 100644 --- a/typing/typeopt.ml +++ b/typing/typeopt.ml @@ -228,7 +228,7 @@ let array_kind_of_elt ~elt_sort env loc ty = (type_legacy_sort ~why:Array_element env loc ty) in let classify_product ty sorts = - if Language_extension.(is_at_least Layouts Alpha) then + if Language_extension.(is_at_least Layouts Beta) then if is_always_gc_ignorable env ty then Pgcignorableproductarray (ignorable_product_array_kind loc sorts) else