Skip to content

Commit 80a0b2c

Browse files
add interface to build npy_array_list objects from C (#30)
* add interface to build npy_array_list objects from C * rename to deepcopy --------- Co-authored-by: Lennart Klebl (alcubierre-drive)
1 parent f88c015 commit 80a0b2c

File tree

4 files changed

+52
-2
lines changed

4 files changed

+52
-2
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,7 @@
33
*~
44
*.npy
55
*.npz
6+
Makefile
7+
*.so
8+
*.pc
9+
*.d

README.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,12 @@ And the linked list structure for `.npz` files:
119119
} npy_array_list_t;
120120

121121
## API
122-
The API is really simple. There is only ~~ten~~eleven public functions:
122+
The API is really simple. There is only ~~eleven~~twelve public functions:
123123

124124
/* These are the four functions for loading and saving .npy files */
125125
npy_array_t* npy_array_load ( const char *filename);
126126
npy_array_t* npy_array_mmap ( const char *filename);
127+
npy_array_t* npy_array_alloc ( const npy_array_t *m );
127128
void npy_array_dump ( const npy_array_t *m );
128129
void npy_array_save ( const char *filename, const npy_array_t *m );
129130
void npy_array_free ( npy_array_t *m );
@@ -156,6 +157,27 @@ You can then run example with a _NumPy_ file as argument.
156157
return 0;
157158
}
158159

160+
## Saving lists of numpy arrays (and building them)
161+
Here is an example of saving multiple arrays into a single .npz file. You can
162+
compile this with:
163+
164+
gcc -O3 -Wall -Wextra -pedantic -std=c11 -c example_list.c
165+
gcc -o example_list example_list.o npy_array.o npy_array_list.o -lzip
166+
167+
You can the run example_list with a filename (_NumPy_ compressed) as argument.
168+
169+
#include "npy_array_list.h"
170+
int main(int argc, char *argv[])
171+
{
172+
if( argc != 2 ) return -1;
173+
double data[] = {0,1,2,3,4,5};
174+
npy_array_list_t* list = NULL;
175+
list = npy_array_list_append( list, NPY_ARRAY_ALLOCATOR(data, SHAPE(3,2), NPY_DTYPE_FLOAT64), "matrix" );
176+
list = npy_array_list_append( list, NPY_ARRAY_ALLOCATOR(data, SHAPE(2,1,2), NPY_DTYPE_FLOAT64), "tensor" );
177+
npy_array_list_save_compressed( argv[1], list, ZIP_CM_DEFAULT, 0 );
178+
npy_array_list_free( list );
179+
}
180+
159181
## Saving other arraylike data as _NumPy_ format.
160182
You may have a pointer to an N-dimensional array, which you want to store as NumPy format, such
161183
that you can load it in Python/Jupiter and plot in matplotlib or whatever you find more

npy_array.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4545
#include <ctype.h>
4646
#include <assert.h>
4747

48-
#define NPY_ARRAY_MAGIC_STRING {0x93,'N','U','M','P','Y'}
48+
#define NPY_ARRAY_MAGIC_STRING {-109,'N','U','M','P','Y'}
4949
#define NPY_ARRAY_MAJOR_VERSION_IDX 6
5050
#define NPY_ARRAY_MINOR_VERSION_IDX 7
5151

@@ -397,3 +397,24 @@ void npy_array_free( npy_array_t *m )
397397

398398
free( m );
399399
}
400+
401+
#define MIN( x, y ) ((x) < (y) ? (x) : (y))
402+
npy_array_t* npy_array_deepcopy( const npy_array_t* m ) {
403+
npy_array_t* ary = calloc( 1, sizeof(*ary) );
404+
if (!ary) {
405+
fprintf(stderr, "Cannot allocate data structure!\n");
406+
return NULL;
407+
}
408+
ary->ndim = MIN( m->ndim, NPY_ARRAY_MAX_DIMENSIONS );
409+
memcpy( ary->shape, m->shape, sizeof(ary->shape) );
410+
ary->typechar = m->typechar;
411+
ary->elem_size = m->elem_size;
412+
ary->data = malloc( npy_array_calculate_datasize(ary) );
413+
if (!ary->data) {
414+
fprintf(stderr, "Cannot allocate memory!\n");
415+
free(ary);
416+
return NULL;
417+
}
418+
memcpy( ary->data, m->data, npy_array_calculate_datasize(ary) );
419+
return ary;
420+
}

npy_array.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ typedef struct _npy_array_t {
6060

6161
npy_array_t* npy_array_load ( const char *filename );
6262
npy_array_t* npy_array_mmap ( const char *filename );
63+
npy_array_t* npy_array_deepcopy ( const npy_array_t *m );
6364
void npy_array_dump ( const npy_array_t *m );
6465
void npy_array_save ( const char *filename, const npy_array_t *m );
6566
void npy_array_free ( npy_array_t *m );
@@ -86,6 +87,8 @@ npy_array_t * _read_matrix( void *fp, reader_func read_func );
8687
#define SHAPE(...) .shape = {__VA_ARGS__}, .ndim = _NARG(__VA_ARGS__)
8788
#define NPY_ARRAY_BUILDER(_data,_shape,...) \
8889
&(npy_array_t){ .data=(char*)_data, _shape, __VA_ARGS__ }
90+
#define NPY_ARRAY_ALLOCATOR(...) \
91+
npy_array_deepcopy(NPY_ARRAY_BUILDER(__VA_ARGS__))
8992

9093
#define NPY_DTYPE_FLOAT16 .typechar='f', .elem_size=2
9194
#define NPY_DTYPE_FLOAT32 .typechar='f', .elem_size=4

0 commit comments

Comments
 (0)