Skip to content

Commit

Permalink
Merge pull request #164 from Sensing-Dev/feature/port-access
Browse files Browse the repository at this point in the history
Feature/port access
  • Loading branch information
iitaku authored Nov 30, 2023
2 parents de782b2 + 554ed8b commit 4436818
Show file tree
Hide file tree
Showing 8 changed files with 297 additions and 16 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ execute_process(COMMAND git describe --tags
message(STATUS "Version: ${GIT_DESCRIBE_RESULT}")
string(STRIP "${GIT_DESCRIBE_RESULT}" ION_KIT_VERSION_S)
add_definitions("-DION_KIT_VERSION=\"${ION_KIT_VERSION_S}\"")
string(REPLACE "v" "" ION_KIT_VERSION ${ION_KIT_VERSION_S})
string(REPLACE "v" "" ION_KIT_VERSION "${ION_KIT_VERSION_S}")
file(GENERATE OUTPUT ${CMAKE_BINARY_DIR}/VERSION CONTENT "${ION_KIT_VERSION_S}")

#
Expand Down
29 changes: 21 additions & 8 deletions include/ion/port.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,15 +147,15 @@ class Port {
friend class Node;

Port()
: key_(), type_(), dimensions_(0), node_id_(), param_info_() {}
: key_(), type_(), dimensions_(0), index_(-1), node_id_(), param_info_() {}

/**
* Construct new port for scalar value.
* @arg k: The key of the port which should be matched with BuildingBlock Input/Output name.
* @arg t: The type of the value.
*/
Port(const std::string& k, Halide::Type t)
: key_(k), type_(t), dimensions_(0), node_id_(), param_info_(new ParamContainer(k, t)) {}
: key_(k), type_(t), dimensions_(0), index_(-1), node_id_(), param_info_(new ParamContainer(k, t)) {}

/**
* Construct new port for vector value.
Expand All @@ -164,7 +164,7 @@ class Port {
* @arg d: The dimension of the port. The range is 1 to 4.
*/
Port(const std::string& k, Halide::Type t, int32_t d)
: key_(k), type_(t), dimensions_(d), node_id_(), param_info_(new ParamContainer(k, t, d)) {}
: key_(k), type_(t), dimensions_(d), index_(-1), node_id_(), param_info_(new ParamContainer(k, t, d)) {}

std::string key() const { return key_; }
std::string& key() { return key_; }
Expand All @@ -175,6 +175,9 @@ class Port {
int32_t dimensions() const { return dimensions_; }
int32_t& dimensions() { return dimensions_; }

int32_t index() const { return index_; }
int32_t& index() { return index_; }

std::string node_id() const { return node_id_; }
std::string& node_id() { return node_id_; }

Expand Down Expand Up @@ -203,15 +206,25 @@ class Port {
return !node_id_.empty();
}

private:
/**
* This port is bound with some node.
*/
Port(const std::string& k, const std::string& ni) : key_(k), type_(), dimensions_(0), node_id_(ni), param_info_(nullptr){}

/**
* Overloaded operator to set the port index and return a reference to the current port. eg. port[0]
*/
Port operator[](int i) {
this->index_ = i;
return *this;
}

private:
/**
* This port is bound with some node.
*/
Port(const std::string& k, const std::string& ni) : key_(k), type_(), index_(-1), dimensions_(0), node_id_(ni), param_info_(nullptr){}

std::string key_;
Halide::Type type_;
int32_t dimensions_;
int32_t index_;
std::string node_id_;
std::shared_ptr<ParamContainer> param_info_;
};
Expand Down
6 changes: 4 additions & 2 deletions src/bb/base/rt.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,12 @@ namespace bb {
namespace base {

std::tuple<std::string, std::string> parse_url(const std::string &url) {
if (url.rfind("http://", 0) != 0) { // not starts_with
auto protocol_end_pos = url.find("://");
if (protocol_end_pos == std::string::npos) {
return std::tuple<std::string, std::string>("", "");
}
auto path_name_pos = url.find("/", 7);
auto host_name_pos = protocol_end_pos + 3;
auto path_name_pos = url.find("/", host_name_pos);
auto host_name = url.substr(0, path_name_pos);
auto path_name = url.substr(path_name_pos);
return std::tuple<std::string, std::string>(host_name, path_name);
Expand Down
162 changes: 162 additions & 0 deletions src/bb/image-io/bb.h
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,164 @@ class Camera : public ion::BuildingBlock<Camera> {
}
};

class Camera2 : public ion::BuildingBlock<Camera2> {
public:
GeneratorParam<int32_t> num_devices{"num_devices", 2};
GeneratorParam<std::string> gc_title{"gc_title", "USBCamera"};
GeneratorParam<std::string> gc_description{"gc_description", "This captures USB camera image."};
GeneratorParam<std::string> gc_tags{"gc_tags", "input,sensor"};
GeneratorParam<std::string> gc_inference{"gc_inference", R"((function(v){ return { output: [parseInt(v.width), parseInt(v.height), 3] }}))"};
GeneratorParam<std::string> gc_mandatory{"gc_mandatory", "width,height"};
GeneratorParam<std::string> gc_strategy{"gc_strategy", "self"};
GeneratorParam<std::string> gc_prefix{"gc_prefix", ""};

GeneratorParam<int32_t> fps{"fps", 30};
GeneratorParam<int32_t> width{"width", 0};
GeneratorParam<int32_t> height{"height", 0};
GeneratorParam<int32_t> index{"index", 0};
GeneratorParam<std::string> url0{"url0", ""};
GeneratorParam<std::string> url1{"url1", ""};



GeneratorOutput<Halide::Func> output0{"output0", Halide::type_of<uint8_t>(), 3};
GeneratorOutput<Halide::Func> output1{"output1", Halide::type_of<uint8_t>(), 3};


void generate() {
using namespace Halide;


for (int i =0; i < num_devices; i++){
std::string url_str;
if(i == 0){
url_str = url0;
}
else{
url_str = url1;
}

Halide::Buffer<uint8_t> url_buf(url_str.size() + 1);
url_buf.fill(0);
std::memcpy(url_buf.data(), url_str.c_str(), url_str.size());

std::vector<ExternFuncArgument> params = {instance_id++, cast<int32_t>(index), cast<int32_t>(fps), cast<int32_t>(width), cast<int32_t>(height), url_buf};
Func camera(static_cast<std::string>(gc_prefix) + "camera");
camera.define_extern("ion_bb_image_io_camera", params, Halide::type_of<uint8_t>(), 2);
camera.compute_root();

Func camera_ = BoundaryConditions::repeat_edge(camera, {{0, 2 * width}, {0, height}});

Var c, x, y;

Expr yv = cast<float>(camera_(2 * x, y));
Expr uv = cast<float>(camera_(select((x & 1) == 0, 2 * x + 1, 2 * x - 1), y));
Expr vv = cast<float>(camera_(select((x & 1) == 0, 2 * x + 3, 2 * x + 1), y));

Expr f128 = cast<float>(128);
Expr r = saturating_cast<uint8_t>(yv + cast<float>(1.403f) * (vv - f128));
Expr g = saturating_cast<uint8_t>(yv - cast<float>(0.344f) * (uv - f128) - (cast<float>(0.714f) * (vv - f128)));
Expr b = saturating_cast<uint8_t>(yv + cast<float>(1.773f) * (uv - f128));




Func f(static_cast<std::string>(gc_prefix) + "output" + std::to_string(i));
f(x, y, c) = mux(c, {r, g, b});


if (i ==0)
output0 = f;
else
output1 = f;
}

}
};



class CameraN : public ion::BuildingBlock<CameraN> {
public:
GeneratorParam<int32_t> num_devices{"num_devices", 2};
GeneratorParam<std::string> gc_title{"gc_title", "USBCamera"};
GeneratorParam<std::string> gc_description{"gc_description", "This captures USB camera image."};
GeneratorParam<std::string> gc_tags{"gc_tags", "input,sensor"};
GeneratorParam<std::string> gc_inference{"gc_inference", R"((function(v){ return { output: [parseInt(v.width), parseInt(v.height), 3] }}))"};
GeneratorParam<std::string> gc_mandatory{"gc_mandatory", "width,height"};
GeneratorParam<std::string> gc_strategy{"gc_strategy", "self"};
GeneratorParam<std::string> gc_prefix{"gc_prefix", ""};

GeneratorParam<int32_t> fps{"fps", 30};
GeneratorParam<int32_t> width{"width", 0};
GeneratorParam<int32_t> height{"height", 0};
GeneratorParam<int32_t> index{"index", 0};
GeneratorParam<std::string> urls{"urls", ""};

// GeneratorInput<Buffer<uint8_t>[]> urls{"urls"};
GeneratorOutput<Halide::Func[]> output{"output", Halide::type_of<uint8_t>(), 3};


void generate() {

std::stringstream urls_stream(urls);
std::string url;
std::vector<std::string> url_list;
while(std::getline(urls_stream, url, ';'))
{
url_list.push_back(url);
}


using namespace Halide;

output.resize(num_devices);

for (int i =0; i < num_devices; i++){
std::string url_str;
if (url_list.size()!=0){
url_str = url_list[i];
}
else{
url_str = "";
}



Halide::Buffer<uint8_t> url_buf(url_str.size() + 1);
url_buf.fill(0);
std::memcpy(url_buf.data(), url_str.c_str(), url_str.size());

std::vector<ExternFuncArgument> params = {instance_id++, cast<int32_t>(index), cast<int32_t>(fps), cast<int32_t>(width), cast<int32_t>(height), url_buf};
Func camera(static_cast<std::string>(gc_prefix) + "camera");
camera.define_extern("ion_bb_image_io_camera", params, Halide::type_of<uint8_t>(), 2);
camera.compute_root();

Func camera_ = BoundaryConditions::repeat_edge(camera, {{0, 2 * width}, {0, height}});

Var c, x, y;

Expr yv = cast<float>(camera_(2 * x, y));
Expr uv = cast<float>(camera_(select((x & 1) == 0, 2 * x + 1, 2 * x - 1), y));
Expr vv = cast<float>(camera_(select((x & 1) == 0, 2 * x + 3, 2 * x + 1), y));

Expr f128 = cast<float>(128);
Expr r = saturating_cast<uint8_t>(yv + cast<float>(1.403f) * (vv - f128));
Expr g = saturating_cast<uint8_t>(yv - cast<float>(0.344f) * (uv - f128) - (cast<float>(0.714f) * (vv - f128)));
Expr b = saturating_cast<uint8_t>(yv + cast<float>(1.773f) * (uv - f128));


Func f(static_cast<std::string>(gc_prefix) + "output" + std::to_string(i));
f(x, y, c) = mux(c, {r, g, b});

output[i](_) = f(_);
}

}
};



class GenericV4L2Bayer : public ion::BuildingBlock<GenericV4L2Bayer> {
public:
GeneratorParam<std::string> gc_title{"gc_title", "GenericV4L2Bayer"};
Expand Down Expand Up @@ -1087,7 +1245,11 @@ class BinaryLoader : public ion::BuildingBlock<BinaryLoader> {
#ifndef _WIN32
ION_REGISTER_BUILDING_BLOCK(ion::bb::image_io::IMX219, image_io_imx219);
ION_REGISTER_BUILDING_BLOCK(ion::bb::image_io::D435, image_io_d435);

ION_REGISTER_BUILDING_BLOCK(ion::bb::image_io::Camera, image_io_camera);
ION_REGISTER_BUILDING_BLOCK(ion::bb::image_io::Camera2, image_io_camera2);
ION_REGISTER_BUILDING_BLOCK(ion::bb::image_io::CameraN, image_io_cameraN);

ION_REGISTER_BUILDING_BLOCK(ion::bb::image_io::GenericV4L2Bayer, image_io_generic_v4l2_bayer);
ION_REGISTER_BUILDING_BLOCK(ion::bb::image_io::CameraSimulation, image_io_camera_simulation);
ION_REGISTER_BUILDING_BLOCK(ion::bb::image_io::FBDisplay, image_io_fb_display);
Expand Down
9 changes: 5 additions & 4 deletions src/bb/image-io/rt_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,11 @@ class DynamicModule {
};

std::tuple<std::string, std::string> parse_url(const std::string &url) {
if (url.rfind("http://", 0) != 0) { // not starts_with
auto protocol_end_pos = url.find("://");
if (protocol_end_pos == std::string::npos)
return std::tuple<std::string, std::string>("", "");
}
auto path_name_pos = url.find("/", 7);
auto host_name_pos = protocol_end_pos + 3;
auto path_name_pos = url.find("/", host_name_pos);
auto host_name = url.substr(0, path_name_pos);
auto path_name = url.substr(path_name_pos);
return std::tuple<std::string, std::string>(host_name, path_name);
Expand Down Expand Up @@ -329,4 +330,4 @@ struct rawHeader {
} // namespace bb
} // namespace ion

#endif
#endif
15 changes: 14 additions & 1 deletion src/builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ Halide::Pipeline Builder::build(const ion::PortMap& pm, std::vector<Halide::Buff
std::vector<std::vector<Internal::StubInput>> args;
for (size_t j=0; j<n.ports().size(); ++j) {
auto p = n.ports()[j];
auto index = p.index();
// Unbounded parameter
auto *in = bb->param_info().inputs().at(j);
if (p.node_id().empty()) {
Expand Down Expand Up @@ -308,7 +309,19 @@ Halide::Pipeline Builder::build(const ion::PortMap& pm, std::vector<Halide::Buff
}
args.push_back(bb->build_input(j, f()));
} else if (in->kind() == Internal::IOKind::Function) {
args.push_back(bb->build_input(j, f));
auto fs =bbs[p.node_id()]->get_outputs(p.key());
// no specific index provided, direct output Port
if (index == -1)
args.push_back(bb->build_input(j,f));
else{
// access to Port[index]
if (index>=fs.size()){
throw std::runtime_error("Port index out of range: " + in->name());
}
args.push_back(bb->build_input(j, fs[index]));
}


} else {
throw std::runtime_error("fixme");
}
Expand Down
6 changes: 6 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ ion_jit(port-binding SRCS port-binding.cc)
add_dependencies(port-binding ion-bb-test)
ion_register_test(port-binding_test port-binding)

# Port index access
ion_jit(port-access SRCS port-access.cc)
add_dependencies(port-access ion-bb-test)
ion_register_test(port-access_test port-access)


ion_jit(direct-extern SRCS direct-extern.cc)
add_dependencies(direct-extern ion-bb-test)
ion_register_test(direct-extern_test direct-extern)
Expand Down
Loading

0 comments on commit 4436818

Please sign in to comment.