<div dir="ltr">> 

<span style="font-family:monospace;font-size:12px;white-space:pre-wrap">Hum. Was hoping we wouldn't need a WKT2021 :-)</span><div><span style="font-family:monospace;font-size:12px;white-space:pre-wrap"><br></span></div><div><span style="font-family:monospace;font-size:12px;white-space:pre-wrap">Next revision cycle is not until 2024, so nothing before that. But things take time,</span></div><div><span style="font-family:monospace;font-size:12px;white-space:pre-wrap">and I need to think, rethink and discuss this extensively, so better be well prepared</span></div><div><span style="font-family:monospace;font-size:12px;white-space:pre-wrap">in ample time before time's up.</span></div><div><span style="font-family:monospace;font-size:12px;white-space:pre-wrap"><br></span></div><div><span style="font-family:monospace;font-size:12px;white-space:pre-wrap">And as the work provides a way towards better PROJ plumbing, whether or not it leads</span></div><div><span style="font-family:monospace;font-size:12px;white-space:pre-wrap">to WKT revisions, I think it's worthwhile.</span></div><div><span style="font-family:monospace;font-size:12px;white-space:pre-wrap"><br></span></div><div><span style="font-family:monospace;font-size:12px;white-space:pre-wrap">I understand from your description of VF that it is fine to move-initialize VF. This</span></div><div><span style="font-family:monospace;font-size:12px;white-space:pre-wrap">obviously simplifies the interfacing, compared to map directly to the user provided</span></div><div><span style="font-family:monospace;font-size:12px;white-space:pre-wrap">data arrays. So essentially one could do (in </span><span style="font-family:monospace;font-size:12px;white-space:pre-wrap">pseudo-code):</span></div><div><span style="font-family:monospace;font-size:12px;white-space:pre-wrap"><br></span></div><div><span style="font-family:monospace;font-size:12px;white-space:pre-wrap">N = 42424242</span></div><div><font face="monospace"><span style="font-size:12px;white-space:pre-wrap">double serialdata[N]</span></font></div><div><font face="monospace"><span style="font-size:12px;white-space:pre-wrap"><br></span></font></div><div><span style="font-family:monospace;font-size:12px;white-space:pre-wrap">for (i = 0;  i < N+3; i+=4) {</span></div><div><span style="font-family:monospace;font-size:12px;white-space:pre-wrap">    LAST = min (N - 1, i + 3)</span></div><div><span style="font-family:monospace;font-size:12px;white-space:pre-wrap">    NUM = i + 4 - LAST</span></div><div><span style="font-family:monospace;font-size:12px;white-space:pre-wrap">    paralleldata[0..3] = serialdata[i..LAST]</span></div><div><span style="font-family:monospace;font-size:12px;white-space:pre-wrap">    </span></div><div><span style="font-family:monospace;font-size:12px;white-space:pre-wrap">    (do cool stuff in 4-way-parallel)</span></div><div><span style="font-family:monospace;font-size:12px;white-space:pre-wrap"><br></span></div><div><span style="font-family:monospace;font-size:12px;white-space:pre-wrap">    serialdata[i..LAST] = paralleldata[0..NUM]</span></div><div><span style="font-family:monospace;font-size:12px;white-space:pre-wrap">}</span></div><div><span style="font-family:monospace;font-size:12px;white-space:pre-wrap"><br></span></div><div><span style="font-family:monospace;font-size:12px;white-space:pre-wrap">is this correctly understood?</span></div><div><br></div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Den fre. 17. apr. 2020 kl. 13.01 skrev Even Rouault <<a href="mailto:even.rouault@spatialys.com">even.rouault@spatialys.com</a>>:<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></blockquote></div>