Need help with sparse matrix for loop code

Đang mở
#488 1 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức phù hợp với người mới
25/100
Loại issue
Lỗi
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Đình trệ
Công nghệ
ocaml
Lĩnh vực
compilers

Hướng nghiên cứu

Bắt đầu với các entry point mkfortnite và for_scalar trên branch sparse-matrix được tham chiếu, sau đó so sánh cách xây dựng biểu thức có kiểu của chúng với triển khai mkfor mới hơn. Build branch sparse3 và xác minh rằng các lỗi kiểu đã được giải quyết và mã được tạo ra tạo ra vòng lặp sparse-matrix được hiển thị.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

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
Ngôn ngữ chính
OCaml
Star
162
Fork
60
Merge trung bình
2 ngày 22 giờ
Pull request đã merge (30 ngày)
14

Chuẩn bị môi trường

  • Không có Dockerfile hay tệp Docker Compose
  • Có mẫu pull request
  • Không có hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của stan-dev/stanc3

Tất cả issue của stan-dev/stanc3

Issue tương tự

Thêm issue về Compilers

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.