<div dir="ltr">I know almost nothing about this, but I *thought* that compilers were moving to do SIMD instructions where possible as an optimization.  It may not be there yet, isn't this something that's getting attention?  Could the library take advantage of this by arranging the code to allow for this optimization, rather than adding explicit sleef interface?</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Apr 17, 2020 at 7:01 AM Even Rouault <<a href="mailto:even.rouault@spatialys.com">even.rouault@spatialys.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><u></u>
<div style="font-family:monospace;font-size:9pt;font-weight:400;font-style:normal">
<p style="margin:0px;text-indent:0px">Thomas,</p>
<p style="margin:0px;text-indent:0px"> </p>
<p style="margin:0px;text-indent:0px">> That is - actually, I work on a proof-of-concept for an improved,</p>
<p style="margin:0px;text-indent:0px">> next generation WKT, ironing out some of the geodetically</p>
<p style="margin:0px;text-indent:0px">> unfortunate elements of WKT2019.</p>
<p style="margin:0px;text-indent:0px"> </p>
<p style="margin:0px;text-indent:0px">Hum. Was hoping we wouldn't need a WKT2021 :-)</p>
<p style="margin:0px;text-indent:0px"> </p>
<p style="margin:0px;text-indent:0px">> </p>
<p style="margin:0px;text-indent:0px">> But incidentally this involves implementing support for the</p>
<p style="margin:0px;text-indent:0px">> OGC/ISO19100 "Coordinate Set" (i.e. "sets of coordinate tuples")</p>
<p style="margin:0px;text-indent:0px">> concept, since ISO metadata is attached at the set, rather than</p>
<p style="margin:0px;text-indent:0px">> tuple, level.</p>
<p style="margin:0px;text-indent:0px"> </p>
<p style="margin:0px;text-indent:0px">For other readers, I suppose you speak about the classes described at:</p>
<p style="margin:0px;text-indent:0px"><a href="http://docs.opengeospatial.org/as/18-005r4/18-005r4.html#18" target="_blank">http://docs.opengeospatial.org/as/18-005r4/18-005r4.html#18</a></p>
<p style="margin:0px;text-indent:0px"> </p>
<p style="margin:0px;text-indent:0px">That's indeed something I left aside during PROJ 6 implementation. CoordinateMetadata could be interesting to implement, as it has a WKT:2019 representation (not implement currently), and could be useful for transformations involving dynamic/time-dependent CRS.</p>
<p style="margin:0px;text-indent:0px"> </p>
<p style="margin:0px;text-indent:0px">> But until then I'll be very interested in discussing the form and</p>
<p style="margin:0px;text-indent:0px">> contents of a parallel coordinate data structure (CoordinateSet</p>
<p style="margin:0px;text-indent:0px">> class), so we can keep things compatible.</p>
<p style="margin:0px;text-indent:0px"> </p>
<p style="margin:0px;text-indent:0px">To give you some hints on what I prototyped, the generic vector-capable type is</p>
<p style="margin:0px;text-indent:0px"> </p>
<p style="margin:0px;text-indent:0px">template<typename T, int N> class VF{};</p>
<p style="margin:0px;text-indent:0px"> </p>
<p style="margin:0px;text-indent:0px">(VF stands Vector Floating point)</p>
<p style="margin:0px;text-indent:0px"> </p>
<p style="margin:0px;text-indent:0px">And it has specializations VF<double,1>, VF<double,2>, VF<double,4> etc</p>
<p style="margin:0px;text-indent:0px"> </p>
<p style="margin:0px;text-indent:0px">VF<double,1> once optimized is equivalent to a plain old double</p>
<p style="margin:0px;text-indent:0px">VF<double,2> on SSE2 expands to a SSE 128bit register (or 2 double on non vector platforms, but not necessarily runtime efficient)</p>
<p style="margin:0px;text-indent:0px">VF<double,4> on AVX/AVX2 expands to a AVX 256bit register, or on SSE2 on 2 SSE 128 bit registers</p>
<p style="margin:0px;text-indent:0px">VF<double,8> on AVX/AVX2 expands to 2 AVX 256bit registers, or on SSE2 to 4 SSE 128 bit registers (and possibly on AVX-512 to a AVX-512 512 bit register)</p>
<p style="margin:0px;text-indent:0px"> </p>
<p style="margin:0px;text-indent:0px">Then you can define a:</p>
<p style="margin:0px;text-indent:0px">template<typename T, int N> struct PJ_VF_XY</p>
<p style="margin:0px;text-indent:0px">{</p>
<p style="margin:0px;text-indent:0px">  VF<T,N> x;</p>
<p style="margin:0px;text-indent:0px">  VF<T,N> y;</p>
<p style="margin:0px;text-indent:0px">};</p>
<p style="margin:0px;text-indent:0px">etc etc</p>
<p style="margin:0px;text-indent:0px"> </p>
<p style="margin:0px;text-indent:0px">But I don't think we would want to expose that on PROJ API level, one of the good reason is that it is C++ so cannot be used at the C level.</p>
<p style="margin:0px;text-indent:0px"> </p>
<p style="margin:0px;text-indent:0px">> My first thought was to make the CoordinateSet class simply a</p>
<p style="margin:0px;text-indent:0px">> container for the material currently given as args to</p>
<p style="margin:0px;text-indent:0px">> proj_transform_generic()</p>
<p style="margin:0px;text-indent:0px"> </p>
<p style="margin:0px;text-indent:0px">I concur with this. I'd also imagine CoordinateSet to be more or less similar to proj_trans_generic() arguments, with pointers to X, Y, Z, T double* arrays and user provided strides, to be accept all reasonable memory arrangements (typically separate/contiguous X, Y, Z, T components, or interleaved XY, XYZ, XYZT patterns)</p>
<p style="margin:0px;text-indent:0px">(I see that CoordinateSet refers to the DirectPosition type, which must be defined in some other ISO standard, but I don't think we want & need possibly heavy weight objects there)</p>
<p style="margin:0px;text-indent:0px"> </p>
<p style="margin:0px;text-indent:0px">If the user chooses a in-memory arrangement of its data that directly matches what PROJ would use under the hood (for a vector type, the separate/contiguous arrangement would be the best), it can save a bit of time for the loading/unloading between memory and SSE/AVX registers, but even if those moves between memory and registers aren't done in the most efficient way, they are certainly neglectable regarding the cost of the math operations.</p>
<p style="margin:0px;text-indent:0px"> </p>
<p style="margin:0px;text-indent:0px">PROJ should be smart enough internally to figure out from the available components of a pipeline if it must use a vector operation or not. Typically you would have a fwd2d_2points, fwd2d_4points, fwd2d_8points function pointers for a PROJ operation, that would be set or not, depending on available hardware capabilities at runtime and benchmarked efficiency of using those variants.</p>
<p style="margin:0px;text-indent:0px"> </p>
<p style="margin:0px;text-indent:0px">Even</p>
<p style="margin:0px;text-indent:0px"> </p>
<p style="margin:0px;text-indent:0px">-- </p>
<p style="margin:0px;text-indent:0px">Spatialys - Geospatial professional services</p>
<p style="margin:0px;text-indent:0px"><a href="http://www.spatialys.com" target="_blank">http://www.spatialys.com</a></p></div>_______________________________________________<br>
PROJ mailing list<br>
<a href="mailto:PROJ@lists.osgeo.org" target="_blank">PROJ@lists.osgeo.org</a><br>
<a href="https://lists.osgeo.org/mailman/listinfo/proj" rel="noreferrer" target="_blank">https://lists.osgeo.org/mailman/listinfo/proj</a><br>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail_signature">Andrew Bell<br><a href="mailto:andrew.bell.ia@gmail.com" target="_blank">andrew.bell.ia@gmail.com</a></div>