Skip to content

Instantly share code, notes, and snippets.

@zoq
Created August 2, 2019 18:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zoq/595906a62690befce85e3935ccc84f9f to your computer and use it in GitHub Desktop.
Save zoq/595906a62690befce85e3935ccc84f9f to your computer and use it in GitHub Desktop.
layerstring.hpp
class TestVisitor : public boost::static_visitor<std::string>
{
public:
//! Set the gradient to zero for the given module.
TestVisitor()
{
}
//! Set the gradient to zero.
template<typename LayerType>
std::string operator()(LayerType* layer) const
{
return LayerString(layer);
}
private:
//! Set the gradient to zero if the module implements the Gradient() function.
template<typename T>
typename std::enable_if<
std::is_same<T, Linear<> >::value, std::string>::type
LayerString(T* layer) const
{
return "linear";
}
//! Do not set the gradient to zero if the module doesn't implement the
//! Gradient() function.
template<typename T>
typename std::enable_if<
!std::is_same<T, Linear<> >::value, std::string>::type
LayerString(T* layer) const
{
return "not linear";
}
};
LayerTypes<> layerA = new Linear<>(20, 30);
LayerTypes<> layerB = new LinearNoBias<>(20, 30);
std::cout << boost::apply_visitor(TestVisitor(), layerB) << std::endl;
@sreenikSS
Copy link

sreenikSS commented Aug 20, 2019

The code below is by itself compiling alright but resulting in a compilation error when called from another file in the manner

LayerTypes<> layerB = new LinearNoBias<>(20, 30);

std::cout << boost::apply_visitor(TestVisitor(), layerB) << std::endl;

The code you shared works fine but the code which causes the error (which is an extension of your code) is:

#include <boost/variant/static_visitor.hpp>
#include <iostream>
#include <string>
#include <mlpack/methods/ann/layer/layer.hpp>

using namespace mlpack::ann;

class TestVisitor : public boost::static_visitor<std::string>
{
 public:
  //! Set the gradient to zero for the given module.
  TestVisitor()
  {

  }

  //! Set the gradient to zero.
  template<typename LayerType>
  std::string operator()(LayerType* layer) const
  {
    return LayerString(layer);

  }

 private:
  //! Set the gradient to zero if the module implements the Gradient() function.
  template<typename T>
  typename std::enable_if<
      std::is_same<T, Linear<> >::value, std::string>::type
  LayerString(T* layer) const
  {
    return "linear";

  }

  //! Do not set the gradient to zero if the module doesn't implement the
  //! Gradient() function.
  template<typename T>
  typename std::enable_if<
      !std::is_same<T, Linear<> >::value, std::string>::type
  LayerString(T* layer) const
  {
    return "not linear";

  }

  private:
  //! Set the gradient to zero if the module implements the Gradient() function.
  template<typename T>
  typename std::enable_if<
      std::is_same<T, LinearNoBias<> >::value, std::string>::type
  LayerString(T* layer) const
  {
    return "linearnobias";
  }

  private:
  //! Set the gradient to zero if the module implements the Gradient() function.
  template<typename T>
  typename std::enable_if<
      !std::is_same<T, LinearNoBias<> >::value, std::string>::type
  LayerString(T* layer) const
  {
    return " not linearnobias";
  }
};

It seems to me that if I implement all the layers supported by LayerTypes<> it won't give an error anymore because the compiler would know that it would match one definition at least. But still, I'm not too sure.

@zoq
Copy link
Author

zoq commented Aug 20, 2019

Unfortunately you have to define every case, here is an example:

template<typename T>
  typename std::enable_if<
      std::is_same<T, Linear<> >::value &&
      !std::is_same<T, LinearNoBias<> >::value &&
      !std::is_same<T, Convolution<> >::value, std::string>::type
LayerString(T* layer) const
{
  return "linear";
}


template<typename T>
  typename std::enable_if<
      !std::is_same<T, Linear<> >::value &&
      std::is_same<T, LinearNoBias<> >::value &&
      !std::is_same<T, Convolution<> >::value, std::string>::type
LayerString(T* layer) const
{
  return "linearnobias";
}

template<typename T>
  typename std::enable_if<
      !std::is_same<T, Linear<> >::value &&
      !std::is_same<T, LinearNoBias<> >::value &&
      std::is_same<T, Convolution<> >::value, std::string>::type
LayerString(T* layer) const
{
  return "convolution";
}

make sure you have a case where everything is false:

template<typename T>
  typename std::enable_if<
      std::is_same<T, Linear<> >::value &&
      !std::is_same<T, LinearNoBias<> >::value &&
      !std::is_same<T, Convolution<> >::value, std::string>::type
LayerString(T* layer) const
{
  return "unknow";
}

@zoq
Copy link
Author

zoq commented Aug 20, 2019

When you include the code, make sure to include:

#include <mlpack/core.hpp>

#include <mlpack/methods/ann/layer/layer.hpp>
#include <mlpack/methods/ann/layer/layer_types.hpp>

before you include anything else. let me know if that solves the compilation issue.

@sreenikSS
Copy link

sreenikSS commented Aug 21, 2019

Thanks @zoq, I will keep in mind these include statements. I tried out your suggestion and it worked! There's just this thing that bothers me and that is the size of each function prototype because for around over 10-15 layers it would look really large and maybe slightly confusing to someone else. However, it still seems to be the best way out, so I am going with it.

I finished it a while ago and it is working fine. I'll write a test and push it :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment