Multiple functions with different return values llvm ir code - malloc

Question
How can I access an external function (malloc) that has multiple possible return values? With malloc, I would like to be able to use it to get a pointer to an array and an array of arrays as is shown below. What is the best way to do this?
IR Code
declare [4000 x double]* #malloc(i64)
declare [4000 x [4000 x double]]* #malloc(i64)
Error
out.ll:3:35: error: invalid redefinition of function 'malloc'
declare [4000 x [4000 x double]]* #malloc(i64)
^
1 error generated.

Related

Online GDB for Fortran: Error: Symbol ‘average1’ at (1) already has basic type of REAL [duplicate]

I have this function, depicted below. It passes in two vectors with three values each, and should pass out one vector with three values as well. I call the function like this:
Fr = Flux(W(:,i),W(:,i+1))
What I have realized through messing around with the code, trying pure functions, and modules, and researching the error statement (that I will include at the bottom), is that fortran is reading my function Flux, and thinks that the input vectors are an attempt to call an entry from the array. That is my best guess as to what is going on. I asked around the lab and most people suggested using subroutines, but that seemed clunky, and I figured there should probably be a more elegant way, but I have not yet found it. I tried to define a result by saying:
DOUBLE PRECISION FUNCTION Flux(W1,W2) Result(FluxArray(3))
and then returning fluxarray but that does not work, as fortran cannot understand the syntax
The actual Function is this:
DOUBLE PRECISION FUNCTION Flux(W1,W2)
USE parameters
IMPLICIT NONE
DOUBLE PRECISION, DIMENSION(3), INTENT(IN)::W1, W2
DOUBLE PRECISION, DIMENSION(3), INTENT(OUT):: Flux
DOUBLE PRECISION, DIMENSION(3):: F1, F2
DOUBLE PRECISION::U1,U2,Rh1,Rh2,P1,P2,E1,E2,Rh,P,u,c,Lambda
INTEGER:: k
U1=W1(2)/W1(1)
U2=W2(2)/W2(1)
Rh1=W1(1)
Rh2=W2(1)
P1=(gamma_constant-1.d0)*(W1(3)-.5d0*Rh1*U1**2)
P2=(gamma_constant-1.d0)*(W2(3)-.5d0*Rh2*U2**2)
E1=W1(3)
E2=W2(3)
F1=[Rh1*U1,Rh1*U1**2+P1,(E1+P1)*U1]
F2=[Rh2*U2,Rh2*U2**2+P2,(E2+P2)*U2]
Rh=.5d0*(Rh1+Rh2)
P=.5d0*(P1+P2)
u=.5d0*(U1+U2)
c=sqrt(gamma_constant*P/Rh)
Lambda=max(u, u+c, u-c)
do k=1,3,1
Flux(k)=.5d0*(F1(k)+F2(k))-.5d0*eps*Lambda*(W2(k)-W1(k))
end do
RETURN
END FUNCTION Flux
Here is the error statement:
Quasi1DEuler.f90:191.51:
DOUBLE PRECISION, DIMENSION(3), INTENT(OUT):: Flux
1
Error: Symbol 'flux' at (1) already has basic type of REAL
Quasi1DEuler.f90:217.58:
Flux(k)=.5d0*(F1(k)+F2(k))-.5d0*eps*Lambda*(W2(k)-W1(k))
1
Error: Unexpected STATEMENT FUNCTION statement at (1)
Quasi1DEuler.f90:76.18:
Fr = Flux(W(:,i),W(:,i+1))
The last error occurs for both Fr and Fl. Thank you for your time and any help or consideration you can give!
EDIT/Follow-up::
Thanks for the help, I don't know a better way to present this so I'm going to edit the initial question.
I did as you suggested and It solved that issue, now it says:
Fr = Flux(W(:,i),W(:,i+1))
1
Error: The reference to function 'flux' at (1) either needs an explicit INTERFACE or the rank is incorrect
I saw a similar issue on SO at this link:
Computing the cross product of two vectors in Fortran 90
where they suggested that he put all his functions into modules. is there a better/simpler way for me to fix this error?
With RESULT(FluxArray), fluxArray is the name of the result variable. As such, your attempt to declare the characteristics in the result clause are mis-placed.
Instead, the result variable should be specified within the function body:
function Flux(W1,W2) result(fluxArray)
double precision, dimension(3), intent(in)::W1, W2
double precision, dimension(3) :: fluxArray ! Note, no intent for result.
end function Flux
Yes, one can declare the type of the result variable in the function statement, but the array-ness cannot be declared there. I wouldn't recommend having a distinct dimension statement in the function body for the result variable.
Note that, when referencing a function returning an array it is required that there be an explicit interface available to the caller. One way is to place the function in a module which is used. See elsewhere on SO, or language tutorials, for more details.
Coming to the errors from your question without the result.
DOUBLE PRECISION FUNCTION Flux(W1,W2)
DOUBLE PRECISION, DIMENSION(3), INTENT(OUT):: Flux
Here the type of Flux has been declared twice. Also, it isn't a dummy argument to the function, so as above it need not have the intent attribute.
One could write
FUNCTION Flux(W1,W2)
DOUBLE PRECISION, DIMENSION(3) :: Flux ! Deleting intent
or (shudder)
DOUBLE PRECISION FUNCTION Flux(W1,W2)
DIMENSION :: Flux(3)
The complaint about a statement function is unimportant here, following on from the bad declaration.

How can I fix the Expected a constant as index error?

I'm trying to do some projects on Verilog, and I have a problem with constant index errors.
integer k=32;
reg[k-1:0] inputs;
In this code, the Verilog compiler gives me this message:
Expected a constant as index error in Verilog
I must use integer k in this project. How can I solve this problem?
integer is a variable type. As the error message states, you need a constant type, such as parameter:
parameter k=32;
reg[k-1:0] inputs;

Fortran CHARACTER FUNCTION without defined size [duplicate]

I am writing the following simple routine:
program scratch
character*4 :: word
word = 'hell'
print *, concat(word)
end program scratch
function concat(x)
character*(*) x
concat = x // 'plus stuff'
end function concat
The program should be taking the string 'hell' and concatenating to it the string 'plus stuff'. I would like the function to be able to take in any length string (I am planning to use the word 'heaven' as well) and concatenate to it the string 'plus stuff'.
Currently, when I run this on Visual Studio 2012 I get the following error:
Error 1 error #6303: The assignment operation or the binary
expression operation is invalid for the data types of the two
operands. D:\aboufira\Desktop\TEMP\Visual
Studio\test\logicalfunction\scratch.f90 9
This error is for the following line:
concat = x // 'plus stuff'
It is not apparent to me why the two operands are not compatible. I have set them both to be strings. Why will they not concatenate?
High Performance Mark's comment tells you about why the compiler complains: implicit typing.
The result of the function concat is implicitly typed because you haven't declared its type otherwise. Although x // 'plus stuff' is the correct way to concatenate character variables, you're attempting to assign that new character object to a (implictly) real function result.
Which leads to the question: "just how do I declare the function result to be a character?". Answer: much as you would any other character variable:
character(len=length) concat
[note that I use character(len=...) rather than character*.... I'll come on to exactly why later, but I'll also point out that the form character*4 is obsolete according to current Fortran, and may eventually be deleted entirely.]
The tricky part is: what is the length it should be declared as?
When declaring the length of a character function result which we don't know ahead of time there are two1 approaches:
an automatic character object;
a deferred length character object.
In the case of this function, we know that the length of the result is 10 longer than the input. We can declare
character(len=LEN(x)+10) concat
To do this we cannot use the form character*(LEN(x)+10).
In a more general case, deferred length:
character(len=:), allocatable :: concat ! Deferred length, will be defined on allocation
where later
concat = x//'plus stuff' ! Using automatic allocation on intrinsic assignment
Using these forms adds the requirement that the function concat has an explicit interface in the main program. You'll find much about that in other questions and resources. Providing an explicit interface will also remove the problem that, in the main program, concat also implicitly has a real result.
To stress:
program
implicit none
character(len=[something]) concat
print *, concat('hell')
end program
will not work for concat having result of the "length unknown at compile time" forms. Ideally the function will be an internal one, or one accessed from a module.
1 There is a third: assumed length function result. Anyone who wants to know about this could read this separate question. Everyone else should pretend this doesn't exist. Just like the writers of the Fortran standard.

Using Rcpp's runif() function within in RcppArmadillo's sample() function

I have an Rcpp script where I do the following:
double m = runif(1); // generate a random number uniformly between 0 and 1.
I then pass m to sample() as follows:
IntegerVector ind = RcppArmadillo::sample<IntegerVector>(perms, ceil(num_specs * m), false); // int perms, num_specs.
The above line results in an error:
error: no viable conversion from 'NumericVector' (aka 'Vector<14>') to 'double'
Unless my thinking (or declarations) is flawed, runif(1) is a scalar (double) not a vector (NumericVector).
The above works fine when I declare:
double m = 0;
Could someone point out how to get around the issue with runif()?
Have a look at the RcppArmadilloExtensions/ directory in the RcppArmadillo header directory -- there is an entire sample() example set up for RcppArmadillo.
And there are
a first Rcpp Gallery post
a second Rcpp Gallery post
with an examples for sampling using it.
Otherwise your problem may be one of confusing the scalar R::runif() (using the C API of R) with the vectorised Rcpp::runif() returning a vector. If you are more explicit about which one you use (i.e. explicit namespacing with ::) your code may still work.

Function changing variables outside of the function (that is not Returned by the function)

First off really sorry for the nondescript title, I don't know how to phrase my question.
Given the code below:
x = [9]
y = [2,4,6]
def f(x, y):
if len(x) > 0:
z = x + y
x.pop(-1)
return z.pop(0)
print(f(x,y)
print(f(x,y))
The second print line gives me an UnboundLocalError: local variable 'z' referenced before assignment
I understand what this error is, as the function is skipping the if clause and going straight to the return z.pop(0), but z doesn't exist because z is defined in the if clause.
What I would like to know is why the value of x is changed by the function
The function skips the if loop because after the first call, x has been changed from x = [9] to x = []
I thought that unless it is a Return statement, then any variables changed or created within a function are local to the function?
For example, geeksforgeeks.org states that
Any variable which is changed or created inside of a function is local, if it hasn’t been declared as a global variable
So why is the value of x changing when it hasn't been returned by the function? Shouldn't the value of x always be [9]?
Thank you
Lists are mutable. When you pass one into the function then you are really passing in a pointer to the list. It's better to think of Python as pass by reference than pass by value. The x you are changing is not created in the function it is passed in as an argument. You're not changing x (the memory address pointed to by the label x), you're changing the contents of that memory address.
See this answer Python functions call by reference

Resources