Need help with sparse matrix for loop code

Abierto
#488 1 comentario 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
25/100
Tipo de issue
Error
Claridad
Bastante claro
Estado de actividad
Estancado
Stack tecnológico
ocaml
Área
compilers

Línea de trabajo

Comience con los puntos de entrada mkfortnite y for_scalar de la rama de matrices dispersas referenciada y, después, compare la construcción de expresiones tipadas con la implementación más reciente de mkfor. Compile la rama sparse3 y verifique que los errores de tipos se hayan resuelto y que el código generado produzca el bucle de matrices dispersas mostrado.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

optimization

I'm working on updating a branch of the compiler that supports sparse matrices and having trouble writing the function that makes a for loop over the sparse matrix to fill it with data. There I had a function that generated the for loop for reading in data like link

let mkfortnite nonzero_rows nonzero_cols bodyfn var smeta =
  let idx s =
    Single {expr= Var s; emeta= {mtype= UInt; mloc = smeta; madlevel= DataOnly}}
  in
  let loopvar, reset = gensym_enter () in
  let lower = loop_bottom in
  let upper = internal_funapp FnLength [nonzero_rows] internal_meta in
  let row_idx = add_int_index nonzero_rows (idx loopvar) in
  let col_idx = add_int_index nonzero_cols (idx loopvar) in
  let bodyfn var =
    add_int_index (add_int_index var (Single row_idx)) (Single col_idx)
    |> bodyfn in
  reset ();
  {stmt= For {loopvar; lower; upper; body=bodyfn var}; smeta}

Where the old version looked like

(** [mkfor] returns a MIR For statement that iterates over the given expression
    [iteratee]. *)
let mkfor upper bodyfn iteratee smeta =
  let idx s =
    Single {expr= Var s; emeta= {mtype= UInt; mloc= smeta; madlevel= DataOnly}}
  in
  let loopvar, reset = gensym_enter () in
  let lower = loop_bottom in
  let stmt = Block [bodyfn (add_int_index iteratee (idx loopvar))] in
  reset () ;
  {stmt= For {loopvar; lower; upper; body= {stmt; smeta}}; smeta}

The new version of mkfor looks like

  (** [mkfor] returns a MIR For statement that iterates over the given expression
    [iteratee]. *)
  let mkfor upper bodyfn iteratee meta =
    let idx s =
      let meta =
        Expr.Typed.Meta.create ~type_:UInt ~loc:meta ~adlevel:DataOnly ()
      in
      let expr = Expr.Fixed.{meta; pattern= Var s} in
      Index.Single expr
    in
    let loopvar, reset = Gensym.enter () in
    let lower = Expr.Helpers.loop_bottom in
    let stmt =
      Fixed.Pattern.Block
        [bodyfn (Expr.Helpers.add_int_index iteratee (idx loopvar))]
    in
    reset () ;
    let body = Fixed.{meta; pattern= stmt} in
    let pattern = Fixed.Pattern.For {loopvar; lower; upper; body} in
    Fixed.{meta; pattern}

I think I'm pretty close, I've written the below but nonzero_rows in row_idx and upper in pattern are giving me the errors

row_idx: (nonzero_rows)

type _ = unit Expr.Fixed.t
This expression has type unit Expr.Fixed.t
but an expression was expected of type
  Expr.Typed.t = Expr.Typed.Meta.t Expr.Fixed.t
Type unit is not compatible with type Expr.Typed.Meta.t

pattern: (upper)

type _ = unit Expr.Fixed.t
This expression has type unit Expr.Fixed.t
but an expression was expected of type
  Expr.Typed.t = Expr.Typed.Meta.t Expr.Fixed.t
Type unit is not compatible with type Expr.Typed.Meta.t
  let mkfortnite nonzero_rows nonzero_cols bodyfn var meta = 
    let idx s = 
       let meta = 
         Expr.Typed.Meta.create ~type_:Uint ~loc:meta ~adlevel:DataOnly () 
        in
        let expr = Expr.Fixed.{meta; pattern= Var s} in
        Index.Single expr
    in
    let loopvar, reset = Gensym.enter () in
    let lower = Expr.Helpers.loop_bottom in
    let upper = Expr.Helpers.internal_funapp FnLength [nonzero_rows] () in (* error from here*)
    let row_idx = Expr.Helpers.add_int_index nonzero_rows (idx loopvar) in (* error here*)
    let col_idx = Expr.Helpers.add_int_index nonzero_cols (idx loopvar) in
    let row_iter = Expr.Helpers.add_int_index var (Index.Single row_idx) in
    let col_iter = Expr.Helpers.add_int_index row_iter (Index.Single col_idx) in
    let bodyfn = col_iter |> bodyfn in
    reset ();
    let body = Fixed.{meta; pattern = bodyfn var} in
    let pattern = Fixed.Pattern.For {loopvar; lower; upper ; body} in (* error here*)
    Fixed.{meta; pattern}

mkfortnite is called in for_scalar here

  let rec for_scalar st bodyfn var smeta =
    match st with
    | SizedType.SInt | SReal -> bodyfn var
    | SVector d | SRowVector d -> mkfor d bodyfn var smeta
    | SMatrix (d1, d2) ->
        mkfor d1 (fun e -> for_scalar (SRowVector d2) bodyfn e smeta) var smeta
    | SSparseMatrix (nonzero_rows, nonzero_cols, _, _) ->
      mkfortnite nonzero_rows nonzero_cols bodyfn var smeta
    | SArray (t, d) -> mkfor d (fun e -> for_scalar t bodyfn e smeta) var smeta

The goal here is to generate a for loop like

      x = Eigen::SparseMatrix<double>(N, M);
      current_statement__ = 7;
      pos__ = 1;
      current_statement__ = 7;
// nz_rows has a size equal to the number of nonzero values
      for (size_t sym1__ = 1; sym1__ <= stan::math::size(nz_rows); ++sym1__) {
        current_statement__ = 7;
        assign(x,
               cons_list(index_uni(nz_cols[(sym1__ - 1)]),
                         cons_list(index_uni(nz_rows[(sym1__ - 1)]),
                                   nil_index_list())),
               context__.vals_r("x")[(pos__ - 1)], "assigning variable x");
        current_statement__ = 7;
        pos__ = (pos__ + 1);
      }

The main things are

  1. I'm not totally sure how to use the new types when making upper where it used to be
  let upper = internal_funapp FnLength [nonzero_rows] internal_meta in

I tried

let upper = Expr.Helpers.internal_funapp FnLength [nonzero_rows] () in

It looks like @enetsee removed internal_meta in 3f037c5be9760be14c4e4b2d41cc4dd560a552e0. @enetsee can you help me find the right setup for this now?

  1. upper above is causing ocaml to think nonzero_rows is unit Expr.Fixed.t when it should be the same as nonzero_cols (Expr.Typed.t). So I think the heart of the problem is the upper statement.

If anyone can help with this it would be v appreciated! You can grab the branch via

git remote add stevebronder  https://github.com/SteveBronder/stanc3
git fetch stevebronder
git checkout stevebronder/sparse3
make
Lenguaje dominante
OCaml
Estrellas
162
Forks
60
Merge medio
2 d 22 h
PR fusionados (30 d)
14

Preparar el entorno

  • Sin Dockerfile ni archivo de Docker Compose
  • Tiene una plantilla de pull request
  • Sin guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de stan-dev/stanc3

Todos los issues de stan-dev/stanc3

Issues similares

Más issues de Compilers

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.