From 31a063e03c2195d6468cafd201e29295d34fc1a3 Mon Sep 17 00:00:00 2001 From: Xinyu Li Date: Mon, 21 Oct 2024 09:47:44 -0700 Subject: [PATCH 1/8] update scalar input array --- include/ion/port.h | 33 ++++++++++++---------- test/CMakeLists.txt | 3 ++ test/scalar_array_input.cc | 57 ++++++++++++++++++++++++++++++++++++++ test/test-bb.h | 19 +++++++++++++ 4 files changed, 98 insertions(+), 14 deletions(-) create mode 100644 test/scalar_array_input.cc diff --git a/include/ion/port.h b/include/ion/port.h index 7206eeee..e717e345 100644 --- a/include/ion/port.h +++ b/include/ion/port.h @@ -103,9 +103,9 @@ class Port { */ template::value>::type * = nullptr> - Port(T *vptr) + Port(T *vptr, int size = 1) : impl_(new Impl(NodeID(""), Halide::Internal::unique_name("_ion_port_"), Halide::type_of(), 0, GraphID(""))), index_(-1) { - this->bind(vptr); + this->bind(vptr, size); } /** @@ -113,9 +113,9 @@ class Port { */ template::value>::type * = nullptr> - Port(T *vptr, const GraphID &gid) + Port(T *vptr, const GraphID &gid, int size = 1) : impl_(new Impl(NodeID(""), Halide::Internal::unique_name("_ion_port_"), Halide::type_of(), 0, gid)), index_(-1) { - this->bind(vptr); + this->bind(vptr, size); } /** @@ -222,21 +222,26 @@ class Port { } template - void bind(T *v) { - bind(Halide::type_of(), v); + void bind(T *v, int size = 1) { + if (size == 1) { + auto i = index_ == -1 ? 0 : index_; + bind(Halide::type_of(), v, i); + }else{ + for(int i = 0;i < size; i++){ + bind(Halide::type_of(), (void *)v, i); + v = v + 1; + } + } } - void bind(Halide::Type target_type, void *v) { - auto i = index_ == -1 ? 0 : index_; - + void bind(Halide::Type target_type, void *v, int idx) { if (has_pred()) { - impl_->params[i] = Halide::Parameter{target_type, false, 0, argument_name(pred_id(), id(), pred_name(), i, graph_id())}; + impl_->params[idx] = Halide::Parameter{target_type, false, 0, argument_name(pred_id(), id(), pred_name(), idx, graph_id())}; } else { - impl_->params[i] = Halide::Parameter{type(), false, dimensions(), argument_name(pred_id(), id(), pred_name(), i, graph_id())}; + impl_->params[idx] = Halide::Parameter{type(), false, dimensions(), argument_name(pred_id(), id(), pred_name(), idx, graph_id())}; } - - impl_->instances[i] = v; - impl_->bound_address[i] = std::make_tuple(v, false); + impl_->instances[idx] = v; + impl_->bound_address[idx] = std::make_tuple(v, false); } template diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 83d3e890..74be0f0d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -31,6 +31,9 @@ ion_jit_executable(array_input SRCS array_input.cc) # Array Output test ion_jit_executable(array_output SRCS array_output.cc) +# Scalar array Input test +ion_jit_executable(scalar_array_input SRCS scalar_array_input.cc) + # Duplicate array names test ion_jit_executable(array_dup_names SRCS array_dup_names.cc) diff --git a/test/scalar_array_input.cc b/test/scalar_array_input.cc new file mode 100644 index 00000000..b7423669 --- /dev/null +++ b/test/scalar_array_input.cc @@ -0,0 +1,57 @@ +#include + +#include "ion/ion.h" +#include +#include "test-bb.h" +#include "test-rt.h" + +using namespace std; +using namespace ion; + +int main() { + try { + constexpr size_t h = 4, w = 4; + + Halide::Buffer in(w, h); + in.fill(42); + + std::vector> outs{ + ion::Buffer{w, h}, + ion::Buffer{w, h}, + ion::Buffer{w, h}, + ion::Buffer{w, h}}; + + for (auto &out : outs) { + out.fill(0); + } + + + Builder b; + b.set_target(Halide::get_host_target()); + + int32_t offsets[4] = {1, 2, 3, 4}; + + Port offset_p = Port("input_offsets",Halide::Int(32)); ; + + auto n = b.add("test_scalar_array")(in, offset_p).set_params(Param("input_offsets.size", 4)); + offset_p.bind(offsets,4); + n["output"].bind(outs); + b.run(); + + std::cout< { Halide::Var x, y; }; + +class scalarArray : public BuildingBlock { +public: + Input input{"input", Int(32), 2}; + Input input_offsets{"input_offsets"}; + Output output{"output", Int(32), 2}; + + void generate() { + output.resize(input_offsets.size()); + for (int i = 0; i < input_offsets.size(); i++){ + output[i](x, y) = input(x, y) + input_offsets[i]; + } + } + +private: + Halide::Var x, y; +}; + } // namespace test } // namespace bb } // namespace ion @@ -332,5 +350,6 @@ ION_REGISTER_BUILDING_BLOCK(ion::bb::test::ExternIncI32x2, test_extern_inc_i32x2 ION_REGISTER_BUILDING_BLOCK(ion::bb::test::AddI32x2, test_add_i32x2); ION_REGISTER_BUILDING_BLOCK(ion::bb::test::SubI32x2, test_sub_i32x2); ION_REGISTER_BUILDING_BLOCK(ion::bb::test::IncByOffset, test_inc_by_offset); +ION_REGISTER_BUILDING_BLOCK(ion::bb::test::scalarArray, test_scalar_array); #endif From 10f664a923fde6b5d3447912d6324b4737cddd8d Mon Sep 17 00:00:00 2001 From: Xinyu Li Date: Tue, 22 Oct 2024 16:00:17 -0700 Subject: [PATCH 2/8] use std_array --- include/ion/node.h | 9 ++++++ include/ion/port.h | 66 ++++++++++++++++++++++++++------------ test/scalar_array_input.cc | 5 ++- 3 files changed, 57 insertions(+), 23 deletions(-) diff --git a/include/ion/node.h b/include/ion/node.h index e2e79599..c1083f24 100644 --- a/include/ion/node.h +++ b/include/ion/node.h @@ -169,6 +169,15 @@ class Node { return Port(arg, impl_->graph_id); } + + template + Port make_iport(std::array * arg) const { + if (to_string(impl_->graph_id).empty()) + return Port(arg); + else + return Port(arg, impl_->graph_id); + } + std::shared_ptr impl_; }; diff --git a/include/ion/port.h b/include/ion/port.h index e717e345..98ce8702 100644 --- a/include/ion/port.h +++ b/include/ion/port.h @@ -103,9 +103,9 @@ class Port { */ template::value>::type * = nullptr> - Port(T *vptr, int size = 1) + Port(T *vptr) : impl_(new Impl(NodeID(""), Halide::Internal::unique_name("_ion_port_"), Halide::type_of(), 0, GraphID(""))), index_(-1) { - this->bind(vptr, size); + this->bind(vptr); } /** @@ -113,9 +113,9 @@ class Port { */ template::value>::type * = nullptr> - Port(T *vptr, const GraphID &gid, int size = 1) + Port(T *vptr, const GraphID &gid) : impl_(new Impl(NodeID(""), Halide::Internal::unique_name("_ion_port_"), Halide::type_of(), 0, gid)), index_(-1) { - this->bind(vptr, size); + this->bind(vptr); } /** @@ -154,6 +154,21 @@ class Port { this->bind(bufs); } + template + Port(std::array * arr) + : impl_(new Impl(NodeID(""), Halide::Internal::unique_name("_ion_port_"), Halide::type_of(), 0, GraphID(""))), index_(-1) { + this->bind(arr); + } + + /** + * Construct new port from scalar array and bind graph id to port + */ + template + Port(std::array * arr, const GraphID &gid) + : impl_(new Impl(NodeID(""), Halide::Internal::unique_name("_ion_port_"), Halide::type_of(), 0, gid)), index_(-1) { + this->bind(arr); + } + // Getter const PortID id() const { return impl_->id; @@ -222,27 +237,38 @@ class Port { } template - void bind(T *v, int size = 1) { - if (size == 1) { - auto i = index_ == -1 ? 0 : index_; - bind(Halide::type_of(), v, i); - }else{ - for(int i = 0;i < size; i++){ - bind(Halide::type_of(), (void *)v, i); - v = v + 1; - } - } + void bind(T *v) { + bind(Halide::type_of(), v); } - void bind(Halide::Type target_type, void *v, int idx) { + void bind(Halide::Type target_type, void *v) { + auto i = index_ == -1 ? 0 : index_; + if (has_pred()) { - impl_->params[idx] = Halide::Parameter{target_type, false, 0, argument_name(pred_id(), id(), pred_name(), idx, graph_id())}; + impl_->params[i] = Halide::Parameter{target_type, false, 0, argument_name(pred_id(), id(), pred_name(), i, graph_id())}; } else { - impl_->params[idx] = Halide::Parameter{type(), false, dimensions(), argument_name(pred_id(), id(), pred_name(), idx, graph_id())}; + impl_->params[i] = Halide::Parameter{type(), false, dimensions(), argument_name(pred_id(), id(), pred_name(), i, graph_id())}; } - impl_->instances[idx] = v; - impl_->bound_address[idx] = std::make_tuple(v, false); - } + + impl_->instances[i] = v; + impl_->bound_address[i] = std::make_tuple(v, false); + } + + + template + void bind(std::array * arr) { + for (int i = 0; i < N; i++) { + if (has_pred()) { + impl_->params[i] = Halide::Parameter{Halide::type_of(), false, 0, + argument_name(pred_id(), id(), pred_name(), i, graph_id())}; + } else { + impl_->params[i] = Halide::Parameter{type(), false, dimensions(), + argument_name(pred_id(), id(), pred_name(), i, graph_id())}; + } + impl_->instances[i] = &(arr->at(i)); + impl_->bound_address[i] = std::make_tuple(&(arr->at(i)), false); + } + } template void bind(const Halide::Buffer &buf) { diff --git a/test/scalar_array_input.cc b/test/scalar_array_input.cc index b7423669..4705b9f5 100644 --- a/test/scalar_array_input.cc +++ b/test/scalar_array_input.cc @@ -29,12 +29,11 @@ int main() { Builder b; b.set_target(Halide::get_host_target()); - int32_t offsets[4] = {1, 2, 3, 4}; - + std::array offsets = {1, 2, 3, 4}; Port offset_p = Port("input_offsets",Halide::Int(32)); ; auto n = b.add("test_scalar_array")(in, offset_p).set_params(Param("input_offsets.size", 4)); - offset_p.bind(offsets,4); + offset_p.bind(&offsets); n["output"].bind(outs); b.run(); From 4579ee8240b35869eabd8503c667834b0a63b06b Mon Sep 17 00:00:00 2001 From: Xinyu Li Date: Tue, 22 Oct 2024 16:05:14 -0700 Subject: [PATCH 3/8] update --- include/ion/port.h | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/include/ion/port.h b/include/ion/port.h index 98ce8702..70ea636b 100644 --- a/include/ion/port.h +++ b/include/ion/port.h @@ -118,6 +118,26 @@ class Port { this->bind(vptr); } + + /** + * Construct new port from scalar array + */ + template + Port(std::array * arr) + : impl_(new Impl(NodeID(""), Halide::Internal::unique_name("_ion_port_"), Halide::type_of(), 0, GraphID(""))), index_(-1) { + this->bind(arr); + } + + /** + * Construct new port from scalar array and bind graph id to port + */ + template + Port(std::array * arr, const GraphID &gid) + : impl_(new Impl(NodeID(""), Halide::Internal::unique_name("_ion_port_"), Halide::type_of(), 0, gid)), index_(-1) { + this->bind(arr); + } + + /** * Construct new port from buffer */ @@ -154,21 +174,6 @@ class Port { this->bind(bufs); } - template - Port(std::array * arr) - : impl_(new Impl(NodeID(""), Halide::Internal::unique_name("_ion_port_"), Halide::type_of(), 0, GraphID(""))), index_(-1) { - this->bind(arr); - } - - /** - * Construct new port from scalar array and bind graph id to port - */ - template - Port(std::array * arr, const GraphID &gid) - : impl_(new Impl(NodeID(""), Halide::Internal::unique_name("_ion_port_"), Halide::type_of(), 0, gid)), index_(-1) { - this->bind(arr); - } - // Getter const PortID id() const { return impl_->id; @@ -259,11 +264,9 @@ class Port { void bind(std::array * arr) { for (int i = 0; i < N; i++) { if (has_pred()) { - impl_->params[i] = Halide::Parameter{Halide::type_of(), false, 0, - argument_name(pred_id(), id(), pred_name(), i, graph_id())}; + impl_->params[i] = Halide::Parameter{Halide::type_of(), false, 0, argument_name(pred_id(), id(), pred_name(), i, graph_id())}; } else { - impl_->params[i] = Halide::Parameter{type(), false, dimensions(), - argument_name(pred_id(), id(), pred_name(), i, graph_id())}; + impl_->params[i] = Halide::Parameter{type(), false, dimensions(), argument_name(pred_id(), id(), pred_name(), i, graph_id())}; } impl_->instances[i] = &(arr->at(i)); impl_->bound_address[i] = std::make_tuple(&(arr->at(i)), false); From 7a1ddfbbf3fa1c21cf22d56bfab6c56b81d37fab Mon Sep 17 00:00:00 2001 From: Xinyu Li Date: Tue, 22 Oct 2024 16:07:18 -0700 Subject: [PATCH 4/8] update test --- test/scalar_array_input.cc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/test/scalar_array_input.cc b/test/scalar_array_input.cc index 4705b9f5..8d808dbd 100644 --- a/test/scalar_array_input.cc +++ b/test/scalar_array_input.cc @@ -30,10 +30,7 @@ int main() { b.set_target(Halide::get_host_target()); std::array offsets = {1, 2, 3, 4}; - Port offset_p = Port("input_offsets",Halide::Int(32)); ; - - auto n = b.add("test_scalar_array")(in, offset_p).set_params(Param("input_offsets.size", 4)); - offset_p.bind(&offsets); + auto n = b.add("test_scalar_array")(in, &offsets).set_params(Param("input_offsets.size", 4)); n["output"].bind(outs); b.run(); From 31f566c056e8523a483a153a1881ce5ca87c53e3 Mon Sep 17 00:00:00 2001 From: Xinyu Li Date: Thu, 24 Oct 2024 13:40:27 -0700 Subject: [PATCH 5/8] capi --- include/ion/c_ion.h | 30 +++++------ include/ion/port.h | 17 ++++++ src/c_ion.cc | 33 ++++++++++++ test/c_api.cc | 127 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 191 insertions(+), 16 deletions(-) diff --git a/include/ion/c_ion.h b/include/ion/c_ion.h index 7be18453..148261b1 100644 --- a/include/ion/c_ion.h +++ b/include/ion/c_ion.h @@ -47,6 +47,20 @@ int ion_port_bind_u32(ion_port_t, uint32_t *); int ion_port_bind_u64(ion_port_t, uint64_t *); int ion_port_bind_f32(ion_port_t, float *); int ion_port_bind_f64(ion_port_t, double *); + +int ion_port_bind_i8_array(ion_port_t, int8_t *, int); +int ion_port_bind_i16_array(ion_port_t, int16_t *, int); +int ion_port_bind_i32_array(ion_port_t, int32_t *, int); +int ion_port_bind_i64_array(ion_port_t, int64_t *, int); +int ion_port_bind_u1_array(ion_port_t, bool *, int); +int ion_port_bind_u8_array(ion_port_t, uint8_t *, int); +int ion_port_bind_u16_array(ion_port_t, uint16_t *, int); +int ion_port_bind_u32_array(ion_port_t, uint32_t *, int); +int ion_port_bind_u64_array(ion_port_t, uint64_t *, int); +int ion_port_bind_f32_array(ion_port_t, float *, int); +int ion_port_bind_f64_array(ion_port_t, double *, int); + + int ion_port_bind_buffer(ion_port_t, ion_buffer_t); int ion_port_bind_buffer_array(ion_port_t, ion_buffer_t *, int); @@ -84,22 +98,6 @@ int ion_graph_destroy(ion_graph_t); int ion_graph_run(ion_graph_t); int ion_graph_create_with_multiple(ion_graph_t *ptr, ion_graph_t *objs, int size); -[[deprecated("ion_port_bind* can be used instead of ion_port_map.")]] int ion_port_map_create(ion_port_map_t *); -[[deprecated("ion_port_bind* can be used instead of ion_port_map.")]] int ion_port_map_destroy(ion_port_map_t); -[[deprecated("ion_port_bind* can be used instead of ion_port_map.")]] int ion_port_map_set_i8(ion_port_map_t, ion_port_t, int8_t); -[[deprecated("ion_port_bind* can be used instead of ion_port_map.")]] int ion_port_map_set_i16(ion_port_map_t, ion_port_t, int16_t); -[[deprecated("ion_port_bind* can be used instead of ion_port_map.")]] int ion_port_map_set_i32(ion_port_map_t, ion_port_t, int32_t); -[[deprecated("ion_port_bind* can be used instead of ion_port_map.")]] int ion_port_map_set_i64(ion_port_map_t, ion_port_t, int64_t); -[[deprecated("ion_port_bind* can be used instead of ion_port_map.")]] int ion_port_map_set_u1(ion_port_map_t, ion_port_t, bool); -[[deprecated("ion_port_bind* can be used instead of ion_port_map.")]] int ion_port_map_set_u8(ion_port_map_t, ion_port_t, uint8_t); -[[deprecated("ion_port_bind* can be used instead of ion_port_map.")]] int ion_port_map_set_u16(ion_port_map_t, ion_port_t, uint16_t); -[[deprecated("ion_port_bind* can be used instead of ion_port_map.")]] int ion_port_map_set_u32(ion_port_map_t, ion_port_t, uint32_t); -[[deprecated("ion_port_bind* can be used instead of ion_port_map.")]] int ion_port_map_set_u64(ion_port_map_t, ion_port_t, uint64_t); -[[deprecated("ion_port_bind* can be used instead of ion_port_map.")]] int ion_port_map_set_f32(ion_port_map_t, ion_port_t, float); -[[deprecated("ion_port_bind* can be used instead of ion_port_map.")]] int ion_port_map_set_f64(ion_port_map_t, ion_port_t, double); -[[deprecated("ion_port_bind* can be used instead of ion_port_map.")]] int ion_port_map_set_buffer(ion_port_map_t, ion_port_t, ion_buffer_t); -[[deprecated("ion_port_bind* can be used instead of ion_port_map.")]] int ion_port_map_set_buffer_array(ion_port_map_t, ion_port_t, ion_buffer_t *, int); - #if defined __cplusplus } #endif diff --git a/include/ion/port.h b/include/ion/port.h index 70ea636b..d91edf3f 100644 --- a/include/ion/port.h +++ b/include/ion/port.h @@ -273,6 +273,23 @@ class Port { } } + + // For C API and Python binding compatibility + template + void bind(T *v, int size) { + for (int i = 0; i < size; i++) { + if (has_pred()) { + impl_->params[i] = Halide::Parameter{Halide::type_of(), false, 0, argument_name(pred_id(), id(), pred_name(), i, graph_id())}; + } else { + impl_->params[i] = Halide::Parameter{type(), false, dimensions(), argument_name(pred_id(), id(), pred_name(), i, graph_id())}; + } + impl_->instances[i] = v; + impl_->bound_address[i] = std::make_tuple(v, false); + v +=1; + } + } + + template void bind(const Halide::Buffer &buf) { auto i = index_ == -1 ? 0 : index_; diff --git a/src/c_ion.cc b/src/c_ion.cc index fcf9abe7..529b6c83 100644 --- a/src/c_ion.cc +++ b/src/c_ion.cc @@ -107,6 +107,39 @@ ION_PORT_BIND_IMPL(double *, f64) #undef ION_PORT_BIND_IMPL +#define ION_PORT_BIND_ARRAY_IMPL(T, POSTFIX) \ + int ion_port_bind_##POSTFIX##_array(ion_port_t obj, T v, int size) { \ + try { \ + reinterpret_cast(obj)->bind(v, size); \ + } catch (const Halide::Error &e) { \ + log::error(e.what()); \ + return 1; \ + } catch (const std::exception &e) { \ + log::error(e.what()); \ + return 1; \ + } catch (...) { \ + log::error("Unknown exception was happened"); \ + return 1; \ + } \ + \ + return 0; \ + } + +ION_PORT_BIND_ARRAY_IMPL(int8_t *, i8) +ION_PORT_BIND_ARRAY_IMPL(int16_t *, i16) +ION_PORT_BIND_ARRAY_IMPL(int32_t *, i32) +ION_PORT_BIND_ARRAY_IMPL(int64_t *, i64) +ION_PORT_BIND_ARRAY_IMPL(bool *, u1) +ION_PORT_BIND_ARRAY_IMPL(uint8_t *, u8) +ION_PORT_BIND_ARRAY_IMPL(uint16_t *, u16) +ION_PORT_BIND_ARRAY_IMPL(uint32_t *, u32) +ION_PORT_BIND_ARRAY_IMPL(uint64_t *, u64) +ION_PORT_BIND_ARRAY_IMPL(float *, f32) +ION_PORT_BIND_ARRAY_IMPL(double *, f64) + +#undef ION_PORT_BIND_ARRAY_IMPL + + int ion_port_bind_buffer(ion_port_t obj, ion_buffer_t b) { try { // NOTE: Halide::Buffer class layout is safe to call Halide::Buffer::type() diff --git a/test/c_api.cc b/test/c_api.cc index 97e272d0..780bca61 100644 --- a/test/c_api.cc +++ b/test/c_api.cc @@ -307,6 +307,133 @@ int main() { if (ret != 0) return ret; } + + { + ion_type_t t = {.code = ion_type_int, .bits = 32, .lanes = 1}; + + ion_port_t ip; + ret = ion_port_create(&ip, "input", t, 2); + if (ret != 0) + return ret; + + + ion_port_t offsets_p; + ret = ion_port_create(&offsets_p, "input_offsets", t, 0); + if (ret != 0) + return ret; + + ion_param_t len; + ret = ion_param_create(&len, "input_offsets.size", "4"); + if (ret != 0) + return ret; + + ion_builder_t b; + ret = ion_builder_create(&b); + if (ret != 0) + return ret; + + ret = ion_builder_set_target(b, "host"); + if (ret != 0) + return ret; + + ret = ion_builder_with_bb_module(b, "ion-bb-test"); + if (ret != 0) + return ret; + + + ion_node_t n; + ret = ion_builder_add_node(b, "test_scalar_array", &n); + if (ret != 0) + return ret; + + ret = ion_node_set_params(n, &len, 1); + if (ret != 0) + return ret; + + ion_port_t *ports = (ion_port_t *) malloc(2 * sizeof(ion_port_t)); + ports[0] = ip; + ports[1] = offsets_p; + ret = ion_node_set_iports(n, ports, 2); + if (ret != 0) + return ret; + + int sizes[] = {4, 4}; + ion_buffer_t ibuf; + ret = ion_buffer_create(&ibuf, t, sizes, 2); + if (ret != 0) + return ret; + + int in[4 * 4]; + for (int i = 0; i < 4 * 4; ++i) { + in[i] = 42; + } + ret = ion_buffer_write(ibuf, in, 4 * 4 * sizeof(int)); + if (ret != 0) + return ret; + + ion_port_t op; + ret = ion_node_get_port(n, "output", &op); + if (ret != 0) + return ret; + + ion_buffer_t *obufs = (ion_buffer_t *) malloc(4 * sizeof(ion_buffer_t)); + for (int i = 0; i < 4; ++i) { + ret = ion_buffer_create(obufs + i, t, sizes, 2); + if (ret != 0) + return ret; + } + + int in_offsets[4]; + for (int i = 0; i < 4; ++i) { + in_offsets[i] = i; + } + + ret = ion_port_bind_i32_array(offsets_p, (int *) (&in_offsets), 4); + if (ret != 0) + return ret; + + ret = ion_port_bind_buffer(ip, ibuf); + if (ret != 0) + return ret; + + ret = ion_port_bind_buffer_array(op, obufs, 4); + if (ret != 0) + return ret; + + ret = ion_builder_run(b); + if (ret != 0) + return ret; + + for (int i = 0;i < 4 ;i++){ + int out[4 * 4] = {0}; + ret = ion_buffer_read(*(obufs + i), out, 4 * 4 * sizeof(int)); + if (ret != 0) + return ret; + if (out[0] != 42 + i) { + printf("%d\n", out[0]); + return -1; + } + } + + ret = ion_port_destroy(ip); + if (ret != 0) + return ret; + + ret = ion_port_destroy(offsets_p); + if (ret != 0) + return ret; + + ret = ion_port_destroy(op); + if (ret != 0) + return ret; + + ret = ion_builder_destroy(b); + if (ret != 0) + return ret; + + free(ports); + } + { ion_type_t t = {.code = ion_type_int, .bits = 32, .lanes = 1}; From ca0d995f8c48e4e6b5e591f38013961eafdb479d Mon Sep 17 00:00:00 2001 From: Xinyu Li Date: Thu, 24 Oct 2024 15:00:13 -0700 Subject: [PATCH 6/8] add python --- python/ionpy/Port.py | 131 +++++++++++++++++++++++++++++++---------- python/ionpy/native.py | 58 +++++++++++++++++- 2 files changed, 157 insertions(+), 32 deletions(-) diff --git a/python/ionpy/Port.py b/python/ionpy/Port.py index 0e5d5082..f9fccb50 100644 --- a/python/ionpy/Port.py +++ b/python/ionpy/Port.py @@ -23,7 +23,21 @@ ion_port_bind_f32, ion_port_bind_f64, ion_port_bind_buffer, - ion_port_bind_buffer_array + ion_port_bind_buffer_array, + + ion_port_bind_i8_array, + ion_port_bind_i16_array, + ion_port_bind_i32_array, + ion_port_bind_i64_array, + + ion_port_bind_u1_array, + ion_port_bind_u8_array, + ion_port_bind_u16_array, + ion_port_bind_u32_array, + ion_port_bind_u64_array, + + ion_port_bind_f32_array, + ion_port_bind_f64_array, ) from .Type import Type @@ -62,38 +76,93 @@ def __del__(self): if self.obj: # check not nullptr ion_port_destroy(self.obj) - def bind(self, v: Union[int, float, Buffer, List[Buffer]]): + def bind(self, v: Union[int, float, Buffer, List[Union[Buffer, int, float]]]): if self.dim == 0: - if self.bind_value is None: - self.bind_value = np.ctypeslib.as_ctypes_type(self.type.to_dtype())(v) - else: - self.bind_value.value = v # scalar - if self.type.code_ == TypeCode.Int: - if self.type.bits_ == 8 and ion_port_bind_i8(self.obj, ctypes.byref(self.bind_value)) != 0: - raise Exception('Invalid operation') - elif self.type.bits_ == 16 and ion_port_bind_i16(self.obj, ctypes.byref(self.bind_value)) != 0: - raise Exception('Invalid operation') - elif self.type.bits_ == 32 and ion_port_bind_i32(self.obj, ctypes.byref(self.bind_value)) != 0: - raise Exception('Invalid operation') - elif self.type.bits_ == 64 and ion_port_bind_i64(self.obj, ctypes.byref(self.bind_value)) != 0: - raise Exception('Invalid operation') - elif self.type.code_ == TypeCode.Uint: - if self.type.bits_ == 1 and ion_port_bind_u1(self.obj, ctypes.byref(self.bind_value)) != 0: - raise Exception('Invalid operation') - if self.type.bits_ == 8 and ion_port_bind_u8(self.obj, ctypes.byref(self.bind_value)) != 0: - raise Exception('Invalid operation') - if self.type.bits_ == 16 and ion_port_bind_u16(self.obj, ctypes.byref(self.bind_value)) != 0: - raise Exception('Invalid operation') - if self.type.bits_ == 32 and ion_port_bind_u32(self.obj, ctypes.byref(self.bind_value)) != 0: - raise Exception('Invalid operation') - if self.type.bits_ == 64 and ion_port_bind_u64(self.obj, ctypes.byref(self.bind_value)) != 0: - raise Exception('Invalid operation') - elif self.type.code_ == TypeCode.Float: - if self.type.bits_ == 32 and ion_port_bind_f32(self.obj, ctypes.byref(self.bind_value)) != 0: - raise Exception('Invalid operation') - if self.type.bits_ == 64 and ion_port_bind_f64(self.obj, ctypes.byref(self.bind_value)) != 0: - raise Exception('Invalid operation') + if type(v) is not list: + if self.bind_value is None: + self.bind_value = np.ctypeslib.as_ctypes_type(self.type.to_dtype())(v) + else: + self.bind_value.value = v + + if self.type.code_ == TypeCode.Int: + if self.type.bits_ == 8 and ion_port_bind_i8_array(self.obj, ctypes.byref(self.bind_value)) != 0: + raise Exception('Invalid operation') + elif self.type.bits_ == 16 and ion_port_bind_i16(self.obj, ctypes.byref(self.bind_value)) != 0: + raise Exception('Invalid operation') + elif self.type.bits_ == 32 and ion_port_bind_i32(self.obj, ctypes.byref(self.bind_value)) != 0: + raise Exception('Invalid operation') + elif self.type.bits_ == 64 and ion_port_bind_i64(self.obj, ctypes.byref(self.bind_value)) != 0: + raise Exception('Invalid operation') + elif self.type.code_ == TypeCode.Uint: + if self.type.bits_ == 1 and ion_port_bind_u1(self.obj, ctypes.byref(self.bind_value)) != 0: + raise Exception('Invalid operation') + if self.type.bits_ == 8 and ion_port_bind_u8(self.obj, ctypes.byref(self.bind_value)) != 0: + raise Exception('Invalid operation') + if self.type.bits_ == 16 and ion_port_bind_u16(self.obj, ctypes.byref(self.bind_value)) != 0: + raise Exception('Invalid operation') + if self.type.bits_ == 32 and ion_port_bind_u32(self.obj, ctypes.byref(self.bind_value)) != 0: + raise Exception('Invalid operation') + if self.type.bits_ == 64 and ion_port_bind_u64(self.obj, ctypes.byref(self.bind_value)) != 0: + raise Exception('Invalid operation') + elif self.type.code_ == TypeCode.Float: + if self.type.bits_ == 32 and ion_port_bind_f32(self.obj, ctypes.byref(self.bind_value)) != 0: + raise Exception('Invalid operation') + if self.type.bits_ == 64 and ion_port_bind_f64(self.obj, ctypes.byref(self.bind_value)) != 0: + raise Exception('Invalid operation') + else: + # scalar array + c_arr = None + if self.type.code_ == TypeCode.Int: + if self.type.bits_ == 8: + c_arr = (ctypes.c_int8 * len(v))(*v) + if ion_port_bind_i8_array(self.obj, c_arr, len(v)) != 0: + raise Exception('Invalid operation') + elif self.type.bits_ == 16: + c_arr = (ctypes.c_int16 * len(v))(*v) + if ion_port_bind_i16_array(self.obj, c_arr, len(v)) != 0: + raise Exception('Invalid operation') + elif self.type.bits_ == 32 : + c_arr = (ctypes.c_int32 * len(v))(*v) + if ion_port_bind_i32_array(self.obj, c_arr, len(v)) != 0: + raise Exception('Invalid operation') + elif self.type.bits_ == 64: + c_arr = (ctypes.c_int64 * len(v))(*v) + if ion_port_bind_i64_array(self.obj, c_arr, len(v)) != 0: + raise Exception('Invalid operation') + elif self.type.code_ == TypeCode.Uint: + if self.type.bits_ == 1: + c_arr = (ctypes.c_bool * len(v))(*v) + if ion_port_bind_u1_array(self.obj, c_arr, len(v)) != 0: + raise Exception('Invalid operation') + if self.type.bits_ == 8 : + c_arr = (ctypes.c_uint8 * len(v))(*v) + if ion_port_bind_u8_array(self.obj, c_arr, len(v)) != 0: + raise Exception('Invalid operation') + if self.type.bits_ == 16: + c_arr = (ctypes.c_uint16 * len(v))(*v) + if ion_port_bind_u16_array(self.obj, c_arr, len(v)) != 0: + raise Exception('Invalid operation') + if self.type.bits_ == 32: + c_arr = (ctypes.c_uint32* len(v))(*v) + if ion_port_bind_u32_array(self.obj, c_arr, len(v)) != 0: + raise Exception('Invalid operation') + if self.type.bits_ == 64: + c_arr = (ctypes.c_uint64 * len(v))(*v) + if ion_port_bind_u64_array(self.obj, c_arr, len(v)) != 0: + raise Exception('Invalid operation') + elif self.type.code_ == TypeCode.Float: + if self.type.bits_ == 32: + c_arr = (ctypes.c_float * len(v))(*v) + if ion_port_bind_f32(self.obj, c_arr, len(v)) != 0: + raise Exception('Invalid operation') + if self.type.bits_ == 64: + c_arr = (ctypes.c_double * len(v))(*v) + if ion_port_bind_f64(self.obj, c_arr, len(v)) != 0: + raise Exception('Invalid operation') + + self.bind_value = c_arr + # vector else: diff --git a/python/ionpy/native.py b/python/ionpy/native.py index 944a9192..d75f8f41 100644 --- a/python/ionpy/native.py +++ b/python/ionpy/native.py @@ -105,11 +105,67 @@ class c_builder_compile_option_t(ctypes.Structure): ion_port_bind_f32.restype = ctypes.c_int ion_port_bind_f32.argtypes = [ c_ion_port_t, ctypes.POINTER(ctypes.c_float) ] -# int ion_port_bind_f64(ion_port_t, double*; +# int ion_port_bind_f64(ion_port_t, double*;); ion_port_bind_f64 = ion_core.ion_port_bind_f64 ion_port_bind_f64.restype = ctypes.c_int ion_port_bind_f64.argtypes = [ c_ion_port_t, ctypes.POINTER(ctypes.c_double) ] +# int ion_port_bind_i8_array(ion_port_t, int8_t*, int); +ion_port_bind_i8_array = ion_core.ion_port_bind_i8_array +ion_port_bind_i8_array.restype = ctypes.c_int +ion_port_bind_i8_array.argtypes = [c_ion_port_t, ctypes.POINTER(ctypes.c_int8), ctypes.c_int ] + +# int ion_port_bind_i16_array(ion_port_t, int16_t*, int); +ion_port_bind_i16_array = ion_core.ion_port_bind_i16_array +ion_port_bind_i16_array.restype = ctypes.c_int +ion_port_bind_i16_array.argtypes = [c_ion_port_t, ctypes.POINTER(ctypes.c_int16), ctypes.c_int ] + +# int ion_port_bind_i32_array(ion_port_t, int32_t*, int); +ion_port_bind_i32_array = ion_core.ion_port_bind_i32_array +ion_port_bind_i32_array.restype = ctypes.c_int +ion_port_bind_i32_array.argtypes = [c_ion_port_t, ctypes.POINTER(ctypes.c_int32), ctypes.c_int ] + +# int ion_port_bind_i64_array(ion_port_t, int64_t*, int); +ion_port_bind_i64_array = ion_core.ion_port_bind_i64_array +ion_port_bind_i64_array.restype = ctypes.c_int +ion_port_bind_i64_array.argtypes = [ c_ion_port_t, ctypes.POINTER(ctypes.c_int64), ctypes.c_int ] + +# int ion_port_map_set_u1_array(ion_port_t, bool*, int); +ion_port_bind_u1_array = ion_core.ion_port_bind_u1_array +ion_port_bind_u1_array.restype = ctypes.c_int +ion_port_bind_u1_array.argtypes = [ c_ion_port_t, ctypes.POINTER(ctypes.c_bool), ctypes.c_int ] + +# int ion_port_bind_u8_array(ion_port_t, uint8_t*, int); +ion_port_bind_u8_array = ion_core.ion_port_bind_u8_array +ion_port_bind_u8_array.restype = ctypes.c_int +ion_port_bind_u8_array.argtypes = [ c_ion_port_t, ctypes.POINTER(ctypes.c_uint8), ctypes.c_int ] + +# int ion_port_bind_u16_array(ion_port_t, uint16_t*, int); +ion_port_bind_u16_array = ion_core.ion_port_bind_u16_array +ion_port_bind_u16_array.restype = ctypes.c_int +ion_port_bind_u16_array.argtypes = [ c_ion_port_t, ctypes.POINTER(ctypes.c_uint16), ctypes.c_int ] + +# int ion_port_bind_u32_array(ion_port_t, uint32_t*, int); +ion_port_bind_u32_array = ion_core.ion_port_bind_u32_array +ion_port_bind_u32_array.restype = ctypes.c_int +ion_port_bind_u32_array.argtypes = [ c_ion_port_t, ctypes.POINTER(ctypes.c_uint32), ctypes.c_int ] + +# int ion_port_bind_u64_array(ion_port_t, uint64_t*, int); +ion_port_bind_u64_array = ion_core.ion_port_bind_u64_array +ion_port_bind_u64_array.restype = ctypes.c_int +ion_port_bind_u64_array.argtypes = [ c_ion_port_t, ctypes.POINTER(ctypes.c_uint64), ctypes.c_int ] + +# int ion_port_bind_f32_array(ion_port_t, float*, int); +ion_port_bind_f32_array = ion_core.ion_port_bind_f32_array +ion_port_bind_f32_array.restype = ctypes.c_int +ion_port_bind_f32_array.argtypes = [ c_ion_port_t, ctypes.POINTER(ctypes.c_float), ctypes.c_int ] + +# int ion_port_bind_f64_array(ion_port_t, double*, int); +ion_port_bind_f64_array = ion_core.ion_port_bind_f64_array +ion_port_bind_f64_array.restype = ctypes.c_int +ion_port_bind_f64_array.argtypes = [ c_ion_port_t, ctypes.POINTER(ctypes.c_double), ctypes.c_int ] + + # int ion_port_bind_buffer(ion_port_t, ion_buffer_t); ion_port_bind_buffer = ion_core.ion_port_bind_buffer ion_port_bind_buffer.restype = ctypes.c_int From f4796d08d7d8ff06cbcd1710f5eabc77dfc56bbc Mon Sep 17 00:00:00 2001 From: Xinyu Li Date: Thu, 24 Oct 2024 15:22:11 -0700 Subject: [PATCH 7/8] fix --- python/ionpy/Port.py | 74 ++++++++++++++++---------------------------- 1 file changed, 26 insertions(+), 48 deletions(-) diff --git a/python/ionpy/Port.py b/python/ionpy/Port.py index f9fccb50..f5dda7b4 100644 --- a/python/ionpy/Port.py +++ b/python/ionpy/Port.py @@ -86,7 +86,7 @@ def bind(self, v: Union[int, float, Buffer, List[Union[Buffer, int, float]]]): self.bind_value.value = v if self.type.code_ == TypeCode.Int: - if self.type.bits_ == 8 and ion_port_bind_i8_array(self.obj, ctypes.byref(self.bind_value)) != 0: + if self.type.bits_ == 8 and ion_port_bind_i8(self.obj, ctypes.byref(self.bind_value)) != 0: raise Exception('Invalid operation') elif self.type.bits_ == 16 and ion_port_bind_i16(self.obj, ctypes.byref(self.bind_value)) != 0: raise Exception('Invalid operation') @@ -112,56 +112,34 @@ def bind(self, v: Union[int, float, Buffer, List[Union[Buffer, int, float]]]): raise Exception('Invalid operation') else: # scalar array - c_arr = None + ctype = np.ctypeslib.as_ctypes_type(self.type.to_dtype()) + c_arr = (ctype* len(v))(*v) + self.bind_value = c_arr if self.type.code_ == TypeCode.Int: - if self.type.bits_ == 8: - c_arr = (ctypes.c_int8 * len(v))(*v) - if ion_port_bind_i8_array(self.obj, c_arr, len(v)) != 0: - raise Exception('Invalid operation') - elif self.type.bits_ == 16: - c_arr = (ctypes.c_int16 * len(v))(*v) - if ion_port_bind_i16_array(self.obj, c_arr, len(v)) != 0: - raise Exception('Invalid operation') - elif self.type.bits_ == 32 : - c_arr = (ctypes.c_int32 * len(v))(*v) - if ion_port_bind_i32_array(self.obj, c_arr, len(v)) != 0: - raise Exception('Invalid operation') - elif self.type.bits_ == 64: - c_arr = (ctypes.c_int64 * len(v))(*v) - if ion_port_bind_i64_array(self.obj, c_arr, len(v)) != 0: - raise Exception('Invalid operation') + if self.type.bits_ == 8 and ion_port_bind_i8_array(self.obj, ctypes.byref(self.bind_value)) != 0: + raise Exception('Invalid operation') + elif self.type.bits_ == 16 and ion_port_bind_i16_array(self.obj, ctypes.byref(self.bind_value)) != 0: + raise Exception('Invalid operation') + elif self.type.bits_ == 32 and ion_port_bind_i32_array(self.obj, ctypes.byref(self.bind_value)) != 0: + raise Exception('Invalid operation') + elif self.type.bits_ == 64 and ion_port_bind_i64_array(self.obj, ctypes.byref(self.bind_value)) != 0: + raise Exception('Invalid operation') elif self.type.code_ == TypeCode.Uint: - if self.type.bits_ == 1: - c_arr = (ctypes.c_bool * len(v))(*v) - if ion_port_bind_u1_array(self.obj, c_arr, len(v)) != 0: - raise Exception('Invalid operation') - if self.type.bits_ == 8 : - c_arr = (ctypes.c_uint8 * len(v))(*v) - if ion_port_bind_u8_array(self.obj, c_arr, len(v)) != 0: - raise Exception('Invalid operation') - if self.type.bits_ == 16: - c_arr = (ctypes.c_uint16 * len(v))(*v) - if ion_port_bind_u16_array(self.obj, c_arr, len(v)) != 0: - raise Exception('Invalid operation') - if self.type.bits_ == 32: - c_arr = (ctypes.c_uint32* len(v))(*v) - if ion_port_bind_u32_array(self.obj, c_arr, len(v)) != 0: - raise Exception('Invalid operation') - if self.type.bits_ == 64: - c_arr = (ctypes.c_uint64 * len(v))(*v) - if ion_port_bind_u64_array(self.obj, c_arr, len(v)) != 0: - raise Exception('Invalid operation') + if self.type.bits_ == 1 and ion_port_bind_u1_array(self.obj, ctypes.byref(self.bind_value)) != 0: + raise Exception('Invalid operation') + if self.type.bits_ == 8 and ion_port_bind_u8_array(self.obj, ctypes.byref(self.bind_value)) != 0: + raise Exception('Invalid operation') + if self.type.bits_ == 16 and ion_port_bind_u16_array(self.obj, ctypes.byref(self.bind_value)) != 0: + raise Exception('Invalid operation') + if self.type.bits_ == 32 and ion_port_bind_u32_array(self.obj, ctypes.byref(self.bind_value)) != 0: + raise Exception('Invalid operation') + if self.type.bits_ == 64 and ion_port_bind_u64_array(self.obj, ctypes.byref(self.bind_value)) != 0: + raise Exception('Invalid operation') elif self.type.code_ == TypeCode.Float: - if self.type.bits_ == 32: - c_arr = (ctypes.c_float * len(v))(*v) - if ion_port_bind_f32(self.obj, c_arr, len(v)) != 0: - raise Exception('Invalid operation') - if self.type.bits_ == 64: - c_arr = (ctypes.c_double * len(v))(*v) - if ion_port_bind_f64(self.obj, c_arr, len(v)) != 0: - raise Exception('Invalid operation') - - self.bind_value = c_arr + if self.type.bits_ == 32 and ion_port_bind_f32_array(self.obj, ctypes.byref(self.bind_value)) != 0: + raise Exception('Invalid operation') + if self.type.bits_ == 64 and ion_port_bind_f64_array(self.obj, ctypes.byref(self.bind_value)) != 0: + raise Exception('Invalid operation') # vector else: From d832727976892e8ccd6373984ce696183291b874 Mon Sep 17 00:00:00 2001 From: Xinyu Li Date: Thu, 24 Oct 2024 15:23:11 -0700 Subject: [PATCH 8/8] fix2 --- python/ionpy/Port.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/python/ionpy/Port.py b/python/ionpy/Port.py index f5dda7b4..0b0738df 100644 --- a/python/ionpy/Port.py +++ b/python/ionpy/Port.py @@ -116,29 +116,29 @@ def bind(self, v: Union[int, float, Buffer, List[Union[Buffer, int, float]]]): c_arr = (ctype* len(v))(*v) self.bind_value = c_arr if self.type.code_ == TypeCode.Int: - if self.type.bits_ == 8 and ion_port_bind_i8_array(self.obj, ctypes.byref(self.bind_value)) != 0: + if self.type.bits_ == 8 and ion_port_bind_i8_array(self.obj, self.bind_value, len(v)) != 0: raise Exception('Invalid operation') - elif self.type.bits_ == 16 and ion_port_bind_i16_array(self.obj, ctypes.byref(self.bind_value)) != 0: + elif self.type.bits_ == 16 and ion_port_bind_i16_array(self.obj, self.bind_value, len(v)) != 0: raise Exception('Invalid operation') - elif self.type.bits_ == 32 and ion_port_bind_i32_array(self.obj, ctypes.byref(self.bind_value)) != 0: + elif self.type.bits_ == 32 and ion_port_bind_i32_array(self.obj, self.bind_value, len(v)) != 0: raise Exception('Invalid operation') - elif self.type.bits_ == 64 and ion_port_bind_i64_array(self.obj, ctypes.byref(self.bind_value)) != 0: + elif self.type.bits_ == 64 and ion_port_bind_i64_array(self.obj, self.bind_value, len(v)) != 0: raise Exception('Invalid operation') elif self.type.code_ == TypeCode.Uint: - if self.type.bits_ == 1 and ion_port_bind_u1_array(self.obj, ctypes.byref(self.bind_value)) != 0: + if self.type.bits_ == 1 and ion_port_bind_u1_array(self.obj, self.bind_value, len(v)) != 0: raise Exception('Invalid operation') - if self.type.bits_ == 8 and ion_port_bind_u8_array(self.obj, ctypes.byref(self.bind_value)) != 0: + if self.type.bits_ == 8 and ion_port_bind_u8_array(self.obj, self.bind_value, len(v)) != 0: raise Exception('Invalid operation') - if self.type.bits_ == 16 and ion_port_bind_u16_array(self.obj, ctypes.byref(self.bind_value)) != 0: + if self.type.bits_ == 16 and ion_port_bind_u16_array(self.obj,self.bind_value, len(v)) != 0: raise Exception('Invalid operation') - if self.type.bits_ == 32 and ion_port_bind_u32_array(self.obj, ctypes.byref(self.bind_value)) != 0: + if self.type.bits_ == 32 and ion_port_bind_u32_array(self.obj, self.bind_value, len(v)) != 0: raise Exception('Invalid operation') - if self.type.bits_ == 64 and ion_port_bind_u64_array(self.obj, ctypes.byref(self.bind_value)) != 0: + if self.type.bits_ == 64 and ion_port_bind_u64_array(self.obj, self.bind_value, len(v)) != 0: raise Exception('Invalid operation') elif self.type.code_ == TypeCode.Float: - if self.type.bits_ == 32 and ion_port_bind_f32_array(self.obj, ctypes.byref(self.bind_value)) != 0: + if self.type.bits_ == 32 and ion_port_bind_f32_array(self.obj,self.bind_value, len(v)) != 0: raise Exception('Invalid operation') - if self.type.bits_ == 64 and ion_port_bind_f64_array(self.obj, ctypes.byref(self.bind_value)) != 0: + if self.type.bits_ == 64 and ion_port_bind_f64_array(self.obj,self.bind_value, len(v)) != 0: raise Exception('Invalid operation') # vector