KhronosGroup / OpenCL-Docs

OpenCL API, OpenCL C, Extensions, SPIR-V Environment Specs, Ref page, and C++ for OpenCL doc sources.
Other
356 stars 113 forks source link

Probem Determining Exported Symbols and Versions from cl.xml #115

Open Kerilk opened 5 years ago

Kerilk commented 5 years ago

I am trying to generate the icd_exports.map of the ICD loader from the cl.xml file. For now it seems impossible without substantial amount of hacks:

This seems a bit too convoluted. Nonetheless this process would be necessary to automatically generate a mock-up/intercept library, or bindings.

Several possibilities exist to alleviate the problem, here are some examples:

I am unsure what the best course of actions would be here, or if I missed something obvious. Any thoughts on the matter?

Thanks,

Brice

oddhack commented 5 years ago

Some feedback, speaking as the person who wrote cl.xml, the XML schema, and most of the Python code that operates on it. TL;DR I can probably assist with this and am probably the best person to do so, although I do need to plan it around other Khronos responsibilities so your timescale is important to know if I'm going to help. Also, I'm unclear if you are doing this as an officially Khronos-sponsored activity, or is this an external project?

cl.xml is (or at least, should be) a complete description of the APIs, but the only current use case is generating the code fragment includes for the specs. I'd like to generate C headers too, but without a clear demand for that from the working group, it has been a questionable use of my time. cl.xml obviously wasn't created with the loader in mind, but I expect that some relatively minor amount of additional tagging or schema additions could accomodate those needs.

While you can certainly write your own XML processing code, which I guess? you've been trying to do based on the issue text, I think you would be better off creating a new generator script that plugs into the existing Python framework. CL doesn't do that yet, but Vulkan and OpenXR both have a lot of custom generators used by the loader and validation layers, CTS, and other ecosystem components. The framework operates by being given a set of core versions & extensions to process, traversing their dependency graph through cl.xml to determine the corresponding tokens, structures, and commands, and calling back to the generator to emit those in whatever fashion is needed.

Without knowing how the ICD determines the supported commands I can't be precise about this, but it sounds like it would be straightforward to fit into the generator framework, either with an explicit exclusion list of commands that you list above, or additional XML attributes as you note.

Determining the API <-> version/extension mapping is not conceptually hard, although it would need some additions to the Python codebase to propagate that information down from the \ / \ tags to the individual APIs. We have a potential use for this in Vulkan as well, so it's been sitting on my queue for a while. The interesting, and rare (for anything except base API types) case is when multiple core versions or extensions require the same API, and the simplest thing to do is probably just track all of them and let the generator script decide amongst them.

I don't know if you need the deprecation information for the ICD? I left this with adding attributes containing the deprecation macros, but again, lacking a requirement for autogenerated headers, this is probably a bit incomplete and/or out of date. Also the particular syntax ('prefix'/'suffix' attributes on \ tags) was chosen solely to have an place to record this information, and I'm not attached to it. A better approach might be to capture this information in the version \ tags and propagate it to the corresponding commands from there. I was literally just reflecting the headers as written today since I had no immediate use for the information.

Lastly, I and other people working a lot with the schema and framework inside Khronos are trying to keep them as unified as possible across the four or five APIs that use them. So if you do end up needing schema and/or scripting changes to do this, I want to be in the loop on it.

Kerilk commented 5 years ago

First, thanks for the very detailed answer.

For now let's say this is a side project, but as maintainer of ocl-icd, and Ruby opencl bindings, and member of the Khronos OpenCL working group, I see an interest in the issue being discussed. I am really not an expert in XML schema design so I won't be pressing for specific solutions.

For more precise answers to your questions:

I do like your idea of capturing the original version, deprecation version in the tag, and maybe keep the prefix and suffix as boolean attributes for commands (allowing to regenerate identical headers). For now, the coherency of the headers on this account is questionable as some symbols have neither prefix nor suffix (there might be a good reason for that, or not).

bashbaug commented 5 years ago

FWIW, I've been experimenting a lot with code generation using the cl.xml file recently and things are generally going fairly well. I've focused mostly on core APIs for now, but I'd like to experiment with auto-generating an extension loader from the XML file at some point in the future.

I looked at the existing Python framework but it looked like overkill for what I needed, so I ended up using a Python + Mako toolchain instead, which was sufficient for my needs.

Don't take it too seriously, but in case it's useful, an example can be found here.

Regarding the ICD loader exports specifically, I don't think that the ICD loader should export any extension functions. See:

https://github.com/KhronosGroup/OpenCL-ICD-Loader/blob/master/loader/linux/icd_exports.map

A few extension functions are implemented in the ICD loader, but my understanding is that these are for backwards compatibility only, and that future extension APIs will not modify the ICD loader. See:

https://github.com/KhronosGroup/OpenCL-ICD-Loader/blob/master/loader/icd_dispatch.c#L1585