1 #include "properties/Distributable.hh" 2 #include "properties/IndexInherit.hh" 3 #include "properties/CommutingAsProduct.hh" 4 #include "properties/DependsInherit.hh" 5 #include "properties/NumericalFlat.hh" 6 #include "properties/WeightInherit.hh" 7 #include "properties/CommutingAsSum.hh" 8 #include "properties/Derivative.hh" 9 #include "properties/Accent.hh" 10 #include "properties/Tableau.hh" 11 #include "properties/FilledTableau.hh" 12 13 #include "CdbPython.hh" 14 15 #include "py_globals.hh" 16 #include "py_helpers.hh" 17 #include "py_kernel.hh" 18 #include "py_ex.hh" 19 20 namespace cadabra { create_scope()21 Kernel *create_scope() 22 { 23 Kernel *k = new Kernel(true); 24 return k; 25 } 26 create_scope_from_global()27 Kernel *create_scope_from_global() 28 { 29 Kernel *k = create_empty_scope(); 30 // FIXME: copy global properties 31 return k; 32 } 33 create_empty_scope()34 Kernel *create_empty_scope() 35 { 36 Kernel *k = new Kernel(false); 37 return k; 38 } 39 get_kernel_from_scope()40 Kernel *get_kernel_from_scope() 41 { 42 Kernel *kernel = nullptr; 43 44 // Try and find the kernel in the local scope 45 auto locals = get_locals(); 46 if (locals && scope_has(locals, "__cdbkernel__")) { 47 kernel = locals["__cdbkernel__"].cast<Kernel*>(); 48 return kernel; 49 } 50 51 // No kernel in local scope, find one in global scope. 52 auto globals = get_globals(); 53 if (globals && scope_has(globals, "__cdbkernel__")) { 54 kernel = globals["__cdbkernel__"].cast<Kernel*>(); 55 return kernel; 56 } 57 58 // No kernel in local or global scope, construct a new global one 59 kernel = create_scope(); 60 globals["__cdbkernel__"] = kernel; 61 return kernel; 62 } 63 init_kernel(pybind11::module & m)64 void init_kernel(pybind11::module& m) 65 { 66 // Declare the Kernel object for Python so we can store it in the local Python context. 67 // We add a 'cadabra2.__cdbkernel__' object to the main module scope, and will 68 // pull that into the interpreter scope in the 'cadabra2_default.py' file. 69 pybind11::enum_<Kernel::scalar_backend_t>(m, "scalar_backend_t") 70 .value("sympy", Kernel::scalar_backend_t::sympy) 71 .value("mathematica", Kernel::scalar_backend_t::mathematica) 72 .export_values(); 73 74 pybind11::class_<Kernel>(m, "Kernel", pybind11::dynamic_attr()) 75 .def(pybind11::init<bool>()) 76 .def_readonly_static("version", &Kernel::version) 77 .def_readonly_static("build", &Kernel::build) 78 .def_readonly("scalar_backend", &Kernel::scalar_backend); 79 80 Kernel* kernel = create_scope(); 81 m.attr("__cdbkernel__") = pybind11::cast(kernel); 82 83 m.def("kernel", [](pybind11::kwargs dict) { 84 Kernel *k = get_kernel_from_scope(); 85 for (auto& item : dict) { 86 std::string key = item.first.cast<std::string>(); 87 if (key == "scalar_backend") { 88 std::string val = item.second.cast<std::string>(); 89 if (val == "sympy") k->scalar_backend = Kernel::scalar_backend_t::sympy; 90 else if (val == "mathematica") k->scalar_backend = Kernel::scalar_backend_t::mathematica; 91 else throw ArgumentException("scalar_backend must be 'sympy' or 'mathematica'."); 92 } 93 else if(key == "call_embedded_python_functions") { 94 bool val = item.second.cast<bool>(); 95 k->call_embedded_python_functions=val; 96 } 97 else { 98 throw ArgumentException("unknown argument '" + key + "'."); 99 } 100 } 101 }); 102 103 m.def("create_scope", &create_scope, 104 pybind11::return_value_policy::take_ownership); 105 m.def("create_scope_from_global", &create_scope_from_global, 106 pybind11::return_value_policy::take_ownership); 107 m.def("create_empty_scope", &create_empty_scope, 108 pybind11::return_value_policy::take_ownership); 109 110 m.def("cdb2python", &cdb2python); 111 m.def("cdb2python_string", &cdb2python_string); 112 } 113 114 } 115