Opencl_api.Programtype t = {handle : Opencl_types.cl_program;context : Context.t;_source : (char, Stdlib.Bigarray.int8_unsigned_elt, Stdlib.Bigarray.c_layout)
Stdlib.Bigarray.Array1.t;}val build : t -> ?options:string -> unit -> unitBuild a program.
options is what the CALLER wants; it is not what clBuildProgram receives. Opencl_fp.build_options screens it — raising Opencl_fp.Fp_conformance_violation on anything that would relax float semantics below docs/fp-contraction-policy.md §1 — and appends the options this backend requires on its own behalf, gated on the device's CL_DEVICE_SINGLE_FP_CONFIG.
This is the ONLY place an option string reaches clBuildProgram, and that is deliberately where the guard sits rather than at the caller: it screens flags a FUTURE maintainer of this module adds itself, not merely a caller's. Same placement argument as Cuda_nvrtc.compile_with_string_opts (docs/fp-contraction-policy.md §5).
Until backlog #136 this function passed options straight through, and every caller in the tree passed nothing — so the effective option string was empty and Sarek silently accepted each vendor's default, including a sqrt of up to 3 ulp.
val release : t -> unit