lms-clean icon indicating copy to clipboard operation
lms-clean copied to clipboard

missing array update for some array returned in tuple

Open namin opened this issue 3 years ago • 4 comments

/*
The array update is sometimes omitted, but it should always be part of the generated code.
 */

import lms.core.stub._
import lms.core.virtualize
import lms.macros.SourceContext

@virtualize
class BugTest extends TutorialFunSuite {
  val under = "bug_"

  test("bug ok") {
    val snippet = new DslDriver[Array[Int],Array[Int]] {
      def snippet(a: Rep[Array[Int]]) = {
        a(0) = 0
        a
      }
    }
    exec("ok", snippet.code)
/*
class Snippet() extends (Array[Int] => Array[Int]) {
  def apply(x0: Array[Int]): Array[Int] = {
    x0(0) = 0
    x0
  }
}
 */
  }

  test("bug ok1") {
    val snippet = new DslDriver[(Array[Int],Int),Array[Int]] with lms.collection.immutable.TupleOps { q =>
      override val codegen = new DslGen with lms.collection.immutable.ScalaCodeGen_Tuple {
        val IR: q.type = q
      }
      def snippet(t: Rep[(Array[Int],Int)]) = {
        val a = t._1
        a(0) = 0
        a
      }
    }
    exec("ok1", snippet.code)
/*
class Snippet() extends (Tuple2[Array[Int], Int] => Array[Int]) {
  def apply(x0: Tuple2[Array[Int], Int]): Array[Int] = {
    val x1 = x0._1
    x1(0) = 0
    x1
  }
}
 */
  }

  test("bug ok2") {
    val snippet = new DslDriver[Array[Int],(Array[Int],Int)] with lms.collection.immutable.TupleOps { q =>
      override val codegen = new DslGen with lms.collection.immutable.ScalaCodeGen_Tuple {
        val IR: q.type = q
      }
      def snippet(a: Rep[Array[Int]]) = {
        a(0) = 0
        (a, 0)
      }
    }
    exec("ok2", snippet.code)
/*
class Snippet() extends (Array[Int] => Tuple2[Array[Int], Int]) {
  def apply(x0: Array[Int]): Tuple2[Array[Int], Int] = {
    x0(0) = 0
    (x0, 0)
  }
}
 */
  }

  // all the bad code is missing the update

  test("bug bad1") {
    val snippet = new DslDriver[(Array[Int],Int),(Array[Int],Int)] with lms.collection.immutable.TupleOps { q =>
      override val codegen = new DslGen with lms.collection.immutable.ScalaCodeGen_Tuple {
        val IR: q.type = q
      }
      def snippet(t: Rep[(Array[Int],Int)]) = {
        val a = t._1
        a(0) = 0
        (a, 0)
      }
    }
    exec("bad1", snippet.code)
/*
class Snippet() extends (Tuple2[Array[Int], Int] => Tuple2[Array[Int], Int]) {
  def apply(x0: Tuple2[Array[Int], Int]): Tuple2[Array[Int], Int] = (x0._1, 0)
}
*/
  }

  test("bug bad2") {
    val snippet = new DslDriver[(Array[Int],Int),(Array[Int],Int)] with lms.collection.immutable.TupleOps { q =>
      override val codegen = new DslGen with lms.collection.immutable.ScalaCodeGen_Tuple {
        val IR: q.type = q
      }
      def snippet(t: Rep[(Array[Int],Int)]) = {
        val a = t._1
        val b = t._2
        a(0) = 0
        (a, b)
      }
    }
    exec("bad2", snippet.code)
/*
class Snippet() extends (Tuple2[Array[Int], Int] => Tuple2[Array[Int], Int]) {
  def apply(x0: Tuple2[Array[Int], Int]): Tuple2[Array[Int], Int] = (x0._1, x0._2)
}
 */
  }

  test("bug bad3") {
    val snippet = new DslDriver[(Array[Int],Int),(Array[Int],Int)] with lms.collection.immutable.TupleOps { q =>
      override val codegen = new DslGen with lms.collection.immutable.ScalaCodeGen_Tuple {
        val IR: q.type = q
      }
      def snippet(t: Rep[(Array[Int],Int)]) = {
        val a = t._1
        val b = t._2
        a(0) = 0
        val (oa, ob) = (a, b)
        (oa, ob)
      }
    }
    exec("bad3", snippet.code)
/*
class Snippet() extends (Tuple2[Array[Int], Int] => Tuple2[Array[Int], Int]) {
  def apply(x0: Tuple2[Array[Int], Int]): Tuple2[Array[Int], Int] = (x0._1, x0._2)
}
 */
  }

  test("bug bad4") {
    val snippet = new DslDriver[(Array[Int],Int),(Array[Int],Int)] with lms.collection.immutable.TupleOps { q =>
      override val codegen = new DslGen with lms.collection.immutable.ScalaCodeGen_Tuple {
        val IR: q.type = q
      }
      def snippet(t: Rep[(Array[Int],Int)]) = {
        val a = t._1
        val b = t._2
        a(0) = 0
        val (oa, ob) = (a, b+1)
        (oa, ob)
      }
    }
    exec("bad4", snippet.code)
/*
class Snippet() extends (Tuple2[Array[Int], Int] => Tuple2[Array[Int], Int]) {
  def apply(x0: Tuple2[Array[Int], Int]): Tuple2[Array[Int], Int] = (x0._1, x0._2 + 1)
}
 */
  }
}

namin avatar Apr 19 '22 22:04 namin

Here are some tests for the same issue with list:


  test("bug list1") {
    val snippet = new DslDriver[List[Array[Int]],Array[Int]] with lms.collection.immutable.ListOps { q =>
      override val codegen = new DslGen with lms.collection.immutable.ScalaCodeGen_List {
        val IR: q.type = q
      }
      def snippet(lst: Rep[List[Array[Int]]]) = {
        val a = lst(0)
        a(0) = 0
        a
      }
    }
    exec("list1", snippet.code)
/*
class Snippet() extends (List[Array[Int]] => Array[Int]) {
  def apply(x0: List[Array[Int]]): Array[Int] = {
    val x1 = x0(0)
    x1(0) = 0
    x1
  }
}
*/
  }

  test("bug list2") {
    val snippet = new DslDriver[List[Array[Int]],List[Array[Int]]] with lms.collection.immutable.ListOps { q =>
      override val codegen = new DslGen with lms.collection.immutable.ScalaCodeGen_List {
        val IR: q.type = q
      }
      def snippet(lst: Rep[List[Array[Int]]]) = {
        val a = lst(0)
        a(0) = 0
        lst
      }
    }
    exec("list2", snippet.code)
/*
class Snippet() extends (List[Array[Int]] => List[Array[Int]]) {
  def apply(x0: List[Array[Int]]): List[Array[Int]] = x0
}
*/
  }

namin avatar Apr 20 '22 00:04 namin

And the same issue with nested arrays:

  test("bug arr1") {
    val snippet = new DslDriver[Array[Array[Int]],Array[Int]] { q =>
      override val codegen = new DslGen {
        val IR: q.type = q
      }
      def snippet(arr: Rep[Array[Array[Int]]]) = {
        val a = arr(0)
        a(0) = 0
        a
      }
    }
    exec("arr1", snippet.code)
/*
class Snippet() extends (Array[Array[Int]] => Array[Int]) {
  def apply(x0: Array[Array[Int]]): Array[Int] = {
    val x1 = x0(0)
    x1(0) = 0
    x1
  }
}
 */
  }

  test("bug arr2") {
    val snippet = new DslDriver[Array[Array[Int]],Array[Array[Int]]] { q =>
      override val codegen = new DslGen {
        val IR: q.type = q
      }
      def snippet(arr: Rep[Array[Array[Int]]]) = {
        val a = arr(0)
        a(0) = 0
        arr
      }
    }
    exec("arr2", snippet.code)
/*
class Snippet() extends (Array[Array[Int]] => Array[Array[Int]]) {
  def apply(x0: Array[Array[Int]]): Array[Array[Int]] = x0
}
*/
  }

namin avatar Apr 20 '22 00:04 namin

Thanks @namin. @Kraks @luke-jiang can one of you take a look? Feel free to reassign to someone else -- seems like a good issue for someone wanting to get into effect dependencies

TiarkRompf avatar Apr 20 '22 00:04 TiarkRompf

Thanks, @namin! I will try to look into the issue in the following days.

Kraks avatar Apr 20 '22 04:04 Kraks