Skip to content

Commit

Permalink
add portmap index access
Browse files Browse the repository at this point in the history
  • Loading branch information
xinyuli1204 committed Dec 8, 2023
1 parent 6e0b038 commit 7238f78
Show file tree
Hide file tree
Showing 6 changed files with 183 additions and 17 deletions.
20 changes: 10 additions & 10 deletions include/ion/port_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,20 @@ namespace std
{

template<>
struct hash<tuple<string, string>>
struct hash<tuple<string, string, int>>
{
std::size_t operator()(const tuple<string, string>& k) const noexcept
std::size_t operator()(const tuple<string, string, int>& k) const noexcept
{
return std::hash<std::string>{}(std::get<0>(k)) ^ std::hash<std::string>{}(std::get<1>(k));
return std::hash<std::string>{}(std::get<0>(k)) ^ std::hash<std::string>{}(std::get<1>(k)) ^ std::hash<int>{}(std::get<2>(k));
}
};

template<>
struct equal_to<tuple<string, string>>
struct equal_to<tuple<string, string, int>>
{
bool operator()(const tuple<string, string>& v0, const tuple<string, string>& v1) const
bool operator()(const tuple<string, string, int>& v0, const tuple<string, string, int>& v1) const
{
return (std::get<0>(v0) == std::get<0>(v1) && std::get<1>(v0) == std::get<1>(v1));
return (std::get<0>(v0) == std::get<0>(v1) && std::get<1>(v0) == std::get<1>(v1) && std::get<2>(v0) == std::get<2>(v1));
}
};

Expand Down Expand Up @@ -98,7 +98,7 @@ class PortMap {
void set(Port p, Halide::Buffer<T> &buf) {
if (p.bound()) {
// This is just an output.
output_buffer_[std::make_tuple(p.node_id(), p.key())] = { buf };
output_buffer_[std::make_tuple(p.node_id(), p.key(), p.index())] = { buf };
} else {
param_func_[p.key()] = p.func();
p.set_to_param_map(param_map_, buf);
Expand Down Expand Up @@ -129,7 +129,7 @@ class PortMap {
// This is just an output.

for (size_t i=0; i<bufs.size(); ++i) {
output_buffer_[std::make_tuple(p.node_id(), p.key())].push_back(bufs[i]);
output_buffer_[std::make_tuple(p.node_id(), p.key(), p.index())].push_back(bufs[i]);
}
} else {
throw std::invalid_argument(
Expand All @@ -149,7 +149,7 @@ class PortMap {
return param_func_.at(k);
}

std::unordered_map<std::tuple<std::string, std::string>, std::vector<Halide::Buffer<>>> get_output_buffer() const {
std::unordered_map<std::tuple<std::string, std::string, int>, std::vector<Halide::Buffer<>>> get_output_buffer() const {
return output_buffer_;
}

Expand All @@ -161,7 +161,7 @@ class PortMap {

std::unordered_map<std::string, Halide::Expr> param_expr_;
std::unordered_map<std::string, Halide::Func> param_func_;
std::unordered_map<std::tuple<std::string, std::string>, std::vector<Halide::Buffer<>>> output_buffer_;
std::unordered_map<std::tuple<std::string, std::string, int>, std::vector<Halide::Buffer<>>> output_buffer_;
Halide::ParamMap param_map_;
};

Expand Down
63 changes: 63 additions & 0 deletions python/tests/test_portmap_access.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# https://github.com/fixstars/ion-csharp/blob/master/test/Test.cs
from ionpy import Node, Builder, Buffer, PortMap, Port, Param, Type, TypeCode
import numpy as np
import cv2
import os


def test_portmap_access():

w = 200
h = 200
t = Type(code_=TypeCode.Uint, bits_=8, lanes_=1)
width = Param(key='width', val=str(w))
height = Param(key='height', val=str(h))
urls = Param(key="urls",val="http://optipng.sourceforge.net/pngtech/img/lena.png;http://upload.wikimedia.org/wikipedia/commons/0/05/Cat.png")

builder = Builder()
builder.set_target(target='host')
# make sure path includes libion-bb.so
builder.with_bb_module(path='/home/xinyu.li/dependency/ion-kit-install/lib/libion-bb.so')

node = builder.add('image_io_cameraN').set_param(params=[width, height, urls])



sizes = (w, h, 3)
obuf1 = Buffer(type=t, sizes=sizes)
obuf2 = Buffer(type=t, sizes=sizes)
odata_bytes1 = np.zeros(w*h*3,dtype=np.uint8).tobytes()
odata_bytes2 = np.zeros(w*h*3,dtype=np.uint8).tobytes()
obuf1.write(data=odata_bytes1)
obuf2.write(data=odata_bytes2)

port_map = PortMap()
port_map.set_buffer(port=node.get_port(key='output')[0], buffer=obuf1)
port_map.set_buffer(port=node.get_port(key='output')[1], buffer=obuf2)

builder.run(port_map=port_map)

out_byte_arr1 = obuf1.read(len(odata_bytes1))
out_byte_arr2 = obuf2.read(len(odata_bytes2))

img_out1 = np.frombuffer(out_byte_arr1, dtype=np.uint8)
img_out2 = np.frombuffer(out_byte_arr2, dtype=np.uint8)


b1 = img_out1[:w*h]
g1 = img_out1[w*h:2*w*h]
r1 = img_out1[2*w*h:]

b2 = img_out2[:w*h]
g2 = img_out2[w*h:2*w*h]
r2 = img_out2[2*w*h:]
#
img_out1 = cv2.merge((r1,g1,b1)).reshape(w,h,3)
img_out2 = cv2.merge((r2,g2,b2)).reshape(w,h,3)

DISPLAY = os.getenv("DISPLAY","false").lower()=="true"

if DISPLAY:
cv2.imshow("display1", img_out1)
cv2.imshow("display2", img_out2)
cv2.waitKey(3000)
26 changes: 19 additions & 7 deletions src/builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -338,19 +338,31 @@ Halide::Pipeline Builder::build(const ion::PortMap& pm, std::vector<Halide::Buff
for (auto kv : pm.get_output_buffer()) {
auto node_id = std::get<0>(kv.first);
auto port_key = std::get<1>(kv.first);
auto index = std::get<2>(kv.first);

bool found = false;
for (auto info : bbs[node_id]->param_info().outputs()) {
if (info->name() == port_key) {
if (info->is_array()) {
auto fs = bbs[node_id]->get_outputs(port_key);
if (fs.size() != kv.second.size()) {
throw std::runtime_error("Invalid size of array : " + node_id + ", " + port_key);
}
for (size_t i=0; i<fs.size(); ++i) {
output_funcs.push_back(fs[i]);
outputs->push_back(kv.second[i]);
if (index!=-1){
auto fs = bbs[node_id]->get_outputs(port_key);
if (index>=fs.size()){
throw std::runtime_error("Port index out of range: " + node_id + ", " + port_key);
}
output_funcs.push_back(fs[index]);
outputs->push_back(kv.second.front());

}else{
auto fs = bbs[node_id]->get_outputs(port_key);
if (fs.size() != kv.second.size()) {
throw std::runtime_error("Invalid size of array : " + node_id + ", " + port_key);
}
for (size_t i=0; i<fs.size(); ++i) {
output_funcs.push_back(fs[i]);
outputs->push_back(kv.second[i]);
}
}

} else {
auto f = bbs[node_id]->get_outputs(port_key).front();
if (1 != kv.second.size()) {
Expand Down
4 changes: 4 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ ion_jit(port-access SRCS port-access.cc)
add_dependencies(port-access ion-bb-test)
ion_register_test(port-access_test port-access)

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

ion_jit(direct-extern SRCS direct-extern.cc)
add_dependencies(direct-extern ion-bb-test)
Expand Down
1 change: 1 addition & 0 deletions test/port-access.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ void display_image_float(Halide::Buffer<float> buffer, std::string filename) {
}
#ifdef DISPLAY
cv::imshow( "Display window: " + filename, img_out);
cv::waitKey(3000);
#endif
}

Expand Down
86 changes: 86 additions & 0 deletions test/portmap-access.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#include <iostream>
#include <ion/ion.h>

// to display
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#define DISPLAY

using namespace ion;

void display_image_uint8(Halide::Buffer<uint8_t> buffer, std::string filename) {
int width = buffer.width();
int height = buffer.height();
int channels = buffer.channels();
cv::Mat img_out;
if (channels == 3) {
cv::merge(std::vector<cv::Mat>{
cv::Mat(height, width, CV_8U, buffer.data() + width * height * 2), //b
cv::Mat(height, width, CV_8U, buffer.data() + width * height * 1), //g
cv::Mat(height, width, CV_8U, buffer.data())}, //r
img_out);

} else {
cv::Mat img_out(height, width, CV_8U, buffer.data());
}
#ifdef DISPLAY
cv::imshow( "Display window: " + filename, img_out);
cv::waitKey(3000);
#endif
}


int main(int argc, char *argv[]) {
try {
// TODO: Test with FullHD
const int width = 200;
const int height = 150;

Param wparam("width", std::to_string(width));
Param hparam("height", std::to_string(height));

Port wport("width", Halide::type_of<int32_t>());
Port hport("height", Halide::type_of<int32_t>());

Builder b;
b.set_target(Halide::get_target_from_environment());
b.with_bb_module("ion-bb");

Node n;
n = b.add("image_io_cameraN").set_param(
wparam,
hparam,
Param{"num_devices", "2"},
Param{"urls", "http://optipng.sourceforge.net/pngtech/img/lena.png;http://upload.wikimedia.org/wikipedia/commons/0/05/Cat.png"}
//input urls split by ';'
);


PortMap pm;
Halide::Buffer<uint8_t> out_buf0( width, height,3);
Halide::Buffer<uint8_t> out_buf1( width, height,3);





pm.set(wport, width);
pm.set(hport, height);

pm.set(n["output"][0],out_buf0);
pm.set(n["output"][1],out_buf1);

b.run(pm);
display_image_uint8(out_buf0, "display.png");
display_image_uint8(out_buf1, "display.png");
std::cout << "Success" << std::endl;
} catch (const std::exception &e) {
std::cerr << e.what() << std::endl;
return -1;
} catch (...) {
return -1;
}

return 0;
}

0 comments on commit 7238f78

Please sign in to comment.