Skip to content

Commit

Permalink
optimize memory management for c# in BoardShim class (#609)
Browse files Browse the repository at this point in the history
* optimize memory allocations in C# for BoardShim class

Signed-off-by: Andrey Parfenov <a1994ndrey@gmail.com>
  • Loading branch information
Andrey1994 committed Mar 5, 2023
1 parent 7d1fbc3 commit df6657d
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 28 deletions.
20 changes: 10 additions & 10 deletions csharp_package/brainflow/brainflow/board_controller_library.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,11 @@ public static class BoardControllerLibrary64
[DllImport ("BoardController.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern int release_session (int board_id, string input_json);
[DllImport ("BoardController.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern int get_current_board_data (int num_samples, int preset, double[] data_buf, int[] returned_samples, int board_id, string input_json);
public static extern int get_current_board_data (int num_samples, int preset, [In, Out][MarshalAs (UnmanagedType.LPArray, ArraySubType = UnmanagedType.R8)] double[,] data_buf, int[] returned_samples, int board_id, string input_json);
[DllImport ("BoardController.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern int get_board_data_count (int preset, int[] result, int board_id, string input_json);
[DllImport ("BoardController.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern int get_board_data (int data_count, int preset, double[] data_buf, int board_id, string input_json);
public static extern int get_board_data (int data_count, int preset, [In, Out][MarshalAs (UnmanagedType.LPArray, ArraySubType = UnmanagedType.R8)] double[,] data_buf, int board_id, string input_json);
[DllImport ("BoardController.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern int set_log_level_board_controller (int log_level);
[DllImport ("BoardController.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
Expand Down Expand Up @@ -213,11 +213,11 @@ public static class BoardControllerLibrary32
[DllImport ("BoardController32.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern int release_session (int board_id, string input_json);
[DllImport ("BoardController32.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern int get_current_board_data (int num_samples, int preset, double[] data_buf, int[] returned_samples, int board_id, string input_json);
public static extern int get_current_board_data (int num_samples, int preset, [In, Out][MarshalAs (UnmanagedType.LPArray, ArraySubType = UnmanagedType.R8)] double[,] data_buf, int[] returned_samples, int board_id, string input_json);
[DllImport ("BoardController32.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern int get_board_data_count (int preset, int[] result, int board_id, string input_json);
[DllImport ("BoardController32.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern int get_board_data (int data_count, int preset, double[] data_buf, int board_id, string input_json);
public static extern int get_board_data (int data_count, int preset, [In, Out][MarshalAs (UnmanagedType.LPArray, ArraySubType = UnmanagedType.R8)] double[,] data_buf, int board_id, string input_json);
[DllImport ("BoardController32.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern int set_log_level_board_controller (int log_level);
[DllImport ("BoardController32.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
Expand Down Expand Up @@ -299,11 +299,11 @@ public static class BoardControllerLibraryLinux
[DllImport ("libBoardController.so", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern int release_session (int board_id, string input_json);
[DllImport ("libBoardController.so", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern int get_current_board_data (int num_samples, int preset, double[] data_buf, int[] returned_samples, int board_id, string input_json);
public static extern int get_current_board_data (int num_samples, int preset, [In, Out][MarshalAs (UnmanagedType.LPArray, ArraySubType = UnmanagedType.R8)] double[,] data_buf, int[] returned_samples, int board_id, string input_json);
[DllImport ("libBoardController.so", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern int get_board_data_count (int preset, int[] result, int board_id, string input_json);
[DllImport ("libBoardController.so", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern int get_board_data (int data_count, int preset, double[] data_buf, int board_id, string input_json);
public static extern int get_board_data (int data_count, int preset, [In, Out][MarshalAs (UnmanagedType.LPArray, ArraySubType = UnmanagedType.R8)] double[,] data_buf, int board_id, string input_json);
[DllImport ("libBoardController.so", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern int set_log_level_board_controller (int log_level);
[DllImport ("libBoardController.so", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
Expand Down Expand Up @@ -387,11 +387,11 @@ public static class BoardControllerLibraryMac
[DllImport ("libBoardController.dylib", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern int release_session (int board_id, string input_json);
[DllImport ("libBoardController.dylib", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern int get_current_board_data (int num_samples, int preset, double[] data_buf, int[] returned_samples, int board_id, string input_json);
public static extern int get_current_board_data (int num_samples, int preset, [In, Out][MarshalAs (UnmanagedType.LPArray, ArraySubType = UnmanagedType.R8)] double[,] data_buf, int[] returned_samples, int board_id, string input_json);
[DllImport ("libBoardController.dylib", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern int get_board_data_count (int preset, int[] result, int board_id, string input_json);
[DllImport ("libBoardController.dylib", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern int get_board_data (int data_count, int preset, double[] data_buf, int board_id, string input_json);
public static extern int get_board_data (int data_count, int preset, [In, Out][MarshalAs (UnmanagedType.LPArray, ArraySubType = UnmanagedType.R8)] double[,] data_buf, int board_id, string input_json);
[DllImport ("libBoardController.dylib", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern int set_log_level_board_controller (int log_level);
[DllImport ("libBoardController.dylib", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
Expand Down Expand Up @@ -530,7 +530,7 @@ public static int release_session (int board_id, string input_json)
return (int)BrainFlowExitCodes.GENERAL_ERROR;
}

public static int get_current_board_data (int num_samples, int preset, double[] data_buf, int[] returned_samples, int board_id, string input_json)
public static int get_current_board_data (int num_samples, int preset, [In, Out][MarshalAs (UnmanagedType.LPArray, ArraySubType = UnmanagedType.R8)] double[,] data_buf, int[] returned_samples, int board_id, string input_json)
{
switch (PlatformHelper.get_library_environment ())
{
Expand Down Expand Up @@ -581,7 +581,7 @@ public static int is_prepared (int[] result, int board_id, string input_json)
return (int)BrainFlowExitCodes.GENERAL_ERROR;
}

public static int get_board_data (int data_count, int preset, double[] data_buf, int board_id, string input_json)
public static int get_board_data (int data_count, int preset, [In, Out][MarshalAs (UnmanagedType.LPArray, ArraySubType = UnmanagedType.R8)] double[,] data_buf, int board_id, string input_json)
{
switch (PlatformHelper.get_library_environment ())
{
Expand Down
76 changes: 60 additions & 16 deletions csharp_package/brainflow/brainflow/board_shim.cs
Original file line number Diff line number Diff line change
Expand Up @@ -835,21 +835,46 @@ public int get_board_data_count (int preset = (int)BrainFlowPresets.DEFAULT_PRES
/// <returns>latest collected data, can be less than "num_samples"</returns>
public double[,] get_current_board_data (int num_samples, int preset = (int)BrainFlowPresets.DEFAULT_PRESET)
{
int size = get_board_data_count (preset);
if (num_samples < 0)
{
throw new BrainFlowError ((int)BrainFlowExitCodes.INVALID_ARGUMENTS_ERROR);
}
size = Math.Min (size, num_samples);
int num_rows = BoardShim.get_num_rows (master_board, preset);
double[] data_arr = new double[num_samples * num_rows];
double[,] result = new double[num_rows, size];
int[] current_size = new int[1];
int ec = BoardControllerLibrary.get_current_board_data (num_samples, preset, data_arr, current_size, board_id, input_json);
int ec = BoardControllerLibrary.get_current_board_data (num_samples, preset, result, current_size, board_id, input_json);
if (ec != (int)BrainFlowExitCodes.STATUS_OK)
{
throw new BrainFlowError (ec);
}
double[,] result = new double[num_rows, current_size[0]];
for (int i = 0; i < num_rows; i++)
return result;
}

/// <summary>
/// get latest collected data, doesnt remove it from ringbuffer
/// </summary>
/// <param name="preset">preset for device</param>
/// <param name="result">array to store results, if provided BrainFlow does not allocate new memory</param>
/// <returns>latest collected data, can be less than "num_samples"</returns>
public double[,] get_current_board_data (double[,] result, int preset = (int)BrainFlowPresets.DEFAULT_PRESET)
{
int size = get_board_data_count (preset);
if (size < result.GetLength(1))
{
for (int j = 0; j < current_size[0]; j++)
{
result[i, j] = data_arr[i * current_size[0] + j];
}
throw new BrainFlowError ((int)BrainFlowExitCodes.INVALID_ARGUMENTS_ERROR);
}
int num_rows = BoardShim.get_num_rows (master_board, preset);
if (result.GetLength(0) != num_rows)
{
throw new BrainFlowError ((int)BrainFlowExitCodes.INVALID_ARGUMENTS_ERROR);
}
int[] current_size = new int[1];
int ec = BoardControllerLibrary.get_current_board_data (result.GetLength (1), preset, result, current_size, board_id, input_json);
if (ec != (int)BrainFlowExitCodes.STATUS_OK)
{
throw new BrainFlowError (ec);
}
return result;
}
Expand Down Expand Up @@ -877,6 +902,7 @@ public int get_board_data_count (int preset = (int)BrainFlowPresets.DEFAULT_PRES
/// <summary>
/// get collected data and remove it from ringbuffer
/// </summary>
/// <param name="num_datapoints">number of datapoints to get</param>
/// <param name="preset">preset for device</param>
/// <returns>all collected data</returns>
public double[,] get_board_data (int num_datapoints, int preset)
Expand All @@ -888,21 +914,39 @@ public int get_board_data_count (int preset = (int)BrainFlowPresets.DEFAULT_PRES
}
size = Math.Min (size, num_datapoints);
int num_rows = BoardShim.get_num_rows (master_board, preset);
double[] data_arr = new double[size * num_rows];
double[,] data_arr = new double[num_rows, size];
int ec = BoardControllerLibrary.get_board_data (size, preset, data_arr, board_id, input_json);
if (ec != (int)BrainFlowExitCodes.STATUS_OK)
{
throw new BrainFlowError (ec);
}
double[,] result = new double[num_rows, size];
for (int i = 0; i < num_rows; i++)
return data_arr;
}

/// <summary>
/// get collected data and remove it from ringbuffer
/// </summary>
/// <param name="data_arr">array to store results, if provided BrainFlow will not allocate memory</param>
/// <param name="preset">preset for device</param>
/// <returns>all collected data</returns>
public double[,] get_board_data (double[,] data_arr, int preset)
{
int size = get_board_data_count (preset);
if (size < data_arr.GetLength(1))
{
for (int j = 0; j < size; j++)
{
result[i, j] = data_arr[i * size + j];
}
throw new BrainFlowError ((int)BrainFlowExitCodes.INVALID_ARGUMENTS_ERROR);
}
return result;
int num_rows = BoardShim.get_num_rows (master_board, preset);
if (num_rows != data_arr.GetLength(0))
{
throw new BrainFlowError ((int)BrainFlowExitCodes.INVALID_ARGUMENTS_ERROR);
}
int ec = BoardControllerLibrary.get_board_data (data_arr.GetLength (1), preset, data_arr, board_id, input_json);
if (ec != (int)BrainFlowExitCodes.STATUS_OK)
{
throw new BrainFlowError (ec);
}
return data_arr;
}
}
}
2 changes: 1 addition & 1 deletion python_package/examples/plot_real_time/plot_real_time.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,8 @@ def main():
params.file = args.file
params.master_board = args.master_board

board_shim = BoardShim(args.board_id, params)
try:
board_shim = BoardShim(args.board_id, params)
board_shim.prepare_session()
board_shim.start_stream(450000, args.streamer_params)
Graph(board_shim)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ def main():
params.file = args.file
params.master_board = args.master_board

board_shim = BoardShim(args.board_id, params)
try:
board_shim = BoardShim(args.board_id, params)
board_shim.prepare_session()
board_shim.start_stream(450000, args.streamer_params)
Graph(board_shim)
Expand Down

0 comments on commit df6657d

Please sign in to comment.