File: addon.cpp

package info (click to toggle)
node-stdlib 0.0.96%2Bds1%2B~cs0.0.429-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 421,476 kB
  • sloc: javascript: 1,562,831; ansic: 109,702; lisp: 49,823; cpp: 27,224; python: 7,871; sh: 6,807; makefile: 6,089; fortran: 3,102; awk: 387
file content (192 lines) | stat: -rw-r--r-- 5,580 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/**
* @license Apache-2.0
*
* Copyright (c) 2018 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.
*/

#include "stdlib/strided/base/binary.h"
#include "stdlib/strided/base/function_object.h"
#include "stdlib/strided/napi/addon_arguments.h"
#include "stdlib/strided/dtypes.h"
#include <node_api.h>
#include <stdint.h>
#include <assert.h>

/**
* Adds two doubles.
*
* @private
* @param x  first double
* @param y  second double
* @return   sum
*/
static double add( double x, double y ) {
	return x + y;
}

/**
* Adds two floats.
*
* @private
* @param x  first float
* @param y  second float
* @return   sum
*/
static float addf( float x, float y ) {
	return x + y;
}

// Define a binary strided array interface name:
static const char name[] = "binary_strided_array_function_add";

// Define a list of strided array functions:
static StridedArrayFcn functions[] = {
	stdlib_strided_dd_d,
	stdlib_strided_ff_f
};

// Define the **strided array** argument types for each strided array function:
static int32_t types[] = {
	STDLIB_STRIDED_FLOAT64, STDLIB_STRIDED_FLOAT64, STDLIB_STRIDED_FLOAT64,
	STDLIB_STRIDED_FLOAT32, STDLIB_STRIDED_FLOAT32, STDLIB_STRIDED_FLOAT32
};

// Define a list of strided array function "data" (in this case, callbacks):
static void *data[] = {
	(void *)add,
	(void *)addf
};

// Create a strided array function object:
static const struct StridedFunctionObject obj = {
	// Strided array function name:
	name,

	// Number of input strided arrays:
	2,

	// Number of output strided arrays:
	1,

	// Total number of strided array arguments (nin + nout):
	3,

	// Array containing strided array functions:
	functions,

	// Number of strided array functions:
	2,

	// Array of type "numbers" (as enumerated elsewhere), where the total number of types equals `narrays * nfunctions` and where each set of `narrays` consecutive types (non-overlapping) corresponds to the set of strided array argument types for a corresponding strided array function:
	types,

	// Array of void pointers corresponding to the "data" (e.g., callbacks) which should be passed to a respective strided array function (note: the number of pointers should match the number of strided array functions):
	data
};

// Define a pointer to the strided function object:
static const struct StridedFunctionObject *optr = &obj;

/**
* Add-on namespace.
*/
namespace addon_strided_add {

	/**
	* Adds each element in `X` to a corresponding element in `Y` and assigns the result to an element in `Z`.
	*
	* ## Notes
	*
	* -   When called from JavaScript, the function expects the following arguments:
	*
	*     -   `N`: number of indexed elements
	*     -   `X`: input array
	*     -   `strideX`: `X` stride length
	*     -   `Y`: input array
	*     -   `strideY`: `Y` stride length
	*     -   `Z`: destination array
	*     -   `strideZ`: `Z` stride length
	*/
	napi_value node_add( napi_env env, napi_callback_info info ) {
		napi_status status;

		// Total number of input arguments:
		int64_t nargs = 7;

		// Number of input strided array arguments:
		int64_t nin = 2;

		// Get callback arguments:
		size_t argc = 7;
		napi_value argv[ 7 ];
		status = napi_get_cb_info( env, info, &argc, argv, nullptr, nullptr );
		assert( status == napi_ok );

		// Check whether we were provided the correct number of arguments:
		int64_t argc64 = (int64_t)argc;
		if ( argc64 < nargs ) {
			napi_throw_error( env, nullptr, "invalid invocation. Insufficient arguments." );
			return nullptr;
		}
		if ( argc64 > nargs ) {
			napi_throw_error( env, nullptr, "invalid invocation. Too many arguments." );
			return nullptr;
		}
		// Process the provided arguments:
		uint8_t *arrays[ 3 ];
		int64_t strides[ 3 ];
		int64_t shape[ 1 ];
		int32_t types[ 3 ];

		napi_value err;
		status = stdlib_strided_napi_addon_arguments( env, argv, nargs, nin, arrays, shape, strides, types, &err );
		assert( status == napi_ok );

		// Check whether processing was successful:
		if ( err != NULL ) {
			status = napi_throw( env, err );
			assert( status == napi_ok );
			return nullptr;
		}
		// Resolve the strided array function satisfying the input array types:
		int64_t idx = stdlib_strided_function_dispatch_index_of( optr, types );

		// Check whether we were able to successfully resolve a strided array function:
		if ( idx < 0 ) {
			napi_throw_error( env, nullptr, "invalid arguments. Unable to resolve a strided array function supporting the provided array argument data types." );
			return nullptr;
		}
		// Retrieve the strided array function:
		StridedArrayFcn fcn = optr->functions[ idx ];

		// Retrieve the associated function data:
		void *clbk = optr->data[ idx ];

		// Evaluate the strided array function:
		fcn( arrays, shape, strides, clbk );

		return nullptr;
	}

	napi_value Init( napi_env env, napi_value exports ) {
		napi_status status;
		napi_value fcn;
		status = napi_create_function( env, "exports", NAPI_AUTO_LENGTH, node_add, NULL, &fcn );
		assert( status == napi_ok );
		return fcn;
	}

	NAPI_MODULE( NODE_GYP_MODULE_NAME, Init )
} // end namespace addon_strided_add