Skip to content

Commit

Permalink
Refactored multi-dim arrays and support for multi-dim assignment
Browse files Browse the repository at this point in the history
  • Loading branch information
wlav committed Jul 3, 2021
1 parent 0c6725f commit 5177298
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 69 deletions.
1 change: 1 addition & 0 deletions doc/source/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ master: 2.1.0
* Support for vector calls with CPython 3.8 and newer
* Support for typed C++ literals as defaults when mixing with keywords
* Enable reshaping of multi-dim LowLevelViews
* Refactored multi-dim arrays and support for multi-dim assignment
* Direct support for C's _Complex (_Complex_double/_float on Windows)
* sizeof() forwards to ctypes.sizeof() for ctypes' types
* Upgrade cmake fragments for Clang9
Expand Down
91 changes: 51 additions & 40 deletions test/datatypes.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -836,59 +836,70 @@ static inline void free_2d(void** arr, size_t N) {
} // namespace MultiDimArrays

MultiDimArrays::DataHolder::DataHolder() {
m_short = allocate_2d<short>(5, 7);
m_unsigned_short = allocate_2d<unsigned short>(5, 7);
m_int = allocate_2d<int>(5, 7);
m_unsigned_int = allocate_2d<unsigned int>(5, 7);
m_long = allocate_2d<long>(5, 7);
m_unsigned_long = allocate_2d<unsigned long>(5, 7);
m_long_long = allocate_2d<long long>(5, 7);
m_unsigned_long_long = allocate_2d<unsigned long long>(5, 7);
m_float = allocate_2d<float>(5, 7);
m_double = allocate_2d<double>(5, 7);
m_short1 = allocate_2d<short>(5, 7);
m_unsigned_short1 = allocate_2d<unsigned short>(5, 7);
m_int1 = allocate_2d<int>(5, 7);
m_unsigned_int1 = allocate_2d<unsigned int>(5, 7);
m_long1 = allocate_2d<long>(5, 7);
m_unsigned_long1 = allocate_2d<unsigned long>(5, 7);
m_long_long1 = allocate_2d<long long>(5, 7);
m_unsigned_long_long1 = allocate_2d<unsigned long long>(5, 7);
m_float1 = allocate_2d<float>(5, 7);
m_double1 = allocate_2d<double>(5, 7);

for (size_t i = 0; i < 5; ++i) {
for (size_t j = 0; j < 7; ++j) {
size_t val = 5*i+j;
m_short[i][j] = (short)val;
m_unsigned_short[i][j] = (unsigned short)val;
m_int[i][j] = (int)val;
m_unsigned_int[i][j] = (unsigned int)val;
m_long[i][j] = (long)val;
m_unsigned_long[i][j] = (unsigned long)val;
m_long_long[i][j] = (long long)val;
m_unsigned_long_long[i][j] = (unsigned long long)val;
m_float[i][j] = (float)val;
m_double[i][j] = (double)val;
m_short1[i][j] = (short)val;
m_unsigned_short1[i][j] = (unsigned short)val;
m_int1[i][j] = (int)val;
m_unsigned_int1[i][j] = (unsigned int)val;
m_long1[i][j] = (long)val;
m_unsigned_long1[i][j] = (unsigned long)val;
m_long_long1[i][j] = (long long)val;
m_unsigned_long_long1[i][j] = (unsigned long long)val;
m_float1[i][j] = (float)val;
m_double1[i][j] = (double)val;
}
}

m_short2 = nullptr;
m_unsigned_short2 = nullptr;
m_int2 = nullptr;
m_unsigned_int2 = nullptr;
m_long2 = nullptr;
m_unsigned_long2 = nullptr;
m_long_long2 = nullptr;
m_unsigned_long_long2 = nullptr;
m_float2 = nullptr;
m_double2 = nullptr;

for (size_t i = 0; i < 3; ++i) {
for (size_t j = 0; j < 5; ++j) {
size_t val = 3*i+j;
m_short2[i][j] = (short)val;
m_unsigned_short2[i][j] = (unsigned short)val;
m_int2[i][j] = (int)val;
m_unsigned_int2[i][j] = (unsigned int)val;
m_long2[i][j] = (long)val;
m_unsigned_long2[i][j] = (unsigned long)val;
m_long_long2[i][j] = (long long)val;
m_unsigned_long_long2[i][j] = (unsigned long long)val;
m_float2[i][j] = (float)val;
m_double2[i][j] = (double)val;
m_short3[i][j] = (short)val;
m_unsigned_short3[i][j] = (unsigned short)val;
m_int3[i][j] = (int)val;
m_unsigned_int3[i][j] = (unsigned int)val;
m_long3[i][j] = (long)val;
m_unsigned_long3[i][j] = (unsigned long)val;
m_long_long3[i][j] = (long long)val;
m_unsigned_long_long3[i][j] = (unsigned long long)val;
m_float3[i][j] = (float)val;
m_double3[i][j] = (double)val;
}
}
}

MultiDimArrays::DataHolder::~DataHolder() {
free_2d((void**)m_short, 5);
free_2d((void**)m_unsigned_short, 5);
free_2d((void**)m_int, 5);
free_2d((void**)m_unsigned_int, 5);
free_2d((void**)m_long, 5);
free_2d((void**)m_unsigned_long, 5);
free_2d((void**)m_long_long, 5);
free_2d((void**)m_unsigned_long_long, 5);
free_2d((void**)m_float, 5);
free_2d((void**)m_double, 5);
free_2d((void**)m_short1, 5);
free_2d((void**)m_unsigned_short1, 5);
free_2d((void**)m_int1, 5);
free_2d((void**)m_unsigned_int1, 5);
free_2d((void**)m_long1, 5);
free_2d((void**)m_unsigned_long1, 5);
free_2d((void**)m_long_long1, 5);
free_2d((void**)m_unsigned_long_long1, 5);
free_2d((void**)m_float1, 5);
free_2d((void**)m_double1, 5);
}
54 changes: 32 additions & 22 deletions test/datatypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -775,28 +775,38 @@ struct DataHolder {
DataHolder();
~DataHolder();

short** m_short;
unsigned short** m_unsigned_short;
int** m_int;
unsigned int** m_unsigned_int;
long** m_long;
unsigned long** m_unsigned_long;
long long** m_long_long;
unsigned long long** m_unsigned_long_long;
float** m_float;
double** m_double;


short m_short2[3][5];
unsigned short m_unsigned_short2[3][5];
int m_int2[3][5];
unsigned int m_unsigned_int2[3][5];
long m_long2[3][5];
unsigned long m_unsigned_long2[3][5];
long long m_long_long2[3][5];
unsigned long long m_unsigned_long_long2[3][5];
float m_float2[3][5];
double m_double2[3][5];
short** m_short1;
unsigned short** m_unsigned_short1;
int** m_int1;
unsigned int** m_unsigned_int1;
long** m_long1;
unsigned long** m_unsigned_long1;
long long** m_long_long1;
unsigned long long** m_unsigned_long_long1;
float** m_float1;
double** m_double1;

short** m_short2;
unsigned short** m_unsigned_short2;
int** m_int2;
unsigned int** m_unsigned_int2;
long** m_long2;
unsigned long** m_unsigned_long2;
long long** m_long_long2;
unsigned long long** m_unsigned_long_long2;
float** m_float2;
double** m_double2;

short m_short3[3][5];
unsigned short m_unsigned_short3[3][5];
int m_int3[3][5];
unsigned int m_unsigned_int3[3][5];
long m_long3[3][5];
unsigned long m_unsigned_long3[3][5];
long long m_long_long3[3][5];
unsigned long long m_unsigned_long_long3[3][5];
float m_float3[3][5];
double m_double3[3][5];
};

} // namespace MultiDimArrays
Expand Down
8 changes: 4 additions & 4 deletions test/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,12 @@ class APICheck3Converter : public CPyCppyy::Converter {
typedef CPyCppyy::ConverterFactory_t cf_t;
void register_a3() {
#ifndef WIN32
CPyCppyy::RegisterConverter("APICheck3", (cf_t)+[](Py_ssize_t*) { static APICheck3Converter c{}; return &c; });
CPyCppyy::RegisterConverter("APICheck3&", (cf_t)+[](Py_ssize_t*) { static APICheck3Converter c{}; return &c; });
CPyCppyy::RegisterConverter("APICheck3", (cf_t)+[](CPyCppyy::dims_t) { static APICheck3Converter c{}; return &c; });
CPyCppyy::RegisterConverter("APICheck3&", (cf_t)+[](CPyCppyy::dims_t) { static APICheck3Converter c{}; return &c; });
#else
// Clang's JIT does not support relocation of the static variable on Windows
CPyCppyy::RegisterConverter("APICheck3", (cf_t)+[](Py_ssize_t*) { return new APICheck3Converter{}; });
CPyCppyy::RegisterConverter("APICheck3&", (cf_t)+[](Py_ssize_t*) { return new APICheck3Converter{}; });
CPyCppyy::RegisterConverter("APICheck3", (cf_t)+[](CPyCppyy::dims_t) { return new APICheck3Converter{}; });
CPyCppyy::RegisterConverter("APICheck3&", (cf_t)+[](CPyCppyy::dims_t) { return new APICheck3Converter{}; });
#endif
}
void unregister_a3() {
Expand Down
2 changes: 1 addition & 1 deletion test/test_concurrent.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ def process(self, c):
assert c.count == 10

class C(consumer):
count = 0
count = 0
def process(self, c):
raise RuntimeError("all wrong")

Expand Down
28 changes: 26 additions & 2 deletions test/test_lowlevel.py
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,9 @@ def setup_class(cls):
'long long', 'unsigned long long', 'float', 'double'
]

def _data_m(self, lbl):
return [('m_'+tp.replace(' ', '_')+lbl, tp) for tp in self.numeric_builtin_types]

def test01_2D_arrays(self):
"""Access and use of 2D data members"""

Expand All @@ -490,8 +493,7 @@ def test01_2D_arrays(self):
ns = cppyy.gbl.MultiDimArrays
h = ns.DataHolder()

data1 = [('m_'+tp.replace(' ', '_'), tp) for tp in self.numeric_builtin_types]

data1 = self._data_m('1')
for m, tp in data1:
getattr(h, m).reshape((5, 7))
assert getattr(h, m).shape == (5, 7)
Expand All @@ -509,3 +511,25 @@ def test01_2D_arrays(self):
for i in range(5):
for j in range(7):
assert arr[i][j] == elem_tp(4+5*i+j)

def test02_assign_2D_arrays(self):
"""Direct assignment of 2D arrays"""

import cppyy

try:
import numpy as np
except ImportError:
py.test.skip('numpy is not installed')

ns = cppyy.gbl.MultiDimArrays
h = ns.DataHolder()

data1 = self._data_m('1')
for m, tp in data1:
getattr(h, m).reshape((5, 7))
assert getattr(h, m).shape == (5, 7)

# copy assignment
h.m_int3 = np.ones((3, 5), dtype=np.int32)
#print(h.m_int3[1][1])
27 changes: 27 additions & 0 deletions test/test_regression.py
Original file line number Diff line number Diff line change
Expand Up @@ -976,3 +976,30 @@ def test34_filesytem(self):
}""")

assert cppyy.gbl.stack_std_path() == '"/usr"'

def test35_ctypes_sizeof(self):
"""cppyy.sizeof forwards to ctypes.sizeof where necessary"""

import cppyy, ctypes

cppyy.cppdef("""\
namespace test35_ctypes_sizeof {
void func(uint32_t* param) {
*param = 42;
}
}""")

ns = cppyy.gbl.test35_ctypes_sizeof

holder = ctypes.c_uint32(17)
param = ctypes.pointer(holder)

ns.func(param)
assert holder.value == 42

holder = ctypes.c_uint32(17)
ns.func(holder)
assert holder.value == 42

assert cppyy.sizeof(param) == ctypes.sizeof(param)

0 comments on commit 5177298

Please sign in to comment.