Thursday 7 March 2019

Intel C++ compiler with C++14 features

The Intel C++ compiler documentation gives a large range of GCC versions in the system requirements, eg. for Intel 18.0 it says that:

gcc versions 4.3 - 6.3 supported

(remember prior to version 5 GCC only updated the minor version number for each major release).

However, this is not the full story, if one reads the Intel C++ Compiler 18.0 Developer Guide and Reference, specifically the subsection 'How the Intel Compiler Uses GCC' under 'GCC* Compatibility and Interoperability' section then it makes clear the Intel compiler will behave like the underlying GCC version with respect to available features and behaviour. This means if you want C++14 standard you must use a GCC with this available, i.e. GCC 5 or greater. Taking this into account, the base GCC you need for Intel 18.0 C++ compiler with C++14 features is version 5 or 6. Any higher and Intel does not support this GCC with it's compiler (I tried myself and saw a range of problems), lower than this and you don't have a C++14 standard compiler.

Intel 2019


For Intel 2019 the range of GCC supported is 4.3 - 8.x. This means for C++14 support the possible GCC versions are 5 - 8.

Friday 24 February 2017

Bug reports, pull requests etc.

This post is a place for links to my bug reports and is mainly for my own reference, most likely it is of no general interest.

AMD x86 Open64 Compiler Suite (link)
Autoconf
Avogadro (link)
Block
Doxygen
Eigen
Flang
GCC
Global Arrays
Intel Fortran compiler
Not my bug report, but I would very much like this to be fixed!

libcint
MPICH
MXE
openSUSE
Portland compilers

Thursday 25 February 2016

A simple C/C++ Libxml2 XmlTextReader example

I had a request recently for a simple example of how to use the XmlTextReader interface to Libxml2. This interface simply traverses a document node by node, so it's perfect if you just want to read a file in incrementally, but is not suitable should you need to run XSLT queries on the whole document.

Here is the code:

#include <stdio.h>
#include <libxml/xmlreader.h>

int main(){
 xmlTextReaderPtr reader;
 /* initialize libxml2 */
 LIBXML_TEST_VERSION

 reader = xmlNewTextReaderFilename("my_file.xml");
 while ( xmlTextReaderRead(reader) ) {
  fprintf(stdout,"ConstName=%s\n",xmlTextReaderConstName(reader));
  fprintf(stdout,"LocalName=%s\n",xmlTextReaderLocalName(reader));
  fprintf(stdout,"Name=%s\n",xmlTextReaderName(reader));
  fprintf(stdout,"NodeType=%d\n",xmlTextReaderNodeType(reader));
  fprintf(stdout,"Prefix=%s\n",xmlTextReaderPrefix(reader));
  fprintf(stdout,"NamespaceUri=%s\n",xmlTextReaderNamespaceUri(reader));
  fprintf(stdout,"BaseUri=%s\n",xmlTextReaderBaseUri(reader));
  fprintf(stdout,"Depth=%d\n",xmlTextReaderDepth(reader));
  fprintf(stdout,"HasAttributes=%d\n",xmlTextReaderHasAttributes(reader));
  fprintf(stdout,"HasValue=%d\n",xmlTextReaderHasValue(reader));
  fprintf(stdout,"Value=%s\n",xmlTextReaderValue(reader));
  fprintf(stdout,"IsDefault=%d\n",xmlTextReaderIsDefault(reader));
  fprintf(stdout,"XmlLang=%s\n",xmlTextReaderXmlLang(reader));
  fprintf(stdout,"IsEmptyElement=%d\n",xmlTextReaderIsEmptyElement(reader));
  fprintf(stdout,"AttributeCount=%d\n",xmlTextReaderAttributeCount(reader));
 }
 xmlFreeTextReader(reader);

 xmlCleanupParser();
 return 0;
}

Friday 24 July 2015

Raising a negative number to a non-integer power

It is undefined to raise a negative number to a non-integer power. However, Fortran compilers differ in their handling of the case when the power is an integer represented as a floating point number. Consider the following code:

      program test
      implicit double precision(a-h,o-z)
      a=-26.5227750387574375d0
      b=1.0000000000000000d0
      write(6,*)a**(b-0.01d0)
      write(6,*)a**b
      write(6,*)a**(b+0.01d0)
      end

With Intel compiler this is the result:

> ifort test.f
> ./a.out 
                     NaN
  -26.5227750387574     
                     NaN

But with NAG compiler all of the results are NaN:

> nagfor -ieee=full test.f
> ./a.out 
                     NaN   
                     NaN
                     NaN

Wednesday 2 July 2014

The Fortran makefile dependency problem

For a project comprising of C/C++ code and header files, to simply compile once there is often no need for dependencies. Assuming that none of the header files are generated as part of the build process, it doesn't matter which order the source files are compiled in.

When developing a piece of code it is inefficient to recompile all the source files when a file has changed. Instead just the files which depend on those changes need to be recompiled. For example, when modifying a single C file only that file need be recompiled, or in the case of modifying a header file, all source files which include the header should be recompiled.

For a while standalone tools such as makedepend were used to generate these dependencies, but these have largely been superceded by the compilers themselves, commonly via a '-M' flag. This has great advantages, not least because the compiler itself knows best how to pre-process the file and which defines are internally set. A typical setup would therefore compile all files and then generate dependencies during the initial make. Subsequent makes include those dependencies and only recompiles things that have changed or are newly created, whilst of course also updating any dependencies accordingly.


There is a problem if one attempts to apply such a set-up to a Fortran project, namely F90 module files. Modules are similar to C header files, except that they themselves are source code which must be compiled before they can be used. For a small project one can of course write by hand that file A generates module M which is needed by files B and C. However, for larger projects, where modules are including other modules, which include other modules etc. this quickly becomes complicated. Some Fortran compilers (eg. gfortran) are able to generate dependencies via a '-M' option, but this is of little help since it can't be done until the relevant modules are available, a classic chicken and egg situation.

So unlike C, with Fortran the order in which source files should be compiled matters, and therefore dependencies must be generated before any compilation is done. This has unsurprisingly resulted in a whole series of tools designed to do this, sfmakedepend is the first that google turns up. In truth, many of these tools are actually more complicated than they need be since they often attempt to deal with Fortran and CPP include directives. These could be handled in the same way as C include directives, but of course it has the advantage that one does not need to generate separately module and include dependencies.

In conclusion, with Fortran one needs to generate at least module dependencies for all source files, and then include those dependencies before attempting to compile any source code.

It should be mentioned that for a Fortran project not making use of F90 module files this problem of course does not exist.

Tuesday 1 July 2014

EKOPath dependency generation bug

Most C/C++ compilers support dependency generation, often through the -M series of flags. For some reason the two version of EKOPath I've installed (5.0.1 and 5.0.5) contain a bug such that:

> pathCC -M test.cpp
psclang: error: unknown argument: '-Eonly'

The solution is to instruct the compiler to pre-process only and pass the -M option through to the preprocessor, i.e.:

> pathCC -E -Wp,-M test.cpp
test.o: test.cpp test.h

Wednesday 25 June 2014

OSX command line user admin

Setting up and modifying user accounts via the command line on OSX is a bit of pain. The supplied tools to do it require one to not only set reasonable things, such as login name, but to also choose a unique id, assign a primary group etc., things that the graphical way of creating users automatically populate with sensible defaults.

Examples of when one might need to do this are: when a machine is only accessible via ssh; when a sysadmin wants a script to run on multiple machines to setup a series of user accounts.

On Linux there are utilities such as useradd which has many options, but crucially has sensible defaults such that in practice only a few need be specified to create a new account, eg.:

useradd -m -c 'Joe Bloggs' joe

Inspired by personal experience of attempting to create a new user account on an OSX machine via ssh, I wrote versions of useradd etc. for OSX, which are available here. Of course I only implemented the features that I needed at the time... but will perhaps make them more complete in the future.