diff --git a/assets/images/coverage.svg b/assets/images/coverage.svg
index cb3cdc0..dba09e2 100644
--- a/assets/images/coverage.svg
+++ b/assets/images/coverage.svg
@@ -9,13 +9,13 @@
-
+
coverage
coverage
- 41%
- 41%
+ 38%
+ 38%
diff --git a/pyproject.toml b/pyproject.toml
index 0246a09..fa7fd1e 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -5,7 +5,7 @@ build-backend = "poetry.core.masonry.api"
[tool.poetry]
name = "PyCXpress"
-version = "0.0.7"
+version = "0.0.8"
description = "PyCXpress is a high-performance hybrid framework that seamlessly integrates Python and C++ to harness the flexibility of Python and the speed of C++ for efficient and expressive computation, particularly in the realm of deep learning and numerical computing."
readme = "README.md"
authors = ["chaoqing "]
diff --git a/src/PyCXpress/example/main.cpp b/src/PyCXpress/example/main.cpp
index 1208548..0d3e243 100644
--- a/src/PyCXpress/example/main.cpp
+++ b/src/PyCXpress/example/main.cpp
@@ -24,6 +24,8 @@ void show_test(pcx::Model &model) {
memcpy(model.set_buffer("new_2d_shape", {2}).first, shape.data(),
shape.size() * sizeof(uint8_t));
+ std::string status = "model ready to run";
+ setenv("PYCXPRESS_STATUS", status.c_str(), 1);
model.run();
// test retrieve output tensor
@@ -54,12 +56,14 @@ void show_test(pcx::Model &model) {
}
int main(int argc, char *argv[]) {
- auto &python = utils::Singleton::Instance();
+ auto &python = utils::Singleton::Instance();
+
+ std::string status = "model ready to initialized.";
+ setenv("PYCXPRESS_STATUS", status.c_str(), 1);
auto &model0 = python.create_model("model.Model");
auto &model1 = python.create_model("model.Model", "odd");
int loop_times = 3;
-
while (loop_times--) {
std::cout << "looping " << loop_times << std::endl;
if (loop_times % 2 == 0) {
diff --git a/src/PyCXpress/example/model.py b/src/PyCXpress/example/model.py
index 4e0652a..2b854cf 100644
--- a/src/PyCXpress/example/model.py
+++ b/src/PyCXpress/example/model.py
@@ -19,6 +19,7 @@
convert_to_spec_tuple,
pycxpress_debugger,
)
+from PyCXpress.utils import getenv
def show(a: np.ndarray):
@@ -76,6 +77,7 @@ def __init__(self):
def initialize(self):
self.input, self.output = InputDataSet(), OutputDataSet()
+ print("current status: ", getenv("PYCXPRESS_STATUS", ""))
return (
self.input,
@@ -84,6 +86,7 @@ def initialize(self):
)
def run(self):
+ print("current status: ", getenv("PYCXPRESS_STATUS", ""))
self.model(self.input, self.output)
@staticmethod
diff --git a/src/PyCXpress/utils.py b/src/PyCXpress/utils.py
index 5f4abd6..9f00a8f 100644
--- a/src/PyCXpress/utils.py
+++ b/src/PyCXpress/utils.py
@@ -1,6 +1,7 @@
from typing import Any, Dict, Tuple
import logging
+import os
import numpy as np
from numpy.typing import DTypeLike
@@ -8,6 +9,52 @@
logger = logging.getLogger("PyCXpress")
+# mypy: disable-error-code="attr-defined"
+def _refresh_environ():
+ """https://discuss.python.org/t/method-to-refresh-os-environ/54774/11"""
+ import ctypes
+ import sys
+
+ if sys.platform == "linux":
+
+ def _get_env_array(*, lib=ctypes.CDLL(None)):
+ return ctypes.POINTER(ctypes.c_char_p).in_dll(lib, "environ")
+
+ elif sys.platform == "win32":
+
+ def _get_env_array(*, lib=ctypes.CDLL("ucrtbase")):
+ p = ctypes.CFUNCTYPE(ctypes.POINTER(ctypes.POINTER(ctypes.c_wchar_p)))
+ return p(("__p__wenviron", lib))()[0]
+
+ else:
+ raise ImportError
+
+ uppercase_names = sys.platform == "win32"
+ _env_array = _get_env_array()
+ if isinstance(_env_array[0], bytes):
+ equals = b"="
+ else:
+ equals = "=" # type: ignore
+ c_environ = {}
+ for entry in _env_array:
+ if entry is None:
+ break
+ name, value = entry.split(equals, 1)
+ if uppercase_names:
+ c_environ[name.upper()] = value
+ else:
+ c_environ[name] = value
+
+ os.environ._data.clear()
+ os.environ._data.update(c_environ)
+
+
+def getenv(key, default=None):
+ """Just like getenv but always do refresh to obtain the latest process environments"""
+ _refresh_environ()
+ return os.getenv(key, default)
+
+
def get_c_type(t: DTypeLike) -> Tuple[str, int]:
dtype = np.dtype(t)
relation = {