I am not a fan of NEEDING numerous compiler flags to get a program to compile. I generally see it as poor programming practice.
I have some old fortran code that uses the POINTER statement and when using gfortran to compile these files it responds with the error
Error: Cray pointer declaration at (1) requires -fcray-pointer flag
here is a sample of what is causing it
COMPLEX*16 matrix(1)
POINTER (PM, mymatrix)
COMMON /M_SHARED/ PM
if I use the intel compiler then there is no problem doing just ifort -O3 myprogram.f but I don't want to be dependent on needing the intel compiler. I would prefer to be able to use gfortran which is free.
I would like to know how far behind the times my example is, and how it should be written properly. Or should i just use the -fcray-pointer flag?
Related
In Eigen FAQ it states that you need to enable vectorization in the compiler.
I am trying to develop an R package using RcppEigen. I would like it if the user would have the best performance without having to manually compile the package with specified flags.
What is best practice for an R package looking to enable vectorization in the Eigen library?
Do exactly what the FAQ says and set the compiler flags. You may have to turn those on from a script configure after you test what the current compiler supports -- and CRAN may still tell you that the flags are not portable.
Also, just to fix terms here, there is no "library" here in our: RcppEigen only uses headers from Eigen which is designed as a templated header-only package.
I'm a beginner too and many hours trying to understand Rcpp may be relevant to you #jds. I wanted to enable vectorisation on my Dell Precision M2800 with AVX architecture so I added the -mavx2 flag to my configure file using the following chunk thrice:
CXXFLAGS= -O3 -std=c++11 -Wall -mavx2
This code change sped up my code (a series of double-nested for loops) from 4.1s to 1.4s!
Find out how to amend the compiler flags that get used by sourceCpp by building a skeleton package using configure and clean files to create your Makevars file as beautifully demonstrated by #nrussell in How to change and set Rcpp compile arguments
this is my first Stackoverflow question :-)
My background:
2 years Python experience
2 months crystal-lang experience ( websites running with Amber framework )
1 month into C, C++ , assembly
Facts:
- crystal-lang is compiling and running without any problem
- running on x86_64
Please be nice, as i don't have much low-level language knowledge yet.
From my understanding, when we compile and run a basic hello.c file using LLVM, it goes as follow:
hello.c :
#include
int main() {
printf("hello world\n");
return 0;
}
shell :
$ clang -O3 -emit-llvm hello.c -c -o hello.bc
$ llc hello.bc -o hello.s
$ gcc hello.s -o hello.native
$ ./hello.native
this comes from the LLVM examples )
My point is that we can produce a pretty short hello.bc file (128 lines) that can be run in a slower way using:
$ lli hello.bc
but when I tried to generate a similar hello.bc from a hello.cr file and run it like i did with the hello.c file:
hello.cr :
puts "hello world"
shell :
$ crystal build hello.cr --emit llvm-bc --release
$ llc hello.bc -o hello.s
what i noticed:
This hello.bc file is much much bigger than the one generating from the c file (43'624 lines)
This hello.bc can't be run using "lli" as it generates an:
"LLVM ERROR: Program used external function 'pcre_malloc' which could not be resolved!
I can't even compile from hello.s to hello.native
Same problem if i try to use generate and hello.ll file
As i understood, LLVM is portable , and that all front-end languages would produce an intermediate *.bc that can then be compiled to any architecture.
My questions are:
Why are the hello.bc not similar in both cases ?
Am I doing something wrong in the crystal procedure ?
Thank you!
Everything is just as it is supposed to be. Crystal has a runtime library that is always present even if you didn't include anything. This is required to run the Crystal program.
The C example pretty much doesn't contain anything else than a syscall to printf. That's why the compiled ASM is also really tiny.
Crystal's simple puts call has a much more behind it. It is based on libraries for handling asynchronous IO, concurrency, signal handling, garbage collection and more. Some of these libraries are completely implemented in the Crystal standard library, some use other libraries that are either directly embedded into the binary (libgc) or still require dynamic libraries from the system (libpcre, libpthread).
Any Crystal program comes with this runtime library by default. Even an empty program. This usually goes completely unnoticed because larger programs will eventually need those things anyway and the compiled binary size of the runtime library is less than 500 KB (in release mode).
Such a small program like yours doesn't really need all of this just to print a string. But these libraries are required for the Crystal runtime.
NOTE: You can compile a Crystal program without these default libraries. But this means you can't use anything from the Crystal stdlib and you have to essentially write C code with Crystal syntax (or implement your own stdlib):
require "lib_c"
require "c/stdio"
LibC.printf pointerof("hello world".#c)
This can be compiled with --prelude=empty option and it will generate a substantially smaller ASM, roughly similar to the C example.
This question is related to LLVM/clang.
I already know how to compile opencl-kernel-file(.cl) using OpenCL API ( clBuildProgram() and clGetProgramBuildInfo() )
my question is this:
How to compile opencl-kernel-file(.cl) to LLVM IR with OpenCL 1.2 or higher?
In the other words, How to compile opnecl-kernel-file(.cl) to LLVM IR without libclc?
I have tried various methods to get LLVM-IR of OpenCL-Kernel-File.
I first followed the clang user manual.(https://clang.llvm.org/docs/UsersManual.html#opencl-features) but it did not run.
Secondly, I found a way to use libclc.
commands is this:
clang++ -emit-llvm -c -target -nvptx64-nvidial-nvcl -Dcl_clang_storage_class_specifiers -include /usr/local/include/clc/clc.h -fpack-struct=64 -o "$#".bc "$#" <br>
llvm-link "$#".bc /usr/local/lib/clc/nvptx64--nvidiacl.bc -o "$#".linked.bc <br>
llc -mcpu=sm_52 -march=nvptx64 "$#".linked.bc -o "$#".nvptx.s<br>
This method worked fine, but since libclc was built on top of the OpenCL 1.1 specification, it could not be used with OpenCL 1.2 or later code such as code using printf.
And this method uses libclc, which implements OpenCL built-in functions in the shape of new function. You can observe that in the assembly(ptx) of result opencl binary, it goes straight to the function call instead of converting it to an inline assembly. I am concerned that this will affect gpu behavior and performance, such as execution time.
So now I am looking for a way to replace compilation using libclc.
As a last resort, I'm considering using libclc with the NVPTX backend and AMDGPU backend of LLVM.
But if there is already another way, I want to use it.
(I expect that the OpenCL front-end I have not found yet exists in clang)
My program's scenarios are:
There is opencl kernel source file(.cl)
Compile the file to LLVM IR
IR-Level process to the IR
Compile(using llc) the IR to Binary
with each gpu targets(nvptx, amdgcn..)
Using the binary, Run host(.c or .cpp with lib OpenCL) with clCreateProgramWithBinary()
Now, When I compile kernel source file to LLVM IR, I have to include header of libclc(-include option in first one of above command) for compiling built-in functions. And I have to link libclc libraries before compile IR to binary
My environments are below:
GTX960
- NVIDIA's Binary appears in nvptx format
- I'm using sm_52 nvptx for my gpu.
Ubuntu Linux 16.04 LTS
LLVM/Clang 5.0.0
- If there is another way, I am willing to change the LLVM version.
Thanks in advice!
Clang 9 (and up) can compile OpenCL kernels written in the OpenCL C language. You can tell Clang to emit LLVM-IR by passing the -emit-llvm flag (add -S to output the IR in text rather than in bytecode format), and specify which version of the OpenCL standard using e.g. -cl-std=CL2.0. Clang currently supports up to OpenCL 2.0.
By default, Clang will not add the standard OpenCL headers, so if your kernel uses any of the OpenCL built-in functions you may see an error like the following:
clang-9 -c -x cl -emit-llvm -S -cl-std=CL2.0 my_kernel.cl -o my_kernel.ll
my_kernel.cl:17:12: error: implicit declaration of function 'get_global_id' is invalid in OpenCL
int i = get_global_id(0);
^
1 error generated.
You can tell Clang to include the standard OpenCL headers by passing the -finclude-default-header flag to the Clang frontend, e.g.
clang-9 -c -x cl -emit-llvm -S -cl-std=CL2.0 -Xclang -finclude-default-header my_kernel.cl -o my_kernel.ll
(I expect that the OpenCL front-end I have not found yet exists in clang)
There is an OpenCL front-end in clang - and you're using it, otherwise you couldn't compile a single line of OpenCL with clang. Frontend is Clang recognizing the OpenCL language. There is no OpenCL backend of any kind in LLVM, it's not the job of LLVM; it's the job of various OpenCL implementations to provide proper libraries. Clang+LLVM just recognizes the language and compiles it to bitcode & machine binaries, that's all it does.
in the assembly(ptx) of result opencl binary, it goes straight to the function call instead of converting it to an inline assembly.
You could try linking to a different library instead of libclc, if you find one. Perhaps NVidia's CUDA has some bitcode libraries somewhere, then again licensing issues... BTW are you 100% sure you need LLVM IR ? getting OpenCL binaries using the OpenCL runtime, or using SPIR-V, might get you faster binaries & certainly be less painful to work with. Even if you manage to get a nice LLVM IR, you'll need some runtime which actually accepts it (i could be wrong, but i doubt proprietary AMD/NVIDIA OpenCL will just accept random LLVM IR as inputs).
Clang does not provide a standard CL declaration header file (for example, C's stdio.h), which is why you're getting "undefined type float" and whatnot.
If you get one such header, you can then mark it as implicit include using "clang -include cl.h -x cl [your filename here]"
One such declaration header can be retrieved from the reference OpenCL compiler implementation at
https://github.com/KhronosGroup/SPIR-Tools/blob/master/headers/opencl_spir.h
And by the way, consider using this compiler which generates SPIR (albeit 1.0) which can be fed into OpenCL drivers as input.
The normal way to run an OpenCL program is to include the openCL kernel that is compiled at runtime (online compilation).
But I've seen examples of compiling OpenCL to binary before, called offline compilation. I'm aware of the disadvantages (reducing compatibility across hardware).
There used to be an offline compiler at http://www.fixstars.com/en/ but it does not seems to be available anymore.
So is there an offline compiler for OpenCL available, in particular for NVIDIA-based cards?
Someone suggested that nvcc.exe in NVidia's CUDA SDK could compile .cl files with
nvcc -x cu file.cl -o file.out -lOpenCL
...but it says missing cl.exe at least on Windows. This might be worth checking out, however: http://clcc.sourceforge.net/
As well as:
https://github.com/HSAFoundation/CLOC (AMD-maintained offline compiler)
https://github.com/Maratyszcza/clcc (includes also links to above ones and more)
I am building a package using Rcpp and RcppArmadillo, and when I install it on one of my machines I get the following compiler warnings from functions which use RcppArmadillo:
WARNING: your C++ compiler is in C++11 mode, but it has incomplete
support for C++11 features; if something breaks, you get to keep all
the pieces
As far as I can tell, this doesn't break any of my code, however it would be nice to turn off these warnings if possible.
Based on another question I know I can disable C++11 support for Armadillo by adding the following macro before I include the RcppArmadillo header file:
#define ARMA_DONT_USE_CXX11
Which is just a shorthand for:
#if defined(ARMA_DONT_USE_CXX11)
#undef ARMA_USE_CXX11
#undef ARMA_USE_CXX11_RNG
#endif
What I'd like to be able to do is detect whether the compiler has full support for C++11 extensions or not, and #undef the appropriate macros only if the machines compiler doesn't support full C++11 extensions.
According to the R extensions manual, this should be stored in CXX1XSTD, so I want to do something like:
#if CXX1XSTD == "-std=c++0x"
#undef ARMA_USE_CXX11
#undef ARMA_USE_CXX11_RNG
#endif
However CXX1XSTD isn't a predefined macro in Rcpp or C++, so I that doesn't work.
Briefly:
The first warning is from Armadillo. Conrad works hard to keep his code compliant; he chose to put this warning in. You did not say which compiler version you used so I can't comment further.
The rest of your post is a little confused. There are actual test macros for compilers and versions -- a well known source is this one at sf.net -- and we try out best to reflect that in our sources.
In short, g++ 4.8 or later (as on Linux) and clang 3.4 or 3.5 (as on Linux and OS X) are good enough.
Windows and its g++ 4.6.* has issues. That latter one is the compiler we are given by Rtools and there is little we can do.
CXX1XSTD is defined by R 3.1.0 or later. R tests the compiler during its compile / build cycle and remember, so when as you for a C++11 etc compliant compiler R knows whether to give you c++0x or c++11. In essence, you are thinking here that you know better; I think you may be wrong in that belief. But hey, if there is something we can do better than we currently do in the Rcpp / RcppArmadillo headers then let us know.
I didn't see where you said why you turned C++11 on. Are you actually using C++11 or later features? Because if you don't then the whole issue is moot. But if you do then you need to be careful. Many R installations will have old compilers (Windows, older RHEL, ...).
I suspect you'd get overall better respones if you posted on rcpp-devel.