We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Zero vectors check is slow
The `vec` class used in ksc-generated code contains an `is_zero_` flag which optimizes the case of all-zero vectors. But this adds overhead in cases where all-zero never happens, e.g. GMM objective function is approximately 50% slower when compared to not having the flag (tested with GCC 7). Is there some way to get the best of both worlds here?

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/python/ksc/utils.py`
Content:
```
1 from collections import namedtuple
2 import importlib.util
3 import os
4 import numpy as np
5 import subprocess
6 import sys
7 from tempfile import NamedTemporaryFile
8 
9 from ksc.type import Type
10 
11 def ensure_list_of_lists(l):
12     """return input, wrapped in a singleton list if its first element is not a list
13 
14        ensure_list_of_lists([])    = []
15        ensure_list_of_lists([1])   = [[1]]
16        ensure_list_of_lists([[1]]) = [[1]]
17        ensure_list_of_lists([[1,2]])        = [[1, 2]]
18        ensure_list_of_lists([[1,2], [3,4]]) = [[1, 2], [3, 4]]
19     """
20 
21     if not isinstance(l, list):
22         raise ValueError("Expect a list")
23     if len(l) < 1:  # Empty list is empty list
24         return l
25     if not isinstance(l[0], list):
26         return [l]
27     else:
28         return l
29 
30 def paren(s):
31     return "(" + s + ")"
32 
33 ShapeType = namedtuple("ShapeType", ["shape", "type"])
34 
35 PYTHON_MODULE_NAME = "ks_mod"
36 
37 def import_module_from_path(module_name, path):
38     # These three lines are for loading a module from a file in Python 3.5+
39     # https://bugs.python.org/issue21436
40     spec = importlib.util.spec_from_file_location(module_name, path)
41     py_out = importlib.util.module_from_spec(spec)
42     spec.loader.exec_module(py_out)
43     return py_out
44 
45 def translate_and_import(*args):
46     from ksc.translate import translate
47     py_out = translate(*args, with_main=False)
48     with NamedTemporaryFile(mode="w", suffix=".py", delete=False) as f:
49         f.write(py_out)
50     print(f.name)
51     return import_module_from_path(PYTHON_MODULE_NAME, f.name)
52 
53 def subprocess_run(cmd, env=None):
54     return subprocess.run(cmd, stdout=subprocess.PIPE, env=env).stdout.decode().strip("\n")
55 
56 def generate_cpp_from_ks(ks_str):
57     if "KSC_PATH" in os.environ:
58         ksc_path = os.environ["KSC_PATH"]
59     else:
60         ksc_path = "./ksc"
61     with NamedTemporaryFile(mode="w", suffix=".ks", delete=False) as fks:
62         fks.write(ks_str)
63     with NamedTemporaryFile(mode="w", suffix=".kso", delete=False) as fkso:
64         pass
65     with NamedTemporaryFile(mode="w", suffix=".cpp", delete=False) as fcpp:
66         pass
67     try:
68         subprocess.check_call([
69             ksc_path,
70             "--generate-cpp-without-diffs",
71             "--ks-source-file", fks.name,
72             "--ks-output-file", fkso.name,
73             "--cpp-output-file", fcpp.name
74         ])
75     except subprocess.CalledProcessError:
76         print(f"ks_str={ks_str}")
77         raise
78     finally:
79         os.unlink(fks.name)
80     with open(fcpp.name) as f:
81         out = f.read()
82     # only delete these file if no error
83     os.unlink(fcpp.name)
84     os.unlink(fkso.name)
85     return out
86 
87 def build_py_module_from_cpp(cpp_str, pybind11_path):
88     if "KSC_RUNTIME_DIR" in os.environ:
89         ksc_runtime_dir = os.environ["KSC_RUNTIME_DIR"]
90     else:
91         ksc_runtime_dir = "./src/runtime"
92 
93     with NamedTemporaryFile(mode="w", suffix=".cpp", delete=False) as fcpp:
94         fcpp.write(cpp_str)
95 
96     extension_suffix = subprocess_run(['python3-config', '--extension-suffix'])
97 
98     with NamedTemporaryFile(mode="w", suffix=extension_suffix, delete=False) as fpymod:
99         pass
100     module_path = fpymod.name
101     module_name = os.path.basename(module_path).split(".")[0]
102     python_includes = subprocess_run(
103         [sys.executable, "-m", "pybind11", "--includes"],
104         env={"PYTHONPATH": "pybind11"}
105     )
106     try:
107         cmd = (f"g++-7 -I{ksc_runtime_dir} -I{pybind11_path}/include "
108                + python_includes
109                + " -Wall"
110                  " -std=c++17"
111                  " -O3"
112                  " -fPIC"
113                  " -shared"
114                  f" -DPYTHON_MODULE_NAME={module_name}"
115                  f" -o {module_path} "
116                + fcpp.name)
117         print(cmd)
118         subprocess.check_call(cmd, shell=True)
119     except subprocess.CalledProcessError:
120         print(f"cpp_str={cpp_str}")
121         raise
122     finally:
123         os.unlink(fcpp.name)
124     return module_name, module_path
125 
126 def arg_type_strings(types):
127     return "".join(t.shortstr() for t in types)
128 
129 def generate_and_compile_cpp_from_ks(ks_str, name_to_call, arg_types, pybind11_path="pybind11"):
130 
131     cpp_str = """
132 #include <pybind11/pybind11.h>
133 #include <pybind11/stl.h>
134 #include <pybind11/operators.h>
135 
136 namespace py = pybind11;
137 
138 {generated_cpp_source}
139 
140 int ks::main(ks::allocator *) {{ return 0; }};
141 
142 ks::allocator g_alloc{{ 1'000'000'000 }};
143 
144 /* template<typename T>
145 void declare_vec(py::module &m, std::string typestr) {{
146   using Class = ks::vec<T>;
147   std::string pyclass_name = std::string("vec_") + typestr;
148   py::class_<Class>(m, pyclass_name.c_str(), py::module_local())
149     .def(py::init<>())
150     .def(py::init([](std::vector<T> const& v) {{ return ks::vec<T>(&g_alloc, v); }}))
151     .def("is_zero",     &Class::is_zero)
152     .def("__getitem__", [](const ks::vec<T> &a, const int &b) {{
153 	return a[b];
154       }})
155     .def("__len__", [](const ks::vec<T> &a) {{ return a.size(); }});
156 }} */
157 
158 template<typename RetType, typename... ParamTypes>
159 auto withGlobalAllocator(RetType(*f)(ks::allocator*, ParamTypes...)) {{
160   return [f](ParamTypes... params) {{ return f(&g_alloc, params...); }};
161 }}
162 
163 PYBIND11_MODULE(PYTHON_MODULE_NAME, m) {{
164   m.def("main", withGlobalAllocator(&ks::{name_to_call}));
165 }}
166 """.format(
167         generated_cpp_source=generate_cpp_from_ks(ks_str),
168         name_to_call=(name_to_call + "@" + arg_type_strings(arg_types)).replace("@", "$a")
169     )
170     module_name, module_path = build_py_module_from_cpp(cpp_str, pybind11_path)
171     return import_module_from_path(module_name, module_path)
172 
173 def shape_type_from_object(o):
174     # import here to avoid circular dependencies
175     from ksc.abstract_value import AbstractValue
176     if hasattr(o, "shape") and hasattr(o, "dtype"):
177         # numpy array-like object
178         if np.issubdtype(o.dtype, np.floating):
179             el_type = Type.Float
180         elif np.issubdtype(o.dtype, np.integer):
181             el_type = Type.Integer
182         elif np.issubdtype(o.dtype, np.bool_):
183             el_type = Type.Bool
184         else:
185             raise ValueError(f"Cannot handle element type {o.dtype}")
186         vec_type = el_type
187         for _ in range(o.ndim):
188             vec_type = Type.Vec(vec_type)
189         return ShapeType(o.shape, vec_type)
190     elif isinstance(o, AbstractValue):
191         return o.shape_type
192     elif hasattr(o, "data") and o.data is not None:
193         # value node
194         return shape_type_from_object(o.data)
195     elif isinstance(o, list):
196         s0, t0 = shape_type_from_object(o[0])
197         assert all(shape_type_from_object(e) == (s0, t0) for e in o)
198         return ShapeType((len(o),) + s0, Type.Vec(t0))
199     elif isinstance(o, tuple):
200         ss, ts = zip(*[shape_type_from_object(e) for e in o])
201         return ShapeType(tuple(ss), Type.Tuple(*ts))
202     elif isinstance(o, bool):
203         return ShapeType((), Type.Bool)
204     elif isinstance(o, int):
205         return ShapeType((), Type.Integer)
206     elif isinstance(o, float):
207         return ShapeType((), Type.Float)
208     else:
209         raise ValueError(f"Cannot handle object {o}")
210
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/python/ksc/utils.py b/src/python/ksc/utils.py
--- a/src/python/ksc/utils.py
+++ b/src/python/ksc/utils.py
@@ -148,7 +148,6 @@
   py::class_<Class>(m, pyclass_name.c_str(), py::module_local())
     .def(py::init<>())
     .def(py::init([](std::vector<T> const& v) {{ return ks::vec<T>(&g_alloc, v); }}))
-    .def("is_zero",     &Class::is_zero)
     .def("__getitem__", [](const ks::vec<T> &a, const int &b) {{
 	return a[b];
       }})

{"golden_diff": "diff --git a/src/python/ksc/utils.py b/src/python/ksc/utils.py\n--- a/src/python/ksc/utils.py\n+++ b/src/python/ksc/utils.py\n@@ -148,7 +148,6 @@\n   py::class_<Class>(m, pyclass_name.c_str(), py::module_local())\n     .def(py::init<>())\n     .def(py::init([](std::vector<T> const& v) {{ return ks::vec<T>(&g_alloc, v); }}))\n-    .def(\"is_zero\",     &Class::is_zero)\n     .def(\"__getitem__\", [](const ks::vec<T> &a, const int &b) {{\n \treturn a[b];\n       }})\n", "issue": "Zero vectors check is slow\nThe `vec` class used in ksc-generated code contains an `is_zero_` flag which optimizes the case of all-zero vectors. But this adds overhead in cases where all-zero never happens, e.g. GMM objective function is approximately 50% slower when compared to not having the flag (tested with GCC 7). Is there some way to get the best of both worlds here?\n", "before_files": [{"content": "from collections import namedtuple\nimport importlib.util\nimport os\nimport numpy as np\nimport subprocess\nimport sys\nfrom tempfile import NamedTemporaryFile\n\nfrom ksc.type import Type\n\ndef ensure_list_of_lists(l):\n    \"\"\"return input, wrapped in a singleton list if its first element is not a list\n\n       ensure_list_of_lists([])    = []\n       ensure_list_of_lists([1])   = [[1]]\n       ensure_list_of_lists([[1]]) = [[1]]\n       ensure_list_of_lists([[1,2]])        = [[1, 2]]\n       ensure_list_of_lists([[1,2], [3,4]]) = [[1, 2], [3, 4]]\n    \"\"\"\n\n    if not isinstance(l, list):\n        raise ValueError(\"Expect a list\")\n    if len(l) < 1:  # Empty list is empty list\n        return l\n    if not isinstance(l[0], list):\n        return [l]\n    else:\n        return l\n\ndef paren(s):\n    return \"(\" + s + \")\"\n\nShapeType = namedtuple(\"ShapeType\", [\"shape\", \"type\"])\n\nPYTHON_MODULE_NAME = \"ks_mod\"\n\ndef import_module_from_path(module_name, path):\n    # These three lines are for loading a module from a file in Python 3.5+\n    # https://bugs.python.org/issue21436\n    spec = importlib.util.spec_from_file_location(module_name, path)\n    py_out = importlib.util.module_from_spec(spec)\n    spec.loader.exec_module(py_out)\n    return py_out\n\ndef translate_and_import(*args):\n    from ksc.translate import translate\n    py_out = translate(*args, with_main=False)\n    with NamedTemporaryFile(mode=\"w\", suffix=\".py\", delete=False) as f:\n        f.write(py_out)\n    print(f.name)\n    return import_module_from_path(PYTHON_MODULE_NAME, f.name)\n\ndef subprocess_run(cmd, env=None):\n    return subprocess.run(cmd, stdout=subprocess.PIPE, env=env).stdout.decode().strip(\"\\n\")\n\ndef generate_cpp_from_ks(ks_str):\n    if \"KSC_PATH\" in os.environ:\n        ksc_path = os.environ[\"KSC_PATH\"]\n    else:\n        ksc_path = \"./ksc\"\n    with NamedTemporaryFile(mode=\"w\", suffix=\".ks\", delete=False) as fks:\n        fks.write(ks_str)\n    with NamedTemporaryFile(mode=\"w\", suffix=\".kso\", delete=False) as fkso:\n        pass\n    with NamedTemporaryFile(mode=\"w\", suffix=\".cpp\", delete=False) as fcpp:\n        pass\n    try:\n        subprocess.check_call([\n            ksc_path,\n            \"--generate-cpp-without-diffs\",\n            \"--ks-source-file\", fks.name,\n            \"--ks-output-file\", fkso.name,\n            \"--cpp-output-file\", fcpp.name\n        ])\n    except subprocess.CalledProcessError:\n        print(f\"ks_str={ks_str}\")\n        raise\n    finally:\n        os.unlink(fks.name)\n    with open(fcpp.name) as f:\n        out = f.read()\n    # only delete these file if no error\n    os.unlink(fcpp.name)\n    os.unlink(fkso.name)\n    return out\n\ndef build_py_module_from_cpp(cpp_str, pybind11_path):\n    if \"KSC_RUNTIME_DIR\" in os.environ:\n        ksc_runtime_dir = os.environ[\"KSC_RUNTIME_DIR\"]\n    else:\n        ksc_runtime_dir = \"./src/runtime\"\n\n    with NamedTemporaryFile(mode=\"w\", suffix=\".cpp\", delete=False) as fcpp:\n        fcpp.write(cpp_str)\n\n    extension_suffix = subprocess_run(['python3-config', '--extension-suffix'])\n\n    with NamedTemporaryFile(mode=\"w\", suffix=extension_suffix, delete=False) as fpymod:\n        pass\n    module_path = fpymod.name\n    module_name = os.path.basename(module_path).split(\".\")[0]\n    python_includes = subprocess_run(\n        [sys.executable, \"-m\", \"pybind11\", \"--includes\"],\n        env={\"PYTHONPATH\": \"pybind11\"}\n    )\n    try:\n        cmd = (f\"g++-7 -I{ksc_runtime_dir} -I{pybind11_path}/include \"\n               + python_includes\n               + \" -Wall\"\n                 \" -std=c++17\"\n                 \" -O3\"\n                 \" -fPIC\"\n                 \" -shared\"\n                 f\" -DPYTHON_MODULE_NAME={module_name}\"\n                 f\" -o {module_path} \"\n               + fcpp.name)\n        print(cmd)\n        subprocess.check_call(cmd, shell=True)\n    except subprocess.CalledProcessError:\n        print(f\"cpp_str={cpp_str}\")\n        raise\n    finally:\n        os.unlink(fcpp.name)\n    return module_name, module_path\n\ndef arg_type_strings(types):\n    return \"\".join(t.shortstr() for t in types)\n\ndef generate_and_compile_cpp_from_ks(ks_str, name_to_call, arg_types, pybind11_path=\"pybind11\"):\n\n    cpp_str = \"\"\"\n#include <pybind11/pybind11.h>\n#include <pybind11/stl.h>\n#include <pybind11/operators.h>\n\nnamespace py = pybind11;\n\n{generated_cpp_source}\n\nint ks::main(ks::allocator *) {{ return 0; }};\n\nks::allocator g_alloc{{ 1'000'000'000 }};\n\n/* template<typename T>\nvoid declare_vec(py::module &m, std::string typestr) {{\n  using Class = ks::vec<T>;\n  std::string pyclass_name = std::string(\"vec_\") + typestr;\n  py::class_<Class>(m, pyclass_name.c_str(), py::module_local())\n    .def(py::init<>())\n    .def(py::init([](std::vector<T> const& v) {{ return ks::vec<T>(&g_alloc, v); }}))\n    .def(\"is_zero\",     &Class::is_zero)\n    .def(\"__getitem__\", [](const ks::vec<T> &a, const int &b) {{\n\treturn a[b];\n      }})\n    .def(\"__len__\", [](const ks::vec<T> &a) {{ return a.size(); }});\n}} */\n\ntemplate<typename RetType, typename... ParamTypes>\nauto withGlobalAllocator(RetType(*f)(ks::allocator*, ParamTypes...)) {{\n  return [f](ParamTypes... params) {{ return f(&g_alloc, params...); }};\n}}\n\nPYBIND11_MODULE(PYTHON_MODULE_NAME, m) {{\n  m.def(\"main\", withGlobalAllocator(&ks::{name_to_call}));\n}}\n\"\"\".format(\n        generated_cpp_source=generate_cpp_from_ks(ks_str),\n        name_to_call=(name_to_call + \"@\" + arg_type_strings(arg_types)).replace(\"@\", \"$a\")\n    )\n    module_name, module_path = build_py_module_from_cpp(cpp_str, pybind11_path)\n    return import_module_from_path(module_name, module_path)\n\ndef shape_type_from_object(o):\n    # import here to avoid circular dependencies\n    from ksc.abstract_value import AbstractValue\n    if hasattr(o, \"shape\") and hasattr(o, \"dtype\"):\n        # numpy array-like object\n        if np.issubdtype(o.dtype, np.floating):\n            el_type = Type.Float\n        elif np.issubdtype(o.dtype, np.integer):\n            el_type = Type.Integer\n        elif np.issubdtype(o.dtype, np.bool_):\n            el_type = Type.Bool\n        else:\n            raise ValueError(f\"Cannot handle element type {o.dtype}\")\n        vec_type = el_type\n        for _ in range(o.ndim):\n            vec_type = Type.Vec(vec_type)\n        return ShapeType(o.shape, vec_type)\n    elif isinstance(o, AbstractValue):\n        return o.shape_type\n    elif hasattr(o, \"data\") and o.data is not None:\n        # value node\n        return shape_type_from_object(o.data)\n    elif isinstance(o, list):\n        s0, t0 = shape_type_from_object(o[0])\n        assert all(shape_type_from_object(e) == (s0, t0) for e in o)\n        return ShapeType((len(o),) + s0, Type.Vec(t0))\n    elif isinstance(o, tuple):\n        ss, ts = zip(*[shape_type_from_object(e) for e in o])\n        return ShapeType(tuple(ss), Type.Tuple(*ts))\n    elif isinstance(o, bool):\n        return ShapeType((), Type.Bool)\n    elif isinstance(o, int):\n        return ShapeType((), Type.Integer)\n    elif isinstance(o, float):\n        return ShapeType((), Type.Float)\n    else:\n        raise ValueError(f\"Cannot handle object {o}\")\n", "path": "src/python/ksc/utils.py"}], "after_files": [{"content": "from collections import namedtuple\nimport importlib.util\nimport os\nimport numpy as np\nimport subprocess\nimport sys\nfrom tempfile import NamedTemporaryFile\n\nfrom ksc.type import Type\n\ndef ensure_list_of_lists(l):\n    \"\"\"return input, wrapped in a singleton list if its first element is not a list\n\n       ensure_list_of_lists([])    = []\n       ensure_list_of_lists([1])   = [[1]]\n       ensure_list_of_lists([[1]]) = [[1]]\n       ensure_list_of_lists([[1,2]])        = [[1, 2]]\n       ensure_list_of_lists([[1,2], [3,4]]) = [[1, 2], [3, 4]]\n    \"\"\"\n\n    if not isinstance(l, list):\n        raise ValueError(\"Expect a list\")\n    if len(l) < 1:  # Empty list is empty list\n        return l\n    if not isinstance(l[0], list):\n        return [l]\n    else:\n        return l\n\ndef paren(s):\n    return \"(\" + s + \")\"\n\nShapeType = namedtuple(\"ShapeType\", [\"shape\", \"type\"])\n\nPYTHON_MODULE_NAME = \"ks_mod\"\n\ndef import_module_from_path(module_name, path):\n    # These three lines are for loading a module from a file in Python 3.5+\n    # https://bugs.python.org/issue21436\n    spec = importlib.util.spec_from_file_location(module_name, path)\n    py_out = importlib.util.module_from_spec(spec)\n    spec.loader.exec_module(py_out)\n    return py_out\n\ndef translate_and_import(*args):\n    from ksc.translate import translate\n    py_out = translate(*args, with_main=False)\n    with NamedTemporaryFile(mode=\"w\", suffix=\".py\", delete=False) as f:\n        f.write(py_out)\n    print(f.name)\n    return import_module_from_path(PYTHON_MODULE_NAME, f.name)\n\ndef subprocess_run(cmd, env=None):\n    return subprocess.run(cmd, stdout=subprocess.PIPE, env=env).stdout.decode().strip(\"\\n\")\n\ndef generate_cpp_from_ks(ks_str):\n    if \"KSC_PATH\" in os.environ:\n        ksc_path = os.environ[\"KSC_PATH\"]\n    else:\n        ksc_path = \"./ksc\"\n    with NamedTemporaryFile(mode=\"w\", suffix=\".ks\", delete=False) as fks:\n        fks.write(ks_str)\n    with NamedTemporaryFile(mode=\"w\", suffix=\".kso\", delete=False) as fkso:\n        pass\n    with NamedTemporaryFile(mode=\"w\", suffix=\".cpp\", delete=False) as fcpp:\n        pass\n    try:\n        subprocess.check_call([\n            ksc_path,\n            \"--generate-cpp-without-diffs\",\n            \"--ks-source-file\", fks.name,\n            \"--ks-output-file\", fkso.name,\n            \"--cpp-output-file\", fcpp.name\n        ])\n    except subprocess.CalledProcessError:\n        print(f\"ks_str={ks_str}\")\n        raise\n    finally:\n        os.unlink(fks.name)\n    with open(fcpp.name) as f:\n        out = f.read()\n    # only delete these file if no error\n    os.unlink(fcpp.name)\n    os.unlink(fkso.name)\n    return out\n\ndef build_py_module_from_cpp(cpp_str, pybind11_path):\n    if \"KSC_RUNTIME_DIR\" in os.environ:\n        ksc_runtime_dir = os.environ[\"KSC_RUNTIME_DIR\"]\n    else:\n        ksc_runtime_dir = \"./src/runtime\"\n\n    with NamedTemporaryFile(mode=\"w\", suffix=\".cpp\", delete=False) as fcpp:\n        fcpp.write(cpp_str)\n\n    extension_suffix = subprocess_run(['python3-config', '--extension-suffix'])\n\n    with NamedTemporaryFile(mode=\"w\", suffix=extension_suffix, delete=False) as fpymod:\n        pass\n    module_path = fpymod.name\n    module_name = os.path.basename(module_path).split(\".\")[0]\n    python_includes = subprocess_run(\n        [sys.executable, \"-m\", \"pybind11\", \"--includes\"],\n        env={\"PYTHONPATH\": \"pybind11\"}\n    )\n    try:\n        cmd = (f\"g++-7 -I{ksc_runtime_dir} -I{pybind11_path}/include \"\n               + python_includes\n               + \" -Wall\"\n                 \" -std=c++17\"\n                 \" -O3\"\n                 \" -fPIC\"\n                 \" -shared\"\n                 f\" -DPYTHON_MODULE_NAME={module_name}\"\n                 f\" -o {module_path} \"\n               + fcpp.name)\n        print(cmd)\n        subprocess.check_call(cmd, shell=True)\n    except subprocess.CalledProcessError:\n        print(f\"cpp_str={cpp_str}\")\n        raise\n    finally:\n        os.unlink(fcpp.name)\n    return module_name, module_path\n\ndef arg_type_strings(types):\n    return \"\".join(t.shortstr() for t in types)\n\ndef generate_and_compile_cpp_from_ks(ks_str, name_to_call, arg_types, pybind11_path=\"pybind11\"):\n\n    cpp_str = \"\"\"\n#include <pybind11/pybind11.h>\n#include <pybind11/stl.h>\n#include <pybind11/operators.h>\n\nnamespace py = pybind11;\n\n{generated_cpp_source}\n\nint ks::main(ks::allocator *) {{ return 0; }};\n\nks::allocator g_alloc{{ 1'000'000'000 }};\n\n/* template<typename T>\nvoid declare_vec(py::module &m, std::string typestr) {{\n  using Class = ks::vec<T>;\n  std::string pyclass_name = std::string(\"vec_\") + typestr;\n  py::class_<Class>(m, pyclass_name.c_str(), py::module_local())\n    .def(py::init<>())\n    .def(py::init([](std::vector<T> const& v) {{ return ks::vec<T>(&g_alloc, v); }}))\n    .def(\"__getitem__\", [](const ks::vec<T> &a, const int &b) {{\n\treturn a[b];\n      }})\n    .def(\"__len__\", [](const ks::vec<T> &a) {{ return a.size(); }});\n}} */\n\ntemplate<typename RetType, typename... ParamTypes>\nauto withGlobalAllocator(RetType(*f)(ks::allocator*, ParamTypes...)) {{\n  return [f](ParamTypes... params) {{ return f(&g_alloc, params...); }};\n}}\n\nPYBIND11_MODULE(PYTHON_MODULE_NAME, m) {{\n  m.def(\"main\", withGlobalAllocator(&ks::{name_to_call}));\n}}\n\"\"\".format(\n        generated_cpp_source=generate_cpp_from_ks(ks_str),\n        name_to_call=(name_to_call + \"@\" + arg_type_strings(arg_types)).replace(\"@\", \"$a\")\n    )\n    module_name, module_path = build_py_module_from_cpp(cpp_str, pybind11_path)\n    return import_module_from_path(module_name, module_path)\n\ndef shape_type_from_object(o):\n    # import here to avoid circular dependencies\n    from ksc.abstract_value import AbstractValue\n    if hasattr(o, \"shape\") and hasattr(o, \"dtype\"):\n        # numpy array-like object\n        if np.issubdtype(o.dtype, np.floating):\n            el_type = Type.Float\n        elif np.issubdtype(o.dtype, np.integer):\n            el_type = Type.Integer\n        elif np.issubdtype(o.dtype, np.bool_):\n            el_type = Type.Bool\n        else:\n            raise ValueError(f\"Cannot handle element type {o.dtype}\")\n        vec_type = el_type\n        for _ in range(o.ndim):\n            vec_type = Type.Vec(vec_type)\n        return ShapeType(o.shape, vec_type)\n    elif isinstance(o, AbstractValue):\n        return o.shape_type\n    elif hasattr(o, \"data\") and o.data is not None:\n        # value node\n        return shape_type_from_object(o.data)\n    elif isinstance(o, list):\n        s0, t0 = shape_type_from_object(o[0])\n        assert all(shape_type_from_object(e) == (s0, t0) for e in o)\n        return ShapeType((len(o),) + s0, Type.Vec(t0))\n    elif isinstance(o, tuple):\n        ss, ts = zip(*[shape_type_from_object(e) for e in o])\n        return ShapeType(tuple(ss), Type.Tuple(*ts))\n    elif isinstance(o, bool):\n        return ShapeType((), Type.Bool)\n    elif isinstance(o, int):\n        return ShapeType((), Type.Integer)\n    elif isinstance(o, float):\n        return ShapeType((), Type.Float)\n    else:\n        raise ValueError(f\"Cannot handle object {o}\")\n", "path": "src/python/ksc/utils.py"}]}