Error when defining function in GDL on Ubuntu 20 - idl

I have a GDL v0.9.9 installed on my machine running Ubuntu 20.04. I am trying to write a function calculating a Julian Date.
list_1 file:
FUNCTION JulianDate, L, M, N
L1 = L + 4716 - FLOOR((14 - M) / 12)
M1 = (M + 9) MOD 12
G = FLOOR(3/4*FLOOR((L1 + 184)/100)) - 38
RETURN, FLOOR(365.25 * L1) + FLOOR(30.6 * M1 + 0.4) + N - G - 1402
END
JD = JulianDate(1990, 4, 30)
Unfortunately, after $ gdl list_1 I get the error(s):
% Programs can't be compiled from single statement mode.
% Variable is undefined: L
% Execution halted at: $MAIN$
% Variable is undefined: M
% Execution halted at: $MAIN$
% Variable is undefined: L1
% Execution halted at: $MAIN$
% Return statement in procedures cannot have values.
% Parser syntax error: unexpected token: END
% Ambiguous: Variable is undefined: JULIANDATE or: Function not found: JULIANDATE
% Execution halted at: $MAIN$
I compared my code with the documentation of IDL (as it should be "mutually intelligible") and it looked good for me. Is declaring/defining/calling a function in GDL different than in IDL?
Edit 1: I managed to run my code on the machine with IDL 8.5. The functions must be declared in the beginning of the file before any variables. However it does not change the behaviour of GDL.

idl and idlde (GUI) behave differently: while idl requires the functions to be stored in the separate .pro files, idlde handles the functions in the same file as the run script, as long as they are declared before any other commands.
gdl behaves just like idl, so functions' declarations in the separate files resolved the issue.

Related

Julia CUDA: UndefVarError: parameters not defined

I have a program for doing Fourier series and I wanted to switch to CuArrays to make it faster. The code is as follows (extract):
#Arrays I want to use
coord = CuArray{ComplexF64,1}(complex.(a[:,1],a[:,2]))
t=CuArray{Float64,1}(-L:(2L/(N-1)):L)
#Array of indexes in the form [0,1,-1,2,-2,...]
n=[((-1)^i)div(i,2) for i in 1:grado]
#Array of functions I need for calculations
base= [x -> exp(π * im * i * x / L) / L for i in n]
base[i](1.) #This line is OK
base[i](-1:.1:1) #This line is OK
base[i].(t) #This line gives error!
base[i].(CuArray{Float64,1}(t)) #This line gives error!
And the error is:
GPU broadcast resulted in non-concrete element type Any.
This probably means that the function you are broadcasting contains an error or type instability.
If I change it like this
base= [(x::Float64) -> (exp(π * im * i * x / L) / L)::ComplexF64 for i in n]
the same lines still give error, but the error now is:
UndefVarError: parameters not defined
Any idea how I could fix this?
Thank you in advance!
Package information:
(#v1.6) pkg> st CUDA
Status `C:\Users\marce\.julia\environments\v1.6\Project.toml`
[052768ef] CUDA v2.6.2
P.S.: This other function has the same problem:
function integra(inizio, fine, arr)
N=size(arr,1)
h=(fine-inizio)/N
integrale=sum(arr)
integrale -= (first(arr)+last(arr))/2
integrale *= h
end
L=2
integra(-L,L,coord)
The first and easier problem is that you should take care to declare global variables to be constant so that the compiler can assume a constant type: const L = 2. A mere L = 2 allows you to do something like L = SomeOtherType(), and if that type can be Anything, so must the return type of your functions. On the CPU that's only a performance hit, but it's a no-no for the GPU. If you actually want L to vary in value, pass it in as an argument so the compiler can still infer types within a function.
Your ::ComplexF64 assertion did actually force a concrete return type, though the middle of the function is still type unstable (check with #code_warntype). The second problem you ran into after that patch was probably caused by this recently patched conflict between ExprTools.jl and LLVM.jl. Seems like you just need to update the packages or maybe reinstall them.

Can I call an R function while using open FSharp.Collections.ParallelSeq?

I have some code that runs with no problems without parallelization. However, the same code generates exceptions if I try to run it using PSeq instead of Seq. The messages I get look a bit random, they are hard to replicate exactly.
Here is the code. When the exception happens the three lines starting with let tmp2 are highlighted.
let frameToRMatrix (df: Frame<'R,string>) =
let foo k df : float list =
df
|> Frame.getCol k
|> Series.values
|> List.ofSeq
let folder acc k = (k, foo k df |> box) :: acc
let tmp =
List.fold folder [] (df.ColumnKeys |> List.ofSeq)
|> namedParams
let sd = df |> Frame.getCol "Vol0" |> Series.lastValue
let sd = sd * 1000.0 |> int
printfn "%s" "I was here"
let rand = System.Random(sd)
let rms = rand.Next(500)
System.Threading.Thread.Sleep rms
let tmp2 =
tmp
|> R.cbind // This line prints something on the console the first time it is executed
printfn "%s" "And here too"
tmp2
The code above includes random number generation and calls to System.Threading.Thread.Sleep. If I do not include this code, which is not needed under sequential execution, I get a message:
System.ArgumentException: 'An item with the same key has already been added.'
and the following on the console:
I was here
I was here
[1] 4095
So execution never gets to the And here too lines.
When I include the random number generator and the call to sleep I get different results, which seem to depend on the build options.
Below are four examples, with the build options, error message and what I see on the console. Notice that in all examples there are four instances of I was here but only three instances of And here too.
---------------------------------------
Any CPU with Prefer 32-bit checked
System.Runtime.InteropServices.SEHException: 'External component has thrown an exception.'
I was here
I was here
[1] 4095
And here too
I was here
And here too
I was here
And here too
Warning: stack imbalance in 'lazyLoadDBfetch', 66 then 65
Error in value[[3L]](cond) : unprotect_ptr: pointer not found
---------------------------------------
Any CPU with Prefer 32-bit unchecked
System.Runtime.InteropServices.SEHException: 'External component has thrown an exception.'
I was here
I was here
[1] 1.759219e+13
And here too
I was here
And here too
I was here
And here too
Error: cons memory exhausted (limit reached?)
Error: cons memory exhausted (limit reached?)
---------------------------------------
x86
System.AccessViolationException" 'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.'
I was here
I was here
[1] 4095
And here too
I was here
And here too
I was here
And here too
---------------------------------------
x64
Exception thrown: 'System.AccessViolationException' in Unknown Module. Attermpted to read or write protected memory.
$$$ - MachineLearning.signal: Calculating signal for ticker AAPL
$$$ - MachineLearning.signal: Calculating signal for ticker AAPL
I was here
I was here
[1] 1.759219e+13
And here too
I was here
And here too
I was here
And here too
Error in loadNamespace(name) :
no function to return from, jumping to top level
Based on my experience with debugging subtle issues with threading in the R type provider, I think the answer is no - sadly, the R native interop layer is not thread-safe and so you cannot call it from multiple threads in your F# application.
I think that the standard way of running R in parallel is to spawn multiple R.exe processes doing the work. I don't think you can easily initialise multiple independent R processes from F#, so your best bet is probably to create multiple .NET processes that each controls one R engine.

Unit testing with `testthat` on functions that write/read files, or a Fortran error

What is the best way to make unit testing with testthat on functions that read and write files?
Apologies for asking a complicated question, but I am not sure what is wrong here.
I have implemented a number of functions in Fortran, that reads and writes files. They are compiled in an R package cf. Writing R Extension manual. My unit testing with testthat generates random content that is written to temporary files with tempfile(). Running R CMD check on the R package works on my local Windows machine.
Running with R-devel fails however because it cannot detect Rtools for R-3.5.0 (devel). So I submitted to win-builder.
http://win-builder.r-project.org/ however fails with the following error:
At line 9 of file auxil.f95
Fortran runtime error: Actual string length is shorter than the declared one for dummy argument 'fn' (96/255)
with corresponding Fortran source:
subroutine get_nlines(fn, nlines, stat) !line 9
implicit none
!! Arguments
character(255), intent(in) :: fn
integer, intent(out) :: nlines, stat
!! Local variables
character(len=1) :: one
nlines = 0
open(40, file=fn, status='OLD')
do
read(40, *, iostat=stat) one
if (stat /= 0) exit
nlines = nlines + 1
end do
close(40)
end subroutine
The Fortran code is stored in the src subdirectory of the R package, and is called with
get_nlines <- function(fn) {
stopifnot(file.exists(fn))
res <- .Fortran('get_nlines', fn=as.character(fn), nlines=integer(1), stat=integer(1))
if (res$nlines == 0 & res$stat != 0) {
warning(paste0('get_nlines did not read lines; IOSTAT error ', res$stat, '.'))
return(structure(NA, code=res$stat))
}
res$nlines
}
So there it is.
I don't know if my Fortran code is wrong, or if it's something that occurs on the win-builder server.
"I don't know if my Fortran code is wrong" I still simply don't understand from your question if the code you have shown is "the" your code or if it is inside some R package you are using.
If it is the Fortran code you are speaking about (you didn't show anything else), then you should try character(*) instead of character(255), because there is no apparent reason for the exact fixed length 255. That is exactly what the error message complains about, that fn is not exactly 255 chars long as you require in get_nlines().

Weird inexact error in julia

I have two instances of my program tracked with git, so I know that they are in sync. One instance is in machine A and the other in machine B.
Machine A runs fine, but when I go to machine B I obtain the following error:
ERROR: InexactError()
in setindex! at array.jl:307
in setindex! at array.jl:345
in main at /path/to/main.jl:122
in include at ./boot.jl:246
in include_from_node1 at loading.jl:128
in process_options at ./client.jl:285
in _start at ./client.jl:354
in _start_3B_3587 at /home/usr/julia/usr/bin/../lib/julia/sys.so
while loading /path/to/main.jl, in expression starting on line 265
I don't understand why it throws and error. Both machines have the last master version of Julia:
Version 0.4.0-dev+3322 (2015-02-12 13:56 UTC)
Commit 1ec68b3* (0 days old master)
The lines that throw the error are
array2 = zeros(Float64,NHn*2000)
for iRealiz in 1:2000
...
ij = (iRealiz-1)*NHn
egvals_ts, egvecs_ts = eig(timeser)
array2[ij+1:ij+NHn] = egvals_ts
...
end
NHn is the matrix dimension.
An Inexact Error gets thrown when you try to convert a value x to a type T that cannot represent the value of x. For example, on julia 0.4:
julia> convert(Int, 3.0)
3
julia> convert(Int, 3.2)
ERROR: InexactError()
in convert at int.jl:189
julia> convert(UInt, -2)
ERROR: InexactError()
and finally, in what is likely relevant for your case:
julia> convert(Float64, 2+0.3im)
ERROR: InexactError()
in convert at complex.jl:16
My theory is that roundoff errors (which are dependent on the particular CPU) caused it to return complex-valued eigenvalues on one machine but not the other.

octave map over multiple arguments

I want to map a function that takes two arguments over two vectors of the same length, taking an argument from each of these vectors. I can do it with one argument:
map(#sqrt, 1:10)
ans = ....
help map gives the following example:
map(#min, A, B)
ans = ...
where A and B are 2 by 2 matrices, and the result matrix is the element-wise minimum. But when I try this example, I get the following error:
A = rand(2,2);
B = rand(2,2);
map(#min, A, B)
error: invalid assignment to cs-list outside multiple assignment.
error: assignment to cell array failed
error: assignment failed, or no method for `<unknown type> = scalar'
error: called from:
error: C:\Octave\3.2.4_gcc-4.4.0\share\octave\packages\miscellaneous-1.0.9\map.m at line 108, column 21
What am I doing wrong? My system is Win7, 64 bit, and as you can see, my octave version is 3.2.4.
Thanks to this question, I was able to find out that map is being deprecated, and the correct function to use is arrayfun, which works out of the box, both with octave version 3.2.4, which is what I got when downloading a normal windows installer, and with octave version 3.6.2, which I got using cygwin. In version 3.6.2 it even seems that map requires the miscellaneous package, which arrayfun does not.
So I will never know what I did wrong, or if there is a bug (unlikely, given that the function is pretty standard), but my problem was solved by just substituting arrayfun:
A = rand(2,2);
B = rand(2,2);
arrayfun(#min, A, B)
ans = .... % correct answer

Resources