Brad,

This worked very nicely for me -- thanks!

-- Nikhil

---------------------------------
Nikhil Padmanabhan
[email protected]

On Fri, Mar 18, 2016 at 8:30 PM, Brad Chamberlain <[email protected]> wrote:

>
> Oh shoot, I misunderstood something about the role of the extern-code.c
> file...  I thought that it was being generated by the compiler for use at C
> compile+link-time.  However, I now believe that it's actually being used by
> the clang-based front-end as a place to store and compile the extern blocks
> of C code themselves.  This happens very early in compilation, which means
> that we haven't yet gotten to the codegen pass I was positing that could
> emit a header file of exported prototypes.  :(
>
> However, now that I understand it, this suggests another workaround
> (albeit a not-completely-satisfying one).  In your extern C code block, if
> you add a C prototype for the routine that the Chapel compiler will create
> (which presumes you can anticipate what its C signature will be), you can
> add a C 'extern' declaration referring back to the Chapel routine that will
> appear later:
>
>   extern double integrand(double x, void* ptr);
>
> Once I add this to your code, it compiles for me with the master branch of
> the project.
>
> It's worth noting that the generation of the header file of exported
> routines could help make this more bulletproof because if there was a
> disagreement between what the compiler created and what you expected it to
> create, the C compiler would complain at you (OTOH, it may also add
> fragility, as it doesn't take much to make some C compilers complain about
> differing prototypes -- like using different type aliases for the same
> underlying type)..
>
> I'll be curious if Michael (who developed the extern blocks) might have a
> smarter proposal than this one...  I'm clearly learning on the job today.
>
> -Brad
>
>
> On Fri, 18 Mar 2016, Brad Chamberlain wrote:
>
>
>> For the sake of the mailing list:
>>
>> Off-list, we confirmed that Nikhil is using 1.12.  I remember hearing
>> that support for c_void_ptr had gotten better since the last release, and
>> believe that the difference we're seeing is the result of that.
>>
>> Meanwhile, I'm starting the process of taking a quick look into what it
>> would take to dump (at least simple) export'ed routines into their own
>> header file (and/or protecting things in chpl__header.h that can't afford
>> to be #included twice.  (That said, I am close to timing out for the night).
>>
>> -Brad
>>
>>
>> On Fri, 18 Mar 2016, Nikhil Padmanabhan wrote:
>>
>> Hi Brad,
>>>
>>> I'm missing something here.
>>>
>>> When I try
>>>   chpl testit.chpl --savec output
>>>
>>> I get
>>>   testit.chpl:12: error: illegal cast from c_void_ptr to c_ptr(R)
>>>
>>> It only has two files in the output directory --- it doesn't look like it
>>> even got to making the chpl__header.h file.
>>>
>>> Hm.
>>> -- Nikhil
>>>
>>>
>>> ---------------------------------
>>> Nikhil Padmanabhan
>>> [email protected]
>>>
>>> On Fri, Mar 18, 2016 at 7:17 PM, Brad Chamberlain <[email protected]>
>>> wrote:
>>>
>>>
>>>> Hi Nikhil / all (Michael in particular may want to perk up as extern
>>>> block
>>>> master) --
>>>>
>>>> This may be a relatively simple fix.  What I find (at least with my
>>>> version of gcc, which is... uh... Apple LLVM version 7.0.2) is that if I
>>>> compile with --savec on, the one thing that's missing is the prototype
>>>> of
>>>> the 'export'ed function integrand within the 'extern block'ed code
>>>> stored
>>>> in output/extern-code.c.  That is, if I:
>>>>
>>>> * paste the code you mailed into testit.chpl
>>>>
>>>> * compile it with an LLVM-enabled copy of 'chpl' with:
>>>>
>>>>         chpl testit.chpl --savec output
>>>>
>>>> * get the prototype for the export'ed function integrand:
>>>>
>>>>         grep integrand output/chpl__header.h
>>>>
>>>> * paste it into the top of output/extern-code.c:
>>>>
>>>>         <use your favorite editor>
>>>>
>>>> * recompile:
>>>>
>>>>         make -f output/Makefile
>>>>
>>>> then things work for me (or at least the code compiles and generates:
>>>>
>>>>         (alpha = 1.0)
>>>>
>>>>
>>>> If you can reproduce this, I think that the fix in the compiler would be
>>>> as simple as:
>>>>
>>>> * making sure to put all export'ed routines into a header of their own
>>>> (we
>>>>   should really be doing this anyway for other clients of the exported
>>>>   routines... it's probably made slightly complicated by having to drag
>>>>   over any types that they make use of as well
>>>>
>>>> * #include-ing that routine in any code files that we generate for
>>>>   extern blocks
>>>>
>>>>
>>>> I'm working on reproducing with a second copy of Chapel, but it means
>>>> having to re-build LLVM... (zzzzz...)
>>>>
>>>> -Brad
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> On Fri, 18 Mar 2016, Nikhil Padmanabhan wrote:
>>>>
>>>> Hi ---
>>>>
>>>>>
>>>>> I'm trying to get a call-back from C into Chapel working -- where the
>>>>> intermediate C routine needs to pass through some data from the
>>>>> function
>>>>> that called it to the function it's calling. (To be specific, the C
>>>>> routine
>>>>> does a numerical integration and it's calling the integrand).
>>>>>
>>>>> The problem here is that the Chapel callback needs to convert the void*
>>>>> back into its original form. Note that it knows exactly what the
>>>>> correct
>>>>> form is -- but Chapel doesn't let me convert a c_void_ptr into
>>>>> anything.....
>>>>>
>>>>> Appended is a relatively simple program (using the extern block
>>>>> feature)
>>>>> that demonstrates the issue. Any thoughts on how to work around this
>>>>> would
>>>>> be great. Ideally, it would be nice to just reconvert the c_void_ptr
>>>>> into
>>>>> a
>>>>> c_ptr that can be dereferences...
>>>>>
>>>>> Thanks in advance!
>>>>> -- Nikhil
>>>>>
>>>>> use SysCTypes;
>>>>>
>>>>> record R {
>>>>>  var alpha : real;
>>>>>  // There could be more complicated things here
>>>>>  // I could define this record in C, but it would be nice
>>>>>  // not to do so.
>>>>> }
>>>>>
>>>>> export proc integrand(x : real, ptr : c_void_ptr) : real {
>>>>>   // THE LINE BELOW DOESN'T WORK
>>>>>   var p = ptr : c_ptr(R); // How do I get this, or equivalent to work
>>>>>   var r = p.deref();
>>>>>   return r.alpha*x;
>>>>> }
>>>>>
>>>>> extern {
>>>>>  static  void integrate(void *p) {
>>>>>    // A real integrator would do more
>>>>>    double y;
>>>>>    y = integrand(1,p);
>>>>>  }
>>>>> }
>>>>>
>>>>> var r1 = new R(1.0);
>>>>> writeln(r1);
>>>>> var p1 = c_ptrTo(r1);
>>>>> integrate(p1:c_void_ptr);
>>>>> ---------------------------------
>>>>> Nikhil Padmanabhan
>>>>> [email protected]
>>>>>
>>>>>
>>>>>
>>>
>>
------------------------------------------------------------------------------
Transform Data into Opportunity.
Accelerate data analysis in your applications with
Intel Data Analytics Acceleration Library.
Click to learn more.
http://pubads.g.doubleclick.net/gampad/clk?id=278785351&iu=/4140
_______________________________________________
Chapel-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/chapel-users

Reply via email to