Subtensor add and division in libtorch

Esmaeil_Farhang: <p>how can I translate this code to libtorch:</p>
<pre><code class="lang-auto"># x and tmp is tensor
x[ 3 : 5] += win_sq[:2]
tmp[:, :, approx_nonzero_indices] /= window[nonzero_indices]
</code></pre>

albanD: <p>Hi,</p>
<p>You have access to the <code>.select()</code> and <code>.narrow()</code> functions in cpp that can be used for this.<br>
You also have access to <code>.index_select()</code> and <code>.index_copy_()</code> to read and write given 1D indices<br>
The python code equivalent to yours is:</p>
<pre><code class="lang-python">x_slice = x.narrow(0, 3, 2)
x_slice.add_(win_sq.narrow(0, 0, 2))
new_val = tmp.index_select(-1, approx_nonzero_indices) / window.index_select(0, nonzero_indices)
tmp.index_copy_(-1, approx_nonzero_indices, new_val)
</code></pre>

Esmaeil_Farhang: <p>thank you for your attention <img src="https://discuss.pytorch.org/images/emoji/apple/slight_smile.png?v=9" title=":slight_smile:" class="emoji" alt=":slight_smile:"></p>

21fa417e3fb06e56040c: <p><a class="mention" href="/u/alband">@albanD</a> <a class="mention" href="/u/yf225">@yf225</a><br>
hi.<br>
Can I ask you one question?<br>
How do I convert the code below to C ++?</p>
<pre><code class="lang-python">//for torchvision maskrcnnn

    def filter_proposals(self, proposals, objectness, image_shapes, num_anchors_per_level):
        num_images = proposals.shape[0]
        device = proposals.device
        # do not backprop throught objectness
        objectness = objectness.detach()
        objectness = objectness.reshape(num_images, -1)

        levels = [
            torch.full((n,), idx, dtype=torch.int64, device=device)
            for idx, n in enumerate(num_anchors_per_level)
        ]
        levels = torch.cat(levels, 0)
        levels = levels.reshape(1, -1).expand_as(objectness)

        # select top_n boxes independently per level before applying nms
        top_n_idx = self._get_top_n_idx(objectness, num_anchors_per_level)
        batch_idx = torch.arange(num_images, device=device)[:, None]
        
       //below code 
        objectness = objectness[batch_idx, top_n_idx]
        levels = levels[batch_idx, top_n_idx]
        proposals = proposals[batch_idx, top_n_idx]
</code></pre>
<p>thanks!</p>

Esmaeil_Farhang: <p>Hi,</p>
<pre><code class="lang-auto">//below code 
        objectness = objectness[batch_idx, top_n_idx]
</code></pre>
<p>I think, translate above line to cpp is</p>
<pre><code class="lang-auto">auto new_val0 = objectness.index_select(0, batch_idx);
auto new_val1 = objectness.index_select(1, top_n_idx);
objectness.index_copy_(0, batch_idx, new_val0);
objectness.index_copy_(1, top_n_idx, new_val1);
</code></pre>

21fa417e3fb06e56040c: <p>Thank you for your answer.<br>
I think, the above code is different</p>
<p>batch_idx is Image count,</p>
<pre><code class="lang-auto">ex)
boxes =  Image * index * 4  
score =  Image * index
</code></pre>
<p>I think, something like the code below<br>
Is this right?<a class="mention" href="/u/alband">@albanD</a> <a class="mention" href="/u/yf225">@yf225</a></p>
<pre><code class="lang-auto">int64_t num_images = proposals.size(0);
torch::Device device = proposals.device();

objectness = objectness.detach();
objectness = objectness.reshape({ num_images, -1 });

std::vector&lt;torch::Tensor&gt; levels;
for (int64_t index = 0; index &lt; num_anchors_per_level.size(); index++)
{
	levels.push_back(torch::full(num_anchors_per_level[index], index, torch::TensorOptions().device(device).dtype(at::kFloat)));
}

auto tensorlevels = torch::cat(levels, 0);

tensorlevels = tensorlevels.reshape({ 1,-1 }).expand_as(objectness);

auto top_n_idx = get_top_n_idx(objectness, num_anchors_per_level);
auto batch_idx = torch::arange(num_images, torch::TensorOptions().device(device));

std::vector&lt;torch::Tensor&gt; final_boxes, final_scores;

for (int64_t index = 0; index &lt; num_images; index++)
{
	auto proposal = proposals[index].index_select(0, top_n_idx[index]);
	auto obj	= objectness[index].index_select(0, top_n_idx[index]);
	auto lvl	= tensorlevels[index].index_select(0, top_n_idx[index]);

	auto boxes = clip_boxes_to_image(proposal, image_shapes[index]);
	auto keep = remove_small_boxes(boxes, min_size_);
}
</code></pre>

FantasyJXF: <p>Hope this would help</p>
<pre><code class="lang-auto">    cv::Mat img = cv::imread(img_file);
    at::Tensor tensor_image = torch::from_blob(img.data, {1, img.rows, img.cols, 3}, torch::kByte);
    tensor_image = tensor_image.permute({0, 3, 1, 2});
    tensor_image = tensor_image.toType(at::kFloat);

    tensor_image[0][0].sub_(123.675).div_(58.395); // subtract mean
    tensor_image[0][1].sub_(116.28).div_(57.12);  // divide variance
    tensor_image[0][2].sub_(103.53).div_(57.375);
</code></pre>