1
type dMatrix with
    member t.Item
        with get(a: int, b: int) = t.dArray.[b+a*t.num_cols |> SizeT]
        and set(a: int, b: int) (value: floatType) = t.dArray.[b+a*t.num_cols |> SizeT] <- value
    member t.setItem(a: int, b: int) (value: floatType) = t.dArray.[b+a*t.num_cols |> SizeT] <- value

let a = dMatrix.createRandomUniformMatrix n m 50.f 50.0f

a.[1,1] <- 654.0f // Gives 'A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...''
a.setItem(1,1) 654.0f // Works fine.

I am not sure what is going in the above. dArray is of type CudaDeviceVariable<float32> from the ManagedCuda library if that helps.

Edit:

type dMatrix = 
    struct
        val num_rows:int
        val num_cols:int
        val dArray: CudaDeviceVariable<floatType>

Here is how the struct above looks. Even if I make dArray mutable, it still does not work, but writing something like a.dArray.[SizeT 0] <- 2.5f does. Is there any workaround for this?

Edit2: Turning the above into a record or a class solves the problem.

talonmies
  • 70,661
  • 34
  • 192
  • 269
Marko Grdinić
  • 3,798
  • 3
  • 18
  • 21

1 Answers1

2

The error message is quite helpful here. In F#, values are immutable by default. Mutability must be declared explicitly see: https://msdn.microsoft.com/en-us/library/dd233185.aspx

If you want to make a mutable, do:

let mutable a = dMatrix.createRandomUniformMatrix n m 50.f 50.0f

It isn't normally required to make something mutable unless you wish to change the value itself (as opposed to mutating one of that object's members), this behaviour is different between value and reference types, for instance this will compile:

let a = [|5; 10; 9; 3; 2|]
a.[2] <- 6

But if a were a struct with an indexer, it would not. For example, this struct produces exactly the same behaviour you describe:

type TestStruct =
    struct 
        val mutable Xs : int[]
    end

    member this.Item
        with get(i) = this.Xs.[i]
        and set(i : int) (value) = this.Xs.[i] <- value

    member this.SetValue i y =
        this.Xs.[i] <- y

So, I'm guessing you have value types involved.

TheInnerLight
  • 12,034
  • 1
  • 29
  • 52