Skip to content

Commit

Permalink
a working version but error when shutdown
Browse files Browse the repository at this point in the history
  • Loading branch information
chaoqing committed Jan 13, 2025
1 parent 7d2313b commit 321acac
Show file tree
Hide file tree
Showing 9 changed files with 467 additions and 171 deletions.
6 changes: 3 additions & 3 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/sample/sample",
"args": [],
"args": ["main.Model"],
"stopAtEntry": false,
"cwd": "${workspaceFolder}/src/PyCXpress/example/",
"cwd": "${workspaceFolder}/build/sample",
"environment": [
{
"name": "PYTHONPATH",
"value": "${workspaceFolder}/src"
"value": "${workspaceFolder}/sample"
},
{
"name": "LD_PRELOAD",
Expand Down
9 changes: 7 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,15 @@ POETRY := poetry
PYTHON := $(POETRY) run python3
PYTHONPATH := $(REPO_DIR)/src
CMAKE := cmake
USE_GCC ?= 1
TYPE ?= D
USE_LIBTENSORFLOW_CC ?= 0

ENVS := CC=clang CXX=clang++
ifeq ($(USE_GCC),1)
ENVS += CC=gcc CXX=g++
else
ENVS += CC=clang CXX=clang++
endif
ENVS += CPM_SOURCE_CACHE=$(CPM_SOURCE_CACHE)
ENVS += POETRY_VIRTUALENVS_IN_PROJECT=true
ENVS += PATH=$(REPO_DIR)/.venv/bin:$(PATH)
Expand Down Expand Up @@ -56,7 +61,7 @@ example-tensorflow: build-sample example-graph
ifeq ($(USE_LIBTENSORFLOW_CC),1)
@env TF_CPP_MIN_LOG_LEVEL=2 $(THIS_MAKEFILE_DIR)/build/sample/sample --name whole_flow -- ./sample/saved_model/
else
@env TF_CPP_MIN_LOG_LEVEL=2 PYTHONPATH=$(THIS_MAKEFILE_DIR)/src/PyCXpress/example $(THIS_MAKEFILE_DIR)/build/sample/sample --name whole_flow -- model.Model
@env TF_CPP_MIN_LOG_LEVEL=2 PYTHONPATH=$(THIS_MAKEFILE_DIR)/sample $(THIS_MAKEFILE_DIR)/build/sample/sample --name whole_flow -- main.Model
endif

example: example-pycxpress example-tensorflow
Expand Down
93 changes: 88 additions & 5 deletions sample/main.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,109 @@
#!/usr/bin//env python

from typing import List
import os

os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3"
from typing import List, Optional

import logging
import shutil
import sys
from contextlib import nullcontext

logging.basicConfig(level=logging.DEBUG)
import numpy as np
import tensorflow as tf
import tensorflow.compat.v1 as tf1
from tensorflow.python.saved_model import tag_constants

from PyCXpress import (
ModelAnnotationCreator,
ModelAnnotationType,
ModelRuntimeType,
TensorMeta,
convert_to_spec_tuple,
pycxpress_debugger,
)
from PyCXpress.utils import getenv

execution_mode = (
ModelRuntimeType.GraphExecution
if __name__ == "__main__"
else ModelRuntimeType.EagerExecution
)

InputFields = dict(
placeHolder_a=TensorMeta(
name="a",
dtype=np.uint8,
shape=(100, 100),
),
placeHolder_b=TensorMeta(name="b", dtype=np.uint8, shape=(100, 100)),
)


class InputDataSet(
metaclass=ModelAnnotationCreator,
fields=InputFields,
type=ModelAnnotationType.Input,
mode=execution_mode,
raw=False,
):
pass


OutputFields = dict(
sum=TensorMeta(
name="import/add:0",
dtype=np.uint8,
shape=(100, 100),
),
)


class OutputDataSet(
metaclass=ModelAnnotationCreator,
fields=OutputFields,
type=ModelAnnotationType.Output,
mode=execution_mode,
raw=False,
):
pass


class Model:
def __init__(self):
self.input, self.output = InputDataSet(), OutputDataSet()

def initialize(self):
print("current status: ", getenv("PYCXPRESS_STATUS", ""))

return (
self.input,
self.output,
tuple(convert_to_spec_tuple(InputFields.values(), OutputFields.values())),
)

def run(self):
print("current status: ", getenv("PYCXPRESS_STATUS", ""))
self.model(self.input, self.output, use_tensorflow=True)

@staticmethod
def model(input: InputDataSet, output: OutputDataSet, use_tensorflow: bool = True):
with nullcontext():
output.sum = input.placeHolder_a + input.placeHolder_b


def main(argv: List[str]):
def main(_: List[str]):
shutil.rmtree("./frozen_graph", ignore_errors=True)
shutil.rmtree("./saved_model", ignore_errors=True)

g = tf.Graph()

with g.as_default() if True else nullcontext():
a = tf1.placeholder(tf.uint8, shape=(None, None), name="a")
b = tf1.placeholder(tf.uint8, shape=(None, None), name="b")
_ = a + b
model = Model()
model.initialize()
model.run()

tf.io.write_graph(g, "./frozen_graph/", name="frozen_graph.pb", as_text=False)

Expand Down
54 changes: 40 additions & 14 deletions src/PyCXpress/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def __new__(

for field_name, field_meta in fields.items():
field_meta.setdefault(field_name)
attrs[field_name] = generate_property(field_meta, raw)
attrs[field_name] = generate_property(field_meta, raw, mode)

get_buffer_shape, set_buffer_value, init_func = mcs.general_funcs(
name, [field_meta.name for field_meta in fields.values()]
Expand Down Expand Up @@ -119,15 +119,28 @@ def init_func(self):
return get_buffer_shape, set_buffer_value, init_func

@staticmethod
def generate_input_property(field: TensorMeta, raw: bool):
def generate_input_property(
field: TensorMeta,
raw: bool,
mode: ModelRuntimeType = ModelRuntimeType.EagerExecution,
):
def get_func(self):
data = self.__buffer_data__[field.name].data
if raw:
return data
if mode == ModelRuntimeType.EagerExecution:
data = self.__buffer_data__[field.name].data
if raw:
return data
else:
import tensorflow as tf

return tf.Variable(data, name=field.name)
elif mode == ModelRuntimeType.GraphExecution:
assert not raw
import tensorflow.compat.v1 as tf1

return tf1.placeholder(field.dtype, shape=field.shape, name=field.name)
# TODO: record used input names in graph mode
else:
import tensorflow as tf

return tf.Variable(data, name=field.name)
raise NotImplementedError("OfflineExecution not supported for now")

def set_func(*_):
raise AssertionError("Not supported for input tensor")
Expand All @@ -138,18 +151,31 @@ def del_func(_):
return property(fget=get_func, fset=set_func, fdel=del_func, doc=field.doc)

@staticmethod
def generate_output_property(field: TensorMeta, raw: bool):
def generate_output_property(
field: TensorMeta,
raw: bool,
mode: ModelRuntimeType = ModelRuntimeType.EagerExecution,
):
def get_func(self):
logger.warning(f"Only read the data field {field.name} in debugging mode")
buffer = self.__buffer_data__[field.name]
return buffer.data[: np.prod(buffer.shape)].reshape(buffer.shape)

def set_func(self, data):
buffer = self.__buffer_data__[field.name]
buffer.shape = data.shape
len = np.prod(data.shape)
assert len <= buffer.data.size
buffer.data[:len] = (data if raw else data.numpy()).flatten()
if mode == ModelRuntimeType.EagerExecution:
buffer = self.__buffer_data__[field.name]
buffer.shape = data.shape
len = np.prod(data.shape)
assert len <= buffer.data.size
buffer.data[:len] = (data if raw else data.numpy()).flatten()
elif mode == ModelRuntimeType.GraphExecution:
assert not raw
import tensorflow.compat.v1 as tf1

assert field.name is None or field.name == f"import/{data.name}"
# TODO: record used output names in graph mode
else:
raise NotImplementedError("OfflineExecution not supported for now")

def del_func(_):
raise AssertionError("Not supported for output tensor")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class TensorShape;
/// object, you can specify it then, or you can create a TensorShape with
/// zero dimensions and one element, and call AddDim() to add dimensions later.
class TensorShape {
std::vector<int64_t> m_dims;
public:
///// \brief Construct a `TensorShapeBase` from the provided sizes.
///// REQUIRES: `dim_sizes[i] >= 0` (or >= -1 for PartialTensorShape)
Expand Down
Loading

0 comments on commit 321acac

Please sign in to comment.