samedi 30 septembre 2023

Makin an array of objects without knowing how many objects are going to be there (c++)

This is something that can be done easily with vectors/linked lists but I'm limited to the use of only dynamic arrays... I'm supposed to create a playlist program which stores different playlists and each playlist can have as many songs as user adds to it. How do I solve this problem without putting a max-cap on the number of songs that can be stored in a playlist?

What I've currently thought so far is making 2 classes, "songs" and "playlist", And include a dynamic array of "songs" class inside the playlist class....

class Playlist{
Songs* song = new Songs[10];
};

This will not work for me as it still puts a cap of 10 songs in the playlist...

edit: you can see the given problem here

using std::forward on the same argument in a loop

I know there are cases where using std::forward on the same argument in a loop is wrong because it may cause moving from a moved object like so:

template <typename T>
auto applyTenTimes(T&& arg, auto&& f){
    for(int i = 0; i < 10; ++i)
        f(std::forward<T>(arg);

    return arg; 
}

But what about the case where the forwarded object gets assigned again, like in this example:

template <typename T>
auto applyTenTimes(T&& arg, auto&& f){
    for(int i = 0; i < 10; ++i)
        arg = f(std::forward<T>(arg);

    return arg; 
}

Would this be valid? If yes, then why? Is it basically never creating a new object (when called with an rvalue) and just moving the arg into the function f and then gets moved back again into arg by RVO?

I tried looking at different stack overflow questions but none seemed to have what I was looking for!

vendredi 29 septembre 2023

Having problem with this C code while running?

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void 
f1(void) {
char *src = "f1";
char *dst;
assert(dst != NULL);
strcpy(dst, src);
printf("%s\n", dst);
free(dst);

}

void 
f2(void) {
char *src = "f2";
char *dst = malloc(strlen(src));
assert(dst != NULL);
strcpy(dst, src);
printf("%s\n", dst);
free(dst); 

}

void 
f3(void) {
char *src = "f3";
char *dst = malloc(strlen(src) + 1);
assert(dst != NULL);
printf("%s\n", dst);
free(dst);

}

void 
f4(void) {
char *src = "f4";
char *dst = malloc(strlen(src) + 1);
assert(dst != NULL);
strcpy(dst, src);
printf("%s\n", dst);

}

void 
f5(void) {
char *src = "f5";
char *dst = malloc(strlen(src) + 1);
assert(dst != NULL);
strcpy(dst, src);
free(dst);
printf("%s\n", dst);

}

static void 
myprintf(char *string) {
printf("%s\n", string);
free(string);

}

void 
f6(void) {
char *src = "f6";
char *dst = malloc(strlen(src) + 1);
assert(dst != NULL);
strcpy(dst, src);
myprintf(dst);
free(dst);

}

void 
f7(void) {
char *src = "f7";
char *dst = malloc(strlen(src) + 1);
assert(dst != NULL);
strcpy(dst, src);
printf("%s\n", dst);
free(src);
free(dst);

}

void 
f8(void) {
char *src = "f8";
char *dst = malloc(strlen(src) + 1);
strcpy(dst, src);
printf("%s\n", dst);
free(dst);

}

int 
main(void) {
f1();
f2();
f3();
f4();
f5();
f6();
f7();
f8();

return 0;
}
While the code can compile, each function contains a common memory mistake that results in             either a run-time error or  undefined behaviour .

main.cpp: In function ‘void f1()’: main.cpp:14:17: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings] 14 | char src = "f1"; | ^~~~ main.cpp: In function ‘void f2()’: main.cpp:26:17: warning: ISO C++ forbids converting a string constant to ‘char’ [-Wwrite-strings] 26 | char src = "f2"; | ^~~~ main.cpp:27:23: error: invalid conversion from ‘void’ to ‘char*’ [-fpermissive] 27 | char dst = malloc(strlen(src) + 1); // Allocate enough memory for src and null terminator | ~~~~~~^~~~~~~~~~~~~~~~~ | | | void main.cpp: In function ‘void f3()’: main.cpp:38:17: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings] 38 | char src = "f3"; | ^~~~ main.cpp:39:23: error: invalid conversion from ‘void’ to ‘char*’ [-fpermissive] 39 | char dst = malloc(strlen(src) + 1); // Allocate memory for dst | ~~~~~~^~~~~~~~~~~~~~~~~ | | | void main.cpp: In function ‘void f4()’: main.cpp:49:17: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings] 49 | char src = "f4"; | ^~~~ main.cpp:50:23: error: invalid conversion from ‘void’ to ‘char*’ [-fpermissive] 50 | char dst = malloc(strlen(src) + 1); // Allocate memory for dst | ~~~~~~^~~~~~~~~~~~~~~~~ | | | void main.cpp: In function ‘void f5()’: main.cpp:61:17: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings] 61 | char src = "f5"; | ^~~~ main.cpp:62:23: error: invalid conversion from ‘void’ to ‘char*’ [-fpermissive] 62 | char dst = malloc(strlen(src) + 1); // Allocate memory for dst | ~~~~~~^~~~~~~~~~~~~~~~~ | | | void main.cpp: In function ‘void f6()’: main.cpp:78:17: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings] 78 | char src = "f6"; | ^~~~ main.cpp:79:23: error: invalid conversion from ‘void’ to ‘char*’ [-fpermissive] 79 | char dst = malloc(strlen(src) + 1); // Allocate memory for dst | ~~~~~~^~~~~~~~~~~~~~~~~ | | | void main.cpp: In function ‘void f7()’: main.cpp:90:17: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings] 90 | char src = "f7"; | ^~~~ main.cpp:91:23: error: invalid conversion from ‘void’ to ‘char*’ [-fpermissive] 91 | char dst = malloc(strlen(src) + 1); // Allocate memory for dst | ~~~~~~^~~~~~~~~~~~~~~~~ | | | void main.cpp: In function ‘void f8()’: main.cpp:102:17: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings] 102 | char src = "f8"; | ^~~~ main.cpp:103:23: error: invalid conversion from ‘void’ to ‘char*’ [-fpermissive] 103 | char dst = malloc(strlen(src) + 1); // Allocate memory for dst | ~~~~~~^~~~~~~~~~~~~~~~~ | | | void

jeudi 28 septembre 2023

Boost Spiri Qi recursive expression parser

    struct NestedStr;

    typedef boost::variant<std::string, boost::recursive_wrapper< NestedStr>> expression;

    struct NestedStr
    {
        vector<expression> children;  // variant instantiated here...

        NestedStr(const vector<expression> & child) : children(child)        
        {
        }

        NestedStr()
        {
        }
    };

    template <typename Iterator>
        struct TimingGrammar : qi::grammar<Iterator, SDFDelayInfo(), ascii::space_type>
    {
        TimingGrammar() : TimingGrammar::base_type(start)
        {

            str_rule            %= +(qi::char_ - (qi::lit('(') | qi::lit(')')));
            brace_rule          %= '(' >> str_rule >> brace_rule >> ')'; 

            start   %= '(' >> qi::lit("TIMING") >> brace_rule ')';
        }

        qi::rule<Iterator, string(), ascii::space_type> str_rule;
        qi::rule<Iterator, NestedStr(), ascii::space_type> start;


    };

I am parsing this nested expression and want to parse till the closing bracket.

(TIMING (RECOVERY (COND(COND(COND(COND))))) (WIDTH (COND AB == 1'b1 (pos CK)) (0.040::0.040)) )

But facing long compiler error.

And second question is there any way whenever "(TIMING" is encountered, omit everything in between the closing bracket of "(TIMING" and move the string iterator after the closing bracket.

mercredi 27 septembre 2023

Function noseen in C++ ,How to find solutions?

`

Please, if someone knows the solution to this problem and the steps to resolve it, I would be very grateful.I am thankful in advance.

`#include <iostream>     /* Begin
using namespace std;     /*Second line of code

void std::basic_string<>::_Rep::_M_clone(allocator *param_1,uint param_2)     /*this is a prob

{ 
  _M_clone(param_1,param_2); /* Solutions,or not.
  return;
}   `     /*End

DirectX issue about new GPU

causes an issue and it affects the other texture because of the code culprit with the new GPU settings i am currently using DirectX 9

BOOL C2DRender::RenderTextureALPHA(CPoint pt, CTexture* pTexture, CTexture* pTextureBG, FLOAT fRadian, FLOAT fScaleX, FLOAT fScaleY, DWORD dwBlendFactorAlhpa)
{
    if (!pTexture || !pTextureBG)
        return FALSE;

    m_pd3dDevice->SetRenderTarget(0, m_pBackBuffer);
    pt += m_ptOrigin;
    CPoint ptCenter = pTexture->m_ptCenter;
    ptCenter.x = (LONG)(ptCenter.x * fScaleX);
    ptCenter.y = (LONG)(ptCenter.y * fScaleY);
    pt -= ptCenter;

    FLOAT _left = (FLOAT)(pt.x);
    FLOAT _top = (FLOAT)(pt.y);
    FLOAT _right = pt.x + (fScaleX * pTexture->m_size.cx);
    FLOAT _bottom = pt.y + (fScaleY * pTexture->m_size.cy);

    FLOAT cx = _left + ((_right - _left) / 2);
    FLOAT cy = _top + ((_bottom - _top) / 2);

    _left -= cx;
    _right -= cx;
    _top -= cy;
    _bottom -= cy;

    D3DXVECTOR2 v1, v2, v3, v4;
    D3DXMATRIX  mRot;

    v1.x = _left;   v1.y = _top;
    v2.x = _right;  v2.y = _top;
    v3.x = _left;   v3.y = _bottom;
    v4.x = _right;  v4.y = _bottom;

    D3DXMatrixRotationZ(&mRot, fRadian);
    D3DXVec2TransformCoord(&v1, &v1, &mRot);
    D3DXVec2TransformCoord(&v2, &v2, &mRot);
    D3DXVec2TransformCoord(&v3, &v3, &mRot);
    D3DXVec2TransformCoord(&v4, &v4, &mRot);

    TEXTUREVERTEX vertex[4];
    TEXTUREVERTEX* pVertices = vertex;

    SetTextureVertex(pVertices, cx + v1.x, cy + v1.y, pTexture->m_fuLT, pTexture->m_fvLT);
    pVertices++;
    SetTextureVertex(pVertices, cx + v2.x, cy + v2.y, pTexture->m_fuRT, pTexture->m_fvRT);
    pVertices++;
    SetTextureVertex(pVertices, cx + v3.x, cy + v3.y, pTexture->m_fuLB, pTexture->m_fvLB);
    pVertices++;
    SetTextureVertex(pVertices, cx + v4.x, cy + v4.y, pTexture->m_fuRB, pTexture->m_fvRB);
    pVertices++;

    m_pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, 1);
    m_pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, 1);
    m_pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
    m_pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);

    m_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
    m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
    m_pd3dDevice->SetRenderState(D3DRS_TEXTUREFACTOR, D3DCOLOR_ARGB(dwBlendFactorAlhpa, 0, 0, 0));

    if (dwBlendFactorAlhpa >= 200)
    {
        m_pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
        m_pd3dDevice->SetRenderState(D3DRS_ALPHAREF, (DWORD)70);
        m_pd3dDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER);
        m_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR);
    }
    else
    {
        m_pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
    }

    m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
    m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
    m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
    m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
    m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TFACTOR);
    
    m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
    m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
    m_pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
    m_pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
    m_pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
    m_pd3dDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU);

    m_pd3dDevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE);
    m_pd3dDevice->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE);

    m_pd3dDevice->SetVertexShader(0);

    m_pd3dDevice->SetTexture(1, pTexture->m_pTexture);
    m_pd3dDevice->SetTexture(0, pTextureBG->m_pTexture);
    m_pd3dDevice->SetTexture(2, 0);

    m_pd3dDevice->SetFVF(D3DFVF_TEXTUREVERTEX);
    m_pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, vertex, sizeof(TEXTUREVERTEX));
    m_pd3dDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1);

    m_pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
    m_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
    m_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
    m_pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);

    m_pd3dDevice->SetSamplerState(0, D3DSAMP_SRGBTEXTURE, 0);
    m_pd3dDevice->SetSamplerState(1, D3DSAMP_SRGBTEXTURE, 0);

    m_pd3dDevice->SetTexture(0, 0);
    m_pd3dDevice->SetTexture(1, 0);
    m_pd3dDevice->SetTexture(2, 0);

    return TRUE;
};

in latest GPU setting i am having an issue in this portion will let my texture missing

    m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
    m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
    m_pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
    m_pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
    m_pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
    m_pd3dDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU);

while if i disable the optimization it goes back to normal what do you think the possible solution in this code

invalid controlling predicate (openMP)

i am currently using openMP to parallelize my program but i get stuck at this line :

#pragma omp parallel for schedule(dynamic)
for (long int i = 2; (i * i) <= high; i++) {
    if (ck[i] == true) {
        for (long int j = i * i; j <= sqrt(high); j = j + i) {
            ck[j] = false;
        }
    }
}

the compiler gives "invalid controlling predicate" error..do you know the workaround to make this work?

mardi 26 septembre 2023

Leetcode 11: Why is my answer so slow compared to this one?

Here is the Question Link. Both my solution and the quickest solution are based on the same algorithm.

Here is my solution, moderate, but no mistakes:

class Solution {
public:
  int maxArea(const std::vector<int> &height) {
    uint32_t cur_v = 0;
    uint32_t tmp;

    std::remove_reference_t<decltype(height)>::const_iterator
        iter1 = height.begin(),
        iter2 = height.begin() + height.size() - 1;
    while (iter1 < iter2) {
      tmp = std::distance(iter1, iter2) * std::min(*iter1, *iter2);
      cur_v = tmp > cur_v ? tmp : cur_v;    // update the greatest storage 
      *iter1 > *iter2 ? --iter2 : ++iter1;  // move the smaller pointer
    }

    return cur_v;
  }
};

Here's the quickest solution:

int init = [] {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    ofstream out("user.out");
    for (string s; getline(cin, s); out << '\n') {
        int n = count(s.begin(), s.end(), ',') + 1;
        int ans = 0, l = 0, r = n - 1, i = 0, j = s.length() - 1, x, y;
        bool read_l = true, read_r = true;
        while (l < r) {
            if (read_l) {
                read_l = false;
                ++i;
                // translate char into decimal number
                x = s[i++] & 15;
                while ((s[i] & 15) < 10) x = x * 10 + (s[i++] & 15);
            }
            if (read_r) {
                read_r = false;
                for (j -= 2; (s[j] & 15) < 10; --j);
                int k = j + 1;
                y = s[k++] & 15;
                while ((s[k] & 15) < 10) y = y * 10 + (s[k++] & 15);
            }
            ans = max(ans, min(x, y) * (r - l));
            if (x < y) ++l, read_l = true;
            else --r, read_r = true;
        }
        out << ans;
    }
    out.flush();
    exit(0);
    return 0;
}();

class Solution {
public:
    int maxArea(vector<int>) { return 0; }
};

My understanding of this solution is:

  1. This solution utilized LeetCode's adjudication mechanism, which uses an output file to check if the user's solution is correct
  2. It uses ASCII and bit operation to accelerate the operating rate and comparing rate.

I mean, these tricks are interesting, but I don't understand how it can be that quick. My solution takes about 100 ms and 57.9 MB while it takes 12 ms and 7.9 MB, it is unacceptable.

What's worse, my solution is also slower 32 ms than the "Beginner Friendly" solution which provided above while takes the same memory.

undefined reference linker error with class and main [duplicate]

I have a class and a main file as shown below:

CLinkedList.cpp

#include "CLinkedList.h"


template<typename T>
bool CLinkedList<T>::empty() const {
    return cursor == nullptr;
}
template<typename T>
const T& CLinkedList<T>::front() const {
    return cursor->next->elem;
}
template<typename T>
const T& CLinkedList<T>::back() const {
    return cursor->elem;
}
template<typename T>
void CLinkedList<T>::advance() {
    cursor = cursor->next;
}
template<typename T>
void CLinkedList<T>::add(const T &e) {
    Node<T>* u  = new Node<T>;
    u-> elem = e;
    if(empty()){
        u->next = u;
        cursor = u;
    } else {
        u->next = cursor->next;
        cursor->next = u;
    }
}
template<typename T>
void CLinkedList<T>::remove() {
    Node<T>* temp = cursor->next;
    if(temp == cursor){
        cursor = nullptr;
    }else{
        cursor->next = temp->next;
    }
    delete temp;
}
template<typename T>
CLinkedList<T>::~CLinkedList(){
    while(!empty()){
        remove();
    }
}

main.cpp

#include "CLinkedList.h"
#include <iostream>
using namespace std;
int main(){
    CLinkedList<string> playList;
    playList.add("Stayin Alive");
    cout << playList.front()<<endl;
}

I defined constructor at the class declaration and I got following when I typed

gcc CLinkedList.cpp main.cpp -o out
/usr/bin/ld: module.o: warning: relocation against `_ZSt4cout' in read-only section `.text'
/usr/bin/ld: module.o: in function `main':
testCLinkedList.cpp:(.text+0x30): undefined reference to `std::allocator<char>::allocator()'
/usr/bin/ld: testCLinkedList.cpp:(.text+0x5d): undefined reference to `CLinkedList<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::add(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
/usr/bin/ld: testCLinkedList.cpp:(.text+0x69): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()'
/usr/bin/ld: testCLinkedList.cpp:(.text+0x75): undefined reference to `std::allocator<char>::~allocator()'
/usr/bin/ld: testCLinkedList.cpp:(.text+0x81): undefined reference to `CLinkedList<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::front() const'
/usr/bin/ld: testCLinkedList.cpp:(.text+0x8b): undefined reference to `std::cout'
/usr/bin/ld: testCLinkedList.cpp:(.text+0x93): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <char, std::char_traits<char>, std::allocator<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
/usr/bin/ld: testCLinkedList.cpp:(.text+0x9a): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)'
/usr/bin/ld: testCLinkedList.cpp:(.text+0xa5): undefined reference to `std::ostream::operator<<(std::ostream& (*)(std::ostream&))'
/usr/bin/ld: testCLinkedList.cpp:(.text+0xb1): undefined reference to `CLinkedList<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::~CLinkedList()'
/usr/bin/ld: testCLinkedList.cpp:(.text+0xda): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()'
/usr/bin/ld: testCLinkedList.cpp:(.text+0xef): undefined reference to `std::allocator<char>::~allocator()'
/usr/bin/ld: testCLinkedList.cpp:(.text+0x104): undefined reference to `CLinkedList<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::~CLinkedList()'
/usr/bin/ld: module.o: in function `__static_initialization_and_destruction_0(int, int)':
testCLinkedList.cpp:(.text+0x14a): undefined reference to `std::ios_base::Init::Init()'
/usr/bin/ld: testCLinkedList.cpp:(.text+0x165): undefined reference to `std::ios_base::Init::~Init()'
/usr/bin/ld: module.o: in function `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Alloc_hider::~_Alloc_hider()':
testCLinkedList.cpp:(.text._ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_Alloc_hiderD2Ev[_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_Alloc_hiderD5Ev]+0x18): undefined reference to `std::allocator<char>::~allocator()'
/usr/bin/ld: module.o: in function `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<std::allocator<char> >(char const*, std::allocator<char> const&)':
testCLinkedList.cpp:(.text._ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2IS3_EEPKcRKS3_[_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC5IS3_EEPKcRKS3_]+0x25): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_local_data()'
/usr/bin/ld: testCLinkedList.cpp:(.text._ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2IS3_EEPKcRKS3_[_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC5IS3_EEPKcRKS3_]+0x3a): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Alloc_hider::_Alloc_hider(char*, std::allocator<char> const&)'
/usr/bin/ld: testCLinkedList.cpp:(.text._ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2IS3_EEPKcRKS3_[_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC5IS3_EEPKcRKS3_]+0x50): undefined reference to `std::__throw_logic_error(char const*)'
/usr/bin/ld: module.o: in function `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*>(char const*, char const*, std::forward_iterator_tag)::_Guard::~_Guard()':
testCLinkedList.cpp:(.text._ZZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tagEN6_GuardD2Ev[_ZZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tagEN6_GuardD5Ev]+0x27): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_dispose()'
/usr/bin/ld: module.o: in function `void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*>(char const*, char const*, std::forward_iterator_tag)':
testCLinkedList.cpp:(.text._ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag[_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag]+0x5c): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_create(unsigned long&, unsigned long)'
/usr/bin/ld: testCLinkedList.cpp:(.text._ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag[_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag]+0x6e): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_data(char*)'
/usr/bin/ld: testCLinkedList.cpp:(.text._ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag[_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag]+0x81): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_capacity(unsigned long)'
/usr/bin/ld: testCLinkedList.cpp:(.text._ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag[_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag]+0x97): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_local_data()'
/usr/bin/ld: testCLinkedList.cpp:(.text._ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag[_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag]+0xb7): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_data() const'
/usr/bin/ld: testCLinkedList.cpp:(.text._ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag[_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag]+0xcd): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_S_copy_chars(char*, char const*, char const*)'
/usr/bin/ld: testCLinkedList.cpp:(.text._ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag[_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag]+0xe8): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_set_length(unsigned long)'
/usr/bin/ld: module.o:(.data.rel.local.DW.ref.__gxx_personality_v0[DW.ref.__gxx_personality_v0]+0x0): undefined reference to `__gxx_personality_v0'
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE
collect2: error: ld returned 1 exit status

How can I solve that problem ?

How does resizing unordered_set impact performance?

As far as I'm aware, resizing an array (like push_back on a vector that requires resizing the array) is O(n) complexity. If this is the case, does this hold for insert in unordered_set? Does resizing the internal array make insert O(n)? Does resizing previous to inserting the elements decrease this time complexity because none of the data has to be copied? Finally, I believe that resizing does not require a rehash. Is this correct? If so, how?

Specialize C++11 template based on type traits while allowing fallback for other types

I am currently working on serializing several data structures to JSON.

The existing data structures already provide a text-based output format that I want to use as the default when the functions that convert a specific type to JSON not yet exists.

I currently have the fallback and several specific specializations done. As the JSON-library I use is already able to consume primintives like int, float etc. without any extra work, I want these types have their own (common) specialized template function.

My current main problem is that I'm not able to get to_json(1) to call the function for fundamentals/primitives, but if I specify the type manually (to_json<int>) the correct function is called. Is there any way to fix this? What type does the compiler deduce in the first line?

I am limited to C++11.

The following summarizes my basic setup


#include <iostream>
#include <type_traits>

// Should rely on fallback
struct S {
};

// Has specialization
struct R {
};


// Fallback. Should catch everything not caught by the specializations
template <typename T>
void to_json(const T& x);


// Specialization for R
template<>
void to_json(const R& x)
{
    std::cout << "For R\n";
}

// Does not work
// Specialization for all fundamentals (e.g. int)
template<typename T>
void to_json(const typename std::enable_if<std::is_fundamental<T>::value, T>::type& x)
{
    std::cout << "For fundamentals\n";
}

template <typename T>
void to_json(const T& x)
{
    std::cout << "General\n";
}

int main()
{
    to_json(1);      // General. (WRONG, expected fundamentals)
    to_json<int>(1); // fundamentals (CORRECT)
    to_json(R{});    // R (CORRECT)
    to_json(S{});    // General (CORRECT)

    return 0;
}

Output:

General
For fundamentals
For R
General

Eliminating use of binary_function and result_type

I am trying to update an abandoned open source library to C++11 and 17. It uses binary_function and its result_type in a way I am not sure how to remove. These features were deprecated in C++11 and removed in 17.

First, I've simply removed binary_function (and urnary_function) from this file https://github.com/ramcdona/Pinocchio/blob/master/Pinocchio/mathutils.h#L44

Next, I'm unsure how to eliminate the use of result_type in places like this. https://github.com/ramcdona/Pinocchio/blob/master/Pinocchio/vector.h#L247

  template<class R, int D, class F>
    static Vector<typename F::result_type, D> apply(const F &func, const VRD &v)
    {
        Vector<typename F::result_type, D> out;
        _apply(func, v, out);
        return out;
    }

I tried replacing Vector<typename F::result_type, D> with 'auto', but my compiler (currently set to C++11) complained that auto for return types is introduced in C++14.

F is a generic functor. How can I re-write the above code when I don't know what result_type is?

lundi 25 septembre 2023

I need to translate this C++ code to MIPS Assembly (make it work on QtSpim)

This code is in C++11, and I need to translate it to MIPS Assembly so that it can run in QtSpim as a .s file:

#include <iostream>
using namespace std;

int main()
{
    int n;
    int c = 0;
    int i = 0;
    float d = 0;
    int even [10];
    float sum = 0;
    cout<<"Enter the number of values: ";
    cin>>n;
    if (n < 1 || n > 10)
    {
        goto err;
    }
    cout<<"Enter "<<n<<" integer values, one per line.\n";
    input:
    {
        cin>>even[i];
        i++;
    }
    if (i < n)
    {
        goto input;
    }
    cout<<"The even numbers are: ";
    show:
    {
        if (even[c]%2!=0)
        {
            goto ret;
        }
        if (sum == 0)
        {
            goto skip;
        }
        cout<<", ";
        skip:
        cout<<even[c];
        sum += (float)even[c];
        d++;
        ret:
        {
            c++;
            if (c < n)
            {
                goto show;
            }
        }
    }
    cout<<"\nThe average of the even numbers is: "<<(sum/d);
    goto end;
    err:
    {
        cout<<"Error: number of values should be between 1-10";
    }
    end:
    {
        return 0;
    }
}

it should produce an output like this:

Enter the number of values: 4
Enter 4 integer values, one per line.
4
6
10
3
The even numbers are: 4, 6, 10
The average of the even numbers is: 6.66667

it must work in QtSpim with no errors, and it must be a .s file

I tried translating the code and it came out like this:

    .data
prompt: .asciiz "Enter the number of values: "
valuesPrompt: .asciiz "Enter n integer values, one per line:\n"
evenNumbers: .asciiz "\nThe even numbers are:\n"
averagePrompt: .asciiz "\nThe average of the even numbers is:\n"
comma: .asciiz ","
negOne: .word -1
count: .word 0
sum: .word 0

    .globl main
    .text

main:
    # Prompt the user for the number of values
    li $v0, 4
    la $a0, prompt
    syscall

    # Read n from the user
    li $v0, 5
    syscall
    move $t0, $v0

    # Check if n is between 1 and 10
    li $t1, 1
    ble $t0, $t1, invalidInput
    li $t1, 10
    bgt $t0, $t1, invalidInput

    # Prompt the user for n values
    li $v0, 4
    la $a0, valuesPrompt
    syscall

    # Initialize loop counter
    li $t1, 0

readValuesLoop:
    # Read the next value from the user
    li $v0, 5
    syscall
    move $t2, $v0

    # Check if the value is even
    andi $t3, $t2, 1
    beqz $t3, evenNumber

    # Value is odd, continue to next iteration
    j incrementCounter

evenNumber:
    # Print the even number
    li $v0, 1
    move $a0, $t2
    syscall

    # Add the even number to the sum
    addu $t4, $t4, $t2

    # Check if it's the last even number
    li $t5, 1
    sub $t6, $t0, $t1
    beq $t5, $t6, calculateAverage

    # Print a comma separator
    li $v0, 4
    la $a0, comma
    syscall

calculateAverage:
    # Increment the loop counter
    incrementCounter:
    addiu $t1, $t1, 1

    # Check if we have processed all values
    beq $t1, $t0, doneReadingValues

    # Continue reading values
    j readValuesLoop

doneReadingValues:
    # Print even numbers message
    li $v0, 4
    la $a0, evenNumbers
    syscall

    # Print a new line
    li $v0, 4
    la $a0, "\n"
    syscall

    # Calculate average of even numbers
    divu $t4, $t0
    mthi $zero  # Clear upper 32 bits of dividend
    mflo $t4

    # Print the average
    li $v0, 2
    move $a0, $t4
    syscall

    # Print a new line
    li $v0, 4
    la $a0, "\n"
    syscall

    # Exit the program
    li $v0, 10
    syscall

invalidInput:
    # Print error message for invalid input
    li $v0, 4
    la $a0, "Invalid input. Please enter a value between 1 and 10.\n"
    syscall

    # Exit the program
    li $v0, 10
    syscall

It looks good but QtSpim gives me this message and the code does not run:

Instruction references undefined symbol at 0x00400044
  [0x00400044]  0x10200000  beq $1, $0, 0 [invalidInput-0x00400040]

std::find in vector with structures

I have a structure

struct position {
    int x;
    int y;
};

and a vector pos of such structures.

When I try to check whether a certain element is present in this vector, I use

    auto it = std::find(pos.begin(), pos.end(), {x,y});

This, however, only works, when I explicitly pass the constructor to std::find() function, i.e.

    auto it = std::find(pos.begin(), pos.end(), position({x,y}));

Otherwise, I get compiler error

    std::find: no matching overloaded function found

Why is that? Is it because compiler cannot deduce the type of {x,y} in the line above?

dimanche 24 septembre 2023

How to make several levels of nested classes work inside a template class in C++? [closed]

I have to put a nested class inside a template class, then I have to put another nested class inside already nested class, and so on. However, only the very first class is generic. I've tried to do this in several ways, and yet, that has resulted in errors. So, what's the right way to make those classes work correctly?

template <typename T>
class Outer {
    class Middle;
    Middle* _pMiddle;
};

template <typename T>
class Outer<T>::Middle {
    class Inner;
    Inner* _pInner;
};

template <typename T>
class Outer<T>::Middle::Inner {
    void DoStuff();
};

template <typename T>
void Outer<T>::Middle::Inner::DoStuff() {
}

I've read this and this questions, they haven't given me a straightforward solution that I need. Sadly, I'm not good in C++, and I have no time and real goal to learn it, I just have to make that relation of three (or even more) classes work to implement the real stuff I'm interested in here.

PS I'm using C++11.

vendredi 22 septembre 2023

How to copy one boost graph into another ( Deep Copy ) with all custom properties?

I have a boost graph with custom properties. I want to make a copy of it. I tried it by following way but got many compilation error.

Here is what I did :

using BGType = boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS,
                                     // Vertex Properties...
                                     vertexProps,
                                     // Edge Propereties...
                                     edgeProps,
                                     // Graph Properties
                                     graphProps>;

vertexProps.h

class vertexProps {
   public:
    explicit vertexProps(const std::string *moduleName = nullptr, const std::string *name = nullptr,
                            long refPtr = 0 )
     : _refPtr(refPtr),
    {
        _moduleName = moduleName ? *moduleName : "";
        _name = name ? *name : "";
    };


struct CustomVertexCopy {
    void operator()(const vertexProps& source_vertex, vertexProps& target_vertex) const {
        target_vertex._refPtr = source_vertex._refPtr;
        target_vertex._moduleName = source_vertex._moduleName;
        target_vertex._name = source_vertex._name;
}

edgeProps.h

class edgeProps {
   public:
    explicit edgeProps(std::string name = "")
        : _name(name){};
    std::string _name;
};

struct CustomEdgeCopy {
    void operator()(const edgeProps& source_edge, edgeProps& target_edge) const {
        target_edge._name = source_edge._name;
    }
};

someFunction.cpp

OnClick(BGType* bGraph)
{
   // some code
  BGType* oldBg = new BGType;
  boost::copy_graph(bGraph, oldBg, boost::vertex_copy(CustomVertexCopy()));
  boost::copy_graph(bGraph, oldBg, boost::edge_copy(CustomEdgeCopy()));
  // some code
}

Where am I wrong ?

I have a one more doubt.
Will such deep copying impact on performance if grpah is big ? If yes, is there any way to avoid it ?

delete constructor in C++: private/protected/public?

what is the best practice to delete constructor in C++: put it in private/protected/public ?:

approach 1:

class Foo{
public:
Foo() = delete;
}

approach 2:

class Foo{
protected:
Foo() = delete;
}

approach 3:

class Foo{
private:
Foo() = delete;
}

jeudi 21 septembre 2023

Any ideas for improvements to this source code?

This program compiles and works fine, I'm new to C++ programming and am looking for constructive criticism.

#include <iostream>
#include <cmath>
using namespace std;

int main()
{
    const double PI = 3.14159;
    double diameter, radius, circumference, area;

    cout << "Please enter the diameter of your circle: ";
    cin >> diameter;
    radius = diameter / 2;
    circumference = (PI * 2) * radius;
    area = PI * pow(radius, 2.0);
    cout << "The area of your circle is: ";
    cout << area << endl;
    cout << "The circumference of your circle is: ";
    cout << circumference << endl;
    return 0;
}

I input 10 as a sample diameter and it returns the expected values.

mercredi 20 septembre 2023

Why is compiler mis-stating namespace?

Doing some C++ development after a good four years in Python, it appears I'm a little rusty.

I have three files in my very cut-down example (the actual code is much larger but this example still exhibits the problem). They are the code for the main file, and the code and header for a separate component that it will use:

// xx.cpp:
#include "xx_store.h"
int main() {
    auto store = XX::XXStore();
    return 0;
}
// xx_store.cpp:
#include "xx_store.h"
namespace XX {
    XXStore::XXStore() : m_map(XXEntries()) { }
    XXStore::~XXStore() { }
}
// xx_store.h:
#include <map>
#include <string>
namespace XX {
    using XXEntry = struct {
        std::string m_value;
        bool m_found;
        uint32_t m_age_ms;
    };
    using XXEntries = std::map<std::string, XXEntry>;

    class XXStore {               // WHERE THE ERROR IS REPORTED.
    public:
        XXStore();
        ~XXStore();
    private:
        XXEntries m_map;          // THE APPARENT CAUSE.
    };
}

Now, when I compile that with g++ --std=c++11 -o xx xx.cpp xx_store.cpp, I get two warnings, one for each of the code files, but both referring to the same place in the header file:

xx_store.h:12:11: warning:
    ‘XX::XXStore’ has a field ‘XX::XXStore::m_map’ whose type uses
        the anonymous namespace [-Wsubobject-linkage]
        12 |     class XXStore {
           |           ^~~~~~~

Now I know from past experience that anonymous namespaces are per translation unit so it's unwise to do that in a header file that may be included by multiple code files.

But I can't see how the type of the m_map variable (which is XXEntries) is actually in the anonymous namespace. It's clearly inside the namespace XX { ... } area in the header file, as is the XXEntry type it depends upon. In fact, the warning even states that it's within the XX:: part of the namespace.

Can anyone suggest why this warning may be happening? I know I can disable the warning but I'd rather not go down that path until I'm sure it's a false positive.

The environment is Ubuntu 20.04 running g++ 9.4.0.

How can I systematically work out compiler errors?

I am trying to learn C++ more in depth, and so I've been toying around with various aspects of the language to help solidify my understanding of what is valid syntax and what isn't. Because the code I'm using to learn more about these specific concepts in the language is small and specifically tailored to test out one or two things of interest, I'm typically able to work out compiler errors. And yet, sometimes, even when I know the exact concept at hand that is causing the compiler error, I know that I would never be able to figure it out on my own if the same error came up in a large project.

Here's a good example:

const std::unordered_map<std::string,int> mymap = { {"hello", 1} };

int main()
{
    int num = mymap["hello"];  // error
}

const-unordered-map.cpp:10:28: error: passing ‘const std::unordered_mapstd::__cxx11::basic_string<char, int>’ as ‘this’ argument discards qualifiers [-fpermissive]
10 | int num = mymap["hello"];

aka: Passing a const unordered_map as 'this' argument discards qualifiers

I understand the bracket operator is not valid for a const map, and that a qualifier refers to a cv-qualifier ('const' in this case) and despite that, I still don't really understand how I could systematically approach an error like this one and find a resolution (other than googling)

I want to learn how to get good at working these issues out for myself though. I've searched online for tips in this regard. Typically answers suggest:

  1. Knowing how the build process actually works will help - I am already currently working on this and I think I have a decent overall understanding. Perhaps my inability to understand this error is just indicative of my having a further way to go in this regard
  2. Simply learning over time by being diligent - I intend to do this, I will begin keeping notes on interesting compiler errors and how to understand them

So I'd like to know how you'd go about resolving this error, and if you have any further suggestions for learning the structure/style/jargon of compiler errors in general.

Part 2 of this question is: are some types of errors standardized in any way? I'd imagine that a parser in any C++ compiler would trigger the same compiler errors, but how similar can I expect them to be?

FAISS CGO throwing "Undefined symbols for architecture arm64" when using libfaiss_c.a

Go version

$ go version
go version go1.20 darwin/arm64

Operating system and Processor architecture?


$ go env GO111MODULE="on" GOARCH="arm64" GOBIN="" GOEXE="" GOEXPERIMENT="" GOFLAGS="" GOHOSTARCH="arm64" GOHOSTOS="darwin" GOINSECURE="" GONOPROXY="" GONOSUMDB="" GOOS="darwin" GOPRIVATE="" GOPROXY="https://proxy.golang.org,direct" GOROOT="/usr/local/go" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/usr/local/go/pkg/tool/darwin_arm64" GOVCS="" GOVERSION="go1.20" GCCGO="gccgo" AR="ar" CC="clang" CXX="clang++" CGO_ENABLED="1" GOMOD="/Users/me/GolandProjects/0learning/faiss-cgo-kmeans/go.mod" GOWORK="" CGO_CFLAGS="-O2 -g" CGO_CPPFLAGS="" CGO_CXXFLAGS="-O2 -g" CGO_FFLAGS="-O2 -g" CGO_LDFLAGS="-O2 -g" PKG_CONFIG="pkg-config"

Summary

I am trying to write a self-dependent go-faiss wrapper for invoking the KMEANS function of FAISS. Repo: https://github.com/arjunsk/faiss-cgo-kmeans

This approach is inspired from https://github.com/andyalm/faissmask/tree/master/FaissMask/runtimes

The FAISS static library libfaiss_c.a is built using -DBUILD_SHARED_LIBS=OFF

When I link that library with CGO, I am getting

Error Log
# faiss-go/pkg/ivf.test
/usr/local/go/pkg/tool/darwin_arm64/link: running clang failed: exit status 1
Undefined symbols for architecture arm64:
  "faiss::Clustering::Clustering(int, int)", referenced from:
      _faiss_Clustering_new in libfaiss_c.a(Clustering_c.cpp.o)
  "faiss::Clustering::Clustering(int, int, faiss::ClusteringParameters const&)", referenced from:
      _faiss_Clustering_new_with_params in libfaiss_c.a(Clustering_c.cpp.o)
  "faiss::kmeans_clustering(unsigned long, unsigned long, unsigned long, float const*, float*)", referenced from:
      _faiss_kmeans_clustering in libfaiss_c.a(Clustering_c.cpp.o)
  "faiss::ClusteringParameters::ClusteringParameters()", referenced from:
      _faiss_ClusteringParameters_init in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_Clustering_new_with_params in libfaiss_c.a(Clustering_c.cpp.o)
  "std::exception_ptr::exception_ptr(std::exception_ptr const&)", referenced from:
      _faiss_get_last_error in libfaiss_c.a(error_impl.cpp.o)
  "std::exception_ptr::~exception_ptr()", referenced from:
      _faiss_get_last_error in libfaiss_c.a(error_impl.cpp.o)
      thread-local wrapper routine for faiss_last_exception in libfaiss_c.a(error_impl.cpp.o)
      _faiss_Clustering_new in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_Clustering_new_with_params in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_Clustering_train in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_kmeans_clustering in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_kmeans_clustering.cold.1 in libfaiss_c.a(Clustering_c.cpp.o)
      ...
  "std::exception_ptr::operator=(std::exception_ptr const&)", referenced from:
      _faiss_Clustering_new in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_Clustering_new_with_params in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_Clustering_train in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_kmeans_clustering in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_kmeans_clustering.cold.1 in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_kmeans_clustering.cold.2 in libfaiss_c.a(Clustering_c.cpp.o)
  "std::runtime_error::runtime_error(char const*)", referenced from:
      _faiss_Clustering_new in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_Clustering_new_with_params in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_Clustering_train in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_kmeans_clustering in libfaiss_c.a(Clustering_c.cpp.o)
  "std::runtime_error::runtime_error(std::runtime_error const&)", referenced from:
      std::exception_ptr std::make_exception_ptr[abi:v15006]<std::runtime_error>(std::runtime_error) in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_Clustering_train in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_kmeans_clustering in libfaiss_c.a(Clustering_c.cpp.o)
  "std::runtime_error::~runtime_error()", referenced from:
      _faiss_Clustering_new in libfaiss_c.a(Clustering_c.cpp.o)
      std::exception_ptr std::make_exception_ptr[abi:v15006]<std::runtime_error>(std::runtime_error) in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_Clustering_new_with_params in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_Clustering_train in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_kmeans_clustering in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_kmeans_clustering.cold.2 in libfaiss_c.a(Clustering_c.cpp.o)
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>::basic_string(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const&)", referenced from:
      std::exception_ptr std::make_exception_ptr[abi:v15006]<faiss::FaissException>(faiss::FaissException) in libfaiss_c.a(Clustering_c.cpp.o)
      faiss::FaissException::FaissException(faiss::FaissException const&) in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_Clustering_train in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_kmeans_clustering in libfaiss_c.a(Clustering_c.cpp.o)
  "std::exception::~exception()", referenced from:
      _faiss_Clustering_new in libfaiss_c.a(Clustering_c.cpp.o)
      std::exception_ptr std::make_exception_ptr[abi:v15006]<std::exception>(std::exception) in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_Clustering_new_with_params in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_Clustering_train in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_kmeans_clustering in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_kmeans_clustering.cold.1 in libfaiss_c.a(Clustering_c.cpp.o)
  "std::exception::~exception()", referenced from:
      std::exception_ptr std::make_exception_ptr[abi:v15006]<faiss::FaissException>(faiss::FaissException) in libfaiss_c.a(Clustering_c.cpp.o)
      faiss::FaissException::FaissException(faiss::FaissException const&) in libfaiss_c.a(Clustering_c.cpp.o)
      faiss::FaissException::~FaissException() in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_Clustering_train in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_kmeans_clustering in libfaiss_c.a(Clustering_c.cpp.o)
  "std::current_exception()", referenced from:
      std::exception_ptr std::make_exception_ptr[abi:v15006]<std::runtime_error>(std::runtime_error) in libfaiss_c.a(Clustering_c.cpp.o)
      std::exception_ptr std::make_exception_ptr[abi:v15006]<std::exception>(std::exception) in libfaiss_c.a(Clustering_c.cpp.o)
      std::exception_ptr std::make_exception_ptr[abi:v15006]<faiss::FaissException>(faiss::FaissException) in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_Clustering_train in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_kmeans_clustering in libfaiss_c.a(Clustering_c.cpp.o)
  "std::rethrow_exception(std::exception_ptr)", referenced from:
      _faiss_get_last_error in libfaiss_c.a(error_impl.cpp.o)
  "std::terminate()", referenced from:
      ___clang_call_terminate in libfaiss_c.a(Clustering_c.cpp.o)
  "typeinfo for faiss::FaissException", referenced from:
      std::exception_ptr std::make_exception_ptr[abi:v15006]<faiss::FaissException>(faiss::FaissException) in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_Clustering_train in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_kmeans_clustering in libfaiss_c.a(Clustering_c.cpp.o)
      GCC_except_table21 in libfaiss_c.a(Clustering_c.cpp.o)
      GCC_except_table28 in libfaiss_c.a(Clustering_c.cpp.o)
      GCC_except_table29 in libfaiss_c.a(Clustering_c.cpp.o)
      GCC_except_table31 in libfaiss_c.a(Clustering_c.cpp.o)
      ...
  "typeinfo for std::runtime_error", referenced from:
      std::exception_ptr std::make_exception_ptr[abi:v15006]<std::runtime_error>(std::runtime_error) in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_Clustering_train in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_kmeans_clustering in libfaiss_c.a(Clustering_c.cpp.o)
  "typeinfo for std::exception", referenced from:
      GCC_except_table0 in libfaiss_c.a(error_impl.cpp.o)
      std::exception_ptr std::make_exception_ptr[abi:v15006]<std::exception>(std::exception) in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_Clustering_train in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_kmeans_clustering in libfaiss_c.a(Clustering_c.cpp.o)
      GCC_except_table21 in libfaiss_c.a(Clustering_c.cpp.o)
      GCC_except_table28 in libfaiss_c.a(Clustering_c.cpp.o)
      GCC_except_table29 in libfaiss_c.a(Clustering_c.cpp.o)
      ...
  "vtable for faiss::FaissException", referenced from:
      std::exception_ptr std::make_exception_ptr[abi:v15006]<faiss::FaissException>(faiss::FaissException) in libfaiss_c.a(Clustering_c.cpp.o)
      faiss::FaissException::FaissException(faiss::FaissException const&) in libfaiss_c.a(Clustering_c.cpp.o)
      faiss::FaissException::~FaissException() in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_Clustering_train in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_kmeans_clustering in libfaiss_c.a(Clustering_c.cpp.o)
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
  "vtable for std::exception", referenced from:
      _faiss_Clustering_new in libfaiss_c.a(Clustering_c.cpp.o)
      std::exception_ptr std::make_exception_ptr[abi:v15006]<std::exception>(std::exception) in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_Clustering_new_with_params in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_Clustering_train in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_kmeans_clustering in libfaiss_c.a(Clustering_c.cpp.o)
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
  "operator delete(void*)", referenced from:
      _faiss_Clustering_new in libfaiss_c.a(Clustering_c.cpp.o)
      faiss::FaissException::~FaissException() in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_Clustering_new_with_params in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_Clustering_train in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_kmeans_clustering in libfaiss_c.a(Clustering_c.cpp.o)
  "operator new(unsigned long)", referenced from:
      _faiss_Clustering_new in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_Clustering_new_with_params in libfaiss_c.a(Clustering_c.cpp.o)
  "___cxa_allocate_exception", referenced from:
      std::exception_ptr std::make_exception_ptr[abi:v15006]<std::runtime_error>(std::runtime_error) in libfaiss_c.a(Clustering_c.cpp.o)
      std::exception_ptr std::make_exception_ptr[abi:v15006]<std::exception>(std::exception) in libfaiss_c.a(Clustering_c.cpp.o)
      std::exception_ptr std::make_exception_ptr[abi:v15006]<faiss::FaissException>(faiss::FaissException) in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_Clustering_train in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_kmeans_clustering in libfaiss_c.a(Clustering_c.cpp.o)
  "___cxa_begin_catch", referenced from:
      _faiss_get_last_error in libfaiss_c.a(error_impl.cpp.o)
      _faiss_Clustering_new in libfaiss_c.a(Clustering_c.cpp.o)
      std::exception_ptr std::make_exception_ptr[abi:v15006]<std::runtime_error>(std::runtime_error) in libfaiss_c.a(Clustering_c.cpp.o)
      ___clang_call_terminate in libfaiss_c.a(Clustering_c.cpp.o)
      std::exception_ptr std::make_exception_ptr[abi:v15006]<std::exception>(std::exception) in libfaiss_c.a(Clustering_c.cpp.o)
      std::exception_ptr std::make_exception_ptr[abi:v15006]<faiss::FaissException>(faiss::FaissException) in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_Clustering_new_with_params in libfaiss_c.a(Clustering_c.cpp.o)
      ...
  "___cxa_end_catch", referenced from:
      _faiss_get_last_error in libfaiss_c.a(error_impl.cpp.o)
      _faiss_Clustering_new in libfaiss_c.a(Clustering_c.cpp.o)
      std::exception_ptr std::make_exception_ptr[abi:v15006]<std::runtime_error>(std::runtime_error) in libfaiss_c.a(Clustering_c.cpp.o)
      std::exception_ptr std::make_exception_ptr[abi:v15006]<std::exception>(std::exception) in libfaiss_c.a(Clustering_c.cpp.o)
      std::exception_ptr std::make_exception_ptr[abi:v15006]<faiss::FaissException>(faiss::FaissException) in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_Clustering_new_with_params in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_Clustering_train in libfaiss_c.a(Clustering_c.cpp.o)
      ...
  "___cxa_free_exception", referenced from:
      std::exception_ptr std::make_exception_ptr[abi:v15006]<faiss::FaissException>(faiss::FaissException) in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_Clustering_train in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_kmeans_clustering in libfaiss_c.a(Clustering_c.cpp.o)
  "___cxa_throw", referenced from:
      std::exception_ptr std::make_exception_ptr[abi:v15006]<std::runtime_error>(std::runtime_error) in libfaiss_c.a(Clustering_c.cpp.o)
      std::exception_ptr std::make_exception_ptr[abi:v15006]<std::exception>(std::exception) in libfaiss_c.a(Clustering_c.cpp.o)
      std::exception_ptr std::make_exception_ptr[abi:v15006]<faiss::FaissException>(faiss::FaissException) in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_Clustering_train in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_kmeans_clustering in libfaiss_c.a(Clustering_c.cpp.o)
  "___gxx_personality_v0", referenced from:
      _faiss_get_last_error in libfaiss_c.a(error_impl.cpp.o)
      _faiss_Clustering_new in libfaiss_c.a(Clustering_c.cpp.o)
      std::exception_ptr std::make_exception_ptr[abi:v15006]<std::runtime_error>(std::runtime_error) in libfaiss_c.a(Clustering_c.cpp.o)
      std::exception_ptr std::make_exception_ptr[abi:v15006]<std::exception>(std::exception) in libfaiss_c.a(Clustering_c.cpp.o)
      std::exception_ptr std::make_exception_ptr[abi:v15006]<faiss::FaissException>(faiss::FaissException) in libfaiss_c.a(Clustering_c.cpp.o)
      faiss::FaissException::FaissException(faiss::FaissException const&) in libfaiss_c.a(Clustering_c.cpp.o)
      _faiss_Clustering_new_with_params in libfaiss_c.a(Clustering_c.cpp.o)
      ...
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

I am using these CGO headers

/*
#cgo darwin LDFLAGS: -L${SRCDIR}/../../cgo/thirdparty/runtimes/osx-arm64/native -lfaiss_c

#include <stdlib.h>
#include <faiss/c_api/Clustering_c.h>
#include <faiss/c_api/impl/AuxIndexStructures_c.h>
#include <faiss/c_api/index_factory_c.h>
#include <faiss/c_api/error_c.h>
*/

However, this CGO code works when we build libfaiss_c.dylib using -DBUILD_SHARED_LIBS=ON and the libfaiss_c.dylib is added to the /usr/local/lib. The CGO header would now look like the below

/*
#cgo LDFLAGS: -lfaiss_c

#include <stdlib.h>
#include <faiss/c_api/Clustering_c.h>
#include <faiss/c_api/impl/AuxIndexStructures_c.h>
#include <faiss/c_api/index_factory_c.h>
#include <faiss/c_api/error_c.h>
*/

Please help me in linking the *.a file with CGO from a custom path.

Update 1

When I have these files in the /usr/local/lib

The test runs image

These files written in the /usr/local/lib is created using the below make file

GIT_COMMAND ?= git
FAISS_COMMIT ?= d87888b13e7eb339bb9c45825e9d20def6665171

all: faiss

.PHONY: faiss
faiss:
    if [ -e faiss ]; then \
        cd faiss && ${GIT_COMMAND} fetch origin && git reset --hard  $(FAISS_COMMIT); \
    else \
        ${GIT_COMMAND} clone https://github.com/facebookresearch/faiss.git && cd faiss && git reset --hard  $(FAISS_COMMIT); \
    fi
    cd faiss && \
        export CMAKE_PREFIX_PATH=/opt/homebrew/opt/openblas:/opt/homebrew/opt/libomp:/opt/homebrew && \
        cmake -B build -DFAISS_ENABLE_GPU=OFF -DFAISS_ENABLE_C_API=ON -DBUILD_SHARED_LIBS=ON -DFAISS_ENABLE_PYTHON=OFF . && \
        make -C build && \
        sudo make -C build install && \
        sudo cp build/c_api/libfaiss_c.dylib /usr/local/lib/libfaiss_c.dylib

Update 2

For the go-rocks db library, https://github.com/linxGnu/grocksdb#build

they also recommend installing/building the rocksdb library locally and linking that with the cgo interface.

Will this approach of building static library "*.a" independently and shipping it as a self-contained library work?

How do we define static member variables in header only projects? [duplicate]

I am using C++11.

Usually, we define static members as follows:

my_static.hpp:

class MyClass
{
public:
    static double MyStaticVar;
};

my_static.cpp:

double::MyClass MyStaticVar = 100.001;

Say I have a static library where all files are header-only *.hpp files.

Suppose I don't want to use any *.cpp files. I only want to use *.hpp header files.

Then how do you define a static member variable?

mardi 19 septembre 2023

C++ template method specialization by type traits

I'm working in C++11, creating a class template. I wish to optimize certain methods according to the type traits of the template parameter (i.e. float/integer, signed/unsigned etc.). I know this could be achieved by template specialization for each specific combination of traits, but that's too unwieldy.

Instead, I've got something working using the partial template specialization of a dummy struct wrapper (because so far as I'm aware partial specialization only works with structs/classes).

Working example here:

#include<type_traits>
#include<iostream>

template<typename T>
struct A
{
    A( T _x ) : x(_x) {}

    template<typename U, bool foobar = std::is_signed<T>::value>
    struct temp{};

    template<typename U>
    struct temp<U,true>
    {
        static constexpr U diff( A const &left, A const &right ) noexcept
        {
            std::cout << "Signed" << std::endl;
            T d = left.x - right.x;
            return d * d;
        }
    };

    template<typename U>
    struct temp<U,false>
    {
        static constexpr U diff( A const &left, A const &right ) noexcept
        {
            std::cout << "Unsigned" << std::endl;
            T d = left.x < right.x ? right.x - left.x : left.x - right.x;
            return d * d;
        }
    };

    protected:

        T x;
};

int main( int argc, char** argv )
{
    // Unsigned
    A<unsigned int> u1( 10 );
    A<unsigned int> u2( 15 );

    // Method call
    std::cout << A<unsigned int>::temp<unsigned long>::diff( u1, u2 ) << std::endl;

    // Signed
    A<float> f1( -1.23f );
    A<float> f2( 12.3f );

    // Method call
    std::cout << A<float>::temp<double>::diff( f1, f2 ) << std::endl;
}

Having to dereference the dummy struct is cumbersome from the template user's point of view, so I'd particularly like to improve that, if possible.

My knowledge of C++ is far from encyclopedic, so I'm wondering if there are nicer solutions out there. Preferably C++11 compatible, but I'm curious to hear about alternatives in modern C++ too.

Obviously I have googled this, but it took all my search skills to get the above working.

Thanks in advance.

lundi 18 septembre 2023

How can I further optimize this code regarding array operations?

In the following code I am performing XOR operation on two arrays result and DB, result is accessed after an offset called rotate1 in following. As you can see I am already doing AVX2 and loop unrolling and also prefetching. I am wondering if I am missing anything that might be giving slow speed. In following else part of branch is accessed only once each time the function is called. I have noticed 50 percent time is spend on xor, rest 40 percent is spend on data store. Remaining on loads.

void perform_array_xor(uint32_t partindex, uint32_t offset, uint64_t *result, uint32_t EntrySize, uint32_t PartSize)
{
    auto B = 1;

    assert(EntrySize/8==B);

    // Ensure that PartSize is a multiple of 32 for this example
    if (PartSize % 8 != 0)
    {
        // Handle this case
        return;
    }

     __m256i a,b,r;

     unsigned int rotate1_1;
     int k;
    
    for (int i = 0; i < PartSize; i += 8)
    {
        rotate1_1 = (i + offset) & (PartSize - 1);


        _mm_prefetch(result + rotate1_1, _MM_HINT_T2);
        k = 0;
        if(rotate1_1 + 7 < PartSize){
            a = _mm256_loadu_si256((__m256i*)(result + rotate1_1));
            b = _mm256_loadu_si256((__m256i*)(DB + partindex + i));
            r = _mm256_xor_si256(a, b);
            _mm256_storeu_si256((__m256i*)(result + rotate1_1), r);
            //std::memcpy(result + rotate1_1, &r, sizeof(__m256i));
            
            k = 4 ;
            a = _mm256_loadu_si256((__m256i*)(result + rotate1_1 + k));
            b = _mm256_loadu_si256((__m256i*)(DB + partindex + i + k));
            r = _mm256_xor_si256(a, b);
            _mm256_storeu_si256((__m256i*)(result + rotate1_1 + k), r);
            //std::memcpy(result + rotate1_1 + k, &r, sizeof(__m256i));
            
        }
        else{
        result[(rotate1_1 + 0) & (PartSize - 1)] ^= DB[partindex + (i + 0)];
        result[(rotate1_1 + 1) & (PartSize - 1)] ^= DB[partindex + (i + 1)];
        result[(rotate1_1 + 2) & (PartSize - 1)] ^= DB[partindex + (i + 2)];
        result[(rotate1_1 + 3) & (PartSize - 1)] ^= DB[partindex + (i + 3)];
        result[(rotate1_1 + 4) & (PartSize - 1)] ^= DB[partindex + (i + 4)];
        result[(rotate1_1 + 5) & (PartSize - 1)] ^= DB[partindex + (i + 5)];
        result[(rotate1_1 + 6) & (PartSize - 1)] ^= DB[partindex + (i + 6)];
        result[(rotate1_1 + 7) & (PartSize - 1)] ^= DB[partindex + (i + 7)];
        }
        
    }
}

How to iterate through a list of pointers to an object?

I have a typedef statement:

typedef list <Event *> EventList;

which is on its own in my header file (not part of a class).

I have a function nd_to_el(), where I want to iterate through this EventList, which has already been filled with instances of Event.

This is what I tried:

EventList::iterator it;

for (it = this->el.begin(); it != this->el.end(); ++it){
    cout << (*it)->key << endl;
}

(I am also not sure if dereferencing the iterator is correct here or not)

but I get this error:

error: request for member ‘end’ in ‘((CS302_Midi*)this)->CS302_Midi::el’, which is of pointer type ‘EventList*’ {aka ‘std::__cxx11::list<Event*>*’} (maybe you meant to use ‘->’ ?)
for (it = this->el.begin(); it != this->el.end(); ++it)

I don't think using the arrow operator is what I intend here.

Github actions fail for Mac with my Haskell package including C++

I have some Github actions for my library 'numerical-integration'. They all work fine except those on Mac. Among the warnings and error messages for Mac, there are:

  • note: expanded from macro '_LIBCPP_DEPRECATED_CXX03_FUNCTION' attribute((deprecated("Using std::function in C++03 is not supported anymore. Please upgrade to C++11 or later, or use a different type")))

  • warning: 'function<double (double)>' is deprecated: Using std::function in C++03 is not supported anymore. Please upgrade to C++11 or later, or use a different type [-Wdeprecated-declarations] std::function<double(double)> f_ = [&](double x) { return f(x); };

I don't understand since I have in my cabal file:

  extra-libraries:     stdc++
  ghc-options:         -optcxx-std=c++11
  cxx-options:         -fPIC -std=c++11

Some of you recommend me to not use a lambda function in my previous post. But again, I'm not fluent in C/C++ and I do what I can, and I'm happy as long as it works... And the library works very well. But I'm ok for changing something if I understand.

Is there something special to do in the Cabal file for Mac ? I googled "cabal mac c++11" but I found nothing.

Is there any exemplary open sourced project which uses the majority/most of C11 standard's new features?

I am learning on static code analysis, but have been struggling to find such real world projects that would be decent test cases for C11 features. In the meantime, any open sourced projects which heavily used C++11 and later features would be appreciated as well.

I tried searching over GitHub and google search results, and only found mini C compiler projects which only used a few of new C11 traits.

dimanche 17 septembre 2023

OpenMP: Finding the maximum value of array using reduction clause

I have the following function that calculates the maximum value of 2D/3D arrays in a nested for loop. I used reduction clause to gain some additional speedup however I am not getting a good speedup and I am wondering how to fix this?

Example Function

double maxFunc(double arr2D[]){ 

    double max_val = 0.;
    #pragma omp parallel for reduction(max:max_val ) 
    for (int i = 0; i < nx; i++){
        for (int j = 0; j < nyk; j++){
            if (arr2D[j + nyk*i] > maxVal){
                max_val = arr2D[j + nyk*i];
            }
        }
    }   
    return max_val ;
     
}

Main Code:

static const int nx = 1024;
static const int ny = 1024;
static const int nyk = ny/2 + 1;

double *Array;
Array = (double*) fftw_malloc(nx*ny*sizeof(double)); 

    for (int i = 0; i < nx; i++){
        for (int j = 0; j < ny; j++){
          Array[j + ny*i]  = //Initialize array to some values; 
            
        }
    }

//test maxFunc with different number of threads
for (int nThreads =1; nThreads <= 16; nThreads++){
        double start_time, run_time;
        start_time = omp_get_wtime();
       
        omp_set_num_threads(nThreads);
        double max_val= 0.;
        #pragma omp parallel for reduction(max:max_val) 
        for (int i = 0; i < nx; i++){
            for (int j = 0; j < nyk; j++){
                if (Array[j + nyk*i] > max_val){ 

                    max_val= Array[j + nyk*i];
                }
            }
        }   
        run_time = omp_get_wtime() - start_time;
        cout << "Threads: " << nThreads <<  "Parallel Time in s: " <<  run_time << "s\n";
        
    }

The output I get looks like:

Threads: 1Parallel Time in s: 0.0003244s
Threads: 2Parallel Time in s: 0.0003887s
Threads: 3Parallel Time in s: 0.0002579s
Threads: 4Parallel Time in s: 0.0001945s
Threads: 5Parallel Time in s: 0.000179s
Threads: 6Parallel Time in s: 0.0001456s
Threads: 7Parallel Time in s: 0.0002081s
Threads: 8Parallel Time in s: 0.000135s
Threads: 9Parallel Time in s: 0.0001262s
Threads: 10Parallel Time in s: 0.0001161s
Threads: 11Parallel Time in s: 0.0001499s
Threads: 12Parallel Time in s: 0.0002939s
Threads: 13Parallel Time in s: 0.0002982s
Threads: 14Parallel Time in s: 0.0002399s
Threads: 15Parallel Time in s: 0.0002283s
Threads: 16Parallel Time in s: 0.0002268s

My PC has 6 cores with 12 logical processors so I sort of expect 6 times speed in best case scenario. Thanks!

passing multiple arguments to pthread (including vector arguments)

I currently have a problem related with the use of pthread.h (since I am still pretty new at it) so I am really hopeful I could get some help from this forum..let's suppose I want to pass this function to a thread that is created with pthread.h :

    void test (long int begin, long int end, vector<long int> x)
    {
                    /*do something*/
    }

do you know how to include this function into that thread along with all of its arguments? Or am I even able to pass this into pthread??

And am I able to pass multiple functions with multiple parameters at the same time into pthread? any help from you is very appreciated, thx

samedi 16 septembre 2023

A question about the argument types to the comp predicate in std::lower_bound

Reference: std::lower_bound

Excerpt:

comp    -   binary predicate which returns ​true if the first argument is less than (i.e. is ordered before) the second.

The signature of the predicate function should be equivalent to the following:

 bool pred(const Type1 &a, const Type2 &b);

While the signature does not need to have const &, the function must not modify the objects passed to it and must be able to accept all values of type (possibly const) Type1 and Type2 regardless of value category (thus, Type1 & is not allowed, nor is Type1 unless for Type1 a move is equivalent to a copy (since C++11)).

What I would like to clarify in the above excerpt with respect to the type mandate is the following:

nor is Type1 unless for Type1 a move is equivalent to a copy (since C++11)

I presume Type1& is not allowed as that could potentially allow the predicate to modify the objects passed in; but why is Type1 not allowed? Is it only due to optimization, taking cues from the precondition that Type1 is allowed if a move is equivalent to copy? Or is there more to it than that?

TIA

How to enforce the C++ named requirement "Container"

I am trying to make a template container class and I want it to conform to the "Container" named requirement as best I can. I am looking at this cppreference link and at the bottom it says:

Other requirements
C (Container)
    DefaultConstructible
    CopyConstructible
    EqualityComparable
    Swappable
T (Type)
    CopyInsertable
    EqualityComparable
    Destructible

I want to add some static asserts in my code such that I never accidentally regress any functionality, and I am looking into adding it inside the class definition. Here is a minimal representation of my code:

#include <iostream>
#include <type_traits>

template <typename T>
class MyContainer {
    public:
        MyContainer() = default;

        static_assert(std::is_default_constructible<MyContainer>::value, "MyContainer is not default constructible!");
};

int main() {
    // instantiate the object so that static assert may be evaluated
    MyContainer<int> obj1;

    std::cout << "All checks passed." << std::endl;

    return 0;
}

However, when trying to compile this (at the moment using g++ 9.4), the compilation fails on the static assert.

Why is this failing?

Are static asserts even meant to be used this way? For example looking at my c++ standard library implementation of std::vector class, I can clearly see they use some static asserts like this (although not for checking that the "Container" requirements are satisfied) Also, any provided answer must be portable for all major compilers (g++, clang++ and msvc)

Problems with Parallel sieve of Eratosthenes

currently I have a problem related with Parallelization of sieve of Eratosthenes..here is my code :

const long int lastNumber = 1*1000*1000*1000LL;

#include <iostream>
#include <vector>
#include <cmath>
#include <thread>
#include <cassert>
#include <sys/time.h>

using namespace std;

double seconds()
{
  timeval now;
  gettimeofday(&now, NULL);
  return now.tv_sec + now.tv_usec/1000000.0;
}
// simple parallel sieve of Eratosthenes

void multithread_calc(int memorySize_chunk_lb, int lastNumberSqrt_chunk_lb, int lastNumber_chunk_lb,int memorySize_chunk, int lastNumberSqrt_chunk, int lastNumber_chunk, int& found_chunk)
{
    // initialize


    char *isPrime = new char[memorySize_chunk+1];

    for (int i = memorySize_chunk_lb; i <= memorySize_chunk; i++) //0
    {
        isPrime[i] = 1;
    }

    // find all odd non-primes

    for (int i = lastNumberSqrt_chunk_lb; i <= lastNumberSqrt_chunk; i += 2) //3
    {
        if (isPrime[i/2])
        {
          for (int j = i*i; j <= lastNumber_chunk; j += 2*i)
          {
              isPrime[j/2] = 0;
          }
        }
    }

    // sieve is complete, count primes
    found_chunk = lastNumber_chunk >= 2 ? 1 : 0;

    for (int i = lastNumber_chunk_lb; i <= memorySize_chunk; i++) //1
    found_chunk += isPrime[i];
    delete[] isPrime;
}


int eratosthenes(int lastNumber)
{
     int found = 0;
     const int lastNumberSqrt = (int)sqrt((double)lastNumber);
     int memorySize = (lastNumber-1)/2;
     //things that will be divided :
     //int lastNumberSqrt
     //int memorySize
     //int lastNumber
     int chunk_memorySize;
     int chunk_lastNumberSqrt;
     int chunk_lastNumber;
     //set lower bound
     int chunk_memorySize_lb=0;
     int chunk_lastNumberSqrt_lb=3;
     int chunk_lastNumber_lb=1;

     int num_threads = 2;
     int chunk_memorySize_part = memorySize/num_threads;
     int chunk_lastNumberSqrt_part = lastNumberSqrt/num_threads;
     int chunk_lastNumber_part = lastNumber/num_threads;


     vector<thread> threads;
     for(int i = 0; i<num_threads; i++){
       if(i>0)
       {
          chunk_memorySize_lb=i*chunk_memorySize_part;
          chunk_lastNumberSqrt_lb=i*chunk_lastNumberSqrt_part;
          chunk_lastNumber_lb=i*chunk_lastNumber_part;
       }

       chunk_memorySize = (i+1)*chunk_memorySize_part;
       chunk_lastNumberSqrt = (i+1)*chunk_lastNumberSqrt_part;
       chunk_lastNumber = (i+1)*chunk_lastNumber_part;

        auto th = thread(&multithread_calc,chunk_memorySize_lb,chunk_lastNumberSqrt_lb,chunk_lastNumber_lb,chunk_memorySize,chunk_lastNumberSqrt,chunk_lastNumber,ref(found));
        threads.push_back(move(th));
        assert(!th.joinable());
    }
     // Wait for all threads to finish
    for (auto &thread : threads)
    {
        thread.join();
    }

  return found;
}

int main(int argc, char* argv[])
{
  int found = 0;
  printf("Primes between 2 and %d\n\n", lastNumber);
  printf("Simple Sieve\n");
  double startTime = seconds();
  found = eratosthenes(lastNumber);
  double duration  = seconds() - startTime;
  printf("%d primes found in %.3fs\n\n", found, duration);

  system("PAUSE");
  return 0;
}

actually I get correct result when I use num_threads = 1, but the more I increase the thread number, the less prime number I get...in my case, it gets divided results whenever I tried to increase the thread...do you know how to solve this problem?? Any help will be very appreciated, thx.

this is the result when I set num_threads = 1 :

enter image description here

and this is the result when I set num_threads = 2 :

enter image description here

Do you know what's the problem with this program and how to solve this?? Any help will be very appreciated..

Mingw C++ Debugger skips all break points and inputs in vscode

I have an issue with debugging in vscode using mingw, first of all it runs with errors,which shows only in terminal, then doesnt fucntion as a debugger and just skips to the end

here is lauch.json file

{
    "version": "0.2.0",
    "configurations": [


        {
            "name": "(gdb) Launch",
            "type": "cppdbg",
            "request": "launch",
            "program": "${fileDirname}\\${fileBasenameNoExtension}.exe",
            "args": [],
            "stopAtEntry": true,
            "cwd": "${fileDirname}",
            "environment": [],
            "externalConsole": true,
            "MIMode": "gdb",
            "miDebuggerPath": "C:\\msys64\\mingw64\\bin\\gdb.exe",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "C/C++: g++.exe build active file"
        }  
    ]
}

Here is message in terminal:

Starting build... C:/MinGW/bin/g++.exe -fdiagnostics-color=always -g C:\KBTU\ADS23\lab1\test.cpp -o C:\KBTU\ADS23\lab1\test.exe spawn C:\WINDOWS\system32\cmd.exe ENOENTBuild finished with error(s).

  • The terminal process failed to launch (exit code: -1).
  • Terminal will be reused by tasks, press any key to close it.

I tried changing the launch.json file and path, but that didnt work out Uninstalling and changing the version of mingw didnt help as well

vendredi 15 septembre 2023

Memory order around atomic operations

I want to build a good mental image about std::memory_order_seq_cst, std::memory_order_relaxed, memory_order_acq_rel.

Imagine a program as a sequence of bricks. Each brick is an operation on some variable. There are only two atomic variables x and y in the program. Atomic operations on x are colored red. Atomic operations on variable y are colored blue. The rest operations are uncolored --- in gray.

Sequential consistency std::memory_order_seq_cst is defined by the following constraints: (i) any blue or red brick will always stay at its original position, (ii) gray bricks between any two colored bricks might be reshuffled by the compiler within the said colored bricks.

The relaxed memory order std::memory_order_relaxed is almost the opposite of the sequential consistency: (i) the red (blue) bricks could be shifted in any manner as long as the order of the red (blue) sequence does not change.

Things get murkier to me about the acquire-release order std::memory_order_acq_rel. I tend to think they are both relaxations from sequential consistency: any colored brick can be shifted around, but it should never collide with another colored brick. In other words, if the code says atomic operation B happens between A and C, then the compiler should never shuffle the code in a way such that B would be executed before A or after C.

I made the following figures:

enter image description here

Figure 1 shows the order of operations in code. Figure 2 is one possibility under sequential consistency. Figure 3 is one possibility under relaxed memory order.

My questions are:

  1. Did I correctly understand sequential consistency and the relaxed memory order?

  2. Is my visualization accurate? Is there any better visualization?

  3. How to delineate acquire-release order with similar visualization?

I am currently not interested in std::memory_order_consume.

And yes, I have read https://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync. But it's still hard for me to digest quickly. I am wondering if there is an even easier way to load this piece of knowledge in my brain after two years without touching the subject.

Thanks a lot!

calculating sum of trapezoid with thread in c++

I have a problem related with threads when I try to calculate the sum of trapezoid for integration of x^2 using C++. Here is my example code :

#include<iostream>
#include <thread>
#include <vector>
#include <mutex>
using namespace std;

float y(float x)
{

    return (x*x);
}

float result;
// Function to evaluate the value of integral
float trapezoid(float a, float b, int n)
{
    float h = (b-a)/n;
    float s = y(a)+y(b);

    for (int i = 1; i < n; i++)
    {
        s += 2*y(a+i*h);
    }
    result += (h/2)*s;
}

// Driver program to test above function
int main()
{
    const int num_threads = 3;
    const int iteration = 600;

    float lb = 0;
    float hb = 0;
    float task_ = 1/num_threads;
    vector<thread> threads;

    for(hb = 0; hb<1; hb+=task_){

           threads.push_back(thread(&trapezoid,lb,hb,iteration));
           lb=hb;
    }
     // Wait for all threads to finish
    for (auto &thread : threads)
    {
        thread.join();
    }
    cout<<result<<endl;
    return 0;
}

I try to divide the task into several parts and calculate them using C++ STL threads but I only get this : enter image description here

do you know what is wrong with my code? I am still pretty much new on anything related with threads in C++..Any help for this is really appreciated.

why element in std::priority_queue deconstructed so many times?

I am using std::priority_queue to do file sort, which i think heap is the best way to sort the stream data.

here is the code:

#include <bits/stdc++.h>
using namespace std;

struct A { 
  A(int a, size_t b, double c) : a_(a), b_(b), c_(c){}
  ~A() { printf("%d dead\n", a_); }
  int a_; 
  size_t b_; 
  double c_; 
  bool operator <(const A & b) const {
    return a_ > b.a_;
  }
  void show() const {
    printf("%d %zu %lf\n", a_, b_, c_);
  }
};

int main() {
  std::priority_queue<A> q;
  q.push(A(1,2,3));
  q.push(A(3,2,3));
  q.push(A(2,2,3));
  while (!q.empty()) {
    const A & s = q.top();
    s.show();
    q.pop();
  }
}

the sorting process is good, but what made me surprised is the element deconstructed so many times as the output is :

1 dead
1 dead
1 dead
1 dead
3 dead
3 dead
3 dead
1 dead
3 dead
2 dead
2 dead
2 dead
1 2 3.000000
2 dead
2 dead
2 dead
1 dead
2 2 3.000000
3 dead
3 dead
3 dead
2 dead
3 2 3.000000
3 dead

i think every element should deconstruct once, could you explain this?

I think there are only 3 elements constructed, what i expected is only 3 times deconstruct. which i think there is no waste.

jeudi 14 septembre 2023

Using add_rvalue_reference and add_lvalue_reference with template types

My small test program is aimed at testing the use of add_rvalue_reference and add_lvalue_reference for obtaining references of template types.

//test.h

#include<cstddef>
#include <type_traits>

using std::size_t;
using std::add_lvalue_reference;
using std::add_rvalue_reference;

template<class T>
  struct unref {typedef T type;};
template<class T> 
  struct unref<T&>{typedef T type;};
template<class T> 
  struct unref<T&&>{typedef T type;};

template<typename T>
class A{
   public:
   constexpr A(T);
   constexpr ~A();
   private:
   A()=delete; 
   A(const A&)=delete;
   A& operator=(const A&)=delete;
   private:
   T elem;
};

template<typename T, size_t N>
using arrayofAs = A<T>[N];

template<typename T, size_t N>
using lvrefarrayofAs = add_lvalue_reference<arrayofAs<T>>;

template<typename T, size_t N>
using rvrefarrayofAs = add_rvalue_reference<arrayofAs<T>>;

template<typename T> constexpr A<T>::A(T elem):elem(elem){}
template<typename T> constexpr A<T>::~A(){}

//main.cpp

#include "test.h"
#include <iostream>

using std::is_same;
using std::cout;
using std::endl;

int main (){

  cout << is_same<unref<lvrefarrayofAs>, arrayofAs>::value << endl;  
  cout << is_same<unref<rvrefarrayofAs>, arrayofAs>::value << endl;  

  return 0;
}

To begin with, I get the following compilation error in test.h:

In file included from main.cpp:1:
test.h:35:55: error: wrong number of template arguments (1, should be 2)
   35 | using lvrefarrayofAs = add_lvalue_reference<arrayofAs<T>>;
      |                                                       ^
compilation terminated due to -Wfatal-errors.

My understanding is that the template array size is not part of its type (please correct me if I am mistaken on this), so not sure why the compiler insists on specifying the template non-type paramter?

The error disappears after I rewrite the two related using declarations in the original code as shown below:

    template<typename T, size_t N>
    using lvrefarrayofAs = add_lvalue_reference<arrayofAs<T,N>>;
    
    template<typename T, size_t N>
    using rvrefarrayofAs = add_rvalue_reference<arrayofAs<T,N>>;

But now I get the following error in main.c:

main.cpp: In function ‘int main()’:
main.cpp:21:39: error: type/value mismatch at argument 1 in template parameter list 
for ‘template<class T> struct unref’
   21 |   cout << is_same<unref<lvrefarrayofAs>, arrayofAs>::value << endl;
      |                                       ^
compilation terminated due to -Wfatal-errors.

I presume the type of argument 1 passed to is_same<> template is valid, based on the using declarations for both unref<T&>and lvrefarrayofAs in test.h.

So why does the compiler report this error?

TIA

mercredi 13 septembre 2023

C++ variable initializes even though the copy constructor is deleted

The code below works unexpectedly!

class CameraBuffer;
class CameraBufferAccessor{
  friend CameraBuffer;
  private:
    CameraBufferAccessor(const int &data, const int &mutex);
  public:
    CameraBufferAccessor() = default;
    CameraBufferAccessor(const CameraBufferAccessor &) = delete;
    CameraBufferAccessor(CameraBufferAccessor &&) = delete;
    void operator=(const CameraBufferAccessor &other) = delete;
    void operator=(CameraBufferAccessor &&other) = delete;
};
class CameraBuffer {
  public:
    const CameraBufferAccessor getReadAccess() const {
        return {1, 2};
    }
};
int main() {
    auto buffer = CameraBuffer();
    CameraBufferAccessor a = buffer.getReadAccess();
    CameraBufferAccessor b = a;

here CameraBufferAccessor b = a; as expected throws error since copy constructor is explicitly deleted.

but something happens that i donot expect and i have searching for it so far no explaianation. the line CameraBufferAccessor a = buffer.getReadAccess(); just works although it uses a function which has non-reference return, which itself is supposed to make use of Copy Constructor, secondly the returned CameraBufferAccessor should be copied into a initializing a using Copy/Move constructor once again, but it compiles and doesn't throw.

I heard That the compiler for optimization purposes is allowed to bypass copy construction when necessary, if that's the case here, how am I supposed to tell when compiler does that?

I thought that it was due to the curly braces in return statement of getReadAccess which directly initialized the return value, So I tried return CameraBufferAccessor(1, 2); but it still works. maybe compiler optimization?

Function invocation in `std::bind`

TLDR: How is std::bind actually works when calling a member function with an instance of a class or a this pointer of the class?

Notes:

  1. I know what a function adapter is
  2. I know this is implicitly used as the first argument when calling a member function
  3. I know how std::placeholder works
  4. I know how to call a member function in a more ordinary way, like (instance.*ptr)()

Here is the code:

#include <functional>
#include <iostream>

struct Test {
  void test(const std::string &info) { std::cout << info << std::endl; }
};

int main() {
  Test test;

  // call with instance
  std::bind(&Test::test, std::placeholders::_1, "call with instance")(test);
  // call with `this`
  std::bind(&Test::test, std::placeholders::_1,
            "call with `this` pointer")(&test);
}

This code works fine on my platform. So I guess either std::bind have done the job to distinguish an instance and a pointer, or I misunderstood something.

Sincere appreciations for any advice in advance.

Using ShellExecute without UAC prompt in C++ Windows

I have a c++ windows application that has two potential users. Depending on which user is logged in they may or may not have full admin access. We now need to modify a config file dynamically. This file needs admin access to modify. I am using ShellExecute to run a separate process which handles the modification. The issue is the UAC prompt appears and requires user interaction. This is not satisfactory. Is it possible to do this in my application.

int ElevatedExecution(const std::string& program)
{
    int res{};
    SHELLEXECUTEINFO info = {0};
    info.cbSize = sizeof(SHELLEXECUTEINFO);
    info.fMask = SEE_MASK_NOCLOSEPROCESS;
    info.lpVerb = "runas";
    info.lpFile = program.c_str();
    info.lpParameters = NULL;
    info.nShow = SW_SHOWNORMAL;

    if (::ShellExecuteEx(&info) == TRUE)
    {
        ::WaitForSingleObject(info.hProcess, INFINITE);
        DWORD ret_val = 0;
        if (::GetExitCodeProcess(info.hProcess, &ret_val))
        {
            res = static_cast<int>(ret_val);
        }
    }
    return res;
}

Is there anyway to restrict c++ template class parameters within one-to-one relationship?

For example, there is a template class:

template<typename A, typename B>
class Example;

If a pair of (A, B) is specialized, then other types cannot specialized with A. For example, (B, C) is allowed, but (A, C) is not allowed.

Example<int, double> E1, E2, E3;  // OK
Example<int, double> E4;          // OK
Example<int, bool> E5;            // Not Allowed (Because <int, double> already exists)
Example<bool, double> E6;         // OK
Example<double, double> E7;       // OK
Example<double, int> E8;          // Not Allowed (<double, double> already exists)

I try to use a std::map between template parameter A and B during runtime, but if there is a way to do this during compiling? Like SFINAE or other techniques?

mardi 12 septembre 2023

is there an error in “The generation of the implicitly-defined copy constructor is deprecated if T has a user-defined destructor”

I read this sentence in cppreference.It says The generation of the implicitly-defined copy constructor is deprecated if T has a user-defined destructor. Maybe there is an error.

I test in a code:

First I define destructor, copy/move constructor and copy/move assignment operator.

#include <iostream>
struct B {
    B() { std::cout << "B()" << std::endl; }
    ~B() { std::cout << "~B()" << std::endl; }

    B(const B&) { std::cout << "B(const B&)" << std::endl; }
    B& operator=(const B&) { std::cout << "B& operator=(const B&)" << std::endl; return *this; }

    B(B&&) { std::cout << "B(B&&)" << std::endl; }
    B& operator=(B&&) { std::cout << "B& operator=(B&&)" << std::endl; return *this; }
};
int main()
{
    B b1{};
    B b2{b1}; //copy constructor
    return 0;
}

console print :

B()
B(const B&)
~B()
~B()

Second I only define move constructor and move assignment operator. The copy constructor will be implicitly-declared deleted.

#include <iostream>
struct B {
    B() { std::cout << "B()" << std::endl; }
    //~B() { std::cout << "~B()" << std::endl; }

    // B(const B&) { std::cout << "B(const B&)" << std::endl; }
    // B& operator=(const B&) { std::cout << "B& operator=(const B&)" << std::endl; return *this; }

    B(B&&) { std::cout << "B(B&&)" << std::endl; }
    B& operator=(B&&) { std::cout << "B& operator=(B&&)" << std::endl; return *this; }
};
int main()
{
    B b1{};
    B b2{b1}; //compile error
    return 0;
}

The test code will compile error. I think this is the correct, because copy constructor is deleted.

Finally, I only define destructor

#include <iostream>
struct B {
    B() { std::cout << "B()" << std::endl; }
    ~B() { std::cout << "~B()" << std::endl; }

    // B(const B&) { std::cout << "B(const B&)" << std::endl; }
    // B& operator=(const B&) { std::cout << "B& operator=(const B&)" << std::endl; return *this; }

    // B(B&&) { std::cout << "B(B&&)" << std::endl; }
    // B& operator=(B&&) { std::cout << "B& operator=(B&&)" << std::endl; return *this; }
};
int main()
{
    B b1{};
    B b2{b1};
    return 0;
}

The generation of the implicitly-defined copy constructor is deprecated if T has a user-defined destructor. so I think the test code will compile error, but it's correct. WHY???