You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mxnet.apache.org by GitBox <gi...@apache.org> on 2018/08/06 19:09:27 UTC

[GitHub] mdespriee edited a comment on issue #11926: segfault in native code while trying to use CustomOp

mdespriee edited a comment on issue #11926: segfault in native code while trying to use CustomOp
URL: https://github.com/apache/incubator-mxnet/issues/11926#issuecomment-410445567
 
 
   @andrewfayres Unfortnuately, I stumbled on another problem, when trying to instantiate 2 constants in a flow. Either there's something I don't get on how CustomOp should be used, or there are some subtle bugs in the code. Or both.
   
   Here we go. I create a symbol adding a variable and 2 instances of Constant.
   ```
     val a = Symbol.Variable("a")
     val symbol = a + const1 + const2      // const1 = 10 and const2 = -10
   ```
   I executed a forward(), with `a` bound to 1. I tracked what instances, kwargs and values were used, and I got that:
   ```
   inferShape called with kwargs(id)=2    
   inferShape called with kwargs(id)=2   <<-  never called for id 1
   CreateOperator called with kwargs(id)=2
   Building ConstantOp instance CustomOpTest$ConstantOp@27c14491 with value [-10.0]
   CreateOperator called with kwargs(id)=2     <<- idem
   Building ConstantOp instance CustomOpTest$ConstantOp@2515240d with value [-10.0]     <<-- one of the 2 should be 10    (probably related to kwargs mixup)
   Forward called on instance CustomOpTest$ConstantOp@27c14491, having value [-10.0]
   Forward called on instance CustomOpTest$ConstantOp@27c14491, having value [-10.0]      <<-- only one of the 2 instances is used (so instance variable)
   Result= -19.0 (should be 1)
   ```
   So 2 problems: the values in kwargs got mixed at instantiation, and only one ConstantOp instance (and value) used in forward()
   
   
   Here is the full code:
   ```
   import org.apache.mxnet.DType.DType
   import org.apache.mxnet._
   
   object CustomOpTest extends App {
   
     class ConstantOpProp(needTopGrad: Boolean = false) extends CustomOpProp(needTopGrad) {
   
       override def listArguments(): Array[String] = Array()
   
       override def listOutputs(): Array[String] = Array("output")
   
       override def inferShape(inShape: Array[Shape]): (Array[Shape], Array[Shape], Array[Shape]) = {
         println("inferShape called with kwargs(id)=" + this.kwargs("id"))
         val data = NDArray.deserialize(this.kwargs("value").toCharArray.map(_.toByte))
         (Array(data.shape), Array(data.shape), null)
       }
   
       override def inferType(inType: Array[DType]): (Array[DType], Array[DType], Array[DType]) = {
         val data = NDArray.deserialize(this.kwargs("value").toCharArray.map(_.toByte))
         (Array(data.dtype), Array(data.dtype), null)
       }
   
       override def createOperator(ctx: String, inShapes: Array[Array[Int]], inDtypes: Array[Int]): CustomOp = {
         println("CreateOperator called with kwargs(id)=" + this.kwargs("id"))
         val data = NDArray.deserialize(this.kwargs("value").toCharArray.map(_.toByte))
         new ConstantOp(data)
       }
     }
   
     class ConstantOp(value: NDArray) extends CustomOp {
       println(s"Building ConstantOp instance $this with value ${value.toArray.mkString("[", ",", "]")}")
   
       def forward(isTrain: Boolean, req: Array[String], inData: Array[NDArray], outData: Array[NDArray], aux: Array[NDArray]): Unit = {
         println(s"Forward called on instance $this, having value ${value.toArray.mkString("[", ",", "]")}")
         val data = value.copyTo(outData(0).context)
         this.assign(outData(0), req(0), data)
         data.dispose()
       }
   
       def backward(req: Array[String], outGrad: Array[NDArray], inData: Array[NDArray], outData: Array[NDArray], inGrad: Array[NDArray], aux: Array[NDArray]): Unit =
         throw new Exception(s"Not implemented")
   
     }
   
     Operator.register("constant", new ConstantOpProp())
   
     val value1 = NDArray.array(Array(10f), Shape(1))
     val value2 = NDArray.array(Array(-10f), Shape(1))
   
     val const1 = Symbol.Custom("constant-1")()(
       kwargs = Map("id" -> 1, "op_type" -> "constant", "value" -> String.copyValueOf(value1.serialize().map(_.toChar)),
         "aaa" -> "aaa"
       )
     )
     val const2 = Symbol.Custom("constant-2")()(
       kwargs = Map("id" -> 2, "op_type" -> "constant", "value" -> String.copyValueOf(value2.serialize().map(_.toChar)),
         "bbb" -> "bbb"
       )
     )
   
     val a = Symbol.Variable("a")
     val symbol = a + const1 + const2
   
     val exec = symbol.bind(Context.defaultCtx, Map(
       "a" -> NDArray.array(Array(1f), Shape(1)))
     )
   
     exec.forward()
     println(s"Result= ${exec.outputs.head.toScalar} (should be 1)")
   }
   ```
   
   Thanks for your help
   
   
   **EDIT** : added a bit of logs for kwargs as well, as it may help

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services