Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoiding transpose #7

Open
MichelJuillard opened this issue Nov 13, 2023 · 4 comments
Open

Avoiding transpose #7

MichelJuillard opened this issue Nov 13, 2023 · 4 comments

Comments

@MichelJuillard
Copy link
Contributor

  1. Transposing a matrix is an expensive operation that should be avoided if at all possible
  2. The Tasmanian C library uses only vectors as input or output arguments
  3. In Julia, one can pass a matrix to ccall vector argument. The vector is just the continuous memory space occupied by the Julia matrix.
  4. The Tasmanian vector is formed by a succession of strips of data piled on top of each others. As a Julia matrix is stored column wise, the most efficient is to have the Julia matrix columns to correspond to the strips of data

Example:

# load needed points
"""
    loadNeededPoints!(tsg::TasmanianSG, vals::Matrix{Float64})

loads the values of the target function at the needed points
if there are no needed points, this reset the currently loaded
values

vals: a matrix
      with dimensions iOutputs X getNumNeeded() 
      each column corresponds to the values of the outputs at
      the corresponding needed point. The order and leading
      dimension must match the points obtained from
      getNeededPoints()
"""
function loadNeededPoints!(tsg::TasmanianSG,vals::Array{Float64})
    if ndims(vals) != 2
        throw(ArgumentError("vals should be a 2-D array, instead it has $(ndims(vals)) dimensions"))
    end
    n = size(vals)
    if n[1] != getNumOutputs(tsg)
        throw(ArgumentError("leading dimension of vals is $(n[1]) but the number of outputs is set to $(getNumOutputs(tsg))"))
    end
    if getNumNeeded(tsg) == 0
        if n[2] != getNumLoaded(tsg)
            throw(ArgumentError("the second dimension of vals is $(n[2]) but the number of current points is $(getNumLoaded(tsg))"))
        end
    elseif n[2] != getNumNeeded(tsg)
        throw(ArgumentError("the second dimension of vals is $(n[2]) but the number of needed points is $(getNumNeeded(tsg))"))
    end
    ccall((:tsgLoadNeededPoints,TASlib),Nothing,(Ptr{Nothing},Ptr{Cdouble}),tsg.pGrid,vals)
end
@floswald
Copy link
Owner

Ok I see, that starts to ring a bell, yes. One thing that would need to be clarified maybe is how to deal with more than 2D. Like what if you have a 3D object. then one needs to reshape ones array into 2D first. correct? Also, in which way is the current implementation "wrong" here - I can't see any transpose operation:

https://github.com/floswald/Tasmanian.jl/blob/81ce15844119e7cd3437078163c77de1b3e64308/src/TSG.jl#L124C5-L124C5

@MichelJuillard
Copy link
Contributor Author

MichelJuillard commented Nov 14, 2023 via email

@floswald
Copy link
Owner

ah yes, I see. I was looking at loadNeededPoints! only. indeed i'm seeing this one

v = Array(reshape(vals',nx*nd,1))

which seems hard to avoid. in the end you always need to strip away all dimension info from the array and supply a 1D vector to tasmanian.

@MichelJuillard
Copy link
Contributor Author

MichelJuillard commented Nov 14, 2023 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants