Repository: spack/spack

Issue:
intel-tbb broken if no transactional memory
I tried to install intel-tbb on an old Intel x86-64 cluster at Rice.
The build fails with:

% spack  install  intel-tbb
...
     21    /work/hpc/krentel/work/spack-repo/lib/spack/env/gcc/g++ -o scheduler.o -c -MMD -DTBB_USE_DEBUG -DDO_ITT_NOTIFY -g -O0 -DUSE_PTHREAD -m64 -mrtm  -fPIC  -D__TBB_BUILD=1 -Wall -Wno-parentheses -Wno-non-virtual-dtor    -I../../src -I../../src/rml/include -I../../include ../../src/tbb/scheduler.cpp
     22    /tmp/cchPyt9b.s: Assembler messages:
  >> 23    /tmp/cchPyt9b.s:672: Error: no such instruction: `xtest'
  >> 24    /tmp/cchPyt9b.s:691: Error: no such instruction: `xend'

The problem is that xtest and xend are transactional memory
instructions and either the machine or the compiler don't understand
transactional memory.

/proc/cpuinfo reports:

processor	: 11
vendor_id	: GenuineIntel
cpu family	: 6
model		: 44
model name	: Intel(R) Xeon(R) CPU     X5660  @ 2.80GHz
stepping	: 2
microcode	: 16
cpu MHz		: 2800.047
cache size	: 12288 KB
...
flags		: fpu vme de pse tsc msr pae mce cx8 apic mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid dca sse4_1 sse4_2 popcnt aes lahf_lm arat epb dtherm tpr_shadow vnmi flexpriority ept vpid

Looking inside the tbb source, we see in include/tbb/tbb_config.h:

#define __TBB_TSX_AVAILABLE  ((__TBB_x86_32 || __TBB_x86_64) && !__TBB_DEFINE_MIC)

So, the real problem is that Intel thinks that all 64-bit x86 machines
(except Xeon Phi/MIC) have transactional memory, and that's not true.

One solution would be to patch the #define to 0, but that would
disable all transactional memory.

I guess a more spack-ish solution would be to add a 'transactional-memory'
variant to intel-tbb and conditionally apply a patch, or otherwise set
__TBB_TSX_AVAILABLE to 0.

But what I really want is a better way to auto test if the given
machine (or host machine in a cross compile) supports some feature, in
this case transactional memory.  I'll open a separate issue for that.

Thanks,

--Mark

P.S. I did search for intel-tbb, but I didn't find anything related to
transactional memory.



Discussion:

Resolving patch:
diff --git a/var/spack/repos/builtin/packages/intel-tbb/package.py b/var/spack/repos/builtin/packages/intel-tbb/package.py
--- a/var/spack/repos/builtin/packages/intel-tbb/package.py
+++ b/var/spack/repos/builtin/packages/intel-tbb/package.py
@@ -73,6 +73,9 @@ class IntelTbb(Package):
             multi=False,
             description='Use the specified C++ standard when building.')
 
+    variant('tm', default=True,
+            description='Enable use of transactional memory on x86')
+
     # Build and install CMake config files if we're new enough.
     depends_on('cmake@3.0.0:', type='build', when='@2017.0:')
 
@@ -84,6 +87,9 @@ class IntelTbb(Package):
     # Patch cmakeConfig.cmake.in to find the libraries where we install them.
     patch("tbb_cmakeConfig.patch", level=0, when='@2017.0:')
 
+    # Some very old systems don't support transactional memory.
+    patch("disable-tm.patch", when='~tm')
+
     def url_for_version(self, version):
         url = 'https://github.com/01org/tbb/archive/{0}.tar.gz'
         if (version[0] >= 2017) and len(version) > 1:


Test patch: