mirror of
https://github.com/pocketpy/pocketpy
synced 2025-11-01 17:30:18 +00:00
some fix
This commit is contained in:
parent
4001f53e10
commit
275f958cfc
@ -1,17 +1,13 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(numpy_bindings)
|
||||
project(numpy)
|
||||
|
||||
# Set C++ standard
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
# Add pocketpy as a subdirectory
|
||||
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../../.." "${CMAKE_CURRENT_BINARY_DIR}/pocketpy")
|
||||
|
||||
# Include pybind11 and numpy
|
||||
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../../../include")
|
||||
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../include")
|
||||
include_directories("${CMAKE_CURRENT_LIST_DIR}/../../include")
|
||||
include_directories("${CMAKE_CURRENT_LIST_DIR}/include")
|
||||
|
||||
# Control xtensor warnings (OFF by default)
|
||||
option(SHOW_XTENSOR_WARNINGS "Show warnings from xtensor" OFF)
|
||||
@ -32,14 +28,17 @@ if(NOT SHOW_XTENSOR_WARNINGS)
|
||||
endif()
|
||||
|
||||
# Add numpy source and test files
|
||||
file (GLOB SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/../src/numpy.cpp")
|
||||
file (GLOB TESTS "${CMAKE_CURRENT_SOURCE_DIR}/test_numpy.cpp")
|
||||
file(GLOB_RECURSE SOURCES ${CMAKE_CURRENT_LIST_DIR}/src/*.cpp)
|
||||
|
||||
# Create numpy executables
|
||||
add_executable(numpy_bindings ${TESTS} ${SOURCES})
|
||||
# Create numpy dynamic library
|
||||
add_library(${PROJECT_NAME} SHARED ${SOURCES})
|
||||
|
||||
# Set VS debugger working directory (if relevant)
|
||||
set_property(TARGET ${PROJECT_NAME} PROPERTY VS_DEBUGGER_WORKING_DIRECTORY CMAKE_CURRENT_LIST_DIR)
|
||||
# Define PY_DYNAMIC_MODULE for numpy
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE PY_DYNAMIC_MODULE)
|
||||
|
||||
# Link numpy with pocketpy
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE pocketpy)
|
||||
target_link_libraries(
|
||||
${PROJECT_NAME}
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_LIST_DIR}/../..//build/Release/pocketpy.lib
|
||||
)
|
||||
@ -1,49 +1,6 @@
|
||||
# numpy
|
||||
# How to build
|
||||
|
||||
### How to run **numpy** module programs with **gsoc-2024-dev** [pybind11](https://github.com/pocketpy/gsoc-2024-dev/tree/main/pybind11)
|
||||
|
||||
1. Prepare the python code file with the numpy operations you want to run. \
|
||||
\
|
||||
For example : let's try out numpy [arange](https://numpy.org/doc/stable/reference/generated/numpy.arange.html) function in `test_numpy.py`
|
||||
```py
|
||||
import numpy_bindings as np
|
||||
|
||||
def test_arange(n):
|
||||
a = np.arange(n)
|
||||
print(a.sum())
|
||||
|
||||
test_arange(100)
|
||||
```
|
||||
|
||||
2. Read the script and execute it in `test_numpy.cpp`.
|
||||
```cpp
|
||||
#include <pybind11/embed.h>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
namespace py = pybind11;
|
||||
using namespace pybind11;
|
||||
|
||||
int main() {
|
||||
py::scoped_interpreter guard{};
|
||||
std::ifstream file("test_numpy.py");
|
||||
std::stringstream buffer;
|
||||
buffer << file.rdbuf();
|
||||
std::string script = buffer.str();
|
||||
py::exec(script);
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
3. Build the project at root to generate the executable at `build/gsoc2024`.
|
||||
```sh
|
||||
cmake -B build
|
||||
cmake --build build
|
||||
```
|
||||
4. Now run the executable to get the output.
|
||||
```sh
|
||||
|base| gsoc-2024-dev ±|main ✗|→ build/gsoc2024
|
||||
4950
|
||||
cmake -B build -DCMAKE_BUILD_TYPE=Release
|
||||
cmake --build build --config Release
|
||||
```
|
||||
|
||||
@ -2869,7 +2869,7 @@ void array_creation_registry(py::module_& m) {
|
||||
}
|
||||
|
||||
|
||||
PYBIND11_EMBEDDED_MODULE(numpy_bindings, m) {
|
||||
PYBIND11_MODULE(numpy, m) {
|
||||
m.doc() = "Python bindings for pkpy::numpy::ndarray using pybind11";
|
||||
|
||||
m.attr("bool_") = "bool";
|
||||
|
||||
@ -3,8 +3,12 @@
|
||||
// clang-format off
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
|
||||
//define something for Windows (32-bit and 64-bit, this part is common)
|
||||
#define PK_EXPORT __declspec(dllexport)
|
||||
// define something for Windows (32-bit and 64-bit, this part is common)
|
||||
#ifdef PY_DYNAMIC_MODULE
|
||||
#define PK_EXPORT __declspec(dllimport)
|
||||
#else
|
||||
#define PK_EXPORT __declspec(dllexport)
|
||||
#endif
|
||||
#define PY_SYS_PLATFORM 0
|
||||
#define PY_SYS_PLATFORM_STRING "win32"
|
||||
#elif __EMSCRIPTEN__
|
||||
|
||||
@ -14,7 +14,6 @@
|
||||
// 4. stack balance guanrantee
|
||||
// 5. stack effect of each opcode
|
||||
// 6. py_TypeInfo
|
||||
// 7. Direct assignment of py_NIL, py_True, py_False, py_None. They are slow.
|
||||
|
||||
typedef struct VM {
|
||||
Frame* top_frame;
|
||||
|
||||
@ -70,15 +70,6 @@ typedef bool (*py_CFunction)(int argc, py_StackRef argv) PY_RAISE PY_RETURN;
|
||||
/// + `SINGLE_MODE`: for REPL or jupyter notebook execution.
|
||||
enum py_CompileMode { EXEC_MODE, EVAL_MODE, SINGLE_MODE };
|
||||
|
||||
/// A shorthand for `True`.
|
||||
PK_EXPORT extern py_GlobalRef py_True;
|
||||
/// A shorthand for `False`.
|
||||
PK_EXPORT extern py_GlobalRef py_False;
|
||||
/// A shorthand for `None`.
|
||||
PK_EXPORT extern py_GlobalRef py_None;
|
||||
/// A shorthand for `nil`. `nil` is not a valid python object.
|
||||
PK_EXPORT extern py_GlobalRef py_NIL;
|
||||
|
||||
/************* Global Setup *************/
|
||||
|
||||
/// Initialize pocketpy and the default VM.
|
||||
@ -145,6 +136,15 @@ PK_EXPORT void py_newlocals(py_OutRef);
|
||||
|
||||
/************* Values Creation *************/
|
||||
|
||||
/// A shorthand for `True`.
|
||||
PK_EXPORT py_GlobalRef py_True();
|
||||
/// A shorthand for `False`.
|
||||
PK_EXPORT py_GlobalRef py_False();
|
||||
/// A shorthand for `None`.
|
||||
PK_EXPORT py_GlobalRef py_None();
|
||||
/// A shorthand for `nil`. `nil` is not a valid python object.
|
||||
PK_EXPORT py_GlobalRef py_NIL();
|
||||
|
||||
/// Create an `int` object.
|
||||
PK_EXPORT void py_newint(py_OutRef, py_i64);
|
||||
/// Create a `float` object.
|
||||
|
||||
@ -51,14 +51,14 @@ class none : public object {
|
||||
PKBIND_TYPE_IMPL(object, none, tp_NoneType);
|
||||
|
||||
// note: none is global instance, so we use ref_t.
|
||||
none() : object(py_None, ref_t{}) {}
|
||||
none() : object(py_None(), ref_t{}) {}
|
||||
};
|
||||
|
||||
class bool_ : public object {
|
||||
PKBIND_TYPE_IMPL(object, bool_, tp_bool);
|
||||
|
||||
// same as none, bool is a singleton.
|
||||
bool_(bool value) : object(value ? py_True : py_False, ref_t{}) {}
|
||||
bool_(bool value) : object(value ? py_True() : py_False(), ref_t{}) {}
|
||||
|
||||
explicit operator bool () { return py_tobool(ptr()); }
|
||||
};
|
||||
|
||||
@ -22,7 +22,10 @@ int load_module_from_dll_desktop_only(const char* path) PY_RAISE PY_RETURN {
|
||||
if(dll == NULL) return 0;
|
||||
py_module_initialize_t f_init = (py_module_initialize_t)dlsym(dll, f_init_name);
|
||||
#endif
|
||||
if(f_init == NULL) return 0;
|
||||
if(f_init == NULL) {
|
||||
RuntimeError("%s() not found in '%s'", f_init_name, path);
|
||||
return -1;
|
||||
}
|
||||
bool success = f_init();
|
||||
if(!success) return -1;
|
||||
return 1;
|
||||
|
||||
@ -52,23 +52,23 @@ static void py_TypeInfo__ctor(py_TypeInfo* self,
|
||||
};
|
||||
|
||||
self->module = module;
|
||||
self->annotations = *py_NIL;
|
||||
self->annotations = *py_NIL();
|
||||
}
|
||||
|
||||
void VM__ctor(VM* self) {
|
||||
self->top_frame = NULL;
|
||||
|
||||
ModuleDict__ctor(&self->modules, NULL, *py_NIL);
|
||||
ModuleDict__ctor(&self->modules, NULL, *py_NIL());
|
||||
TypeList__ctor(&self->types);
|
||||
|
||||
self->builtins = *py_NIL;
|
||||
self->main = *py_NIL;
|
||||
self->builtins = *py_NIL();
|
||||
self->main = *py_NIL();
|
||||
|
||||
self->callbacks.importfile = pk_default_importfile;
|
||||
self->callbacks.print = pk_default_print;
|
||||
|
||||
self->last_retval = *py_NIL;
|
||||
self->curr_exception = *py_NIL;
|
||||
self->last_retval = *py_NIL();
|
||||
self->curr_exception = *py_NIL();
|
||||
self->is_curr_exc_handled = false;
|
||||
|
||||
self->ctx = NULL;
|
||||
@ -329,7 +329,7 @@ py_Type pk_newtype(const char* name,
|
||||
if(base_ti && base_ti->is_sealed) {
|
||||
c11__abort("type '%s' is not an acceptable base type", py_name2str(base_ti->name));
|
||||
}
|
||||
py_TypeInfo__ctor(ti, py_name(name), index, base, base_ti, module ? *module : *py_NIL);
|
||||
py_TypeInfo__ctor(ti, py_name(name), index, base, base_ti, module ? *module : *py_NIL());
|
||||
if(!dtor && base) dtor = base_ti->dtor;
|
||||
ti->dtor = dtor;
|
||||
ti->is_python = is_python;
|
||||
|
||||
@ -106,7 +106,7 @@ static bool array2d_get(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARG_TYPE(1, tp_int);
|
||||
PY_CHECK_ARG_TYPE(2, tp_int);
|
||||
if(argc == 3) {
|
||||
default_ = py_None;
|
||||
default_ = py_None();
|
||||
} else if(argc == 4) {
|
||||
default_ = py_arg(3);
|
||||
} else {
|
||||
|
||||
@ -21,9 +21,9 @@ static bool json_dumps(int argc, py_Ref argv) {
|
||||
void pk__add_module_json() {
|
||||
py_Ref mod = py_newmodule("json");
|
||||
|
||||
py_setdict(mod, py_name("null"), py_None);
|
||||
py_setdict(mod, py_name("true"), py_True);
|
||||
py_setdict(mod, py_name("false"), py_False);
|
||||
py_setdict(mod, py_name("null"), py_None());
|
||||
py_setdict(mod, py_name("true"), py_True());
|
||||
py_setdict(mod, py_name("false"), py_False());
|
||||
|
||||
py_bindfunc(mod, "loads", json_loads);
|
||||
py_bindfunc(mod, "dumps", json_dumps);
|
||||
|
||||
@ -162,7 +162,7 @@ void CodeObject__dtor(CodeObject* self) {
|
||||
void Function__ctor(Function* self, FuncDecl_ decl, py_TValue* module) {
|
||||
PK_INCREF(decl);
|
||||
self->decl = decl;
|
||||
self->module = module ? *module : *py_NIL;
|
||||
self->module = module ? *module : *py_NIL();
|
||||
self->clazz = NULL;
|
||||
self->closure = NULL;
|
||||
self->cfunc = NULL;
|
||||
|
||||
@ -11,13 +11,9 @@
|
||||
|
||||
VM* pk_current_vm;
|
||||
|
||||
py_GlobalRef py_True;
|
||||
py_GlobalRef py_False;
|
||||
py_GlobalRef py_None;
|
||||
py_GlobalRef py_NIL;
|
||||
|
||||
static VM pk_default_vm;
|
||||
static VM* pk_all_vm[16];
|
||||
static py_TValue _True, _False, _None, _NIL;
|
||||
|
||||
void py_initialize() {
|
||||
if(pk_current_vm){
|
||||
@ -30,18 +26,18 @@ void py_initialize() {
|
||||
pk_current_vm = pk_all_vm[0] = &pk_default_vm;
|
||||
|
||||
// initialize some convenient references
|
||||
static py_TValue _True, _False, _None, _NIL;
|
||||
py_newbool(&_True, true);
|
||||
py_newbool(&_False, false);
|
||||
py_newnone(&_None);
|
||||
py_newnil(&_NIL);
|
||||
py_True = &_True;
|
||||
py_False = &_False;
|
||||
py_None = &_None;
|
||||
py_NIL = &_NIL;
|
||||
VM__ctor(&pk_default_vm);
|
||||
}
|
||||
|
||||
py_GlobalRef py_True() { return &_True; }
|
||||
py_GlobalRef py_False() { return &_False; }
|
||||
py_GlobalRef py_None() { return &_None; }
|
||||
py_GlobalRef py_NIL() { return &_NIL; }
|
||||
|
||||
void py_finalize() {
|
||||
for(int i = 1; i < 16; i++) {
|
||||
VM* vm = pk_all_vm[i];
|
||||
@ -169,7 +165,7 @@ bool pk_loadmethod(py_StackRef self, py_Name name) {
|
||||
py_Ref cls_var = py_tpfindmagic(py_totype(self), name);
|
||||
if(cls_var) {
|
||||
self[0] = *cls_var;
|
||||
self[1] = *py_NIL;
|
||||
self[1] = *py_NIL();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -197,7 +193,7 @@ bool pk_loadmethod(py_StackRef self, py_Name name) {
|
||||
}
|
||||
case tp_staticmethod:
|
||||
self[0] = *py_getslot(cls_var, 0);
|
||||
self[1] = *py_NIL;
|
||||
self[1] = *py_NIL();
|
||||
break;
|
||||
case tp_classmethod:
|
||||
self[0] = *py_getslot(cls_var, 0);
|
||||
|
||||
@ -676,11 +676,11 @@ py_TValue pk_builtins__register() {
|
||||
|
||||
// some patches
|
||||
py_bindmagic(tp_NoneType, __repr__, NoneType__repr__);
|
||||
*py_tpgetmagic(tp_NoneType, __hash__) = *py_None;
|
||||
*py_tpgetmagic(tp_NoneType, __hash__) = *py_None();
|
||||
py_bindmagic(tp_ellipsis, __repr__, ellipsis__repr__);
|
||||
*py_tpgetmagic(tp_ellipsis, __hash__) = *py_None;
|
||||
*py_tpgetmagic(tp_ellipsis, __hash__) = *py_None();
|
||||
py_bindmagic(tp_NotImplementedType, __repr__, NotImplementedType__repr__);
|
||||
*py_tpgetmagic(tp_NotImplementedType, __hash__) = *py_None;
|
||||
*py_tpgetmagic(tp_NotImplementedType, __hash__) = *py_None();
|
||||
return *builtins;
|
||||
}
|
||||
|
||||
|
||||
@ -389,7 +389,7 @@ static bool dict_update(int argc, py_Ref argv) {
|
||||
static bool dict_get(int argc, py_Ref argv) {
|
||||
Dict* self = py_touserdata(argv);
|
||||
if(argc > 3) return TypeError("get() takes at most 3 arguments (%d given)", argc);
|
||||
py_Ref default_val = argc == 3 ? py_arg(2) : py_None;
|
||||
py_Ref default_val = argc == 3 ? py_arg(2) : py_None();
|
||||
DictEntry* entry;
|
||||
if(!Dict__try_get(self, py_arg(1), &entry)) return false;
|
||||
*py_retval() = entry ? entry->val : *default_val;
|
||||
@ -399,7 +399,7 @@ static bool dict_get(int argc, py_Ref argv) {
|
||||
static bool dict_pop(int argc, py_Ref argv) {
|
||||
Dict* self = py_touserdata(argv);
|
||||
if(argc < 2 || argc > 3) return TypeError("pop() takes 1 or 2 arguments (%d given)", argc - 1);
|
||||
py_Ref default_val = argc == 3 ? py_arg(2) : py_None;
|
||||
py_Ref default_val = argc == 3 ? py_arg(2) : py_None();
|
||||
int res = Dict__pop(self, py_arg(1));
|
||||
if(res == -1) return false;
|
||||
if(res == 0) { py_assign(py_retval(), default_val); }
|
||||
@ -482,7 +482,7 @@ py_Type pk_dict__register() {
|
||||
py_bindmethod(type, "keys", dict_keys);
|
||||
py_bindmethod(type, "values", dict_values);
|
||||
|
||||
py_setdict(py_tpobject(type), __hash__, py_None);
|
||||
py_setdict(py_tpobject(type), __hash__, py_None());
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
@ -134,8 +134,8 @@ bool py_matchexc(py_Type type) {
|
||||
|
||||
void py_clearexc(py_StackRef p0) {
|
||||
VM* vm = pk_current_vm;
|
||||
vm->last_retval = *py_NIL;
|
||||
vm->curr_exception = *py_NIL;
|
||||
vm->last_retval = *py_NIL();
|
||||
vm->curr_exception = *py_NIL();
|
||||
vm->is_curr_exc_handled = false;
|
||||
|
||||
/* Don't clear this, because StopIteration() may corrupt the class defination */
|
||||
|
||||
@ -444,6 +444,6 @@ py_Type pk_list__register() {
|
||||
|
||||
py_bind(py_tpobject(type), "sort(self, key=None, reverse=False)", list_sort);
|
||||
|
||||
py_setdict(py_tpobject(type), __hash__, py_None);
|
||||
py_setdict(py_tpobject(type), __hash__, py_None());
|
||||
return type;
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@ static bool property__new__(int argc, py_Ref argv) {
|
||||
py_newobject(py_retval(), tp_property, 2, 0);
|
||||
if(argc == 1 + 1) {
|
||||
py_setslot(py_retval(), 0, py_arg(1));
|
||||
py_setslot(py_retval(), 1, py_None);
|
||||
py_setslot(py_retval(), 1, py_None());
|
||||
} else if(argc == 1 + 2) {
|
||||
py_setslot(py_retval(), 0, py_arg(1));
|
||||
py_setslot(py_retval(), 1, py_arg(2));
|
||||
|
||||
@ -100,7 +100,7 @@ py_Type pk_slice__register() {
|
||||
py_bindmagic(type, __eq__, slice__eq__);
|
||||
py_bindmagic(type, __ne__, slice__ne__);
|
||||
|
||||
py_setdict(py_tpobject(type), __hash__, py_None);
|
||||
py_setdict(py_tpobject(type), __hash__, py_None());
|
||||
|
||||
py_bindproperty(type, "start", slice_start, NULL);
|
||||
py_bindproperty(type, "stop", slice_stop, NULL);
|
||||
|
||||
@ -30,7 +30,7 @@ void py_setdict(py_Ref self, py_Name name, py_Ref val) {
|
||||
}
|
||||
|
||||
py_ItemRef py_emplacedict(py_Ref self, py_Name name){
|
||||
py_setdict(self, name, py_NIL);
|
||||
py_setdict(self, name, py_NIL());
|
||||
return py_getdict(self, name);
|
||||
}
|
||||
|
||||
|
||||
@ -67,7 +67,7 @@ void py_bindproperty(py_Type type, const char* name, py_CFunction getter, py_CFu
|
||||
if(setter) {
|
||||
py_newnativefunc(py_getslot(&tmp, 1), setter);
|
||||
} else {
|
||||
py_setslot(&tmp, 1, py_None);
|
||||
py_setslot(&tmp, 1, py_None());
|
||||
}
|
||||
py_setdict(py_tpobject(type), py_name(name), &tmp);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user