Re: A question about C++ interop
On Saturday, 28 March 2020 at 19:14:38 UTC, YD wrote: Hi, now I have a further question: when the C++ class A actually has a method that looks like virtual void get_info(std::string ) const = 0; in order to preserve the virtual function table layout (I found that if I omit this function completely in the D declaration, and try to use a virtual member function originally defined in C++ after this function, the result is core dump), even if I don't use this function, in the D file I have to put in line like this abstract void get_info(basic_string!(char) s) const; Yes, ABI implies that. If you don't use it at all you can just put a dummy entry like in the following code, otherwise it tries to call wrong method. In many cases it will just crash, but this also could introduce very hard to find bugs when vtable is changed due to class changes, and the method that you were trying to call landed in vtable on another method with same signature - Imagine having API like Database class and instead of dump database it will drop all tables... phew. ... // other methods void vtable_dummy01() {} // or abstract if it's abstract // other methods ... When I try this on Linux (Ubuntu 18.04), the compiler (both dmd and ldc2) will complain about "std::__cxx11::basic_string is not yet supported", but otherwise the code compiles and links correctly, and can run without problem. STL bindings is unfinished, and don't expect it to be done any time soon. Tiny fractions of it might be present in Phobos (D standard library), but this work was done by few people who really needed that feature and it seems they are now too busy to continue that work. So does this mean that there is no way I can interface to this C++ API in Windows? Thanks. Same here, STL bindings is not yet finished. If you don't need that method specifically, just replace it with a dummy. Or make your own bindings.
Re: auto vectorization notes
On Saturday, 28 March 2020 at 18:01:37 UTC, Crayo List wrote: On Saturday, 28 March 2020 at 06:56:14 UTC, Bruce Carneal wrote: On Saturday, 28 March 2020 at 05:21:14 UTC, Crayo List wrote: On Monday, 23 March 2020 at 18:52:16 UTC, Bruce Carneal wrote: [snip] Explicit SIMD code, ispc or other, isn't as readable or composable or vanilla portable but it certainly is performance predictable. This is not true! The idea of ispc is to write portable code that will vectorize predictably based on the target CPU. The object file/binary is not portable, if that is what you meant. Also, I find it readable. There are many waypoints on the readability <==> performance axis. If ispc works for you along that axis, great! I find SIMT code readability better than SIMD but a little worse than auto-vectorizable kernels. Hugely better performance though for less effort than SIMD if your platform supports it. Again I don't think this is true. Unless I am misunderstanding you, SIMT and SIMD are not mutually exclusive and if you need performance then you must use both. Also based on the workload and processor SIMD may be much more effective than SIMT.j SIMD might become part of the solution under the hood for a number of reasons including: ease of deployment, programmer familiarity, PCIe xfer overheads, kernel launch overhead, memory subsystem suitability, existing code base issues, ... SIMT works for me in high throughput situations where it's hard to "take a log" on the problem. SIMD, in auto-vectorizable or more explicit form, works in others. Combinations can be useful but most of the work I've come in contact with splits pretty clearly along the memory bandwidth divide (SIMT on one side, SIMD/CPU on the other). Others need a plus-up in arithmetic horsepower. The more extreme the requirements, the more attractive SIMT appears. (hence my excitement about dcompute possibly expanding the dlang performance envelope with much less cognitive load than CUDA/OpenCL/SycL/...) On the readability front, I find per-lane programming, even with the current thread-divergence caveats, to be easier to reason about wrt correctness and performance predictability than other approaches. Apparently your mileage does vary. When you have chosen SIMD, whether ispc or other, over SIMT what drove the decision? Performance? Ease of programming to reach a target speed?
Re: A question about C++ interop
On Saturday, 28 March 2020 at 07:33:38 UTC, Jacob Carlborg wrote: On 2020-03-27 20:17, YD wrote: Hi, I have a C++ header file which looks like class A { public: static A *create(); virtual int f() const = 0; }; And there is a C++ library file which provides the implementation, so that if I write a C++ program and call auto *p = A::create(); std::cout << p->f() << '\n'; It will work. Now I want to interface to this C++ library through D, and I wrote module test; import std.stdio; extern(C++) { class A { static A *create(); abstract int f() const; } } void main() { auto p = A.create(); writeln(p.f()); } This program will compile and link, but it core dumps at the call to f(). If I wrap up the C++ interface into a C interface (using a void *), and interface to the wrapped-up C library through D, it will work fine. So what am I doing wrong here? Thanks! Classes in D are always passed by reference. Try dropping the pointer in the `create` method: static A create(); Hi, now I have a further question: when the C++ class A actually has a method that looks like virtual void get_info(std::string ) const = 0; in order to preserve the virtual function table layout (I found that if I omit this function completely in the D declaration, and try to use a virtual member function originally defined in C++ after this function, the result is core dump), even if I don't use this function, in the D file I have to put in line like this abstract void get_info(basic_string!(char) s) const; When I try this on Linux (Ubuntu 18.04), the compiler (both dmd and ldc2) will complain about "std::__cxx11::basic_string is not yet supported", but otherwise the code compiles and links correctly, and can run without problem. But when I try this on Windows 10, dmd will simply refuse to compile it, saying "windows c++ runtime not supported", and ldc2 will allow the compilation but fail at the linking stage, saying something like "error LNK2019: unresolved external symbol __D4core6stdcpp9allocator33_Allocate_manually_vector_alignedFNixkZPv referenced in function __D4core6stdcpp9allocator__TQnTaZQs8allocateMFNikZPa" So does this mean that there is no way I can interface to this C++ API in Windows? Thanks.
Re: auto vectorization notes
On Saturday, 28 March 2020 at 06:56:14 UTC, Bruce Carneal wrote: On Saturday, 28 March 2020 at 05:21:14 UTC, Crayo List wrote: On Monday, 23 March 2020 at 18:52:16 UTC, Bruce Carneal wrote: [snip] (on the downside you have to guard against compiler code-gen performance regressions) auto vectorization is bad because you never know if your code will get vectorized next time you make some change to it and recompile. Just use : https://ispc.github.io/ Yes, that's a downside, you have to measure your performance sensitive code if you change it *or* change compilers or targets. Explicit SIMD code, ispc or other, isn't as readable or composable or vanilla portable but it certainly is performance predictable. This is not true! The idea of ispc is to write portable code that will vectorize predictably based on the target CPU. The object file/binary is not portable, if that is what you meant. Also, I find it readable. I find SIMT code readability better than SIMD but a little worse than auto-vectorizable kernels. Hugely better performance though for less effort than SIMD if your platform supports it. Again I don't think this is true. Unless I am misunderstanding you, SIMT and SIMD are not mutually exclusive and if you need performance then you must use both. Also based on the workload and processor SIMD may be much more effective than SIMT.
Re: A question about C++ interop
On Saturday, 28 March 2020 at 07:33:38 UTC, Jacob Carlborg wrote: On 2020-03-27 20:17, YD wrote: [...] Classes in D are always passed by reference. Try dropping the pointer in the `create` method: static A create(); Thanks! I got it to work for now.
Re: A question about C++ interop
On 2020-03-27 20:17, YD wrote: Hi, I have a C++ header file which looks like class A { public: static A *create(); virtual int f() const = 0; }; And there is a C++ library file which provides the implementation, so that if I write a C++ program and call auto *p = A::create(); std::cout << p->f() << '\n'; It will work. Now I want to interface to this C++ library through D, and I wrote module test; import std.stdio; extern(C++) { class A { static A *create(); abstract int f() const; } } void main() { auto p = A.create(); writeln(p.f()); } This program will compile and link, but it core dumps at the call to f(). If I wrap up the C++ interface into a C interface (using a void *), and interface to the wrapped-up C library through D, it will work fine. So what am I doing wrong here? Thanks! Classes in D are always passed by reference. Try dropping the pointer in the `create` method: static A create(); -- /Jacob Carlborg
Re: auto vectorization notes
On Saturday, 28 March 2020 at 05:21:14 UTC, Crayo List wrote: On Monday, 23 March 2020 at 18:52:16 UTC, Bruce Carneal wrote: [snip] (on the downside you have to guard against compiler code-gen performance regressions) auto vectorization is bad because you never know if your code will get vectorized next time you make some change to it and recompile. Just use : https://ispc.github.io/ Yes, that's a downside, you have to measure your performance sensitive code if you change it *or* change compilers or targets. Explicit SIMD code, ispc or other, isn't as readable or composable or vanilla portable but it certainly is performance predictable. I find SIMT code readability better than SIMD but a little worse than auto-vectorizable kernels. Hugely better performance though for less effort than SIMD if your platform supports it. Is anyone actively using dcompute (SIMT enabler)? Unless I hear bad things I'll try it down the road as neither going back to CUDA nor "forward" to the SycL-verse appeals.