How to use the Vc implementation within ROOT6.05/03

Dear ROOTers,

I would like to use the ROOT implementation of the Vc library, but it is not clear to me how I am supposed to use that.

The namespace seems not visible at the prompt:

root [12] ROOT::Vc::float_v m
ROOT_prompt_12:1:7: error: 'Vc' is not a class, namespace, or enumeration
ROOT::Vc::float_v m
      ^
ROOT_prompt_12:1:7: note: 'Vc' declared here

on the other hand, the template class Vector seems visible in the global namespace but the interpret looks misled by the expression and makes strange complaints:

root [3] Vector<float> a;
ROOT_prompt_3:1:13: error: expected '(' for function-style cast or type construction
Vector<float> a;
       ~~~~~^
ROOT_prompt_3:1:15: error: use of undeclared identifier 'a'
Vector<float> a;
              ^
root [4] float pippo[4] = {1.,2.,3.,4.}
(float [4]) { 1.00000f, 2.00000f, 3.00000f, 4.00000f }
root [5] Vector<float> pippo2(pippo)
ROOT_prompt_5:1:13: error: expected '(' for function-style cast or type construction
Vector<float> pippo2(pippo)
       ~~~~~^
ROOT_prompt_5:1:15: error: use of undeclared identifier 'pippo2'
Vector<float> pippo2(pippo)
              ^
root [6] auto pippo3 = Vector<float>(pippo)
ROOT_prompt_6:1:27: error: expected '(' for function-style cast or type construction
auto pippo3 = Vector<float>(pippo)
                     ~~~~~^

Any help is very welcome.

Thanks,
Matteo

Hi,

This is a known problem caused by the fact that Vc is build in a static library which cannot be loaded at run time by ROOT. For this reason Vc cannot be used in the current version in the ROOT prompt. Also since Cling is not compiled with the right optimisation flags, one couldn’t profit from the vectorisation capabilities of Vc.

If you need Vc, I would suggest you to use in a compiled application, where you can add the static link to Vc.
Otherwise, if you really need at the prompt we can try to offer this in a next ROOT version.
For the time being you would need to change the build system to build a shared Vc library instead of a static, although you will have decreased performances.

Best Regards

Lorenzo

Dear Lorenzo,

thanks for your reply.

Actually I wanted to tried out this tool and I used the ROOT prompt because it is way more practical for learning and testing.

Would be possible to use such objects as member of a class, compiled and loaded e.g. as shared library with ACliC? (I have no idea if a .so can include stuff from static libraries…)

If possible, besides learning how to use that, would this approach be also representative of the achievable performance?

Hello,

I think it is the same if you use Vc in a class that you load with AClic, because you will have missing symbols caused by Vc.
The only solution is to compile your class in a shared libraries linking with the static library Vc.a and then load that shared library into ROOT

Best Regards

Lorenzo

Try to execute (e.g. add it to “rootlogon.C”):
gSystem->AddLinkedLibs("-lVc");
then loading your code with ACLiC could possibly work fine.

Hi Lorenzo and Wile,

sorry if I was misleading, but with “loaded as a shared lib with AcLiC” I meant compiled not just loaded, i.e. something like:

.L myClass.cpp++

or

gSystem->CompileMacro("myClass.cpp","k","myClass");

I have always assumed that this is just calling rootcling+gcc to compile a .so with the right include and library paths, and then it is loading the resulting .so as ‘‘gSystem->Load(“myClass.so”)’’

Am I wrong and do I really have to compile the shared object outside root?

Thanks,
Matteo

Try: gSystem->AddLinkedLibs("-lVc"); .L myClass.cpp++

Hi,

Sorry for what I have said before. You can use ACLIC, but you need to specify the full path for the static Vc library. gSystem->AddLinkedLibs("-lVc") will not work because Vc is not a shared library.

You need to do :

gSystem->AddLinkedLibs("$ROOTSYS/lib/libVc.a")
.L myClass.cpp++

Lorenzo

Why do you need the full path to the library?
If I try “gSystem->GetLinkedLibs()”, I get something like “-L$ROOTSYS/lib -lCore -lCint -lRint”, and then after adding “-lVc”, I get “-L$ROOTSYS/lib -lCore -lCint -lRint -lVc”, so the “-L$ROOTSYS/lib” automatically instructs the linker where to look for libraries and this should be completely independent of whether shared or static libraries are used in “-l” (for the linker it makes no difference, I believe).

-lVC works only if Vc is a shard library (i.e. for a libVc.so) and not for a static library. A static library is just any like other compiled file (.o) and you just need to add it to the linking command.

Lorenzo

Here’s an extract from “man ld” (binutils-2.24-system, 2015-09-16): [quote] -l namespec
–library=namespec
Add the archive or object file specified by namespec to the list of
files to link. This option may be used any number of times. If
namespec is of the form :filename, ld will search the library path
for a file called filename, otherwise it will search the library
path for a file called libnamespec.a.

       On systems which support shared libraries, ld may also search for
       files other than libnamespec.a.  Specifically, on ELF and SunOS
       systems, ld will search a directory for a library called
       libnamespec.so before searching for one called libnamespec.a.  (By
       convention, a ".so" extension indicates a shared library.)  Note
       that this behavior does not apply to :filename, which always
       specifies a file called filename.

       The linker will search an archive only once, at the location where
       it is specified on the command line.  If the archive defines a
       symbol which was undefined in some object which appeared before the
       archive on the command line, the linker will include the
       appropriate file(s) from the archive.  However, an undefined symbol
       in an object appearing later on the command line will not cause the
       linker to search the archive again.

       See the -( option for a way to force the linker to search archives
       multiple times.

       You may list the same archive multiple times on the command line.

       This type of archive searching is standard for Unix linkers.
       However, if you are using ld on AIX, note that it is different from
       the behaviour of the AIX linker.

   -L searchdir
   --library-path=searchdir
       Add path searchdir to the list of paths that ld will search for
       archive libraries and ld control scripts.  You may use this option
       any number of times.  The directories are searched in the order in
       which they are specified on the command line.  Directories
       specified on the command line are searched before the default
       directories.  All -L options apply to all -l options, regardless of
       the order in which the options appear.  -L options do not affect
       how ld searches for a linker script unless -T option is specified.

       If searchdir begins with "=", then the "=" will be replaced by the
       sysroot prefix, a path specified when the linker is configured.

       The default set of paths searched (without being specified with -L)
       depends on which emulation mode ld is using, and in some cases also
       on how it was configured.

       The paths can also be specified in a link script with the
       "SEARCH_DIR" command.  Directories specified this way are searched
       at the point in which the linker script appears in the command
       line.[/quote]

Yes, you are right. It is then a problem with gSystem->AddLinkedLibs.

Because this fails

root [0] gSystem->AddLinkedLibs("-lVc")
root [1] .L MyVcClass.C++
Info in <TMacOSXSystem::ACLiC>: creating shared library /Users/moneta/root/tests/./MyVcClass_C.so
ld: library not found for -lVc
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Error in <ACLiC>: Compilation failed!

while, after re-adding “-L” works

root [0] gSystem->AddLinkedLibs("-L$ROOTSYS/lib -lVc")
root [1] .L MyVcClass.C++

Lorenzo

So what do you get when you try “gSystem->GetLinkedLibs()” before and after adding “-lVc” (I started to suspect that it’s incorrect in the first place)?