/// <inheritdoc/>
        public virtual Tensor Alloc(TensorShape shape, ITensorData buffer, AllocScope scope, DataType dataType)
        {
            Profiler.BeginSample("Barracuda.SizeAllocator.Alloc");
            var name = "untitled";

            var tensor = AllocTensorInternal(dataType, shape, buffer);

            tensor.name = name;
            m_BusyTensors.Add(tensor, tensor.tensorOnDevice);
            AddRef(tensor.tensorOnDevice);

            Profiler.EndSample();
            return(tensor);
        }
        public virtual Tensor Alloc(TensorShape shape, ITensorData buffer, AllocScope scope, DataType dataType)
        {
            Profiler.BeginSample("Barracuda.ShapeAllocator.Alloc");
            var name = "untitled";

            var tensor = new Tensor(shape, buffer, this); // @TODO: reuse Tensor instances

            tensor.name = name;
            m_BusyTensors.Add(tensor, buffer);
            AddRef(buffer);

            Profiler.EndSample();
            return(tensor);
        }
        public virtual Tensor Alloc(TensorShape shape, AllocScope scope, DataType dataType)
        {
            Profiler.BeginSample("Barracuda.ShapeAllocator.Alloc");
            var name = "untitled";
            var key  = new CacheKey {
                shape = shape, dataType = dataType
            };
            LinkedListNode <Entry> node;

            if (m_FreeBufferByShape.TryGetValue(key, out node))
            {
                Assert.AreEqual(node.Value.shape, shape);

                // advance dictionary to the next Tensor with the same shape, if available
                if (node.Next != null && node.Next.Value.shape == shape)
                {
                    m_FreeBufferByShape[key] = node.Next;
                }
                else
                {
                    m_FreeBufferByShape.Remove(key);
                }

                var buffer = node.Value.buffer;
                buffer?.Reserve(shape.length);

                var tensor = new Tensor(shape, buffer, this); // @TODO: reuse Tensor instances
                tensor.name = name;

                m_FreeBuffers.Remove(node);
                m_BusyTensors.Add(tensor, buffer);
                AddRef(buffer);

                Assert.AreEqual(tensor.shape, shape);
                Profiler.EndSample();
                return(tensor);
            }

            var newTensor = new Tensor(shape, this);

            newTensor.name = name;
            m_BusyTensors.Add(newTensor, newTensor.tensorOnDevice);
            AddRef(newTensor.tensorOnDevice);

            Profiler.EndSample();
            return(newTensor);
        }
        /// <inheritdoc/>
        public virtual Tensor Alloc(TensorShape shape, AllocScope scope, DataType dataType)
        {
            Profiler.BeginSample("Barracuda.SizeAllocator.Alloc");
            var name = "untitled";

            for (int i = 0; i < m_AllocatedBuffers.Count; ++i)
            {
                var entry = m_AllocatedBuffers[i];
                if (entry.size >= shape.length && entry.dataType == dataType && entry.free)
                {
                    entry.free            = false;
                    m_AllocatedBuffers[i] = entry;

                    ITensorData buffer = entry.tensorData;
                    buffer?.Reserve(shape.length);

                    var tensor = AllocTensorInternal(dataType, shape, buffer);
                    tensor.name = name;

                    m_BusyTensors.Add(tensor, tensor.tensorOnDevice);
                    AddRef(tensor.tensorOnDevice);

                    Profiler.EndSample();
                    return(tensor);
                }
            }

            ++m_NumAllocatedBufferSinceCleanup;

            var newTensor = AllocTensorInternal(dataType, shape, null);

            newTensor.name = name;
            m_BusyTensors.Add(newTensor, newTensor.tensorOnDevice);
            AddRef(newTensor.tensorOnDevice);

            Profiler.EndSample();
            return(newTensor);
        }