- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This is my first posting here, so I apologize if this isn't quite the right place for this question.
So I just got very interested in multiversioning in order to do some performance comparisons of instruction sets between Haswell and SandyBridge, and with functions it's a breeze, but when I tried to do the same with operators I received the following error:
internal error: assertion failed: mangled_operator_name: bad kind (shared/cfe/edgcpfe/lower_name.c, line 10192)
__attribute__ ((target("default")))
IntVec& operator+=(IntVec& v1, const IntVec& v2) {
v1.data()[0:v1.size()] += v2.data()[0:v2.size()];
return v1;
}
//IntVec is just short for std::vector<int>
I can't seem to find any information as to why this is invalid on the web, so I assume there must be some way to accomplish this, though everything I've tried has failed or created overhead I know shouldn't be necessary. Is it valid to try this? If so, what's the proper course? Otherwise, why is it invalid to have multiple versions of an operator for various instruction sets?
Also, if I wanted to specifically target a Xeon Phi, how would I best go about this?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
From my understanding, this is valid and should be accepted!!
Whatever, such an error at least means a bug of compiler crash. I've reproduced it with 15.0 v2 compiler, I'll submit it to dev team to fix.
Thanks,
Shenghong
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Patrick,
This issue is fixed in update 3 release, v15.0. Please upgrade and verify.
$ cat temp.cpp #include <vector> // this works __attribute__ ((target("default"))) void foo() {} // this will crash __attribute__ ((target("default"))) void operator+=(std::vector<int>& v1, std::vector<int>& v2){ } $ icc temp.cpp -c $ icc -V Intel(R) C Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 15.0.3.187 Build 20150407 Copyright (C) 1985-2015 Intel Corporation. All rights reserved. $
Thanks,
Shenghong
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
shenghong-geng (Intel) wrote:
Patrick,
This issue is fixed in update 3 release, v15.0. Please upgrade and verify.
Thanks,
Shenghong
Oh you're gonna love this. The following version will not let me compile with an attribute on an operator with a template, BUT, the second version will. Notice the backslash on the second version, AND, I can correctly target different architectures. So, someone still has some work to do. As to the original point, I can now put an attribute on an operator, but it will not work if there is a template. Or is there a more correct way to do this?
#include <vector> #include <iostream> std::vector<int> data1 = {0,1,2,3,4}; std::vector<int> data2 = {5,4,3,2,1}; // this works __attribute__ ((target("default"))) void foo() {} // this will crash __attribute__ ((target("default"))) template <class T> void operator+=(std::vector<T>& v1, std::vector<T>& v2){ v1.data()[0:v1.size()] += v2.data()[0:v2.size()]; } int main(int argc, char** argv) { for (auto a : data1) std::cout << a << ' '; std::cout << std::endl; for (auto b : data2) std::cout << b << ' '; std::cout << std::endl; foo(); data1 += data2; for (auto c : data1) std::cout << c << ' '; std::cout << std::endl; }
//gets error: temp.cpp(12): error: attributes are not allowed here
__attribute__ ((target("default")))
//the following works
#include <vector> #include <iostream> std::vector<int> data1 = {0,1,2,3,4}; std::vector<int> data2 = {5,4,3,2,1}; // this works and can target any desired attribute __attribute__ ((target("default"))) void foo() {} // this will crash\ __attribute__ ((target("default"))) template <class T> void operator+=(std::vector<T>& v1, std::vector<T>& v2){ v1.data()[0:v1.size()] += v2.data()[0:v2.size()]; } int main(int argc, char** argv) { for (auto a : data1) std::cout << a << ' '; std::cout << std::endl; for (auto b : data2) std::cout << b << ' '; std::cout << std::endl; foo(); data1 += data2; for (auto c : data1) std::cout << c << ' '; std::cout << std::endl; }
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Patrick,
I do spend some time to understand the differences of your 2 versions of code!!! :) And finally, I saw the "Notice the backslash on the second version" description!!
First, I'll explain why adding "\" makes it work. With "\", the attribute line is commented!! And by default, ICC will generate the code for all arch. So, it works for difference arch, but they share the same code in fact.
Second, it is an usage error for your code, you cannot add attribute before "template", instead, below is correct usage:
template <class T> __attribute__ ((target("default"))) void operator+=(std::vector<T>& v1, std::vector<T>& v2){ v1.data()[0:v1.size()] += v2.data()[0:v2.size()]; }
Let me know if you still have issues.
Thanks,
Shenghong
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
shenghong-geng (Intel) wrote:
Hi Patrick,
I do spend some time to understand the differences of your 2 versions of code!!! :) And finally, I saw the "Notice the backslash on the second version" description!!
First, I'll explain why adding "\" makes it work. With "\", the attribute line is commented!! And by default, ICC will generate the code for all arch. So, it works for difference arch, but they share the same code in fact.
Second, it is an usage error for your code, you cannot add attribute before "template", instead, below is correct usage:
template <class T> __attribute__ ((target("default"))) void operator+=(std::vector<T>& v1, std::vector<T>& v2){ v1.data()[0:v1.size()] += v2.data()[0:v2.size()]; }Let me know if you still have issues.
Thanks,
Shenghong
1)Thank you very much. I have no further problems related to this, for now anyway.
2) Who's hair-brained idea was it to require the template go before the attribute?! It makes far more sense the other way around! Bah...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Patrick,
Regarding your #2 concern, this is not decided by us, we follow the 'standard' of GCC. Different people may like different style, there is no reason why it dost not accept attribute to put before template, this is totally a design of syntax...:)
See my testing below:
// Build with: gcc temp.cpp // works (the way I like) template <class T> __attribute__((noinline)) void foo1(T arg); // works (same with above) template <class T> __attribute__((noinline)) void foo2(T arg); // works (I do not use like this usually, but it works in fact) template <class T> void __attribute__((noinline)) foo3(T arg); // works (the way I also like) template <class T> void foo4(T arg) __attribute__((noinline)); // fail, not accepted // temp.cpp:23:1: error: expected unqualified-id before 'template' __attribute__((noinline)) template <class T> void foo5(T arg); int main(int argc, char** argv) { return 0; }
Thanks,
Shenghong

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page