dotnet / TorchSharp

A .NET library that provides access to the library that powers PyTorch.
MIT License
1.37k stars 177 forks source link

Arrays of Arrays #1349

Closed travisjj closed 2 months ago

travisjj commented 3 months ago

Sorry of this seems too simple, I tried to localize the problem I was facing. I am trying to create a tensor with an array of an array of ints.

public static void ArrayOfArrays()
{
    int[][] ints = Enumerable.Range(0,50).Select( i => new int[] { 1, 2, 3 } ).ToArray();

    var inT = torch.tensor(ints);
    var inA = torch.from_array(ints);
}

inT fails to compile with "Error (active) CS1503 Argument 1: cannot convert from 'int[][]' to 'bool' " inA fails during runtime with "System.NotSupportedException: 'The type System.Int32[] is not supported.'"

Okay, so the second response does seem fairly clear, perhaps this just isn't supported? Or is it just that I am doing it wrong?

Is there a way to properly create a tensor of the int[][] structure shown here? In pytorch it would look like:

ints = [] 
arr = [1] * 3
ints.append(arr)

inA = torch.tensor(ints);

Please let me know, ty

yueyinqiu commented 2 months ago

You shall use int[,] (multidimensional arrays) rather than int[][] (jagged arrays). Here we explained why we don't support jagged arrays currently https://github.com/dotnet/TorchSharp/issues/1347#issuecomment-2203495714.

You could use the following code to convert a 2d jagged array to a 2d array and create the tensor.

using TorchSharp;

int[][] jagged = Enumerable.Range(0, 50).Select(i => new int[] { 1, 2, 3 }).ToArray();

int[,] multi = new int[50, 3];
for (int i = 0; i < multi.GetLength(0); i++)
{
    for (int j = 0; j < multi.GetLength(1); j++)
    {
        multi[i, j] = jagged[i][j];
    }
}

var tensor = torch.tensor(multi);
Console.WriteLine(tensor.cstr());

/*
[50x3], type = Int32, device = cpu, value =
int [,] {
 {1, 2, 3},
 {1, 2, 3},
 {1, 2, 3},
 ...
 {1, 2, 3},
 {1, 2, 3},
 {1, 2, 3}
}
*/

Of course it will be better to create the multidimensional arrays directly:

using TorchSharp;

int[,] ints = new int[50, 3];
for (int i = 0; i < 50; i++)
{
    for (int j = 0; j < 3; )
    {
        ints[i, j] = ++j;
    }
}
var tensor = torch.tensor(ints);
Console.WriteLine(tensor.cstr());

Or, you could create the flattened tensor and reshape it:

using TorchSharp;

int[] flattened = Enumerable.Range(0, 50).SelectMany(i => new int[] { 1, 2, 3 }).ToArray();
using var temp = torch.tensor(flattened);
var tensor = temp.reshape(50, 3);
Console.WriteLine(tensor.cstr());
travisjj commented 2 months ago

Thank you @yueyinqiu for your assistance, I missed the nuance between jagged and multidimensional in this use. I appreciate it.

NiklasGustafsson commented 2 months ago

@travisjj -- can this be closed?

travisjj commented 2 months ago

@NiklasGustafsson Yes, this resolved the issue and worked in setting up the sample tensors I was using for training. Thanks