-
-
Notifications
You must be signed in to change notification settings - Fork 142
Open
Description
Hi, I'm trying to write a custom serializer for an Nd4j array (see http://nd4j.org). I was about to get it working with json but when I try yaml output I get an exception:
Cause: com.fasterxml.jackson.dataformat.yaml.snakeyaml.emitter.EmitterException: expected NodeEvent, but got <com.fasterxml.jackson.dataformat.yaml.snakeyaml.events.DocumentEndEvent()>
at com.fasterxml.jackson.dataformat.yaml.snakeyaml.emitter.Emitter.expectNode(Emitter.java:409)
at com.fasterxml.jackson.dataformat.yaml.snakeyaml.emitter.Emitter.access$1600(Emitter.java:63)
at com.fasterxml.jackson.dataformat.yaml.snakeyaml.emitter.Emitter$ExpectBlockMappingValue.expect(Emitter.java:651)
at com.fasterxml.jackson.dataformat.yaml.snakeyaml.emitter.Emitter.emit(Emitter.java:217)
at com.fasterxml.jackson.dataformat.yaml.YAMLGenerator.close(YAMLGenerator.java:308)
at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:3398)
at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:2779)In order to simplify the test I created dummy classes for Nd4j so I know the issue is not specific to that package. This test case:
import com.fasterxml.jackson.databind.JsonSerializer
//import org.nd4j.linalg.api.ndarray.INDArray
import com.fasterxml.jackson.core.JsonGenerator
import com.fasterxml.jackson.databind.SerializerProvider
//import org.nd4j.linalg.api.buffer.DataBuffer
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import com.fasterxml.jackson.databind.module.SimpleModule
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
import com.fasterxml.jackson.databind.jsontype.TypeSerializer
//import org.nd4j.linalg.factory.Nd4j
import com.fasterxml.jackson.annotation.JsonTypeInfo
import org.scalatest.FunSuite
// Dummy INDArray
class INDArray {
val _data = new DataBuffer
def shape() = Array[Int](1, 3)
def data = _data
def ordering() = 'f'
}
// Dummy DataBuffer
class DataBuffer {
def dataType = 1
def asBytes() = Array[Byte](1, 2, 3)
}
// Custom serializer for INDArray
class NDArraySerializer extends JsonSerializer[INDArray] {
def serialize(
value: INDArray,
jgen: JsonGenerator,
provider: SerializerProvider) {
jgen.writeStartObject()
jgen.writeArrayFieldStart("shape")
for (i <- value.shape()) jgen.writeNumber(i)
jgen.writeEndArray()
val dtype =
if (value.data.dataType == 1 /*DataBuffer.FLOAT*/ )
"float"
else
"double"
jgen.writeStringField("dtype", dtype)
jgen.writeStringField("order", value.ordering().toString())
jgen.writeBinaryField("data", value.data.asBytes())
jgen.writeEndObject()
}
override def serializeWithType(
value: INDArray,
jgen: JsonGenerator,
provider: SerializerProvider,
typeSer: TypeSerializer) {
typeSer.writeTypePrefixForObject(value, jgen)
serialize(value, jgen, provider)
typeSer.writeTypeSuffixForObject(value, jgen)
}
}
class TestYAML extends FunSuite {
test("yaml") {
try {
val nd4jModule = new SimpleModule()
nd4jModule.addSerializer(classOf[INDArray], new NDArraySerializer())
val jsonMapper = new ObjectMapper
jsonMapper.registerModule(DefaultScalaModule)
jsonMapper.registerModule(nd4jModule)
jsonMapper.enableDefaultTyping(
ObjectMapper.DefaultTyping.NON_FINAL,
JsonTypeInfo.As.PROPERTY)
val yamlMapper = new ObjectMapper(new YAMLFactory)
yamlMapper.registerModule(DefaultScalaModule)
yamlMapper.registerModule(nd4jModule)
yamlMapper.enableDefaultTyping(
ObjectMapper.DefaultTyping.NON_FINAL,
JsonTypeInfo.As.PROPERTY)
val array = new INDArray
jsonMapper.writeValueAsString(array)
yamlMapper.writeValueAsString(array)
}
catch {
case e: Throwable => fail("shouldn't throw an exception.", e)
}
}
}
If I comment out the enableDefaultTyping call it works.
Metadata
Metadata
Assignees
Labels
No labels