Modify

Ticket #8048 (closed Bugs: fixed)

Opened 14 months ago

Last modified 6 months ago

Boost 1.53 + GCC 4.6.3 __int128 undefined.

Reported by: wchan212@… Owned by: johnmaddock
Milestone: To Be Determined Component: config
Version: Boost 1.53.0 Severity: Showstopper
Keywords: Cc:

Description

Hi. I am using gcc 4.6.3 as well as boost 1.53.0; my program previously compiles fine w/ boost 1.52.0.

I get this error:

/opt/orange/include/boost/config/suffix.hpp(496): error: identifier "int128" is undefined

/opt/orange/include/boost/config/suffix.hpp(497): error: expected a ";"

/opt/orange/include/boost/config/suffix.hpp(496): error: identifier "int128" is undefined

/opt/orange/include/boost/config/suffix.hpp(497): error: expected a ";"

/opt/orange/include/boost/config/suffix.hpp(496): error: identifier "int128" is undefined

/opt/orange/include/boost/config/suffix.hpp(497): error: expected a ";"

/opt/orange/include/boost/type_traits/is_integral.hpp(74): error: namespace "boost" has no member "uint128_type"

/opt/orange/include/boost/type_traits/is_integral.hpp(74): error: class "boost::is_integral<boost::int128_type>" has already been defined

/opt/orange/include/boost/type_traits/is_integral.hpp(74): error: namespace "boost" has no member "uint128_type"

/opt/orange/include/boost/type_traits/is_integral.hpp(74): error: class "boost::is_integral<const boost::int128_type>" has already been defined

/opt/orange/include/boost/type_traits/is_integral.hpp(74): error: namespace "boost" has no member "uint128_type"

/opt/orange/include/boost/type_traits/is_integral.hpp(74): error: class "boost::is_integral<volatile boost::int128_type>" has already been defined

/opt/orange/include/boost/type_traits/is_integral.hpp(74): error: namespace "boost" has no member "uint128_type"

/opt/orange/include/boost/type_traits/is_integral.hpp(74): error: class "boost::is_integral<const volatile boost::int128_type>" has already been defined

/opt/orange/include/boost/type_traits/is_integral.hpp(74): error: namespace "boost" has no member "uint128_type"

/opt/orange/include/boost/type_traits/is_integral.hpp(74): error: class "boost::is_integral<boost::int128_type>" has already been defined

/opt/orange/include/boost/type_traits/is_integral.hpp(74): error: namespace "boost" has no member "uint128_type"

/opt/orange/include/boost/type_traits/is_integral.hpp(74): error: class "boost::is_integral<const boost::int128_type>" has already been defined

/opt/orange/include/boost/type_traits/is_integral.hpp(74): error: namespace "boost" has no member "uint128_type"

/opt/orange/include/boost/type_traits/is_integral.hpp(74): error: class "boost::is_integral<volatile boost::int128_type>" has already been defined

/opt/orange/include/boost/type_traits/is_integral.hpp(74): error: namespace "boost" has no member "uint128_type"

/opt/orange/include/boost/type_traits/is_integral.hpp(74): error: class "boost::is_integral<const volatile boost::int128_type>" has already been defined

/opt/orange/include/boost/type_traits/is_integral.hpp(74): error: namespace "boost" has no member "uint128_type"

/opt/orange/include/boost/type_traits/is_integral.hpp(74): error: class "boost::is_integral<boost::int128_type>" has already been defined

/opt/orange/include/boost/type_traits/is_integral.hpp(74): error: namespace "boost" has no member "uint128_type"

/opt/orange/include/boost/type_traits/is_integral.hpp(74): error: class "boost::is_integral<const boost::int128_type>" has already been defined

/opt/orange/include/boost/type_traits/is_integral.hpp(74): error: namespace "boost" has no member "uint128_type"

/opt/orange/include/boost/type_traits/is_integral.hpp(74): error: class "boost::is_integral<volatile boost::int128_type>" has already been defined

/opt/orange/include/boost/type_traits/is_integral.hpp(74): error: namespace "boost" has no member "uint128_type"

/opt/orange/include/boost/type_traits/is_integral.hpp(74): error: class "boost::is_integral<const volatile boost::int128_type>" has already been defined

/opt/orange/include/boost/type_traits/make_unsigned.hpp(79): error: namespace "boost" has no member "uint128_type"

/opt/orange/include/boost/type_traits/make_unsigned.hpp(111): error: namespace "boost" has no member "uint128_type"

/opt/orange/include/boost/type_traits/make_unsigned.hpp(79): error: namespace "boost" has no member "uint128_type"

/opt/orange/include/boost/type_traits/make_unsigned.hpp(111): error: namespace "boost" has no member "uint128_type"

/opt/orange/include/boost/type_traits/make_unsigned.hpp(79): error: namespace "boost" has no member "uint128_type"

/opt/orange/include/boost/type_traits/make_unsigned.hpp(111): error: namespace "boost" has no member "uint128_type"

/opt/orange/include/boost/functional/hash/hash.hpp(92): error: namespace "boost" has no member "uint128_type"

/opt/orange/include/boost/functional/hash/hash.hpp(92): error: namespace "boost" has no member "uint128_type"

/opt/orange/include/boost/functional/hash/hash.hpp(92): error: namespace "boost" has no member "uint128_type"

/opt/orange/include/boost/functional/hash/hash.hpp(444): error: namespace "boost" has no member "uint128_type"

/opt/orange/include/boost/functional/hash/hash.hpp(444): error: class "boost::hash<boost::int128_type>" has already been defined

/opt/orange/include/boost/functional/hash/hash.hpp(444): error: namespace "boost" has no member "uint128_type"

/opt/orange/include/boost/functional/hash/hash.hpp(444): error: namespace "boost" has no member "uint128_type"

/opt/orange/include/boost/functional/hash/hash.hpp(444): error: namespace "boost" has no member "uint128_type"

/opt/orange/include/boost/functional/hash/hash.hpp(444): error: class "boost::hash<boost::int128_type>" has already been defined

/opt/orange/include/boost/functional/hash/hash.hpp(444): error: namespace "boost" has no member "uint128_type"

/opt/orange/include/boost/functional/hash/hash.hpp(444): error: namespace "boost" has no member "uint128_type"

/opt/orange/include/boost/functional/hash/hash.hpp(444): error: namespace "boost" has no member "uint128_type"

/opt/orange/include/boost/functional/hash/hash.hpp(444): error: class "boost::hash<boost::int128_type>" has already been defined

/opt/orange/include/boost/functional/hash/hash.hpp(444): error: namespace "boost" has no member "uint128_type"

/opt/orange/include/boost/functional/hash/hash.hpp(444): error: namespace "boost" has no member "uint128_type"

Attachments

Change History

comment:1 Changed 14 months ago by marshall

Can you run a test, please?

Check if __SIZEOF_INT128__ is defined.

Thanks!

comment:2 Changed 14 months ago by anonymous

See below:

wchan@speech07:/tmp$ cat test.cc
#include <iostream>

int main(int argc, char* argv[]) {
#ifdef __SIZEOF_INT128__
  std::cout << "__SIZEOF_INT128__ = " << __SIZEOF_INT128__ << std::endl;
#else
  std::cout << "Nope! no __SIZEOF_INT128__" << std::endl;
#endif
}

wchan@speech07:/tmp$ g++ -o test.gcc test.cc && ./test.gcc
__SIZEOF_INT128__ = 16
wchan@speech07:/tmp$ nvcc -o test.nvcc test.cc && ./test.nvcc
__SIZEOF_INT128__ = 16
Last edited 14 months ago by viboes (previous) (diff)

comment:3 Changed 14 months ago by anonymous

Previous comment screwed up, see below again.

wchan@speech07:/tmp$ cat test.cc
#include <iostream>

int main(int argc, char* argv[]) {
#ifdef __SIZEOF_INT128__
  std::cout << "__SIZEOF_INT128__ = " << __SIZEOF_INT128__ << std::endl;
#else
  std::cout << "Nope! no __SIZEOF_INT128__" << std::endl;
#endif
}

wchan@speech07:/tmp$ g++ -o test.gcc test.cc && ./test.gcc
__SIZEOF_INT128__ = 16
wchan@speech07:/tmp$ nvcc -o test.nvcc test.cc && ./test.nvcc
__SIZEOF_INT128__ = 16

comment:4 Changed 14 months ago by marshall

Great!

Next test, please:

typedef __int128 Cint128_1;

and:

__extension__ typedef __int128 Cint128_2;

Do either of those work?

comment:5 Changed 14 months ago by anonymous

wchan@speech07:/tmp$ cat test.cc
#include <iostream>

typedef __int128 Cint128_1;
__extension__ typedef __int128 Cint128_2;

int main(int argc, char* argv[]) {
#ifdef __SIZEOF_INT128__
  std::cout << "__SIZEOF_INT128__ = " << __SIZEOF_INT128__ << std::endl;
  std::cout << "sizeof(Cint128_1) = " << sizeof(Cint128_1) << std::endl;
  std::cout << "sizeof(Cint128_1) = " << sizeof(Cint128_2) << std::endl;
#else
  std::cout << "Nope! no __SIZEOF_INT128__" << std::endl;
#endif
}

wchan@speech07:/tmp$ g++ --version && g++ -o test.gcc test.cc && ./test.gcc
g++ (GCC) 4.6.3
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

__SIZEOF_INT128__ = 16
sizeof(Cint128_1) = 16
sizeof(Cint128_1) = 16
wchan@speech07:/tmp$ nvcc --version && nvcc -o test.nvcc test.cc && ./test.nvcc
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2012 NVIDIA Corporation
Built on Thu_Apr__5_00:24:31_PDT_2012
Cuda compilation tools, release 4.2, V0.2.1221
__SIZEOF_INT128__ = 16
sizeof(Cint128_1) = 16
sizeof(Cint128_1) = 16

comment:6 Changed 14 months ago by marshall

Ok. that's almost the same code that's in suffix.hpp.

Let's make it exact. try this code, please:

namespace boost{
#  ifdef __GNUC__
   __extension__ typedef __int128 int128_type;
   __extension__ typedef unsigned __int128 uint128_type;
#  else
   typedef __int128 int128_type;
   typedef unsigned __int128 uint128_type;
#  endif
}

If that works, I'm out of suggestions.

comment:7 Changed 14 months ago by anonymous

wchan@speech07:/tmp$ cat test.cc
#include <iostream>

namespace boost{
#  ifdef __GNUC__
   __extension__ typedef __int128 int128_type;
   __extension__ typedef unsigned __int128 uint128_type;
#  else
   typedef __int128 int128_type;
   typedef unsigned __int128 uint128_type;
#  endif
};

typedef __int128 Cint128_1;
__extension__ typedef __int128 Cint128_2;

int main(int argc, char* argv[]) {
#ifdef __SIZEOF_INT128__
  std::cout << "__SIZEOF_INT128__ = " << __SIZEOF_INT128__ << std::endl;
  std::cout << "sizeof(Cint128_1) = " << sizeof(boost::int128_type) << std::endl;
  std::cout << "sizeof(Cint128_2) = " << sizeof(boost::uint128_type) << std::endl;
#else
  std::cout << "Nope! no __SIZEOF_INT128__" << std::endl;
#endif
}

wchan@speech07:/tmp$ g++ -o test.gcc test.cc && ./test.gcc
__SIZEOF_INT128__ = 16
sizeof(Cint128_1) = 16
sizeof(Cint128_2) = 16
wchan@speech07:/tmp$ nvcc -o test.nvcc test.cc && ./test.nvcc
__SIZEOF_INT128__ = 16
sizeof(Cint128_1) = 16
sizeof(Cint128_2) = 16

comment:8 Changed 14 months ago by anonymous

Are you on #boost on irc? Do you want me to go on?

comment:9 Changed 14 months ago by marshall

I'm on #boost now.

comment:10 follow-up: ↓ 11 Changed 14 months ago by marshall

After discussing this with the OP, it turns out that he is using nvcc, Nvidia's compiler, which claims to be gcc.

Furthermore, he's seeing this error only when compiling a cuda source file (xxx.cu), not C++.

In this mode, nvcc is defining the preprocessor symbol __SIZEOF_INT128__, but not the type __int128

comment:11 in reply to: ↑ 10 ; follow-up: ↓ 12 Changed 14 months ago by anonymous

Replying to marshall:

After discussing this with the OP, it turns out that he is using nvcc, Nvidia's compiler, which claims to be gcc.

Furthermore, he's seeing this error only when compiling a cuda source file (xxx.cu), not C++.

In this mode, nvcc is defining the preprocessor symbol __SIZEOF_INT128__, but not the type __int128

Can you give me an indication of whether there is a workaround for this. I'm compiling a file that is named .cu but contains heavy c++. I get the 128 error with 4.7.1 nvcc release 5.0, V0.2.1221 and boost 1.53?

comment:12 in reply to: ↑ 11 Changed 14 months ago by marshall

Replying to anonymous:

Replying to marshall:

After discussing this with the OP, it turns out that he is using nvcc, Nvidia's compiler, which claims to be gcc.

Furthermore, he's seeing this error only when compiling a cuda source file (xxx.cu), not C++.

In this mode, nvcc is defining the preprocessor symbol __SIZEOF_INT128__, but not the type __int128

Can you give me an indication of whether there is a workaround for this. I'm compiling a file that is named .cu but contains heavy c++. I get the 128 error with 4.7.1 nvcc release 5.0, V0.2.1221 and boost 1.53?

I suspect that:

#if defined(BOOST_HAS_INT128) && defined(__CUDACC__)
#undef BOOST_HAS_INT128
#endif

added to the end of boost/config/compiler/nvcc.hpp will solve the problem; but I don't know for sure. I am working with the OP to test this.

comment:13 Changed 14 months ago by viboes

  • Owner set to johnmaddock
  • Component changed from None to config

comment:14 Changed 14 months ago by johnmaddock

Many thanks for investigating this Marshall, is there anything you need me to do?

John Maddock.

comment:15 Changed 14 months ago by anonymous

To the GCC 4.7.1 guy above, AFAIK IIRC CUDA 5.0 still only supports GCC 4.6.x and not 4.7.x

comment:16 follow-up: ↓ 29 Changed 14 months ago by anonymous

credits to @Marshall, adding this to:

#if defined(BOOST_HAS_INT128)
#undef BOOST_HAS_INT128
#endif

the end of boost/config/nvcc.hpp fixes the compile for now. This would be a quick hack for those who need boost 1.53 compiling w/ nvcc.

comment:17 follow-up: ↓ 18 Changed 14 months ago by anonymous

credits to @Marshall

Adding

#if defined(BOOST_HAS_INT128) && defined(__CUDACC__)
#undef BOOST_HAS_INT128
#endif

to the end of boost/config/nvcc.hpp also works. I think this is a slightly more robust solution? (@Marshall, the first time we tried it we forgot the "if", that's why it didnt work)

comment:18 in reply to: ↑ 17 Changed 14 months ago by anonymous

Replying to anonymous:

credits to @Marshall

Adding

#if defined(BOOST_HAS_INT128) && defined(__CUDACC__)
#undef BOOST_HAS_INT128
#endif

to the end of boost/config/nvcc.hpp also works. I think this is a slightly more robust solution? (@Marshall, the first time we tried it we forgot the "if", that's why it didnt work)

Guys, thanks for that, this worked adding that to config/compiler/nvcc.hpp (not config/nvcc,hpp for future readers). However, I have come across an other problem this time with property tree. Although the file I'm compiling with nvcc contains no device code and is pure host code, it does need to be parsed and compiled by nvcc not gcc for various reasons. Even the mere inclusion of:

#include <boost/property_tree/json_parser.hpp> #include <boost/foreach.hpp> #include <boost/property_tree/ptree.hpp>

Gives the following error, using the same set up as above in terms of my compiler, nvcc and boost 1.53. The error begins with: boost-1.53.0/include/boost/property_tree/detail/ptree_implementation.hpp:111:73: error: expected template-name before ‘<’ token boost-1.53.0/include/boost/property_tree/detail/ptree_implementation.hpp:111:73: error: expected ‘{’ before ‘<’ token boost-1.53.0/include/boost/property_tree/detail/ptree_implementation.hpp:111:73: error: expected unqualified-id before ‘<’ token boost-1.53.0/include/boost/property_tree/detail/ptree_implementation.hpp:121:79: error: expected template-name before ‘<’ token boost-1.53.0/include/boost/property_tree/detail/ptree_implementation.hpp:121:79: error: expected ‘{’ before ‘<’ token boost-1.53.0/include/boost/property_tree/detail/ptree_implementation.hpp:121:79: error: expected unqualified-id before ‘<’ token boost-1.53.0/include/boost/property_tree/detail/json_parser_read.hpp: In constructor ‘boost::property_tree::json_parser::json_grammar<Ptree>::definition<Scanner>::definition(const boost::property_tree::json_parser::json_grammar<Ptree>&)’: boost-1.53.0/include/boost/property_tree/detail/json_parser_read.hpp:257:298: error: ‘type name’ declared as function returning an array boost-1.53.0/include/boost/property_tree/detail/json_parser_read.hpp:257:298: error: ‘type name’ declared as function returning an array

This is before I even try to use property tree. Any thoughts or work arounds this time? It works perfectly correctly and compiles with gcc 4.7.1

Cheers,

comment:19 follow-up: ↓ 20 Changed 14 months ago by anonymous

CUDA 5 does NOT support GCC 4.7.* ... please try again w. gcc 4.6

comment:20 in reply to: ↑ 19 Changed 14 months ago by anonymous

Replying to anonymous:

CUDA 5 does NOT support GCC 4.7.* ... please try again w. gcc 4.6

Sure, I appreciate that, then again there are many of us using it quite successfully, so it would be useful to have these sort of things worked-around if possible. Could suggest a fix even though I appreciate it's unsupported?

comment:21 Changed 14 months ago by anonymous

Can you still try w/ GCC 4.6.*? This will help isolate the issue.

comment:22 follow-up: ↓ 24 Changed 14 months ago by johnmaddock

I'm not against the patch as proposed. However, what happens when the CUDA guys update their compiler to support GCC-4.7.x and add support for __int128 ? Can we make the #undef conditional on the CUDA version?

comment:23 Changed 14 months ago by anonymous

AFAIK there is a CUDA_VERSION macro. For the CUDA 5 cuda.h we have:

 133 /**
 134  * CUDA API version number
 135  */
 136 #define CUDA_VERSION 5000
 137 

comment:24 in reply to: ↑ 22 Changed 14 months ago by marshall

Replying to johnmaddock:

I'm not against the patch as proposed. However, what happens when the CUDA guys update their compiler to support GCC-4.7.x and add support for __int128 ? Can we make the #undef conditional on the CUDA version?

"Always in motion is the future"

Certainly we can add something like "if GCC < 4.7" to the #ifdef, but what if the 4.7 version of nvcc still doesn't support __int128. Then we'd have to rev anyway.

John - do you have knowledge that the CUDA guys are planning this?

comment:25 Changed 14 months ago by johnmaddock

"Always in motion is the future"

Ain't that the truth.

Certainly we can add something like "if GCC < 4.7" to the #ifdef, but what if the 4.7 >version of nvcc still doesn't support int128. Then we'd have to rev anyway.

John - do you have knowledge that the CUDA guys are planning this?

Nope, but if they "officially" support 4.7 and later and still define __SIZEOF_INT128__ then they'd better support __int128 or else it's a bug in their compiler support.

I guess either way we won't do anything about it unless someone complains. Hmmm, maybe you're right that a blanket exclusion is safer - at least pretty much all of Boost will work just fine then. OK... I think I've convinced myself :-) I'll commit the original fix unless someone disagrees.

comment:26 Changed 14 months ago by johnmaddock

(In [83012]) Fix Int128 support on CUDA. Exclude BOOST_GCC from getting defined on CUDA. Refs #8048. Refs #7841.

comment:27 Changed 14 months ago by johnmaddock

(In [83014]) Add comment on change. Refs #8048.

comment:28 Changed 14 months ago by johnmaddock

  • Status changed from new to closed
  • Resolution set to fixed

(In [83139]) Merge changes from Trunk. Fixes #6013. Fixes #7151. Fixes #7359. Fixes #7389. Fixes #7452. Fixes #7528. Fixes #7703. Fixes #7841. Fixes #7898. Fixes #7938. Fixes #8048.

comment:29 in reply to: ↑ 16 Changed 10 months ago by anonymous

Replying to anonymous:

credits to @Marshall, adding this to:

#if defined(BOOST_HAS_INT128)
#undef BOOST_HAS_INT128
#endif

the end of boost/config/nvcc.hpp fixes the compile for now. This would be a quick hack for those who need boost 1.53 compiling w/ nvcc.

Yes - works here too! Thanks!

comment:30 Changed 7 months ago by anonymous

(Original bug filer reposting)... This bug has reappeared with GCC 4.7.3 and Boost 1.54.0 and CUDA 5.5

comment:31 Changed 7 months ago by anonymous

The code has:

#if defined(__SIZEOF_INT128__) && !defined(__CUDACC__)
#  define BOOST_HAS_INT128
#endif

Is __CUDACC__ not defined? And if not what is?

comment:32 Changed 6 months ago by anonymous

(Original bug filer reposting)... This bug has reappeared with GCC 4.7.3 and Boost 1.54.0 and CUDA 5.5 EDIT: on OSX but not on Linux.

comment:33 Changed 6 months ago by anonymous

Please see my comment above - is __CUDAC__ not defined? And if not what the heck does identify this compiler?

comment:34 Changed 6 months ago by anonymous

(Original bug filer) posting.

wchan:/private/tmp$ gcc --version
gcc (GCC) 4.7.3
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

wchan:/private/tmp$ nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2013 NVIDIA Corporation
Built on Wed_Jul_10_11:16:01_PDT_2013
Cuda compilation tools, release 5.5, V5.5.0
wchan:/private/tmp$ cat test.cu
// #include <boost/functional/hash.hpp>
// If I uncomment the line above, it will not compile.
// error: identifier "__int128" is undefined

#include <iostream>

int main(int argc, char* argv[]) {
#if defined(__CUDACC__)
  std::cout << "__CUDACC__ == 1" << std::endl;
#else
  std::cout << "__CUDACC__ == 0" << std::endl;
#endif
}

wchan:/private/tmp$ nvcc test.cu
wchan:/private/tmp$ ./a.out 
__CUDACC__ == 1

comment:35 Changed 6 months ago by johnmaddock

Well this is very strange then - I've checked that all uses of int128 in Boost are guarded by BOOST_HAS_INT128 (they are), and that macro is defined in boost/config/compiler/gcc.hpp via:

#if defined(__SIZEOF_INT128__) && !defined(__CUDACC__)
#  define BOOST_HAS_INT128
#endif

Can you try and figure out how/why BOOST_HAS_INT128 macro is getting set in the above code?

View

Add a comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
The resolution will be deleted. Next status will be 'reopened'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.