| 782 | } |
| 783 | |
| 784 | shared_ptr<CoefficientFunction> |
| 785 | optimize_path(const string &signature, |
| 786 | const Array<shared_ptr<CoefficientFunction>>& input_cfs, |
| 787 | const map<string, bool> &aoptions) |
| 788 | { |
| 789 | map<string, bool> options = aoptions; |
| 790 | options["optimize_path"] = false; |
| 791 | options["expand_einsum"] = false; |
| 792 | |
| 793 | #ifndef NGS_PYTHON |
| 794 | throw Exception("Function not available"); |
| 795 | #else // NGS_PYTHON |
| 796 | |
| 797 | namespace py = pybind11; |
| 798 | |
| 799 | auto np = py::module::import("numpy"); |
| 800 | |
| 801 | bool new_numpy_einsum_layout = np.attr("__version__").attr("__ge__")("2.4.1").cast<bool>(); |
| 802 | |
| 803 | using namespace pybind11::literals; |
| 804 | py::object einsum_path = np.attr("einsum_path"); |
| 805 | |
| 806 | py::list inputs{}; |
| 807 | for (auto icf: input_cfs) |
| 808 | { |
| 809 | py::array::ShapeContainer shape{}; |
| 810 | for (int dim: icf->Dimensions()) |
| 811 | shape->push_back(dim); |
| 812 | inputs.append(py::array_t<double>(shape)); |
| 813 | } |
| 814 | |
| 815 | py::object res; |
| 816 | try |
| 817 | { |
| 818 | res = einsum_path(signature, *inputs, "einsum_call"_a = true); |
| 819 | } |
| 820 | catch (const exception& e) |
| 821 | { |
| 822 | cout << "Exception in call to einsum_path" |
| 823 | << "\n\t" |
| 824 | << "for signature" << signature |
| 825 | << "\n\t" |
| 826 | << "and input dims \n"; |
| 827 | for (auto cf : input_cfs) |
| 828 | cout << cf->Dimensions() << "\n"; |
| 829 | cout << endl; |
| 830 | cout << e.what(); |
| 831 | throw e; |
| 832 | } |
| 833 | |
| 834 | |
| 835 | auto res_tuple = py::extract<py::tuple>(res)(); |
| 836 | auto path = py::extract<py::list>(res_tuple[1])(); |
| 837 | Array<shared_ptr<CoefficientFunction>> tp_inputs{input_cfs}; |
| 838 | for (size_t j: Range(path.size())) |
| 839 | { |
| 840 | auto op = py::extract<py::tuple>(path[j])(); |
| 841 | Array<shared_ptr<CoefficientFunction>> new_inputs; |
no test coverage detected