-1

Not sure if this is even possible. I need to pass a function from C to C++. It cannot be a function pointer.

C++ Function that I need to call:

template<class Lam>
void parfor(int N, Lam lam) {
  lam(i);
}

C Function that I want to give to parfor (ptr can be a global pointer here):

void calc(int num) {
  ptr[0] = num;
}

C Main to look like this:

include <ParFor.hpp>
parfor(calc, 1);

I could put my function definitions inside a header. On the C++ side I have a function (from an outside library) that takes a C++ lambda or a C++ functor. It's templated to a lambda

My current thinking is put my C functions inside a file, compile LLVM IR for them and somehow force inline the IR generated by clang into my C++ function. C calls mycppfunc(mycfunc). mycppfunc has the LLVM IR for mycfunc and is able to generate proper code. I tried this but but compiler crashes at link stage due to what seems to be incompatible IRs.

  • 1
    It's easier to reason about code that we see, over code that is (vaguely) described. – StoryTeller - Unslander Monica May 13 '20 at 13:32
  • 1
    How might one represent a C function *without* a function pointer? – Scott Hunter May 13 '20 at 13:34
  • 1
    [XY problem](https://en.wikipedia.org/wiki/XY_problem). – n. m. could be an AI May 13 '20 at 13:39
  • @StoryTeller-UnslanderMonica Added a few code snippets to clarify – Paulius Velesko May 13 '20 at 13:41
  • "I tried to kill a fly so I detonated a tactical nuke and now the city and everything in it is radioactive, send help". That's how a description of your attempt sounds, more or less. Let's try to clean up the mess. You can call C code from C++. You cannot call C++ specific code (templates, lambdas, member functions) directly from C. You may call such C++ code from C indirectly, by wrapping your template or whatever in an ordinary C++ function with `extern "C"` linkage. Have you tried that? – n. m. could be an AI May 13 '20 at 13:56
  • @n.'pronouns'm. Sorry, my first or second time posting here. How do I deal with the fact that my C++ is templated to a lambda? If it were just return types and arguments sure I could specialize those and call extern C but this is not the case. The C++ function needs a lamda to generate device code so thus I can't use function pointers and asked the question of how to pass the function body from C to C++ – Paulius Velesko May 13 '20 at 14:00
  • @PauliusVelesko - It doesn't look like it needs a lambda. By your description it needs something *invocable*. And function pointers are the original invocable objects. – StoryTeller - Unslander Monica May 13 '20 at 14:04
  • @StoryTeller-UnslanderMonica lambda goes into JIT and function pointer does not provide the source code/IR to generate device side assembly. In my description I noted that I cannot use function pointers so thus me asking this question. I tried to narrow it down as much as possible. – Paulius Velesko May 13 '20 at 14:08
  • "my C++ is templated to a lambda" I don't understand what this could possibly mean. Shown C++ code is a bog standard function template that can accept a normal function, a function object, or a lambda.. "lambda goes into JIT" I don't believe anything like that exists in the observable universe. But this doesn't actually matter. **You don't call your template from C. You call it from an intermediate C++ code**. You pass it whatever it needs. A lambda, an object, a devil with horns. Your C code doesn't care, it doesn't see any of this. It calls your C++ wrapper, a normal `extern "C"` function. – n. m. could be an AI May 13 '20 at 14:29
  • @n.'pronouns'm. A SYCL parallel for, or Kokkos, RAJA all work in similar ways - pass a lambda, compile it to a specific device. Sounds like your solution is to just use C++ (your intermediate layer) which is out of the scope of this exercise. – Paulius Velesko May 13 '20 at 14:51
  • @PauliusVelesko Uh, it you want to compile something for a specific device, then you need to feed the source code to a compiler that can generate code for that device. I don't quite understand how you plan to get around that. – n. m. could be an AI May 13 '20 at 20:01
  • @n.'pronouns'm. Well my current approach is IR injection but that was kind of the whole point of asking this question. That's what I meant by "pass a function body" in the title of this question. Sorry if that wasn't clear but I thought "source" is not the best word to be used here since it can be represented by IR as well. – Paulius Velesko May 14 '20 at 03:59
  • Now this doesn't have any sense whatsoever. If you have the IR, you have the source code. Why not just use the source code? If you for some unknown reason need to manipulate LLVM IR, which looks about 1,000,000,000 times more work to me, then you are asking the wrong question in the wrong place. Your question should be "How do I inject LLVM IR etc etc" and tagged with appropriate tags. It is only tangentially related to C or C++ as IR is mostly language agnostic. – n. m. could be an AI May 14 '20 at 16:38

1 Answers1

0

From the code snippets and the comments I understand that you attempt to launch a C kernel using a SYCL parallel_for.

From an official support perspective, since the SYCL device compiler is by definition a C++ compiler (as SYCL is a programming model based on C++), the kernel code must be parsed as C++ code. I don't think there's any official way to achieve any more interoperability with C code than to just try to compile it as C++ by the device compiler. However, I have the impression that you are more interested in experimenting with interoperability beyond this as a research project.

For this, injecting IR might be a path worthy of investigation but I don't think that it will be straight-forward. Depending on which SYCL features you use, the device compiler might need to perform additional IR transformations to achieve correct semantics. So, you might have to replicate these transformations in order to inject your IR. You might end up reinventing a SYCL compiler for C...

Since any more in-depth discussion about this requires extensive knowledge of the internal implementation details of your SYCL implementation, I would suggest that you contact the developers of your implementation directly for clarification.

illuhad
  • 506
  • 2
  • 5