SDL中文论坛

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 15885|回复: 2
打印 上一主题 下一主题

[opencv] 编译

[复制链接]

149

主题

331

帖子

2445

积分

版主

Rank: 7Rank: 7Rank: 7

积分
2445
跳转到指定楼层
楼主
发表于 2017-6-12 09:37:58 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 ancientcc 于 2021-3-6 11:20 编辑

cmake编译OpenCV时经常因为ippicv而编译失败,IPPICV: Download failed: 28;"Timeout was reached"。OpenCV编译用的是这么个逻辑,如果缓存(.cache)中有该文件,就直接使用缓存中文件,否则从网上下载。具体到ippicv,以下是opencv3.3.0中相关参数。

版本缓存文件下载URL
32位opencv-3.3.0/.cache/ippicv/60fcf3ccd9a2ebc9e432ffb5cb91638b-ippicv_2017u2_win_ia32_20170418.ziphttps://raw.githubusercontent.com/opencv/opencv_3rdparty/a62e20676a60ee0ad6581e217fe7e4bada3b95db/ippicv/ippicv_2017u2_win_ia32_20170418.zip
64位opencv-3.3.0/.cache/ippicv/75060a0c662c0800f48995b7e9b085f6-ippicv_2017u2_win_intel64_20170418.ziphttps://raw.githubusercontent.com/opencv/opencv_3rdparty/a62e20676a60ee0ad6581e217fe7e4bada3b95db/ippicv/ippicv_2017u2_win_intel64_20170418.zip


75060A0C662C0800F48995B7E9B085F6是根据ippicv_2017u2_win_intel64_20170418.zip内容计算出的哈希值(MD5)。要计算这个值可以下载hasher.zip。把ippicv_2017u2_win_intel64_20170418.zip拖到字符串区就会显示以下内容。


只有Windows须要ippicv。

4、复制到相关目录下

将文件复制到相应的目录下:
<opencv>/.cache/ippicv/879741a7946b814455eee6c6ffde2984-ippicv_2020_win_intel64_20191018_general.zip
<opencv>/.cache/ippicv/cd39bdf0c2e1cac9a61101dad7a2413e-ippicv_2020_win_ia32_20191018_general.zip
回复

使用道具 举报

149

主题

331

帖子

2445

积分

版主

Rank: 7Rank: 7Rank: 7

积分
2445
沙发
 楼主| 发表于 2017-6-30 19:46:35 | 只看该作者

编译

本帖最后由 ancientcc 于 2018-3-4 21:43 编辑

参考:https://zhuanlan.zhihu.com/p/34221622

ios-opencv.png (62.73 KB, 下载次数: 2034)

ios-opencv.png
回复 支持 反对

使用道具 举报

149

主题

331

帖子

2445

积分

版主

Rank: 7Rank: 7Rank: 7

积分
2445
板凳
 楼主| 发表于 2017-8-28 22:36:30 | 只看该作者
本帖最后由 ancientcc 于 2017-8-29 11:07 编辑

cv_cpu_config.h
由cmake生成,指示了要使用的优化设置。以下是一个例子,支持优化指令集:SSE、SSE2、SSE_1、SSE_2、FP16、AVX、AVX2。
  1. // OpenCV CPU baseline features

  2. #define CV_CPU_COMPILE_SSE 1
  3. #define CV_CPU_BASELINE_COMPILE_SSE 1

  4. #define CV_CPU_COMPILE_SSE2 1
  5. #define CV_CPU_BASELINE_COMPILE_SSE2 1

  6. #define CV_CPU_BASELINE_FEATURES 0 \
  7.     , CV_CPU_SSE \
  8.     , CV_CPU_SSE2 \


  9. // OpenCV supported CPU dispatched features

  10. #define CV_CPU_DISPATCH_COMPILE_SSE4_1 1
  11. #define CV_CPU_DISPATCH_COMPILE_SSE4_2 1
  12. #define CV_CPU_DISPATCH_COMPILE_FP16 1
  13. #define CV_CPU_DISPATCH_COMPILE_AVX 1
  14. #define CV_CPU_DISPATCH_COMPILE_AVX2 1
复制代码

让以fastAtan32f为例,描述OpenCV如何根据特定指令集进行优化过程。
  1. modules/core/mathfuncs_core.dispatch.cpp
  2. void fastAtan32f(const float *Y, const float *X, float *angle, int len, bool angleInDegrees)
  3. {
  4.     CV_INSTRUMENT_REGION()

  5.     CALL_HAL(fastAtan32f, cv_hal_fastAtan32f, Y, X, angle, len, angleInDegrees);

  6.     CV_CPU_DISPATCH(fastAtan32f, (Y, X, angle, len, angleInDegrees),
  7.         CV_CPU_DISPATCH_MODES_ALL);
  8. }
复制代码


让深入CALL_HAL。
  1. #define CALL_HAL(name, fun, ...) \
  2. { \
  3.     int res = fun(__VA_ARGS__); \
  4.     if (res == CV_HAL_ERROR_OK) \
  5.         return; \
  6.     else if (res != CV_HAL_ERROR_NOT_IMPLEMENTED) \
  7.         CV_Error_(cv::Error::StsInternal, \
  8.             ("HAL implementation " CVAUX_STR(name) " ==> " CVAUX_STR(fun) " returned %d (0x%08x)", res, res)); \
  9. }

  10. #define cv_hal_fastAtan32f hal_ni_fastAtan32f

  11. inline int hal_ni_fastAtan32f(const float* y, const float* x, float* dst, int len, bool angleInDegrees) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
复制代码

CALL_HAL最后执行hal_ni_fastAtan32f,它就是空操作,但由于返回CV_HAL_ERROR_NOT_IMPLEMENTED,调用它的fastAtan32f会继续执行后面的CV_CPU_DISPATCH,正是这个宏执行了真正操作。在深入这宏前让介绍mathfuncs_core.dispatch.cpp中的两条include语句。
  1. #include "mathfuncs_core.simd.hpp"
  2. #include "mathfuncs_core.simd_declarations.hpp"
复制代码

第一个include作用是两个,1)声明cpu_baseline版本,2)实现baseline版本,这是通过不定义CV_CPU_OPTIMIZATION_DECLARATIONS_ONLY宏,使得mathfuncs_core.simd.hpp包含实现。第二个include也两个作用,1)声明特殊指令集版本(只是声明),2)定义一个叫CV_CPU_DISPATCH_MODES_ALL的宏。
  1. #define CV_CPU_DISPATCH_MODES_ALL AVX2, AVX, SSE2, BASELINE
复制代码

CV_CPU_DISPATCH_MODES_ALL宏指示了每个模块实现了的指令集版本。它实现了4种指令集,AVX2、AVX、SSE2是特殊指令集,BASELINE则是cpu_baseline实现。
上面4个种版本,cpu_baseline的函数已由第一个include实现,三种特殊指令集则由另外三个源文件实现,它们有着一样内容。
  1. #include "precomp.hpp"
  2. #include "mathfuncs_core.simd.hpp"
复制代码

要编译这三个文件,必须在文件层定义一个叫CV_CPU_DISPATCH_MODE的宏。
文件文件层的预定义宏最后实现的函数
mathfuncs_core.avx.cppCV_CPU_DISPATCH_MODE=AVXcv::hal:pt_AVX::fastAtan32f
mathfuncs_core.avx2.cppCV_CPU_DISPATCH_MODE=AVX2cv::hal:pt_AVX2::fastAtan32f
mathfuncs_core.sse2.cppCV_CPU_DISPATCH_MODE=SSE2cv::hal:pt_SSE2::fastAtan32f

有了这4个版本的fastAtan32f实现,让回到CV_CPU_DISPATCH,看它是如何调用这四个函数。以下这个宏的伪代码。
  1. CV_CPU_DISPATCH(fastAtan32f, (Y, X, angle, len, angleInDegrees), AVX2, AVX, SSE2, baseline)
  2. {
  3.         if (cv::checkHardwareSupport(CV_CPU_AVX2) {
  4.                 cv::hal::opt_AVX2::fastAtan32f(Y, X, angle, len, angleInDegrees);
  5.                 return;
  6.         }
  7.         if (cv::checkHardwareSupport(CV_CPU_AVX) {
  8.                 cv::hal::opt_AVX::fastAtan32f(Y, X, angle, len, angleInDegrees);
  9.                 return;
  10.         }
  11.         cv::hal::opt_SSE2::fastAtan32f(Y, X, angle, len, angleInDegrees); return;
  12.         cv::hal::cpu_baseline::fastAtan32f(Y, X, angle, len, angleInDegrees); return;

  13. }
复制代码
CV_CPU_DISPATCH_MODES_ALL宏决定了四个fastAtan32f调用次序。要没意外,CV_CPU_DISPATCH的最后两个总是__CV_CPU_DISPATCH_CHAIN_BASELINE, __CV_CPU_DISPATCH_CHAIN_END,后者是个空操作。

  1. #define __CV_CPU_DISPATCH_CHAIN_END(fn, args, mode, ...)  /* done */
复制代码



baseline features和dispatched features
  1. #if !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_COMPILE_AVX
  2. #  define CV_TRY_AVX 1
  3. #  define CV_CPU_HAS_SUPPORT_AVX 1
  4. #  define CV_CPU_CALL_AVX(fn, args) return (opt_AVX::fn args)
  5. #elif !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_DISPATCH_COMPILE_AVX
  6. #  define CV_TRY_AVX 1
  7. #  define CV_CPU_HAS_SUPPORT_AVX (cv::checkHardwareSupport(CV_CPU_AVX))
  8. #  define CV_CPU_CALL_AVX(fn, args) if (CV_CPU_HAS_SUPPORT_AVX) return (opt_AVX::fn args)
  9. #else
  10. #  define CV_TRY_AVX 0
  11. #  define CV_CPU_HAS_SUPPORT_AVX 0
  12. #  define CV_CPU_CALL_AVX(fn, args)
  13. #endif
  14. #define __CV_CPU_DISPATCH_CHAIN_AVX(fn, args, mode, ...)  CV_CPU_CALL_AVX(fn, args); __CV_EXPAND(__CV_CPU_DISPATCH_CHAIN_ ## mode(fn, args, __VA_ARGS__))
复制代码

当中有两个宏:CV_CPU_COMPILE_AVX、CV_CPU_DISPATCH_COMPILE_AVX。回看cv_cpu_config.h,第一个是baseline features,第二个是dispatched features。baseline features指的是那些必须满足的SIMD。一旦运行在的cpu不支持这种SIMD,app会因为非法而退出。dispatched features指的是那些会运行时判断是否支持的指令集,即用cv::checkHardwareSupport运行时检查cpu是否能支持这种SIMD。

为让支持更多cpu,应尽可能低的定义baseline features。当前就是SSE、SSE2。

opencv3.3.0有BUG,必须把AVX、AVX2定义为baseline features。以下是个人解决这BUG方法。
  1. #ifdef CV_CPU_COMPILE_AVX
  2. # include <immintrin.h>
  3. # define CV_AVX 1
  4. #endif
复制代码
中的第一句改为
  1. #if defined CV_CPU_COMPILE_AVX || defined CV_CPU_DISPATCH_COMPILE_AVX
复制代码

  1. #ifdef CV_CPU_COMPILE_AVX2
  2. # include <immintrin.h>
  3. # define CV_AVX2 1
  4. #endif
复制代码
中的第一句改为
  1. #if defined CV_CPU_COMPILE_AVX2 || defined CV_CPU_DISPATCH_COMPILE_AVX2
复制代码
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|丽谷软件|libsdl.cn

GMT+8, 2025-5-2 02:19 , Processed in 0.060077 second(s), 22 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表