You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I am trying to implement this Rust implementation into c# so far I created FFIArray which holds data to simplify as well as simplified data returned from Rust.
[StructLayout(LayoutKind.Sequential)]
internal unsafe struct FfiArray
{
public required nint data;
public required nuint len;
}
I am converting float[][] array into nint and vice versa using these methods.
public static nint CopyDataFromFloatJaggedArrayToIntPtr(float[][] jaggedArray)
{
int length = jaggedArray.Length;
double[] joinedArray = jaggedArray.Select(coords =>
{
var x = BitConverter.GetBytes(coords[0]);
var y = BitConverter.GetBytes(coords[1]);
return BitConverter.ToDouble([..x, ..y], 0);
}).ToArray();
nint arrayPtr = Marshal.AllocHGlobal(jaggedArray.Length * sizeof(double));
Marshal.Copy(joinedArray, 0, arrayPtr, joinedArray.Length);
return arrayPtr;
}
public static float[][] CopyDataFromIntPtrToFloatJaggedArray(nint ptr, int length, int innerLength = 2)
{
float[][] jaggedArray = new float[length][];
for (int i = 0; i < length; i++)
{
byte[] x = new byte[4];
byte[] y = new byte[4];
Marshal.Copy(ptr + (i * 8), x, 0, 4);
Marshal.Copy(ptr + (i * 8 + 4), y, 0, 4);
jaggedArray[i] = [BitConverter.ToSingle(x), BitConverter.ToSingle(y)];
}
return jaggedArray;
}
public static void FreeIntPtr(nint ptr, int length)
{
for (int i = 0; i < length; i++)
{
nint innerPtr = Marshal.ReadIntPtr(ptr, i * nint.Size);
Marshal.FreeHGlobal(innerPtr);
}
Marshal.FreeHGlobal(ptr);
}
Rust bindings from DLL:
internal class RustBindings
{
[DllImport("RustSimplificationAlgorithms.dll")]
public static extern FfiArray simplify_rdp_ffi(FfiArray array, double precision);
[DllImport("RustSimplificationAlgorithms.dll")]
public static extern FfiArray simplify_rdp_idx_ffi(FfiArray array, double precision);
[DllImport("RustSimplificationAlgorithms.dll")]
public static extern FfiArray simplify_visvalingam_ffi(FfiArray array, double precision);
[DllImport("RustSimplificationAlgorithms.dll")]
public static extern FfiArray simplify_visvalingam_idx_ffi(FfiArray array, double precision);
[DllImport("RustSimplificationAlgorithms.dll")]
public static extern FfiArray simplify_visvalingamp_ffi(FfiArray array, double precision);
[DllImport("RustSimplificationAlgorithms.dll")]
public static extern void drop_float_array(FfiArray ptr);
[DllImport("RustSimplificationAlgorithms.dll")]
public static extern void drop_usize_array(FfiArray ptr);
}
And Public Api looks like this (for testing purposes I am trying to implement only RDP algorithm).
public static float[][] Simplify(float[][] data, double tolerance)
{
FfiArray? dataInArray = null;
FfiArray? simplified = null;
try
{
nint dataForSimplification = MarshalOperations.CopyDataFromFloatJaggedArrayToIntPtr(data);
dataInArray = new FfiArray()
{
data = dataForSimplification,
len = (nuint)data.Length
};
simplified = RustBindings.simplify_rdp_ffi((FfiArray)dataInArray, tolerance);
float[][] result = MarshalOperations.CopyDataFromIntPtrToFloatJaggedArray(((FfiArray)simplified).data, (int)((FfiArray)simplified).len);
return result;
}
finally
{
if (dataInArray is not null)
MarshalOperations.FreeIntPtr(((FfiArray)dataInArray).data, (int)((FfiArray)dataInArray).len);
if (simplified is not null)
RustBindings.drop_float_array((FfiArray)simplified!);
Console.WriteLine("memory freed");
}
}
My problem is that the simplification algorithm always returns different values despite the same values being provided. For checking I am using the Python library which is part of this repository. According to that, I am expecting 26 values but I got only 15 at best. Also when I check the returned values only the first two are valid and the others are junk.
I expect this problem is in bad memory handling.
string[] lines = File.ReadAllLines("generatedValuesSin.csv");
float[][] data = new float[lines.Length - 1][];
for (int i = 1; i < lines.Length; i++) // skip first line
{
data[i - 1] = [(i - 1) * 3600, float.Parse(lines[i], NumberStyles.AllowExponent | NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture)];
}
float[][] simplified = RdpAlgorithm.Simplify(data, 0.15);
I am trying to implement this Rust implementation into c# so far I created FFIArray which holds data to simplify as well as simplified data returned from Rust.
I am converting float[][] array into nint and vice versa using these methods.
Rust bindings from DLL:
And Public Api looks like this (for testing purposes I am trying to implement only RDP algorithm).
My problem is that the simplification algorithm always returns different values despite the same values being provided. For checking I am using the Python library which is part of this repository. According to that, I am expecting 26 values but I got only 15 at best. Also when I check the returned values only the first two are valid and the others are junk.
I expect this problem is in bad memory handling.
Source code repository: https://github.com/AiwendilsCode/Simplification.NET
Python testing code: https://github.com/AiwendilsCode/Simplification.NET/tree/master/Python
As a testing data I am using generated Sin values.
The text was updated successfully, but these errors were encountered: