Module Sarek_ppx_lib.Sarek_native_gen

Expression Generation

module IntSet : sig ... end

Mutable variable tracking. We track which variable IDs are mutable so that TEVar can dereference them.

module StringSet : sig ... end

Set of inline type names for first-class module approach

type gen_context = {
  1. mut_vars : IntSet.t;
    (*

    Variable IDs that are mutable (need dereferencing)

    *)
  2. inline_types : StringSet.t;
    (*

    Type names that use first-class module accessors

    *)
  3. current_module : string option;
    (*

    Current module name for same-module type detection

    *)
  4. gen_mode : Sarek_native_intrinsics.gen_mode;
    (*

    Generation mode - affects how thread indices are accessed

    *)
  5. use_native_arg : bool;
    (*

    When true, vector params are accessor objects (v#get i, v#set i x) instead of Vector.t (Vector.get v i, Vector.kernel_set v i x)

    *)
}

Expression generation context

val empty_ctx : gen_context

Empty generation context

val is_same_module : gen_context -> string -> bool

Check if a qualified type name is from the current module. For "Test_registered_variant.color", returns true if current_module is "Test_registered_variant".

val types_module_var : string

The name of the first-class module variable

First-Class Module Name Helpers

val field_getter_name : string -> string -> string

Generate accessor function name for a field getter

val record_maker_name : string -> string

Generate constructor function name for a record

val variant_ctor_name : string -> string -> string

Generate constructor function name for a variant constructor

val gen_literal : loc:Ppxlib.location -> Sarek_typed_ast.texpr -> Ppxlib.expression
val gen_variable : loc:Ppxlib__.Location.t -> ctx:gen_context -> string -> int -> Ppxlib.expression

Generate variable reference (local, module-level, qualified)

val gen_memory_access : loc:Ppxlib.location -> ctx:gen_context -> gen_expr: (loc:Ppxlib.location -> Sarek_typed_ast.texpr -> Ppxlib_ast.Ast.expression) -> Sarek_typed_ast.texpr -> Ppxlib.expression

Generate memory access operations (vectors, arrays, record fields)

val gen_let_binding : loc:Ppxlib__.Location.t -> ctx:gen_context -> gen_expr: (loc:Ppxlib__.Location.t -> Sarek_typed_ast.texpr -> Ppxlib_ast.Ast.expression) -> gen_expr_impl: (loc:Ppxlib__.Location.t -> ctx:gen_context -> Sarek_typed_ast.texpr -> Ppxlib_ast.Ast.expression) -> Sarek_typed_ast.texpr -> Ppxlib.expression

Generate let bindings (let, let mut, assignment)

val gen_control_flow : loc:Ppxlib.location -> gen_expr: (loc:Ppxlib.location -> Sarek_typed_ast.texpr -> Ppxlib_ast.Ast.expression) -> Sarek_typed_ast.texpr -> Ppxlib.expression

Generate control flow (if, for, while)

val gen_data_structure : loc:Ppxlib.location -> ctx:gen_context -> gen_expr: (loc:Ppxlib.location -> Sarek_typed_ast.texpr -> Ppxlib__.Import.expression) -> Sarek_typed_ast.texpr -> Ppxlib.expression

Generate data structures (records, variants, tuples, arrays)

val gen_special_expr : loc:Ppxlib__.Location.t -> gen_expr: (loc:Ppxlib__.Location.t -> Sarek_typed_ast.texpr -> Ppxlib.expression) -> Sarek_typed_ast.texpr -> Ppxlib.expression

Generate special expressions (return, global ref, native, pragma, open)

val gen_parallel_construct : loc:Ppxlib.location -> gen_expr: (loc:Ppxlib.location -> Sarek_typed_ast.texpr -> Ppxlib_ast.Ast.expression) -> Sarek_typed_ast.texpr -> Ppxlib.expression

Generate BSP parallel constructs (let%shared, let%superstep, let rec)

val gen_expr_impl : loc:Ppxlib__.Location.t -> ctx:gen_context -> Sarek_typed_ast.texpr -> Ppxlib_ast.Ast.expression

Generate OCaml expression from typed Sarek expression.

  • parameter ctx

    Generation context with mutable vars and inline types

val gen_pattern_impl : loc:Ppxlib.location -> ctx:gen_context -> Sarek_typed_ast.tpattern -> Ppxlib.pattern

Generate pattern from typed pattern. Takes context to detect same-module types that shouldn't be qualified.

val gen_binop : loc:Ppxlib.location -> Sarek_ast.binop -> Ppxlib.expression -> Ppxlib.expression -> Sarek_types.typ -> Ppxlib.expression

Generate binary operation

val gen_unop : loc:Ppxlib.location -> Sarek_ast.unop -> Ppxlib.expression -> Sarek_types.typ -> Ppxlib.expression

Generate unary operation

val module_name_of_sarek_loc : Sarek_ast.loc -> string

Extract module name from a Sarek location (file path). For "/path/to/test_registered_variant.ml", returns "Test_registered_variant".

val gen_expr : loc:Ppxlib__.Location.t -> Sarek_typed_ast.texpr -> Ppxlib.expression

Top-level entry point for generating expressions. Starts with empty context.

val gen_expr_with_inline_types : loc:Ppxlib__.Location.t -> inline_type_names:StringSet.t -> current_module:string option -> Sarek_typed_ast.texpr -> Ppxlib.expression

Generate expression with inline types context for first-class modules.

Module Item Generation

val gen_module_fun : loc:Ppxlib__.Location.t -> string -> Sarek_typed_ast.tparam list -> Sarek_typed_ast.texpr -> Ppxlib.pattern * Ppxlib.expression

Generate a module-level function (TMFun) as a let binding.

val gen_module_const : loc:Ppxlib__.Location.t -> string -> int -> Sarek_types.typ -> Sarek_typed_ast.texpr -> Ppxlib.pattern * Ppxlib.expression

Generate a module-level constant (TMConst) as a let binding.

Type Declaration Generation

val gen_type_decl_record : loc:Ppxlib.location -> string -> (string * Sarek_types.typ * bool) list -> Ppxlib.structure_item

Generate a type declaration for a record type

val gen_type_decl_variant : loc:Ppxlib.location -> string -> (string * Sarek_types.typ option) list -> Ppxlib.structure_item

Generate a type declaration for a variant type

val gen_type_decl_item : loc:Ppxlib.location -> Sarek_typed_ast.ttype_decl -> Ppxlib.structure_item

Generate a structure item from a typed type declaration

val wrap_module_items : loc:Ppxlib__.Location.t -> Sarek_typed_ast.tmodule_item list -> Ppxlib.expression -> Ppxlib.expression

Wrap expression with module item bindings.

First-Class Module Approach for Inline Types

To avoid "type escapes its scope" errors, we use first-class modules to encapsulate inline types. The approach:

1. Generate a module signature KERNEL_TYPES with abstract types and accessors 2. Generate a concrete module implementation with the actual types 3. Transform the kernel body to use T.get_field and T.make_type accessors 4. Pass (module T : KERNEL_TYPES) as a parameter to the kernel

This keeps the concrete types hidden behind an existential type.

val gen_module_impl : loc:Ppxlib.location -> Sarek_typed_ast.ttype_decl list -> Ppxlib.module_expr

Generate a concrete module implementation for inline types (types only). Example for record type point with fields x and y: struct type point = record with fields x: float and y: float end

Note: We only generate type declarations here, not accessor functions. The accessor functions are generated as object methods by gen_types_object.

val inline_type_decls : Sarek_typed_ast.ttype_decl list -> Sarek_typed_ast.ttype_decl list

Get only inline type declarations (those without module prefix). External/registered types have qualified names like "Module.type".

val has_inline_types : Sarek_typed_ast.tkernel -> bool

Check if a kernel has inline types that need first-class module handling

Kernel Generation

Convert execution strategy to generation mode

val gen_arg_cast : loc:Ppxlib.location -> Sarek_typed_ast.tparam -> int -> Ppxlib.expression

Generate a type cast expression for extracting a kernel argument.

For vectors: extract NA_Vec and create an accessor wrapper. For scalars: match on NA_Int32/NA_Float32/etc and extract the value.

Uses typed native_arg for type safety.

val gen_types_object : loc:Ppxlib.location -> Sarek_typed_ast.ttype_decl list -> Ppxlib.expression

Generate an object expression with accessor methods for FCM. Example for type point with fields x and y: object method get_point_x r = r.x method get_point_y r = r.y method make_point ~x ~y = record with fields x and y end

Using an object avoids needing to define a record type for the accessors.

val gen_cpu_kern_native : loc:Ppxlib__.Location.t -> Sarek_typed_ast.tkernel -> Ppxlib.expression

Generate V2 cpu_kern - uses Spoc_core.Vector.get/set instead of Spoc.Mem.

Generated signature: thread_state -> shared_mem -> args_tuple -> unit This matches the signature expected by run_parallel/run_sequential.

val gen_simple_cpu_kern_native : loc:Ppxlib__.Location.t -> exec_strategy:Sarek_convergence.exec_strategy -> Sarek_typed_ast.tkernel -> Ppxlib.expression

Generate simple kernel for optimized threadpool execution using the modern vector path (Spoc_core.Vector).

val gen_cpu_kern_native_wrapper : loc:Ppxlib__.Location.t -> Sarek_typed_ast.tkernel -> Ppxlib.expression

Generate the cpu_kern wrapper for use with native_fn_t.

Generated function type: parallel:bool -> block:int*int*int -> grid:int*int*int -> native_arg array -> unit

Uses typed native_arg accessors for type-safe vector access. Vectors are wrapped in accessor objects with get/set/length/underlying.