You’re welcome @arnby! I’m glad it worked so well :).
@Ryan_Draves I’m not sure there is such a complete library for time measurement since it varies by os (like you can only use .clock()
on windows). One possible solution is to create a decorator in python to monitor different functions using the time module. There is an article about it here. You could have it return the time necessary or maybe check inside of the decorator. There are several different solutions here, this is just one. However, I personally believe the same fundamental steps apply, it just varies on how you do them. I’m not sure why you’d get inaccuracies though .
@arnby, in regards to your question about handling errors in a python c++ extension, you can read the official documentation here. Essentially though, exceptions are an object, just like anything else in Python (even c++ python code, it is just a PyObject*). And if you want it to show (which would be good practice) you would create a normal c++ check or exception and if it is not true you would need to return the PyObject* error which will then be shown in the pure python. Here is a small example of a check I do when multiplying two vectors together (for my ML algos, lol rip):
Py_ssize_t TupleSize = PyTuple_Size(args);
if(!TupleSize) {
if(!PyErr_Occurred())
PyErr_SetString(PyExc_TypeError,"You must supply two vector inputs.");
return NULL;
}
A little bit about memory in Python :)…
So python tracks its own memory and has its own heap. Thus, undefined behavior will occur if you attempt to access memory created from c++ (malloc()
) vs python (PyMem_RawMalloc()
). If you create an object on the c++ heap and delete it using python’s memory deallocation this will definitely cause undefined behavior. This means it is perfectly safe to use new
with c++ so long as you don’t access it using python’s tools (objects). I personally just create a function to convert whatever c++ heap object I am returning to a PyObject*j and return that. This may seem inefficient but it is actually extremely fast, nothing to worry about (unless you are transferring a truly ridiculous amount of information, we are talking like a microsecond or less).
Regarding debugging python c++ extensions. What I discovered here has personally been invaluable for tracking down memory bugs and seg. faults. I strongly strongly recommend using a Linux build because then you can use the gdb
debugger. I’m not aware (haven’t looked) of a simple windows counterpart for what I do.
Essentially, I just run the algo_strategy.py
without using the engine and supply the input manually. This has several advantages. Specifically, you can input whatever you want and you can stop the algo for as long as you want. The clear disadvantage is that entering engine strings is an absolute nightmare. However, we don’t have to :). Simply run your algo and output all strings (nothing else) to a file. Then you simply copy and paste the commands generated from the engine. If you have a deterministic algo this will work every time. If not, you usually just have to run it once or twice before the seg. fault occurs. Then, gdb tells you where that pesky error is.
Step by step:
- Run your algo normally, saving commands from the engine to a .txt file.
- Run gdb, specifically (assuming you are in your algo’s main folder):
gdb python.py
>…
>run algo_strategy.py
- Copy and paste all the commands from (separated by
\n
) the generated text file
gdb will then run and tell you where it seg fault was. If you still can’t just see it then just use the command where
(in the same session) inside gdb while still debugging.
Without this I definitely would have just given up out of frustration when working on my simulator :), hope it helps some people :).
@Thorn0906 I haven’t had a chance to work with Rust yet but have been wanting to for a while, maybe someday soon…