|
1 | 1 | /*
|
2 |
| - Copyright 2019 The TensorFlow Authors. All Rights Reserved. |
| 2 | +Copyright 2019 The TensorFlow Authors. All Rights Reserved. |
3 | 3 |
|
4 |
| - Licensed under the Apache License, Version 2.0 (the "License"); |
5 |
| - you may not use this file except in compliance with the License. |
6 |
| - You may obtain a copy of the License at |
| 4 | +Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | +you may not use this file except in compliance with the License. |
| 6 | +You may obtain a copy of the License at |
7 | 7 |
|
8 |
| - http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | + http://www.apache.org/licenses/LICENSE-2.0 |
9 | 9 |
|
10 |
| - Unless required by applicable law or agreed to in writing, software |
11 |
| - distributed under the License is distributed on an "AS IS" BASIS, |
12 |
| - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 |
| - See the License for the specific language governing permissions and |
14 |
| - limitations under the License. |
15 |
| - ======================================================================= |
16 |
| - */ |
| 10 | +Unless required by applicable law or agreed to in writing, software |
| 11 | +distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | +See the License for the specific language governing permissions and |
| 14 | +limitations under the License. |
| 15 | +======================================================================= |
| 16 | +*/ |
17 | 17 |
|
18 | 18 | package org.tensorflow.internal.c_api;
|
19 | 19 |
|
|
25 | 25 | import static org.tensorflow.internal.c_api.global.tensorflow.TF_TString_Init;
|
26 | 26 | import static org.tensorflow.internal.c_api.global.tensorflow.TF_TensorData;
|
27 | 27 | import static org.tensorflow.internal.c_api.global.tensorflow.TF_TensorElementCount;
|
| 28 | +import static org.tensorflow.internal.c_api.global.tensorflow.TF_TensorMaybeMove; |
28 | 29 | import static org.tensorflow.internal.c_api.global.tensorflow.TF_TensorType;
|
29 | 30 |
|
30 | 31 | import org.bytedeco.javacpp.Pointer;
|
31 | 32 | import org.bytedeco.javacpp.annotation.Properties;
|
32 | 33 |
|
33 | 34 | @Properties(inherit = org.tensorflow.internal.c_api.presets.tensorflow.class)
|
34 | 35 | public abstract class AbstractTF_Tensor extends Pointer {
|
35 |
| - protected static class DeleteDeallocator extends TF_Tensor implements Pointer.Deallocator { |
36 |
| - DeleteDeallocator(TF_Tensor s) { super(s); } |
37 |
| - @Override public void deallocate() { |
38 |
| - if (!isNull()) { |
39 |
| - if (TF_TensorType(this) == TF_STRING) { |
40 |
| - // we need to deallocate the strings themselves before deallocating the tensor memory |
41 |
| - long n = TF_TensorElementCount(this); |
42 |
| - TF_TString data = new TF_TString(TF_TensorData(this)); |
43 |
| - for (int i = 0; i < n; i++) { |
44 |
| - TF_TString_Dealloc(data.position(i)); |
45 |
| - } |
46 |
| - } |
47 |
| - TF_DeleteTensor(this); |
| 36 | + protected static class DeleteDeallocator extends TF_Tensor implements Pointer.Deallocator { |
| 37 | + DeleteDeallocator(TF_Tensor s) { |
| 38 | + super(s); |
| 39 | + } |
| 40 | + |
| 41 | + @Override |
| 42 | + public void deallocate() { |
| 43 | + if (!isNull()) { |
| 44 | + if (TF_TensorType(this) == TF_STRING) { |
| 45 | + TF_Tensor moved = TF_TensorMaybeMove(this); |
| 46 | + if (moved != null) { |
| 47 | + // we need to deallocate the strings themselves before deallocating the tensor memory |
| 48 | + long n = TF_TensorElementCount(moved); |
| 49 | + TF_TString data = new TF_TString(TF_TensorData(moved)); |
| 50 | + for (int i = 0; i < n; i++) { |
| 51 | + TF_TString_Dealloc(data.position(i)); |
48 | 52 | }
|
49 |
| - setNull(); |
| 53 | + TF_DeleteTensor(moved); |
| 54 | + } else { |
| 55 | + // TensorBuffer is shared, leave contained strings alone. |
| 56 | + TF_DeleteTensor(this); |
| 57 | + } |
| 58 | + } else { |
| 59 | + TF_DeleteTensor(this); |
50 | 60 | }
|
| 61 | + } |
| 62 | + setNull(); |
51 | 63 | }
|
| 64 | + } |
52 | 65 |
|
53 |
| - /** TensorFlow crashes if we don't pass it a deallocator, so... */ |
54 |
| - protected static Deallocator_Pointer_long_Pointer dummyDeallocator = new Deallocator_Pointer_long_Pointer() { |
55 |
| - @Override public void call(Pointer data, long len, Pointer arg) { } |
56 |
| - }.retainReference(); |
| 66 | + /** TensorFlow crashes if we don't pass it a deallocator, so... */ |
| 67 | + protected static Deallocator_Pointer_long_Pointer dummyDeallocator = |
| 68 | + new Deallocator_Pointer_long_Pointer() { |
| 69 | + @Override |
| 70 | + public void call(Pointer data, long len, Pointer arg) {} |
| 71 | + }.retainReference(); |
57 | 72 |
|
58 |
| - /** A reference to prevent deallocation. */ |
59 |
| - protected Pointer pointer; |
| 73 | + /** A reference to prevent deallocation. */ |
| 74 | + protected Pointer pointer; |
60 | 75 |
|
61 |
| - public AbstractTF_Tensor(Pointer p) { super(p); } |
| 76 | + public AbstractTF_Tensor(Pointer p) { |
| 77 | + super(p); |
| 78 | + } |
62 | 79 |
|
63 |
| - /** |
64 |
| - * Calls TF_NewTensor(), and registers a deallocator. |
65 |
| - * @return TF_Tensor created. Do not call TF_DeleteTensor() on it. |
66 |
| - */ |
67 |
| - public static TF_Tensor newTensor(int dtype, long[] dims, Pointer data) { |
68 |
| - TF_Tensor t = TF_NewTensor(dtype, dims, dims.length, data, data.limit(), dummyDeallocator, null); |
69 |
| - if (t != null) { |
70 |
| - t.pointer = data; |
71 |
| - t.deallocator(new DeleteDeallocator(t)); |
72 |
| - } |
73 |
| - return t; |
| 80 | + /** |
| 81 | + * Calls TF_NewTensor(), and registers a deallocator. |
| 82 | + * |
| 83 | + * @return TF_Tensor created. Do not call TF_DeleteTensor() on it. |
| 84 | + */ |
| 85 | + public static TF_Tensor newTensor(int dtype, long[] dims, Pointer data) { |
| 86 | + TF_Tensor t = |
| 87 | + TF_NewTensor(dtype, dims, dims.length, data, data.limit(), dummyDeallocator, null); |
| 88 | + if (t != null) { |
| 89 | + t.pointer = data; |
| 90 | + t.deallocator(new DeleteDeallocator(t)); |
74 | 91 | }
|
| 92 | + return t; |
| 93 | + } |
75 | 94 |
|
76 |
| - /** |
77 |
| - * Calls TF_AllocateTensor(), and registers a deallocator. |
78 |
| - * @return TF_Tensor created. Do not call TF_DeleteTensor() on it. |
79 |
| - */ |
80 |
| - public static TF_Tensor allocateTensor(int dtype, long[] dims, long length) { |
81 |
| - TF_Tensor t = TF_AllocateTensor(dtype, dims, dims.length, length); |
82 |
| - if (t != null) { |
83 |
| - if (TF_TensorType(t) == TF_STRING) { |
84 |
| - // we need to initialize the strings themselves after allocating the tensor memory |
85 |
| - long n = TF_TensorElementCount(t); |
86 |
| - TF_TString data = new TF_TString(TF_TensorData(t)); |
87 |
| - for (int i = 0; i < n; i++) { |
88 |
| - TF_TString_Init(data.position(i)); |
89 |
| - } |
90 |
| - } |
91 |
| - t.deallocator(new DeleteDeallocator(t)); |
| 95 | + /** |
| 96 | + * Calls TF_AllocateTensor(), and registers a deallocator. |
| 97 | + * |
| 98 | + * @return TF_Tensor created. Do not call TF_DeleteTensor() on it. |
| 99 | + */ |
| 100 | + public static TF_Tensor allocateTensor(int dtype, long[] dims, long length) { |
| 101 | + TF_Tensor t = TF_AllocateTensor(dtype, dims, dims.length, length); |
| 102 | + if (t != null) { |
| 103 | + if (TF_TensorType(t) == TF_STRING) { |
| 104 | + // we need to initialize the strings themselves after allocating the tensor memory |
| 105 | + long n = TF_TensorElementCount(t); |
| 106 | + TF_TString data = new TF_TString(TF_TensorData(t)); |
| 107 | + for (int i = 0; i < n; i++) { |
| 108 | + TF_TString_Init(data.position(i)); |
92 | 109 | }
|
93 |
| - return t; |
| 110 | + } |
| 111 | + t.deallocator(new DeleteDeallocator(t)); |
94 | 112 | }
|
| 113 | + return t; |
| 114 | + } |
95 | 115 |
|
96 |
| - /** Registers a deallocator and returns this. */ |
97 |
| - public TF_Tensor withDeallocator() { |
98 |
| - return (TF_Tensor)this.deallocator(new DeleteDeallocator((TF_Tensor)this)); |
99 |
| - } |
| 116 | + /** Registers a deallocator and returns this. */ |
| 117 | + public TF_Tensor withDeallocator() { |
| 118 | + return (TF_Tensor) this.deallocator(new DeleteDeallocator((TF_Tensor) this)); |
| 119 | + } |
100 | 120 |
|
101 |
| - /** |
102 |
| - * Calls the deallocator, if registered, otherwise has no effect. |
103 |
| - */ |
104 |
| - public void delete() { |
105 |
| - deallocate(); |
106 |
| - } |
| 121 | + /** Calls the deallocator, if registered, otherwise has no effect. */ |
| 122 | + public void delete() { |
| 123 | + deallocate(); |
| 124 | + } |
107 | 125 | }
|
0 commit comments