[R] bizarre color space conversion problem

Sarah Goslee @@r@h@go@|ee @end|ng |rom gm@||@com
Thu Jul 18 19:30:09 CEST 2019


I'll address all of your questions below, but starting with this:

> Could any of the computers
exhibiting the bizarre behaviour be equipped with an AVX-512-capable
CPU?

Yes. Both computers that are giving the bizarre results have Intel
i9-7900X CPUs; the X-series apparently is AVX-512-capable.

That would be an incredibly disturbing cause... But I can't find
anything else that differs. They're using the same BLAS.

I'm not even remotely a hardware expert: if the difference is due to
changes in the instruction set, I assume that has potential
consequences for other things, and I just happened to spot it in this
particular case because it's visualization-based? (Yikes.)

I really appreciate your suggestions, by the way. Thanks!


Here's a complete rundown:



As it says in my first email (but way at the bottom), I'd already
gotten as far as locating the problem in this line from
grDevices::convertColor()

    xyz <- from$toXYZ(color, from.ref.white)

Your test code confirms that as the source of the problem:


> red.rgb <- t(col2rgb(rep('red',8), alpha = 0)/255)
> # let's hope this implementation detail wasn't changed in 3.6.1
> white.point <- grDevices:::c2to3(grDevices:::white.points[,'D65'])
> (red.xyz <- grDevices::colorspaces$sRGB$toXYZ(red.rgb, white.point))[1,]
[1] 0.7733981 0.9280769 0.1383974
> # [1] 0.4168213 0.2149235 0.0195385
> (red.lab <- grDevices::colorspaces$Lab$fromXYZ(red.xyz,white.point))[1,]
        L         a         b
 97.14950 -21.36677  94.42044
> #        L        a        b
> # 53.48418 80.01027 67.38407
> convertColor(red.rgb, from = "sRGB", to = "Lab")[1,]
        L         a         b
 97.14950 -21.36677  94.42044
> #        L        a        b
> # 53.48418 80.01027 67.38407
>
>
>
>
>
> red.rgb
     red green blue
[1,]   1     0    0
[2,]   1     0    0
[3,]   1     0    0
[4,]   1     0    0
[5,]   1     0    0
[6,]   1     0    0
[7,]   1     0    0
[8,]   1     0    0
> white.point
        x                   y
0.9532057 1.0000000 1.0853844
> red.xyz
          [,1]      [,2]      [,3]
[1,] 0.7733981 0.9280769 0.1383974
[2,] 0.7733981 0.9280769 0.1383974
[3,] 0.7733981 0.9280769 0.1383974
[4,] 0.7733981 0.9280769 0.1383974
[5,] 0.0000000 0.0000000 0.0000000
[6,] 0.0000000 0.0000000 0.0000000
[7,] 0.0000000 0.0000000 0.0000000
[8,] 0.0000000 0.0000000 0.0000000
> red.lab
           L         a        b
[1,] 97.1495 -21.36677 94.42044
[2,] 97.1495 -21.36677 94.42044
[3,] 97.1495 -21.36677 94.42044
[4,] 97.1495 -21.36677 94.42044
[5,]  0.0000   0.00000  0.00000
[6,]  0.0000   0.00000  0.00000
[7,]  0.0000   0.00000  0.00000
[8,]  0.0000   0.00000  0.00000





grDevices::colorspaces$sRGB$toXYZ is pretty simple, just a matrix
product.  (I hope there are no differences in
as.list(environment(grDevices::colorspaces$sRGB$toXYZ))[c('dogamma','M')]


No, that's identical on working and nonworking computers. (Whew!)

A: working

Installed Packages
blas.x86_64                                 3.8.0-12.fc30
           @updates
liblas.x86_64                               1.8.1-1.fc30
           @fedora
openblas.x86_64                             0.3.6-2.fc30
           @updates
openblas-Rblas.x86_64                       0.3.6-2.fc30
           @updates
openblas-openmp.x86_64                      0.3.6-2.fc30
           @updates
openblas-serial.x86_64                      0.3.6-2.fc30
           @updates
openblas-srpm-macros.noarch                 2-5.fc30
           @fedora
openblas-threads.x86_64                     0.3.6-2.fc30
           @updates
openblas-threads64_.x86_64                  0.3.6-2.fc30
           @updates

ls -l /usr/lib64/R/lib/libRblas.so

-rwxr-xr-x. 1 root root 60204008 Jul  2 10:15 /usr/lib64/R/lib/libRblas.so


lscpu
Architecture:        x86_64
CPU op-mode(s):      32-bit, 64-bit
Byte Order:          Little Endian
Address sizes:       46 bits physical, 48 bits virtual
CPU(s):              12
On-line CPU(s) list: 0-11
Thread(s) per core:  2
Core(s) per socket:  6
Socket(s):           1
NUMA node(s):        1
Vendor ID:           GenuineIntel
CPU family:          6
Model:               63
Model name:          Intel(R) Xeon(R) CPU E5-1650 v3 @ 3.50GHz
Stepping:            2
CPU MHz:             1197.305
CPU max MHz:         3800.0000
CPU min MHz:         1200.0000
BogoMIPS:            6983.42
Virtualization:      VT-x
L1d cache:           32K
L1i cache:           32K
L2 cache:            256K
L3 cache:            15360K
NUMA node0 CPU(s):   0-11




B: not working

Installed Packages
blas.x86_64                                 3.8.0-12.fc30
           @updates
liblas.x86_64                               1.8.1-1.fc30
           @fedora
openblas.x86_64                             0.3.6-2.fc30
           @updates
openblas-Rblas.x86_64                       0.3.6-2.fc30
           @updates
openblas-openmp.x86_64                      0.3.6-2.fc30
           @updates
openblas-serial.x86_64                      0.3.6-2.fc30
           @updates
openblas-srpm-macros.noarch                 2-5.fc30
           @fedora
openblas-threads.x86_64                     0.3.6-2.fc30
           @updates
openblas-threads64_.x86_64                  0.3.6-2.fc30
           @updates

-rwxr-xr-x. 1 root root 60204008 Jul  2 10:15 /usr/lib64/R/lib/libRblas.so

lscpu
Architecture:        x86_64
CPU op-mode(s):      32-bit, 64-bit
Byte Order:          Little Endian
Address sizes:       46 bits physical, 48 bits virtual
CPU(s):              20
On-line CPU(s) list: 0-19
Thread(s) per core:  2
Core(s) per socket:  10
Socket(s):           1
NUMA node(s):        1
Vendor ID:           GenuineIntel
CPU family:          6
Model:               85
Model name:          Intel(R) Core(TM) i9-7900X CPU @ 3.30GHz
Stepping:            4
CPU MHz:             1200.180
CPU max MHz:         4500.0000
CPU min MHz:         1200.0000
BogoMIPS:            6600.00
Virtualization:      VT-x
L1d cache:           32K
L1i cache:           32K
L2 cache:            1024K
L3 cache:            14080K
NUMA node0 CPU(s):   0-19



On Thu, Jul 18, 2019 at 1:05 PM Ivan Krylov <krylov.r00t using gmail.com> wrote:
>
> On Thu, 18 Jul 2019 11:50:17 -0400
> Sarah Goslee <sarah.goslee using gmail.com> wrote:
>
> > The problem is in the conversion from RGB to Lab.
>
> Hmm. Assuming defaults and skipping all checks, convertColor(red.rgb,
> from = "sRGB", to = "Lab") amounts to the following:
>
> red.rgb <- t(col2rgb(rep('red',8), alpha = 0)/255)
> # let's hope this implementation detail wasn't changed in 3.6.1
> white.point <- grDevices:::c2to3(grDevices:::white.points[,'D65'])
> (red.xyz <- grDevices::colorspaces$sRGB$toXYZ(red.rgb, white.point))[1,]
> # [1] 0.4168213 0.2149235 0.0195385
> (red.lab <- grDevices::colorspaces$Lab$fromXYZ(red.xyz,white.point))[1,] #        L        a        b
> # 53.48418 80.01027 67.38407
> convertColor(red.rgb, from = "sRGB", to = "Lab")[1,]
> #        L        a        b
> # 53.48418 80.01027 67.38407
>
> Does the manual way result in a different output? If so, do the
> differences appear in red.xyz or red.lab?
>
> grDevices::colorspaces$sRGB$toXYZ is pretty simple, just a matrix
> product.  (I hope there are no differences in
> as.list(environment(grDevices::colorspaces$sRGB$toXYZ))[c('dogamma','M')]
> on different computers - that would be strange.)
> grDevices::colorspaces$Lab$fromXYZ looks more complicated but is just a
> bunch of vectorised element-wise algebra, so tracing the intermediate
> results should also be possible.
>
> > And to make it even more bizarre, it fails with eight or more colors,
> > but works correctly with seven or fewer.
>
> This is just a wild guess, but could /usr/lib64/R/lib/libRblas.so per
> chance be a symlink to an OpenBLAS copy? Could any of the computers
> exhibiting the bizarre behaviour be equipped with an AVX-512-capable
> CPU?
>
> --
> Best regards,
> Ivan



-- 
Sarah Goslee (she/her)
http://www.numberwright.com



More information about the R-help mailing list