decodeTensor decodes the Tensor from the buffer to ptr using the format specified in c_api.h. Use stringDecoder for String tensors.
(r *bytes.Reader, shape []int64, typ reflect.Type, ptr reflect.Value)
| 349 | // decodeTensor decodes the Tensor from the buffer to ptr using the format |
| 350 | // specified in c_api.h. Use stringDecoder for String tensors. |
| 351 | func decodeTensor(r *bytes.Reader, shape []int64, typ reflect.Type, ptr reflect.Value) error { |
| 352 | switch typ.Kind() { |
| 353 | case reflect.Bool: |
| 354 | b, err := r.ReadByte() |
| 355 | if err != nil { |
| 356 | return err |
| 357 | } |
| 358 | ptr.Elem().SetBool(b == 1) |
| 359 | case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128: |
| 360 | if err := binary.Read(r, nativeEndian, ptr.Interface()); err != nil { |
| 361 | return err |
| 362 | } |
| 363 | |
| 364 | case reflect.Slice: |
| 365 | val := reflect.Indirect(ptr) |
| 366 | val.Set(reflect.MakeSlice(typ, int(shape[0]), int(shape[0]))) |
| 367 | |
| 368 | // Optimization: if only one dimension is left we can use binary.Read() directly for this slice |
| 369 | if len(shape) == 1 && val.Len() > 0 { |
| 370 | switch val.Index(0).Kind() { |
| 371 | case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128: |
| 372 | return binary.Read(r, nativeEndian, val.Interface()) |
| 373 | } |
| 374 | } |
| 375 | |
| 376 | for i := 0; i < val.Len(); i++ { |
| 377 | if err := decodeTensor(r, shape[1:], typ.Elem(), val.Index(i).Addr()); err != nil { |
| 378 | return err |
| 379 | } |
| 380 | } |
| 381 | |
| 382 | default: |
| 383 | return fmt.Errorf("unsupported type %v", typ) |
| 384 | } |
| 385 | return nil |
| 386 | } |
| 387 | |
| 388 | type stringEncoder struct { |
| 389 | offsets io.Writer |