UNPKG

82.3 kBJavaScriptView Raw
1/**
2 * @license
3 * Copyright 2017 Google LLC. All Rights Reserved.
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 *
8 * http://www.apache.org/licenses/LICENSE-2.0
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 */
17import * as tf from './index';
18import { ALL_ENVS, describeWithFlags, SYNC_BACKEND_ENVS } from './jasmine_util';
19import { tensor5d } from './ops/ops';
20import { Tensor } from './tensor';
21import { encodeStrings, expectArraysClose, expectArraysEqual, expectNumbersClose } from './test_util';
22import { encodeString } from './util';
23describeWithFlags('tensor', ALL_ENVS, () => {
24 it('Tensors of arbitrary size', async () => {
25 // [1, 2, 3]
26 let t = tf.tensor1d([1, 2, 3]);
27 expect(t.rank).toBe(1);
28 expect(t.size).toBe(3);
29 expectArraysClose(await t.data(), [1, 2, 3]);
30 // [[1, 2, 3]]
31 t = tf.tensor2d([1, 2, 3], [1, 3]);
32 expect(t.rank).toBe(2);
33 expect(t.size).toBe(3);
34 expectArraysClose(await t.data(), [1, 2, 3]);
35 // [[1, 2, 3],
36 // [4, 5, 6]]
37 t = tf.tensor2d([1, 2, 3, 4, 5, 6], [2, 3]);
38 expect(t.rank).toBe(2);
39 expect(t.size).toBe(6);
40 expectArraysClose(await t.data(), [1, 2, 3, 4, 5, 6]);
41 // Shape mismatch with the values.
42 expect(() => tf.tensor2d([1], [1, 2])).toThrowError();
43 });
44 it('Tensors of explicit size', async () => {
45 const t = tf.tensor1d([5, 3, 2]);
46 expect(t.rank).toBe(1);
47 expect(t.shape).toEqual([3]);
48 // tslint:disable-next-line:no-any
49 expect(() => tf.tensor3d([1, 2], [1, 2, 3, 5])).toThrowError();
50 const t4 = tf.tensor4d([1, 2, 3, 4], [1, 2, 1, 2]);
51 expectArraysClose(await t4.data(), [1, 2, 3, 4]);
52 // Tensor of ones.
53 const x = tf.ones([3, 4, 2]);
54 expect(x.rank).toBe(3);
55 expect(x.size).toBe(24);
56 expectArraysClose(await x.data(), [
57 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
58 ]);
59 // Tensor of zeros.
60 const z = tf.zeros([3, 4, 2]);
61 expect(z.rank).toBe(3);
62 expect(z.size).toBe(24);
63 expectArraysClose(await z.data(), [
64 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
65 ]);
66 });
67 it('Tensor dataSync CPU --> GPU', async () => {
68 const a = tf.tensor2d([1, 2, 3, 4, 5, 6], [3, 2]);
69 expectArraysClose(await a.data(), new Float32Array([1, 2, 3, 4, 5, 6]));
70 });
71 it('Tensor.data() CPU --> GPU', async () => {
72 const a = tf.tensor2d([1, 2, 3, 4, 5, 6], [3, 2]);
73 expectArraysClose(await a.data(), new Float32Array([1, 2, 3, 4, 5, 6]));
74 });
75 it('Tensor.data() packed CPU --> GPU', async () => {
76 const a = tf.tensor2d([1, 2, 3, 4, 5, 6], [3, 2]);
77 tf.matMul(a, tf.tensor2d([1, 2], [2, 1]));
78 expectArraysClose(await a.data(), new Float32Array([1, 2, 3, 4, 5, 6]));
79 });
80 it('Scalar basic methods', async () => {
81 const a = tf.scalar(5);
82 expectArraysClose(await a.data(), [5]);
83 expect(a.rank).toBe(0);
84 expect(a.size).toBe(1);
85 expect(a.shape).toEqual([]);
86 });
87 it('indexToLoc Scalar', async () => {
88 const a = await tf.scalar(0).buffer();
89 expect(a.indexToLoc(0)).toEqual([]);
90 const b = await tf.zeros([]).buffer();
91 expect(b.indexToLoc(0)).toEqual([]);
92 });
93 it('indexToLoc Tensor1D', async () => {
94 const a = await tf.zeros([3]).buffer();
95 expect(a.indexToLoc(0)).toEqual([0]);
96 expect(a.indexToLoc(1)).toEqual([1]);
97 expect(a.indexToLoc(2)).toEqual([2]);
98 const b = await tf.zeros([3]).buffer();
99 expect(b.indexToLoc(0)).toEqual([0]);
100 expect(b.indexToLoc(1)).toEqual([1]);
101 expect(b.indexToLoc(2)).toEqual([2]);
102 });
103 it('indexToLoc Tensor2D', async () => {
104 const a = await tf.zeros([3, 2]).buffer();
105 expect(a.indexToLoc(0)).toEqual([0, 0]);
106 expect(a.indexToLoc(1)).toEqual([0, 1]);
107 expect(a.indexToLoc(2)).toEqual([1, 0]);
108 expect(a.indexToLoc(3)).toEqual([1, 1]);
109 expect(a.indexToLoc(4)).toEqual([2, 0]);
110 expect(a.indexToLoc(5)).toEqual([2, 1]);
111 const b = await tf.zeros([3, 2]).buffer();
112 expect(b.indexToLoc(0)).toEqual([0, 0]);
113 expect(b.indexToLoc(1)).toEqual([0, 1]);
114 expect(b.indexToLoc(2)).toEqual([1, 0]);
115 expect(b.indexToLoc(3)).toEqual([1, 1]);
116 expect(b.indexToLoc(4)).toEqual([2, 0]);
117 expect(b.indexToLoc(5)).toEqual([2, 1]);
118 });
119 it('indexToLoc Tensor3D', async () => {
120 const a = await tf.zeros([3, 2, 2]).buffer();
121 expect(a.indexToLoc(0)).toEqual([0, 0, 0]);
122 expect(a.indexToLoc(1)).toEqual([0, 0, 1]);
123 expect(a.indexToLoc(2)).toEqual([0, 1, 0]);
124 expect(a.indexToLoc(3)).toEqual([0, 1, 1]);
125 expect(a.indexToLoc(4)).toEqual([1, 0, 0]);
126 expect(a.indexToLoc(5)).toEqual([1, 0, 1]);
127 expect(a.indexToLoc(11)).toEqual([2, 1, 1]);
128 const b = await tf.zeros([3, 2, 2]).buffer();
129 expect(b.indexToLoc(0)).toEqual([0, 0, 0]);
130 expect(b.indexToLoc(1)).toEqual([0, 0, 1]);
131 expect(b.indexToLoc(2)).toEqual([0, 1, 0]);
132 expect(b.indexToLoc(3)).toEqual([0, 1, 1]);
133 expect(b.indexToLoc(4)).toEqual([1, 0, 0]);
134 expect(b.indexToLoc(5)).toEqual([1, 0, 1]);
135 expect(b.indexToLoc(11)).toEqual([2, 1, 1]);
136 });
137 it('indexToLoc Tensor 5D', async () => {
138 const values = new Float32Array([1, 2, 3, 4]);
139 const a = await tensor5d(values, [2, 1, 1, 1, 2]).buffer();
140 expect(a.indexToLoc(0)).toEqual([0, 0, 0, 0, 0]);
141 expect(a.indexToLoc(1)).toEqual([0, 0, 0, 0, 1]);
142 expect(a.indexToLoc(2)).toEqual([1, 0, 0, 0, 0]);
143 expect(a.indexToLoc(3)).toEqual([1, 0, 0, 0, 1]);
144 });
145 it('locToIndex Scalar', async () => {
146 const a = await tf.scalar(0).buffer();
147 expect(a.locToIndex([])).toEqual(0);
148 const b = await tf.zeros([]).buffer();
149 expect(b.locToIndex([])).toEqual(0);
150 });
151 it('locToIndex Tensor1D', async () => {
152 const a = await tf.zeros([3]).buffer();
153 expect(a.locToIndex([0])).toEqual(0);
154 expect(a.locToIndex([1])).toEqual(1);
155 expect(a.locToIndex([2])).toEqual(2);
156 const b = await tf.zeros([3]).buffer();
157 expect(b.locToIndex([0])).toEqual(0);
158 expect(b.locToIndex([1])).toEqual(1);
159 expect(b.locToIndex([2])).toEqual(2);
160 });
161 it('locToIndex Tensor2D', async () => {
162 const a = await tf.zeros([3, 2]).buffer();
163 expect(a.locToIndex([0, 0])).toEqual(0);
164 expect(a.locToIndex([0, 1])).toEqual(1);
165 expect(a.locToIndex([1, 0])).toEqual(2);
166 expect(a.locToIndex([1, 1])).toEqual(3);
167 expect(a.locToIndex([2, 0])).toEqual(4);
168 expect(a.locToIndex([2, 1])).toEqual(5);
169 const b = await tf.zeros([3, 2]).buffer();
170 expect(b.locToIndex([0, 0])).toEqual(0);
171 expect(b.locToIndex([0, 1])).toEqual(1);
172 expect(b.locToIndex([1, 0])).toEqual(2);
173 expect(b.locToIndex([1, 1])).toEqual(3);
174 expect(b.locToIndex([2, 0])).toEqual(4);
175 expect(b.locToIndex([2, 1])).toEqual(5);
176 });
177 it('locToIndex Tensor3D', async () => {
178 const a = await tf.zeros([3, 2, 2]).buffer();
179 expect(a.locToIndex([0, 0, 0])).toEqual(0);
180 expect(a.locToIndex([0, 0, 1])).toEqual(1);
181 expect(a.locToIndex([0, 1, 0])).toEqual(2);
182 expect(a.locToIndex([0, 1, 1])).toEqual(3);
183 expect(a.locToIndex([1, 0, 0])).toEqual(4);
184 expect(a.locToIndex([1, 0, 1])).toEqual(5);
185 expect(a.locToIndex([2, 1, 1])).toEqual(11);
186 const b = await tf.zeros([3, 2, 2]).buffer();
187 expect(b.locToIndex([0, 0, 0])).toEqual(0);
188 expect(b.locToIndex([0, 0, 1])).toEqual(1);
189 expect(b.locToIndex([0, 1, 0])).toEqual(2);
190 expect(b.locToIndex([0, 1, 1])).toEqual(3);
191 expect(b.locToIndex([1, 0, 0])).toEqual(4);
192 expect(b.locToIndex([1, 0, 1])).toEqual(5);
193 expect(b.locToIndex([2, 1, 1])).toEqual(11);
194 });
195 it('Tensor assignability (asserts compiler)', () => {
196 // This test asserts compilation, not doing any run-time assertion.
197 const a = null;
198 const b = a;
199 expect(b).toBeNull();
200 const a1 = null;
201 const b1 = a1;
202 expect(b1).toBeNull();
203 const a2 = null;
204 const b2 = a2;
205 expect(b2).toBeNull();
206 const a3 = null;
207 const b3 = a3;
208 expect(b3).toBeNull();
209 const a4 = null;
210 const b4 = a4;
211 expect(b4).toBeNull();
212 });
213 it('tf.tensor1d() from number[]', async () => {
214 const a = tf.tensor1d([1, 2, 3]);
215 expectArraysClose(await a.data(), [1, 2, 3]);
216 });
217 it('tf.tensor1d() throw error with null input value', () => {
218 expect(() => tf.tensor1d(null))
219 .toThrowError('The input to the tensor constructor ' +
220 'must be a non-null value.');
221 });
222 it('tf.tensor1d() from string[]', async () => {
223 const a = tf.tensor1d(['aa', 'bb', 'cc']);
224 expect(a.dtype).toBe('string');
225 expect(a.shape).toEqual([3]);
226 expectArraysEqual(await a.data(), ['aa', 'bb', 'cc']);
227 });
228 it('tf.tensor1d() from encoded strings', async () => {
229 const bytes = encodeStrings(['aa', 'bb', 'cc']);
230 const a = tf.tensor1d(bytes, 'string');
231 expect(a.dtype).toBe('string');
232 expect(a.shape).toEqual([3]);
233 expectArraysEqual(await a.data(), ['aa', 'bb', 'cc']);
234 });
235 it('tf.tensor1d() from encoded strings without dtype errors', async () => {
236 // We do not want to infer 'string' when the user passes Uint8Array in order
237 // to be forward compatible in the future when we add uint8 dtype.
238 const bytes = encodeStrings(['aa', 'bb', 'cc']);
239 expect(() => tf.tensor1d(bytes)).toThrowError();
240 });
241 it('tf.tensor1d() from encoded strings, shape mismatch', () => {
242 const bytes = encodeStrings([['aa'], ['bb'], ['cc']]);
243 expect(() => tf.tensor1d(bytes)).toThrowError();
244 });
245 it('tf.tensor1d() from number[][], shape mismatch', () => {
246 // tslint:disable-next-line:no-any
247 expect(() => tf.tensor1d([[1], [2], [3]])).toThrowError();
248 });
249 it('tf.tensor1d() from string[][], shape mismatch', () => {
250 // tslint:disable-next-line:no-any
251 expect(() => tf.tensor1d([['a'], ['b'], ['c']])).toThrowError();
252 });
253 it('tf.tensor2d() from number[][]', async () => {
254 const a = tf.tensor2d([[1, 2, 3], [4, 5, 6]], [2, 3]);
255 expectArraysClose(await a.data(), [1, 2, 3, 4, 5, 6]);
256 });
257 it('tf.tensor2d() from string[][]', async () => {
258 const a = tf.tensor2d([['aa', 'bb'], ['cc', 'dd']]);
259 expect(a.dtype).toBe('string');
260 expect(a.shape).toEqual([2, 2]);
261 expectArraysEqual(await a.data(), ['aa', 'bb', 'cc', 'dd']);
262 });
263 it('tf.tensor2d() from encoded strings', async () => {
264 const bytes = encodeStrings([['aa', 'bb'], ['cc', 'dd']]);
265 const a = tf.tensor2d(bytes, [2, 2], 'string');
266 expect(a.dtype).toBe('string');
267 expect(a.shape).toEqual([2, 2]);
268 expectArraysEqual(await a.data(), ['aa', 'bb', 'cc', 'dd']);
269 });
270 it('tf.tensor2d() from encoded strings without dtype errors', async () => {
271 // We do not want to infer 'string' when the user passes Uint8Array in order
272 // to be forward compatible in the future when we add uint8 dtype.
273 const bytes = encodeStrings([['aa', 'bb'], ['cc', 'dd']]);
274 expect(() => tf.tensor2d(bytes)).toThrowError();
275 });
276 it('tf.tensor2d() from encoded strings, shape mismatch', () => {
277 const bytes = encodeStrings([['aa', 'bb'], ['cc', 'dd']]);
278 expect(() => tf.tensor2d(bytes, [3, 2], 'string')).toThrowError();
279 });
280 it('tf.tensor2d() requires shape to be of length 2', () => {
281 // tslint:disable-next-line:no-any
282 const shape = [4];
283 expect(() => tf.tensor2d([1, 2, 3, 4], shape)).toThrowError();
284 });
285 it('tf.tensor2d() from number[][], but shape does not match', () => {
286 // Actual shape is [2, 3].
287 expect(() => tf.tensor2d([[1, 2, 3], [4, 5, 6]], [3, 2])).toThrowError();
288 });
289 it('tf.tensor2d() from string[][], but shape does not match', () => {
290 // Actual shape is [2, 3].
291 const vals = [['a', 'b', 'c'], ['d', 'e', 'f']];
292 expect(() => tf.tensor2d(vals, [3, 2])).toThrowError();
293 });
294 it('tf.tensor2d() from number[], but no shape throws error', () => {
295 expect(() => tf.tensor2d([1, 2, 3, 4])).toThrowError();
296 });
297 it('tf.tensor2d() from string[], but no shape throws error', () => {
298 expect(() => tf.tensor2d(['a', 'b', 'c', 'd'])).toThrowError();
299 });
300 it('tf.tensor2d() throw error with null input value', () => {
301 expect(() => tf.tensor2d(null))
302 .toThrowError('The input to the tensor constructor ' +
303 'must be a non-null value.');
304 });
305 it('tensor3d() from number[][][]', async () => {
306 const a = tf.tensor3d([[[1], [2], [3]], [[4], [5], [6]]], [2, 3, 1]);
307 expectArraysClose(await a.data(), [1, 2, 3, 4, 5, 6]);
308 });
309 it('tensor3d() from string[][][]', async () => {
310 const vals = [[['a'], ['b'], ['c']], [['d'], ['e'], ['f']]];
311 const a = tf.tensor3d(vals, [2, 3, 1]);
312 expect(a.dtype).toBe('string');
313 expect(a.shape).toEqual([2, 3, 1]);
314 expectArraysEqual(await a.data(), ['a', 'b', 'c', 'd', 'e', 'f']);
315 });
316 it('tf.tensor3d() from encoded strings', async () => {
317 const bytes = encodeStrings([[['a'], ['b'], ['c']], [['d'], ['e'], ['f']]]);
318 const a = tf.tensor3d(bytes, [2, 3, 1], 'string');
319 expect(a.dtype).toBe('string');
320 expect(a.shape).toEqual([2, 3, 1]);
321 expectArraysEqual(await a.data(), ['a', 'b', 'c', 'd', 'e', 'f']);
322 });
323 it('tf.tensor3d() from encoded strings without dtype errors', async () => {
324 // We do not want to infer 'string' when the user passes Uint8Array in order
325 // to be forward compatible in the future when we add uint8 dtype.
326 const bytes = encodeStrings([[['a'], ['b'], ['c']], [['d'], ['e'], ['f']]]);
327 expect(() => tf.tensor3d(bytes)).toThrowError();
328 });
329 it('tf.tensor3d() from encoded strings, shape mismatch', () => {
330 const bytes = encodeStrings([[['a'], ['b'], ['c']], [['d'], ['e'], ['f']]]);
331 // Actual shape is [2, 3, 1].
332 expect(() => tf.tensor3d(bytes, [3, 2, 1], 'string'))
333 .toThrowError();
334 });
335 it('tensor3d() from number[][][], but shape does not match', () => {
336 const values = [[[1], [2], [3]], [[4], [5], [6]]];
337 // Actual shape is [2, 3, 1].
338 expect(() => tf.tensor3d(values, [3, 2, 1])).toThrowError();
339 });
340 it('tf.tensor3d() from number[], but no shape throws error', () => {
341 expect(() => tf.tensor3d([1, 2, 3, 4])).toThrowError();
342 });
343 it('tf.tensor3d() requires shape to be of length 3', () => {
344 // tslint:disable-next-line:no-any
345 const shape = [4, 1];
346 expect(() => tf.tensor3d([1, 2, 3, 4], shape)).toThrowError();
347 });
348 it('tf.tensor3d() throw error with null input value', () => {
349 expect(() => tf.tensor3d(null))
350 .toThrowError('The input to the tensor constructor ' +
351 'must be a non-null value.');
352 });
353 it('tensor4d() from number[][][][]', async () => {
354 const a = tf.tensor4d([[[[1]], [[2]]], [[[4]], [[5]]]], [2, 2, 1, 1]);
355 expectArraysClose(await a.data(), [1, 2, 4, 5]);
356 });
357 it('tensor4d() from string[][][][]', async () => {
358 const vals = [[[['a']], [['b']]], [[['c']], [['d']]]];
359 const a = tf.tensor4d(vals, [2, 2, 1, 1]);
360 expect(a.dtype).toBe('string');
361 expect(a.shape).toEqual([2, 2, 1, 1]);
362 expectArraysEqual(await a.data(), ['a', 'b', 'c', 'd']);
363 });
364 it('tf.tensor4d() from encoded strings', async () => {
365 const bytes = encodeStrings([[[['a']], [['b']]], [[['c']], [['d']]]]);
366 const a = tf.tensor4d(bytes, [2, 2, 1, 1], 'string');
367 expect(a.dtype).toBe('string');
368 expect(a.shape).toEqual([2, 2, 1, 1]);
369 expectArraysEqual(await a.data(), ['a', 'b', 'c', 'd']);
370 });
371 it('tf.tensor4d() from encoded strings without dtype errors', async () => {
372 // We do not want to infer 'string' when the user passes Uint8Array in order
373 // to be forward compatible in the future when we add uint8 dtype.
374 const bytes = encodeStrings([[[['a']], [['b']]], [[['c']], [['d']]]]);
375 expect(() => tf.tensor4d(bytes)).toThrowError();
376 });
377 it('tf.tensor4d() from encoded strings, shape mismatch', () => {
378 const bytes = encodeStrings([[[['a']], [['b']]], [[['c']], [['d']]]]);
379 // Actual shape is [2, 2, 1. 1].
380 expect(() => tf.tensor4d(bytes, [2, 1, 2, 1], 'string'))
381 .toThrowError();
382 });
383 it('tensor4d() from string[][][][] infer shape', async () => {
384 const vals = [[[['a']], [['b']]], [[['c']], [['d']]]];
385 const a = tf.tensor4d(vals);
386 expect(a.dtype).toBe('string');
387 expect(a.shape).toEqual([2, 2, 1, 1]);
388 expectArraysEqual(await a.data(), ['a', 'b', 'c', 'd']);
389 });
390 it('tensor4d() from number[][][][], but shape does not match', () => {
391 const f = () => {
392 // Actual shape is [2, 2, 1, 1].
393 tf.tensor4d([[[[1]], [[2]]], [[[4]], [[5]]]], [2, 1, 2, 1]);
394 };
395 expect(f).toThrowError();
396 });
397 it('tf.tensor4d() from number[], but no shape throws error', () => {
398 expect(() => tf.tensor4d([1, 2, 3, 4])).toThrowError();
399 });
400 it('tf.tensor4d() requires shape to be of length 4', () => {
401 // tslint:disable-next-line:no-any
402 const shape = [4, 1];
403 expect(() => tf.tensor4d([1, 2, 3, 4], shape)).toThrowError();
404 });
405 it('tf.tensor4d() throw error with null input value', () => {
406 expect(() => tf.tensor4d(null))
407 .toThrowError('The input to the tensor constructor ' +
408 'must be a non-null value.');
409 });
410 it('tf.tensor5d() throw error with null input value', () => {
411 expect(() => tf.tensor5d(null))
412 .toThrowError('The input to the tensor constructor ' +
413 'must be a non-null value.');
414 });
415 it('tf.tensor6d() throw error with null input value', () => {
416 expect(() => tf.tensor6d(null))
417 .toThrowError('The input to the tensor constructor ' +
418 'must be a non-null value.');
419 });
420 it('default dtype', async () => {
421 const a = tf.scalar(3);
422 expect(a.dtype).toBe('float32');
423 expectArraysClose(await a.data(), 3);
424 });
425 it('float32 dtype', async () => {
426 const a = tf.scalar(3, 'float32');
427 expect(a.dtype).toBe('float32');
428 expectArraysClose(await a.data(), 3);
429 });
430 it('int32 dtype', async () => {
431 const a = tf.scalar(3, 'int32');
432 expect(a.dtype).toBe('int32');
433 expectArraysEqual(await a.data(), 3);
434 });
435 it('int32 dtype, 3.9 => 3, like numpy', async () => {
436 const a = tf.scalar(3.9, 'int32');
437 expect(a.dtype).toBe('int32');
438 expectArraysEqual(await a.data(), 3);
439 });
440 it('int32 dtype, -3.9 => -3, like numpy', async () => {
441 const a = tf.scalar(-3.9, 'int32');
442 expect(a.dtype).toBe('int32');
443 expectArraysEqual(await a.data(), -3);
444 });
445 it('bool dtype, 3 => true, like numpy', async () => {
446 const a = tf.scalar(3, 'bool');
447 expect(a.dtype).toBe('bool');
448 expectArraysEqual(await a.data(), 1);
449 });
450 it('bool dtype, -2 => true, like numpy', async () => {
451 const a = tf.scalar(-2, 'bool');
452 expect(a.dtype).toBe('bool');
453 expectArraysEqual(await a.data(), 1);
454 });
455 it('bool dtype, 0 => false, like numpy', async () => {
456 const a = tf.scalar(0, 'bool');
457 expect(a.dtype).toBe('bool');
458 expectArraysEqual(await a.data(), 0);
459 });
460 it('bool dtype from boolean', async () => {
461 const a = tf.scalar(false, 'bool');
462 expectArraysEqual(await a.data(), 0);
463 expect(a.dtype).toBe('bool');
464 const b = tf.scalar(true, 'bool');
465 expectArraysEqual(await a.data(), 0);
466 expect(b.dtype).toBe('bool');
467 });
468 it('int32 dtype from boolean', async () => {
469 const a = tf.scalar(true, 'int32');
470 expectArraysEqual(await a.data(), 1);
471 expect(a.dtype).toBe('int32');
472 });
473 it('default dtype from boolean', async () => {
474 const a = tf.scalar(false);
475 expectArraysEqual(await a.data(), 0);
476 expect(a.dtype).toBe('bool');
477 });
478 it('default dtype', async () => {
479 const a = tf.tensor1d([1, 2, 3]);
480 expect(a.dtype).toBe('float32');
481 expect(a.shape).toEqual([3]);
482 expectArraysClose(await a.data(), [1, 2, 3]);
483 });
484 it('float32 dtype', async () => {
485 const a = tf.tensor1d([1, 2, 3], 'float32');
486 expect(a.dtype).toBe('float32');
487 expect(a.shape).toEqual([3]);
488 expectArraysClose(await a.data(), [1, 2, 3]);
489 });
490 it('int32 dtype', async () => {
491 const a = tf.tensor1d([1, 2, 3], 'int32');
492 expect(a.dtype).toBe('int32');
493 expect(a.shape).toEqual([3]);
494 expectArraysEqual(await a.data(), [1, 2, 3]);
495 });
496 it('int32 dtype, non-ints get floored, like numpy', async () => {
497 const a = tf.tensor1d([1.1, 2.5, 3.9], 'int32');
498 expect(a.dtype).toBe('int32');
499 expect(a.shape).toEqual([3]);
500 expectArraysEqual(await a.data(), [1, 2, 3]);
501 });
502 it('int32 dtype, negative non-ints get ceiled, like numpy', async () => {
503 const a = tf.tensor1d([-1.1, -2.5, -3.9], 'int32');
504 expect(a.dtype).toBe('int32');
505 expect(a.shape).toEqual([3]);
506 expectArraysEqual(await a.data(), [-1, -2, -3]);
507 });
508 it('bool dtype, !=0 is truthy, 0 is falsy, like numpy', async () => {
509 const a = tf.tensor1d([1, -2, 0, 3], 'bool');
510 expect(a.dtype).toBe('bool');
511 expect(a.shape).toEqual([4]);
512 expectArraysEqual(await a.data(), [1, 1, 0, 1]);
513 });
514 it('default dtype from boolean[]', async () => {
515 const a = tf.tensor1d([false, false, true]);
516 expect(a.dtype).toBe('bool');
517 expectArraysClose(await a.data(), [0, 0, 1]);
518 });
519 it('default dtype from UInt8Array', async () => {
520 const a = tf.tensor1d(new Uint8Array([1, 5, 2]));
521 expect(a.dtype).toBe('int32');
522 expect(a.shape).toEqual([3]);
523 expectArraysClose(await a.data(), [1, 5, 2]);
524 });
525 it('default dtype from Int32Array', async () => {
526 const a = tf.tensor1d(new Int32Array([1, 5, 2]));
527 expect(a.dtype).toBe('int32');
528 expect(a.shape).toEqual([3]);
529 expectArraysClose(await a.data(), [1, 5, 2]);
530 });
531 it('tf.tensor() from Float32Array and number[]', async () => {
532 const a = tf.tensor([
533 new Float32Array([1, 2]), new Float32Array([3, 4]),
534 new Float32Array([5, 6]), [7, 8]
535 ]);
536 expect(a.dtype).toBe('float32');
537 expect(a.shape).toEqual([4, 2]);
538 expectArraysClose(await a.data(), [1, 2, 3, 4, 5, 6, 7, 8]);
539 });
540 it('tf.tensor() from Int32Array and number[]', async () => {
541 const a = tf.tensor([
542 new Int32Array([1, 2]), new Int32Array([3, 4]), new Int32Array([5, 6]),
543 [7, 8]
544 ]);
545 expect(a.dtype).toBe('int32');
546 expect(a.shape).toEqual([4, 2]);
547 expectArraysClose(await a.data(), [1, 2, 3, 4, 5, 6, 7, 8]);
548 });
549 it('tf.tensor() from mixed TypedArray', async () => {
550 const a = tf.tensor([
551 new Float32Array([1, 2]), new Int32Array([3, 4]), new Uint8Array([5, 6]),
552 [7, 8]
553 ]);
554 expect(a.dtype).toBe('float32');
555 expect(a.shape).toEqual([4, 2]);
556 expectArraysClose(await a.data(), [1, 2, 3, 4, 5, 6, 7, 8]);
557 });
558 it('tf.tensor() from TypedArrays which are themselves 3D', () => {
559 // 2 tensors, each with shape 20x20x3, as flat Float32Arrays.
560 const img1 = new Float32Array(20 * 20 * 3);
561 const img2 = new Float32Array(20 * 20 * 3);
562 const t = tf.tensor([img1, img2], [2, 20, 20, 3]);
563 expect(t.dtype).toBe('float32');
564 expect(t.shape).toEqual([2, 20, 20, 3]);
565 });
566 it('tf.tensor() from TypedArrays which are themselves 3D, wrong shape', () => {
567 const img1 = new Float32Array(20 * 20 * 3);
568 const img2 = new Float32Array(20 * 20 * 3);
569 expect(() => tf.tensor([img1, img2], [3, 20, 20, 3])).toThrowError();
570 });
571 it('default dtype from ascii string', async () => {
572 const a = tf.tensor('hello');
573 expect(a.dtype).toBe('string');
574 expect(a.shape).toEqual([]);
575 expectArraysEqual(await a.data(), ['hello']);
576 });
577 it('default dtype from utf-8 string', async () => {
578 const a = tf.tensor('даниел');
579 expect(a.dtype).toBe('string');
580 expect(a.shape).toEqual([]);
581 expectArraysEqual(await a.data(), ['даниел']);
582 });
583 it('default dtype from empty string', async () => {
584 const a = tf.tensor('');
585 expect(a.dtype).toBe('string');
586 expect(a.shape).toEqual([]);
587 expectArraysEqual(await a.data(), ['']);
588 });
589 it('default dtype from unicode escaped string', async () => {
590 const a = tf.tensor('\u0434\u0430\u043d\u0438\u0435\u043b');
591 expect(a.dtype).toBe('string');
592 expect(a.shape).toEqual([]);
593 expectArraysEqual(await a.data(), ['даниел']);
594 });
595 it('default dtype from string[]', async () => {
596 const a = tf.tensor(['a', 'b']);
597 expect(a.dtype).toBe('string');
598 expect(a.shape).toEqual([2]);
599 expectArraysEqual(await a.data(), ['a', 'b']);
600 });
601 it('float32 dtype from boolean[]', async () => {
602 const a = tf.tensor1d([false, false, true], 'float32');
603 expect(a.dtype).toBe('float32');
604 expectArraysClose(await a.data(), [0, 0, 1]);
605 });
606 it('int32 dtype from boolean[]', async () => {
607 const a = tf.tensor1d([false, false, true], 'int32');
608 expect(a.dtype).toBe('int32');
609 expectArraysEqual(await a.data(), [0, 0, 1]);
610 });
611 it('bool dtype from boolean[]', async () => {
612 const a = tf.tensor1d([false, false, true], 'bool');
613 expect(a.dtype).toBe('bool');
614 expectArraysEqual(await a.data(), [0, 0, 1]);
615 });
616 it('default dtype', async () => {
617 const a = tf.tensor2d([1, 2, 3, 4], [2, 2]);
618 expect(a.dtype).toBe('float32');
619 expect(a.shape).toEqual([2, 2]);
620 expectArraysClose(await a.data(), [1, 2, 3, 4]);
621 });
622 it('float32 dtype', async () => {
623 const a = tf.tensor2d([1, 2, 3, 4], [2, 2], 'float32');
624 expect(a.dtype).toBe('float32');
625 expect(a.shape).toEqual([2, 2]);
626 expectArraysClose(await a.data(), [1, 2, 3, 4]);
627 });
628 it('int32 dtype', async () => {
629 const a = tf.tensor2d([[1, 2], [3, 4]], [2, 2], 'int32');
630 expect(a.dtype).toBe('int32');
631 expect(a.shape).toEqual([2, 2]);
632 expectArraysEqual(await a.data(), [1, 2, 3, 4]);
633 });
634 it('int32 dtype, non-ints get floored, like numpy', async () => {
635 const a = tf.tensor2d([1.1, 2.5, 3.9, 4.0], [2, 2], 'int32');
636 expect(a.dtype).toBe('int32');
637 expect(a.shape).toEqual([2, 2]);
638 expectArraysEqual(await a.data(), [1, 2, 3, 4]);
639 });
640 it('int32 dtype, negative non-ints get ceiled, like numpy', async () => {
641 const a = tf.tensor2d([-1.1, -2.5, -3.9, -4.0], [2, 2], 'int32');
642 expect(a.dtype).toBe('int32');
643 expect(a.shape).toEqual([2, 2]);
644 expectArraysEqual(await a.data(), [-1, -2, -3, -4]);
645 });
646 it('bool dtype, !=0 is truthy, 0 is falsy, like numpy', async () => {
647 const a = tf.tensor2d([1, -2, 0, 3], [2, 2], 'bool');
648 expect(a.dtype).toBe('bool');
649 expect(a.shape).toEqual([2, 2]);
650 expectArraysEqual(await a.data(), [1, 1, 0, 1]);
651 });
652 it('default dtype from boolean[]', async () => {
653 const a = tf.tensor2d([[false, false], [true, false]], [2, 2]);
654 expect(a.dtype).toBe('bool');
655 expectArraysClose(await a.data(), [0, 0, 1, 0]);
656 });
657 it('float32 dtype from boolean[]', async () => {
658 const a = tf.tensor2d([[false, false], [true, false]], [2, 2], 'float32');
659 expect(a.dtype).toBe('float32');
660 expectArraysEqual(await a.data(), [0, 0, 1, 0]);
661 });
662 it('int32 dtype from boolean[]', async () => {
663 const a = tf.tensor2d([[false, false], [true, false]], [2, 2], 'int32');
664 expect(a.dtype).toBe('int32');
665 expectArraysEqual(await a.data(), [0, 0, 1, 0]);
666 });
667 it('bool dtype from boolean[]', async () => {
668 const a = tf.tensor2d([[false, false], [true, false]], [2, 2], 'bool');
669 expect(a.dtype).toBe('bool');
670 expectArraysEqual(await a.data(), [0, 0, 1, 0]);
671 });
672 it('default dtype', async () => {
673 const a = tf.tensor3d([1, 2, 3, 4], [2, 2, 1]);
674 expect(a.dtype).toBe('float32');
675 expect(a.shape).toEqual([2, 2, 1]);
676 expectArraysClose(await a.data(), [1, 2, 3, 4]);
677 });
678 it('float32 dtype', async () => {
679 const a = tf.tensor3d([1, 2, 3, 4], [2, 2, 1], 'float32');
680 expect(a.dtype).toBe('float32');
681 expect(a.shape).toEqual([2, 2, 1]);
682 expectArraysClose(await a.data(), [1, 2, 3, 4]);
683 });
684 it('int32 dtype', async () => {
685 const a = tf.tensor3d([[[1], [2]], [[3], [4]]], [2, 2, 1], 'int32');
686 expect(a.dtype).toBe('int32');
687 expect(a.shape).toEqual([2, 2, 1]);
688 expectArraysEqual(await a.data(), [1, 2, 3, 4]);
689 });
690 it('int32 dtype, non-ints get floored, like numpy', async () => {
691 const a = tf.tensor3d([1.1, 2.5, 3.9, 4.0], [2, 2, 1], 'int32');
692 expect(a.dtype).toBe('int32');
693 expect(a.shape).toEqual([2, 2, 1]);
694 expectArraysEqual(await a.data(), [1, 2, 3, 4]);
695 });
696 it('int32 dtype, negative non-ints get ceiled, like numpy', async () => {
697 const a = tf.tensor3d([-1.1, -2.5, -3.9, -4.0], [2, 2, 1], 'int32');
698 expect(a.dtype).toBe('int32');
699 expect(a.shape).toEqual([2, 2, 1]);
700 expectArraysEqual(await a.data(), [-1, -2, -3, -4]);
701 });
702 it('bool dtype, !=0 is truthy, 0 is falsy, like numpy', async () => {
703 const a = tf.tensor3d([1, -2, 0, 3], [2, 2, 1], 'bool');
704 expect(a.dtype).toBe('bool');
705 expect(a.shape).toEqual([2, 2, 1]);
706 expectArraysEqual(await a.data(), [1, 1, 0, 1]);
707 });
708 it('default dtype from boolean[]', async () => {
709 const a = tf.tensor3d([[[false], [false]], [[true], [false]]], [2, 2, 1]);
710 expect(a.dtype).toBe('bool');
711 expectArraysClose(await a.data(), [0, 0, 1, 0]);
712 });
713 it('float32 dtype from boolean[]', async () => {
714 const a = tf.tensor3d([[[false], [false]], [[true], [false]]], [2, 2, 1], 'float32');
715 expect(a.dtype).toBe('float32');
716 expectArraysClose(await a.data(), [0, 0, 1, 0]);
717 });
718 it('int32 dtype from boolean[]', async () => {
719 const a = tf.tensor3d([[[false], [false]], [[true], [false]]], [2, 2, 1], 'int32');
720 expect(a.dtype).toBe('int32');
721 expectArraysEqual(await a.data(), [0, 0, 1, 0]);
722 });
723 it('bool dtype from boolean[]', async () => {
724 const a = tf.tensor3d([[[false], [false]], [[true], [false]]], [2, 2, 1], 'bool');
725 expect(a.dtype).toBe('bool');
726 expectArraysEqual(await a.data(), [0, 0, 1, 0]);
727 });
728 it('default dtype', async () => {
729 const a = tf.tensor4d([1, 2, 3, 4], [2, 2, 1, 1]);
730 expect(a.dtype).toBe('float32');
731 expect(a.shape).toEqual([2, 2, 1, 1]);
732 expectArraysClose(await a.data(), [1, 2, 3, 4]);
733 });
734 it('float32 dtype', async () => {
735 const a = tf.tensor4d([1, 2, 3, 4], [2, 2, 1, 1], 'float32');
736 expect(a.dtype).toBe('float32');
737 expect(a.shape).toEqual([2, 2, 1, 1]);
738 expectArraysClose(await a.data(), [1, 2, 3, 4]);
739 });
740 it('int32 dtype', async () => {
741 const a = tf.tensor4d([[[[1]], [[2]]], [[[3]], [[4]]]], [2, 2, 1, 1], 'int32');
742 expect(a.dtype).toBe('int32');
743 expect(a.shape).toEqual([2, 2, 1, 1]);
744 expectArraysEqual(await a.data(), [1, 2, 3, 4]);
745 });
746 it('int32 dtype, non-ints get floored, like numpy', async () => {
747 const a = tf.tensor4d([1.1, 2.5, 3.9, 4.0], [2, 2, 1, 1], 'int32');
748 expect(a.dtype).toBe('int32');
749 expect(a.shape).toEqual([2, 2, 1, 1]);
750 expectArraysEqual(await a.data(), [1, 2, 3, 4]);
751 });
752 it('int32 dtype, negative non-ints get ceiled, like numpy', async () => {
753 const a = tf.tensor4d([-1.1, -2.5, -3.9, -4.0], [2, 2, 1, 1], 'int32');
754 expect(a.dtype).toBe('int32');
755 expect(a.shape).toEqual([2, 2, 1, 1]);
756 expectArraysEqual(await a.data(), [-1, -2, -3, -4]);
757 });
758 it('bool dtype, !=0 is truthy, 0 is falsy, like numpy', async () => {
759 const a = tf.tensor4d([1, -2, 0, 3], [2, 2, 1, 1], 'bool');
760 expect(a.dtype).toBe('bool');
761 expect(a.shape).toEqual([2, 2, 1, 1]);
762 expectArraysEqual(await a.data(), [1, 1, 0, 1]);
763 });
764 it('default dtype from boolean[]', async () => {
765 const a = tf.tensor4d([[[[false], [false]], [[true], [false]]]], [1, 2, 2, 1]);
766 expect(a.dtype).toBe('bool');
767 expectArraysClose(await a.data(), [0, 0, 1, 0]);
768 });
769 it('float32 dtype from boolean[]', async () => {
770 const a = tf.tensor4d([[[[false], [false]], [[true], [false]]]], [1, 2, 2, 1], 'float32');
771 expect(a.dtype).toBe('float32');
772 expectArraysClose(await a.data(), [0, 0, 1, 0]);
773 });
774 it('int32 dtype from boolean[]', async () => {
775 const a = tf.tensor4d([[[[false], [false]], [[true], [false]]]], [1, 2, 2, 1], 'int32');
776 expect(a.dtype).toBe('int32');
777 expectArraysEqual(await a.data(), [0, 0, 1, 0]);
778 });
779 it('bool dtype from boolean[]', async () => {
780 const a = tf.tensor4d([[[[false], [false]], [[true], [false]]]], [1, 2, 2, 1], 'bool');
781 expect(a.dtype).toBe('bool');
782 expectArraysEqual(await a.data(), [0, 0, 1, 0]);
783 });
784 it('Scalar default dtype', async () => {
785 const a = tf.scalar(4);
786 const b = a.reshape([1, 1]);
787 expect(b.dtype).toBe('float32');
788 expect(b.shape).toEqual([1, 1]);
789 expectArraysClose(await a.data(), await b.data());
790 });
791 it('Scalar float32 dtype', () => {
792 const a = tf.scalar(4, 'float32');
793 const b = a.reshape([1, 1]);
794 expect(b.dtype).toBe('float32');
795 expect(b.shape).toEqual([1, 1]);
796 });
797 it('Scalar string dtype', () => {
798 const a = tf.scalar('test', 'string');
799 const b = a.reshape([1, 1]);
800 expect(b.dtype).toBe('string');
801 expect(b.shape).toEqual([1, 1]);
802 });
803 it('scalar from encoded string', async () => {
804 const a = tf.scalar(encodeString('hello'), 'string');
805 expect(a.dtype).toBe('string');
806 expect(a.shape).toEqual([]);
807 expectArraysEqual(await a.data(), ['hello']);
808 });
809 it('scalar from encoded string, but missing dtype', async () => {
810 // We do not want to infer 'string' when the user passes Uint8Array in order
811 // to be forward compatible in the future when we add uint8 dtype.
812 expect(() => tf.scalar(encodeString('hello'))).toThrowError();
813 });
814 it('scalar from encoded string, but value is not uint8array', async () => {
815 // tslint:disable-next-line:no-any
816 expect(() => tf.scalar(new Float32Array([1, 2, 3]))).toThrowError();
817 });
818 it('Scalar inferred dtype from bool', async () => {
819 const a = tf.scalar(true);
820 expect(a.dtype).toBe('bool');
821 expect(a.shape).toEqual([]);
822 expectArraysClose(await a.data(), [1]);
823 });
824 it('Scalar inferred dtype from string', async () => {
825 const a = tf.scalar('hello');
826 expect(a.dtype).toBe('string');
827 expect(a.shape).toEqual([]);
828 expectArraysEqual(await a.data(), ['hello']);
829 });
830 it('Scalar int32 dtype', () => {
831 const a = tf.scalar(4, 'int32');
832 const b = a.reshape([1, 1]);
833 expect(b.dtype).toBe('int32');
834 expect(b.shape).toEqual([1, 1]);
835 });
836 it('Scalar bool dtype', async () => {
837 const a = tf.scalar(4, 'bool');
838 const b = a.reshape([1, 1, 1]);
839 expect(b.dtype).toBe('bool');
840 expect(b.shape).toEqual([1, 1, 1]);
841 expectArraysClose(await a.data(), await b.data());
842 });
843 it('Scalar complex64 dtype', async () => {
844 const a = tf.complex(4, 5);
845 const b = a.reshape([1, 1]);
846 expectArraysClose(await a.data(), [4, 5]);
847 expect(b.dtype).toBe('complex64');
848 expect(b.shape).toEqual([1, 1]);
849 expectArraysClose(await a.data(), await b.data());
850 });
851 it('Tensor1D default dtype', async () => {
852 const a = tf.tensor1d([1, 2, 3, 4]);
853 const b = a.reshape([2, 2]);
854 expect(b.dtype).toBe('float32');
855 expect(b.shape).toEqual([2, 2]);
856 expectArraysClose(await a.data(), await b.data());
857 });
858 it('Tensor1D inferred dtype from bools', async () => {
859 const a = tf.tensor1d([true, false, false, true]);
860 expect(a.dtype).toBe('bool');
861 expect(a.shape).toEqual([4]);
862 expectArraysClose(await a.data(), [1, 0, 0, 1]);
863 });
864 it('Tensor1D inferred dtype from strings', async () => {
865 const a = tf.tensor1d(['a', 'b', 'c']);
866 expect(a.dtype).toBe('string');
867 expect(a.shape).toEqual([3]);
868 expectArraysEqual(await a.data(), ['a', 'b', 'c']);
869 });
870 it('Tensor1D float32 dtype', () => {
871 const a = tf.tensor1d([1, 2, 3, 4], 'float32');
872 const b = a.reshape([2, 2]);
873 expect(b.dtype).toBe('float32');
874 expect(b.shape).toEqual([2, 2]);
875 });
876 it('Tensor1D int32 dtype', async () => {
877 const a = tf.tensor1d([1, 2, 3, 4], 'int32');
878 const b = a.reshape([2, 2]);
879 expect(b.dtype).toBe('int32');
880 expect(b.shape).toEqual([2, 2]);
881 expectArraysClose(await a.data(), await b.data());
882 });
883 it('Tensor1D complex64 dtype', async () => {
884 const a = tf.complex([1, 3, 5, 7], [2, 4, 6, 8]);
885 const b = a.reshape([2, 2]);
886 expect(b.dtype).toBe('complex64');
887 expect(b.shape).toEqual([2, 2]);
888 expectArraysClose(await a.data(), await b.data());
889 });
890 it('Tensor2D default dtype', async () => {
891 const a = tf.tensor2d([1, 2, 3, 4, 5, 6], [2, 3]);
892 const b = a.reshape([6]);
893 expect(b.dtype).toBe('float32');
894 expect(b.shape).toEqual([6]);
895 expectArraysClose(await a.data(), await b.data());
896 });
897 it('Tensor2D float32 dtype', () => {
898 const a = tf.tensor2d([1, 2, 3, 4, 5, 6], [2, 3], 'float32');
899 const b = a.reshape([6]);
900 expect(b.dtype).toBe('float32');
901 expect(b.shape).toEqual([6]);
902 });
903 it('Tensor2D int32 dtype', () => {
904 const a = tf.tensor2d([1, 2, 3, 4, 5, 6], [2, 3], 'int32');
905 const b = a.reshape([6]);
906 expect(b.dtype).toBe('int32');
907 expect(b.shape).toEqual([6]);
908 });
909 it('Tensor2D bool dtype', async () => {
910 const a = tf.tensor2d([1, 2, 3, 4, 5, 6], [2, 3], 'bool');
911 const b = a.reshape([6]);
912 expect(b.dtype).toBe('bool');
913 expect(b.shape).toEqual([6]);
914 expectArraysClose(await a.data(), await b.data());
915 });
916 it('Tensor2D complex64 dtype', async () => {
917 const a = tf.complex([[1, 3, 5], [7, 9, 11]], [[2, 4, 6], [8, 10, 12]]);
918 const b = a.reshape([6]);
919 expect(b.dtype).toBe('complex64');
920 expect(b.shape).toEqual([6]);
921 expectArraysClose(await a.data(), await b.data());
922 });
923 it('Tensor3D default dtype', async () => {
924 const a = tf.tensor3d([1, 2, 3, 4, 5, 6], [2, 3, 1]);
925 const b = a.reshape([6]);
926 expect(b.dtype).toBe('float32');
927 expect(b.shape).toEqual([6]);
928 expectArraysClose(await a.data(), await b.data());
929 });
930 it('Tensor3D float32 dtype', () => {
931 const a = tf.tensor3d([1, 2, 3, 4, 5, 6], [2, 3, 1], 'float32');
932 const b = a.reshape([6]);
933 expect(b.dtype).toBe('float32');
934 expect(b.shape).toEqual([6]);
935 });
936 it('Tensor3D int32 dtype', () => {
937 const a = tf.tensor3d([1, 2, 3, 4, 5, 6], [2, 3, 1], 'int32');
938 const b = a.reshape([6]);
939 expect(b.dtype).toBe('int32');
940 expect(b.shape).toEqual([6]);
941 });
942 it('Tensor3D bool dtype', async () => {
943 const a = tf.tensor3d([1, 2, 3, 4, 5, 6], [2, 3, 1], 'bool');
944 const b = a.reshape([6]);
945 expect(b.dtype).toBe('bool');
946 expect(b.shape).toEqual([6]);
947 expectArraysClose(await a.data(), await b.data());
948 });
949 it('Tensor3D complex64 dtype', async () => {
950 const a = tf.complex([[[1], [3], [5]], [[7], [9], [11]]], [[[2], [4], [6]], [[8], [10], [12]]]);
951 const b = a.reshape([6]);
952 expect(b.dtype).toBe('complex64');
953 expect(b.shape).toEqual([6]);
954 expectArraysClose(await a.data(), await b.data());
955 });
956 it('Tensor4D default dtype', async () => {
957 const a = tf.tensor4d([1, 2, 3, 4, 5, 6], [2, 3, 1, 1]);
958 const b = a.reshape([2, 3]);
959 expect(b.dtype).toBe('float32');
960 expect(b.shape).toEqual([2, 3]);
961 expectArraysClose(await a.data(), await b.data());
962 });
963 it('Tensor4D float32 dtype', () => {
964 const a = tf.tensor4d([1, 2, 3, 4, 5, 6], [2, 3, 1, 1], 'float32');
965 const b = a.reshape([2, 3]);
966 expect(b.dtype).toBe('float32');
967 expect(b.shape).toEqual([2, 3]);
968 });
969 it('Tensor4D int32 dtype', async () => {
970 const a = tf.tensor4d([1, 2, 3, 4, 5, 6], [2, 3, 1, 1], 'int32');
971 const b = a.reshape([3, 2]);
972 expect(b.dtype).toBe('int32');
973 expect(b.shape).toEqual([3, 2]);
974 expectArraysClose(await a.data(), await b.data());
975 });
976 it('Tensor4D complex64 dtype', async () => {
977 const a = tf.complex([[[[1]], [[3]], [[5]]], [[[7]], [[9]], [[11]]]], [[[[2]], [[4]], [[6]]], [[[8]], [[10]], [[12]]]]);
978 const b = a.reshape([3, 2]);
979 expect(b.dtype).toBe('complex64');
980 expect(b.shape).toEqual([3, 2]);
981 expectArraysClose(await a.data(), await b.data());
982 });
983 it('Tensor4D bool dtype', () => {
984 const a = tf.tensor4d([1, 2, 3, 4, 5, 6], [2, 3, 1, 1], 'bool');
985 const b = a.reshape([3, 2]);
986 expect(b.dtype).toBe('bool');
987 expect(b.shape).toEqual([3, 2]);
988 });
989 it('.data() with casting, string tensor', async () => {
990 const a = tf.tensor(['a', 'b']);
991 const data = await a.data();
992 expect(data).toEqual(['a', 'b']);
993 });
994 it('reshape is functional', async () => {
995 const a = tf.scalar(2.4);
996 const b = a.reshape([]);
997 expect(a.id).not.toBe(b.id);
998 b.dispose();
999 expectArraysClose(await a.data(), [2.4]);
1000 });
1001 it('reshape a string tensor', async () => {
1002 const a = tf.tensor(['a', 'b']);
1003 const b = a.reshape([2, 1, 1]);
1004 expect(b.dtype).toBe('string');
1005 expect(b.shape).toEqual([2, 1, 1]);
1006 expectArraysEqual(await b.data(), ['a', 'b']);
1007 });
1008 it('reshape throws when passed a non-tensor', () => {
1009 // tslint:disable-next-line:no-any
1010 expect(() => tf.reshape({}, []))
1011 .toThrowError(/Argument 'x' passed to 'reshape' must be a Tensor/);
1012 });
1013 it('reshape accepts a tensor-like object', async () => {
1014 const res = tf.reshape([[1, 2, 3], [4, 5, 6]], [3, 2]);
1015 expect(res.dtype).toBe('float32');
1016 expect(res.shape).toEqual([3, 2]);
1017 expectArraysClose(await res.data(), [1, 2, 3, 4, 5, 6]);
1018 });
1019 it('cast bool -> bool', () => {
1020 const a = tf.tensor1d([1, 0], 'bool');
1021 expect(a.cast('bool').dtype).toEqual('bool');
1022 });
1023 it('cast bool -> int32', () => {
1024 const a = tf.tensor1d([1, 0], 'bool');
1025 expect(a.cast('int32').dtype).toEqual('int32');
1026 });
1027 it('cast bool -> float32', () => {
1028 const a = tf.tensor1d([1, 0], 'bool');
1029 expect(a.cast('float32').dtype).toEqual('float32');
1030 });
1031 it('cast int32 -> bool', () => {
1032 const a = tf.tensor1d([1, 0], 'int32');
1033 expect(a.cast('bool').dtype).toEqual('bool');
1034 });
1035 it('cast int32 -> int32', () => {
1036 const a = tf.tensor1d([1, 2], 'int32');
1037 expect(a.cast('int32').dtype).toEqual('int32');
1038 });
1039 it('cast int32 -> float32', () => {
1040 const a = tf.tensor1d([1, 2], 'int32');
1041 expect(a.cast('float32').dtype).toEqual('float32');
1042 });
1043 it('cast float32 -> bool', () => {
1044 const a = tf.tensor1d([1.0, 0.0]);
1045 expect(a.cast('bool').dtype).toEqual('bool');
1046 });
1047 it('cast float32 -> int32', () => {
1048 const a = tf.tensor1d([1.0, 2.0]);
1049 expect(a.cast('int32').dtype).toEqual('int32');
1050 });
1051 it('cast float32 -> int32. async download', async () => {
1052 const a = tf.tensor1d([1, 2]);
1053 const aInt = a.cast('int32');
1054 expect(aInt.dtype).toEqual('int32');
1055 const asyncData = await aInt.data();
1056 expect(asyncData instanceof Int32Array).toEqual(true);
1057 });
1058 it('cast float32 -> int32. queued async download', async () => {
1059 const a = tf.tensor1d([1, 2]);
1060 const aInt = a.cast('int32');
1061 expect(aInt.dtype).toEqual('int32');
1062 const [first, second] = await Promise.all([aInt.data(), aInt.data()]);
1063 expect(first instanceof Int32Array).toEqual(true);
1064 expect(second instanceof Int32Array).toEqual(true);
1065 });
1066 it('cast float32 -> int32. sync download', async () => {
1067 const a = tf.tensor1d([1, 2]).cast('int32');
1068 expect(a.dtype).toEqual('int32');
1069 const data = await a.data();
1070 expect(data instanceof Int32Array).toEqual(true);
1071 });
1072 it('cast float32 -> float32', () => {
1073 const a = tf.tensor1d([1.0, 2.0]);
1074 expect(a.cast('float32').dtype).toEqual('float32');
1075 });
1076 it('cast complex64 -> float32', async () => {
1077 const a = tf.complex([1.0, 2.0], [3.0, 4.0]);
1078 const result = a.cast('float32');
1079 expect(result.dtype).toEqual('float32');
1080 expectArraysClose(await result.data(), [1.0, 2.0]);
1081 });
1082 it('cast complex64 -> int32', async () => {
1083 const a = tf.complex([1.0, 2.0], [3.0, 4.0]);
1084 const result = a.cast('int32');
1085 expect(result.dtype).toEqual('int32');
1086 expectArraysEqual(await result.data(), [1, 2]);
1087 });
1088 it('cast complex64 -> bool', async () => {
1089 const a = tf.complex([1.0, 0.0], [1.0, 1.0]);
1090 const result = a.cast('bool');
1091 expect(result.dtype).toEqual('bool');
1092 expectArraysEqual(await result.data(), [true, false]);
1093 });
1094 it('cast throws when passed a non-tensor', () => {
1095 expect(() => tf.cast({}, 'float32'))
1096 .toThrowError(/Argument 'x' passed to 'cast' must be a Tensor/);
1097 });
1098 it('cast accepts a tensor-like object', async () => {
1099 const a = [1.0, 2.0];
1100 const res = tf.cast(a, 'int32');
1101 expect(res.dtype).toEqual('int32');
1102 expectArraysClose(await res.data(), [1, 2]);
1103 });
1104 it('cast string -> !string throws error', () => {
1105 const a = ['a', 'b'];
1106 expect(() => tf.cast(a, 'int32')).toThrowError();
1107 expect(() => tf.cast(a, 'float32')).toThrowError();
1108 expect(() => tf.cast(a, 'bool')).toThrowError();
1109 expect(() => tf.cast(a, 'complex64')).toThrowError();
1110 });
1111 it('cast !string -> string throws error', () => {
1112 expect(() => tf.cast(tf.tensor(1, [], 'float32'), 'string')).toThrowError();
1113 expect(() => tf.cast(tf.tensor(1, [], 'int32'), 'string')).toThrowError();
1114 expect(() => tf.cast(tf.tensor(1, [], 'bool'), 'string')).toThrowError();
1115 expect(() => tf.cast(tf.tensor(1, [], 'complex64'), 'string'))
1116 .toThrowError();
1117 });
1118 it('scalar bool -> int32', async () => {
1119 const a = tf.scalar(true, 'bool').toInt();
1120 expect(a.dtype).toBe('int32');
1121 expectArraysEqual(await a.data(), 1);
1122 });
1123 it('Tensor1D float32 -> int32', async () => {
1124 const a = tf.tensor1d([1.1, 3.9, -2.9, 0]).toInt();
1125 expect(a.dtype).toBe('int32');
1126 expectArraysEqual(await a.data(), [1, 3, -2, 0]);
1127 });
1128 it('Tensor2D float32 -> bool', async () => {
1129 const a = tf.tensor2d([1.1, 3.9, -2.9, 0], [2, 2]).asType('bool');
1130 expect(a.dtype).toBe('bool');
1131 expectArraysEqual(await a.data(), [1, 1, 1, 0]);
1132 });
1133 it('Tensor2D int32 -> bool', async () => {
1134 const a = tf.tensor2d([1, 3, 0, -1], [2, 2], 'int32').toBool();
1135 expect(a.dtype).toBe('bool');
1136 expectArraysEqual(await a.data(), [1, 1, 0, 1]);
1137 });
1138 it('Tensor3D bool -> float32', async () => {
1139 const a = tf.tensor3d([true, false, false, true], [2, 2, 1], 'bool').toFloat();
1140 expect(a.dtype).toBe('float32');
1141 expectArraysClose(await a.data(), [1, 0, 0, 1]);
1142 });
1143 it('bool CPU -> GPU -> CPU', async () => {
1144 const a = tf.tensor1d([1, 2, 0, 0, 5], 'bool');
1145 expectArraysEqual(await a.data(), [1, 1, 0, 0, 1]);
1146 });
1147 it('int32 CPU -> GPU -> CPU', async () => {
1148 const a = tf.tensor1d([1, 2, 0, 0, 5], 'int32');
1149 expectArraysEqual(await a.data(), [1, 2, 0, 0, 5]);
1150 });
1151 it('asType is functional', async () => {
1152 const a = tf.scalar(2.4, 'float32');
1153 const b = a.toFloat();
1154 expect(a.id).not.toBe(b.id);
1155 b.dispose();
1156 expectArraysClose(await a.data(), [2.4]);
1157 });
1158 it('squeeze no axis', () => {
1159 const a = tf.tensor2d([4, 2, 1], [3, 1], 'bool');
1160 const b = a.squeeze();
1161 expect(b.shape).toEqual([3]);
1162 });
1163 it('squeeze with axis', () => {
1164 const a = tf.tensor3d([4, 2, 1], [3, 1, 1], 'bool');
1165 const b = a.squeeze([1]);
1166 expect(b.shape).toEqual([3, 1]);
1167 });
1168 it('squeeze with negative axis', () => {
1169 const a = tf.tensor3d([4, 2, 1], [3, 1, 1], 'bool');
1170 const b = a.squeeze([-1]);
1171 expect(b.shape).toEqual([3, 1]);
1172 });
1173 it('squeeze with multiple negative axis', () => {
1174 const a = tf.tensor3d([4, 2, 1], [3, 1, 1], 'bool');
1175 const b = a.squeeze([-1, -2]);
1176 expect(b.shape).toEqual([3]);
1177 });
1178 it('squeeze wrong axis', () => {
1179 const a = tf.tensor3d([4, 2, 1], [3, 1, 1], 'bool');
1180 expect(() => a.squeeze([0, 1])).toThrowError();
1181 });
1182 it('squeeze wrong negative axis', () => {
1183 const a = tf.tensor3d([4, 2, 1], [3, 1, 1], 'bool');
1184 expect(() => a.squeeze([-3, -2])).toThrowError();
1185 });
1186 it('squeeze axis out of range', () => {
1187 const a = tf.tensor3d([4, 2, 1], [3, 1, 1], 'bool');
1188 expect(() => a.squeeze([10, 11])).toThrowError();
1189 });
1190 it('squeeze negative axis out of range', () => {
1191 const a = tf.tensor3d([4, 2, 1], [3, 1, 1], 'bool');
1192 expect(() => a.squeeze([-13, -12])).toThrowError();
1193 });
1194 it('squeeze throws when passed a non-tensor', () => {
1195 expect(() => tf.squeeze({}))
1196 .toThrowError(/Argument 'x' passed to 'squeeze' must be a Tensor/);
1197 });
1198 it('squeeze accepts a tensor-like object', async () => {
1199 const res = tf.squeeze([[[4]], [[2]], [[1]]] /* shape is [3, 1, 1] */);
1200 expect(res.shape).toEqual([3]);
1201 expectArraysClose(await res.data(), [4, 2, 1]);
1202 });
1203 it('squeeze a zero-sized tensor', () => {
1204 const a = tf.tensor3d([], [0, 1, 0]);
1205 const res = tf.squeeze(a);
1206 expect(res.shape).toEqual([0, 0]);
1207 });
1208 it('squeeze can take an empty list of axis', () => {
1209 const a = tf.zeros([2, 1, 3, 1, 4]);
1210 const axes = [];
1211 // Empty axes list means all possible axes.
1212 const res = tf.squeeze(a, axes);
1213 expect(res.shape).toEqual([2, 3, 4]);
1214 });
1215 it('squeeze a complex64 tensor', async () => {
1216 const a = tf.complex([[4], [1], [5]], [[2], [3], [6]]);
1217 const b = a.squeeze();
1218 expect(b.shape).toEqual([3]);
1219 expectArraysClose(await b.data(), [4, 2, 1, 3, 5, 6]);
1220 });
1221 it('scalar -> 2d', () => {
1222 const a = tf.scalar(4, 'int32');
1223 const b = a.as2D(1, 1);
1224 expect(b.dtype).toBe('int32');
1225 expect(b.shape).toEqual([1, 1]);
1226 });
1227 it('1d -> 2d', () => {
1228 const a = tf.tensor1d([4, 2, 1], 'bool');
1229 const b = a.as2D(3, 1);
1230 expect(b.dtype).toBe('bool');
1231 expect(b.shape).toEqual([3, 1]);
1232 });
1233 it('2d -> 4d', () => {
1234 const a = tf.tensor2d([4, 2, 1, 3], [2, 2]);
1235 const b = a.as4D(1, 1, 2, 2);
1236 expect(b.dtype).toBe('float32');
1237 expect(b.shape).toEqual([1, 1, 2, 2]);
1238 });
1239 it('3d -> 2d', () => {
1240 const a = tf.tensor3d([4, 2, 1, 3], [2, 2, 1], 'float32');
1241 const b = a.as2D(2, 2);
1242 expect(b.dtype).toBe('float32');
1243 expect(b.shape).toEqual([2, 2]);
1244 });
1245 it('4d -> 1d', () => {
1246 const a = tf.tensor4d([4, 2, 1, 3], [2, 2, 1, 1], 'bool');
1247 const b = a.as1D();
1248 expect(b.dtype).toBe('bool');
1249 expect(b.shape).toEqual([4]);
1250 });
1251 it('throws when passed non-integer shape', () => {
1252 const msg = 'Tensor must have a shape comprised of positive ' +
1253 'integers but got shape [2,2.2].';
1254 expect(() => tf.tensor([1, 2, 3, 4], [2, 2.2])).toThrowError(msg);
1255 });
1256 it('throws when passed negative shape', () => {
1257 const msg = 'Tensor must have a shape comprised of positive ' +
1258 'integers but got shape [2,-2].';
1259 expect(() => tf.tensor([1, 2, 3, 4], [2, -2])).toThrowError(msg);
1260 });
1261 it('ones with complex type', async () => {
1262 // Imaginary part should be zero.
1263 const a = tf.ones([2, 2], 'complex64');
1264 expectArraysClose(await a.data(), [1, 0, 1, 0, 1, 0, 1, 0]);
1265 });
1266 it('can create a tensor where values.size != buffer.size', async () => {
1267 const a = new Float32Array([1, 2, 3, 4, 5]);
1268 const b = a.subarray(0, 2);
1269 const t = tf.tensor1d(b);
1270 expect(t.shape).toEqual([2]);
1271 expectArraysClose(await t.data(), [1, 2]);
1272 });
1273});
1274describeWithFlags('tensor debug mode', ALL_ENVS, () => {
1275 beforeAll(() => {
1276 // Silence debug warnings.
1277 spyOn(console, 'warn');
1278 tf.enableDebugMode();
1279 });
1280 it('tf.tensor() from TypedArray + number[] fails due to wrong shape', () => {
1281 expect(() => tf.tensor([
1282 new Float32Array([1, 2]),
1283 new Float32Array([3, 4]),
1284 new Float32Array([5, 6]),
1285 // Should be of length 4
1286 [7, 8, 9, 10],
1287 ]))
1288 .toThrowError(/Element arr\[3\] should have 2 elements, but has 4 elements/);
1289 });
1290});
1291describeWithFlags('tensor dataSync', SYNC_BACKEND_ENVS, () => {
1292 it('.dataSync() with casting, string tensor', () => {
1293 const a = tf.tensor(['a', 'b']);
1294 const data = a.dataSync();
1295 expect(data).toEqual(['a', 'b']);
1296 });
1297});
1298describeWithFlags('tensor arraySync', SYNC_BACKEND_ENVS, () => {
1299 it('.arraySync() with a non-complex tensor', () => {
1300 const a = tf.tensor([1, 2, 3, 4, 5, 6], [2, 3]);
1301 expect(a.arraySync()).toEqual([[1, 2, 3], [4, 5, 6]]);
1302 });
1303 it('.arraySync() with a complex tensor', () => {
1304 const a = tf.complex([[1, 2], [3, 4]], [[11, 12], [13, 14]]);
1305 expect(a.arraySync()).toEqual([[1, 11, 2, 12], [3, 13, 4, 14]]);
1306 });
1307 // The other cases should be covered by toNestedArray tests in util_test.ts.
1308});
1309describeWithFlags('tensor.toString', SYNC_BACKEND_ENVS, () => {
1310 it('scalar verbose', () => {
1311 const verbose = true;
1312 const str = tf.scalar(5).toString(verbose);
1313 expect(str).toEqual('Tensor\n' +
1314 ' dtype: float32\n' +
1315 ' rank: 0\n' +
1316 ' shape: []\n' +
1317 ' values:\n' +
1318 ' 5');
1319 });
1320 it('string scalar verbose', () => {
1321 const verbose = true;
1322 const str = tf.scalar('test').toString(verbose);
1323 expect(str).toEqual('Tensor\n' +
1324 ' dtype: string\n' +
1325 ' rank: 0\n' +
1326 ' shape: []\n' +
1327 ' values:\n' +
1328 ' test');
1329 });
1330 it('bool scalar verbose', () => {
1331 const verbose = true;
1332 const str = tf.scalar(true).toString(verbose);
1333 expect(str).toEqual('Tensor\n' +
1334 ' dtype: bool\n' +
1335 ' rank: 0\n' +
1336 ' shape: []\n' +
1337 ' values:\n' +
1338 ' true');
1339 });
1340 it('1d tensor verbose', () => {
1341 const verbose = true;
1342 const str = tf.zeros([4]).toString(verbose);
1343 expect(str).toEqual('Tensor\n' +
1344 ' dtype: float32\n' +
1345 ' rank: 1\n' +
1346 ' shape: [4]\n' +
1347 ' values:\n' +
1348 ' [0, 0, 0, 0]');
1349 });
1350 it('1d string tensor verbose', () => {
1351 const verbose = true;
1352 const str = tf.tensor(['a', 'bb', 'ccc']).toString(verbose);
1353 expect(str).toEqual('Tensor\n' +
1354 ' dtype: string\n' +
1355 ' rank: 1\n' +
1356 ' shape: [3]\n' +
1357 ' values:\n' +
1358 ' [\'a\', \'bb\', \'ccc\']');
1359 });
1360 it('1d bool tensor verbose', () => {
1361 const verbose = true;
1362 const str = tf.tensor([true, false, true]).toString(verbose);
1363 expect(str).toEqual('Tensor\n' +
1364 ' dtype: bool\n' +
1365 ' rank: 1\n' +
1366 ' shape: [3]\n' +
1367 ' values:\n' +
1368 ' [true, false, true]');
1369 });
1370 it('2d tensor verbose', () => {
1371 const verbose = true;
1372 const str = tf.zeros([3, 3]).toString(verbose);
1373 expect(str).toEqual('Tensor\n' +
1374 ' dtype: float32\n' +
1375 ' rank: 2\n' +
1376 ' shape: [3,3]\n' +
1377 ' values:\n' +
1378 ' [[0, 0, 0],\n' +
1379 ' [0, 0, 0],\n' +
1380 ' [0, 0, 0]]');
1381 });
1382 it('2d string tensor verbose', () => {
1383 const verbose = true;
1384 const vals = [
1385 ['a', 'bb', 'ccc'],
1386 ['d', 'e', 'f'],
1387 ['g', 'h', 'i'],
1388 ];
1389 const str = tf.tensor(vals).toString(verbose);
1390 expect(str).toEqual('Tensor\n' +
1391 ' dtype: string\n' +
1392 ' rank: 2\n' +
1393 ' shape: [3,3]\n' +
1394 ' values:\n' +
1395 ' [[\'a\', \'bb\', \'ccc\'],\n' +
1396 ' [\'d\', \'e\' , \'f\' ],\n' +
1397 ' [\'g\', \'h\' , \'i\' ]]');
1398 });
1399 it('2d bool tensor verbose', () => {
1400 const verbose = true;
1401 const str = tf.zeros([3, 3], 'bool').toString(verbose);
1402 expect(str).toEqual('Tensor\n' +
1403 ' dtype: bool\n' +
1404 ' rank: 2\n' +
1405 ' shape: [3,3]\n' +
1406 ' values:\n' +
1407 ' [[false, false, false],\n' +
1408 ' [false, false, false],\n' +
1409 ' [false, false, false]]');
1410 });
1411 it('3d tensor verbose', () => {
1412 const verbose = true;
1413 const str = tf.zeros([3, 3, 2]).toString(verbose);
1414 expect(str).toEqual('Tensor\n' +
1415 ' dtype: float32\n' +
1416 ' rank: 3\n' +
1417 ' shape: [3,3,2]\n' +
1418 ' values:\n' +
1419 ' [[[0, 0],\n' +
1420 ' [0, 0],\n' +
1421 ' [0, 0]],\n\n' +
1422 ' [[0, 0],\n' +
1423 ' [0, 0],\n' +
1424 ' [0, 0]],\n\n' +
1425 ' [[0, 0],\n' +
1426 ' [0, 0],\n' +
1427 ' [0, 0]]]');
1428 });
1429 it('3d string tensor verbose', () => {
1430 const verbose = true;
1431 const vals = [
1432 [['a', 'bb'], ['ccc', 'dddd']],
1433 [['e', 'ff'], ['ggg', 'hhhh']],
1434 [['i', 'jj'], ['kkk', 'llll']],
1435 ];
1436 const str = tf.tensor(vals).toString(verbose);
1437 expect(str).toEqual('Tensor\n' +
1438 ' dtype: string\n' +
1439 ' rank: 3\n' +
1440 ' shape: [3,2,2]\n' +
1441 ' values:\n' +
1442 ' [[[\'a\' , \'bb\' ],\n' +
1443 ' [\'ccc\', \'dddd\']],\n\n' +
1444 ' [[\'e\' , \'ff\' ],\n' +
1445 ' [\'ggg\', \'hhhh\']],\n\n' +
1446 ' [[\'i\' , \'jj\' ],\n' +
1447 ' [\'kkk\', \'llll\']]]');
1448 });
1449 it('3d bool tensor verbose', () => {
1450 const verbose = true;
1451 const str = tf.ones([3, 3, 2], 'bool').toString(verbose);
1452 expect(str).toEqual('Tensor\n' +
1453 ' dtype: bool\n' +
1454 ' rank: 3\n' +
1455 ' shape: [3,3,2]\n' +
1456 ' values:\n' +
1457 ' [[[true, true],\n' +
1458 ' [true, true],\n' +
1459 ' [true, true]],\n\n' +
1460 ' [[true, true],\n' +
1461 ' [true, true],\n' +
1462 ' [true, true]],\n\n' +
1463 ' [[true, true],\n' +
1464 ' [true, true],\n' +
1465 ' [true, true]]]');
1466 });
1467 it('1d long tensor verbose', () => {
1468 const verbose = true;
1469 const str = tf.zeros([100]).toString(verbose);
1470 expect(str).toEqual('Tensor\n' +
1471 ' dtype: float32\n' +
1472 ' rank: 1\n' +
1473 ' shape: [100]\n' +
1474 ' values:\n' +
1475 ' [0, 0, 0, ..., 0, 0, 0]');
1476 });
1477 it('1d long string tensor verbose', () => {
1478 const verbose = true;
1479 const str = tf.fill([100], 'hi').toString(verbose);
1480 expect(str).toEqual('Tensor\n' +
1481 ' dtype: string\n' +
1482 ' rank: 1\n' +
1483 ' shape: [100]\n' +
1484 ' values:\n' +
1485 ' [\'hi\', \'hi\', \'hi\', ..., \'hi\', \'hi\', \'hi\']');
1486 });
1487 it('2d long tensor verbose', () => {
1488 const verbose = true;
1489 const str = tf.zeros([100, 100]).toString(verbose);
1490 expect(str).toEqual('Tensor\n' +
1491 ' dtype: float32\n' +
1492 ' rank: 2\n' +
1493 ' shape: [100,100]\n' +
1494 ' values:\n' +
1495 ' [[0, 0, 0, ..., 0, 0, 0],\n' +
1496 ' [0, 0, 0, ..., 0, 0, 0],\n' +
1497 ' [0, 0, 0, ..., 0, 0, 0],\n' +
1498 ' ...,\n' +
1499 ' [0, 0, 0, ..., 0, 0, 0],\n' +
1500 ' [0, 0, 0, ..., 0, 0, 0],\n' +
1501 ' [0, 0, 0, ..., 0, 0, 0]]');
1502 });
1503 it('2d long string tensor verbose', () => {
1504 const verbose = true;
1505 const str = tf.fill([100, 100], 'a').toString(verbose);
1506 expect(str).toEqual('Tensor\n' +
1507 ' dtype: string\n' +
1508 ' rank: 2\n' +
1509 ' shape: [100,100]\n' +
1510 ' values:\n' +
1511 ' [[\'a\', \'a\', \'a\', ..., \'a\', \'a\', \'a\'],\n' +
1512 ' [\'a\', \'a\', \'a\', ..., \'a\', \'a\', \'a\'],\n' +
1513 ' [\'a\', \'a\', \'a\', ..., \'a\', \'a\', \'a\'],\n' +
1514 ' ...,\n' +
1515 ' [\'a\', \'a\', \'a\', ..., \'a\', \'a\', \'a\'],\n' +
1516 ' [\'a\', \'a\', \'a\', ..., \'a\', \'a\', \'a\'],\n' +
1517 ' [\'a\', \'a\', \'a\', ..., \'a\', \'a\', \'a\']]');
1518 });
1519 it('2d with padding to align columns verbose', () => {
1520 const verbose = true;
1521 const str = tf.tensor([
1522 [0.8597712, 3, 0.2740789], [0.6696132, 0.4825962, 2.75],
1523 [1.991, 0.0640865, 0.2983858]
1524 ]).toString(verbose);
1525 expect(str).toEqual('Tensor\n' +
1526 ' dtype: float32\n' +
1527 ' rank: 2\n' +
1528 ' shape: [3,3]\n' +
1529 ' values:\n' +
1530 ' [[0.8597712, 3 , 0.2740789],\n' +
1531 ' [0.6696132, 0.4825962, 2.75 ],\n' +
1532 ' [1.9910001, 0.0640865, 0.2983858]]');
1533 });
1534 it('2d string tensor with padding verbose', () => {
1535 const verbose = true;
1536 const str = tf.tensor([
1537 ['abcdef', 'a', 'abcdef'],
1538 ['abcdef', 'abcdef', 'abc'],
1539 ['abcd', 'abcdef', 'abcdef'],
1540 ]).toString(verbose);
1541 expect(str).toEqual('Tensor\n' +
1542 ' dtype: string\n' +
1543 ' rank: 2\n' +
1544 ' shape: [3,3]\n' +
1545 ' values:\n' +
1546 ' [[\'abcdef\', \'a\' , \'abcdef\'],\n' +
1547 ' [\'abcdef\', \'abcdef\', \'abc\' ],\n' +
1548 ' [\'abcd\' , \'abcdef\', \'abcdef\']]');
1549 });
1550 it('scalar', () => {
1551 const str = tf.scalar(5).toString();
1552 expect(str).toEqual('Tensor\n' +
1553 ' 5');
1554 });
1555 it('scalar string', () => {
1556 const str = tf.scalar('hello').toString();
1557 expect(str).toEqual('Tensor\n' +
1558 ' hello');
1559 });
1560 it('1d tensor', () => {
1561 const str = tf.zeros([4]).toString();
1562 expect(str).toEqual('Tensor\n' +
1563 ' [0, 0, 0, 0]');
1564 });
1565 it('2d tensor', () => {
1566 const str = tf.zeros([3, 3]).toString();
1567 expect(str).toEqual('Tensor\n' +
1568 ' [[0, 0, 0],\n' +
1569 ' [0, 0, 0],\n' +
1570 ' [0, 0, 0]]');
1571 });
1572 it('3d tensor', () => {
1573 const str = tf.zeros([3, 3, 2]).toString();
1574 expect(str).toEqual('Tensor\n' +
1575 ' [[[0, 0],\n' +
1576 ' [0, 0],\n' +
1577 ' [0, 0]],\n\n' +
1578 ' [[0, 0],\n' +
1579 ' [0, 0],\n' +
1580 ' [0, 0]],\n\n' +
1581 ' [[0, 0],\n' +
1582 ' [0, 0],\n' +
1583 ' [0, 0]]]');
1584 });
1585 it('1d long tensor', () => {
1586 const str = tf.zeros([100]).toString();
1587 expect(str).toEqual('Tensor\n' +
1588 ' [0, 0, 0, ..., 0, 0, 0]');
1589 });
1590 it('2d long tensor', () => {
1591 const str = tf.zeros([100, 100]).toString();
1592 expect(str).toEqual('Tensor\n' +
1593 ' [[0, 0, 0, ..., 0, 0, 0],\n' +
1594 ' [0, 0, 0, ..., 0, 0, 0],\n' +
1595 ' [0, 0, 0, ..., 0, 0, 0],\n' +
1596 ' ...,\n' +
1597 ' [0, 0, 0, ..., 0, 0, 0],\n' +
1598 ' [0, 0, 0, ..., 0, 0, 0],\n' +
1599 ' [0, 0, 0, ..., 0, 0, 0]]');
1600 });
1601 it('2d with padding to align columns', () => {
1602 const str = tf.tensor([
1603 [0.8597712, 3, 0.2740789], [0.6696132, 0.4825962, 2.75],
1604 [1.991, 0.0640865, 0.2983858]
1605 ]).toString();
1606 expect(str).toEqual('Tensor\n' +
1607 ' [[0.8597712, 3 , 0.2740789],\n' +
1608 ' [0.6696132, 0.4825962, 2.75 ],\n' +
1609 ' [1.9910001, 0.0640865, 0.2983858]]');
1610 });
1611 it('scalar complex64 verbose', () => {
1612 const verbose = true;
1613 const str = tf.complex(5, 6).toString(verbose);
1614 expect(str).toEqual('Tensor\n' +
1615 ' dtype: complex64\n' +
1616 ' rank: 0\n' +
1617 ' shape: []\n' +
1618 ' values:\n' +
1619 ' 5 + 6j');
1620 });
1621 it('1d complex64 tensor verbose', () => {
1622 const verbose = true;
1623 const str = tf.complex([3, 5], [4, 6]).toString(verbose);
1624 expect(str).toEqual('Tensor\n' +
1625 ' dtype: complex64\n' +
1626 ' rank: 1\n' +
1627 ' shape: [2]\n' +
1628 ' values:\n' +
1629 ' [3 + 4j, 5 + 6j]');
1630 });
1631 it('2d complex64 tensor verbose', () => {
1632 const verbose = true;
1633 const str = tf.complex(tf.linspace(0, 8, 9), tf.linspace(8, 0, 9))
1634 .reshape([3, 3])
1635 .toString(verbose);
1636 expect(str).toEqual('Tensor\n' +
1637 ' dtype: complex64\n' +
1638 ' rank: 2\n' +
1639 ' shape: [3,3]\n' +
1640 ' values:\n' +
1641 ' [[0 + 8j, 1 + 7j, 2 + 6j],\n' +
1642 ' [3 + 5j, 4 + 4j, 5 + 3j],\n' +
1643 ' [6 + 2j, 7 + 1j, 8 + 0j]]');
1644 });
1645 it('3d complex64 tensor verbose', () => {
1646 const verbose = true;
1647 const str = tf.complex(tf.linspace(0, 17, 18), tf.linspace(17, 0, 18))
1648 .reshape([3, 3, 2])
1649 .toString(verbose);
1650 expect(str).toEqual('Tensor\n' +
1651 ' dtype: complex64\n' +
1652 ' rank: 3\n' +
1653 ' shape: [3,3,2]\n' +
1654 ' values:\n' +
1655 ' [[[0 + 17j, 1 + 16j],\n' +
1656 ' [2 + 15j, 3 + 14j],\n' +
1657 ' [4 + 13j, 5 + 12j]],\n\n' +
1658 ' [[6 + 11j, 7 + 10j],\n' +
1659 ' [8 + 9j , 9 + 8j ],\n' +
1660 ' [10 + 7j, 11 + 6j]],\n\n' +
1661 ' [[12 + 5j, 13 + 4j],\n' +
1662 ' [14 + 3j, 15 + 2j],\n' +
1663 ' [16 + 1j, 17 + 0j]]]');
1664 });
1665 it('1d long complex64 tensor verbose', () => {
1666 const verbose = true;
1667 const str = tf.complex(tf.linspace(0, 99, 100), tf.linspace(99, 0, 100))
1668 .toString(verbose);
1669 expect(str).toEqual('Tensor\n' +
1670 ' dtype: complex64\n' +
1671 ' rank: 1\n' +
1672 ' shape: [100]\n' +
1673 ' values:\n' +
1674 ' [0 + 99j, 1 + 98j, 2 + 97j, ..., 97 + 2j, 98 + 1j, 99 + 0j]');
1675 });
1676 it('2d long complex64 tensor verbose', () => {
1677 const verbose = true;
1678 const dim = 100;
1679 const str = tf.complex(tf.linspace(0, dim * dim - 1, dim * dim), tf.linspace(dim * dim - 1, 0, dim * dim))
1680 .reshape([dim, dim])
1681 .toString(verbose);
1682 expect(str).toEqual('Tensor\n' +
1683 ' dtype: complex64\n' +
1684 ' rank: 2\n' +
1685 ' shape: [100,100]\n' +
1686 ' values:\n' +
1687 // tslint:disable:max-line-length
1688 ' [[0 + 9999j , 1 + 9998j , 2 + 9997j , ..., 97 + 9902j , 98 + 9901j , 99 + 9900j ],\n' +
1689 ' [100 + 9899j , 101 + 9898j , 102 + 9897j , ..., 197 + 9802j , 198 + 9801j , 199 + 9800j ],\n' +
1690 ' [200 + 9799j , 201 + 9798j , 202 + 9797j , ..., 297 + 9702j , 298 + 9701j , 299 + 9700j ],\n' +
1691 ' ...,\n' +
1692 ' [9700 + 299j , 9701 + 298j , 9702 + 297j , ..., 9797 + 202j , 9798 + 201j , 9799 + 200j ],\n' +
1693 ' [9800 + 199j , 9801 + 198j , 9802 + 197j , ..., 9897 + 102j , 9898 + 101j , 9899 + 100j ],\n' +
1694 ' [9900 + 99j , 9901 + 98j , 9902 + 97j , ..., 9997 + 2j , 9998 + 1j , 9999 + 0j ]]');
1695 // tslint:enable:max-line-length
1696 });
1697 it('2d complex64 with padding to align columns verbose', () => {
1698 const verbose = true;
1699 const str = tf.complex([
1700 [0.8597712, 3, 0.2740789], [0.6696132, 0.4825962, 2.75],
1701 [1.991, 0.0640865, 0.2983858]
1702 ], [[1, 1.0102332, 3], [2, 5, 2.34424], [1.23, 2, 0.123]])
1703 .toString(verbose);
1704 expect(str).toEqual('Tensor\n' +
1705 ' dtype: complex64\n' +
1706 ' rank: 2\n' +
1707 ' shape: [3,3]\n' +
1708 ' values:\n' +
1709 ' [[0.8597712 + 1j , 3 + 1.0102332j, 0.2740789 + 3j ],\n' +
1710 ' [0.6696132 + 2j , 0.4825962 + 5j, 2.75 + 2.34424j ],\n' +
1711 ' [1.9910001 + 1.23j, 0.0640865 + 2j, 0.2983858 + 0.123j]]');
1712 });
1713 it('scalar complex64', () => {
1714 const str = tf.complex(5, 4).toString();
1715 expect(str).toEqual('Tensor\n' +
1716 ' 5 + 4j');
1717 });
1718 it('1d complex64 tensor', () => {
1719 const str = tf.complex(tf.linspace(0, 3, 4), tf.linspace(3, 0, 4)).toString();
1720 expect(str).toEqual('Tensor\n' +
1721 ' [0 + 3j, 1 + 2j, 2 + 1j, 3 + 0j]');
1722 });
1723 it('2d complex64 tensor', () => {
1724 const str = tf.complex(tf.linspace(0, 8, 9), tf.linspace(8, 0, 9))
1725 .reshape([3, 3])
1726 .toString();
1727 expect(str).toEqual('Tensor\n' +
1728 ' [[0 + 8j, 1 + 7j, 2 + 6j],\n' +
1729 ' [3 + 5j, 4 + 4j, 5 + 3j],\n' +
1730 ' [6 + 2j, 7 + 1j, 8 + 0j]]');
1731 });
1732 it('3d complex64 tensor', () => {
1733 const str = tf.complex(tf.linspace(0, 17, 18), tf.linspace(17, 0, 18))
1734 .reshape([3, 3, 2])
1735 .toString();
1736 expect(str).toEqual('Tensor\n' +
1737 ' [[[0 + 17j, 1 + 16j],\n' +
1738 ' [2 + 15j, 3 + 14j],\n' +
1739 ' [4 + 13j, 5 + 12j]],\n\n' +
1740 ' [[6 + 11j, 7 + 10j],\n' +
1741 ' [8 + 9j , 9 + 8j ],\n' +
1742 ' [10 + 7j, 11 + 6j]],\n\n' +
1743 ' [[12 + 5j, 13 + 4j],\n' +
1744 ' [14 + 3j, 15 + 2j],\n' +
1745 ' [16 + 1j, 17 + 0j]]]');
1746 });
1747 it('1d long complex64 tensor', () => {
1748 const str = tf.complex(tf.linspace(0, 99, 100), tf.linspace(99, 0, 100)).toString();
1749 expect(str).toEqual('Tensor\n' +
1750 ' [0 + 99j, 1 + 98j, 2 + 97j, ..., 97 + 2j, 98 + 1j, 99 + 0j]');
1751 });
1752 it('2d long complex64 tensor', () => {
1753 const dim = 100;
1754 const str = tf.complex(tf.linspace(0, dim * dim - 1, dim * dim), tf.linspace(dim * dim - 1, 0, dim * dim))
1755 .reshape([dim, dim])
1756 .toString();
1757 expect(str).toEqual('Tensor\n' +
1758 // tslint:disable:max-line-length
1759 ' [[0 + 9999j , 1 + 9998j , 2 + 9997j , ..., 97 + 9902j , 98 + 9901j , 99 + 9900j ],\n' +
1760 ' [100 + 9899j , 101 + 9898j , 102 + 9897j , ..., 197 + 9802j , 198 + 9801j , 199 + 9800j ],\n' +
1761 ' [200 + 9799j , 201 + 9798j , 202 + 9797j , ..., 297 + 9702j , 298 + 9701j , 299 + 9700j ],\n' +
1762 ' ...,\n' +
1763 ' [9700 + 299j , 9701 + 298j , 9702 + 297j , ..., 9797 + 202j , 9798 + 201j , 9799 + 200j ],\n' +
1764 ' [9800 + 199j , 9801 + 198j , 9802 + 197j , ..., 9897 + 102j , 9898 + 101j , 9899 + 100j ],\n' +
1765 ' [9900 + 99j , 9901 + 98j , 9902 + 97j , ..., 9997 + 2j , 9998 + 1j , 9999 + 0j ]]');
1766 // tslint:enable:max-line-length
1767 });
1768 it('2d complex64 with padding to align columns', () => {
1769 const str = tf.complex([
1770 [0.8597712, 3, 0.2740789], [0.6696132, 0.4825962, 2.75],
1771 [1.991, 0.0640865, 0.2983858]
1772 ], [[1, 1.0102332, 3], [2, 5, 2.34424], [1.23, 2, 0.123]])
1773 .toString();
1774 expect(str).toEqual('Tensor\n' +
1775 ' [[0.8597712 + 1j , 3 + 1.0102332j, 0.2740789 + 3j ],\n' +
1776 ' [0.6696132 + 2j , 0.4825962 + 5j, 2.75 + 2.34424j ],\n' +
1777 ' [1.9910001 + 1.23j, 0.0640865 + 2j, 0.2983858 + 0.123j]]');
1778 });
1779});
1780describeWithFlags('tensor grad', ALL_ENVS, () => {
1781 it('grad with second derivative', async () => {
1782 // f(x) = x ^ 3
1783 const f = (x) => x.pow(tf.scalar(3, 'int32'));
1784 // f'(x) = 3x ^ 2
1785 const g = tf.grad(f);
1786 // f''(x) = 6x
1787 const gg = tf.grad(g);
1788 const x = tf.tensor1d([2, 3]);
1789 const data = gg(x);
1790 expectArraysClose(await data.data(), [12, 18]);
1791 });
1792});
1793describeWithFlags('tensor.data', ALL_ENVS, () => {
1794 it('interleaving .data() and .dataSync()', async () => {
1795 const a = tf.tensor1d([1, 2, 3]);
1796 const b = tf.tensor1d([4, 5, 6]);
1797 const ra = a.square();
1798 const rb = b.square();
1799 expectArraysClose(await a.data(), [1, 2, 3]);
1800 expectArraysClose(await b.data(), [4, 5, 6]);
1801 expectArraysClose(await rb.data(), [16, 25, 36]);
1802 expectArraysClose(await ra.data(), [1, 4, 9]);
1803 });
1804 it('.data() postpones disposal of tensor', done => {
1805 expect(tf.memory().numTensors).toBe(0);
1806 tf.tidy(() => {
1807 const a = tf.scalar(5);
1808 expect(tf.memory().numTensors).toBe(1);
1809 a.square(); // Uploads it on GPU.
1810 a.data().then(vals => {
1811 // The tidy above should not dispose the scalar since there is
1812 // a pending data read.
1813 expectNumbersClose(vals[0], 5);
1814 });
1815 });
1816 // tidy ends immediately, but should not dispose the scalar.
1817 setTimeout(() => {
1818 // tidy should dispose the tensor.
1819 expect(tf.memory().numTensors).toBe(0);
1820 done();
1821 });
1822 });
1823 it('calling .data() twice works (2 subscribers to a single read)', done => {
1824 tf.tidy(() => {
1825 const a = tf.scalar(5);
1826 a.square(); // Uploads it on GPU.
1827 a.data().then(vals => {
1828 expectNumbersClose(vals[0], 5);
1829 });
1830 a.data()
1831 .then(vals => {
1832 expectNumbersClose(vals[0], 5);
1833 })
1834 .then(done);
1835 });
1836 // tidy ends immediately, but should not dispose the scalar since there is
1837 // a pending data read.
1838 });
1839});
1840describeWithFlags('x instanceof Tensor', ALL_ENVS, () => {
1841 it('x: Tensor', () => {
1842 const t = tf.scalar(1);
1843 expect(t instanceof Tensor).toBe(true);
1844 });
1845 it('x: other object, fails', () => {
1846 const t = { something: 'else' };
1847 expect(t instanceof Tensor).toBe(false);
1848 });
1849 it('x: undefined or null, fails', () => {
1850 // tslint:disable-next-line:no-any
1851 expect(undefined instanceof Tensor).toBe(false);
1852 // tslint:disable-next-line:no-any
1853 expect(null instanceof Tensor).toBe(false);
1854 });
1855});
1856describeWithFlags('tensor with 0 in shape', ALL_ENVS, () => {
1857 it('1d of shape [0]', async () => {
1858 const a = tf.tensor1d([]);
1859 expect(a.dtype).toBe('float32');
1860 expect(a.rank).toBe(1);
1861 expect(a.shape).toEqual([0]);
1862 expectArraysEqual(await a.data(), []);
1863 });
1864 it('1d string tensor of shape [0]', async () => {
1865 const a = tf.tensor1d([], 'string');
1866 expect(a.dtype).toBe('string');
1867 expect(a.rank).toBe(1);
1868 expect(a.shape).toEqual([0]);
1869 expectArraysEqual(await a.data(), []);
1870 });
1871 it('2d of shape [0, 5]', async () => {
1872 const a = tf.tensor2d([], [0, 5]);
1873 expect(a.dtype).toBe('float32');
1874 expect(a.rank).toBe(2);
1875 expect(a.shape).toEqual([0, 5]);
1876 expectArraysEqual(await a.data(), []);
1877 });
1878 it('2d string tensor of shape [0, 5]', async () => {
1879 const a = tf.tensor2d([], [0, 5], 'string');
1880 expect(a.dtype).toBe('string');
1881 expect(a.rank).toBe(2);
1882 expect(a.shape).toEqual([0, 5]);
1883 expectArraysEqual(await a.data(), []);
1884 });
1885 it('2d throws when values are not empty', () => {
1886 const values = [1, 2, 3, 4];
1887 expect(() => tf.tensor2d(values, [0, 5], 'float32'))
1888 .toThrowError('Based on the provided shape, [0,5], the ' +
1889 'tensor should have 0 values but has 4');
1890 });
1891 it('3d of shape [0, 3, 0]', async () => {
1892 const a = tf.tensor3d([], [0, 3, 0]);
1893 expect(a.dtype).toBe('float32');
1894 expect(a.rank).toBe(3);
1895 expect(a.shape).toEqual([0, 3, 0]);
1896 expectArraysEqual(await a.data(), []);
1897 });
1898 it('3d throws when values are not empty', () => {
1899 const values = [1, 2, 3];
1900 expect(() => tf.tensor3d(values, [0, 3, 0], 'float32'))
1901 .toThrowError('Based on the provided shape, [0,3,0], the ' +
1902 'tensor should have 0 values but has 3');
1903 });
1904 it('4d of shape [1, 3, 0, 5]', async () => {
1905 const a = tf.tensor4d([], [1, 3, 0, 5]);
1906 expect(a.dtype).toBe('float32');
1907 expect(a.rank).toBe(4);
1908 expect(a.shape).toEqual([1, 3, 0, 5]);
1909 expectArraysEqual(await a.data(), []);
1910 });
1911 it('4d throws when values are not empty', () => {
1912 const values = [1, 2, 3];
1913 expect(() => tf.tensor4d(values, [1, 3, 0, 5], 'float32'))
1914 .toThrowError('Based on the provided shape, [1,3,0,5], the ' +
1915 'tensor should have 0 values but has 3');
1916 });
1917 it('complex64 with 0 in shape', async () => {
1918 const areal = tf.tensor2d([], [0, 5]);
1919 const breal = tf.tensor2d([], [0, 5]);
1920 const a = tf.complex(areal, breal);
1921 expect(a.dtype).toBe('complex64');
1922 expect(a.rank).toBe(2);
1923 expect(a.shape).toEqual([0, 5]);
1924 expectArraysEqual(await a.data(), []);
1925 });
1926});
1927describeWithFlags('tensor.bytes()', ALL_ENVS, () => {
1928 /** Helper method to get the bytes from a typed array. */
1929 function getBytes(a) {
1930 return new Uint8Array(a.buffer);
1931 }
1932 it('float32 tensor', async () => {
1933 const a = tf.tensor([1.1, 3.2, 7], [3], 'float32');
1934 expect(await a.bytes()).toEqual(getBytes(new Float32Array([1.1, 3.2, 7])));
1935 });
1936 it('int32 tensor', async () => {
1937 const a = tf.tensor([1.1, 3.2, 7], [3], 'int32');
1938 expect(await a.bytes()).toEqual(getBytes(new Int32Array([1, 3, 7])));
1939 });
1940 it('bool tensor', async () => {
1941 const a = tf.tensor([true, true, false], [3], 'bool');
1942 expect(await a.bytes()).toEqual(new Uint8Array([1, 1, 0]));
1943 });
1944 it('string tensor from native strings', async () => {
1945 const a = tf.tensor(['hello', 'world'], [2], 'string');
1946 expect(await a.bytes()).toEqual([
1947 encodeString('hello'), encodeString('world')
1948 ]);
1949 });
1950 it('string tensor from encoded bytes', async () => {
1951 const a = tf.tensor([encodeString('hello'), encodeString('world')], [2], 'string');
1952 expect(await a.bytes()).toEqual([
1953 encodeString('hello'), encodeString('world')
1954 ]);
1955 });
1956});
1957//# sourceMappingURL=tensor_test.js.map
\No newline at end of file