[SOLVED] Julia – How macros are related (based on exemple from OpenCL.jl

Issue

This Content is from Stack Overflow. Question asked by user3680029

I’ve put a discord but no result. May be here somebody could help me

When you look in the OpenCL implementation code you have two macros that seems to refer one another in some (misterious) way, I cannot see how this happens. One macro is @check define in src/ macros.jl the other one @ocl_func define in api.jl.
@check is responsible for running the clfunc => $(esc(clfunc)), but as far as I understood it is the @ocl_func macro (in the api.jl file) that will ccall the clfunc.

My question how does the ‘called’ clfunc, for example this one:

@check api.clGetPlatformIDs(0, C_NULL, nplatforms) (in /platforms.jl) 

is passed to the @ocl_func macro?

Is it implicit( because the ocl macro is define in api so every function called with api.will activate the macro, in the example it will be then:

@ocl_func(clGetPlatformIDs(0, C_NULL, nplatforms)) )

I cannot find the code which glue the two macros. Clarifying this will help me to understand how macros work.



Solution

An easy way to think about macros is that they are source-code generation tools.

as far as I understood it is the @ocl_func macro (in the api.jl file) that will ccall the clfunc.

If you look at the the implementation of @ocl_func, you’ll see that the ccall is part of a quote block, that’s being returned. So it’s not that @ocl_func will ccall the clfunc, rather @ocl_func generates the source code expression which ccalls the clfunc. The quoted block that is returned by a macro is seen as source code by Julia and is compiled like any other code, a function definiton in this case.

So when Julia sees the line:

@ocl_func(clGetPlatformIDs, CL_int,
              (CL_uint, Ptr{CL_platform_id}, Ptr{CL_uint}))

this gets turned into a function definition that uses ccall inside it.

Similarly, @check also generates code that does an error check and throws if it’s not a success. @check doesn’t need to know about @ocl_func, instead both just expand into the quoted code that they return, so any interaction is between those generated code blocks.

My question how does the ‘called’ clfunc, for example this one:

@check api.clGetPlatformIDs(0, C_NULL, nplatforms) (in /platforms.jl)

is passed to the @ocl_func macro?

The function definition for api.clGetPlatformIDs is generated by the @ocl_func macro, but once its generated it can be called like any normal function, and that’s what’s happening here. So there’s no dependency between @check and @ocl_func necessary for this to work.


This Question was asked in StackOverflow by user3680029 and Answered by Sundar R It is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.

people found this article helpful. What about you?