time-to-botec

Benchmark sampling in different programming languages
Log | Files | Refs | README

iget_ptr.c (3327B)


      1 /**
      2 * @license Apache-2.0
      3 *
      4 * Copyright (c) 2018 The Stdlib Authors.
      5 *
      6 * Licensed under the Apache License, Version 2.0 (the "License");
      7 * you may not use this file except in compliance with the License.
      8 * You may obtain a copy of the License at
      9 *
     10 *    http://www.apache.org/licenses/LICENSE-2.0
     11 *
     12 * Unless required by applicable law or agreed to in writing, software
     13 * distributed under the License is distributed on an "AS IS" BASIS,
     14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15 * See the License for the specific language governing permissions and
     16 * limitations under the License.
     17 */
     18 
     19 #include "stdlib/ndarray/ctor/iget_ptr.h"
     20 #include "stdlib/ndarray/ctor/ndarray.h"
     21 #include "stdlib/ndarray/ctor/macros.h"
     22 #include "stdlib/ndarray/orders.h"
     23 #include "stdlib/ndarray/base/bytes_per_element.h"
     24 #include "stdlib/ndarray/base/ind.h"
     25 #include "stdlib/ndarray/base/iteration_order.h"
     26 #include <stdlib.h>
     27 #include <stdint.h>
     28 
     29 /**
     30 * Returns a pointer in the underlying byte array for an ndarray data element located at a specified linear index.
     31 *
     32 * ## Notes
     33 *
     34 * -   For zero-dimensional arrays, the function returns a pointer to the first (and only) indexed element, regardless of the value of `idx`.
     35 *
     36 * @param arr  input ndarray
     37 * @param idx  linear view index
     38 * @return     underlying byte array pointer
     39 */
     40 uint8_t * stdlib_ndarray_iget_ptr( const struct ndarray *arr, const int64_t idx ) {
     41 	int64_t *strides;
     42 	int64_t *shape;
     43 	int64_t ndims;
     44 	uint8_t *ind;
     45 	int64_t s;
     46 	int64_t i;
     47 	int64_t j;
     48 	int8_t io;
     49 
     50 	// Retrieve the number of dimensions
     51 	ndims = arr->ndims;
     52 
     53 	// For zero-dimensional ndarrays, we ignore the index argument and return a pointer to the first (and only) indexed element...
     54 	if ( ndims == 0 ) {
     55 		return (arr->data) + (arr->offset); // pointer arithmetic
     56 	}
     57 	// Copy index argument to a mutable variable:
     58 	j = idx;
     59 
     60 	// Resolve an ndarray index based on the ndarray index mode:
     61 	j = stdlib_ndarray_ind( j, (arr->length)-1, arr->imode );
     62 	if ( j < 0 ) {
     63 		return NULL;
     64 	}
     65 	// Determine the pointer to the first indexed element:
     66 	ind = (arr->data) + (arr->offset); // pointer arithmetic
     67 
     68 	// Determine the iteration order based on the ndarray strides:
     69 	strides = arr->strides;
     70 	io = stdlib_ndarray_iteration_order( ndims, strides );
     71 
     72 	// Check for trivial case...
     73 	if ( (arr->flags) & (STDLIB_NDARRAY_ROW_MAJOR_CONTIGUOUS_FLAG | STDLIB_NDARRAY_COLUMN_MAJOR_CONTIGUOUS_FLAG) ) {
     74 		// Trivial case where we have all positive strides...
     75 		if ( io == 1 ) {
     76 			return ind + (j*(arr->BYTES_PER_ELEMENT)); // pointer arithmetic
     77 		}
     78 		// Trivial case where we have all negative strides...
     79 		if ( io == -1 ) {
     80 			return ind - (j*(arr->BYTES_PER_ELEMENT)); // pointer arithmetic
     81 		}
     82 	}
     83 	// The approach which follows is to resolve a view index to its subscripts and then plug the subscripts into the standard formula for computing the linear index in the underlying byte array...
     84 	shape = arr->shape;
     85 	if ( (arr->order) == STDLIB_NDARRAY_COLUMN_MAJOR ) {
     86 		for ( i = 0; i < ndims; i++ ) {
     87 			s = j % shape[ i ];
     88 			j -= s;
     89 			j /= shape[ i ];
     90 			ind += s * strides[ i ]; // pointer arithmetic
     91 		}
     92 		return ind;
     93 	}
     94 	// Case: row-major
     95 	for ( i = ndims-1; i >= 0; i-- ) {
     96 		s = j % shape[ i ];
     97 		j -= s;
     98 		j /= shape[ i ];
     99 		ind += s * strides[ i ]; // pointer arithmetic
    100 	}
    101 	return ind;
    102 }