Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add b2nd_nans method #624 #625

Merged
merged 1 commit into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions blosc/b2nd.c
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,23 @@ int b2nd_zeros(b2nd_context_t *ctx, b2nd_array_t **array) {
}


int b2nd_nans(b2nd_context_t *ctx, b2nd_array_t **array) {
BLOSC_ERROR_NULL(ctx, BLOSC2_ERROR_NULL_POINTER);
BLOSC_ERROR_NULL(array, BLOSC2_ERROR_NULL_POINTER);

BLOSC_ERROR(array_new(ctx, BLOSC2_SPECIAL_NAN, array));

const int32_t typesize = (*array)->sc->typesize;
if (typesize != 4 && typesize != 8)
{
BLOSC_TRACE_ERROR("Unsupported typesize for NaN");
return BLOSC2_ERROR_DATA;
}

return BLOSC2_ERROR_SUCCESS;
}


int b2nd_full(b2nd_context_t *ctx, b2nd_array_t **array, const void *fill_value) {
BLOSC_ERROR_NULL(ctx, BLOSC2_ERROR_NULL_POINTER);
BLOSC_ERROR_NULL(array, BLOSC2_ERROR_NULL_POINTER);
Expand Down
1 change: 1 addition & 0 deletions doc/reference/b2nd.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ Constructors
.. doxygenfunction:: b2nd_uninit
.. doxygenfunction:: b2nd_empty
.. doxygenfunction:: b2nd_zeros
.. doxygenfunction:: b2nd_nans
.. doxygenfunction:: b2nd_full

From/To buffer
Expand Down
13 changes: 13 additions & 0 deletions include/b2nd.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,19 @@ BLOSC_EXPORT int b2nd_empty(b2nd_context_t *ctx, b2nd_array_t **array);
BLOSC_EXPORT int b2nd_zeros(b2nd_context_t *ctx, b2nd_array_t **array);


/**
* Create an array, with NaN being used as the default value for
* uninitialized portions of the array. Should only be used with type sizes
* of either 4 or 8. Other sizes generate an error.
*
* @param ctx The b2nd context for the new array.
* @param array The memory pointer where the array will be created.
*
* @return An error code.
*/
BLOSC_EXPORT int b2nd_nans(b2nd_context_t *ctx, b2nd_array_t **array);


/**
* Create an array, with @p fill_value being used as the default value for
* uninitialized portions of the array.
Expand Down
105 changes: 105 additions & 0 deletions tests/b2nd/test_b2nd_nans.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*********************************************************************
Blosc - Blocked Shuffling and Compression Library

Copyright (c) 2021 Blosc Development Team <[email protected]>
https://blosc.org
License: BSD 3-Clause (see LICENSE.txt)

See LICENSE.txt for details about copyright and rights to use.
**********************************************************************/

#include "test_common.h"
#include <math.h>

CUTEST_TEST_SETUP(nans) {
blosc2_init();

// Add parametrizations
CUTEST_PARAMETRIZE(typesize, uint8_t, CUTEST_DATA(
4, 8
));
CUTEST_PARAMETRIZE(shapes, _test_shapes, CUTEST_DATA(
{0, {0}, {0}, {0}}, // 0-dim
{1, {5}, {3}, {2}}, // 1-idim
{2, {20, 0}, {7, 0}, {3, 0}}, // 0-shape
{2, {20, 10}, {7, 5}, {3, 5}}, // 0-shape
{2, {14, 10}, {8, 5}, {2, 2}}, // general,
{3, {12, 10, 14}, {3, 5, 9}, {3, 4, 4}}, // general
{3, {10, 21, 30, 55}, {8, 7, 15, 3}, {5, 5, 10, 1}}, // general,
));
CUTEST_PARAMETRIZE(backend, _test_backend, CUTEST_DATA(
{false, false},
{true, false},
{true, true},
{false, true},
));
}


CUTEST_TEST_TEST(nans) {
CUTEST_GET_PARAMETER(backend, _test_backend);
CUTEST_GET_PARAMETER(shapes, _test_shapes);
CUTEST_GET_PARAMETER(typesize, uint8_t);

char *urlpath = "test_nans.b2frame";
blosc2_remove_urlpath(urlpath);

blosc2_cparams cparams = BLOSC2_CPARAMS_DEFAULTS;
cparams.nthreads = 2;
cparams.typesize = typesize;
blosc2_storage b2_storage = {.cparams=&cparams};
if (backend.persistent) {
b2_storage.urlpath = urlpath;
}
b2_storage.contiguous = backend.contiguous;

b2nd_context_t *ctx = b2nd_create_ctx(&b2_storage, shapes.ndim, shapes.shape,
shapes.chunkshape, shapes.blockshape, NULL, 0, NULL, 0);

/* Create original data */
int64_t buffersize = typesize;
for (int i = 0; i < shapes.ndim; ++i) {
buffersize *= shapes.shape[i];
}

/* Create b2nd_array_t with original data */
b2nd_array_t *src;
B2ND_TEST_ASSERT(b2nd_nans(ctx, &src));

/* Fill dest array with b2nd_array_t data */
uint8_t *buffer_dest = malloc(buffersize);
B2ND_TEST_ASSERT(b2nd_to_cbuffer(src, buffer_dest, buffersize));

/* Testing */
for (int i = 0; i < buffersize / typesize; ++i) {
bool is_true = false;
switch (typesize) {
case 8:
is_true = isnan(((double *) buffer_dest)[i]);
break;
case 4:
is_true = isnan(((float *) buffer_dest)[i]);
break;
default:
break;
}
CUTEST_ASSERT("Elements are not equals", is_true);
}

/* Free mallocs */
free(buffer_dest);
B2ND_TEST_ASSERT(b2nd_free(src));
B2ND_TEST_ASSERT(b2nd_free_ctx(ctx));
blosc2_remove_urlpath(urlpath);

return BLOSC2_ERROR_SUCCESS;
}


CUTEST_TEST_TEARDOWN(nans) {
blosc2_destroy();
}

int main() {
CUTEST_TEST_RUN(nans);
}