1 // Small stub to produce a module-specific entry point 2 // for a Python module. It assumes/requires that it is 3 // linked with PyStubImpl.o to be useful. 4 // 5 // Note that this quite deliberately doesn't include any PyBind11 headers; 6 // it is designed to be compiled without PyBind11 being available at compile time, 7 // to simplify build requirements in downstream environments. 8 9 #include <Python.h> 10 #include <memory> 11 12 #ifndef HALIDE_PYSTUB_GENERATOR_NAME 13 #error "HALIDE_PYSTUB_GENERATOR_NAME must be defined" 14 #endif 15 16 #ifndef HALIDE_PYSTUB_MODULE_NAME 17 #define HALIDE_PYSTUB_MODULE_NAME HALIDE_PYSTUB_GENERATOR_NAME 18 #endif 19 20 namespace Halide { 21 class GeneratorContext; 22 namespace Internal { 23 class GeneratorBase; 24 } // namespace Internal 25 } // namespace Halide 26 27 using FactoryFunc = std::unique_ptr<Halide::Internal::GeneratorBase> (*)(const Halide::GeneratorContext &context); 28 29 extern "C" PyObject *_halide_pystub_impl(const char *module_name, FactoryFunc factory); 30 31 #define HALIDE_STRINGIFY(x) #x 32 #define HALIDE_TOSTRING(x) HALIDE_STRINGIFY(x) 33 34 #define _HALIDE_CONCAT(first, second) first##second 35 #define HALIDE_CONCAT(first, second) _HALIDE_CONCAT(first, second) 36 37 #if !defined(HALIDE_EXPORT) 38 #if defined(WIN32) || defined(_WIN32) 39 #define HALIDE_EXPORT __declspec(dllexport) 40 #else 41 #define HALIDE_EXPORT __attribute__((visibility("default"))) 42 #endif 43 #endif 44 45 static_assert(PY_MAJOR_VERSION >= 3, "Python bindings for Halide require Python 3+"); 46 47 #define _HALIDE_PLUGIN_IMPL(name) extern "C" HALIDE_EXPORT PyObject *PyInit_##name() 48 #define HALIDE_PLUGIN_IMPL(name) _HALIDE_PLUGIN_IMPL(name) 49 50 // clang-format off 51 52 namespace halide_register_generator { 53 namespace HALIDE_CONCAT(HALIDE_PYSTUB_GENERATOR_NAME, _ns) { 54 extern std::unique_ptr<Halide::Internal::GeneratorBase> factory(const Halide::GeneratorContext &context); 55 } // namespace HALIDE_CONCAT(HALIDE_PYSTUB_GENERATOR_NAME,_ns) 56 } // namespace halide_register_generator 57 58 HALIDE_PLUGIN_IMPL(HALIDE_PYSTUB_MODULE_NAME) { 59 const auto factory = halide_register_generator::HALIDE_CONCAT(HALIDE_PYSTUB_GENERATOR_NAME, _ns)::factory; 60 return _halide_pystub_impl(HALIDE_TOSTRING(HALIDE_PYSTUB_MODULE_NAME), factory); 61 } 62 63 // clang-format on 64