How extract element from VectorType in LLVM? - llvm

I am trying to compare two VectorType objects in LLVM and since VectorType does not have == operator I am trying to extract elements from my vector and compare them individually. I am working with FixedVectorType.
This is what I am trying to do.
if (VT->getElementType() == other.VT->getElementType() && VT->getNumElements() == other.VT->getNumElements()) {
for (unsigned i = 0; i < VT->getNumElements(); i++) {
//extract elements and compare them
}
return true;
}
I know that I need to use an instance of ExtractElementInst class to extract element. I am not able to find any example of how to actually do that.

Related

How to reorder vector elements in C++?

I have a vector of objects whose elements I want to access in a sequence other than originally stored. My initial thought was to create an array of pointers, one for each array object, and move the pointer values to the desired order (so the underlying array doesn't need to change).
The vector iterator seems similar to an array of pointers, but I couldn't determine if they can be repointed.
Is there a customary way to do this?
ETA:
#doug's comment below sent my mind down another path and I think I was overcomplicating the task. Each object in the array has an attribute that determines the order I want to consume another attribute. Based on doug's suggestion, I could traverse the array and write out two new arrays (one for each attribute) and do a vector of pairs sort. Consistent with #Ted Lyngmo's thought, maybe I could traverse the array and write out a single new array of structures comprised of the two attributes and then do a std::sort.
ETA 2:
In case it matters, the vector of objects is generated by an external library and the attributes are only exposed through method calls.
Despite my poorly composed question, the responses helped me arrive at a solution. As an FYI, here it is:
#include <algorithm>
using namespace std;
//structure to hold select data from array provided by external library
struct outdata
{
string Sort; //data to be sorted
double SortInfo1; //sort criteria1
double SortInfo2; //sort criteria2
} od;
//function used to sort by criteria1 and then by criteria2
bool CompareFunc(const outdata& a, const outdata& b)
{
if (a.SortInfo1 < b.SortInfo1) return true;
if (b.SortInfo1 < a.SortInfo1) return false;
// a=b for SortInfo1, go to SortInfo2
if (a.SortInfo2 < b.SortInfo2) return true;
if (b.SortInfo2 < a.SortInfo2) return false;
return false;
}
int main()
{
vector<obj> source (getarray()); //array provided by external library
vector<outdata> outarray; //array to hold data extracted from source
//traverse source array and load select data to outarray
for (vector<obj>::iterator it = source.begin(); it != source.end(); ++it)
{
od.Sort = it->getSort();
od.SortInfo1 = it->getSortInfo1();
od.SortInfo2 = it->getSortInfo2();
outarray.push_back(od);
}
sort(outarray.begin(), outarray.end(), CompareFunc); //sort outarray
//view results
for (vector<outdata>::iterator it = outarray.begin(); it != outarray.end(); ++it)
{
printf("%s\n", it->Sort.c_str());
}
}

fast way to compare two vector containing strings

I have a vector of strings I that pass to my function and I need to compare it with some pre-defined values. What is the fastest way to do this?
The following code snippet shows what I need to do (This is how I am doing it, but what is the fastest way of doing this):
bool compare(vector<string> input1,vector<string> input2)
{
if(input1.size() != input2.size()
{
return false;
}
for(int i=0;i<input1.siz();i++)
{
if(input1[i] != input2[i])
{
return false;
}
}
return true;
}
int compare(vector<string> inputData)
{
if (compare(inputData,{"Apple","Orange","three"}))
{
return 129;
}
if (compare(inputData,{"A","B","CCC"}))
{
return 189;
}
if (compare(inputData,{"s","O","quick"}))
{
return 126;
}
if (compare(inputData,{"Apple","O123","three","four","five","six"}))
{
return 876;
}
if (compare(inputData,{"Apple","iuyt","asde","qwe","asdr"}))
{
return 234;
}
return 0;
}
Edit1
Can I compare two vector like this:
if(inputData=={"Apple","Orange","three"})
{
return 129;
}
You are asking what is the fastest way to do this, and you are indicating that you are comparing against a set of fixed and known strings. I would argue that you would probably have to implement it as a kind of state machine. Not that this is very beautiful...
if (inputData.size() != 3) return 0;
if (inputData[0].size() == 0) return 0;
const char inputData_0_0 = inputData[0][0];
if (inputData_0_0 == 'A') {
// possibly "Apple" or "A"
...
} else if (inputData_0_0 == 's') {
// possibly "s"
...
} else {
return 0;
}
The weakness of your approach is its linearity. You want a binary search for teh speedz.
By utilising the sortedness of a map, the binaryness of finding in one, and the fact that equivalence between vectors is already defined for you (no need for that first compare function!), you can do this quite easily:
std::map<std::vector<std::string>, int> lookup{
{{"Apple","Orange","three"}, 129},
{{"A","B","CCC"}, 189},
// ...
};
int compare(const std::vector<std::string>& inputData)
{
auto it = lookup.find(inputData);
if (it != lookup.end())
return it->second;
else
return 0;
}
Note also the reference passing for extra teh speedz.
(I haven't tested this for exact syntax-correctness, but you get the idea.)
However! As always, we need to be context-aware in our designs. This sort of approach is more useful at larger scale. At the moment you only have a few options, so the addition of some dynamic allocation and sorting and all that jazz may actually slow things down. Ultimately, you will want to take my solution, and your solution, and measure the results for typical inputs and whatnot.
Once you've done that, if you still need more speed for some reason, consider looking at ways to reduce the dynamic allocations inherent in both the vectors and the strings themselves.
To answer your follow-up question: almost; you do need to specify the type:
// new code is here
// ||||||||||||||||||||||||
if (inputData == std::vector<std::string>{"Apple","Orange","three"})
{
return 129;
}
As explored above, though, let std::map::find do this for you instead. It's better at it.
One key to efficiency is eliminating needless allocation.
Thus, it becomes:
bool compare(
std::vector<std::string> const& a,
std::initializer_list<const char*> b
) noexcept {
return std::equal(begin(a), end(a), begin(b), end(b));
}
Alternatively, make them static const, and accept the slight overhead.
As an aside, using C++17 std::string_view (look at boost), C++20 std::span (look for the Guideline support library (GSL)) also allows a nicer alternative:
bool compare(std::span<std::string> a, std::span<std::string_view> b) noexcept {
return a == b;
}
The other is minimizing the number of comparisons. You can either use hashing, binary search, or manual ordering of comparisons.
Unfortunately, transparent comparators are a C++14 thing, so you cannot use std::map.
If you want a fast way to do it where the vectors to compare to are not known in advance, but are reused so can have a little initial run-time overhead, you can build a tree structure similar to the compile time version Dirk Herrmann has. This will run in O(n) by just iterating over the input and following a tree.
In the simplest case, you might build a tree for each letter/element. A partial implementation could be:
typedef std::vector<std::string> Vector;
typedef Vector::const_iterator Iterator;
typedef std::string::const_iterator StrIterator;
struct Node
{
std::unique_ptr<Node> children[256];
std::unique_ptr<Node> new_str_child;
int result;
bool is_result;
};
Node root;
int compare(Iterator vec_it, Iterator vec_end, StrIterator str_it, StrIterator str_end, const Node *node);
int compare(const Vector &input)
{
return compare(input.begin(), input.end(), input.front().begin(), input.front().end(), &root);
}
int compare(Iterator vec_it, Iterator vec_end, StrIterator str_it, StrIterator str_end, const Node *node)
{
if (str_it != str_end)
{
// Check next character
auto next_child = node->children[(unsigned char)*str_it].get();
if (next_child)
return compare(vec_it, vec_end, str_it + 1, str_end, next_child);
else return -1; // No string matched
}
// At end of input string
++vec_it;
if (vec_it != vec_end)
{
auto next_child = node->new_str_child.get();
if (next_child)
return compare(vec_it, vec_end, vec_it->begin(), vec_it->end(), next_child);
else return -1; // Have another string, but not in tree
}
// At end of input vector
if (node->is_result)
return node->result; // Got a match
else return -1; // Run out of input, but all possible matches were longer
}
Which can also be done without recursion. For use cases like yours you will find most nodes only have a single success value, so you can collapse those into prefix substrings, to use the OP example:
"A"
|-"pple" - new vector - "O" - "range" - new vector - "three" - ret 129
| |- "i" - "uyt" - new vector - "asde" ... - ret 234
| |- "0" - "123" - new vector - "three" ... - ret 876
|- new vector "B" - new vector - "CCC" - ret 189
"s" - new vector "O" - new vector "quick" - ret 126
you could make use of std::equal function like below :
bool compare(vector<string> input1,vector<string> input2)
{
if(input1.size() != input2.size()
{
return false;
}
return std::equal(input1.begin(), input2.end(), input2.begin())
}
Can I compare two vector like this
The answer is No, you need compare a vector with another vector, like this:
vector<string>data = {"ab", "cd", "ef"};
if(data == vector<string>{"ab", "cd", "efg"})
cout << "Equal" << endl;
else
cout << "Not Equal" << endl;
What is the fastest way to do this?
I'm not an expert of asymptotic analysis but:
Using the relational operator equality (==) you have a shortcut to compare two vectors, first validating the size and, second, each element on them. This way provide a linear execution (T(n), where n is the size of vector) which compare each item of the vector, but each string must be compared and, generally, it is another linear comparison (T(m), where m is the size of the string).
Suppose that each string has de same size (m) and you have a vector of size n, each comparison could have a behavior of T(nm).
So:
if you want a shortcut to compare two vector you can use the
relational operator equality.
If you want an program which perform a fast comparison you should look for some algorithm for compare strings.

performing vector intersection in C++

I have a vector of vector of unsigned. I need to find the intersection of all these vector of unsigned's for doing so I wrote the following code:
int func()
{
vector<vector<unsigned> > t;
vector<unsigned> intersectedValues;
bool firstIntersection=true;
for(int i=0;i<(t).size();i++)
{
if(firstIntersection)
{
intersectedValues=t[0];
firstIntersection=false;
}else{
vector<unsigned> tempIntersectedSubjects;
set_intersection(t[i].begin(),
t[i].end(), intersectedValues.begin(),
intersectedValues.end(),
std::inserter(tempIntersectedSubjects, tempIntersectedSubjects.begin()));
intersectedValues=tempIntersectedSubjects;
}
if(intersectedValues.size()==0)
break;
}
}
Each individual vector has 9000 elements and there are many such vectors in "t". When I profiled my code I found that set_intersection takes the maximum amount of time and hence makes the code slow when there are many invocations of func(). Can someone please suggest as to how can I make the code more efficient.
I am using: gcc (GCC) 4.8.2 20140120 (Red Hat 4.8.2-15)
EDIT: Individual vectors in vector "t" are sorted.
I don't have a framework to profile the operations but I'd certainly change the code to reuse the readily allocated vector. In addition, I'd hoist the initial intersection out of the loop. Also, std::back_inserter() should make sure that elements are added in the correct location rather than in the beginning:
int func()
{
vector<vector<unsigned> > t = some_initialization();
if (t.empty()) {
return;
}
vector<unsigned> intersectedValues(t[0]);
vector<unsigned> tempIntersectedSubjects;
for (std::vector<std::vector<unsigned>>::size_type i(1u);
i < t.size() && !intersectedValues.empty(); ++i) {
std::set_intersection(t[i].begin(), t[i].end(),
intersectedValues.begin(), intersectedValues.end(),
std::back_inserter(tempIntersectedSubjects);
std::swap(intersectedValues, tempIntersectedSubjects);
tempIntersectedSubjects.clear();
}
}
I think this code has a fair chance to be faster. It may also be reasonable to intersect the sets different: instead of keeping one set and intersecting with that you could create a new intersection for pairs of adjacent sets and then intersect the first sets with their respect adjacent ones:
std::vector<std::vector<unsigned>> intersections(
std::vector<std::vector<unsigned>> const& t) {
std::vector<std::vector<unsigned>> r;
std::vector<std::vector<unsignned>>::size_type i(0);
for (; i + 1 < t.size(); i += 2) {
r.push_back(intersect(t[i], t[i + 1]));
}
if (i < t.size()) {
r.push_back(t[i]);
}
return r;
}
std::vector<unsigned> func(std::vector<std::vector<unsigned>> const& t) {
if (t.empty()) { /* deal with t being empty... */ }
std::vector<std::vector<unsigned>> r(intersections(t))
return r.size() == 1? r[0]: func(r);
}
Of course, you wouldn't really implement it like this: you'd use Stepanov's binary counter to keep the intermediate sets. This approach assumes that the result is most likely non-empty. If the expectation is that the result will be empty that may not be an improvement.
I can't test this but maybe something like this would be faster?
int func()
{
vector<vector<unsigned> > t;
vector<unsigned> intersectedValues;
// remove if() branching from loop
if(t.empty())
return -1;
intersectedValues = t[0];
// now start from 1
for(size_t i = 1; i < t.size(); ++i)
{
vector<unsigned> tempIntersectedSubjects;
tempIntersectedSubjects.reserve(intersectedValues.size()); // pre-allocate
// insert at end() not begin()
set_intersection(t[i].begin(),
t[i].end(), intersectedValues.begin(),
intersectedValues.end(),
std::inserter(tempIntersectedSubjects, tempIntersectedSubjects.end()));
// as these are not used again you can move them rather than copy
intersectedValues = std::move(tempIntersectedSubjects);
if(intersectedValues.empty())
break;
}
return 0;
}
Another possibility:
Thinking about it using swap() could optimize the exchange of data and remove the need to re-allocate. Also then the temp constructor can be moved out of the loop.
int func()
{
vector<vector<unsigned> > t;
vector<unsigned> intersectedValues;
// remove if() branching from loop
if(t.empty())
return -1;
intersectedValues = t[0];
// no need to construct this every loop
vector<unsigned> tempIntersectedSubjects;
// now start from 1
for(size_t i = 1; i < t.size(); ++i)
{
// should already be the correct size from previous loop
// but just in case this should be cheep
// (profile removing this line)
tempIntersectedSubjects.reserve(intersectedValues.size());
// insert at end() not begin()
set_intersection(t[i].begin(),
t[i].end(), intersectedValues.begin(),
intersectedValues.end(),
std::inserter(tempIntersectedSubjects, tempIntersectedSubjects.end()));
// swap should leave tempIntersectedSubjects preallocated to the
// correct size
intersectedValues.swap(tempIntersectedSubjects);
tempIntersectedSubjects.clear(); // will not deallocate
if(intersectedValues.empty())
break;
}
return 0;
}
You can make std::set_intersection as well as a bunch of other standard library algorithms run in parallel by defining _GLIBCXX_PARALLEL during compilation. That probably has the best work-gain ratio. For documentation see this.
Obligatory pitfall warning:
Note that the _GLIBCXX_PARALLEL define may change the sizes and behavior of standard class templates such as std::search, and therefore one can only link code compiled with parallel mode and code compiled without parallel mode if no instantiation of a container is passed between the two translation units. Parallel mode functionality has distinct linkage, and cannot be confused with normal mode symbols.
from here.
Another simple, though probably insignificantly small, optimization would be reserving enough space before filling your vectors.
Also, try to find out whether inserting the values at the back instead of the front and then reversing the vector helps. (Although I even think that your code is wrong right now and your intersectedValues is sorted the wrong way. If I'm not mistaken, you should use std::back_inserter instead of std::inserter(...,begin) and then not reverse.) While shifting stuff through memory is pretty fast, not shifting should be even faster.
To copy elements from vectors from vector for loop with emplace_back() may save your time. And no need of a flag if you change the iterator index of for loop. So for loop can be optimized, and condition check can be removed for each iteration.
void func()
{
vector<vector<unsigned > > t;
vector<unsigned int > intersectedValues;
for(unsigned int i=1;i<(t).size();i++)
{
intersectedValues=t[0];
vector<unsigned > tempIntersectedSubjects;
set_intersection(t[i].begin(),
t[i].end(), intersectedValues.begin(),
intersectedValues.end(),
std::back_inserter(tempIntersectedSubjects);
for(auto &ele: tempIntersectedSubjects)
intersectedValues.emplace_back(ele);
if( intersectedValues.empty())
break;
}
}
set::set_intersection can be rather slow for large vectors. It's possible use create a similar function that uses lower_bound. Something like this:
template<typename Iterator1, typename Iterator2, typename Function>
void lower_bound_intersection(Iterator1 begin_1, Iterator1 end_1, Iterator2 begin_2, Iterator2 end_2, Function func)
{
for (; begin_1 != end_1 && begin_2 != end_2;)
{
if (*begin_1 < *begin_2)
{
begin_1 = begin_1.lower_bound(*begin_2);
//++begin_1;
}
else if (*begin_2 < *begin_1)
{
begin_2 = begin_2.lower_bound(*begin_1);
//++begin_2;
}
else // equivalent
{
func(*begin_1);
++begin_1;
++begin_2;
}
}
}

Finding position of the element in array

How can I find position of the element inside an array? I have following piece of code where I need to test if the element is at some position, however it is not working as expected. I need your help about it.
string knockemdead[4], bashemup[4], street[4], newyork[9999];
string car;
if (knockemdead[i] == car)
{
if (knockemdead[i].find(1)){ // tried knockemdead[i] = knockemdead[1] and knockemdead[i].at(1) but all it did was nothing
fare = 10;
}
else if (knockemdead[i].find(2))
{
fare = 15;
}
else if (knockemdead[i].at(3) || knockemdead[i].at(4))
{
fare = 25;
}
if cont is some form of container of T, and obj is an object of T,
and T implements ==, then:
auto iter = find( begin(cont), end(cont), obj );
will return either an iterator to the object (or something that compares equal to it),
or end() if no such object exists in the container.
if the container is random-access (vector,array etc), then:
auto idx = iter - begin(cont);
will return the index of the found object
find is declared in <algorithm>, and namespace std is assumed to be accessible
A different solution would be to do it 'manually'
int idx;
for(idx=0; idx<SZ; ++idx)
if( cont[idx] == obj ) break;
you need to put the size of the container in SZ prior.
idx will have the value SZ if no object was found, or the index if it was
You can make a method that finds the position.
Example
int findElementPositionInArray(TYPE[] array , TYPE elementValue){
for(int i=0 ; i<array.length ; i++){
if(array[i]==elementValue){
return i;
}
//let's also treat the case in which the element is not found in the array
//this way we can test the output (we know that if this method returns -1
//the element is not in the array
return -1;
}
}
So just replace TYPE with your desired type (String for your case as I can see) and call this method .
For more complex data types (example your own class that might contain multiple primitive typess) be sure to properly override the "==" operator.
Might contain errors , I don't have an IDE to test this right now.Hope it helps

Printing the First Array in a Deque of Structs

I have a Deque that contains this kind of stucts.
struct New_Array {
array<array<int,4>,4> mytable;
int h;
};
In this stuct 2 different arrays may have same value of h.
deque<New_Array> Mydeque;
I also know how many different h are in the deque(the value of steps). And how many stucts are in the deque(Mydeque.size()).
I need to print one array for each h. Starting from h=0 till h=steps (steps is a known int value). Each array that is going to be printed must be the closer to the end of the deque.
I tried something like this:
void foo(deque<New_Array> Mydeque, int steps)
for(int i=0; i<steps; i++)
{
deque<New_Array>::iterator it;
it = find(Mydeque.begin(),Mydeque.end(),i);
PrintBoard(*it); // This if a function where you enter the New_Array struct
// and it prints the array
}
}
The above gives me : error C2679: binary '==' : no operator found which takes a right-hand operand of type 'const bool' (or there is no acceptable conversion)
Or something like this:
void foo(deque<New_Array> Mydeque, int steps)
for(int i=0; i<steps; i++)
{
deque<New_Array>::iterator it;
for(unsigned int j=0;j<Mydeque.size();j++)
{
it = find_if(Mydeque.begin(),Mydeque.end(),Mydeque[j].h==i);
PrintBoard(*it);
break;
}
}
The above gives me: error C2064: term does not evaluate to a function taking 1 arguments
EDIT: The deque is not sorted. For each h an array should be printed. This array should be the one that is at this moment closer to the end of the deque.
Remember the last value and skip:
assert(!Mydeque.empty());
int old_h = Mydeque[0].h + 1; // make sure it's different!
for (std::size_t i = 0, end != Mydeque.size(); i != end; ++i)
{
if (Mydeque[i].h == old_h) continue;
print(Mydeque[i]);
old_h = Mydeque[i].h;
}
Firstly, note that you declare your std::array on the stack, so the storage will also be on the stack. This means that iterating over the structure involves loading a (4*4+1)*int for each comparison. If this is performance-sensitive, I would suggest using std::vector since the load will be only of the outer vector pointer and the h when only comparing h.
struct New_Array {
vector<vector<int,4>,4> mytable;
int h;
};
Secondly, if you need to access these tables through their h values, or access all the tables with a given h at once, make it easier for everyone and store them as vectors in a map, or a sorted vector of vectors:
std::map<int,std::vector<New_Array> > rolodex;
rolodex[someNewArray.h].push_back(someNewArray);
If you construct this in-order, then the first item in each vector will be the one to print:
for(auto it : rolodex) {
vector<New_Array> tablesForThisH = it->second;
if(tablesForThisH.begin() != tablesForThisH.end())
PrintBoard(it->second[0]);
}
Since std:map stores (and iterates) its keys in ascending (I think) order, this will run over the different h values in ascending order. Again it will only need to load the stack-stored struct, which is just the h int and the vector header (probably 12 bytes, as mentioned in this question).
Forgive me if the code is wrong, my stl is a little rusty.
Loop through the deque, and insert all elements into a map, using h as the key. Since your set of h values seems to be sequential, you can use a vector instead, but testing whether an element has already been found will be more difficult.
The solution is :
void Find_Solution_Path(deque<New_Array> Mydeque, int steps)
{
for(int i=0; i<steps+1; i++)
{
for(int j=Mydeque.size()-1;j>-1;j--)
{
if (Mydeque[j].h==i)
{
PrintBoard(Mydeque[j]);
cout<<endl;
break;
}
}
}
}