Custom submodules in pytorch / libtorch C++ - c++

Full disclosure, I asked this same question on the PyTorch forums about a few days ago and got no reply, so this is technically a repost, but I believe it's still a good question, because I've been unable to find an answer anywhere online. Here goes:
Can you show an example of using register_module with a custom module?
The only examples I’ve found online are registering linear layers or convolutional layers as the submodules.
I tried to write my own module and register it with another module and I couldn’t get it to work.
My IDE is telling me no instance of overloaded function "MyModel::register_module" matches the argument list -- argument types are: (const char [14], TreeEmbedding)
(TreeEmbedding is the name of another struct I made which extends torch::nn::Module.)
Am I missing something? An example of this would be very helpful.
Edit: Additional context follows below.
I have a header file "model.h" which contains the following:
struct TreeEmbedding : torch::nn::Module {
TreeEmbedding();
torch::Tensor forward(Graph tree);
};
struct MyModel : torch::nn::Module{
size_t embeddingSize;
TreeEmbedding treeEmbedding;
MyModel(size_t embeddingSize=10);
torch::Tensor forward(std::vector<Graph> clauses, std::vector<Graph> contexts);
};
I also have a cpp file "model.cpp" which contains the following:
MyModel::MyModel(size_t embeddingSize) :
embeddingSize(embeddingSize)
{
treeEmbedding = register_module("treeEmbedding", TreeEmbedding{});
}
This setup still has the same error as above. The code in the documentation does work (using built-in components like linear layers), but using a custom module does not. After tracking down torch::nn::Linear, it looks as though that is a ModuleHolder (Whatever that is...)
Thanks,
Jack

I will accept a better answer if anyone can provide more details, but just in case anyone's wondering, I thought I would put up the little information I was able to find:
register_module takes in a string as its first argument and its second argument can either be a ModuleHolder (I don't know what this is...) or alternatively it can be a shared_ptr to your module. So here's my example:
treeEmbedding = register_module<TreeEmbedding>("treeEmbedding", make_shared<TreeEmbedding>());
This seemed to work for me so far.

Related

(ROS) Failed to create global planner

My setup is: ROS melodic, Ubuntu: 18.04
I want simulate turtlebot3 moving with my own global planner and have been following this tutorial to get started: http://wiki.ros.org/navigation/Tutorials/Writing%20A%20Global%20Path%20Planner%20As%20Plugin%20in%20ROS#Running_the_Plugin_on_the_Turtlebot. The tutorial seem to be made for ROS hydro, but as it was the best source of guidance I could find I hoped it would work.
The error I'm having is:
Failed to create the global_planner/GlobalPlanner planner, are you sure it is properly registered and that the containing library is built? Exception: MultiLibraryClassLoader: Could not create object of class type global_planner::GlobalPlanner as no factory exists for it. Make sure that the library exists and was explicitly loaded through MultiLibraryClassLoader::loadLibrary()
To my knowledge I've followed the tutorial as much as possible with a only a few things done differently because I wanted to test it, couldn't do as the tutorial asked, or because I thought it wouldn't impact the results. What I have done differently is:
I use the carrot_planner.h and carrot_planner.cpp files in the tutorial section 1 to test that it works before trying with my own code to avoid confusion about where possible errors come from. It's not 'different' from the tutorial to my knowledge, but figured I'd mention it. They are placed in catkin_ws/src/carrot_planner/src/global_planner/
The ros package I'm working from is in catkin_ws/src and is called the carrot_planner. In the tutorial step 1.3 I use add_library(global_planner_lib src/global_planner/carrot_planner.cpp). Would not imagine it affects the results either.
In section 3 of the tutorial it mentions that 'First, you need to copy the package that contains your global planner (in our case global_planner) into the catkin workspace of your Turtlebot (e.g. catkin_ws).' Since my package was already in catkin_ws/src/ I haven't moved it since I guess I didn't need to.
I've altered the 'move_base.launch' file in '/opt/ros/melodic/share/turtlebot3_navigation/launch/' instead of the 'move_base.launch.xml' in '/opt/ros/hydro/share/turtlebot_navigation/launch/includes/' as there doesn't seem to be a destination '...turtlebot3_navigation/launch/includes/'. There are files in launch, but no includes folder. Maybe that a difference from Hydro to Melodic, I don't know. There may be a whole lot of things that need to be done differently from the tutorial when using Melodic, or with turtlebot3, but I don't know.
I haven't made my own launch file for bringup of the turtlebot, but have instead followed this tutorial (https://emanual.robotis.com/docs/en/platform/turtlebot3/nav_simulation/) to guide me with turtlebot3. After finishing this step in the global planner tutorial 'Save and close the move_base.launch.xml. Note that the name of the planner is global_planner/GlobalPlanner the same specified in global_planner_plugin.xml. Now, you are ready to use your new planner' I tested whether it worked by running: 'roslaunch turtlebot3_gazebo turtlebot3_world.launch' and then I tried running: 'roslaunch turtlebot3_navigation turtlebot3_navigation.launch map_file:=$HOME/map.yaml' which led to the error I showed above. I have created the map-yaml, so there's no misunderstanding whether that's missing.
I would be very glad for any help, thank you ^^
Edit: My system only had 'navfn' on it, not 'global_planner' or 'carrot_planner', if that makes a difference.
After looking over the code I found a solution. It doesn't make everything work perfectly yet, but seems to solve the immediate problem.
The problem was that in my 'global_planner_plugin.xml' I just used the code provided in the tutorial:
<library path="lib/libglobal_planner_lib">
<class name="global_planner/GlobalPlanner" type="global_planner::GlobalPlanner" base_class_type="nav_core::BaseGlobalPlanner">
<description>This is a global planner plugin by iroboapp project.</description>
</class>
</library>
But in the carrot_planner.cpp file it says:
PLUGINLIB_EXPORT_CLASS(carrot_planner::CarrotPlanner, nav_core::BaseGlobalPlanner)
Changing type="global_planner::GlobalPlanner to type="carrot_planner::CarrotPlanner and then launching turtlebot3 doesn't give the same error anymore.

Sphinx: Correct way to document an enum?

Looking through the C and C++ domains of Sphinx, it doesn't appear to have native support for documenting enums (and much less anonymous enums). As of now, I use cpp:type:: for the enum type, and then a list of all possible values and their description, but that doesn't seem like an ideal way to deal with it, especially since it makes referencing certain values a pain (either I reference just the type, or add an extra marker in front of the value).
Is there a better way to do this? And how would I go about handling anonymous enums?
A project on Github, spdylay, seems to have an approach. One of the header files at
https://github.com/tatsuhiro-t/spdylay/blob/master/lib/includes/spdylay/spdylay.h
has code like this:
/**
* #enum
* Error codes used in the Spdylay library.
*/
typedef enum {
/**
* Invalid argument passed.
*/
SPDYLAY_ERR_INVALID_ARGUMENT = -501,
/**
* Zlib error.
*/
SPDYLAY_ERR_ZLIB = -502,
} spdylay_error;
There some description of how they're doing it at https://github.com/tatsuhiro-t/spdylay/tree/master/doc, which includes using a API generator called mkapiref.py, available at
https://github.com/tatsuhiro-t/spdylay/blob/master/doc/mkapiref.py
The RST it generates for this example is
.. type:: spdylay_error
Error codes used in the Spdylay library.
.. macro:: SPDYLAY_ERR_INVALID_ARGUMENT
(``-501``)
Invalid argument passed.
.. macro:: SPDYLAY_ERR_ZLIB
(``-502``)
Zlib error.
You could take a look and see if it's useful for you.
Sphinx now has support for enums
Here is an example with enum values:
.. enum-class:: partition_affinity_domain
.. enumerator:: \
not_applicable
numa
L4_cache
L3_cache
L2_cache
L1_cache
next_partitionab
Hi Maybe you should consider using doxygen for documentation as it has a lot more native support for c / c++. if you want to retain the sphinx output of your documentation you can output from doxygen as xml, then using Breathe it will take the xml and give you the same sphinx output you are used to having.
Here is an example of documenting an enum in doxygen format from the breathe website.
//! Our toolset
/*! The various tools we can opt to use to crack this particular nut */
enum Tool
{
kHammer = 0, //!< What? It does the job
kNutCrackers, //!< Boring
kNinjaThrowingStars //!< Stealthy
};
hope this helps.

Implementation of active appearance models

I'm having an internship in the field of computer vision, and i am really interested to know some details about the implementation of the Active Appearence Models aam-opencv that exists in the Google Code site.
In fact, i downloaded aam-opencv.tar.gz then built it with cmake and i solved some syntax problems but the only error that i am still having when i try to generate the solution is the following :
This function should return something:
aamImage* delaunay:: warpImageToMeanShape(aamImage*input)
{
}
I wonder if there is something missing in that function, or is it a compiler problem.
Please give me an answer or just guide me to complete the missing part of that function.
I would really appreciate if anyone kindly help me.
Thank you.
I suppose that is not used in code function, so it is not important what it return. Some C++ compilers allow to write such code and give only warning, another treat as errors:
ReturnType f()
{
}
looks like you use not the same compiler as author of source code. So just add something like:
aamImage* delaunay:: warpImageToMeanShape(aamImage*input)
{
return NULL;
}

In the .cpp, is there a way to auto-implement all the functions from its .h?

I think this would increase the quality of life when devving, but google came up with nothing and I couldn't find anything specific inside inside Netbeans either.
What I want is to start with this header:
class bla
{
public:
static void gfg(somearg asd);
};
Then I open the blank bla.cpp and pressed 'autoimplement'. After that, it would look like this:
#include "bla.h"
static void bla::gfg(somearg asd)
{
//TODO: implement
throw unimplemented("void bla::gfg(somearg) is unimplemented");
}
Anyone know of a tool like this?
I found http://www.radwin.org/michael/projects/stubgen/
"stubgen is a C++ development tool that keeps code files in sync with their associated headers. When it finds a member function declaration in a header file that doesn't have a corresponding implementation, it creates an empty skeleton with descriptive comment headers."
This looks like it does exactly what you want it to do.
Some time has passed and in the meantime the requested feature seems to have been implemented in netbeans. Refer to https://netbeans.org/bugzilla/show_bug.cgi?id=213811 , which also gives a description on how to use it:
Note:
Implemented CTRL+SPACE.
IDE suggest implementing of class method if CTRL+SPACE was pressed:
- inside file that already has at least one method definition
- between method declarations

Boost GIL image constructors

I'm currently trying to figure out how to use the Generic Image Library included in Boost. Right now, I just want to use the library to store pixel data and use the Image IO to write PNGs. I'm having trouble understanding just how to set up the object however.
The hpp says
image(const point_t& dimensions,
std::size_t alignment=1) : _memory(0), _align(alignment) {
allocate_and_default_construct(dimensions);
}
but I cannot find any references to point_t except a type_def for view_t::point_t to point_t.
Also, the tutorial found with the GIL seems to only include writing filters and generic algorithms, and thus each function example they provide has a source image view, from which they take the dimensions.
Am I going about this the wrong way? Or is there something I've missed completely?
Thanks in advance
Edit: I don't know if anyone cares, or has read this, but for the record, I just used the boost interleaved image function to create a PNG. It's not exactly the same solution, but it works for my applications.
it sounds like you solved your problem in the meantime, but just for the record... here are some pointers to information about your problem:
First of all you may have missed the second constructor of boost::gil::image, which offers explicit access to the horizontal and vertical dimensions without the need of the point_t:
image(x_coord_t width, y_coord_t height,
std::size_t alignment=0,
const Alloc alloc_in = Alloc()) : _memory(0), _align_in_bytes(alignment), _alloc(alloc_in) {
allocate_and_default_construct(point_t(width,height));
}
point_t will most likely refer to the point2 class template defined in boost/gil/utilities.hpp.
In general you should check the complete documentation of Boost GIL for all questions not mentioned in the tutorial. For a deeper understanding of the library it is absolutely necessary to get familiar with the Design Guide and the Doxygen Documentation.