Skip to content

Commit

Permalink
feat: add macros for 1d and 2d ndarray
Browse files Browse the repository at this point in the history
  • Loading branch information
Jaysukh-409 committed Sep 30, 2024
1 parent 4eeeb46 commit 4e40c79
Show file tree
Hide file tree
Showing 61 changed files with 1,862 additions and 1,210 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/**
* @license Apache-2.0
*
* Copyright (c) 2024 The Stdlib Authors.
*
* Licensed 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.
*/

#ifndef STDLIB_NDARRAY_BASE_MSKFILTER_MACROS_1D_H
#define STDLIB_NDARRAY_BASE_MSKFILTER_MACROS_1D_H

#include "stdlib/ndarray/ctor.h"
#include <stdint.h>

/**
* Macro containing the preamble for a loop which operates on elements of a one-dimensional ndarray, with a mask array.
*
* ## Notes
*
* - Variable naming conventions:
*
* - `sx#`, `px#`, and `d@x#` where `#` corresponds to the ndarray argument number, starting at `1`.
* - `S@`, `i@`, and `d@x#` where `@` corresponds to the loop number, with `0` being the innermost loop.
*
* @example
* STDLIB_NDARRAY_MSKFILTER_1D_LOOP_PREMABLE {
* // Innermost loop body...
* }
* STDLIB_NDARRAY_MSKFILTER_1D_LOOP_EPILOGUE
*/
#define STDLIB_NDARRAY_MSKFILTER_1D_LOOP_PREAMBLE \
struct ndarray *x1 = arrays[ 0 ]; \
struct ndarray *x2 = arrays[ 1 ]; \
struct ndarray *x3 = arrays[ 2 ]; \
int64_t *shx1 = stdlib_ndarray_shape( x1 ); \
int64_t *shx3 = stdlib_ndarray_shape( x3 ); \
int64_t *sx1 = stdlib_ndarray_strides( x1 ); \
int64_t *sx2 = stdlib_ndarray_strides( x2 ); \
int64_t *sx3 = stdlib_ndarray_strides( x3 ); \
uint8_t *px1 = stdlib_ndarray_data( x1 ); \
uint8_t *px2 = stdlib_ndarray_data( x2 ); \
uint8_t *px3 = stdlib_ndarray_data( x3 ); \
int64_t d0x1; \
int64_t d0x2; \
int64_t d0x3; \
int64_t S0; \
int64_t i0; \
/* Extract loop variables: dimensions and loop offset (pointer) increments... */ \
S0 = shx1[ 0 ]; \
d0x1 = sx1[ 0 ]; \
d0x2 = sx2[ 0 ]; \
d0x3 = sx3[ 0 ]; \
/* Set the pointers to the first indexed elements... */ \
px1 += stdlib_ndarray_offset( x1 ); \
px2 += stdlib_ndarray_offset( x2 ); \
px3 += stdlib_ndarray_offset( x3 ); \
/* Iterate over the ndarray dimensions... */ \
for ( i0 = 0; i0 < S0; i0++, px1 += d0x1, px2 += d0x2 )

/**
* Macro containing the epilogue for loops which operate on elements of a one-dimensional ndarray with a mask.
*
* @example
* STDLIB_NDARRAY_MSKFILTER_1D_LOOP_PREMABLE {
* // Innermost loop body...
* }
* STDLIB_NDARRAY_MSKFILTER_1D_LOOP_EPILOGUE
*/
#define STDLIB_NDARRAY_MSKFILTER_1D_LOOP_EPILOGUE

/**
* Macro for a unary one-dimensional ndarray loop which applies mask and cast input ndarray elements and assigns unmasked values to an output ndarray.
*
* ## Notes
*
* - Retrieves each ndarray element according to type `tin` via the pointer `px1`.
* - Retrieves a mask element according to type `uint8_t` via the pointer `px2`.
* - If the mask element is truthy then explicitly casts the ndarray element to `tout`.
* - Stores the result in an output ndarray via the pointer `px3`.
*
* @param tin input type
* @param tout output type
*
* @example
* // e.g., d_d
* STDLIB_NDARRAY_MSKFILTER_1D_LOOP_CAST( double, double )
*/
#define STDLIB_NDARRAY_MSKFILTER_1D_LOOP_CAST( tin, tout ) \
STDLIB_NDARRAY_MSKFILTER_1D_LOOP_PREAMBLE { \
if ( *(uint8_t *)px2 ) { \
const tin x = *(tin *)px1; \
*(tout *)px3 = (tout)x; \
px3 += d0x3; \
} \
} \
STDLIB_NDARRAY_MSKFILTER_1D_LOOP_EPILOGUE

/**
* Macro for a unary one-dimensional ndarray loop which applies mask and does not cast input ndarray elements and assigns unmasked values to an output ndarray.
*
* ## Notes
*
* - Retrieves each ndarray element according to type `tin` via the pointer `px1`.
* - Retrieves a mask element according to type `uint8_t` via the pointer `px2`.
* - If the mask element is truthy then stores the ndarray element in an output ndarray of type `tout` via the pointer `px3`.
*
* @param tin input type
* @param tout output type
*
* @example
* #include "stdlib/complex/float64/ctor.h"
*
* // e.g., z_z
* STDLIB_NDARRAY_ASSIGN_1D_LOOP_NOCAST( stdlib_complex128_t, stdlib_complex128_t )
*/
#define STDLIB_NDARRAY_MSKFILTER_1D_LOOP_NOCAST( tin, tout ) \
STDLIB_NDARRAY_MSKFILTER_1D_LOOP_PREAMBLE { \
if ( *(uint8_t *)px2 ) { \
const tin x = *(tin *)px1; \
*(tout *)px3 = x; \
px3 += d0x3; \
} \
} \
STDLIB_NDARRAY_MSKFILTER_1D_LOOP_EPILOGUE

#endif // !STDLIB_NDARRAY_BASE_MSKFILTER_MACROS_1D_H
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/**
* @license Apache-2.0
*
* Copyright (c) 2024 The Stdlib Authors.
*
* Licensed 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.
*/

#ifndef STDLIB_NDARRAY_BASE_MSKFILTER_MACROS_2D_H
#define STDLIB_NDARRAY_BASE_MSKFILTER_MACROS_2D_H

#include "stdlib/ndarray/ctor.h"
#include "stdlib/ndarray/orders.h"
#include <stdint.h>

/**
* Macro containing the preamble for a loop which operates on elements of a two-dimensional ndarray, with a mask array.
*
* ## Notes
*
* - Variable naming conventions:
*
* - `sx#`, `px#`, and `d@x#` where `#` corresponds to the ndarray argument number, starting at `1`.
* - `S@`, `i@`, and `d@x#` where `@` corresponds to the loop number, with `0` being the innermost loop.
*
* @example
* STDLIB_NDARRAY_MSKFILTER_2D_LOOP_PREMABLE {
* // Innermost loop body...
* }
* STDLIB_NDARRAY_MSKFILTER_2D_LOOP_EPILOGUE
*/
#define STDLIB_NDARRAY_MSKFILTER_2D_LOOP_PREAMBLE \
struct ndarray *x1 = arrays[ 0 ]; \
struct ndarray *x2 = arrays[ 1 ]; \
struct ndarray *x3 = arrays[ 2 ]; \
int64_t *shx1 = stdlib_ndarray_shape( x1 ); \
int64_t *shx3 = stdlib_ndarray_shape( x3 ); \
int64_t *sx1 = stdlib_ndarray_strides( x1 ); \
int64_t *sx2 = stdlib_ndarray_strides( x2 ); \
int64_t *sx3 = stdlib_ndarray_strides( x3 ); \
uint8_t *px1 = stdlib_ndarray_data( x1 ); \
uint8_t *px2 = stdlib_ndarray_data( x2 ); \
uint8_t *px3 = stdlib_ndarray_data( x3 ); \
int64_t d0x1; \
int64_t d1x1; \
int64_t d0x2; \
int64_t d1x2; \
int64_t d0x3; \
int64_t S0; \
int64_t S1; \
int64_t i0; \
int64_t i1; \
/* Extract loop variables for purposes of loop interchange: dimensions and loop offset (pointer) increments... */ \
if ( stdlib_ndarray_order( x1 ) == STDLIB_NDARRAY_ROW_MAJOR ) { \
/* For row-major ndarrays, the last dimensions have the fastest changing indices... */ \
S0 = shx1[ 1 ]; \
S1 = shx1[ 0 ]; \
d0x1 = sx1[ 1 ]; \
d1x1 = sx1[ 0 ] - ( S0*sx1[1] ); \
d0x2 = sx2[ 1 ]; \
d1x2 = sx2[ 0 ] - ( S0*sx2[1] ); \
} else { \
/* For column-major ndarrays, the first dimensions have the fastest changing indices... */ \
S0 = shx1[ 0 ]; \
S1 = shx1[ 1 ]; \
d0x1 = sx1[ 0 ]; \
d1x1 = sx1[ 1 ] - ( S0*sx1[0] ); \
d0x2 = sx2[ 0 ]; \
d1x2 = sx2[ 1 ] - ( S0*sx2[0] ); \
} \
d0x3 = sx3[ 0 ]; \
/* Set the pointers to the first indexed elements... */ \
px1 += stdlib_ndarray_offset( x1 ); \
px2 += stdlib_ndarray_offset( x2 ); \
px3 += stdlib_ndarray_offset( x3 ); \
/* Iterate over the ndarray dimensions... */ \
for ( i1 = 0; i1 < S1; i1++, px1 += d1x1, px2 += d1x2 ) { \
for ( i0 = 0; i0 < S0; i0++, px1 += d0x1, px2 += d0x2 )

/**
* Macro containing the epilogue for loops which operate on elements of a two-dimensional ndarray with a mask.
*
* @example
* STDLIB_NDARRAY_MSKFILTER_2D_LOOP_PREMABLE {
* // Innermost loop body...
* }
* STDLIB_NDARRAY_MSKFILTER_2D_LOOP_EPILOGUE
*/
#define STDLIB_NDARRAY_MSKFILTER_2D_LOOP_EPILOGUE \
}

/**
* Macro for a unary two-dimensional ndarray loop which applies mask and cast input ndarray elements and assigns unmasked values to an output ndarray.
*
* ## Notes
*
* - Retrieves each ndarray element according to type `tin` via the pointer `px1`.
* - Retrieves a mask element according to type `uint8_t` via the pointer `px2`.
* - If the mask element is truthy then explicitly casts the ndarray element to `tout`.
* - Stores the result in an output ndarray via the pointer `px3`.
*
* @param tin input type
* @param tout output type
*
* @example
* // e.g., d_d
* STDLIB_NDARRAY_MSKFILTER_2D_LOOP_CAST( double, double )
*/
#define STDLIB_NDARRAY_MSKFILTER_2D_LOOP_CAST( tin, tout ) \
STDLIB_NDARRAY_MSKFILTER_2D_LOOP_PREAMBLE { \
if ( *(uint8_t *)px2 ) { \
const tin x = *(tin *)px1; \
*(tout *)px3 = (tout)x; \
px3 += d0x3; \
} \
} \
STDLIB_NDARRAY_MSKFILTER_2D_LOOP_EPILOGUE

/**
* Macro for a unary one-dimensional ndarray loop which applies mask and does not cast input ndarray elements and assigns unmasked values to an output ndarray.
*
* ## Notes
*
* - Retrieves each ndarray element according to type `tin` via the pointer `px1`.
* - Retrieves a mask element according to type `uint8_t` via the pointer `px2`.
* - If the mask element is truthy then stores the ndarray element in an output ndarray of type `tout` via the pointer `px3`.
*
* @param tin input type
* @param tout output type
*
* @example
* #include "stdlib/complex/float64/ctor.h"
*
* // e.g., z_z
* STDLIB_NDARRAY_MSKFILTER_2D_LOOP_NOCAST( stdlib_complex128_t, stdlib_complex128_t )
*/
#define STDLIB_NDARRAY_MSKFILTER_2D_LOOP_NOCAST( tin, tout ) \
STDLIB_NDARRAY_MSKFILTER_2D_LOOP_PREAMBLE { \
if ( *(uint8_t *)px2 ) { \
const tin x = *(tin *)px1; \
*(tout *)px3 = x; \
px3 += d0x3; \
} \
} \
STDLIB_NDARRAY_MSKFILTER_2D_LOOP_EPILOGUE

#endif // !STDLIB_NDARRAY_BASE_MSKFILTER_MACROS_2D_H
Loading

0 comments on commit 4e40c79

Please sign in to comment.