forked from danieldk/tensorflow
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtensor_int32.go
133 lines (105 loc) · 2.78 KB
/
tensor_int32.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// This file was automatically generated by genny.
// Any changes will be lost if this file is regenerated.
// see https://github.com/cheekybits/genny
package tensorflow
import (
"fmt"
"unsafe"
)
// #include <string.h>
// #include <tensor_c_api.h>
// #include "tensorflow.h"
import "C"
var _ Tensor = &Int32Tensor{}
var _ Tensor = &Float32Tensor{}
type Int32Tensor struct {
dims []int
data []int32
}
func NewInt32Tensor(dims []int) *Int32Tensor {
size := 1
for _, dim := range dims {
size *= dim
}
return &Int32Tensor{
dims: dims,
data: make([]int32, size),
}
}
func (t *Int32Tensor) index(idx []int) (int, int) {
if len(idx) >= len(t.dims) {
panic(fmt.Sprintf("Trying to address using %d dimensions, only %d permitted",
len(idx), len(t.dims)-1))
}
// Special case: the full array
if len(idx) == 0 {
dimSize := 1
for _, dim := range t.dims {
dimSize *= dim
}
return 0, dimSize
}
startIdx := 0
var dimSize int
for i, idx := range idx {
dimSize = 1
for _, dim := range t.dims[i+1:] {
dimSize *= dim
}
startIdx += idx * dimSize
}
return startIdx, dimSize
}
func (t *Int32Tensor) Get(idx []int) []int32 {
startIdx, dimSize := t.index(idx)
return t.data[startIdx : startIdx+dimSize]
}
func (t *Int32Tensor) Assign(idx []int, data []int32) {
startIdx, _ := t.index(idx)
if len(idx) >= len(t.dims) {
panic(fmt.Sprintf("Trying to address using %d dimensions, only %d permitted",
len(idx), len(t.dims)-1))
}
// TODO: bounds checks?
copy(t.data[startIdx:], data)
}
func (t *Int32Tensor) Fill(idx []int, v int32) {
startIdx, dimSize := t.index(idx)
for idx := startIdx; idx < startIdx+dimSize; idx++ {
t.data[idx] = v
}
}
func (t *Int32Tensor) toCTensor() *C.TF_Tensor {
// TF_NewTensor copies dims, does not take ownership.
llDims := make([]C.longlong, len(t.dims))
for idx, val := range t.dims {
llDims[idx] = C.longlong(val)
}
// TF_NewTensor potentially adopts data, so we cannot pass the Go
// slice backing array.
dataLen := C.size_t(len(t.data)) * C.size_t(unsafe.Sizeof(t.data[0]))
cData := C.malloc(dataLen)
C.memcpy(cData, unsafe.Pointer(&t.data[0]), dataLen)
return C.tfgo_tensor(C.TF_INT32, (*C.longlong)(unsafe.Pointer(&llDims[0])),
C.int(len(llDims)), cData, dataLen)
}
func adoptint32Tensor(ct *C.TF_Tensor) *Int32Tensor {
dims := C.TF_NumDims(ct)
shape := make([]int, dims)
size := uint(1)
for i := C.int(0); i < dims; i++ {
shape[i] = int(C.TF_Dim(ct, i))
size *= uint(shape[i])
}
bs := C.TF_TensorByteSize(ct)
var valForSize int32
if uint(bs)/uint(unsafe.Sizeof(valForSize)) != size {
panic("Expected tensor size does not correspond to the actual tensor size")
}
data := make([]int32, size)
C.memcpy(unsafe.Pointer(&data[0]), C.TF_TensorData(ct), bs)
return &Int32Tensor{
dims: shape,
data: data,
}
}