Libtorch regression modeling bug

complexhhs: <p>Hi! There is a libtorch bug issue that I can’t find the solution.<br>
I want to make the 3dimension input regression model using libtorch.<br>
But, I stuck in this step.</p>
<p>Anyone who can help me?</p>
<p>Here is the bug message.</p>
<pre><code class="lang-auto">(base) myaccount@ubuntu:{mydirectory}$ ./{libtorch_exe_file}
terminate called after throwing an instance of 'c10::Error'
  what():  falseINTERNAL ASSERT FAILED at
 "{mylibtorchdirectory}/include/torch/csrc/api/include/torch/detail/TensorDataContainer.h":299, please report a bug to PyTorch. TensorDataContainer is already a Tensor type, `fill_tensor` should not be called
Exception raised from fill_tensor at {mylibtorchdirectory}/include/torch/csrc/api/include/torch/detail/TensorDataContainer.h:299 (most recent call first):
frame #0: c10::Error::Error(c10::SourceLocation, std::string) + 0x42 (0x7f019c304a22 in {mylibtorchdirectory}/lib/libc10.so)
frame #1: c10::detail::torchCheckFail(char const*, char const*, unsigned int, std::string const&amp;) + 0x5b (0x7f019c3013db in {mylibtorchdirectory}/lib/libc10.so)
frame #2: c10::detail::torchInternalAssertFail(char const*, char const*, unsigned int, char const*, char const*) + 0x42 (0x7f019c301942 in {mylibtorchdirectory}/lib/libc10.so)
frame #3: torch::detail::TensorDataContainer::fill_tensor(at::Tensor&amp;) const + 0x28b (0x556357f08961 in ./{libtorch_exe_file})
frame #4: torch::detail::TensorDataContainer::fill_tensor(at::Tensor&amp;) const + 0x235 (0x556357f0890b in ./{libtorch_exe_file})
frame #5: torch::detail::TensorDataContainer::convert_to_tensor(c10::TensorOptions) const + 0x11c (0x556357f05c7a in ./{libtorch_exe_file})
frame #6: torch::tensor(torch::detail::TensorDataContainer, c10::TensorOptions const&amp;) + 0x73 (0x556357f0950a in ./{libtorch_exe_file})
frame #7: MYDataset::get(unsigned long) + 0x119 (0x556357f0c7ad in ./{libtorch_exe_file})
frame #8: torch::data::datasets::Dataset&lt;MYDataset, torch::data::Example&lt;at::Tensor, at::Tensor&gt; &gt;::get_batch(c10::ArrayRef&lt;unsigned long&gt;) + 0xae (0x556357f2e2dc in ./{libtorch_exe_file})
frame #9: torch::data::Example&lt;at::Tensor, at::Tensor&gt; torch::data::datasets::MapDataset&lt;MYDataset, torch::data::transforms::Stack&lt;torch::data::Example&lt;at::Tensor, at::Tensor&gt; &gt; &gt;::get_batch_impl&lt;MYDataset, void&gt;(c10::ArrayRef&lt;unsigned long&gt;) + 0x5f (0x556357f29d43 in ./{libtorch_exe_file})
frame #10: torch::data::datasets::MapDataset&lt;MYDataset, torch::data::transforms::Stack&lt;torch::data::Example&lt;at::Tensor, at::Tensor&gt; &gt; &gt;::get_batch(c10::ArrayRef&lt;unsigned long&gt;) + 0x4d (0x556357f25d97 in ./{libtorch_exe_file})
frame #11: torch::data::DataLoaderBase&lt;torch::data::datasets::MapDataset&lt;MYDataset, torch::data::transforms::Stack&lt;torch::data::Example&lt;at::Tensor, at::Tensor&gt; &gt; &gt;, torch::data::Example&lt;at::Tensor, at::Tensor&gt;, std::vector&lt;unsigned long, std::allocator&lt;unsigned long&gt; &gt; &gt;::next() + 0x20c (0x556357f1f8cc in ./{libtorch_exe_file})
frame #12: torch::data::DataLoaderBase&lt;torch::data::datasets::MapDataset&lt;MYDataset, torch::data::transforms::Stack&lt;torch::data::Example&lt;at::Tensor, at::Tensor&gt; &gt; &gt;, torch::data::Example&lt;at::Tensor, at::Tensor&gt;, std::vector&lt;unsigned long, std::allocator&lt;unsigned long&gt; &gt; &gt;::begin()::{lambda()#1}::operator()() const + 0x35 (0x556357f183cd in ./{libtorch_exe_file})
frame #13: std::_Function_handler&lt;c10::optional&lt;torch::data::Example&lt;at::Tensor, at::Tensor&gt; &gt; (), torch::data::DataLoaderBase&lt;torch::data::datasets::MapDataset&lt;MYDataset, torch::data::transforms::Stack&lt;torch::data::Example&lt;at::Tensor, at::Tensor&gt; &gt; &gt;, torch::data::Example&lt;at::Tensor, at::Tensor&gt;, std::vector&lt;unsigned long, std::allocator&lt;unsigned long&gt; &gt; &gt;::begin()::{lambda()#1}&gt;::_M_invoke(std::_Any_data const&amp;) + 0x3d (0x556357f29f27 in ./{libtorch_exe_file})
frame #14: std::function&lt;c10::optional&lt;torch::data::Example&lt;at::Tensor, at::Tensor&gt; &gt; ()&gt;::operator()() const + 0x4c (0x556357f39f0a in ./{libtorch_exe_file})
frame #15: torch::data::detail::ValidIterator&lt;torch::data::Example&lt;at::Tensor, at::Tensor&gt; &gt;::lazy_initialize() const + 0x41 (0x556357f39e61 in ./{libtorch_exe_file})
frame #16: torch::data::detail::ValidIterator&lt;torch::data::Example&lt;at::Tensor, at::Tensor&gt; &gt;::operator==(torch::data::detail::SentinelIterator&lt;torch::data::Example&lt;at::Tensor, at::Tensor&gt; &gt; const&amp;) const + 0x1c (0x556357f39742 in ./{libtorch_exe_file})
frame #17: torch::data::detail::SentinelIterator&lt;torch::data::Example&lt;at::Tensor, at::Tensor&gt; &gt;::operator==(torch::data::detail::ValidIterator&lt;torch::data::Example&lt;at::Tensor, at::Tensor&gt; &gt; const&amp;) const + 0x2e (0x556357f3955e in ./{libtorch_exe_file})
frame #18: torch::data::detail::ValidIterator&lt;torch::data::Example&lt;at::Tensor, at::Tensor&gt; &gt;::operator==(torch::data::detail::IteratorImpl&lt;torch::data::Example&lt;at::Tensor, at::Tensor&gt; &gt; const&amp;) const + 0x2e (0x556357f3970a in ./{libtorch_exe_file})
frame #19: torch::data::Iterator&lt;torch::data::Example&lt;at::Tensor, at::Tensor&gt; &gt;::operator==(torch::data::Iterator&lt;torch::data::Example&lt;at::Tensor, at::Tensor&gt; &gt; const&amp;) const + 0x41 (0x556357f1fea9 in ./{libtorch_exe_file})
frame #20: torch::data::Iterator&lt;torch::data::Example&lt;at::Tensor, at::Tensor&gt; &gt;::operator!=(torch::data::Iterator&lt;torch::data::Example&lt;at::Tensor, at::Tensor&gt; &gt; const&amp;) const + 0x23 (0x556357f18627 in ./{libtorch_exe_file})
frame #21: main + 0x400 (0x556357f008a9 in ./{libtorch_exe_file})
frame #22: __libc_start_main + 0xe7 (0x7f0145a06bf7 in /lib/x86_64-linux-gnu/libc.so.6)
frame #23: _start + 0x2a (0x556357eff5ca in ./{libtorch_exe_file})

Aborted (core dumped)
</code></pre>
<p>and this is CMakeList.txt information.</p>
<pre><code class="lang-auto">cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(custom_ops)

find_package(Torch REQUIRED)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
add_executable({libtorch_exe_file} {libtorch_exe_file}.cpp)
target_link_libraries({libtorch_exe_file} "${TORCH_LIBRARIES}")
set_property(TARGET t{libtorch_exe_file} PROPERTY CXX_STANDARD 14)

set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
</code></pre>
<p>Plus, below two blocks are main and header code that I suspect the critical bug within.<br>
main</p>
<pre><code class="lang-auto">#include &lt;torch/torch.h&gt;
#include &lt;torch/script.h&gt;
#include &lt;cmath&gt;
#include &lt;iostream&gt;
#include &lt;iomanip&gt;
#include &lt;memory&gt;
#include &lt;fstream&gt;
#include &lt;vector&gt;
#include &lt;time.h&gt;
#include &lt;torch/utils.h&gt;
#include &lt;limits&gt;
#include "csvloader.h"
#include "utils.h"

using namespace std;
using namespace torch;

/*torch Basic model*/
struct BasicModel : nn::Module {
    BasicModel(int64_t input_dim=3, int64_t output_dim=1):
        linear
        ~ (block structure)
    {
        register_module("linear",linear);
        ~
    }
    torch::Tensor forward(torch::Tensor x){
        ~ forward ~
        return x;
    }
    ~variables~;
};

int main(int argc, char** argv)
{
    // torch device checking
    torch::Device device(torch::kCPU);
    if (torch::cuda::is_available()){
        device = torch::Device(torch::kCUDA,1);
    }

    BasicModel model;
    model.to(device);

    // Load csv data
    string path = argc &gt; 1? argv[1] : "{csv_path}.csv";

    torch::data::DataLoaderOptions train_options;
    torch::data::DataLoaderOptions valid_options;
    train_options.batch_size(128);
    valid_options.batch_size(128);
    auto dataset = MYDataset(path).map(torch::data::transforms::Stack&lt;&gt;());
    auto dataloader = torch::data::make_data_loader&lt;torch::data::samplers::RandomSampler&gt;(dataset,train_options);
    torch::optim::Adam optimizer(model.parameters(), torch::optim::AdamOptions(0.001));
    float train_loss;

    clock_t tstart = clock();
    for (int64_t epoch=0; epoch&lt;2; epoch++){
        float cnt = 0;
        for (auto&amp; batch : *dataloader){
            //model.zero_grad();
            torch::Tensor x = batch.data.to(device);
            torch::Tensor y = batch.target.to(device);
            auto output = model.forward(x);
            auto loss = torch::nn::functional::mse_loss(output,y);
            train_loss += loss.item&lt;float&gt;();
            optimizer.zero_grad();
            loss.backward();
            optimizer.step();
            cnt += 1.;
        };
        train_loss /= cnt;
        if (epoch % 500 == 0){
            cout &lt;&lt; "Epoch : " &lt;&lt; epoch &lt;&lt; " Train loss: " &lt;&lt; train_loss &lt;&lt; endl;
        }
    };
    cout &lt;&lt; "Time taken: " &lt;&lt; (clock()-tstart) &lt;&lt; "ms\n" &lt;&lt; endl;
    return -1;
};

</code></pre>
<p>header</p>
<pre><code class="lang-auto">auto ReadCsv(std::string&amp; location){
    std::fstream in(location, std::ios::in);
    std::string line;
    std::string name;
    std::string label;
    std::string dummy;
    float X1;
    float X2;
    float X3;
    float Y;
    std::vector&lt;std::tuple&lt;std::vector&lt;float&gt;,float&gt;&gt; csv;
    std::vector&lt;float&gt; x;
    getline(in,line); // Skipping first row
    while (getline(in,line)) {
        std::stringstream s(line);
        getline(s,dummy,','); 
        getline(s,dummy,','); 
        getline(s,dummy,','); 
        getline(s,dummy,',');
        X1 = stof(dummy);
        getline(s,dummy,',');
        X2 = stof(dummy);
        getline(s,dummy,',');
        X3 = stof(dummy);
        getline(s,dummy,',');
        Y = stof(dummy);
        x.push_back(X1);
        x.push_back(X2);
        x.push_back(X3);
        csv.push_back(std::make_tuple(x,Ids));
        x.clear();
    }
    return csv;
};

struct MYDataset : torch::data::Dataset&lt;MYDataset&gt;
{
    std::vector&lt;std::tuple&lt;std::vector&lt;float&gt; /*x_data*/, float /*y_data*/&gt;&gt; csv_;
    MYDataset(std::string&amp; file_name_csv)
        // Load csv file with file locations and labels.
        : csv_(ReadCsv(file_name_csv)) {
    };

    //override the get method to load custom data.
    torch::data::Example&lt;&gt; get(size_t index) override {
        std::vector&lt;float&gt; x = std::get&lt;0&gt;(csv_[index]);
        float y = std::get&lt;1&gt;(csv_[index]);

        torch::Tensor x_input = torch::tensor({x});
        torch::Tensor y_label = torch::tensor({y});
        return {x_input, y_label};
    };

    // Override the size method to infer the size of the data set.
    torch::optional&lt;size_t&gt; size() const override {
        return csv_.size();
    };
};
</code></pre>
<p>So, csv format is like this</p>
<div class="md-table">
<table>
<thead>
<tr>
<th>x1</th>
<th>x2</th>
<th>x3</th>
<th>y</th>
</tr>
</thead>
<tbody>
<tr>
<td>0.5</td>
<td>0.2</td>
<td>0.3</td>
<td>1</td>
</tr>
</tbody>
</table>
</div><p>…</p>

Matej_Kompanek: <p>Hi, I tried running your code, there is some variable missing - ‘Ids’ in ‘ReadCsv’. How many columns does your CSV have ? You wrote its x1,x2,x3, y but in your code there is like 3 extra getline s … before parsing x1, x2, …</p>

complexhhs: <p>I skipped to wrote the unwanted column information in csv file.<br>
Actually, true csv format is like this,</p>
<div class="md-table">
<table>
<thead>
<tr>
<th>Unwanted value1</th>
<th>Unwanted value2</th>
<th>Unwanted value3</th>
<th>X1</th>
<th>X2</th>
<th>X3</th>
<th>Y</th>
</tr>
</thead>
<tbody>
<tr>
<td>dummy</td>
<td>dummy</td>
<td>dummy</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>5</td>
</tr>
</tbody>
</table>
</div>

Matej_Kompanek: <p>You need to change the get method of your dataset (x is already array type).</p>
<pre><code class="lang-auto">torch::data::Example&lt;&gt; get(size_t index) override {
   std::vector&lt;float&gt; x = std::get&lt;0&gt;(csv_[index]);
   float y = std::get&lt;1&gt;(csv_[index]);

   torch::Tensor x_input = torch::tensor( x ); // - removed braces here
   torch::Tensor y_label = torch::tensor({ y });

   return { x_input, y_label };
};
</code></pre>

complexhhs: <p>Thank you! It works!!</p>