-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
global const variables in __init__() are useless #13817
Comments
My current very poor work around is to essentially remove the const declarations and call init() twice. I do the latter by copying the contents of init() outside the function declaration as a cheesy way to use type inference to initialize my global variables. This probably won't be a very good idea for a sufficiently complex module. |
That recommendation should be removed. You can use a const |
So is the idea is the idea that you should write something like this?: module Foo
type Bar
...
end
global const bar = Ref{Bar}()
function __init__()
bar() = unsafe_load(cglobal((:bar,lib),Bar))
end
end #module If so, is there any way we could express this in one line to reduce the amount of code? |
You mean
Not too easy currently (I hope we can register In the long term, I believe this is basically the plan to improve the performance of globals. See #11456 (comment) and related discussions linked from that thread. |
I think the technical part of this issue is already well covered in a number of global related issues. Add |
@yuyichao As far as the const Ref idea, how could I use it to initialize cumatmul in the above example? My problem is that the cumatmul variable is used in this line, which from the CUDArt package requires a fairly complex C signature. Is the Ref declaration sort of the equivalent of void *? I was getting type errors when I tried to initialize this variable naively. |
I don't really understand the problem. You don't seem to be calling I'm not exactly sure what is the type of the using CUDArt
const MaxBlocks = 65535
const MaxThreads = 1024
const MyBlocks = MaxBlocks
const devnumber = 0
# Replace these with actual concrete types (if they are not already)
const gpumd = Ref{CuModule}()
const cuaper = Ref{CuFunction}()
const cumatmul = Ref{CuFunction}()
function __init__()
# select a CUDA device
CUDArt.init(devnumber)
# load the PTX module (each module can contain multiple kernel functions)
gpumd[] = CuModule("aper.ptx",false)
# get kernel functions
cuaper[] = CuFunction(gpumd[], "cuaper")
cumatmul[] = CuFunction(gpumd[], "matmul")
end
function gmmul(gA, gB)
rA = convert(Int32, size(gA, 1))
cA = convert(Int32, size(gA, 2))
cB = convert(Int32, size(gB, 2))
gC = CudaArray(Ftype, (size(gA, 1), size(gB, 2)))
blksize = min(MaxThreads, cB)
gridsize = min(MyBlocks, rA)
launch(cumatmul[], gridsize, blksize, (gA, rA, cA, gB, cB, gC))
return gC
end
end |
Might be nice to update the documentation if |
With the update to Julia 1.0 the Ref{} approach seems to have some trouble. Maybe someone can help?
The trouble is the "lib" is not known. Am I missing something here? The persistent variable is needed to make JavaCall a bit nices, such that several modules can "register" their classpath via the JavaCall.addClasspath method before the JVM is started. However, since these are using JavaCall from different modules, each of these has a different internal classpath variable. |
|
Thanks for the comment, but I did not intend to call any library. I am just looking for a way to have a variable collecting strings throughout all using JavaCall occurances. Do you mean that for this aim, one would need to write a library that is external to Julia and then call it? This sounds like a lot of work... |
I'm not really sure what you're asking, but it sounds like it would be better discussed as an issue on the JavaCall.jl repository. |
I think I now found a workable solution by misusing the ENV mechanism.
|
You can do the same thing with module A
const classpath = Ref("")
function register(myClassPath)
sep = ";"
if classpath[] == ""
classpath[] = string("-Djava.class.path=",myClassPath)
else
classpath[] = string(classpath[],sep,myClassPath)
end
end
end
module B
using Main.A
function __init__()
A.register("myclassPath_B")
end
end
module C
using Main.A
function __init__()
A.register("myclassPath_C")
end
end
using Main.B
using Main.C |
I see. And then access the value via
|
Better to use |
By the way. I had to find out the hard way, that for this to work, it is important to put the code in init() rather than just into the main body of the module. |
I am trying to precompile some of my modules, one of which tries to initialize some cuda kernels which must be done at run time. I have code that looks something like this,
The use of global const variables in init() is recommended in the documentation.
Unfortunately cumatmul is not defined in gmmul() because init() is called after evaluating the rest of the code in the file. Therefore this file will not compile. I see no way to use cumatmul and it certainly can't be a constant.
Even worse if you try to initialize it outside of init() and then let init() update it's value, you lose the ability to do type inference. This is really annoying since I have no idea how to do default initializations of some of these complex C types.
Is there some code pattern here that actually lets you precompile modules that must initialize data using external C libraries? It sure doesn't make sense to define global constants that can nowhere be used in your actual module.
The text was updated successfully, but these errors were encountered: