fiedl / hole-ice-study

This project aims to incorporate the effects of hole ice into the clsim photon propagation simulation of the icecube neutrino observatory.
Other
4 stars 2 forks source link

I3CLSimModuleHelper: struct OpenCLInitOptions #121

Open fiedl opened 4 years ago

fiedl commented 4 years ago

I have used an options struct to pass on parameters to I3CLSimModuleHelper::initializeOpenCL. But now, after merging with a recent version of combo, this approach does not work anymore.

https://github.com/fiedl/clsim/commit/f6c0ed7502c20f4b9b8bc8bfb9109f8c13bc071d:

Options struct for initializeOpenCL.

Pass the options to I3CLSimModuleHelper::initializeOpenCL using a new struct I3CLSimModuleHelper::OpenCLInitOptions since the boost python bindings would limit the use of more parameters.

This commit does not change any functionality. No new features are implemented.

Cherry-picked from https://github.com/fiedl/clsim/commit/e7bfe2da57215532479e8a362effe48474219d88.

See also: https://github.com/fiedl/clsim/commit/9c7f0e4ab90713e0ee41cda262b536e2ad67723a#commitcomment-6518341

What was the original intent of the options struct?

https://github.com/fiedl/clsim/commit/9c7f0e4ab90713e0ee41cda262b536e2ad67723a#commitcomment-6518341

[ 37%] Building CXX object clsim/private/pybindings/CMakeFiles/clsim-pybindings.dir/I3CLSimModuleHelper.cxx.o
In file included from <built-in>:174:
In file included from <command line>:8:
In file included from /Users/fiedl/icecube/software/simulation-trunk-2014-05-12/debug_build/CMakeFiles/I3.h:57:
In file included from /usr/local/include/boost/python.hpp:18:
In file included from /usr/local/include/boost/python/class.hpp:17:
In file included from /usr/local/include/boost/python/data_members.hpp:15:
/usr/local/include/boost/python/make_function.hpp:76:11: error: no matching function for call to
      'get_signature'
        , detail::get_signature(f)
          ^~~~~~~~~~~~~~~~~~~~~

uhh.. ich bin mir nicht sicher, aber eventuell hat boost eine maximale Anzahl von Parametern für den Aufruf? Einige dieser Aufrufe mit "variabler" Anzahl von Parametern sind über Makros implementiert, die einen Maximalwert haben. Was leider bedeutet, dass Du entweder die Anzahl in einem der Boost-Header ändern musst oder anderweitig konfigurieren musst (schau mal, wo das make_function() definiert ist, eventuell hilft das weiter).

Introducing the options struct did resolve the original issue.

Where does it break now?

In order to define the struct

    struct OpenCLInitOptions {
        const I3CLSimOpenCLDevice &device;
        I3RandomServicePtr rng;
        I3CLSimSimpleGeometryConstPtr geometry;
        I3CLSimMediumPropertiesConstPtr medium;
        I3CLSimFunctionConstPtr wavelengthGenerationBias;
        const std::vector<I3CLSimRandomValueConstPtr> &wavelengthGenerators;
        bool enableDoubleBuffering;
        bool doublePrecision;
        bool stopDetectedPhotons;
        bool saveAllPhotons;
        double saveAllPhotonsPrescale;
        double maxNumOutputPhotonsCorrectionFactor;
        bool simulateHoleIce;
        double holeIceScatteringLengthFactor;
        double holeIceAbsorptionLengthFactor;
        double fixedNumberOfAbsorptionLengths;
        double pancakeFactor;
        uint32_t photonHistoryEntries;
        uint32_t limitWorkgroupSize;
        I3Vector<I3Position> holeIceCylinderPositions;
        I3Vector<float> holeIceCylinderRadii;
        I3Vector<float> holeIceCylinderScatteringLengths;
        I3Vector<float> holeIceCylinderAbsorptionLengths;
    };

in boost python, I've tried:

    bp::class_<OpenCLInitOptions>("OpenCLInitOptions")
      .def_readwrite("openCLDevice", &OpenCLInitOptions::device)
      .def_readwrite("randomService", &OpenCLInitOptions::rng)
      .def_readwrite("geometry", &OpenCLInitOptions::geometry)
      .def_readwrite("mediumProperties", &OpenCLInitOptions::medium)
      .def_readwrite("wavelengthGenerationBias", &OpenCLInitOptions::wavelengthGenerationBias)
      .def_readwrite("wavelengthGenerators", &OpenCLInitOptions::wavelengthGenerators)
      .def_readwrite("enableDoubleBuffering", &OpenCLInitOptions::enableDoubleBuffering)
      .def_readwrite("doublePrecision", &OpenCLInitOptions::doublePrecision)
      .def_readwrite("stopDetectedPhotons", &OpenCLInitOptions::stopDetectedPhotons)
      .def_readwrite("saveAllPhotons", &OpenCLInitOptions::saveAllPhotons)
      .def_readwrite("saveAllPhotonsPrescale", &OpenCLInitOptions::saveAllPhotonsPrescale)
      .def_readwrite("maxNumOutputPhotonsCorrectionFactor", &OpenCLInitOptions::maxNumOutputPhotonsCorrectionFactor)
      .def_readwrite("simulateHoleIce", &OpenCLInitOptions::simulateHoleIce)
      .def_readwrite("holeIceScatteringLengthFactor", &OpenCLInitOptions::holeIceScatteringLengthFactor)
      .def_readwrite("holeIceAbsorptionLengthFactor", &OpenCLInitOptions::holeIceAbsorptionLengthFactor)
      .def_readwrite("fixedNumberOfAbsorptionLengths", &OpenCLInitOptions::fixedNumberOfAbsorptionLengths)
      .def_readwrite("pancakeFactor", &OpenCLInitOptions::pancakeFactor)
      .def_readwrite("photonHistoryEntries", &OpenCLInitOptions::photonHistoryEntries)
      .def_readwrite("limitWorkgroupSize", &OpenCLInitOptions::limitWorkgroupSize)
      .def_readwrite("holeIceCylinderPositions", &OpenCLInitOptions::holeIceCylinderPositions)
      .def_readwrite("holeIceCylinderRadii", &OpenCLInitOptions::holeIceCylinderRadii)
      .def_readwrite("holeIceCylinderScatteringLengths", &OpenCLInitOptions::holeIceCylinderScatteringLengths)
      .def_readwrite("holeIceCylinderAbsorptionLengths", &OpenCLInitOptions::holeIceCylinderAbsorptionLengths)
    ;

But this raised:

[2020-04-19 19:05:56] fiedl@fiedl-mbp ~/icecube/builds/2020-04-15_combo_merge-clsim-hole-ice
▶ ./env-shell.sh make
[ 98%] Building CXX object clsim/CMakeFiles/clsim-pybindings.dir/private/pybindings/I3CLSimModuleHelper.cxx.o
/Users/fiedl/icecube/combo/clsim/private/pybindings/I3CLSimModuleHelper.cxx:44:38: error: cannot form a
      pointer-to-member to member 'device' of reference type 'const I3CLSimOpenCLDevice &'
      .def_readwrite("openCLDevice", &I3CLSimModuleHelper::OpenCLInitOptions::device)
fiedl commented 4 years ago

When reverting the options struct and going back to a regular function signature, I'm getting the original error again:

[2020-04-20 20:45:53] fiedl@fiedl-mbp ~/icecube/builds/2020-04-15_combo_merge-clsim-hole-ice
▶ ./env-shell.sh make -j 4
[ 98%] Building CXX object clsim/CMakeFiles/clsim-pybindings.dir/private/pybindings/I3CLSimModuleHelper.cxx.o
In file included from <built-in>:1:
In file included from /Users/fiedl/icecube/builds/2020-04-15_combo_merge-clsim-hole-ice/CMakeFiles/I3.h:62:
In file included from /usr/local/include/boost/python.hpp:18:
In file included from /usr/local/include/boost/python/class.hpp:17:
In file included from /usr/local/include/boost/python/data_members.hpp:15:
/usr/local/include/boost/python/make_function.hpp:76:11: error: no matching function for call to 'get_signature'
        , detail::get_signature(f)
          ^~~~~~~~~~~~~~~~~~~~~

By experimenting, I'm seeing that the error does occur when the signature has more than 15 arguments.

https://stackoverflow.com/a/8312525/2066546

Yes there is a limit. You can find those limits here. It appears to be 15, though I believe you can change it, according to the link.

Without variadic templates(in the new standard) you would have to hand write each version, so you would have to stop somewhere. As far as ability to change those numbers using different values of these macros when compiling different libraries (including extension modules and the Boost.Python library itself) is a violation of the ODR. However, we know of no C++ implementations on which this particular violation is detectable or causes any problems.

https://www.boost.org/doc/libs/1_41_0/libs/python/doc/v2/configuration.html

BOOST_PYTHON_MAX_ARITY 15 The maximum arity of any function, member function, or constructor to be wrapped, invocation of a Boost.Python function wich is specified as taking arguments x1, x2,...Xn. This includes, in particular, callback mechanisms such as object::operator()(...) or call_method(... ).

fiedl commented 4 years ago

How can I set BOOST_PYTHON_MAX_ARITY?

https://stackoverflow.com/a/30516216/2066546

#define BOOST_PYTHON_MAX_ARITY 16

If I set this directly in I3CLSimModuleHelper.cxx, I'm getting:

[2020-04-20 22:31:51] fiedl@fiedl-mbp ~/icecube/builds/2020-04-15_combo_merge-clsim-hole-ice
▶ ./env-shell.sh make -j 8
[ 98%] Building CXX object clsim/CMakeFiles/clsim-pybindings.dir/private/pybindings/I3CLSimModuleHelper.cxx.o
/Users/fiedl/icecube/combo/clsim/private/pybindings/I3CLSimModuleHelper.cxx:30:9: warning: 'BOOST_PYTHON_MAX_ARITY'
      macro redefined [-Wmacro-redefined]
#define BOOST_PYTHON_MAX_ARITY 25
        ^
/usr/local/include/boost/python/detail/preprocessor.hpp:29:11: note: previous definition is here
#  define BOOST_PYTHON_MAX_ARITY 15

Maybe, I have to set it before the preprocessor.hpp of boost is included.

[2020-04-20 22:36:09] fiedl@fiedl-mbp ~/icecube/combo fiedl/merge-clsim-hole-ice ⚡
▶ g preprocessor.hpp

This leads to ./clsim/private/pybindings/module.cxx:

// ./clsim/private/pybindings/module.cxx

// https://github.com/fiedl/hole-ice-study/issues/121
#define BOOST_PYTHON_MAX_ARITY 25

using namespace boost::python;
namespace bp = boost::python;
#include <boost/preprocessor.hpp>

And it does not resolve the issue. :(

fiedl commented 4 years ago

Setting the macro in /usr/local/include/boost/python/detail/preprocessor.hpp fixes the issue.

# ifndef BOOST_PYTHON_MAX_ARITY
#  define BOOST_PYTHON_MAX_ARITY 35
# endif

But where would I set this within combo?

https://icecube-spno.slack.com/archives/C02KQL9KN/p1587418792173700

fiedl commented 4 years ago

From our slack discussion:

I also was thinking about leaving device a const reference separate from the options struct. This depends on how the python code uses the device.