public IWeightTensor Softmax(IWeightTensor w, bool runGradients = true, bool inPlace = false)
        {
            WeightTensor m   = w as WeightTensor;
            WeightTensor res = null;

            if (inPlace)
            {
                res = m.CopyWeightsRef($"{GetHashString(w.Name)}.Softmax");
            }
            else
            {
                res = m_weightTensorFactory.CreateWeightTensor(m.Sizes, m_deviceId, name: $"{GetHashString(w.Name)}.Softmax");
            }

            VisualizeNodes(w, res);

            Ops.Softmax(res.TWeight, m.TWeight);
            if (m_needsBackprop && runGradients)
            {
                Action backward = () =>
                {
                    if (inPlace)
                    {
                        m.TGradient = res.TGradient.CopyRef();
                    }

                    m.AddSoftmaxGradient(res, inPlace);
                    res.Dispose();
                };
                this.m_backprop.Add(backward);
            }

            return(res);
        }