makeTensor(values, shape, dtype, backend) {
        if (values == null) throw new Error("Values passed to engine.makeTensor() are null");
        dtype = dtype || "float32";
        backend = backend || this.backend;
        let backendVals = values;
        if (dtype === "string" && _util.isString(values[0])) backendVals = values.map((d)=>_util.encodeString(d));
        const dataId = backend.write(backendVals, shape, dtype);
        const t = new (0, _tensor.Tensor)(shape, dtype, dataId, this.nextTensorId());
        this.trackTensor(t, backend);
        // Count bytes for string tensors.
        if (dtype === "string") {
            const info = this.state.tensorInfo.get(dataId);
            const newBytes = (0, _util.bytesFromStringArray)(backendVals);
            this.state.numBytes += newBytes - info.bytes;
            info.bytes = newBytes;
        }
        return t;
    }
Internal method used by public APIs for tensor creation. Makes a new
tensor with the provided shape, dtype and values. It always
creates a new data id and writes the values to the underlying backend.