From 41768f0842f5fa1a9300e1d37ecf0746afe69c2d Mon Sep 17 00:00:00 2001 From: Sarah Gilmore Date: Thu, 4 May 2023 10:06:37 -0400 Subject: [PATCH 01/22] Create a NumericArray class templated on CType to use as the proxy classes for numeric arrays. Co-authored-by: Kevin Gurney --- .../arrow/matlab/array/proxy/float64_array.cc | 25 -------- .../arrow/matlab/array/proxy/float64_array.h | 60 ------------------- matlab/src/cpp/arrow/matlab/proxy/factory.cc | 6 +- .../src/matlab/+arrow/+array/Float64Array.m | 4 ++ matlab/src/matlab/+arrow/+array/UInt64Array.m | 44 ++++++++++++++ .../cmake/BuildMatlabArrowInterface.cmake | 4 +- 6 files changed, 55 insertions(+), 88 deletions(-) delete mode 100644 matlab/src/cpp/arrow/matlab/array/proxy/float64_array.cc delete mode 100644 matlab/src/cpp/arrow/matlab/array/proxy/float64_array.h create mode 100644 matlab/src/matlab/+arrow/+array/UInt64Array.m diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/float64_array.cc b/matlab/src/cpp/arrow/matlab/array/proxy/float64_array.cc deleted file mode 100644 index 4f25912b9eaea..0000000000000 --- a/matlab/src/cpp/arrow/matlab/array/proxy/float64_array.cc +++ /dev/null @@ -1,25 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -#include "float64_array.h" - -namespace arrow::matlab::array::proxy { -void Float64Array::Print(libmexclass::proxy::method::Context& context) { - // TODO: Return an MDA string representation of the Arrow array. - std::cout << array->ToString() << std::endl; -} -} // namespace arrow::matlab::array::proxy diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/float64_array.h b/matlab/src/cpp/arrow/matlab/array/proxy/float64_array.h deleted file mode 100644 index 3d6e449326e31..0000000000000 --- a/matlab/src/cpp/arrow/matlab/array/proxy/float64_array.h +++ /dev/null @@ -1,60 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -#pragma once - -#include "arrow/array.h" -#include "arrow/builder.h" - -#include "libmexclass/proxy/Proxy.h" - -namespace arrow::matlab::array::proxy { -class Float64Array : public libmexclass::proxy::Proxy { - public: - Float64Array(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - // Get the mxArray from constructor arguments - const ::matlab::data::TypedArray double_mda = constructor_arguments[0]; - - // Get raw pointer of mxArray - auto it(double_mda.cbegin()); - auto dt = it.operator->(); - - // Pass pointer to Arrow array constructor that takes a buffer - // Do not make a copy when creating arrow::Buffer - std::shared_ptr buffer( - new arrow::Buffer(reinterpret_cast(dt), - sizeof(double) * double_mda.getNumberOfElements())); - - // Construct arrow::NumericArray specialization using arrow::Buffer. - // pass in nulls information...we could compute and provide the number of nulls here too - std::shared_ptr array_wrapper( - new arrow::NumericArray(double_mda.getNumberOfElements(), buffer, - nullptr, // TODO: fill validity bitmap with data - -1)); - - array = array_wrapper; - - // Register Proxy methods. - REGISTER_METHOD(Float64Array, Print); - } - private: - void Print(libmexclass::proxy::method::Context& context); - - // "Raw" arrow::Array - std::shared_ptr array; -}; -} // namespace arrow::matlab::array::proxy diff --git a/matlab/src/cpp/arrow/matlab/proxy/factory.cc b/matlab/src/cpp/arrow/matlab/proxy/factory.cc index 9bf7ec2dc9f8a..ee1dbe230eee6 100644 --- a/matlab/src/cpp/arrow/matlab/proxy/factory.cc +++ b/matlab/src/cpp/arrow/matlab/proxy/factory.cc @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -#include "arrow/matlab/array/proxy/float64_array.h" +#include "arrow/matlab/array/proxy/numeric_array.h" #include "factory.h" @@ -26,7 +26,9 @@ namespace arrow::matlab::proxy { std::shared_ptr Factory::make_proxy(const ClassName& class_name, const FunctionArguments& constructor_arguments) { // Register MATLAB Proxy classes with corresponding C++ Proxy classes. - REGISTER_PROXY(arrow.array.proxy.Float64Array, arrow::matlab::array::proxy::Float64Array); + REGISTER_PROXY(arrow.array.proxy.Float64Array, arrow::matlab::array::proxy::NumericArray); + + REGISTER_PROXY(arrow.array.proxy.UInt64Array, arrow::matlab::array::proxy::NumericArray); // TODO: Decide what to do in the case that there isn't a Proxy match. std::cout << "Did not find a matching C++ proxy for: " + class_name << std::endl; diff --git a/matlab/src/matlab/+arrow/+array/Float64Array.m b/matlab/src/matlab/+arrow/+array/Float64Array.m index 71d56e6cc0abb..1596e411a76ff 100644 --- a/matlab/src/matlab/+arrow/+array/Float64Array.m +++ b/matlab/src/matlab/+arrow/+array/Float64Array.m @@ -33,6 +33,10 @@ function Print(obj) obj.Proxy.Print(); end + + function array = double(obj) + + end end methods (Access=protected) diff --git a/matlab/src/matlab/+arrow/+array/UInt64Array.m b/matlab/src/matlab/+arrow/+array/UInt64Array.m new file mode 100644 index 0000000000000..bb71d9390766a --- /dev/null +++ b/matlab/src/matlab/+arrow/+array/UInt64Array.m @@ -0,0 +1,44 @@ +classdef UInt64Array < matlab.mixin.CustomDisplay + % arrow.array.Float64Array + + % Licensed to the Apache Software Foundation (ASF) under one or more + % contributor license agreements. See the NOTICE file distributed with + % this work for additional information regarding copyright ownership. + % The ASF licenses this file to you under the Apache License, Version + % 2.0 (the "License"); you may not use this file except in compliance + % with the License. You may obtain a copy of the License at + % + % http://www.apache.org/licenses/LICENSE-2.0 + % + % Unless required by applicable law or agreed to in writing, software + % distributed under the License is distributed on an "AS IS" BASIS, + % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + % implied. See the License for the specific language governing + % permissions and limitations under the License. + + properties (Access=private) + Proxy + end + + properties (Access=private) + MatlabArray + end + + methods + function obj = UInt64Array(matlabArray) + obj.MatlabArray = matlabArray; + obj.Proxy = libmexclass.proxy.Proxy("Name", "arrow.array.proxy.UInt64Array", "ConstructorArguments", {obj.MatlabArray}); + end + + function Print(obj) + obj.Proxy.Print(); + end + end + + methods (Access=protected) + function displayScalarObject(obj) + obj.Print(); + end + end + +end diff --git a/matlab/tools/cmake/BuildMatlabArrowInterface.cmake b/matlab/tools/cmake/BuildMatlabArrowInterface.cmake index 59c48c02356a7..f231df8dac5e3 100644 --- a/matlab/tools/cmake/BuildMatlabArrowInterface.cmake +++ b/matlab/tools/cmake/BuildMatlabArrowInterface.cmake @@ -34,7 +34,9 @@ set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_FETCH_CONTENT_SOURCE_SUBDIR "libmexclass/cpp set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_LIBRARY_NAME arrowproxy) set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_LIBRARY_ROOT_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/src/cpp") set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/array/proxy") -set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_SOURCES "${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/array/proxy/float64_array.cc") + +# This variable will be populated with future proxy sources. Currently, we only have templated proxies defined in header files. +set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_SOURCES "") set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_FACTORY_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/proxy") set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_FACTORY_SOURCES "${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/proxy/factory.cc") set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_LIBRARY_INCLUDE_DIRS ${MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_LIBRARY_ROOT_INCLUDE_DIR} From ebb44e952e80d40dc3ddf3cf6ffc362ea47c7f9a Mon Sep 17 00:00:00 2001 From: Sarah Gilmore Date: Thu, 4 May 2023 11:04:06 -0400 Subject: [PATCH 02/22] Add missing header file numeric_array.h --- .../arrow/matlab/array/proxy/numeric_array.h | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h b/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h new file mode 100644 index 0000000000000..a628ad6117dbe --- /dev/null +++ b/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h @@ -0,0 +1,69 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +#pragma once + +#include "arrow/array.h" +#include "arrow/builder.h" +#include "arrow/type_traits.h" + +#include "libmexclass/proxy/Proxy.h" + +namespace arrow::matlab::array::proxy { + +template +class NumericArray : public libmexclass::proxy::Proxy { + public: + NumericArray(const libmexclass::proxy::FunctionArguments& constructor_arguments) { + using ArrowType = typename arrow::CTypeTraits::ArrowType; + + // Get the mxArray from constructor arguments + const ::matlab::data::TypedArray numeric_mda = constructor_arguments[0]; + + // Get raw pointer of mxArray + auto it(numeric_mda.cbegin()); + auto dt = it.operator->(); + + // Pass pointer to Arrow array constructor that takes a buffer + // Do not make a copy when creating arrow::Buffer + std::shared_ptr buffer( + new arrow::Buffer(reinterpret_cast(dt), + sizeof(CType) * numeric_mda.getNumberOfElements())); + + // Construct arrow::NumericArray specialization using arrow::Buffer. + // pass in nulls information...we could compute and provide the number of nulls here too + std::shared_ptr array_wrapper( + new arrow::NumericArray(numeric_mda.getNumberOfElements(), buffer, + nullptr, // TODO: fill validity bitmap with data + -1)); + array = array_wrapper; + + // Register Proxy methods. + REGISTER_METHOD(NumericArray, Print); + } + + private: + + void Print(libmexclass::proxy::method::Context& context) { + std::cout << array->ToString() << std::endl; + } + + // "Raw" arrow::Array + std::shared_ptr array; +}; + +} \ No newline at end of file From 9b8f7b05ab6b406cd4865ea5d533b5f509fedfc7 Mon Sep 17 00:00:00 2001 From: Sarah Gilmore Date: Thu, 4 May 2023 13:58:37 -0400 Subject: [PATCH 03/22] Scoping PR to Float64 Co-authored-by: Kevin Gurney --- matlab/src/cpp/arrow/matlab/proxy/factory.cc | 2 - matlab/src/matlab/+arrow/+array/UInt64Array.m | 44 ------------------- 2 files changed, 46 deletions(-) delete mode 100644 matlab/src/matlab/+arrow/+array/UInt64Array.m diff --git a/matlab/src/cpp/arrow/matlab/proxy/factory.cc b/matlab/src/cpp/arrow/matlab/proxy/factory.cc index ee1dbe230eee6..c767d7dc37508 100644 --- a/matlab/src/cpp/arrow/matlab/proxy/factory.cc +++ b/matlab/src/cpp/arrow/matlab/proxy/factory.cc @@ -28,8 +28,6 @@ std::shared_ptr Factory::make_proxy(const ClassName& class_name, const Fu // Register MATLAB Proxy classes with corresponding C++ Proxy classes. REGISTER_PROXY(arrow.array.proxy.Float64Array, arrow::matlab::array::proxy::NumericArray); - REGISTER_PROXY(arrow.array.proxy.UInt64Array, arrow::matlab::array::proxy::NumericArray); - // TODO: Decide what to do in the case that there isn't a Proxy match. std::cout << "Did not find a matching C++ proxy for: " + class_name << std::endl; return nullptr; diff --git a/matlab/src/matlab/+arrow/+array/UInt64Array.m b/matlab/src/matlab/+arrow/+array/UInt64Array.m deleted file mode 100644 index bb71d9390766a..0000000000000 --- a/matlab/src/matlab/+arrow/+array/UInt64Array.m +++ /dev/null @@ -1,44 +0,0 @@ -classdef UInt64Array < matlab.mixin.CustomDisplay - % arrow.array.Float64Array - - % Licensed to the Apache Software Foundation (ASF) under one or more - % contributor license agreements. See the NOTICE file distributed with - % this work for additional information regarding copyright ownership. - % The ASF licenses this file to you under the Apache License, Version - % 2.0 (the "License"); you may not use this file except in compliance - % with the License. You may obtain a copy of the License at - % - % http://www.apache.org/licenses/LICENSE-2.0 - % - % Unless required by applicable law or agreed to in writing, software - % distributed under the License is distributed on an "AS IS" BASIS, - % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - % implied. See the License for the specific language governing - % permissions and limitations under the License. - - properties (Access=private) - Proxy - end - - properties (Access=private) - MatlabArray - end - - methods - function obj = UInt64Array(matlabArray) - obj.MatlabArray = matlabArray; - obj.Proxy = libmexclass.proxy.Proxy("Name", "arrow.array.proxy.UInt64Array", "ConstructorArguments", {obj.MatlabArray}); - end - - function Print(obj) - obj.Proxy.Print(); - end - end - - methods (Access=protected) - function displayScalarObject(obj) - obj.Print(); - end - end - -end From cdc4672c1ad2d09675087de9cab1176806a95c92 Mon Sep 17 00:00:00 2001 From: Sarah Gilmore Date: Thu, 4 May 2023 14:37:59 -0400 Subject: [PATCH 04/22] Rename Print() to ToString() and return a string array from C++. Co-authored-by: Kevin Gurney --- .../cpp/arrow/matlab/array/proxy/numeric_array.h | 14 ++++++++++---- matlab/src/matlab/+arrow/+array/Float64Array.m | 11 +++-------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h b/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h index a628ad6117dbe..5ce56fb32627e 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h +++ b/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h @@ -23,6 +23,8 @@ #include "libmexclass/proxy/Proxy.h" +#include + namespace arrow::matlab::array::proxy { template @@ -53,17 +55,21 @@ class NumericArray : public libmexclass::proxy::Proxy { array = array_wrapper; // Register Proxy methods. - REGISTER_METHOD(NumericArray, Print); + REGISTER_METHOD(NumericArray, ToString); } private: - void Print(libmexclass::proxy::method::Context& context) { - std::cout << array->ToString() << std::endl; + void ToString(libmexclass::proxy::method::Context& context) { + ::matlab::data::ArrayFactory factory; + + // TODO: handle non-ascii characters + auto str_mda = factory.createScalar(array->ToString()); + context.outputs[0] = str_mda; } // "Raw" arrow::Array std::shared_ptr array; }; -} \ No newline at end of file +} diff --git a/matlab/src/matlab/+arrow/+array/Float64Array.m b/matlab/src/matlab/+arrow/+array/Float64Array.m index 1596e411a76ff..bfe02f6d2f046 100644 --- a/matlab/src/matlab/+arrow/+array/Float64Array.m +++ b/matlab/src/matlab/+arrow/+array/Float64Array.m @@ -30,19 +30,14 @@ obj.Proxy = libmexclass.proxy.Proxy("Name", "arrow.array.proxy.Float64Array", "ConstructorArguments", {obj.MatlabArray}); end - function Print(obj) - obj.Proxy.Print(); - end - - function array = double(obj) - + function str = ToString(obj) + str = obj.Proxy.ToString(); end end methods (Access=protected) function displayScalarObject(obj) - obj.Print(); + disp(obj.ToString()); end end - end From fd84dcf7b04f013395f65fb652c23c3382345691 Mon Sep 17 00:00:00 2001 From: Sarah Gilmore Date: Thu, 4 May 2023 16:15:59 -0400 Subject: [PATCH 05/22] Add ToMatlab() method to NumericArray Proxy Class. Co-authored-by: Kevin Gurney --- .../arrow/matlab/array/proxy/numeric_array.h | 16 +++++++++++ .../src/matlab/+arrow/+array/Float64Array.m | 27 +++++++++++++++---- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h b/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h index 5ce56fb32627e..640ccaaf2b6ab 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h +++ b/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h @@ -56,6 +56,7 @@ class NumericArray : public libmexclass::proxy::Proxy { // Register Proxy methods. REGISTER_METHOD(NumericArray, ToString); + REGISTER_METHOD(NumericArray, ToMatlab); } private: @@ -67,6 +68,21 @@ class NumericArray : public libmexclass::proxy::Proxy { auto str_mda = factory.createScalar(array->ToString()); context.outputs[0] = str_mda; } + + void ToMatlab(libmexclass::proxy::method::Context& context) { + using ArrowArrayType = typename arrow::CTypeTraits::ArrayType; + + const size_t num_elements = static_cast(array->length()); + const auto numeric_array = std::static_pointer_cast(array); + const CType* const data_begin = numeric_array->raw_values(); + const CType* const data_end = data_begin + num_elements; + + ::matlab::data::ArrayFactory factory; + + // Constructs a TypedArray from the raw values. Makes a copy. + ::matlab::data::TypedArray result = factory.createArray({num_elements, 1}, data_begin, data_end); + context.outputs[0] = result; + } // "Raw" arrow::Array std::shared_ptr array; diff --git a/matlab/src/matlab/+arrow/+array/Float64Array.m b/matlab/src/matlab/+arrow/+array/Float64Array.m index bfe02f6d2f046..d84ac3fe5b955 100644 --- a/matlab/src/matlab/+arrow/+array/Float64Array.m +++ b/matlab/src/matlab/+arrow/+array/Float64Array.m @@ -25,13 +25,24 @@ end methods - function obj = Float64Array(matlabArray) - obj.MatlabArray = matlabArray; - obj.Proxy = libmexclass.proxy.Proxy("Name", "arrow.array.proxy.Float64Array", "ConstructorArguments", {obj.MatlabArray}); + function obj = Float64Array(data, opts) + arguments + data + opts.ID = false + end + + if opts.ID + validateattributes(data, "uint64", "scalar"); + obj.Proxy = libmexclass.proxy.Proxy("Name", "arrow.array.proxy.Float64Array", "ID", data); + else + validateattributes(data, "double", ["vector", "nonsparse", "real"]); + obj.MatlabArray = data; + obj.Proxy = libmexclass.proxy.Proxy("Name", "arrow.array.proxy.Float64Array", "ConstructorArguments", {obj.MatlabArray}); + end end - function str = ToString(obj) - str = obj.Proxy.ToString(); + function data = double(obj) + data = obj.Proxy.ToMatlab(); end end @@ -40,4 +51,10 @@ function displayScalarObject(obj) disp(obj.ToString()); end end + + methods (Access = private) + function str = ToString(obj) + str = obj.Proxy.ToString(); + end + end end From 180b832c2382854238a50ad497fa78ba24626037 Mon Sep 17 00:00:00 2001 From: Sarah Gilmore Date: Thu, 4 May 2023 16:39:51 -0400 Subject: [PATCH 06/22] Add basic tests for double() method for Float64Array Co-authored-by: Kevin Gurney --- .../src/matlab/+arrow/+array/Float64Array.m | 3 ++- matlab/test/arrow/array/tFloat64Array.m | 27 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/matlab/src/matlab/+arrow/+array/Float64Array.m b/matlab/src/matlab/+arrow/+array/Float64Array.m index d84ac3fe5b955..79c0f42858e02 100644 --- a/matlab/src/matlab/+arrow/+array/Float64Array.m +++ b/matlab/src/matlab/+arrow/+array/Float64Array.m @@ -35,7 +35,8 @@ validateattributes(data, "uint64", "scalar"); obj.Proxy = libmexclass.proxy.Proxy("Name", "arrow.array.proxy.Float64Array", "ID", data); else - validateattributes(data, "double", ["vector", "nonsparse", "real"]); + validateattributes(data, "double", ["2d", "nonsparse", "real"]); + if (~isempty(data)), validateattributes(data, "double", "vector"); end obj.MatlabArray = data; obj.Proxy = libmexclass.proxy.Proxy("Name", "arrow.array.proxy.Float64Array", "ConstructorArguments", {obj.MatlabArray}); end diff --git a/matlab/test/arrow/array/tFloat64Array.m b/matlab/test/arrow/array/tFloat64Array.m index f104ad4a7d533..66e6b32868b94 100755 --- a/matlab/test/arrow/array/tFloat64Array.m +++ b/matlab/test/arrow/array/tFloat64Array.m @@ -37,5 +37,32 @@ function Basic(testCase) className = string(class(A)); testCase.verifyEqual(className, "arrow.array.Float64Array"); end + + function Double(testCase) + % Create a Float64Array from a scalar double + A1 = arrow.array.Float64Array(100); + data = double(A1); + testCase.verifyEqual(data, 100); + + % Create a Float64Array from a double vector + A2 = arrow.array.Float64Array([1 2 3]); + data = double(A2); + testCase.verifyEqual(data, [1 2 3]'); + + % Create a Float64Array from an empty double vector + A3 = arrow.array.Float64Array([]); + data = double(A3); + testCase.verifyEqual(data, double.empty(0, 1)); + end + + function ErrorIfComplex(testCase) + fcn = @() arrow.array.Float64Array([10 + 1i, 4]); + testCase.verifyError(fcn, "MATLAB:expectedReal"); + end + + function ErrorIfSparse(testCase) + fcn = @() arrow.array.Float64Array(sparse(ones([10 1]))); + testCase.verifyError(fcn, "MATLAB:expectedNonsparse"); + end end end From 42ffe1a236b1b5a4e49be61af64ccdc7e46af099 Mon Sep 17 00:00:00 2001 From: Sarah Gilmore Date: Fri, 5 May 2023 13:30:47 -0400 Subject: [PATCH 07/22] Add test proxy class for creating arrow Arrays not backed by MATLAB arrays. Co-authored-by: Kevin Gurney --- matlab/src/cpp/arrow/matlab/proxy/factory.cc | 4 + .../arrow/matlab/test/array/proxy/array.cc | 84 +++++++++++++++++++ .../cpp/arrow/matlab/test/array/proxy/array.h | 37 ++++++++ matlab/src/matlab/+arrow/+test/+array/Array.m | 42 ++++++++++ .../cmake/BuildMatlabArrowInterface.cmake | 7 +- 5 files changed, 170 insertions(+), 4 deletions(-) create mode 100644 matlab/src/cpp/arrow/matlab/test/array/proxy/array.cc create mode 100644 matlab/src/cpp/arrow/matlab/test/array/proxy/array.h create mode 100644 matlab/src/matlab/+arrow/+test/+array/Array.m diff --git a/matlab/src/cpp/arrow/matlab/proxy/factory.cc b/matlab/src/cpp/arrow/matlab/proxy/factory.cc index c767d7dc37508..91a7c7b7f39f1 100644 --- a/matlab/src/cpp/arrow/matlab/proxy/factory.cc +++ b/matlab/src/cpp/arrow/matlab/proxy/factory.cc @@ -16,6 +16,7 @@ // under the License. #include "arrow/matlab/array/proxy/numeric_array.h" +#include "arrow/matlab/test/array/proxy/array.h" #include "factory.h" @@ -28,6 +29,9 @@ std::shared_ptr Factory::make_proxy(const ClassName& class_name, const Fu // Register MATLAB Proxy classes with corresponding C++ Proxy classes. REGISTER_PROXY(arrow.array.proxy.Float64Array, arrow::matlab::array::proxy::NumericArray); + + REGISTER_PROXY(arrow.test.array.proxy.Array, arrow::matlab::test::array::proxy::Array); + // TODO: Decide what to do in the case that there isn't a Proxy match. std::cout << "Did not find a matching C++ proxy for: " + class_name << std::endl; return nullptr; diff --git a/matlab/src/cpp/arrow/matlab/test/array/proxy/array.cc b/matlab/src/cpp/arrow/matlab/test/array/proxy/array.cc new file mode 100644 index 0000000000000..2b37ba5e45597 --- /dev/null +++ b/matlab/src/cpp/arrow/matlab/test/array/proxy/array.cc @@ -0,0 +1,84 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +#include "arrow/matlab/test/array/proxy/array.h" + +#include "arrow/builder.h" +#include "arrow/type_traits.h" + +namespace arrow::matlab::test::array::proxy { + +template +std::shared_ptr createNumericArray(const ::matlab::data::TypedArray numeric_mda) { + using BuilderType = typename arrow::CTypeTraits::BuilderType; + + BuilderType builder; + + // Get raw pointer of mxArray + auto it(numeric_mda.cbegin()); + auto dt = it.operator->(); + + // TODO: throw an error + auto st = builder.AppendValues(dt, numeric_mda.getNumberOfElements()); + if (st.ok()) { + return nullptr; + } + + auto maybe_array = builder.Finish(); + + // TODO: throw an error + if (!maybe_array.ok()) { + return nullptr; + } + + std::shared_ptr array = *maybe_array; + return array; +} + +std::shared_ptr createArray(const ::matlab::data::Array mda_array) { + switch (mda_array.getType()) { + case ::matlab::data::ArrayType::SINGLE: + return createNumericArray(::matlab::data::TypedArray(mda_array)); + case ::matlab::data::ArrayType::DOUBLE: + return createNumericArray(::matlab::data::TypedArray(mda_array)); + case ::matlab::data::ArrayType::UINT8: + return createNumericArray(::matlab::data::TypedArray(mda_array)); + case ::matlab::data::ArrayType::UINT16: + return createNumericArray(::matlab::data::TypedArray(mda_array)); + case ::matlab::data::ArrayType::UINT32: + return createNumericArray(::matlab::data::TypedArray(mda_array)); + case ::matlab::data::ArrayType::UINT64: + return createNumericArray(::matlab::data::TypedArray(mda_array)); + case ::matlab::data::ArrayType::INT8: + return createNumericArray(::matlab::data::TypedArray(mda_array)); + case ::matlab::data::ArrayType::INT16: + return createNumericArray(::matlab::data::TypedArray(mda_array)); + case ::matlab::data::ArrayType::INT32: + return createNumericArray(::matlab::data::TypedArray(mda_array)); + case ::matlab::data::ArrayType::INT64: + return createNumericArray(::matlab::data::TypedArray(mda_array)); + default: + return nullptr; + } +} + +Array::Array(const libmexclass::proxy::FunctionArguments& constructor_arguments) { + const ::matlab::data::Array mda_array = constructor_arguments[0]; + array = createArray(mda_array); +} + +} diff --git a/matlab/src/cpp/arrow/matlab/test/array/proxy/array.h b/matlab/src/cpp/arrow/matlab/test/array/proxy/array.h new file mode 100644 index 0000000000000..218eafb28610a --- /dev/null +++ b/matlab/src/cpp/arrow/matlab/test/array/proxy/array.h @@ -0,0 +1,37 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +#pragma once + +#include "arrow/array.h" + +#include "libmexclass/proxy/Proxy.h" + +namespace arrow::matlab::test::array::proxy { + +class Array : public libmexclass::proxy::Proxy { + public: + Array(const libmexclass::proxy::FunctionArguments& constructor_arguments); + + private: + + // "Raw" arrow::Array + std::shared_ptr array; + + + }; +} diff --git a/matlab/src/matlab/+arrow/+test/+array/Array.m b/matlab/src/matlab/+arrow/+test/+array/Array.m new file mode 100644 index 0000000000000..a15688089e686 --- /dev/null +++ b/matlab/src/matlab/+arrow/+test/+array/Array.m @@ -0,0 +1,42 @@ +classdef Array + % Test class utility for allocating Arrow Arrays not backed by MATLAB + % arrays. + + % Licensed to the Apache Software Foundation (ASF) under one or more + % contributor license agreements. See the NOTICE file distributed with + % this work for additional information regarding copyright ownership. + % The ASF licenses this file to you under the Apache License, Version + % 2.0 (the "License"); you may not use this file except in compliance + % with the License. You may obtain a copy of the License at + % + % http://www.apache.org/licenses/LICENSE-2.0 + % + % Unless required by applicable law or agreed to in writing, software + % distributed under the License is distributed on an "AS IS" BASIS, + % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + % implied. See the License for the specific language governing + % permissions and limitations under the License. + + properties(Access = private) + Proxy + end + + properties (Dependent, GetAccess = public, SetAccess = private) + ProxyID + end + + methods + function obj = Array(data) + arguments + % TODO: support non-numeric types + data (1, :) {mustBeNumeric, mustBeReal, mustBeNonsparse} + end + % Copies data to create an Arrow Array. + obj.Proxy = libmexclass.proxy.Proxy("Name", "arrow.test.array.proxy.Array", "ConstructorArguments", {data}); + end + + function id = get.ProxyID(obj) + id = obj.Proxy.ID; + end + end +end \ No newline at end of file diff --git a/matlab/tools/cmake/BuildMatlabArrowInterface.cmake b/matlab/tools/cmake/BuildMatlabArrowInterface.cmake index f231df8dac5e3..eec778a803d11 100644 --- a/matlab/tools/cmake/BuildMatlabArrowInterface.cmake +++ b/matlab/tools/cmake/BuildMatlabArrowInterface.cmake @@ -33,10 +33,9 @@ set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_FETCH_CONTENT_SOURCE_SUBDIR "libmexclass/cpp set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_LIBRARY_NAME arrowproxy) set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_LIBRARY_ROOT_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/src/cpp") -set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/array/proxy") - -# This variable will be populated with future proxy sources. Currently, we only have templated proxies defined in header files. -set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_SOURCES "") +set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/array/proxy" + "${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/test/array/proxy") +set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_SOURCES "${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/test/array/proxy/array.cc") set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_FACTORY_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/proxy") set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_FACTORY_SOURCES "${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/proxy/factory.cc") set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_LIBRARY_INCLUDE_DIRS ${MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_LIBRARY_ROOT_INCLUDE_DIR} From 438ca97523a8ed636ff9eaf3c2fad3e28139f0e0 Mon Sep 17 00:00:00 2001 From: Sarah Gilmore Date: Fri, 5 May 2023 15:11:23 -0400 Subject: [PATCH 08/22] Remove test class for generating arrow arrays not backed by MATLAB. Co-authored-by: Kevin Gurney --- matlab/src/cpp/arrow/matlab/proxy/factory.cc | 4 - .../arrow/matlab/test/array/proxy/array.cc | 84 ------------------- .../cpp/arrow/matlab/test/array/proxy/array.h | 37 -------- matlab/src/matlab/+arrow/+test/+array/Array.m | 42 ---------- 4 files changed, 167 deletions(-) delete mode 100644 matlab/src/cpp/arrow/matlab/test/array/proxy/array.cc delete mode 100644 matlab/src/cpp/arrow/matlab/test/array/proxy/array.h delete mode 100644 matlab/src/matlab/+arrow/+test/+array/Array.m diff --git a/matlab/src/cpp/arrow/matlab/proxy/factory.cc b/matlab/src/cpp/arrow/matlab/proxy/factory.cc index 91a7c7b7f39f1..c767d7dc37508 100644 --- a/matlab/src/cpp/arrow/matlab/proxy/factory.cc +++ b/matlab/src/cpp/arrow/matlab/proxy/factory.cc @@ -16,7 +16,6 @@ // under the License. #include "arrow/matlab/array/proxy/numeric_array.h" -#include "arrow/matlab/test/array/proxy/array.h" #include "factory.h" @@ -29,9 +28,6 @@ std::shared_ptr Factory::make_proxy(const ClassName& class_name, const Fu // Register MATLAB Proxy classes with corresponding C++ Proxy classes. REGISTER_PROXY(arrow.array.proxy.Float64Array, arrow::matlab::array::proxy::NumericArray); - - REGISTER_PROXY(arrow.test.array.proxy.Array, arrow::matlab::test::array::proxy::Array); - // TODO: Decide what to do in the case that there isn't a Proxy match. std::cout << "Did not find a matching C++ proxy for: " + class_name << std::endl; return nullptr; diff --git a/matlab/src/cpp/arrow/matlab/test/array/proxy/array.cc b/matlab/src/cpp/arrow/matlab/test/array/proxy/array.cc deleted file mode 100644 index 2b37ba5e45597..0000000000000 --- a/matlab/src/cpp/arrow/matlab/test/array/proxy/array.cc +++ /dev/null @@ -1,84 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -#include "arrow/matlab/test/array/proxy/array.h" - -#include "arrow/builder.h" -#include "arrow/type_traits.h" - -namespace arrow::matlab::test::array::proxy { - -template -std::shared_ptr createNumericArray(const ::matlab::data::TypedArray numeric_mda) { - using BuilderType = typename arrow::CTypeTraits::BuilderType; - - BuilderType builder; - - // Get raw pointer of mxArray - auto it(numeric_mda.cbegin()); - auto dt = it.operator->(); - - // TODO: throw an error - auto st = builder.AppendValues(dt, numeric_mda.getNumberOfElements()); - if (st.ok()) { - return nullptr; - } - - auto maybe_array = builder.Finish(); - - // TODO: throw an error - if (!maybe_array.ok()) { - return nullptr; - } - - std::shared_ptr array = *maybe_array; - return array; -} - -std::shared_ptr createArray(const ::matlab::data::Array mda_array) { - switch (mda_array.getType()) { - case ::matlab::data::ArrayType::SINGLE: - return createNumericArray(::matlab::data::TypedArray(mda_array)); - case ::matlab::data::ArrayType::DOUBLE: - return createNumericArray(::matlab::data::TypedArray(mda_array)); - case ::matlab::data::ArrayType::UINT8: - return createNumericArray(::matlab::data::TypedArray(mda_array)); - case ::matlab::data::ArrayType::UINT16: - return createNumericArray(::matlab::data::TypedArray(mda_array)); - case ::matlab::data::ArrayType::UINT32: - return createNumericArray(::matlab::data::TypedArray(mda_array)); - case ::matlab::data::ArrayType::UINT64: - return createNumericArray(::matlab::data::TypedArray(mda_array)); - case ::matlab::data::ArrayType::INT8: - return createNumericArray(::matlab::data::TypedArray(mda_array)); - case ::matlab::data::ArrayType::INT16: - return createNumericArray(::matlab::data::TypedArray(mda_array)); - case ::matlab::data::ArrayType::INT32: - return createNumericArray(::matlab::data::TypedArray(mda_array)); - case ::matlab::data::ArrayType::INT64: - return createNumericArray(::matlab::data::TypedArray(mda_array)); - default: - return nullptr; - } -} - -Array::Array(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - const ::matlab::data::Array mda_array = constructor_arguments[0]; - array = createArray(mda_array); -} - -} diff --git a/matlab/src/cpp/arrow/matlab/test/array/proxy/array.h b/matlab/src/cpp/arrow/matlab/test/array/proxy/array.h deleted file mode 100644 index 218eafb28610a..0000000000000 --- a/matlab/src/cpp/arrow/matlab/test/array/proxy/array.h +++ /dev/null @@ -1,37 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -#pragma once - -#include "arrow/array.h" - -#include "libmexclass/proxy/Proxy.h" - -namespace arrow::matlab::test::array::proxy { - -class Array : public libmexclass::proxy::Proxy { - public: - Array(const libmexclass::proxy::FunctionArguments& constructor_arguments); - - private: - - // "Raw" arrow::Array - std::shared_ptr array; - - - }; -} diff --git a/matlab/src/matlab/+arrow/+test/+array/Array.m b/matlab/src/matlab/+arrow/+test/+array/Array.m deleted file mode 100644 index a15688089e686..0000000000000 --- a/matlab/src/matlab/+arrow/+test/+array/Array.m +++ /dev/null @@ -1,42 +0,0 @@ -classdef Array - % Test class utility for allocating Arrow Arrays not backed by MATLAB - % arrays. - - % Licensed to the Apache Software Foundation (ASF) under one or more - % contributor license agreements. See the NOTICE file distributed with - % this work for additional information regarding copyright ownership. - % The ASF licenses this file to you under the Apache License, Version - % 2.0 (the "License"); you may not use this file except in compliance - % with the License. You may obtain a copy of the License at - % - % http://www.apache.org/licenses/LICENSE-2.0 - % - % Unless required by applicable law or agreed to in writing, software - % distributed under the License is distributed on an "AS IS" BASIS, - % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - % implied. See the License for the specific language governing - % permissions and limitations under the License. - - properties(Access = private) - Proxy - end - - properties (Dependent, GetAccess = public, SetAccess = private) - ProxyID - end - - methods - function obj = Array(data) - arguments - % TODO: support non-numeric types - data (1, :) {mustBeNumeric, mustBeReal, mustBeNonsparse} - end - % Copies data to create an Arrow Array. - obj.Proxy = libmexclass.proxy.Proxy("Name", "arrow.test.array.proxy.Array", "ConstructorArguments", {data}); - end - - function id = get.ProxyID(obj) - id = obj.Proxy.ID; - end - end -end \ No newline at end of file From f1588b168862e54e334b87cf8688f3a078c9fa5b Mon Sep 17 00:00:00 2001 From: Sarah Gilmore Date: Fri, 5 May 2023 15:24:17 -0400 Subject: [PATCH 09/22] Add file that was excluded in the previous changelist --- matlab/tools/cmake/BuildMatlabArrowInterface.cmake | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/matlab/tools/cmake/BuildMatlabArrowInterface.cmake b/matlab/tools/cmake/BuildMatlabArrowInterface.cmake index eec778a803d11..f231df8dac5e3 100644 --- a/matlab/tools/cmake/BuildMatlabArrowInterface.cmake +++ b/matlab/tools/cmake/BuildMatlabArrowInterface.cmake @@ -33,9 +33,10 @@ set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_FETCH_CONTENT_SOURCE_SUBDIR "libmexclass/cpp set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_LIBRARY_NAME arrowproxy) set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_LIBRARY_ROOT_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/src/cpp") -set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/array/proxy" - "${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/test/array/proxy") -set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_SOURCES "${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/test/array/proxy/array.cc") +set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/array/proxy") + +# This variable will be populated with future proxy sources. Currently, we only have templated proxies defined in header files. +set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_SOURCES "") set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_FACTORY_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/proxy") set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_FACTORY_SOURCES "${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/proxy/factory.cc") set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_LIBRARY_INCLUDE_DIRS ${MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_LIBRARY_ROOT_INCLUDE_DIR} From ec1a61c5ad1dffa64fd2a32b7f4ac02b63e22ecc Mon Sep 17 00:00:00 2001 From: Sarah Gilmore Date: Fri, 5 May 2023 16:13:19 -0400 Subject: [PATCH 10/22] Enable creating Float64Array by copying the original Matlab array --- .../arrow/matlab/array/proxy/numeric_array.h | 45 ++++++++++++------- .../src/matlab/+arrow/+array/Float64Array.m | 18 +++----- matlab/test/arrow/array/tFloat64Array.m | 21 +++++++++ 3 files changed, 58 insertions(+), 26 deletions(-) diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h b/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h index 640ccaaf2b6ab..ee3240b31a69b 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h +++ b/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h @@ -23,8 +23,6 @@ #include "libmexclass/proxy/Proxy.h" -#include - namespace arrow::matlab::array::proxy { template @@ -32,27 +30,44 @@ class NumericArray : public libmexclass::proxy::Proxy { public: NumericArray(const libmexclass::proxy::FunctionArguments& constructor_arguments) { using ArrowType = typename arrow::CTypeTraits::ArrowType; + using BuilderType = typename arrow::CTypeTraits::BuilderType; // Get the mxArray from constructor arguments const ::matlab::data::TypedArray numeric_mda = constructor_arguments[0]; + const ::matlab::data::TypedArray make_copy = constructor_arguments[1]; // Get raw pointer of mxArray auto it(numeric_mda.cbegin()); auto dt = it.operator->(); - // Pass pointer to Arrow array constructor that takes a buffer - // Do not make a copy when creating arrow::Buffer - std::shared_ptr buffer( - new arrow::Buffer(reinterpret_cast(dt), - sizeof(CType) * numeric_mda.getNumberOfElements())); - - // Construct arrow::NumericArray specialization using arrow::Buffer. - // pass in nulls information...we could compute and provide the number of nulls here too - std::shared_ptr array_wrapper( - new arrow::NumericArray(numeric_mda.getNumberOfElements(), buffer, - nullptr, // TODO: fill validity bitmap with data - -1)); - array = array_wrapper; + if (make_copy[0]) { + + // Pass pointer to Arrow array constructor that takes a buffer + // Do not make a copy when creating arrow::Buffer + std::shared_ptr buffer( + new arrow::Buffer(reinterpret_cast(dt), + sizeof(CType) * numeric_mda.getNumberOfElements())); + + // Construct arrow::NumericArray specialization using arrow::Buffer. + // pass in nulls information...we could compute and provide the number of nulls here too + std::shared_ptr array_wrapper( + new arrow::NumericArray(numeric_mda.getNumberOfElements(), buffer, + nullptr, // TODO: fill validity bitmap with data + -1)); + array = array_wrapper; + + } else { + BuilderType builder; + auto st = builder.AppendValues(dt, numeric_mda.getNumberOfElements()); + + // TODO: handle error case + if (st.ok()) { + auto maybe_array = builder.Finish(); + if (maybe_array.ok()) { + array = *maybe_array; + } + } + } // Register Proxy methods. REGISTER_METHOD(NumericArray, ToString); diff --git a/matlab/src/matlab/+arrow/+array/Float64Array.m b/matlab/src/matlab/+arrow/+array/Float64Array.m index 79c0f42858e02..004d98f105c1d 100644 --- a/matlab/src/matlab/+arrow/+array/Float64Array.m +++ b/matlab/src/matlab/+arrow/+array/Float64Array.m @@ -20,7 +20,7 @@ Proxy end - properties (Access=private) + properties (Hidden, SetAccess=private) MatlabArray end @@ -28,18 +28,14 @@ function obj = Float64Array(data, opts) arguments data - opts.ID = false + opts.DeepCopy = false end - if opts.ID - validateattributes(data, "uint64", "scalar"); - obj.Proxy = libmexclass.proxy.Proxy("Name", "arrow.array.proxy.Float64Array", "ID", data); - else - validateattributes(data, "double", ["2d", "nonsparse", "real"]); - if (~isempty(data)), validateattributes(data, "double", "vector"); end - obj.MatlabArray = data; - obj.Proxy = libmexclass.proxy.Proxy("Name", "arrow.array.proxy.Float64Array", "ConstructorArguments", {obj.MatlabArray}); - end + validateattributes(data, "double", ["2d", "nonsparse", "real"]); + if ~isempty(data), validateattributes(data, "double", "vector"); end + % Store a reference to the array if not doing a deep copy + if (~opts.DeepCopy), obj.MatlabArray = data; end + obj.Proxy = libmexclass.proxy.Proxy("Name", "arrow.array.proxy.Float64Array", "ConstructorArguments", {data, opts.DeepCopy}); end function data = double(obj) diff --git a/matlab/test/arrow/array/tFloat64Array.m b/matlab/test/arrow/array/tFloat64Array.m index 66e6b32868b94..fdec6afb873fe 100755 --- a/matlab/test/arrow/array/tFloat64Array.m +++ b/matlab/test/arrow/array/tFloat64Array.m @@ -38,6 +38,27 @@ function Basic(testCase) testCase.verifyEqual(className, "arrow.array.Float64Array"); end + function ShallowCopy(testCase) + % By default, Float64Array does not create a deep copy on + % construction when constructed from a MATLAB array. Instead, + % it stores a shallow copy of the array keep the memory alive. + A = arrow.array.Float64Array([1, 2, 3]); + testCase.verifyEqual(A.MatlabArray, [1 2 3]); + testCase.verifyEqual(double(A), [1 2 3]'); + + A = arrow.array.Float64Array([1, 2, 3], DeepCopy=false); + testCase.verifyEqual(A.MatlabArray, [1 2 3]); + testCase.verifyEqual(double(A), [1 2 3]'); + end + + function DeepCopy(testCase) + % Verify Float64Array does not store shallow copy of the MATLAB + % array if DeepCopy=true was supplied. + A = arrow.array.Float64Array([1, 2, 3], DeepCopy=true); + testCase.verifyEqual(A.MatlabArray, []); + testCase.verifyEqual(double(A), [1 2 3]'); + end + function Double(testCase) % Create a Float64Array from a scalar double A1 = arrow.array.Float64Array(100); From 14078a84febf4f3310005c740c6476903fed0c4e Mon Sep 17 00:00:00 2001 From: Sarah Gilmore Date: Fri, 5 May 2023 17:09:19 -0400 Subject: [PATCH 11/22] Create Array Proxy Interface for shared functionality Co-authored-by: Kevin Gurney --- .../src/cpp/arrow/matlab/array/proxy/array.cc | 37 ++++++++++++++++ .../src/cpp/arrow/matlab/array/proxy/array.h | 43 +++++++++++++++++++ .../arrow/matlab/array/proxy/numeric_array.h | 27 +++--------- .../cmake/BuildMatlabArrowInterface.cmake | 3 +- 4 files changed, 89 insertions(+), 21 deletions(-) create mode 100644 matlab/src/cpp/arrow/matlab/array/proxy/array.cc create mode 100644 matlab/src/cpp/arrow/matlab/array/proxy/array.h diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/array.cc b/matlab/src/cpp/arrow/matlab/array/proxy/array.cc new file mode 100644 index 0000000000000..865dd694b78ef --- /dev/null +++ b/matlab/src/cpp/arrow/matlab/array/proxy/array.cc @@ -0,0 +1,37 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +#include "arrow/matlab/array/proxy/array.h" + +namespace arrow::matlab::array::proxy { + + Array::Array(const libmexclass::proxy::FunctionArguments& constructor_arguments) { + + // Register Proxy methods. + REGISTER_METHOD(Array, ToString); + REGISTER_METHOD(Array, ToMatlab); + + } + + void Array::ToString(libmexclass::proxy::method::Context& context) { + ::matlab::data::ArrayFactory factory; + + // TODO: handle non-ascii characters + auto str_mda = factory.createScalar(array->ToString()); + context.outputs[0] = str_mda; + } +} diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/array.h b/matlab/src/cpp/arrow/matlab/array/proxy/array.h new file mode 100644 index 0000000000000..9381e05bcb77d --- /dev/null +++ b/matlab/src/cpp/arrow/matlab/array/proxy/array.h @@ -0,0 +1,43 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +#pragma once + +#include "arrow/array.h" + +#include "libmexclass/proxy/Proxy.h" + +namespace arrow::matlab::array::proxy { + +class Array : public libmexclass::proxy::Proxy { + public: + Array(const libmexclass::proxy::FunctionArguments& constructor_arguments); + + virtual ~Array() {} + + protected: + + void ToString(libmexclass::proxy::method::Context& context); + + virtual void ToMatlab(libmexclass::proxy::method::Context& context) = 0; + + void TestFunc(libmexclass::proxy::method::Context& context); + + std::shared_ptr array; +}; + +} diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h b/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h index ee3240b31a69b..d82f64b7ce5fb 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h +++ b/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h @@ -21,14 +21,17 @@ #include "arrow/builder.h" #include "arrow/type_traits.h" +#include "arrow/matlab/array/proxy/array.h" + #include "libmexclass/proxy/Proxy.h" namespace arrow::matlab::array::proxy { template -class NumericArray : public libmexclass::proxy::Proxy { +class NumericArray : public arrow::matlab::array::proxy::Array { public: - NumericArray(const libmexclass::proxy::FunctionArguments& constructor_arguments) { + NumericArray(const libmexclass::proxy::FunctionArguments& constructor_arguments) + : arrow::matlab::array::proxy::Array(constructor_arguments) { using ArrowType = typename arrow::CTypeTraits::ArrowType; using BuilderType = typename arrow::CTypeTraits::BuilderType; @@ -68,23 +71,10 @@ class NumericArray : public libmexclass::proxy::Proxy { } } } - - // Register Proxy methods. - REGISTER_METHOD(NumericArray, ToString); - REGISTER_METHOD(NumericArray, ToMatlab); } - private: - - void ToString(libmexclass::proxy::method::Context& context) { - ::matlab::data::ArrayFactory factory; - - // TODO: handle non-ascii characters - auto str_mda = factory.createScalar(array->ToString()); - context.outputs[0] = str_mda; - } - - void ToMatlab(libmexclass::proxy::method::Context& context) { + protected: + void ToMatlab(libmexclass::proxy::method::Context& context) override { using ArrowArrayType = typename arrow::CTypeTraits::ArrayType; const size_t num_elements = static_cast(array->length()); @@ -98,9 +88,6 @@ class NumericArray : public libmexclass::proxy::Proxy { ::matlab::data::TypedArray result = factory.createArray({num_elements, 1}, data_begin, data_end); context.outputs[0] = result; } - - // "Raw" arrow::Array - std::shared_ptr array; }; } diff --git a/matlab/tools/cmake/BuildMatlabArrowInterface.cmake b/matlab/tools/cmake/BuildMatlabArrowInterface.cmake index f231df8dac5e3..2e521a7d33771 100644 --- a/matlab/tools/cmake/BuildMatlabArrowInterface.cmake +++ b/matlab/tools/cmake/BuildMatlabArrowInterface.cmake @@ -36,7 +36,8 @@ set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_LIBRARY_ROOT_INCLUDE_DIR "${CMAKE_SOUR set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/array/proxy") # This variable will be populated with future proxy sources. Currently, we only have templated proxies defined in header files. -set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_SOURCES "") +set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_SOURCES "${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/array/proxy/array.cc") + set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_FACTORY_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/proxy") set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_FACTORY_SOURCES "${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/proxy/factory.cc") set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_LIBRARY_INCLUDE_DIRS ${MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_LIBRARY_ROOT_INCLUDE_DIR} From c4f82a648a1e52ad9230856535870cf93d340eef Mon Sep 17 00:00:00 2001 From: Sarah Gilmore Date: Fri, 5 May 2023 17:18:16 -0400 Subject: [PATCH 12/22] 1. Add basic tests for edge case values (NaN, (+)(-)inf, realmin, realmax, etc.) 2. Add DeepCopy parameterization to test points. Co-authored-by: Kevin Gurney --- matlab/test/arrow/array/tFloat64Array.m | 49 ++++++++++++++++--------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/matlab/test/arrow/array/tFloat64Array.m b/matlab/test/arrow/array/tFloat64Array.m index fdec6afb873fe..c0abcb8e959df 100755 --- a/matlab/test/arrow/array/tFloat64Array.m +++ b/matlab/test/arrow/array/tFloat64Array.m @@ -16,6 +16,10 @@ % implied. See the License for the specific language governing % permissions and limitations under the License. + properties (TestParameter) + MakeDeepCopy = {true false} + end + methods(TestClassSetup) function verifyOnMatlabPath(testCase) % arrow.array.Float64Array must be on the MATLAB path. @@ -24,16 +28,9 @@ function verifyOnMatlabPath(testCase) end end - methods(TestMethodSetup) - function setupTempWorkingDirectory(testCase) - import matlab.unittest.fixtures.WorkingFolderFixture; - testCase.applyFixture(WorkingFolderFixture); - end - end - methods(Test) - function Basic(testCase) - A = arrow.array.Float64Array([1, 2, 3]); + function Basic(testCase, MakeDeepCopy) + A = arrow.array.Float64Array([1, 2, 3], DeepCopy=MakeDeepCopy); className = string(class(A)); testCase.verifyEqual(className, "arrow.array.Float64Array"); end @@ -59,30 +56,48 @@ function DeepCopy(testCase) testCase.verifyEqual(double(A), [1 2 3]'); end - function Double(testCase) + function Double(testCase, MakeDeepCopy) % Create a Float64Array from a scalar double - A1 = arrow.array.Float64Array(100); + A1 = arrow.array.Float64Array(100, DeepCopy=MakeDeepCopy); data = double(A1); testCase.verifyEqual(data, 100); % Create a Float64Array from a double vector - A2 = arrow.array.Float64Array([1 2 3]); + A2 = arrow.array.Float64Array([1 2 3], DeepCopy=MakeDeepCopy); data = double(A2); testCase.verifyEqual(data, [1 2 3]'); % Create a Float64Array from an empty double vector - A3 = arrow.array.Float64Array([]); + A3 = arrow.array.Float64Array([], DeepCopy=MakeDeepCopy); data = double(A3); testCase.verifyEqual(data, double.empty(0, 1)); end - function ErrorIfComplex(testCase) - fcn = @() arrow.array.Float64Array([10 + 1i, 4]); + function MinValue(testCase, MakeDeepCopy) + A1 = arrow.array.Float64Array(realmin, DeepCopy=MakeDeepCopy); + data = double(A1); + testCase.verifyEqual(data, realmin); + end + + function MaxValue(testCase, MakeDeepCopy) + A1 = arrow.array.Float64Array(realmax, DeepCopy=MakeDeepCopy); + data = double(A1); + testCase.verifyEqual(data, realmax); + end + + function InfValues(testCase, MakeDeepCopy) + A1 = arrow.array.Float64Array([Inf -Inf], DeepCopy=MakeDeepCopy); + data = double(A1); + testCase.verifyEqual(data, [Inf -Inf]'); + end + + function ErrorIfComplex(testCase, MakeDeepCopy) + fcn = @() arrow.array.Float64Array([10 + 1i, 4], DeepCopy=MakeDeepCopy); testCase.verifyError(fcn, "MATLAB:expectedReal"); end - function ErrorIfSparse(testCase) - fcn = @() arrow.array.Float64Array(sparse(ones([10 1]))); + function ErrorIfSparse(testCase, MakeDeepCopy) + fcn = @() arrow.array.Float64Array(sparse(ones([10 1])), DeepCopy=MakeDeepCopy); testCase.verifyError(fcn, "MATLAB:expectedNonsparse"); end end From 57289845f4eb855c45e2cfb55811a621f6c2db40 Mon Sep 17 00:00:00 2001 From: Sarah Gilmore Date: Fri, 5 May 2023 17:20:57 -0400 Subject: [PATCH 13/22] Delete temporary method. --- matlab/src/cpp/arrow/matlab/array/proxy/array.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/array.h b/matlab/src/cpp/arrow/matlab/array/proxy/array.h index 9381e05bcb77d..8a16630348797 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/array.h +++ b/matlab/src/cpp/arrow/matlab/array/proxy/array.h @@ -35,8 +35,6 @@ class Array : public libmexclass::proxy::Proxy { virtual void ToMatlab(libmexclass::proxy::method::Context& context) = 0; - void TestFunc(libmexclass::proxy::method::Context& context); - std::shared_ptr array; }; From 281933da920044d001a41ed3a43fc714187259b4 Mon Sep 17 00:00:00 2001 From: Sarah Gilmore Date: Fri, 5 May 2023 17:24:03 -0400 Subject: [PATCH 14/22] Delete out of date comment in cmake file --- matlab/tools/cmake/BuildMatlabArrowInterface.cmake | 2 -- 1 file changed, 2 deletions(-) diff --git a/matlab/tools/cmake/BuildMatlabArrowInterface.cmake b/matlab/tools/cmake/BuildMatlabArrowInterface.cmake index 2e521a7d33771..92ed955ed4e0d 100644 --- a/matlab/tools/cmake/BuildMatlabArrowInterface.cmake +++ b/matlab/tools/cmake/BuildMatlabArrowInterface.cmake @@ -34,8 +34,6 @@ set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_FETCH_CONTENT_SOURCE_SUBDIR "libmexclass/cpp set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_LIBRARY_NAME arrowproxy) set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_LIBRARY_ROOT_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/src/cpp") set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/array/proxy") - -# This variable will be populated with future proxy sources. Currently, we only have templated proxies defined in header files. set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_SOURCES "${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/array/proxy/array.cc") set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_FACTORY_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/proxy") From 26657a4de5758ca637eb70cccc571b7c5e89b5fa Mon Sep 17 00:00:00 2001 From: Sarah Gilmore Date: Mon, 8 May 2023 11:43:08 -0400 Subject: [PATCH 15/22] Fix incorrect logic deciding when to make a deep copy or not in the C++ layer. Co-authored-by: Kevin Gurney --- .../arrow/matlab/array/proxy/numeric_array.h | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h b/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h index d82f64b7ce5fb..3df96019192b2 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h +++ b/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h @@ -43,8 +43,20 @@ class NumericArray : public arrow::matlab::array::proxy::Array { auto it(numeric_mda.cbegin()); auto dt = it.operator->(); - if (make_copy[0]) { + const bool make_deep_copy = make_copy[0]; + if (make_deep_copy) { + BuilderType builder; + auto st = builder.AppendValues(dt, numeric_mda.getNumberOfElements()); + + // TODO: handle error case + if (st.ok()) { + auto maybe_array = builder.Finish(); + if (maybe_array.ok()) { + array = *maybe_array; + } + } + } else { // Pass pointer to Arrow array constructor that takes a buffer // Do not make a copy when creating arrow::Buffer std::shared_ptr buffer( @@ -58,18 +70,6 @@ class NumericArray : public arrow::matlab::array::proxy::Array { nullptr, // TODO: fill validity bitmap with data -1)); array = array_wrapper; - - } else { - BuilderType builder; - auto st = builder.AppendValues(dt, numeric_mda.getNumberOfElements()); - - // TODO: handle error case - if (st.ok()) { - auto maybe_array = builder.Finish(); - if (maybe_array.ok()) { - array = *maybe_array; - } - } } } From 3be33d1baeb2d27de31ab89ded9ab52e5c9b7f65 Mon Sep 17 00:00:00 2001 From: sgilmore10 <74676073+sgilmore10@users.noreply.github.com> Date: Tue, 9 May 2023 10:06:22 -0400 Subject: [PATCH 16/22] Fix indentation in comment Co-authored-by: Sutou Kouhei --- matlab/test/arrow/array/tFloat64Array.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/matlab/test/arrow/array/tFloat64Array.m b/matlab/test/arrow/array/tFloat64Array.m index c0abcb8e959df..685405fed9e21 100755 --- a/matlab/test/arrow/array/tFloat64Array.m +++ b/matlab/test/arrow/array/tFloat64Array.m @@ -36,9 +36,9 @@ function Basic(testCase, MakeDeepCopy) end function ShallowCopy(testCase) - % By default, Float64Array does not create a deep copy on - % construction when constructed from a MATLAB array. Instead, - % it stores a shallow copy of the array keep the memory alive. + % By default, Float64Array does not create a deep copy on + % construction when constructed from a MATLAB array. Instead, + % it stores a shallow copy of the array keep the memory alive. A = arrow.array.Float64Array([1, 2, 3]); testCase.verifyEqual(A.MatlabArray, [1 2 3]); testCase.verifyEqual(double(A), [1 2 3]'); From c0b6104ad9cf15a15997f58d63c50b8c729aedf3 Mon Sep 17 00:00:00 2001 From: sgilmore10 <74676073+sgilmore10@users.noreply.github.com> Date: Tue, 9 May 2023 10:06:39 -0400 Subject: [PATCH 17/22] Use auto instead of bool Co-authored-by: Sutou Kouhei --- matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h b/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h index 3df96019192b2..ced1dbffef526 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h +++ b/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h @@ -43,7 +43,7 @@ class NumericArray : public arrow::matlab::array::proxy::Array { auto it(numeric_mda.cbegin()); auto dt = it.operator->(); - const bool make_deep_copy = make_copy[0]; + const auto make_deep_copy = make_copy[0]; if (make_deep_copy) { BuilderType builder; From 9d929a20b3db9679044a63d9fb61814b518c5282 Mon Sep 17 00:00:00 2001 From: sgilmore10 <74676073+sgilmore10@users.noreply.github.com> Date: Tue, 9 May 2023 10:06:54 -0400 Subject: [PATCH 18/22] Use auto instead of size_t Co-authored-by: Sutou Kouhei --- matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h b/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h index ced1dbffef526..c9a0a40d598b6 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h +++ b/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h @@ -77,7 +77,7 @@ class NumericArray : public arrow::matlab::array::proxy::Array { void ToMatlab(libmexclass::proxy::method::Context& context) override { using ArrowArrayType = typename arrow::CTypeTraits::ArrayType; - const size_t num_elements = static_cast(array->length()); + const auto num_elements = static_cast(array->length()); const auto numeric_array = std::static_pointer_cast(array); const CType* const data_begin = numeric_array->raw_values(); const CType* const data_end = data_begin + num_elements; From 6c2455a13429f7fc57ae413e8a08691ac76c3633 Mon Sep 17 00:00:00 2001 From: sgilmore10 <74676073+sgilmore10@users.noreply.github.com> Date: Tue, 9 May 2023 10:08:39 -0400 Subject: [PATCH 19/22] Remove extra spaces Co-authored-by: Sutou Kouhei --- matlab/src/matlab/+arrow/+array/Float64Array.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matlab/src/matlab/+arrow/+array/Float64Array.m b/matlab/src/matlab/+arrow/+array/Float64Array.m index 004d98f105c1d..c48ee45574662 100644 --- a/matlab/src/matlab/+arrow/+array/Float64Array.m +++ b/matlab/src/matlab/+arrow/+array/Float64Array.m @@ -49,7 +49,7 @@ function displayScalarObject(obj) end end - methods (Access = private) + methods (Access=private) function str = ToString(obj) str = obj.Proxy.ToString(); end From eb111f43e738fbaa56df7423c52c3507cb227225 Mon Sep 17 00:00:00 2001 From: sgilmore10 <74676073+sgilmore10@users.noreply.github.com> Date: Tue, 9 May 2023 10:09:59 -0400 Subject: [PATCH 20/22] Use auto and make_shared to create shared_ptr Co-authored-by: Sutou Kouhei --- matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h b/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h index c9a0a40d598b6..6d497cd0d9d5c 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h +++ b/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h @@ -59,9 +59,8 @@ class NumericArray : public arrow::matlab::array::proxy::Array { } else { // Pass pointer to Arrow array constructor that takes a buffer // Do not make a copy when creating arrow::Buffer - std::shared_ptr buffer( - new arrow::Buffer(reinterpret_cast(dt), - sizeof(CType) * numeric_mda.getNumberOfElements())); + auto buffer = std::make_shared(reinterpret_cast(dt), + sizeof(CType) * numeric_mda.getNumberOfElements()); // Construct arrow::NumericArray specialization using arrow::Buffer. // pass in nulls information...we could compute and provide the number of nulls here too From f2646768f268a970f7274320619431aa12173d7c Mon Sep 17 00:00:00 2001 From: sgilmore10 <74676073+sgilmore10@users.noreply.github.com> Date: Tue, 9 May 2023 10:10:32 -0400 Subject: [PATCH 21/22] Fix indentation Co-authored-by: Sutou Kouhei --- matlab/test/arrow/array/tFloat64Array.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/matlab/test/arrow/array/tFloat64Array.m b/matlab/test/arrow/array/tFloat64Array.m index 685405fed9e21..7e1a878c425d6 100755 --- a/matlab/test/arrow/array/tFloat64Array.m +++ b/matlab/test/arrow/array/tFloat64Array.m @@ -49,8 +49,8 @@ function ShallowCopy(testCase) end function DeepCopy(testCase) - % Verify Float64Array does not store shallow copy of the MATLAB - % array if DeepCopy=true was supplied. + % Verify Float64Array does not store shallow copy of the MATLAB + % array if DeepCopy=true was supplied. A = arrow.array.Float64Array([1, 2, 3], DeepCopy=true); testCase.verifyEqual(A.MatlabArray, []); testCase.verifyEqual(double(A), [1 2 3]'); From 983ff905df340325ba64e18bceb80b68e78ac919 Mon Sep 17 00:00:00 2001 From: Sarah Gilmore Date: Tue, 9 May 2023 10:36:56 -0400 Subject: [PATCH 22/22] Use ArrayData to construct Arrays. Co-authored-by: Kevin Gurney --- .../arrow/matlab/array/proxy/numeric_array.h | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h b/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h index 6d497cd0d9d5c..f7f19a60b0757 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h +++ b/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h @@ -17,7 +17,11 @@ #pragma once + #include "arrow/array.h" +#include "arrow/array/data.h" +#include "arrow/array/util.h" + #include "arrow/builder.h" #include "arrow/type_traits.h" @@ -57,18 +61,19 @@ class NumericArray : public arrow::matlab::array::proxy::Array { } } } else { - // Pass pointer to Arrow array constructor that takes a buffer + const auto data_type = arrow::CTypeTraits::type_singleton(); + const auto length = static_cast(numeric_mda.getNumberOfElements()); // cast size_t to int64_t + // Do not make a copy when creating arrow::Buffer - auto buffer = std::make_shared(reinterpret_cast(dt), + auto data_buffer = std::make_shared(reinterpret_cast(dt), sizeof(CType) * numeric_mda.getNumberOfElements()); - - // Construct arrow::NumericArray specialization using arrow::Buffer. - // pass in nulls information...we could compute and provide the number of nulls here too - std::shared_ptr array_wrapper( - new arrow::NumericArray(numeric_mda.getNumberOfElements(), buffer, - nullptr, // TODO: fill validity bitmap with data - -1)); - array = array_wrapper; + + // TODO: Implement null support + std::shared_ptr null_buffer = nullptr; + + auto array_data = arrow::ArrayData::Make(data_type, length, {null_buffer, data_buffer}); + array = arrow::MakeArray(array_data); + } }