Darknet: ☛ 1 crazy trick to get vanilla YOLO working natively on Windows x86_64. Go users hate it.

Created on 21 Apr 2018  Â·  3Comments  Â·  Source: pjreddie/darknet

  1. get MinGW64

  2. run the installer for the latest working version (I used 7.2.0 rev 1)
    image

  3. in Makefile remove go.o from build:
    :fire: #EXECOBJA=captcha.o lsd.o super.o art.o tag.o cifar.o ~go.o~ rnn.o segmenter.o regressor.o classifier.o coco.o yolo.o detector.o nightmare.o darknet.o
    :seedling: EXECOBJA=captcha.o lsd.o super.o art.o tag.o cifar.o rnn.o segmenter.o regressor.o classifier.o coco.o yolo.o detector.o nightmare.o darknet.o

  4. in examples/darknet.c comment out run_go references:
    :fire: /*extern void run_go(int argc, char **argv);*/
    :fire: else if (0 == strcmp(argv[1], "go")){ /*run_go(argc, argv);*/ }

  5. in include/darknet.h add the following header:
    #include <time.h>

  6. open up Run terminal under MinGW - W64 project from the start menu

  7. cd to the darknet project directory you just modded

  8. enter mingw32-make
    b. when it finishes building you can close the terminal window as you won't need it after the next steps

  9. copy libwinpthread-1.dll to the darknet project root directory from the mingw64 install (should be something like mingw-w64\x86_64-version-posix-seh-whatever\mingw64\bin)

  10. [shift+right click] in darknet directory to Open command window here
    b. You might also want to grab a pretrained weight file and stick it in darknet root directory: https://pjreddie.com/media/files/yolov3.weights

  11. run darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg

  12. :tada:
    image
    (see also predictions.png)

Most helpful comment

Please use this forked version for Windows builds, this is super easy to setup.
https://github.com/AlexeyAB/darknet

All 3 comments

With GPU and OpenCV disabled, I can confirm this works.

Haven't yet been able to get it to compile with either of those options, but still working on it...

GPU

Currently plugged up here:

./src/blas_kernels.cu(870): error: expected a "{" introducing a lambda body

./src/blas_kernels.cu(874): error: expected a "{" introducing a lambda body

./src/blas_kernels.cu(882): error: expected an expression

./src/blas_kernels.cu(893): warning: unrecognized attribute

./src/blas_kernels.cu(893): error: expected a declaration

./src/blas_kernels.cu(893): error: attributes are not allowed here

./src/blas_kernels.cu(895): warning: unrecognized attribute

./src/blas_kernels.cu(895): error: expected a declaration

./src/blas_kernels.cu(895): error: attributes are not allowed here

./src/blas_kernels.cu(890): warning: variable "b" was declared but never referenced

./src/blas_kernels.cu(902): error: expected an expression

8 errors detected in the compilation of "C:/tools/msys64/tmp/tmpxft_00006290_00000000-13_blas_kernels.compute_52.cpp1.ii".
blas_kernels.cu
make: *** [Makefile:89: obj/blas_kernels.o] Error 1

Where

// Line 861 here, 862 follows
__global__ void deinter_kernel(int NX, float *X, int NY, float *Y, int B, float *OUT)
{
    int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x;
    if(i < (NX+NY)*B){
        int b = i / (NX+NY);
        int j = i % (NX+NY);
        if (j < NX){
          if(X) {
            X[b*NX + j] += OUT[i]; // 870
          }
        } else {
          if(Y) {
            Y[b*NY + j - NX] += OUT[i]; // 874
          }
        }
    }
}

extern "C" void deinter_gpu(int NX, float *X, int NY, float *Y, int B, float *OUT)
{
    deinter_kernel<<<cuda_gridsize((NX+NY)*B), BLOCK>>>(NX, X, NY, Y, B, OUT); // 882
    check_error(cudaPeekAtLastError());
}

__global__ void inter_kernel(int NX, float *X, int NY, float *Y, int B, float *OUT)
{
    int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x;
    if(i < (NX+NY)*B){
        int b = i / (NX+NY); // 890
        int j = i % (NX+NY);
        if (j < NX){
            OUT[i] = X[b*NX + j]; // 893
        } else {
            OUT[i] = Y[b*NY + j - NX]; // 895
        }
    }
}

extern "C" void inter_gpu(int NX, float *X, int NY, float *Y, int B, float *OUT)
{
    inter_kernel<<<cuda_gridsize((NX+NY)*B), BLOCK>>>(NX, X, NY, Y, B, OUT); // 902
    check_error(cudaPeekAtLastError());
}

OpenCV:

Currently plugged up here:

./src/blas.c: In function 'deinter_cpu':
./src/blas.c:196:1: error: parameter name omitted
 void deinter_cpu(int NX, float *X, int NY, float *Y, int B, float *OUT)
 ^~~~
compilation terminated due to -Wfatal-errors.
make: *** [Makefile:86: obj/blas.o] Error 1

The full function it's complaining about...

void deinter_cpu(int NX, float *X, int NY, float *Y, int B, float *OUT)
{
    int i, j;
    int index = 0;
    for(j = 0; j < B; ++j) {
        for(i = 0; i < NX; ++i){
            if(X) X[j*NX + i] += OUT[index];
            ++index;
        }
        for(i = 0; i < NY; ++i){
            if(Y) Y[j*NY + i] += OUT[index];
            ++index;
        }
    }
}

I installed minGW32 from offical website instead of minGW64, and then used MinGW Installation Manager to install the pthread package manually.
Then I followed your steps without step9, yolov2 can be runned totally correct. THX!

I hope this trick can help someone who meets the following error using win10:

gcc -Iinclude/ -Isrc/ -Wall -Wno-unused-result -Wno-unknown-pragmas -Wfatal-errors -fPIC -Ofast -c ./src/gemm.c -o obj/gemm.o
In file included from ./src/utils.h:5:0,
                 from ./src/gemm.c:2:
include/darknet.h:6:21: fatal error: pthread.h: No such file or directory
 #include <pthread.h>
                     ^
compilation terminated.
Makefile:85: recipe for target 'obj/gemm.o' failed
mingw32-make: *** [obj/gemm.o] Error 1

Please use this forked version for Windows builds, this is super easy to setup.
https://github.com/AlexeyAB/darknet

Was this page helpful?
0 / 5 - 0 ratings