Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
eabb66a
Initial version
rahur-NI Mar 18, 2026
8bbb854
Enabling grpc for nirfsg
rahur-NI Mar 18, 2026
2769be2
Merge remote-tracking branch 'origin' into nirfsgGrpcEnable
rahur-NI Mar 18, 2026
0d0e209
Updated change log
rahur-NI Mar 18, 2026
89c16cc
nirfsg grpc enable
rahur-NI Mar 20, 2026
fd619a3
With default template update
rahur-NI Mar 20, 2026
86fde87
SIngle template changes
rahur-NI Mar 20, 2026
ffced12
Updated version of numpy template
rahur-NI Mar 22, 2026
b98dcfb
Updating generate temply for numpy_write_method
rahur-NI Mar 23, 2026
d69e843
updating numpy read template instead of write template.
rahur-NI Mar 23, 2026
cd63014
Updated read method
rahur-NI Mar 23, 2026
104ab97
With nifake changes
rahur-NI Mar 23, 2026
5af2c2d
Updated template to use helper methods
rahur-NI Mar 23, 2026
cf39c3b
Updated with proto changes
rahur-NI Mar 23, 2026
66d41ad
Remove log file
rahur-NI Mar 23, 2026
4804429
Merge branch 'master' into nirfsgGrpcComplexNumberSupport
rahur-NI Mar 23, 2026
e2964b7
Code refractoring for template.
rahur-NI Mar 23, 2026
544dcdd
Updated with code review comments
rahur-NI Mar 24, 2026
9033a52
Including more verbose output to check on system test failure
rahur-NI Mar 27, 2026
097a731
Reverting verbose log change of nirfsg system test and moving the tes…
rahur-NI Mar 27, 2026
d6e6f18
Implementation of code review comments.
rahur-NI Mar 27, 2026
1898173
Updating comment for newly added test cases
rahur-NI Mar 27, 2026
feb959a
Updatig with geerated Tox executio
rahur-NI Mar 29, 2026
bbecc5f
System Test failure on 32 bit debug
rahur-NI Mar 30, 2026
a81a954
Reverting the advanced logging mechanism during system tests.
rahur-NI Mar 30, 2026
0217316
Changing order of TestLibrary and TestGrpc classes
rahur-NI Mar 30, 2026
799b901
Skip gRPC tests on 32-bit systems to prevent timeout
rahur-NI Mar 30, 2026
968177c
Revert "Skip gRPC tests on 32-bit systems to prevent timeout"
rahur-NI Mar 30, 2026
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
4 changes: 4 additions & 0 deletions build/templates/_grpc_stub_interpreter.py.mako
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module_name = config['module_name']
proto_name = config.get('proto_name', module_name)
service_class_prefix = config['grpc_service_class_prefix']
functions = helper.filter_codegen_functions(config['functions'])
are_complex_parameters_used = helper.are_complex_parameters_used(functions)
%>\

import grpc
Expand All @@ -19,6 +20,9 @@ import warnings
from . import enums as enums # noqa: F401
% endif
from . import errors as errors
% if are_complex_parameters_used:
from . import nidevice_pb2 as grpc_complex_types # noqa: F401
% endif
from . import ${proto_name}_pb2 as grpc_types
from . import ${proto_name}_pb2_grpc as ${module_name}_grpc
from . import session_pb2 as session_grpc_types
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,62 @@
<%page args="f, config, method_template"/>\
## numpy_read and numpy_write are identical for gRPC -- both return a NotImplementedError
<%include file="/_grpc_stub_interpreter.py/numpy_read_method.py.mako" args="f=f, config=config, method_template=method_template" />\
<%
'''Renders a GrpcStubInterpreter method for numpy write operations with complex number support.'''

import build.helper as helper

full_func_name = f['interpreter_name'] + method_template['method_python_name_suffix']
method_decl_params = helper.get_params_snippet(f, helper.ParameterUsageOptions.INTERPRETER_METHOD_DECLARATION)
grpc_name = f.get('grpc_name', f['name'])
grpc_request_args = helper.get_params_snippet(f, helper.ParameterUsageOptions.GRPC_REQUEST_PARAMETERS)
return_statement = helper.get_grpc_interpreter_method_return_snippet(f['parameters'], config)
if return_statement == 'return':
return_statement = None
capture_response = 'response = ' if return_statement else ''
included_in_proto = f.get('included_in_proto', True)
numpy_complex_params = helper.filter_parameters(f['parameters'], helper.ParameterUsageOptions.COMPLEX_NUMBER_PARAMETERS)
for param in numpy_complex_params:
grpc_request_args = grpc_request_args.replace(
param['grpc_name'] + '=' + param['python_name'],
param['grpc_name'] + '=' + param['python_name'] + '_list'
)
%>\

def ${full_func_name}(${method_decl_params}): # noqa: N802
% if included_in_proto:
% if numpy_complex_params:
# Use ravel() so that gRPC always receives a flat numpy array, regardless of input dimensions.
% for param in numpy_complex_params:
% if param['original_type'] == 'NIComplexNumber[]':
${param['python_name']}_list = [
grpc_complex_types.NIComplexNumber(real=val.real, imaginary=val.imag)
for val in ${param['python_name']}.ravel()
]
% elif param['original_type'] == 'NIComplexNumberF32[]':
${param['python_name']}_list = [
grpc_complex_types.NIComplexNumberF32(real=val.real, imaginary=val.imag)
for val in ${param['python_name']}.ravel()
]
% elif param['original_type'] == 'NIComplexI16[]':
arr = ${param['python_name']}.ravel()
if arr.size % 2 != 0:
raise ValueError("Interleaved int16 array must have even length (real/imag pairs)")
arr_pairs = arr.reshape(-1, 2)
${param['python_name']}_list = [
grpc_complex_types.NIComplexI16(real=int(pair[0]), imaginary=int(pair[1]))
for pair in arr_pairs
]
% endif
% endfor
${capture_response}self._invoke(
self._client.${grpc_name},
grpc_types.${grpc_name}Request(${grpc_request_args}),
)
% if return_statement:
${return_statement}
% endif
% else:
raise NotImplementedError('numpy-specific methods are not supported over gRPC')
% endif
% else:
raise NotImplementedError('${full_func_name} is not supported over gRPC')
% endif
45 changes: 41 additions & 4 deletions generated/nifake/nifake/_grpc_stub_interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from . import enums as enums # noqa: F401
from . import errors as errors
from . import nidevice_pb2 as grpc_complex_types # noqa: F401
from . import nifake_pb2 as grpc_types
from . import nifake_pb2_grpc as nifake_grpc
from . import session_pb2 as session_grpc_types
Expand Down Expand Up @@ -145,7 +146,15 @@ def fetch_waveform_into(self, number_of_samples): # noqa: N802
raise NotImplementedError('numpy-specific methods are not supported over gRPC')

def function_with_3d_numpy_array_of_numpy_complex128_input_parameter(self, multidimensional_array): # noqa: N802
raise NotImplementedError('numpy-specific methods are not supported over gRPC')
# Use ravel() so that gRPC always receives a flat numpy array, regardless of input dimensions.
multidimensional_array_list = [
grpc_complex_types.NIComplexNumber(real=val.real, imaginary=val.imag)
for val in multidimensional_array.ravel()
]
self._invoke(
self._client.FunctionWith3dNumpyArrayOfNumpyComplex128InputParameter,
grpc_types.FunctionWith3dNumpyArrayOfNumpyComplex128InputParameterRequest(vi=self._vi, multidimensional_array=multidimensional_array_list),
)

def function_with_intflag_parameter(self, flag): # noqa: N802
self._invoke(
Expand Down Expand Up @@ -512,13 +521,41 @@ def write_waveform_numpy(self, waveform): # noqa: N802
raise NotImplementedError('numpy-specific methods are not supported over gRPC')

def write_waveform_numpy_complex128(self, waveform_data_array): # noqa: N802
raise NotImplementedError('numpy-specific methods are not supported over gRPC')
# Use ravel() so that gRPC always receives a flat numpy array, regardless of input dimensions.
waveform_data_array_list = [
grpc_complex_types.NIComplexNumber(real=val.real, imaginary=val.imag)
for val in waveform_data_array.ravel()
]
self._invoke(
self._client.WriteWaveformNumpyComplex128,
grpc_types.WriteWaveformNumpyComplex128Request(vi=self._vi, waveform_data_array=waveform_data_array_list),
)

def write_waveform_numpy_complex64(self, waveform_data_array): # noqa: N802
raise NotImplementedError('numpy-specific methods are not supported over gRPC')
# Use ravel() so that gRPC always receives a flat numpy array, regardless of input dimensions.
waveform_data_array_list = [
grpc_complex_types.NIComplexNumberF32(real=val.real, imaginary=val.imag)
for val in waveform_data_array.ravel()
]
self._invoke(
self._client.WriteWaveformNumpyComplex64,
grpc_types.WriteWaveformNumpyComplex64Request(vi=self._vi, waveform_data_array=waveform_data_array_list),
)

def write_waveform_numpy_complex_interleaved_i16(self, waveform_data_array): # noqa: N802
raise NotImplementedError('numpy-specific methods are not supported over gRPC')
# Use ravel() so that gRPC always receives a flat numpy array, regardless of input dimensions.
arr = waveform_data_array.ravel()
if arr.size % 2 != 0:
raise ValueError("Interleaved int16 array must have even length (real/imag pairs)")
arr_pairs = arr.reshape(-1, 2)
waveform_data_array_list = [
grpc_complex_types.NIComplexI16(real=int(pair[0]), imaginary=int(pair[1]))
for pair in arr_pairs
]
self._invoke(
self._client.WriteWaveformNumpyComplexInterleavedI16,
grpc_types.WriteWaveformNumpyComplexInterleavedI16Request(vi=self._vi, waveform_data_array=waveform_data_array_list),
)

def close(self): # noqa: N802
self._invoke(
Expand Down
884 changes: 451 additions & 433 deletions generated/nifake/nifake/nifake_pb2.py

Large diffs are not rendered by default.

132 changes: 132 additions & 0 deletions generated/nifake/nifake/nifake_pb2_grpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,21 @@ def __init__(self, channel):
request_serializer=nifake__pb2.WriteWaveformRequest.SerializeToString,
response_deserializer=nifake__pb2.WriteWaveformResponse.FromString,
)
self.WriteWaveformNumpyComplex128 = channel.unary_unary(
'/nifake_grpc.NiFake/WriteWaveformNumpyComplex128',
request_serializer=nifake__pb2.WriteWaveformNumpyComplex128Request.SerializeToString,
response_deserializer=nifake__pb2.WriteWaveformNumpyComplex128Response.FromString,
)
self.WriteWaveformNumpyComplex64 = channel.unary_unary(
'/nifake_grpc.NiFake/WriteWaveformNumpyComplex64',
request_serializer=nifake__pb2.WriteWaveformNumpyComplex64Request.SerializeToString,
response_deserializer=nifake__pb2.WriteWaveformNumpyComplex64Response.FromString,
)
self.WriteWaveformNumpyComplexInterleavedI16 = channel.unary_unary(
'/nifake_grpc.NiFake/WriteWaveformNumpyComplexInterleavedI16',
request_serializer=nifake__pb2.WriteWaveformNumpyComplexInterleavedI16Request.SerializeToString,
response_deserializer=nifake__pb2.WriteWaveformNumpyComplexInterleavedI16Response.FromString,
)
self.SetCustomType = channel.unary_unary(
'/nifake_grpc.NiFake/SetCustomType',
request_serializer=nifake__pb2.SetCustomTypeRequest.SerializeToString,
Expand Down Expand Up @@ -319,6 +334,11 @@ def __init__(self, channel):
request_serializer=nifake__pb2.FunctionWithOverriddenGrpcName2xRequest.SerializeToString,
response_deserializer=nifake__pb2.FunctionWithOverriddenGrpcName2xResponse.FromString,
)
self.FunctionWith3dNumpyArrayOfNumpyComplex128InputParameter = channel.unary_unary(
'/nifake_grpc.NiFake/FunctionWith3dNumpyArrayOfNumpyComplex128InputParameter',
request_serializer=nifake__pb2.FunctionWith3dNumpyArrayOfNumpyComplex128InputParameterRequest.SerializeToString,
response_deserializer=nifake__pb2.FunctionWith3dNumpyArrayOfNumpyComplex128InputParameterResponse.FromString,
)
self.StringValuedEnumNoEnumGenerated = channel.unary_unary(
'/nifake_grpc.NiFake/StringValuedEnumNoEnumGenerated',
request_serializer=nifake__pb2.StringValuedEnumNoEnumGeneratedRequest.SerializeToString,
Expand Down Expand Up @@ -772,6 +792,24 @@ def WriteWaveform(self, request, context):
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')

def WriteWaveformNumpyComplex128(self, request, context):
"""Missing associated documentation comment in .proto file."""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')

def WriteWaveformNumpyComplex64(self, request, context):
"""Missing associated documentation comment in .proto file."""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')

def WriteWaveformNumpyComplexInterleavedI16(self, request, context):
"""Missing associated documentation comment in .proto file."""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')

def SetCustomType(self, request, context):
"""Missing associated documentation comment in .proto file."""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
Expand Down Expand Up @@ -880,6 +918,12 @@ def FunctionWithOverriddenGrpcName2x(self, request, context):
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')

def FunctionWith3dNumpyArrayOfNumpyComplex128InputParameter(self, request, context):
"""Missing associated documentation comment in .proto file."""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')

def StringValuedEnumNoEnumGenerated(self, request, context):
"""Missing associated documentation comment in .proto file."""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
Expand Down Expand Up @@ -1326,6 +1370,21 @@ def add_NiFakeServicer_to_server(servicer, server):
request_deserializer=nifake__pb2.WriteWaveformRequest.FromString,
response_serializer=nifake__pb2.WriteWaveformResponse.SerializeToString,
),
'WriteWaveformNumpyComplex128': grpc.unary_unary_rpc_method_handler(
servicer.WriteWaveformNumpyComplex128,
request_deserializer=nifake__pb2.WriteWaveformNumpyComplex128Request.FromString,
response_serializer=nifake__pb2.WriteWaveformNumpyComplex128Response.SerializeToString,
),
'WriteWaveformNumpyComplex64': grpc.unary_unary_rpc_method_handler(
servicer.WriteWaveformNumpyComplex64,
request_deserializer=nifake__pb2.WriteWaveformNumpyComplex64Request.FromString,
response_serializer=nifake__pb2.WriteWaveformNumpyComplex64Response.SerializeToString,
),
'WriteWaveformNumpyComplexInterleavedI16': grpc.unary_unary_rpc_method_handler(
servicer.WriteWaveformNumpyComplexInterleavedI16,
request_deserializer=nifake__pb2.WriteWaveformNumpyComplexInterleavedI16Request.FromString,
response_serializer=nifake__pb2.WriteWaveformNumpyComplexInterleavedI16Response.SerializeToString,
),
'SetCustomType': grpc.unary_unary_rpc_method_handler(
servicer.SetCustomType,
request_deserializer=nifake__pb2.SetCustomTypeRequest.FromString,
Expand Down Expand Up @@ -1416,6 +1475,11 @@ def add_NiFakeServicer_to_server(servicer, server):
request_deserializer=nifake__pb2.FunctionWithOverriddenGrpcName2xRequest.FromString,
response_serializer=nifake__pb2.FunctionWithOverriddenGrpcName2xResponse.SerializeToString,
),
'FunctionWith3dNumpyArrayOfNumpyComplex128InputParameter': grpc.unary_unary_rpc_method_handler(
servicer.FunctionWith3dNumpyArrayOfNumpyComplex128InputParameter,
request_deserializer=nifake__pb2.FunctionWith3dNumpyArrayOfNumpyComplex128InputParameterRequest.FromString,
response_serializer=nifake__pb2.FunctionWith3dNumpyArrayOfNumpyComplex128InputParameterResponse.SerializeToString,
),
'StringValuedEnumNoEnumGenerated': grpc.unary_unary_rpc_method_handler(
servicer.StringValuedEnumNoEnumGenerated,
request_deserializer=nifake__pb2.StringValuedEnumNoEnumGeneratedRequest.FromString,
Expand Down Expand Up @@ -2347,6 +2411,57 @@ def WriteWaveform(request,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)

@staticmethod
def WriteWaveformNumpyComplex128(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/nifake_grpc.NiFake/WriteWaveformNumpyComplex128',
nifake__pb2.WriteWaveformNumpyComplex128Request.SerializeToString,
nifake__pb2.WriteWaveformNumpyComplex128Response.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)

@staticmethod
def WriteWaveformNumpyComplex64(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/nifake_grpc.NiFake/WriteWaveformNumpyComplex64',
nifake__pb2.WriteWaveformNumpyComplex64Request.SerializeToString,
nifake__pb2.WriteWaveformNumpyComplex64Response.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)

@staticmethod
def WriteWaveformNumpyComplexInterleavedI16(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/nifake_grpc.NiFake/WriteWaveformNumpyComplexInterleavedI16',
nifake__pb2.WriteWaveformNumpyComplexInterleavedI16Request.SerializeToString,
nifake__pb2.WriteWaveformNumpyComplexInterleavedI16Response.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)

@staticmethod
def SetCustomType(request,
target,
Expand Down Expand Up @@ -2653,6 +2768,23 @@ def FunctionWithOverriddenGrpcName2x(request,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)

@staticmethod
def FunctionWith3dNumpyArrayOfNumpyComplex128InputParameter(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/nifake_grpc.NiFake/FunctionWith3dNumpyArrayOfNumpyComplex128InputParameter',
nifake__pb2.FunctionWith3dNumpyArrayOfNumpyComplex128InputParameterRequest.SerializeToString,
nifake__pb2.FunctionWith3dNumpyArrayOfNumpyComplex128InputParameterResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)

@staticmethod
def StringValuedEnumNoEnumGenerated(request,
target,
Expand Down
Loading