0

I know openmp now can compile things like #pragma omp parallel for simd, but it can't do it with msvc, so I installed mingw64-8.1.0, and wrote files:

// test.h
#pragma once
void test(float* a, float* b, float* c, long long size);
// test.cpp
#include <iostream>
#include <omp.h>
#include <vector>
#include "test.h"
using namespace std;
void test(float* a, float* b, float* c, long long size) {
#pragma omp parallel for simd
    for (long long i = 0; i < size; ++i) c[i] = a[i] + b[i];
    for (long long i = 0; i < 30; ++i) cout << c[i] << '\t';
    cout << endl;
}

int main() {
    vector<float> a(65536);
    vector<float> b(65536);
    vector<float> c(65536);
    for (size_t i = 0; i < 65536; ++i) b[i] = static_cast<float>(i);
    test(a.data(), b.data(), c.data(), 65536);
    return 0;
}

and compiled by g++ test.cpp -O3 -fopenmp, and everything went well, a.exe worked well. Now I'd like to wrap it to python package by cython, so I wrote:

# test_.pxd
cdef extern from "test.cpp":
    pass
cdef extern from "test.h":
    cdef void test(float*, float*, float*, long long)
# test_.pyx
# distutils: language = c++
from test_ cimport test
import cython

@cython.boundscheck(False)
@cython.wraparound(False)
def pyTest(float[::1] a, float[::1] b, float[::1] c, long long size):
    test(&a[0], &b[0], &c[0], size)
# setup.py
from distutils.core import setup, Extension
from Cython.Build import cythonize

extensions = [
    Extension(
        "Test",
        sources = ["test_.pyx"],
        language = "C++",
        extra_compile_args = ['-fopenmp', '-O3'],
        extra_link_args = []
    )
]

if __name__ == "__main__":
    setup(ext_modules=cythonize(extensions, language_level=3))

I followed this and this, and run python setup.py build_ext --inplace, and raised an error:

C:\Program Files\mingw64\bin\gcc.exe -mdll -O -Wall -DMS_WIN64 -I. -IC:\Users\mon\Anaconda3\include -IC:\Users\mon\Anaconda3\include -c test_.cpp -o build\temp.win-amd64-3.8\Release\test_.o -fopenmp -O3
writing build\temp.win-amd64-3.8\Release\Test.cp38-win_amd64.def
C:\Program Files\mingw64\bin\g++.exe -shared -s build\temp.win-amd64-3.8\Release\test_.o build\temp.win-amd64-3.8\Release\Test.cp38-win_amd64.def -LC:\Users\mon\Anaconda3\libs -LC:\Users\mon\Anaconda3\PCbuild\amd64 -lpython38 -lvcruntime140 -o C:\Project\Polaris_Toolkit\test\Test.cp38-win_amd64.pyd
build\temp.win-amd64-3.8\Release\test_.o:test_.cpp:(.text+0x48c): undefined reference to `omp_get_num_threads'
build\temp.win-amd64-3.8\Release\test_.o:test_.cpp:(.text+0x493): undefined reference to `omp_get_thread_num'
build\temp.win-amd64-3.8\Release\test_.o:test_.cpp:(.text+0x18453): undefined reference to `GOMP_parallel'
collect2.exe: error: ld returned 1 exit status
error: command 'C:\\Program Files\\mingw64\\bin\\g++.exe' failed with exit status 1

seems like some errors with openmp

But when I changed #pragma omp parallel for simd to #pragma omp simd in test.cpp, and again ran python setup.py build_ext --inplace, it was compiled succesfully.

So I wonder, is there any way to use cython to wrap #pragma omp parallel for simd on windows?

I'm using python 3.8.8, cython 0.29.23 installed by anaconda on win10 amd64.

Chuang Men
  • 371
  • 3
  • 10
  • Looks like you only passed `-fopenmp` to the compile command, not linking. – Peter Cordes Nov 19 '21 at 07:18
  • @PeterCordes You're right, thank you! But I wonder why it could work when I use `#pragma omp simd`? – Chuang Men Nov 19 '21 at 07:26
  • SIMD is just using different instructions in the same thread, same as with normal auto-vectorization with `-O3` which includes `-ftree-vectorize`, no helper functions needed and thus no library calls. (Although OpenMP vectorization sometimes makes different choices than normal -O3, and for FP it's like `-fassociative-math` and some (but not all) other fast-math options for that loop.) – Peter Cordes Nov 19 '21 at 07:39
  • (I'm possibly wrong but) MingW hasn't worked for compiling Python modules on Windows since about Python 3.4. You need to use a compiler that matches what Python itself was compiled with (i.e. https://wiki.python.org/moin/WindowsCompilers) – DavidW Nov 19 '21 at 07:55
  • @PeterCordes I got it, thank you! – Chuang Men Nov 19 '21 at 08:00
  • @DavidW You're right, but it worked, maybe not as stable as `msvc` on windows. The problem is I wish to use `#pragma omp parallel for simd`, which can't be compiled by `msvc`. – Chuang Men Nov 19 '21 at 08:02

0 Answers0