akankshakshurai/cuda-error-resolution-analysis huggingface dataset:
Torch Unsqueeze not changing size

maxrivera: <p>torch.unsqueeze seems to add a batch dimension here but why doesn’t tensor.size() change?</p>
<pre><code class="lang-auto">&gt;&gt;&gt; x = torch.Tensor([1,2,3,4])

&gt;&gt;&gt; x

tensor([1., 2., 3., 4.])

&gt;&gt;&gt; x.size()

torch.Size([4])

&gt;&gt;&gt; torch.unsqueeze(x,0)

tensor([[1., 2., 3., 4.]])

&gt;&gt;&gt; x.size()

torch.Size([4])
</code></pre>

ptrblck: <p><code>torch.unsqueeze</code> is not an inplace operation so either assign the result to a tensor or use the inplace version as <code>tensor.unsqueeze_()</code>.</p>
How to draw the prediction result about MNIST dataset (or other dataset with ten prediction point)?

MonKeyBoy: <p>I hope that there are some methods to show the prediction results of certain dataset. Those datasets have ten different labels. So the prediction results of one model also have ten point. I found some methods to draw point with three dim. However, I did not know how to convert the 10-D point to 3-D point reasonably.<br>
<div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/3X/0/2/02d37c78c91a476722e7f6e2a6353453c0604736.png" data-download-href="https://discuss.pytorch.org/uploads/default/02d37c78c91a476722e7f6e2a6353453c0604736" title="Screen Shot 2022-08-15 at 11.03.36 pm"><img src="https://discuss.pytorch.org/uploads/default/optimized/3X/0/2/02d37c78c91a476722e7f6e2a6353453c0604736_2_656x499.png" alt="Screen Shot 2022-08-15 at 11.03.36 pm" data-base62-sha1="p03QBOAr6mKLxXVhRFXge2XBj0" width="656" height="499" srcset="https://discuss.pytorch.org/uploads/default/optimized/3X/0/2/02d37c78c91a476722e7f6e2a6353453c0604736_2_656x499.png, https://discuss.pytorch.org/uploads/default/original/3X/0/2/02d37c78c91a476722e7f6e2a6353453c0604736.png 1.5x, https://discuss.pytorch.org/uploads/default/original/3X/0/2/02d37c78c91a476722e7f6e2a6353453c0604736.png 2x" data-dominant-color="F1F1F0"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">Screen Shot 2022-08-15 at 11.03.36 pm</span><span class="informations">914×696 306 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div></p>
Not sure how to treat each point within a batch separately

rushil: <p>Hey, I am working with PyTorch and cvxpylayers together. I am training a model which first predicts a value from an image (regression) and then uses that value to solve an optimization problem defined in cvxpylayers. The gradients are fed backward after solving the optimization.<br>
I use a batch size of 64, which seemed to be good for the first half (regression from image) but then for some reason the whole 64 size batch of predicted values is inputted to the cvxpylayer, which is only meant to read 1 input.<br>
Any ideas on how I can fix my method to resolve this?</p>

nivek: <p>Is it possible for you provide a minimal, run-able code snippet so that we can see how your code is structured?</p>

rushil: <p>Sorry for the late update - I was able to solve this already from the description under line 119 here <img src="https://discuss.pytorch.org/images/emoji/apple/slight_smile.png?v=12" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p><aside class="onebox githubblob" data-onebox-src="https://github.com/cvxgrp/cvxpylayers/blob/master/cvxpylayers/torch/cvxpylayer.py">
  <header class="source">

      <a href="https://github.com/cvxgrp/cvxpylayers/blob/master/cvxpylayers/torch/cvxpylayer.py" target="_blank" rel="noopener nofollow ugc">github.com</a>
  </header>

  <article class="onebox-body">
    <h4><a href="https://github.com/cvxgrp/cvxpylayers/blob/master/cvxpylayers/torch/cvxpylayer.py" target="_blank" rel="noopener nofollow ugc">cvxgrp/cvxpylayers/blob/master/cvxpylayers/torch/cvxpylayer.py</a></h4>


      <pre><code class="lang-py">import diffcp
import time
import cvxpy as cp
from cvxpy.reductions.solvers.conic_solvers.scs_conif import \
    dims_to_solver_dict
import numpy as np

try:
    import torch
except ImportError:
    raise ImportError("Unable to import torch. Please install at "
                      "https://pytorch.org.")

torch_major_version = int(torch.__version__.split('.')[0])
if torch_major_version &lt; 1:
    raise ImportError("cvxpylayers requires PyTorch &gt;= 1.0; please "
                      "upgrade your installation of PyTorch, which is "
                      "version %s." % torch.__version__)


</code></pre>



  This file has been truncated. <a href="https://github.com/cvxgrp/cvxpylayers/blob/master/cvxpylayers/torch/cvxpylayer.py" target="_blank" rel="noopener nofollow ugc">show original</a>

  </article>

  <div class="onebox-metadata">
    
    
  </div>

  <div style="clear: both"></div>
</aside>
How should I write this "Custom Loss Function"?

hashfury42: <p>Hi, I want to custom a loss function in Pytorch to implement the following functions:</p>
<ol>
<li>This is a binary classification problem. This loss function evaluates the Precision of the sample that exceeds a certain probability ranking quantile</li>
<li>This is an example: y_prob_ preds = [0.3, 0.5, 0.7, 0.8,0.9], y_ true=[0, 0, 0, 1, 1]<br>
When the prediction probability is greater than 60% quantile of all probs, the precision (loss) = 2 / 3</li>
</ol>
<p>Is there anyone who can offer some professional advice？</p>
<p>Thank you very much !</p>
Dictionary input to scripted model

111392: <p>I would like to use a dictionary as input to the ScriptModule in C++</p>
<pre><code class="lang-auto">  auto x = torch::OrderedDict&lt;std::string, torch::Tensor&gt;();
  x.insert("feat1", torch::rand({1, 10, 64, 64}));
  x.insert("feat2", torch::rand({1, 20, 16, 16}));
  x.insert("feat3", torch::rand({1, 30, 8, 8}));
  auto ouput = module({x});
</code></pre>
<p>however I got following error</p>
<blockquote>
<p>error: no match for call to ‘(torch::jit::script::Module {aka torch::jit::Module}) ()’<br>
35 |     auto ouput = module({x});</p>
</blockquote>
<p>do we have way to use dictionary as input in c++</p>

111392: <p>solved<br>
I can use torch::Dict instead of torch::OrderedDict.</p>
<pre><code class="lang-auto">    auto x = torch::Dict&lt;std::string, torch::Tensor&gt;();
    x.insert("feat1", torch::rand({1, 10, 64, 64}));
    x.insert("feat2", torch::rand({1, 20, 16, 16}));
    x.insert("feat3", torch::rand({1, 30, 8, 8}));
    auto ouput = module({x});
    std::cout &lt;&lt; ouput.toGenericDict().at("feat1") &lt;&lt; std::endl;
</code></pre>
[Android] Process gets killed after forwarding to the model

TimPushkin: <p>I’m trying to use <a href="https://github.com/TimPushkin/SuperPointPretrainedNetwork/blob/4f3926f66fe7eb98eedf0cd4963161a4e9d04407/demo_superpoint.py#L72" rel="noopener nofollow ugc">this SuperPoint model</a> in my Android application. It has pretrained weights and I save it for mobile like so:</p>
<pre><code class="lang-python">module = SuperPointNet()
module.load_state_dict(torch.load("..."))
module.eval()

torch.quantization.fuse_modules(
    module,
    modules_to_fuse=[["conv1a", "relu1a"], ["conv1b", "relu1b"],
                     ["conv2a", "relu2a"], ["conv2b", "relu2b"],
                     ["conv3a", "relu3a"], ["conv3b", "relu3b"],
                     ["conv4a", "relu4a"], ["conv4b", "relu4b"],
                     ["convPa", "reluPa"], ["convDa", "reluDa"]],
    inplace=True
)

scripted = torch.jit.script(module)
scripted._save_for_lite_interpreter("...")
</code></pre>
<p>The saved model works absolutely fine with images somewhere up to 720p. But when I try to forward larger images, it runs for a while, then UI starts lagging, I get the messages like these in logs (these are taken from an emulator, but on real devices the behaviour is the same), and eventually the process gets killed by the system (because the app stops responding, I figure):</p>
<pre><code class="lang-auto">2022-08-15 08:57:54.339 7249-7249/com.github.kpdandroid I/Choreographer: Skipped 30 frames!  The application may be doing too much work on its main thread.
2022-08-15 08:57:54.965 7249-7280/com.github.kpdandroid D/EGL_emulation: app_time_stats: avg=1255.40ms min=1255.40ms max=1255.40ms count=1
2022-08-15 08:57:55.080 7249-7552/com.github.kpdandroid I/OpenGLRenderer: Davey! duration=2458ms; Flags=0, FrameTimelineVsyncId=24646, IntendedVsync=439844396372, Vsync=440361063018, InputEventId=0, HandleInputStart=440834660800, AnimationStart=440834725000, PerformTraversalsStart=441327235600, DrawStart=441465262000, FrameDeadline=439877729704, FrameInterval=440362785000, FrameStartTime=16666666, SyncQueued=441576657100, SyncStart=441607291100, IssueDrawCommandsStart=441639554200, SwapBuffers=442253047100, FrameCompleted=442333966600, DequeueBufferDuration=98000, QueueBufferDuration=37406400, GpuCompleted=442298839300, SwapBuffersCompleted=442333966600, DisplayPresentTime=35188667079900, 
</code></pre>
<p>Of course, I don’t run call <code>forward()</code> on main thread. This happends both when I use CameraX with <code>ImageAnalysis</code> executed on a dedicated <code>Executors.newSingleThreadExecutor()</code> and when I try to run the model on images from file system in a coroutine launched in <code>Dispatchers.Default</code> context (I also tried launching on a dedicated thread, but it doesn’t help).</p>
<p>I tried to set the number of threads PyTorch uses to a single one with <code>PyTorchAndroid.setNumThreads(1)</code>, but to no avail.</p>
<p>What can I do with this?</p>
M1 mps error v1.12.1 vae example

Jianshu_Zhao: <p>Hello Team,</p>
<p>M1 pro van example (PyTorch) example vae: <a href="https://github.com/pytorch/examples/blob/main/vae/main.py" class="inline-onebox" rel="noopener nofollow ugc">examples/main.py at main · pytorch/examples · GitHub</a>, I use mps:<br>
device = torch.device(“mps” if torch.backends.mps.is_available() else “cpu”)</p>
<p>However the example return non after 10 epoch. For CPU only, every is ok.</p>
<p>Any idea?</p>
<p>Thanks,</p>
How to use torch.topk on multiple dimensional tensor

Givan: <p>I want to do the feature selection based on the score map with two dimensional index. I can realize this without batch of tensor and batch also can be implemented with a for loop. But I want to know more elegant code to realize this. The following my code.</p>
<pre><code class="lang-auto">feature_map = torch.randn(8, 256, 64, 64)  # [batch_size, C, H, W]
score_map = torch.randn(8, 1, 64, 64)      # [batch_size, 1, H, W]

batch_select_feature = []
for i in range(feature_map.size(0)):
    cur_score_map = score_map[i].detach().cpu().squeeze()
    val, idx = torch.topk(cur_score_map.flatten(), topk)
    topk_idx = np.array(np.unravel_index(idx.numpy(), cur_score_map.shape)).T 
    select_feature = torch.cat([feature_map[i, :, x, y].unsqueeze(0) for x, y in topk_idx]) 
    batch_select_feature.append(select_feature.unsqueeze(0))
batch_select_feature = torch.cat(batch_select_feature)
</code></pre>

Givan: <p>Any solution? Thanks</p>
Transformer Positional Encoding Class

maxrivera: <p>I’m learning a transformer implementation through this Kaggle tutorial <a href="https://www.kaggle.com/code/arunmohan003/transformer-from-scratch-using-pytorch/notebook" class="inline-onebox" rel="noopener nofollow ugc">Transformer from scratch using pytorch | Kaggle</a> . I don’t understand several of the lines of code in the PositionalEmbedding class:</p>
<pre><code class="lang-auto"># register buffer in Pytorch -&gt;
# If you have parameters in your model, which should be saved and restored in the state_dict,
# but not trained by the optimizer, you should register them as buffers.


class PositionalEmbedding(nn.Module):
    def __init__(self,max_seq_len,embed_model_dim):
        """
        Args:
            seq_len: length of input sequence
            embed_model_dim: demension of embedding
        """
        super(PositionalEmbedding, self).__init__()
        self.embed_dim = embed_model_dim

        pe = torch.zeros(max_seq_len,self.embed_dim)
        for pos in range(max_seq_len):
            for i in range(0,self.embed_dim,2):
                pe[pos, i] = math.sin(pos / (10000 ** ((2 * i)/self.embed_dim)))
                pe[pos, i + 1] = math.cos(pos / (10000 ** ((2 * (i + 1))/self.embed_dim)))
        pe = pe.unsqueeze(0)
        self.register_buffer('pe', pe)


    def forward(self, x):
        """
        Args:
            x: input vector
        Returns:
            x: output
        """
      
        # make embeddings relatively larger
        x = x * math.sqrt(self.embed_dim)
        #add constant to embedding
        seq_len = x.size(1)
        x = x + torch.autograd.Variable(self.pe[:,:seq_len], requires_grad=False)
        return x
</code></pre>
<ul>
<li>What is unsqueeze() doing? I’m guessing it adds a batch dimensions but I’m not sure…</li>
<li>Why are we using “self.register_buffer(‘pe’, pe)” ? What is this doing? Why can’t we just do “self.pe = pe”?</li>
<li>I don’t understand these 2 lines of code at all:</li>
</ul>
<pre><code class="lang-auto">        seq_len = x.size(1)
        x = x + torch.autograd.Variable(self.pe[:,:seq_len]```

If anyone has experience with implementing transformers I would appreciate the help! Thanks</code></pre>

maxrivera: <p>And to add to that, why does PositionalEmbedding class need to inherit from torch.nn.Module at all? A Positional Encoding vector just contains positional information, it shouldn’t have any learnable parameters. It’s supposed to be added to the actual learnable embedding matrix…</p>
Need a robust way to resize

blackbirdbarber: <p>Hi,</p>
<ol>
<li>I need a way to resize the inputs like  <code>MaxPool2d</code> do with kernel size</li>
</ol>
<pre><code class="lang-auto">nn.MaxPool2d(kernel_size=2)
</code></pre>
<p>but in a form like <a href="https://pytorch.org/vision/main/generated/torchvision.transforms.functional.resize.html" rel="noopener nofollow ugc"><code>Resize</code></a> because <code>Resize</code> has interpolation mode to set.</p>
<p>I checked a bit, seams like  neither of the <em>pooling methods</em> has interpolation parameter to set.</p>
<ol start="2">
<li>The other thing I need is something like maxunpooling2d with kernel size. I would like to set the kernel size of 2 to double the size of the input axes keeping the max values. Currently as I checked maxunpooling2d sets 0 for elements other than indices, and you need to provide the indices.</li>
</ol>

ptrblck: <aside class="quote no-group" data-username="blackbirdbarber" data-post="1" data-topic="158866">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/b/6de8d8/48.png" class="avatar"> blackbirdbarber:</div>
<blockquote>
<p>I checked a bit, seams like neither of the <em>pooling methods</em> has interpolation parameter to set.</p>
</blockquote>
</aside>
<p>Pooling layers are not interpolating but are applying the pool operation on the used window.<br>
E.g. <code>MaxPool2d</code> will apply <code>torch.max</code> on each window and will not try to calculate any interpolated values, <code>AvgPool2d</code> will use <code>torch.mean</code> etc.</p>
<p>I don’t fully understand which values should be interpolated at all using this window approach.</p>

blackbirdbarber: <p>Actually I only needed <code>F.Interpolate(x, scale_factor)</code>. <img src="https://discuss.pytorch.org/images/emoji/apple/star_struck.png?v=12" title=":star_struck:" class="emoji" alt=":star_struck:" loading="lazy" width="20" height="20"></p>
Negative samples, ValueError Expected target boxes to be a tensor of shape [N, 4] got torch.Size([0])

David_Gleba: <p>I posted a question on Stackoverflow.</p>
<p>Can anyone comment?</p>
<aside class="onebox stackexchange" data-onebox-src="https://stackoverflow.com/questions/73340770/pytorch-torchvision-negative-samples-valueerror-expected-target-boxes-to-be-a">
  <header class="source">

      <a href="https://stackoverflow.com/questions/73340770/pytorch-torchvision-negative-samples-valueerror-expected-target-boxes-to-be-a" target="_blank" rel="noopener nofollow ugc">stackoverflow.com</a>
  </header>

  <article class="onebox-body">
      <a href="https://stackoverflow.com/users/2744870/david-gleba" target="_blank" rel="noopener nofollow ugc">
    <img alt="David Gleba" src="https://www.gravatar.com/avatar/05ac79a6f6cbaf3860515ad78e15bb1c?s=256&amp;d=identicon&amp;r=PG" class="thumbnail onebox-avatar" width="256" height="256">
  </a>

<h4>
  <a href="https://stackoverflow.com/questions/73340770/pytorch-torchvision-negative-samples-valueerror-expected-target-boxes-to-be-a" target="_blank" rel="noopener nofollow ugc">Pytorch torchvision, negative samples, ValueError Expected target boxes to be a tensor of shape [N, 4] got torch.Size([0])</a>
</h4>

<div class="tags">
  <strong>python, pytorch, bounding-box, torchvision</strong>
</div>

<div class="date">
  asked by
  
  <a href="https://stackoverflow.com/users/2744870/david-gleba" target="_blank" rel="noopener nofollow ugc">
    David Gleba
  </a>
  on <a href="https://stackoverflow.com/questions/73340770/pytorch-torchvision-negative-samples-valueerror-expected-target-boxes-to-be-a" target="_blank" rel="noopener nofollow ugc">12:10AM - 13 Aug 22 UTC</a>
</div>

  </article>

  <div class="onebox-metadata">
    
    
  </div>

  <div style="clear: both"></div>
</aside>
Torch.nn modules dont accept 0-batch dim tensors on gpu

cheyennee: <p>torch.nn modules accept 0-batch dim tensors on cpu, however I found that torch.nn modules  don’t accept 0-batch dim tensors on gpu. Is it reasonable?<br>
I run a piece of code on cpu and gpu, the result is {‘res_cpu’: (tensor([], size=(0, 1, 1)), tensor([], size=(0, 1, 1), dtype=torch.int64)), ‘err_gpu’: ‘ERROR:CUDA error: invalid configuration argument’}. I think cpu’s result should be consistent with gpu’s result. I wonder if my needs are reasonable😂</p>

ptrblck: <p>Could you post a code snippet showing this error?<br>
Some layers seem to work, e.g. as seen here:</p>
<pre><code class="lang-python">conv = nn.Conv2d(3, 3, 3).cuda()
x = torch.randn(0, 3, 24, 24).cuda()

out = conv(x)
print(out)
# tensor([], device='cuda:0', size=(0, 3, 22, 22),
#        grad_fn=&lt;ConvolutionBackward0&gt;)
</code></pre>
<p>and you are right that no CUDA error should be raised (even if I don’t really understand the use case of <code>0-dim</code> tensors <img src="https://discuss.pytorch.org/images/emoji/apple/wink.png?v=12" title=":wink:" class="emoji" alt=":wink:" loading="lazy" width="20" height="20"> ).</p>

cheyennee: <p>The code snippet is as follows:</p>
<pre><code class="lang-auto">results = dict()
import torch
arg_1 = 2
arg_2 = 50
arg_3 = True
arg_class = torch.nn.MaxPool1d(arg_1,stride=arg_2,return_indices=arg_3,)
arg_4 = torch.rand([0, 1, 49], dtype=torch.float32)
try:
  results["res_cpu"] = arg_class(arg_4)
except Exception as e:
  results["err_cpu"] = "ERROR:"+str(e)
arg_class = arg_class.cuda()
arg_5 = arg_4.clone().cuda()
try:
  results["res_gpu"] = arg_class(arg_5)
except Exception as e:
  results["err_gpu"] = "ERROR:"+str(e)
print(results)
</code></pre>
<p>The result is : {‘res_cpu’: (tensor([], size=(0, 1, 1)), tensor([], size=(0, 1, 1), dtype=torch.int64)), ‘err_gpu’: ‘ERROR:CUDA error: invalid configuration argument’}.<br>
My torch version is 1.8.1, cuda version is 1.11.0. I’m not sure whether it runs differently in latest pytorch w(ﾟДﾟ)w</p>

ptrblck: <p>The code snippet works for me and prints:</p>
<pre><code class="lang-python">{'res_cpu': (tensor([], size=(0, 1, 1)), tensor([], size=(0, 1, 1), dtype=torch.int64)), 'res_gpu': (tensor([], device='cuda:0', size=(0, 1, 1)), tensor([], device='cuda:0', size=(0, 1, 1), dtype=torch.int64))}
</code></pre>
<p>so your PyTorch installations is probably too old.</p>

cheyennee: <p>Get it. I will install latest pytorch. Thanks <img src="https://discuss.pytorch.org/images/emoji/apple/stuck_out_tongue_closed_eyes.png?v=12" title=":stuck_out_tongue_closed_eyes:" class="emoji" alt=":stuck_out_tongue_closed_eyes:" loading="lazy" width="20" height="20"></p>
Installing torchaudio makes cuda unusable

skerlet_flandorle: <p>Installing torchaudio makes cuda unusable</p>
<p>I found a similar question, but it didn’t work because my environment is not LINAX</p><aside class="quote quote-modified" data-post="1" data-topic="18512">
  <div class="title">
    <div class="quote-controls"></div>
    <img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/a/4491bb/48.png" class="avatar">
    <a href="https://discuss.pytorch.org/t/installing-torchaudio-on-google-colab/18512">Installing torchaudio on google colab</a> <a class="badge-category__wrapper " href="/c/audio/9"><span data-category-id="9" data-drop-close="true" class="badge-category "><span class="badge-category__name">audio</span></span></a>
  </div>
  <blockquote>
    Hi, 
I am trying to install the torchaudio library in google Colaboratory notebook. However I get this dependency error: 
running install
running bdist_egg
running egg_info
creating torchaudio.egg-info
writing torchaudio.egg-info/PKG-INFO
writing dependency_links to torchaudio.egg-info/dependency_links.txt
writing top-level names to torchaudio.egg-info/top_level.txt
writing manifest file 'torchaudio.egg-info/SOURCES.txt'
reading manifest file 'torchaudio.egg-info/SOURCES.txt'
writing manifest fi…
  </blockquote>
</aside>

<p>tried</p>
<pre><code class="lang-auto">conda install sox libsox-dev libsox-fmt-all
pip install git+git://github.com/pytorch/audio
</code></pre>
<p>result<br>
ERROR: Command errored out with exit status 1: ‘C:\Users\PC_User\Anaconda3\envs\testflan22a08m14d\python.exe’ ‘C:\Users\PC_User\Anaconda3\envs\testflan22a08m14d\lib\site-packages\pip\ _vendor\pep517_in_process.py’ get_requires_for_build_wheel ‘C:\Users\PC_User\AppData\Local\Temp\tmpp4f2vitk’ Check the logs for full command output.</p>
<p>I also tried to download it and put it in, but it doesn’t work</p>
<pre><code class="lang-auto">Users\PC_User&gt;git clone -q git://github.com/pytorch/audio
 Users\PC_User&gt;pip install audio
</code></pre>
<p>result<br>
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.</p>
<p>my environment<br>
anaconda<br>
os win10<br>
python 3.7<br>
pytorch 1.5.0 py3.7_cuda101_cudnn7_0 pytorch</p>

ptrblck: <p>Your PyTorch binary is quite old (<code>1.5.0</code> with the CUDA 10.1 runtime) so I would recommend to try to use the latest PyTorch release since you are trying to also install the latest <code>torchaudio</code> build.</p>
AttributeError: 'collections.OrderedDict' object has no attribute 'seek'

Sri_Nirmal: <p>I tried to import SSDlite model. And when I proceed on doing so I am getting this error. Here’s the code snippet and the error that  I am receiving.<br>
<div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/3X/a/b/abd1403bb33c184c7c27db3be56bd3f8f35b4080.png" data-download-href="https://discuss.pytorch.org/uploads/default/abd1403bb33c184c7c27db3be56bd3f8f35b4080" title="code error"><img src="https://discuss.pytorch.org/uploads/default/optimized/3X/a/b/abd1403bb33c184c7c27db3be56bd3f8f35b4080_2_690x355.png" alt="code error" data-base62-sha1="ovXXRdav7DctT8YoQqarQtvAiv6" width="690" height="355" srcset="https://discuss.pytorch.org/uploads/default/optimized/3X/a/b/abd1403bb33c184c7c27db3be56bd3f8f35b4080_2_690x355.png, https://discuss.pytorch.org/uploads/default/optimized/3X/a/b/abd1403bb33c184c7c27db3be56bd3f8f35b4080_2_1035x532.png 1.5x, https://discuss.pytorch.org/uploads/default/original/3X/a/b/abd1403bb33c184c7c27db3be56bd3f8f35b4080.png 2x" data-dominant-color="272828"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">code error</span><span class="informations">1183×609 55.7 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div></p>
<p>Can you please suggest me on how to import the model and get the performance metrics</p>

ptrblck: <p><code>model</code> seems to be the <code>state_dict</code> and not an <code>nn.Module</code> object.<br>
Create the model object before and load the <code>state_dict</code> afterwards:</p>
<pre><code class="lang-python">model = MyModel() # create model object
model.load_state_dict(torch.load(path))
</code></pre>
Retrieval Mean Reciprocal Rank (MRR) in torch model training

Aldebaran: <p>Suppose that after a forward pass, the model outputs a prediction as shown below:</p>
<pre><code class="lang-python">{
    "query_idx": tensor([0, 1, ..., 2]),
    "query_rpr": tensor([
        [0.1790, 0.4046, ..., 0.5882],
            ...
        [0.1207, 0.6405, ..., 0.0214]
    ]),
    "doc_idx": tensor([9, 5, ..., 7]),
    "doc_rpr": tensor([
        [0.290, 0.1045, ..., 0.8852],
            ...
        [0.774, 0.4056, ..., 0.1012]
    ])
}
</code></pre>
<p>where:</p>
<ul>
<li>
<code>query_idx</code>: is the query index;</li>
<li>
<code>query_rpr</code>: is the query embedding;</li>
<li>
<code>doc_idx</code>: is the document idx;</li>
<li>
<code>doc_rpr</code>: is the document representation.</li>
</ul>
<p>and the relevance map contains:</p>
<pre><code class="lang-python">{ # query_idx -&gt; (relevant) doc_ids
    0: [31, 74, ..., 85]
    1: [15, 18, ..., 91] 
        ...
    541247: [17, 32, ..., 49]
}
    
</code></pre>
<p>Therefore, how compute the MRR metric during model training?</p>
Memory Leak after moving tensor to CPU

Anirudh_Buvanesh1: <p>Hi everyone, I have the following 2 cases in the iteration loop of one 1 epoch, Simplified code is below</p>
<p><strong>Case 1</strong></p>
<pre><code class="lang-auto">for index, data in enumerate(train_loader):
   input = data['input']
   output = model(input)
</code></pre>
<p><strong>Case 2</strong></p>
<pre><code class="lang-auto">num_train_examples = 50
output_size = 20
outputs = np.zeros(num_train_examples, output_size)
for index, data in enumerate(train_loader):
   input = data['input']
   # Provides the index of training points in this batch
   indices = data['index'] 
   output = model(input).detach().cpu().numpy()
   outputs[indices] = np.array(output)
   del output
</code></pre>
<p>In case 1 I observe a constant memory being used by the code, but in case 2 I see the memory usage increases with the number of iterations of the loop.</p>
<p>I monitor memory usage with a snippet like this in the iteration loop</p>
<pre><code class="lang-auto">mem = psutil.virtual_memory()
print(f' {mem.percent:5} - {mem.free/1024**3:10.2f} - {mem.available/1024**3:10.2f} - {mem.used/1024**3:10.2f}')
</code></pre>
<p>My question is why is <code>output</code> not garbage collected as there are no references to output anymore? I suspect that the assignment <code>outputs[indices] = np.array(output)</code> might be the cause, would appreciate if someone could explain what the right way would be to handle it to ensure constant memory usage across the iteration loop</p>
Update tqdm loop for two models

kabbas570: <p>Hello Everyone,<br>
I am training two models together, each with a separate loss function and optimizer… if I update tqdm loop for the first model do I need to update it for the second as well? Or I should only update it after the second model… the sample code looks like this,</p>
<h4>
<a name="model_1-training-loop-1" class="anchor" href="#model_1-training-loop-1"></a>Model_1 Training Loop</h4>
<p>with torch.cuda.amp.autocast():<br>
out1 = model1(img)<br>
loss1 = loss_fn1(out1, gt1)<br>
# backward<br>
optimizer1.zero_grad()<br>
scaler.scale(loss1).backward()<br>
scaler.step(optimizer1)<br>
scaler.update()<br>
# update tqdm loop<br>
loop.set_postfix(loss=loss.item())  #### tqdm loop is updated here for first model   (1)<br>
train_losses1.append(loss.item())</p>
<h4>
<a name="model_2-training-loop-2" class="anchor" href="#model_2-training-loop-2"></a>Model_2 Training Loop</h4>
<p>with torch.cuda.amp.autocast():<br>
out2 = model2(img_batch)<br>
loss2 = loss_fn1(out2, gt_batch)<br>
# backward<br>
optimizer2.zero_grad()<br>
scaler.scale(loss2).backward()<br>
scaler.step(optimizer2)<br>
scaler.update()<br>
loop.set_postfix(loss=loss2 .item())  ### tqdm loop is updated here for second model   (2)<br>
train_losses2.append(loss2 .item())</p>
<p>Should I  remove the (2) line of code, or is this a valid practice?<br>
Thanks<br>
Cheers</p>
The size of tensor a (516) must match the size of tensor b (513) at non-singleton dimension 3

rezraz: <p>Hi,</p>
<p>first i run an algorithm with its dataset and that was ok. the link of the code is in the following : <a href="https://github.com/sanghyun-son/EDSR-PyTorch" rel="noopener nofollow ugc">EDSR-<strong>PyTorch</strong></a><br>
(What this code does is that it receives an image with two modes of high and low resolution and improves the quality of the image with low resolution image and finally compares the improved image with the image with high resolution to check the quality of the improvement. does So, the input images are two high and low resolution images from the same photo.)</p>
<p>After that i tried to used my <strong>RGB</strong> dataset to test and run this code, but i got this error :</p>
<pre><code class="lang-auto">   The size of tensor a (516) must match the size of tensor b (513) at non-singleton dimension 3
</code></pre>
<p><strong>Now i wanto to know, how can i fix this error?</strong></p>
<p>As an additional explanation, I changed the size of my input image to 513 but still got the same error:<br>
RuntimeError: The size of tensor a (3) must match the size of tensor b (4) at non-singleton dimension 1</p>
Python `in` operator in torch

Jay_Chan: <p>I am accidentally using <code>in</code> operator to check whether a two-dimensional torch contains a single vector. But the results are not the same as expected?</p>
<p>Intuitively, test 2 3 4 should also fail but they didn’t.</p>
<p>My platform: windows 10, torch1.12.0+cpu.</p>
<pre><code class="lang-auto">    import torch
    b = torch.LongTensor([
        [1, 2, 3],
        [4, 5, 6],
    ])
    # test 1 
    assert torch.LongTensor([1, 2, 3]) in b  # pass as expected 
    # test 2
    assert torch.LongTensor([1, 2, 4]) in b  # why pass ?
    # test 3
    assert torch.LongTensor([1, 2, 8]) in b  # why pass ?
    # test 4
    assert torch.LongTensor([2, 2, 6]) in b  # why pass ?
    # test 5 
    assert torch.LongTensor([8, 8, 8]) in b  # fail as expected

</code></pre>
Share gradients in multiprocessing

chengyangfu: <p>Hi,<br>
I am wondering if there is a way to share gradients in multiprocessing.<br>
Currently, I am following the [hogwild] (<a href="http://pytorch.org/docs/master/notes/multiprocessing.html#hogwild" rel="nofollow noopener">http://pytorch.org/docs/master/notes/multiprocessing.html#hogwild</a>) example to run the asynchronous training. The shared model is the CPU. The local model is on the GPU and has their own or shared optimizer. Each local model can update the shared model directly.<br>
I want to modify the current case to the synchronous version. For example, each local model can upload their gradients to the shared model. After aggregating a certain amount the gradients, the shared model can update itself.  However, in this example [hogwild] (<a href="http://pytorch.org/docs/master/notes/multiprocessing.html#hogwild" rel="nofollow noopener">http://pytorch.org/docs/master/notes/multiprocessing.html#hogwild</a>), the gradient part of the shared model is not shared with other processes.</p>

Kamer_Ali_Yuksel: <p>I want to do the exact same thing (as my multiprocesses have local models on multiple GPUs) but could not figure that out yet. There are some insights in the following link where the gradients of the local model can be copied, vica versa. I guess that it should be possible to add gradients from local model to the global shared model before making the optimizer step. Please, let me also know if you figure it out.</p>
<aside class="onebox whitelistedgeneric">
  <header class="source">
      <img src="https://github.githubassets.com/favicon.ico" class="site-icon" width="16" height="16">
      <a href="https://github.com/dchetelat/acer" target="_blank" rel="nofollow noopener">GitHub</a>
  </header>
  <article class="onebox-body">
    <img src="https://avatars1.githubusercontent.com/u/8616319?s=400&amp;v=4" class="thumbnail onebox-avatar" width="60" height="60">

<h3><a href="https://github.com/dchetelat/acer" target="_blank" rel="nofollow noopener">dchetelat/acer</a></h3>

<p>PyTorch implementation of both discrete and continuous ACER - dchetelat/acer</p>


  </article>
  <div class="onebox-metadata">
    
    
  </div>
  <div style="clear: both"></div>
</aside>


benalex: <p>Did you figure it out?</p>
Negative or positive loss when using autograd.grad

Belial: <p>Hello. I have a loss function. When the calculated value gets larger, the result is better. Do I need to make the value negative or remain positive when use autograd.grad?</p>
<pre><code class="lang-auto">loss = my_loss(input) # when value gets larger, the result should be better
# do I need to use loss * -1 to make it negative?
grad += autograd.grad(loss.sum(), input)[0]
</code></pre>
<p>Thanks!</p>

AlphaBetaGamma96: <p>Hi <a class="mention" href="/u/belial">@Belial</a>,</p>
<p>When you use gradient descent you go against the gradient, so if you’re trying to minimize a loss you would do something like,</p>
<pre><code class="lang-auto">loss = my_loss(input)

optim.zero_grad()
loss.backward()
optim.step()
</code></pre>
<p>However, if you’re trying to <em>maximize</em> a loss you need to take the <em>negative</em> of the loss in order to <em>maximize</em> the loss because minimizing a negative is equivalent to maximizing a positive. You’ll want something like this (assuming you’re using an <code>optim</code> class),</p>
<pre><code class="lang-auto">loss = my_loss(input)
loss = -1. * loss #out-of-place (do NOT use *= ) we're now maximizing instead

optim.zero_grad()
loss.backward()
optim.step()
</code></pre>

Belial: <p>Sorry for my ambiguity. I am not using optim class, I only use autograd.grad to calculate the gradient.<br>
Does the same rule stiil apply?</p>

AlphaBetaGamma96: <p>The same rule applies if you’re using <code>torch.autograd.grad</code>.</p>
<p>Also check if your <code>loss</code> should be <code>loss.sum()</code> or <code>loss.mean()</code>. If you’re minimizing some statistical expectation it should be <code>mean()</code>.</p>

Belial: <p>ok. I will take a look. Thanks!</p>
SVD grad values are 'NaN'

Liran_Taib: <p>Hi all,<br>
when dealing with matrices with number of rows much greater than number of columns (X10)<br>
I’m receiving NaN grads for SVD</p>
<p>when I use matrix size of  256X15 everything is fine<br>
when I use 4096X100 I get NaN (this is the size I need)<br>
any idea why?</p>

Wei_Wang: <p>I have a similar problem. I also get NaN in the gradient. My matrix has the size of [2028, 64]. Please post the solutions if you fixed it.</p>

Hamze_Asadi: <p>There are a few solutions</p>
<p>1- You can add small amount of noise to your matrix</p>
<p>2- Since nan are for numbers that are very large or small you can use torch.nan_to_num</p>
<p>3- you can use linalg.svd(X.cpu().detach().numpy(), full_matrices=False, lapack_driver=“gesvd”), which I believe still have problem but better than torch.svd</p>

AlphaBetaGamma96: <p>The gradient of an SVD decomposition is only defined if the singular values aren’t arbitrarily close together. There’s more detail about this shown in the documentation <a href="https://pytorch.org/docs/stable/generated/torch.svd.html" rel="noopener nofollow ugc">here</a>.</p>
Attention Layer whether to play a role in the network feedforward?

MartinZhang: <p>Attention Layer whether to play a role in the network feedforward?</p>
<p>I know, Attention plays a role in training， but it’s needed for testing?</p>
<p>I find the torch.nn.Dropout in the attention.</p>
<p>I think the Dropout layer may will not  be used in testing.</p>
<pre><code class="lang-auto">class Attention(nn.Module):
    def __init__(self, dim, heads=8, dim_head=64, dropout=0.):
        super().__init__()
        inner_dim = dim_head * heads
        project_out = not (heads == 1 and dim_head == dim)

        self.heads = heads
        self.scale = dim_head ** -0.5

        self.attend = nn.Softmax(dim=-1)
        self.to_qkv = nn.Linear(dim, inner_dim * 3, bias=False)

        self.to_out = nn.Sequential(
            nn.Linear(inner_dim, dim),
            nn.Dropout(dropout)
        ) if project_out else nn.Identity()

    def forward(self, x):
        qkv = self.to_qkv(x).chunk(3, dim=-1)
        q, k, v = map(lambda t: rearrange(t, 'b p n (h d) -&gt; b p h n d', h=self.heads), qkv)

        dots = torch.matmul(q, k.transpose(-1, -2)) * self.scale
        attn = self.attend(dots)
        out = torch.matmul(attn, v)
        out = rearrange(out, 'b p h n d -&gt; b p n (h d)')
        return self.to_out(out)


</code></pre>
<p>ps: <a href="https://github.com/murufeng/awesome_lightweight_networks/blob/3917c7f919bdd5c445b07e6df617f96f1392321f/light_cnns/Transformer/mobile_vit.py#L57" rel="noopener nofollow ugc">awesome_lightweight_networks/mobile_vit.py at 3917c7f919bdd5c445b07e6df617f96f1392321f · murufeng/awesome_lightweight_networks (github.com)</a></p>

azhanmohammed: <p>Unlike dropout, attention layer is used while testing/ performing inference as well.<br>
Dropout is a regularization technique that turns off random neurons while training. You can read more about dropout <a href="https://machinelearningmastery.com/dropout-for-regularizing-deep-neural-networks/" rel="noopener nofollow ugc">here</a>.<br>
Attention on the other hand is used to enhance certain parts of the input data, telling the network which regions should be given extra emphasis to. <a href="https://medium.com/syncedreview/a-brief-overview-of-attention-mechanism-13c578ba9129" rel="noopener nofollow ugc">This blog</a> gives a good overview of attention mechanism. While attention and dropout seems similar, a neural network learns the attention map while training, and unlike dropout it is not random in nature.</p>
CPU memory usage greatly increases when moving model from cpu to gpu

aafg: <p>Hi,</p>
<p>I have trained a scaled-yolov4 object detection model in darknet, which I have converted to a pytorch model via <a href="https://github.com/Tianxiaomo/pytorch-YOLOv4" class="inline-onebox" rel="noopener nofollow ugc">GitHub - Tianxiaomo/pytorch-YOLOv4: PyTorch ,ONNX and TensorRT implementation of YOLOv4</a>. When I load the pytorch model onto my CPU, I get a very small increase in CPU memory usage (less than 0.2GB, which is the size of the .weights darknet file). However, when I run the command “model.to(‘cuda:0’)”, I get an increase in CPU memory by 2.5GB, which is strange as (1) shouldn’t it be GPU memory that increases and (2) why is it so much bigger than 0.2GB?</p>
<p>The command I use to obtain the memory usage inside my docker container is os.system(‘cat /sys/fs/cgroup/memory/memory.usage_in_bytes’). I am assuming returns CPU memory usage.</p>
<p>I’ve looked at <a href="https://discuss.pytorch.org/t/why-does-moving-a-model-to-the-gpu-increase-the-cpu-memory-usage/124078" class="inline-onebox">Why does moving a model to the GPU increase the CPU memory usage?</a> but it was pretty handwavy and I was wondering if there were other explanations for this phenomena. I do see a lot of cuda related libraries being imported, could it be due to that?</p>
LeNet5 0% validation accuracy

maxrivera: <p>I’m trying to classify chinese characters from the CASIA Chinese handwritten character database, which is a really large dataset (over 3 million examples, 7330 classes) using a LeNet5 architecture, which has been used in the past for handwritten digit classification. After 5 epochs, I have over 80% training accuracy, but &lt; 1% validation accuracy. The validation accuracy stayed at &lt;1% for all 5 epochs. I would think this means overfitting, but the LeNet5 architecture is a very small model and the  the dataset is huge, so overfitting shouldn’t be a huge problem right now. Is a LeNet5 model not appropriate for this dataset? I could try a larger model, but wouldn’t that  just make overfitting worse? Does anyone have any suggestions on what direction to go from here?</p>

azhanmohammed: <p>Can you please share your training code? Maybe there is some error there. Hard to say without taking a look.</p>
A out of memory error when using list with tensor

BuxianChen: <pre><code class="lang-auto">import torch
n = 1000
y = torch.rand(5000,5000,10)
a = []
for i in range(n):
    x = torch.rand(5000, 5000, 10)
    y = torch.cat([x[:5], y], axis=0)
    a.append(y[0,0,0])
</code></pre>
<p>I try this code, but found the memory grow dramatically. But if I remove the code of list <code>a</code>, then the problem goes away. What’s the problem?</p>

ptrblck: <p><code>y</code> takes ~1GB of memory and you are concatenating itself with <code>x[:5]</code> thus increasing it in each iteration by a bit (the temp. tensor creation would of course use additional memory). Afterwards you are then appending a single tensor, so your peak memory should increase by ~2GB (with the slight increase in each iteration).</p>

BuxianChen: <p>Maybe I should clarify, The snippet I show will occupy memory far more then ~2GB. I suspect in every iteration, the variable <code>x</code> is not be released properly. But if I remove all code about the list <code>a</code> (the code below), the memory occupied is around ~2GB.</p>
<pre><code class="lang-auto">import torch
n = 1000
y = torch.rand(5000,5000,10)
for i in range(n):
    x = torch.rand(5000, 5000, 10)
    y = torch.cat([x[:5], y], axis=0)
</code></pre>
<p>So I don’t know the differences.</p>

BuxianChen: <p>hello, I use a more cleaner snippet to clarify my problem, this code will cause memory occupation increasing rapidly.</p>
<pre><code class="lang-auto">import torch
n = 1000
a = []
for i in range(n):
    x = torch.rand(5000, 5000, 10)
    a.append(x[0, 0, 0])
</code></pre>
<p>But the equivalent version for <strong>numpy</strong> will not</p>
<pre><code class="lang-auto">import numpy as np
n = 1000
a = []
for i in range(n):
    x = np.random.rand(5000, 5000, 10)
    a.append(x[0, 0, 0])
</code></pre>
Memory issues even after setting memory_conf

Felipe_bivort_haiek: <p>I am currently getting out of memory errors. And I have too much memory reserved comparesdto what has actually been allocated.</p>
<blockquote>
<p>(GPU 0; 23.70 GiB total capacity; 15.52 GiB already allocated; 1.29 GiB free; 20.33 GiB reserved in total by PyTorch)</p>
</blockquote>
<p>I am setting the values for PYTORCH_CUDA_ALLOC_CONF with</p>
<pre><code class="lang-auto">
os.environ["PYTORCH_CUDA_ALLOC_CONF"] = 'max_split_size_mb:10000,garbage_collection_threshold:0.7'
</code></pre>
<p>But it does not seem to be changing anything.</p>
Extracting speccific layers' output from a module list

Tm4: <p>I’m using a <a href="https://github.com/facebookresearch/TimeSformer/blob/main/timesformer/models/vit.py#L291" rel="noopener nofollow ugc">pretrained model</a> in which there are several self_attentions sequentially stacked each one after another and the number of them is 12. I need to extract the output of the fourth and 10th blocks of this sequential layers. In the following script, the <code>BLock</code> represents each self-attention layer:</p>
<pre><code>dpr = [x.item() for x in torch.linspace(0, 0.1, 12)]  # stochastic depth decay rule
    
    self.blocks = nn.ModuleList([
        Block(
            dim=embed_dim, num_heads=num_heads, mlp_ratio=mlp_ratio, qkv_bias=qkv_bias, qk_scale=qk_scale,
            drop=drop_rate, attn_drop=attn_drop_rate, drop_path=dpr[i], norm_layer=norm_layer, attention_type=self.attention_type)
        for i in range(12)])
</code></pre>
<p>The self-attention layers (stack of <code>Block</code>) are as follows:</p>
<pre><code>## Attention blocks
    for blk in self.blocks:
        x = blk(x, B, T, W)
</code></pre>
<p>How can I extract the fourth and the 10th layers’ output?</p>

ptrblck: <p>You can use forward hooks as described <a href="https://discuss.pytorch.org/t/how-can-l-load-my-best-model-as-a-feature-extractor-evaluator/17254/6">here</a> and register them to the 4th and 10th layers.</p>

Tm4: <p><a class="mention" href="/u/ptrblck">@ptrblck</a>  ,Thanks a lot .</p>
Libtorch tensor to image with OpenCV

Isabela_Marinho: <p>Hello!<br>
I’m trying to plot an image using OpenCV, from a torch::tensor with rgb values (dim=100x100x3), but the output image is all black. The rgb tensor has float values between 0 and 1.</p>
<p>I’m using the following code:</p>
<pre><code class="lang-auto">auto img = cv::Mat(100, 100, CV_32FC3, rgb.data_ptr&lt;float&gt;());
cv::cvtColor(img, img, cv::COLOR_BGR2RGB);
cv::imwrite("../new_img.jpg", img);
</code></pre>
<p>Am I missing something?</p>

ptrblck: <p><code>imwrite</code> expects int8 or int16 images as explained in the <a href="https://docs.opencv.org/2.4/modules/highgui/doc/reading_and_writing_images_and_video.html?highlight=imwrite#imwrite">docs</a>:</p>
<blockquote>
<p>The function <code>imwrite</code> saves the image to the specified file. The image format is chosen based on the <code>filename</code> extension (see <a href="https://docs.opencv.org/2.4/modules/highgui/doc/reading_and_writing_images_and_video.html"><code>imread()</code></a> for the list of extensions). Only 8-bit (or 16-bit unsigned (<code>CV_16U</code>) in case of PNG, JPEG 2000, and TIFF) single-channel or 3-channel (with ‘BGR’ channel order) images can be saved using this function. If the format, depth or channel order is different, use <a href="https://docs.opencv.org/2.4/modules/core/doc/basic_structures.html"><code>Mat::convertTo()</code></a> , and <a href="https://docs.opencv.org/2.4/modules/imgproc/doc/miscellaneous_transformations.html"><code>cvtColor()</code></a> to convert it before saving. Or, use the universal <a href="https://docs.opencv.org/2.4/modules/core/doc/xml_yaml_persistence.html#FileStorage"><code>FileStorage</code></a> I/O functions to save the image to XML or YAML format.</p>
</blockquote>
Custom cuda kernel using for backward pass using numba?

Luke_Taylor: <p>I am looking to write a custom kernel for the backward pass in my model to speedup training. The tutorial posted on PyTorch website goes into detail writing c++ and cuda code<br>
<a href="https://pytorch.org/tutorials/advanced/cpp_extension.html" class="onebox" target="_blank" rel="noopener nofollow ugc">https://pytorch.org/tutorials/advanced/cpp_extension.html</a></p>
<p>Given that numba is pretty straightforward for writing cuda kernels, would there be any performance hurdle in doing so? It seems like data on the GPU can be passed between numba and pytorch without much performance issue.</p>
<p>Has anyone tried this? Does anyone have some words of warning against doing so?</p>
<p>Thanks!</p>

ptrblck: <p>I haven’t compared any implementations and are not aware of comparisons, but would recommend to just go for it. I’m not aware of any specific limitations and would probably stick to what would work best for you.</p>